Quickstart
1. Install
keygrant needs Python 3.10 or newer. Install it as a standalone tool:
uv tool install keygrant # or: pipx install keygrant
pip install fails there.
uv fetches a suitable Python automatically.Check it works:
keygrant list # prints "(vault empty)" on a fresh install
2. Wire up your project
Run this in the project folder where the agent works:
keygrant init
It does two things, both safe to repeat:
- adds a
keygrantserver to the project’s.mcp.json, keeping any servers already there; - appends a short guidance block to
CLAUDE.mdtelling the model to reference secrets as environment variables and never to ask you to paste one.
3. Store a secret
The value is read from stdin, so it never appears in your shell history or a process list:
echo "sk-test-..." | keygrant set STRIPE_KEY --desc "stripe, test mode"
Paste from the clipboard instead of typing the value:
pbpaste | keygrant set STRIPE_KEY --desc "stripe, test mode" # macOS
Get-Clipboard | keygrant set STRIPE_KEY --desc "stripe, test mode" # Windows PowerShell
xclip -o -selection clipboard | keygrant set STRIPE_KEY # Linux
The description is what the agent sees, so make it useful: which service, which environment, what it may be used for.
4. Use it from Claude Code
Restart Claude Code in that folder so it loads the new MCP server, then ask in plain language:
List the five most recent Stripe charges using STRIPE_KEY.
The model calls exec_with_secrets with a command like
curl https://api.stripe.com/v1/charges -u "$STRIPE_KEY:". A dialog pops up
showing that exact command. Read it, then click Allow (or Yes on
Windows). The output comes back with the key redacted.
Running the identical command again within 15 minutes doesn’t ask again; any different command does. See Approvals and grants.
5. Try it by hand (optional)
You can run the same injection yourself from a terminal. The CLI runs the command directly, not through a shell, so wrap it in one to expand the variable:
keygrant exec --redact STRIPE_KEY -- sh -c 'curl -s https://api.stripe.com/v1/charges -u "$STRIPE_KEY:"'
keygrant exec --redact STRIPE_KEY -- cmd /c "echo %STRIPE_KEY%" # Windows: prints [STRIPE_KEY:REDACTED]
The CLI asks for approval on every run; it never reuses a grant.