secret_listLABSCO SUMMARY
The agent gets results, not credentials — and the allowlist decides which commands it may run at all.
Two controls do the work: injection means the value exists only in the child process's environment, and the policy file denies by default so only the commands you named are runnable. The stated limit is worth reading — output sanitisation is exact string matching, so a secret that appears base64-encoded or partially in the output will not be caught. Note also that the master password lives in the MCP client's config as an environment variable.
What it is
A local secret vault with an MCP server attached. The agent never receives plaintext values: it asks secretctl to run a command, secretctl injects the secrets as environment variables for that process, and the output is scrubbed before it goes back. Everything stays on your machine — one binary, a SQLite vault, no service to sign up for.
What you get
secret_listlists keys with metadata and no values;secret_existschecks onesecret_get_maskedreturns a masked value such as ****WXYZ, enough to confirm which credential is storedsecret_runexecutes a command with secrets injected as environment variables, and sanitises the outputsecret_run_with_bindingsdoes the same with predefined environment bindingssecret_list_fieldsandsecret_get_fieldhandle multi-field secrets, returning only the non-sensitive fields- A policy file at
~/.secretctl/mcp-policy.yamlsetsdefault_action: denyand an explicit allowed-commands list - Values are encrypted at rest with AES-256-GCM under an Argon2id-derived key, and the audit log is HMAC-chained so tampering shows
Requirements
A single binary — build from source with Go 1.24+, or download a release for Linux, macOS or Windows. Initialise the vault with secretctl init and a master password of at least 8 characters. The MCP server needs that password in SECRETCTL_PASSWORD at launch: secretctl mcp-server. On macOS an unsigned download needs xattr -d com.apple.quarantine.
Setup effort
One command plus credentials — brew install forest6511/tap/secretctl, then supply credentials
USE CASES
Letting an agent use cloud CLIs safely
It runs the command through secretctl; the keys are injected for that process only and never enter the conversation.
Confirming which credential is stored
Read the masked tail of the value instead of printing it.
Letting it discover what is available
List keys and their metadata so the agent can pick the right one without seeing any values.
Constraining what it may execute
Set the policy to deny by default and list only the commands you want reachable.
7 tools
Listed in project docs. Your client may show a different list.
secret_existssecret_get_maskedsecret_runsecret_list_fieldssecret_get_fieldsecret_run_with_bindingsBEFORE YOU INSTALL
What to know first
Tools you get
7 tools named in the project's documentation.
Requires
SECRETCTL_PASSWORD in your environment
Where it runs
The documented client runs the server on your machine.
INSTALLATION
Connect your client
Server setup
Install the binary — Homebrew: brew install forest6511/tap/secretctl; or download the release for your platform, chmod +x it and move it onto your PATH; or build from source: git clone https://github.com/forest6511/secretctl.git && cd secretctl && go build -o secretctl ./cmd/secretctl (requires Go 1.24+)
Verify:
secretctl --helpInitialize your vault and enter a master password (min 8 characters):
secretctl initCreate the MCP policy file FIRST — it is required before the server will start: mkdir -p ~/.secretctl and write ~/.secretctl/mcp-policy.yaml with version: 1, default_action: deny, and an allowed_commands list
Add the mcpServers block to ~/.claude.json with the binary path, args ["mcp-server"] and SECRETCTL_PASSWORD in env
MCP Clients
Claude Code
{
"mcpServers": {
"secretctl": {
"command": "secretctl",
"args": [
"mcp-server"
],
"env": {
"SECRETCTL_PASSWORD": "<YOUR_SECRETCTL_PASSWORD>"
}
}
}
}