Troubleshooting
Install fails on macOS
macOS ships Python 3.9; keygrant needs 3.10+. Use uv tool install keygrant,
which downloads a suitable Python, rather than pip install.
Claude Code doesn’t see the tools
- Restart Claude Code after
keygrant init: it reads.mcp.jsonat startup. - Check the server starts on its own:
keygrant-mcpshould sit waiting for input (Ctrl+C to quit). “Command not found” means the tool directory isn’t onPATH; use the absolute path fromuv tool dirin.mcp.json. - In Claude Code,
/mcplists connected servers.
The model pastes or prints a value
The value came from somewhere other than keygrant: a .env file the agent read,
or a value in your shell environment. keygrant can only keep values out of
context if they live in keygrant. Move them in with keygrant set, delete the
.env copy, and make sure CLAUDE.md has the guidance block (keygrant init
adds it).
$NAME isn’t expanded on the CLI
keygrant exec runs the command directly, without a shell. Wrap it:
keygrant exec --redact KEY -- sh -c 'echo "$KEY"' # macOS, Linux
keygrant exec --redact KEY -- cmd /c "echo %KEY%" # Windows
“command is longer than 2000 characters”
Long commands can’t be reviewed in a dialog, so they’re refused. Put the logic in a script file, read it, then approve running the script.
The dialog never appears
- Linux: install
zenity. Without it there’s no local dialog and requests are denied (or sent to your phone approver). - Remote sessions: the dialog appears on the machine running the MCP server, which over SSH is the remote host. Use a phone approver.
A request was denied and the agent keeps asking
It shouldn’t: the tool tells it not to retry. If it does, say so in the chat; denial is final for that request either way.
Exit codes
keygrant exec exits with 2 on a usage error, 1 if a secret doesn’t exist
or another error occurs, 3 when access is denied, and otherwise with the
command’s own exit code.
Reporting a bug
Open an issue on GitHub. For anything security-sensitive, see Security instead.