MCP server that allows agents to request secrets from humans via a local browser form, storing values in the OS keystore (Keychain, Secret Service, Credential Manager) without exposing them to the agent
Strong tool definitions with comprehensive schemas and clear descriptions. All 10 tools have explicit input schemas with proper JSON Schema types and descriptions. Tool annotations (readOnlyHint, destructiveHint, idempotentHint) are present and correct. Descriptions are detailed and actionable (avg ~150 chars). Key strengths: secret_request has exceptional parameter documentation with preset enums and custom field support; secret_run and secret_write_file clearly explain output scrubbing and security properties. Gaps: no documented output schemas for any tool (what fields are returned?); secret_request's 'fields' parameter uses union type ['string', 'object'] which is ambiguous; some parameter descriptions could be more concise (secret_request is verbose); no error handling guidance (what happens if keystore is unavailable? if command times out?). Composition is excellent, tools are single-responsibility and chain well (request → status/wait → events → use via run/write_file).
Forget a secret's value and metadata.
Metadata for one secret: purpose, length, fingerprint.
Every request that was answered, declined or expired, newest last, with a cursor. Pass `wait` to block until the next one. This is how an agent that did not stay blocked - or a different agent entirely - learns that the human pasted something.
Check the local broker is up and which store it uses.
Names and metadata only - no values.
Open a local browser form so the human can paste a secret (API key, password, token). The value is stored in the operating system's keystore - Keychain, Secret Service or Credential Manager - and is NEVER returned to you. Blocks until the human answers or `wait` seconds pass. Use this instead of asking for a secret in chat.
No documented output schemas for any tool. LLMs cannot plan downstream calls or extract required fields (e.g., what does secret_request return? Is it {request_id, state, fingerprint}?). This violates pattern:tool and forces agents to guess response structure.
secret_request 'fields' parameter uses union type ['string', 'object'] without clear discrimination. When is it a string vs object? The description says 'each field is stored as its own secret' but the schema allows bare strings. This ambiguity will cause LLM errors.
No error handling guidance. Tools lack descriptions of failure modes and recovery steps. E.g., secret_request: what if the keystore is locked? secret_run: what if the command times out or the secret is not found? Agents have no guidance on retryability or next steps.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | C | 68 | 2025-06-18+ | v2 |
Run a command with stored secrets injected as environment variables. Output is scrubbed of the secret values before it reaches you. This is how you USE a secret.
Poll a request created with wait=0.
Block until a specific request is answered, declined or expires. Use after a wait: 0 request when you are still in the same turn.
Render a template containing {{secret:name}} placeholders into a file with 0600 permissions - e.g. a .env or a config file. The rendered content is not returned to you.
secret_list and secret_health descriptions are too brief (<70 chars). 'Names and metadata only - no values' and 'Check the local broker is up and which store it uses' lack context on when to call these tools or what structure they return.
secret_request 'notify' parameter lacks validation guidance. The webhook URL must be http:// on 127.0.0.1, but the description does not state this constraint. LLMs may pass https:// or external URLs, causing silent failures.