Rightshold™ Sign up

Answers · MCP security

How do I require human confirmation (a HITL gate) before MCP write and other side-effecting tools run?

Last updated

TL;DR: Splitting read-only tools from write tools (and lazy-loading schemas) reduces accidents; it does not authorize a write. Put a human-in-the-loop gate in the MCP host or gateway that every side-effecting tools/call must pass: classify write/send/pay/delete/deploy tools on your own allowlist (do not trust readOnlyHint alone), pause before the call, show the person the exact tool name and full arguments (not the model's summary), bind their yes to a hash of those arguments, and refuse if anything changed. The MCP tools specification says there SHOULD always be a human able to deny tool invocations, and that clients SHOULD prompt for confirmation on sensitive operations and show tool inputs before calling the server. OWASP's MCP Security Cheat Sheet says the same: display full parameters, never auto-approve in multi-server setups, and make sure the confirmation UI cannot be bypassed by LLM-crafted responses. Pair the gate with least-privilege credentials and a short-lived approval record outside the agent's session.

What should I check, step by step?

1. Maintain your own write/side-effect allowlist (write, send, pay, delete, deploy, merge, grant). Unannotated or untrusted tools default to side-effecting until proven otherwise by credentials and review.

  1. In the host or gateway, intercept tools/call for those tools before the server runs. Do not rely on the model to 'ask first'.
  2. Render the confirmation from the real tool name and arguments: recipients, paths, amounts, URLs, record ids — escaped for display. Never let a description or chat summary decide what the approver sees.
  3. Hash the canonical arguments (for example RFC 8785 / JCS) and store the hash with the approval. verify (or re-hash) immediately before execution; if the hash differs, require a new confirmation.
  4. Expire approvals quickly (minutes for high-risk writes). Single-use for payments, deletes and production changes.
  5. Keep confirmations on even after a toolset was lazy-loaded or enabled for the session — enablement is not a standing yes for every later call.
  6. Fail closed on timeout or UI errors: no silent auto-approve. Log allow/deny with tool, argument hash, approver and time outside the agent.
  7. Use separate, narrower credentials for write tools so a read-only session cannot call them even if the gate is misconfigured.

Why isn't lazy-loading write tools enough without a confirmation gate?

Withholding write schemas until a task needs them (progressive discovery) shrinks context and reduces accidental selection. The companion guide on separating read-only tools and lazy-loading covers that catalog split.

What does a binding human confirmation for an MCP write look like?

Show the tool name and every argument the server will receive. For money: payee, amount, currency. For messages: channel and full body. For files or tickets: resolved paths or ids.

Which host patterns enforce confirmation before MCP writes?

Claude Code permission rules: put write MCP tools in ask (or deny), evaluated deny → ask → allow, so a broad ask wins over a narrower allow.

What can go wrong?

Confirmations are turned off after the first yes for the session, so later writes skip the person.

How do I ask Rightshold about this (free, no key)?

Add the MCP server https://www.rightshold.com/mcp to Claude, Cursor, ChatGPT, Grok or VS Code, then ask: “Before my agent runs this MCP write tool, ask me to approve the exact tool name and argument hash, expire the yes in 15 minutes, and wait for my decision.”

One-click setup

{
  "tool": "request_human_approval",
  "arguments": {
    "summary": "Allow support-agent to call mcp__tickets__update_ticket status=closed on ticket T-1042",
    "action": {
      "type": "mcp_tools_call",
      "server": "tickets",
      "tool": "update_ticket",
      "arguments_sha256": "<sha256 of canonical args>",
      "ticket_id": "T-1042",
      "status": "closed"
    },
    "expires_in_minutes": 15
  }
}

Rightshold records human approvals and signed run receipts for agents that call it. It does not sit in your MCP host, render your confirmation UI, or stop a client that auto-approves write tools. Enforce the HITL gate in your host or gateway. Not legal advice.

What are the sources?

Related

Not legal advice. JSON · Markdown · All answers

Get a free API key in one call

No card and no email needed. 100 free credits; the license and policy checks stay free without a key.

curl -s -X POST https://www.rightshold.com/v1/accounts/signup -H "Content-Type: application/json" -d '{"accept_terms":true}'
export RIGHTSHOLD_API_KEY=rs_...   # the api_key from the reply (shown once)
curl -s https://www.rightshold.com/v1/licenses/check -H "Authorization: Bearer $RIGHTSHOLD_API_KEY" \
  -H "Content-Type: application/json" -d '{"license":"MIT","intended_use":{"commercial_use":true}}'