Use Case

Pause your AI agent before it does something it can't undo

Cordon sits between your LLM client and your MCP servers. When an agent calls a tool flagged for approval, the call stops. You see exactly what it's about to do — tool name, arguments, context — and decide whether to let it run.

✓ read_file("schema.sql") allowed ✓ query_database("SELECT ...") allowed   ? APPROVAL REQUIRED Tool : delete_rows Args : { "table": "users", "where": "created_at < '2024-01-01'" } Policy : approve-writes on server "database"   Approve [A] / Deny [D]: _   The agent is paused. Nothing runs until you decide.

The problem with fully automated tool calls

Most MCP setups are binary: a tool is either allowed or blocked. That works for tools you're certain about. It breaks down for tools that are safe in some contexts and dangerous in others.

delete_rows is fine when you're cleaning test data. It's not fine when an agent misread the task and is about to wipe your production users table. An allowlist can't tell the difference. You can.

A human checkpoint costs 10 seconds. It catches the cases a ruleset misses — and it gives you an exact record of what the agent tried to do and why you approved or denied it.

The Cordon model: reads pass automatically. Writes pause for approval. Specific tools you designate as always-block never run at all. You set the policy once; Cordon enforces it on every agent turn.

What human-in-the-loop means in Cordon

The approval is synchronous. Cordon intercepts the tool call at the proxy layer, before it reaches the MCP server. The agent's entire turn is suspended at that point. No tool fires. No result is fabricated. The agent waits.

1️⃣

Agent calls a tool

The agent makes a tools/call request. Cordon intercepts it before the MCP server sees it.

2️⃣

Policy check

Cordon checks the tool against your config. If the action is approve or approve-writes, the call is held.

3️⃣

You see the call

Tool name, all arguments, the policy that triggered. Terminal or Slack — you choose.

4️⃣

You decide

Type A to approve — the tool runs and returns its result. Type D to deny — the agent gets an error and can try a different approach.

Set it up in 3 steps

No Docker. No Kubernetes. Works with Claude Desktop out of the box.

Step 1 — Install
npm install -g @getcordon/cli
Step 2 — Initialize (auto-patches Claude Desktop)
cordon init
Step 3 — Configure approval policy
// cordon.config.ts
import { defineConfig } from '@getcordon/policy';

export default defineConfig({
  servers: [
    {
      name: 'database',
      transport: 'stdio',
      command: 'npx',
      args: ['-y', '@my-org/db-mcp'],
      policy: 'approve-writes',          // reads pass; writes require approval
      tools: {
        drop_table: { action: 'block' }, // this one never runs
      },
    },
  ],
  approvals: {
    channel: 'terminal',                 // or 'slack'
    timeoutMs: 60_000,                   // 60 seconds before auto-deny
  },
  audit: { enabled: true },
});
Run cordon start and restart Claude Desktop. From that point, every write operation your agent attempts arrives in your terminal for a go / no-go before it runs.

Where a human checkpoint earns its place

Database writes

Reads flow freely. Any insert, update, or delete pauses for approval. You see the exact query args before anything changes.

File system access

Let the agent read files without interruption. Block or approve any write — especially useful when an agent might overwrite a config or source file.

External API calls

Reads from an API are fine. Any call that sends data outbound, posts to a webhook, or charges an account waits for a go-ahead.

Infrastructure commands

Shell execution, deployment commands, and infra changes are often irreversible. A five-second approval is cheaper than a rollback.

Email and messaging

Let the agent draft as much as it wants. Any send action pauses so you can read the output before it reaches the recipient.

Multi-agent pipelines

One agent hands off to another. Insert a checkpoint before the hand-off tool fires so a human reviews the intermediate state before the next agent runs.

Cordon vs a typical MCP gateway

As of mid-2026. Enterprise gateways (MCPX/Lunar.dev, Kong, Docker MCP Gateway, Bifrost) enforce automated policy — allow or block against a ruleset, no human in the loop.

Capability Cordon Typical enterprise MCP gateway
Synchronous human approval Agent pauses until you decide Automated policy only
Reads pass automatically approve-writes policy Configurable allow rules
Per-tool block list Named tools can be always-block Rule-based blocking
Call-graph sequence rules Block read → write patterns in one turn Per-tool rules only
Audit log Every call, arg, decision, timestamp Call logging
Install time 2 minutes via npm Kubernetes / Docker deployment
Pricing Free and open source (MIT) Enterprise / contact sales

Comparing Cordon to a specific gateway? See the Cordon vs MCPX breakdown →

FAQ

How do I add human approval before an AI agent runs a tool?

Install Cordon (npm install -g @getcordon/cli), run cordon init to auto-patch Claude Desktop, then set policy: 'approve' or policy: 'approve-writes' in your cordon.config.ts. When the agent calls a matching tool, Cordon shows you the tool name and arguments and waits. Type A to approve or D to deny.

Does the agent actually wait while a human approves?

Yes. The approval is synchronous. Cordon holds the tool call before it reaches the MCP server. The agent's turn is fully suspended — no tool runs, no result is returned — until you respond. The agent then continues from where it paused with the approved or denied result.

Which MCP gateways support human-in-the-loop approvals?

Cordon is the only MCP gateway built around synchronous human-in-the-loop approval. Enterprise gateways (MCPX/Lunar.dev, Kong, Docker MCP Gateway, Bifrost) enforce automated allow/block policies only — there is no mechanism for a human to review and approve a pending tool call in real time.

Can I send approvals to Slack instead of the terminal?

Yes. Set approvals.channel to 'slack' in your config and provide your Slack webhook. When a tool call requires approval, Cordon posts to Slack with the tool name, arguments, and approve/deny controls. The agent waits until a response comes back.

How do I stop an AI agent from dropping database tables?

Two options. Set the tool to always block: tools: { drop_table: { action: 'block' } } — the call is rejected every time. Or set it to approve: tools: { drop_table: { action: 'approve' } } — it pauses so you can decide in context. Block is right when the tool should never run. Approve is right when you occasionally need it but want a checkpoint every time.

Add a human checkpoint to your agent

Free, open source, no Docker required. Two minutes from npm install to your first approval prompt.