2.9 KiB
Configuration
Sherlock reads all deployment-specific values — the Authentik issuer/client IDs and each service's base URL — from a single TOML file. There are no compiled-in defaults: a missing file, section, or required field is a hard error, so an MCP can never silently target the wrong host.
A starter file lives at config.example.toml.
Location
Resolved in this order:
$SHERLOCK_CONFIG(an explicit path; handy for tests / non-standard installs).$XDG_CONFIG_HOME/sherlock/config.toml.$HOME/.config/sherlock/config.toml.
Shape
[providers.sherlock-cli]
issuer = "https://id.example.com/application/o/sherlock-cli/"
client_id = "…"
[services.gitea]
issuer = "https://gitea.example.com"
client_id = "…"
base_url = "https://gitea.example.com"
[services.grafana]
provider = "sherlock-cli"
base_url = "https://grafana.example.com"
[services.gssh]
provider = "sherlock-cli"
base_url = "https://terminal.example.com"
Providers
A [providers.<name>] block is a reusable OAuth/OIDC client
(issuer, client_id, optional client_secret). Define it once and
share it across every service it fronts. The sherlock-cli Authentik
provider is shared by grafana and gssh (and any future
Authentik-fronted service); it is a Public/PKCE client, so
client_secret is omitted and its redirect URI must be whitelisted as
http://127.0.0.1:6990/callback.
Services
Each [services.<name>] is one MCP's target. <name> is both the
config key and the wallet key (sherlock logout <name>). A service
must resolve to a non-empty issuer, client_id, and base_url, by
either:
- referencing a provider —
provider = "sherlock-cli"(Authentik services), or - carrying an inline identity —
issuer+client_id(+client_secretif required). Gitea uses this form because it runs its own OAuth2 server rather than authenticating against Authentik.
Setting both provider and an inline issuer/client_id on the same
service is rejected — pick one.
base_url is the API origin the MCP calls (e.g. /api/v1/... for
Gitea, /api/... for Grafana). It is always required.
What is not in the config
- OAuth scopes — each MCP declares the scopes it needs in code
(Gitea pulls a broad read set; Grafana/Gssh ask for
openid profile email). Scopes are a function of what the MCP does, not of the deployment. - Secrets / tokens — the operator's OAuth tokens live in the OS keyring, never in this file. See storage.md.
- The loopback redirect port (
127.0.0.1:6990) — fixed in code; see auth-model.md.
Adding a service
- Add a
[services.<name>]block (provider reference or inline identity, plusbase_url). - Point its MCP's
serviceNameconstant at<name>(it's the config key and the wallet key).
See conventions.md for the broader extensibility model.