MCP tools
These are the tools keymitt mcp offers to agents. Placeholders look like {{secret:NAME}} for a secret and {{file:ID}} for a temporary file declared in the same request.
list_secrets
No arguments. Returns each secret's name, description, allowed channels, programs and hosts, and whether it is usable at all. Never values.
run_with_secrets
Runs a program — directly, not through a shell — with secrets injected.
| Argument | Type | Notes |
|---|---|---|
command | string[] | Program and arguments. The program is a bare name on PATH or an absolute path. May contain {{file:ID}}, never {{secret:…}} |
stdin | string | Written to standard input. May contain {{secret:NAME}} and {{file:ID}} |
env | object | Environment variables. Each value must be exactly one {{secret:NAME}} placeholder |
files | {id, content}[] | Temporary owner-only files, deleted after the run. Content may contain secrets |
cwd | string | Working directory. Defaults to the server's |
timeout_secs | number | Default 60, maximum 600 |
The request is refused, before any prompt, when:
- a secret appears in the arguments;
- the policy does not allow a secret through that channel, or to that program;
- an environment variable could hijack the program:
PATH,HOME, loader variables (LD_*,DYLD_*), interpreter and tool families (NODE_*,PYTHON*,GIT_*,CARGO_*, …), proxies, CA bundles,SSLKEYLOGFILE, pagers and editors — or the secret's policy restricts names; - arguments, stdin or a file exceed 1 MiB, or more than 16 files are declared;
- the approval prompt would be longer than 700 characters;
- no secret is used at all — such commands don't need keymitt.
The program is looked up only in absolute PATH directories, and on macOS and Linux it runs in its own process group, which is killed when the run ends.
Returns exit_code, timed_out, stdout, stderr (each at most 256 KiB, redacted) and the number of redactions.
{
"command": ["curl", "-sS", "--config", "-"],
"stdin": "url = \"https://api.example.com/me\"\nheader = \"Authorization: Bearer {{secret:api}}\""
}http_request
keymitt sends the request itself, through the system curl, and only to hosts the policy allows for every secret used.
| Argument | Type | Notes |
|---|---|---|
method | string | GET (default), HEAD, POST, PUT, PATCH, DELETE, OPTIONS |
url | string | Must not contain placeholders or credentials |
headers | object | Values may contain {{secret:NAME}} |
body | string | May contain {{secret:NAME}} |
timeout_secs | number | Default 30, maximum 300 |
Redirects are not followed. Header names and values are validated, so a line break cannot inject another header, and transport headers (Host, Content-Length, Transfer-Encoding, Connection, …) are refused. The body is limited to 1 MiB. curl is started with --disable, so your ~/.curlrc cannot add options.
Returns status, headers, body (at most 256 KiB), an error if curl failed, and the number of redactions — all redacted.
{
"url": "https://api.github.com/user",
"headers": { "Authorization": "Bearer {{secret:github}}" }
}read_file_redacted
| Argument | Type | Notes |
|---|---|---|
path | string | Absolute, or relative to the server's working directory |
max_bytes | number | Default 262144, maximum 4 MiB |
Reads only below the MCP server's working directory (unless that is your home directory or a filesystem root) and the read_roots you configure. Credential stores and key files are refused, as are FIFOs and devices. Masks the values of all registered secrets, plus anything that looks like a credential: values of keys such as password, secret, token, api_key, client_secret or dsn; private key blocks; passwords inside URLs; and well-known token formats (JWT, GitHub, GitLab, Slack, AWS, Google, npm, OpenAI and Anthropic keys). Refuses binary files. No approval is needed: no secret leaves keymitt.
request_secret
| Argument | Type | Notes |
|---|---|---|
name | string | Suggested name: letters, digits, ., _, - |
description | string | What the secret is |
intended_use | string | Programs or hosts it will be used with |
Returns a keymitt add … command for the agent to show you. You run it in your own terminal; the value is never typed into the chat.