Files
sherlock/docs/architecture.md
T
amacocianandCopilot 87e6a0cc49
Charlie/project-charlie: Build image / config (push) Successful in 1s
Charlie/project-charlie: Build image / build (push) Skipped
Charlie/project-charlie: Deploy runners / config (push) Successful in 1s
Charlie/project-charlie: Deploy runners / deploy-morgott (push) Skipped
Charlie/project-charlie: Deploy runners / deploy-melina (push) Skipped
Charlie/project-charlie: Deploy stack / config (push) Successful in 0s
Charlie/project-charlie: Deploy stack / deploy (push) Skipped
Release / release (push) Successful in 1m48s
config: layer a project-local .sherlock.toml over the global config
Sherlock now reads an optional .sherlock.toml found by walking up from
the working directory and layers it on top of the global config. Each
[oauth]/[providers.x]/[services.x]/[agents.x] entry the local file
declares replaces the same-named global entry wholesale; everything else
falls back to the global file. Either file may be absent.

An empty section means disabled: a disabled service is left out of the
rendered MCP config (and its MCP refuses to start if launched directly),
and a disabled agent is removed from dispatch, built-ins included.

The resolved local file is pinned on spawned MCPs via
SHERLOCK_LOCAL_CONFIG so a child with a different working directory
still reads the same config.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot-Session: fdf86527-ca08-420d-89ee-47bcee60bebe
2026-09-04 09:14:35 +02:00

2.1 KiB

Architecture

Sherlock is a local CLI, not a daemon. It either manages the wallet (status, logout) or replaces itself with an agent CLI (copilot, claude, ...). MCPs run as agent child processes and own service authentication.

Runtime flow

  1. sherlock <agent> opens the keyring, loads the config (global plus any project-local .sherlock.toml above the working directory), resolves installed MCP binaries for the services that are not disabled, writes $XDG_RUNTIME_DIR/sherlock/<agent>.mcp.json, and execs the agent.
  2. The agent starts the configured stdio MCPs.
  3. Each MCP loads its [services.<name>] config — the same layered view, pinned via SHERLOCK_LOCAL_CONFIG — authenticates on first tool call, keeps its token fresh, and calls the target service.

Code map

Area Role
cmd/sherlock/ CLI, wallet commands, agent dispatch, update entry point.
cmd/*-mcp/ Service MCP binaries. Tool details live with each MCP.
internal/agent/ Registered agent profiles and spawn helpers.
internal/mcp/ MCP config rendering.
internal/config/ Layered TOML loading and service/provider resolution.
internal/authn/ OAuth/PKCE login, refresh, token sources, locks.
internal/keyring/ OS keyring wallet.
internal/installer/, internal/selfupdate/ Install and update logic.

Boundaries

Sherlock does not federate identities, run a background broker, issue SSH credentials, enforce service policy, or define MCP tool behavior. It gets the right credential to the right local MCP process.