CLI-managed MCP server setup, without required env variables for credentials
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 152
- Forks
- 16
- Avg merge
- 14h 48m
- Merged PRs (30d)
- 536
Description
Summary
Make setting up an MCP server easy from the CLI, and stop requiring an environment
variable for the credential-store key. Today both are manual and error-prone: adding
a server means hand-editing the operator settings.yaml mcp.servers[] block, and
the local OAuth credential store can only take its encryption key from a MECATL_*
env var that must be present in every shell/process that logs in or reads the credential.
Motivation
Writing the setup guide for connecting mecatui to an OAuth MCP server (the Stacklok
staging connector-gateway) surfaced two friction points:
-
No CLI to manage servers.
mecated mcponly supportslogin
(cmd/mecated/command.go). Adding a server means hand-writing a ~20-line nested
mcp.servers[]OAuth/DCR block with several non-obvious, easy-to-get-wrong fields:
the servernamemust be[A-Za-z0-9_]+(no hyphens),urlmust include the
resource path (e.g./gw/mcp),issuermust be the exact origin,
client: {mode: dcr, dcr: {}}, pluscredentialsandnetworkblocks. A typo in
any of these fails discovery with a generic, detail-suppressed error (the specific
cause is dropped ininternal/app/mcplogin.go'sloginDiagnostic). -
The credential-store key must come from an env var. The local OAuth credential
store (MCPLocalCredentialProfile,internal/adapter/permconfig/schema.go) accepts
onlykey_env: MECATL_*. So the operator has to generate a 32-byte key, store it,
and exportMECATL_MCP_CREDENTIAL_KEYin every shell that runsmecated mcp login
and every process that later reads the credential (e.g. mecatui). Miss it in the
runtime shell and the credential silently can't be decrypted → the server drops to
"login required" with no obvious cause. This is exactly the "harder to set up in a
durable way" concern raised in review.
Proposal
1. CLI management of MCP servers
Add mecated mcp subcommands to add/list/remove/inspect servers without hand-editing YAML:
mecated mcp add <name> --url <url> --auth oauth— sensible OAuth/DCR defaults;
discoverissuer/resource from the server's RFC 9728 protected-resource metadata
where possible (the samediscoverDCRMetadatapathloginalready runs), prompting
only for what can't be discovered, and validating up front so it can surface the
specific failure (issuer mismatch, DCR unsupported, missing scope) instead of the
current generic "authorization unavailable".mecated mcp list/mecated mcp status— configured servers plus connection and
credential state.mecated mcp remove <name>.
These read/write the same operator settings.yaml mcp.servers[] schema, so config
stays declarative and reviewable — the CLI is a safe editor over it, not a second
source of truth. mecated mcp login <name> already exists and composes with this.
2. Don't require an env variable for the credential-store key
Give the MCP local credential store the same key-custody choice the OIDC provider
credential store already has. NativeCredentialKey
(internal/adapter/permconfig/providers.go) already supports source: keyring | environment,
defaulting to the OS keyring. MCPLocalCredentialProfile should adopt the same union so
the default is keyring custody (macOS Keychain / Secret Service / etc.) with no env
var, and key_env becomes one opt-in option (for headless/CI) rather than the only
mechanism.
Result: mecated mcp login <name> and the runtime both get the key from the keyring
automatically — nothing to export, nothing to re-export per shell, and it survives
across sessions and processes durably.
Acceptance sketch
mecated mcp add|list|removemanagemcp.servers[]entries in operator
settings.yaml; round-trip preserves unknown top-level keys.- The MCP local credential store defaults to keyring-backed key custody; no
MECATL_*
env var is required to log in or to read the credential at runtime.key_envremains
supported for headless deployments. - Docs updated to the CLI-first, no-env-var flow
(user-docs/features/mcp-oauth-and-credentials.md, and the eng setup guide).
References
- Current CLI surface:
cmd/mecated/command.go(onlymcp login). - Env-only key today:
internal/adapter/permconfig/schema.go(MCPLocalCredentialProfile.KeyEnv). - Existing keyring pattern to reuse:
internal/adapter/permconfig/providers.go(NativeCredentialKey,source: keyring). - Generic-error masking to improve alongside
add:internal/app/mcplogin.go(loginDiagnostic).
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with cmd/mecated/command.go for the existing mcp login surface, then read internal/adapter/permconfig/schema.go and providers.go to compare MCP and provider key custody. Review internal/app/mcplogin.go for diagnostic behavior and the referenced MCP documentation. Done means add/list/remove, keyring and key_env flows, YAML round-tripping, diagnostics, and docs meet the acceptance sketch.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- go
- Domain
- authentication, cli, documentation, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 42/100