For teams running agents with MCP tools
The control that stays on your machine.
Holdcall sits between your agent and its MCP servers. It decides every tool call where the call happens, shows you the real arguments before anything dangerous runs, and keeps a record you can verify offline. The arguments never leave the machine. Neither does the decision.
| # | when | agent | connector | tool | decision | what happened |
|---|---|---|---|---|---|---|
| 6 | 20:29:45 | claude-code | github | add | allow | forwarded, answered in 63 ms |
| 8 | 20:29:45 | claude-code | github | echo | allow | forwarded, answered in 1 ms |
| 10 | 20:29:45 | claude-code | github | explode | deny | a rule denies this tool; the server never saw it |
| 11 | 20:29:45 | claude-code | github | add | allow | forwarded |
| 13 | 20:29:45 | claude-code | github | add | allow | forwarded, third of three allowed |
| 15 | 20:29:45 | claude-code | github | add | deny | budget of 3 calls spent this session |
| 16 | 20:29:47 | claude-code | github | dangerous_tool | rejected | held for a human, who read the arguments and said no |
Decides on the machine
Rules that deny, allow, or hold a tool for a human, scoped to an agent and a connector. Budgets that cap how many calls a session may make. Every way of not getting a decision is a denial: no daemon, no decision, no call.
Approves with the real arguments
A held call waits until someone runs holdcall approve and reads exactly what the server would receive, every byte shown as itself. Never a summary, never text the model wrote about the call.
Records what you can verify
Each call, decision and policy change is one entry in a hash-chained journal on disk. holdcall verify checks it without a network, and the format is documented so a second program can check it too.
The moment that matters
The agent asked to run dangerous_tool on a release branch, with force. The rule for that tool says ask. Holdcall held the call, the operator read the arguments and rejected it, and the agent was told so in words it does not retry.
The daemon wrote the rejection to the journal before the relay was told. The server never received the call.
$ holdcall approve id 483e0508febce5dcc97fb26becf27180-7 age 2s agent claude-code connector github tool dangerous_tool arguments: { "branch": "release/2026-09", "force": true } $ holdcall reject 483e0508febce5dcc97fb26becf27180-7 --reason "not that branch" rejected dangerous_tool for agent claude-code on connector github (recorded in the journal) reason: not that branch
what the agent received
A human reviewing this call's real arguments rejected it. Do not retry automatically.How it fits
- Your clientClaude Code, Cursor, Claude Desktop. Pointed at Holdcall by
holdcall init. - holdcall serveRelays every byte unchanged. A
tools/callis decided before it is forwarded. - Your MCP serverReceives exactly what the client sent, or nothing.
Under the relay, one daemon per user decides against rules and budgets in SQLite, keeps credentials in the OS store bound to one command, and writes the journal. It answers only to processes that are Holdcall, and it works with no network. The agent's identity is derived from the executable that spawned the relay, as the kernel reports it; nothing on the wire can claim to be Claude Code.

What it does not promise
- Not tamper-proof
- The chain has no key. Anyone who can write the journal file can rewrite it and it will verify. What turns the record into evidence is
holdcall verify --expect-headagainst a head you recorded somewhere else. We do not use the words audit log. - Verified on macOS
- Linux and Windows are compiled and vetted, not yet run. The status page says which claims hold on which platform, per test.
- Rules match names, not arguments
- A rule is keyed on agent, connector and tool. Conditions on what a call carries are not built; a human reading the arguments is how that gap is covered today.
- 414tests, run with the race detector on every change
- 56attacks tried against real builds, 23 of them live before they were closed
- 23guarantees, each citing the tests that hold it
- 29findings published, 2 still open
All of it is on the status page, which refuses to build on a claim without a test behind it.
Early access
The engine is free for one person and one machine, and always will be. The team console, with the journal of every machine, policy in one place and approvals from your phone, opens to a small group first.