// field note · patterns

Human-in-the-loop for MCP tool calls

"Put a human in the loop" is easy to say and easy to do badly. Gate every call and you build an approve-everything wall that trains people to click "yes" without reading — worse than no gate. The skill is gating the small dangerous subset and letting everything else flow. Here's how to decide, and where the checkpoint has to live.

THE SHORT VERSION

What "human-in-the-loop" should mean

The failure mode isn't too little oversight — it's oversight applied indiscriminately. If your agent asks a human to approve every list_files and search_records, two things happen: the workflow slows to a crawl, and the human, buried in trivial prompts, stops reading them. When the one dangerous call finally appears — the drop-database, the send, the refund — it looks exactly like the hundred harmless ones before it, and it gets the same reflexive "yes."

An approval wall that gets rubber-stamped is a false sense of safety, not safety.

Real human-in-the-loop is selective: the system does the triage, and the human only sees the calls where their judgment actually changes the outcome. That means the hard part isn't the approval UI — it's the classification.

The three questions that decide whether to gate a call

Run any tool call through those three and you get a risk tier — which maps cleanly onto three modes.

Risk-tiered gating: log, gate, block

ModeForBehavior
logReads; reversible low-stakes writesPass through, record it. Zero friction. Start here to see what your agent actually does.
gateMutating & irreversible calls; high blast radiusPause for a human. Show the impact. Wait for yes/no. This is the checkpoint.
blockDestructive actions in unattended/locked-down runsRefuse outright — no human needed. For environments where the answer is always "no."

The point is that a single agent doesn't get one blanket policy — each class of action gets the mode that fits it. Reads flow, the refund waits for a person, and in a nightly unattended job the destructive tools are simply blocked.

Where the checkpoint has to live

Here's the part that's easy to get wrong: the checkpoint cannot be an instruction in the prompt. "Ask me before doing anything destructive" is a request the model may forget, misjudge, or be argued out of by a cleverly-worded input — the same reason a code-freeze instruction didn't stop an agent from deleting a production database. Enforcement has to be deterministic and outside the model.

For MCP agents, that place already exists: the tools/call boundary. A proxy sitting between the MCP client and the MCP server sees every call on the wire and can:

Because it's deterministic and off to the side, the agent can't reason its way past it — it isn't asking the model for permission, it's asking a person.

The approval UX that doesn't train rubber-stamping

Two rules keep the human's judgment sharp:

Gate rarely. If approvals are frequent, they're being over-applied — tighten the classification so only genuinely consequential calls surface. A person who's asked once an hour reads carefully; a person asked every ten seconds does not.

Show the consequence, not a question. "Approve?" is uninformative. "This will delete the customers table (irreversible — no backup captured)" or "This will refund $2,300 to card ***12 — a new transaction, fees not returned" gives the human the one thing they need: what actually happens if they say yes. A good impact diff also flags the irreversible steps before approval, so the honest limit is visible up front — compensation is not undo.

The whole idea in one line: a good human-in-the-loop system does the triage so the human doesn't have to — surfacing the few calls where a person's "no" prevents something that can't be taken back, and getting out of the way for everything else.

This is exactly what the field guide grades

Every profile in our MCP field guide is really an answer to "which calls on this server deserve a gate?" — the read-only servers where a checkpoint is ceremony, the write-capable databases where a DROP needs a human, the payment surfaces where money can't be un-moved, the browser tools where the same click is harmless or catastrophic depending on the page. Same three questions, one server at a time.

FAQ

How do you add a human in the loop to an AI agent?
Put a deterministic checkpoint at the tool boundary — where the agent's decision becomes a real action — not in the prompt. Intercept the call, classify its risk, and require approval only for mutating and irreversible calls while letting reads pass. The checkpoint must live outside the model, or the agent can talk its way around it.
How do you avoid approval fatigue?
Gate only what can hurt — destructive, irreversible, or high-blast-radius actions — and pass read-only and easily-reversible calls straight through. Show an impact diff so the person approves a specific consequence, not a vague yes/no. Frequent approvals are a sign the classification is too broad.
Why not just tell the model to ask before dangerous actions?
Because an instruction in a prompt is a request a probabilistic model can forget, misjudge, or be argued out of — the same failure that let an agent delete a production database during a code freeze. Enforcement has to be deterministic and outside the model, at the tool boundary.

Gate the dangerous subset, ship the rest

ChronoMCP is a proxy that does exactly this at the MCP boundary — classify, gate, and record, with reads flowing through. Free CLI, MIT.

Read the quickstart → See the field guide