Clients & Libraries
MCP bridge
A standalone stdio Model Context Protocol server. It gives MCP clients operation-only access to non-exportable HSM and smart-card signing keys, and optionally resolves an allowlisted set of named variables.
Build
git clone https://github.com/afterdarksys/secretserver-clients.git cd secretserver-clients/mcp go build -o secretserver-mcp .
The module needs Go 1.25 or newer and uses the official Go MCP SDK.
Authenticate and register
Create a short-lived API key with only the keys:sign scope and write it to a file that only you can read. Never put the key itself in MCP configuration or in an environment variable.
umask 077 printf '%s\n' 'sk_...' > /absolute/path/to/agent-token # mode 0600
| Variable | Required | Meaning |
|---|---|---|
SECRETSERVER_URL | yes | API origin, for example https://api.secretserver.io. https only; http is allowed for loopback. A reverse-proxy path prefix is kept. |
SECRETSERVER_TOKEN_FILE | yes | Absolute path to a regular, owner-only file holding the API key (16 to 8192 bytes). |
SECRETSERVER_ENABLE_SECRET_RESOLUTION | no | Set to 1 to register resolve_secret_template. |
SECRETSERVER_RESOLVE_ALLOW | with the above | Comma-separated variable names the tool may resolve. Startup fails if resolution is enabled without it. |
Codex
codex mcp add \ --env SECRETSERVER_URL=https://api.secretserver.io \ --env SECRETSERVER_TOKEN_FILE=/absolute/path/to/agent-token \ secretserver \ -- /absolute/path/to/secretserver-mcp
Claude Code
claude mcp add --transport stdio --scope user secretserver \ --env SECRETSERVER_URL=https://api.secretserver.io \ --env SECRETSERVER_TOKEN_FILE=/absolute/path/to/agent-token \ -- /absolute/path/to/secretserver-mcp
The key is read once into locked memory and wiped when the bridge exits.
Tools
| Tool | Input | Scope | Returns secrets |
|---|---|---|---|
list_key_metadata | backend: pkcs11 | ehsm | keys:sign | no |
sign_with_key | backend, key_id, message (base64, 1 MiB max decoded), purpose | keys:sign | no |
resolve_secret_template | template | read (and export) on the underlying credential | yes, opt-in only |
Read a secret
By default the bridge cannot read secret values. To let a model read specific values, enable resolution and allowlist the variable names:
--env SECRETSERVER_ENABLE_SECRET_RESOLUTION=1 \ --env SECRETSERVER_RESOLVE_ALLOW=LOG_SERVER_TX1_S,DEPLOY_TOKEN
The tool then accepts {"template":"%%LOG_SERVER_TX1_S%%"} and returns {"rendered": "..."}. Any name outside the allowlist, or a malformed template, is refused before the server is contacted.
Write a secret
The bridge has no write, update or delete tools. Store and change secrets with the dashboard, the CLI or a client library.
List keys
list_key_metadata lists signing-key metadata for a backend (it calls GET /api/v1/crypto/signing-keys?backend=...). It returns no private material. Call it before sign_with_key to pick a key ID. Listing secrets is not supported.
Error handling
Startup errors are fatal and printed to stderr. Tool errors come back as MCP results with isError set and text starting with operation failed:.
| Error | Cause |
|---|---|
| SECRETSERVER_TOKEN_FILE is required | Variable not set |
| token file must be regular and accessible only by its owner | File mode allows group or other access, or it is not a regular file |
| SECRETSERVER_URL must use HTTPS | Plain http to a non-loopback host |
| ...requires SECRETSERVER_RESOLVE_ALLOW=NAME[,NAME...] | Resolution enabled without an allowlist |
| variable NAME is not allowlisted for this bridge | Template referenced a name outside the allowlist |
| unsupported signing backend | backend was not pkcs11 or ehsm |
Complete setup
cd secretserver-clients/mcp && go build -o secretserver-mcp . install -d -m 0700 ~/.config/secretserver umask 077 && printf '%s\n' "$KEYS_SIGN_API_KEY" > ~/.config/secretserver/mcp-token claude mcp add --transport stdio --scope user secretserver \ --env SECRETSERVER_URL=https://api.secretserver.io \ --env SECRETSERVER_TOKEN_FILE=$HOME/.config/secretserver/mcp-token \ -- "$PWD/secretserver-mcp"
Then ask the model to call list_key_metadata with backend: "pkcs11", and sign_with_key with the chosen key ID, the base64 message and an audit purpose. Verify the returned signature against the key's trusted public key.