Intercept -- Policy Enforcement for MCP Tool Calls | PolicyLayer

7 min read Original article ↗

stripe.create_refund aws.tf_destroy github.delete_repository postgres.drop_table gmail.batchDelete kubectl.delete cloudflare.update_dns_record stripe.cancel_subscription mongo.drop_database drive.emptyTrash aws.delete_resource pagerduty.delete_team stripe.create_refund aws.tf_destroy github.delete_repository postgres.drop_table gmail.batchDelete kubectl.delete cloudflare.update_dns_record stripe.cancel_subscription mongo.drop_database drive.emptyTrash aws.delete_resource pagerduty.delete_team

OPEN SOURCE · MCP ENFORCEMENT LAYER

Run agents in production.
Keep complete control.

DENY It drained a $230,000 treasury in six minutes.

DENY It emailed 400,000 customers a test template.

AWAIT A $4,200 refund was held for approval before processing.

Intercept gives your team hard limits over every MCP tool call. Rate limits, spend caps, approval workflows, access controls, audit logs. One YAML file. No agent changes.

npx -y @policylayer/intercept

go install github.com/policylayer/intercept@latest

// THE DIFFERENCE

Same agent. Same tools. One has a policy file.

Nine tool calls in nine seconds. On the left, everything goes through. On the right, Intercept is running.

00:00create_refund$2,500ALLOW

00:01drop_tableusersALLOW

00:02delete_repositoryprod-apiALLOW

00:03send_emailall_customersALLOW

00:04terminate_instancesi-09f3a*ALLOW

00:05push_filesmainALLOW

00:06list_issuesmy-org/apiALLOW

00:07list_customersALLOW

00:08retrieve_balanceALLOW

$2,500 refunded. 1 table dropped. 1 repo deleted. 400,000 emails sent. 1 instance terminated. No limit hit. Everything went through.

00:00create_refund$2,500AWAIT

00:01drop_tableusersDENY

00:02delete_repositoryprod-apiDENY

00:03send_emailall_customersDENY

00:04terminate_instancesi-09f3a*DENY

00:05push_filesmainDENY

00:06list_issuesmy-org/apiALLOW

00:07list_customersALLOW

00:08retrieve_balanceALLOW

$0 refunded without approval. 0 tables dropped. 0 repos deleted. 0 emails sent. 0 instances terminated. 3 reads allowed. 5 blocked. 1 held for approval.

// THE GAP

MCP servers expose tools. The limits are your job.

There's no built-in way to make tools read-only, cap spend, require approval, or stop a runaway loop. You have to define that yourself.

You can't cap daily refunds or rate limit by default. Every call goes through.

POSTGRES

32

tools exposed

DENY

No read-only mode. Every tool can write. You can't restrict queries to specific schemas out of the box.

No built-in retry limits or resource caps. A loop runs until you notice.

// HOW IT WORKS

Every tool call is checked before it runs.

Intercept sits between your agent and the MCP server. Every tool call is evaluated against your policy file before execution -- then allowed, denied, held for approval, or logged.

create_refund $52,000

DENY

Daily refund cap (10/day)

terminate_instances i-09f3a*

DENY

Tool blocked (deny-by-default)

drop_table users

DENY

Table not in allow-list

send_email to: all_customers

DENY

Recipient cap (50/batch)

create_refund $4,200

AWAIT

Requires approval (amount > $100)

list_issues repo: my-org/api

ALLOW

Read-only, within limits

// ENFORCEMENT, NOT PROMPTS

SYSTEM PROMPTS

Ask the agent to behave.

You can't enforce a rate limit with a prompt.

You can't make a tool read-only with a prompt.

You can't cap spend with a prompt.

You can't require human approval with a prompt.

There's no audit trail.

INTERCEPT

Define what it is allowed to do.

Rate limits that actually enforce.

Tools that are genuinely read-only.

Spend caps with hard cutoffs.

Approval workflows with one-time-use controls.

Every decision logged automatically.

// CONFIGURATION

One YAML file. That's it.

Commit it to your repo. Deploy it with your agent. The file is the policy.

version: "1"
default: deny

hide:
  - delete_repository
  - merge_pull_request

tools:
  create_refund:
    rules:
      - name: "daily cap"
        rate_limit: 10/day

  issue_refund:
    rules:
      - name: "large refunds"
        action: require_approval
        approval_timeout: 10m

  write_file:
    rules:
      - name: "safe paths"
        conditions:
          - path: "args.path"
            op: "regex"
            value: "^/app/src/"

default: deny

Every tool is blocked until you explicitly allow it. New tools added upstream don't automatically reach the agent.

hide:

Removed from the agent's context entirely -- no schema, no description, no token cost.

rate_limit: 10/day

Shared counter across all agent instances. Hard cutoff, not a suggestion.

op: "regex"

Scope any tool to a subset of what it can do -- specific paths, regions, table names, account IDs.

action: require_approval

Holds the call for human approval. The agent is told to wait. One-time use -- the approval is consumed after a single successful call.

idempotency_window: "5m"

If the same call succeeds, retries within 5 minutes skip policy evaluation. Prevents double dispatch, double charge, double anything.

// SETUP

Scan, generate, and enforce in minutes.

No architecture changes. One line in your MCP config.

01

Scan

See which tools can write, delete, spend, or execute before your agent uses them.

intercept scan -o policy.yaml \
  -- npx -y @stripe/mcp-server

02

Generate policy

Start from a generated policy, then tighten it for your use case. Add rate limits, approval rules, and access controls in YAML. Commit it to your repo.

03

Enforce

Run Intercept in front of the MCP server. Every call is checked before execution and every decision is logged.

intercept -c policy.yaml \
  -- npx -y @stripe/mcp-server

// PROPERTIES

Built for production, not demos.

Invisible until a limit is hit. Completely transparent about why when one is.

Fail-closed

If Intercept goes down, nothing runs. Your agent doesn't get a free pass.

Hot reload

Push a policy change without restarting. Useful when you're tightening limits mid-incident.

Sub-ms evaluation

Policy checks run in-process. No network calls. No latency hit. Your agent doesn't know it's there.

Audit trail

Every tool call logged: what was called, what the decision was, what rule fired. Reconstruct exactly what happened.

Single binary

One Go binary. No runtime. No dependencies. Runs on anything.

Human-in-the-loop

Hold sensitive actions for human approval. One-time use, fingerprinted, audited, with optional webhook notifications.

Idempotent enforcement

Prevent duplicate actions from agent retries. Same call within the window skips re-evaluation and counter increments.

// POLICIES

Policies for the tools you already use.

Generate a starting policy from your MCP setup. Tighten the rules. Carry the same file from development into production.

Stripe

27 tools

Payments, refunds, subscriptions, customers.

VIEW POLICY →

AWS

55 tools

S3, Lambda, DynamoDB, EC2, infrastructure.

VIEW POLICY →

Supabase

32 tools

Postgres, edge functions, storage, auth.

VIEW POLICY →

PagerDuty

62 tools

Incidents, on-call, alerts, escalations.

VIEW POLICY →

// FAQ

Questions.

What is Intercept? +

An open-source MCP proxy that enforces policy on tool calls before they execute. Intercept lets you scan risk, generate a YAML policy, and block dangerous actions or hold them for human approval without changing your agent. One line change in your MCP config.

What can I limit? +

Tool access, spend, call volume, arguments, paths, and destructive actions. Block tools entirely. Rate limit by minute, hour, or day. Cap cumulative spend. Restrict which paths a file tool can write to, which regions AWS can touch, which tables a database tool can modify. Require human approval for sensitive actions like high-value refunds, PR merges, or infrastructure changes. Prevent duplicate actions from agent retries with idempotency windows. Start with deny-by-default and open up from there.

Do I need to change my agent? +

No. One line change in your MCP config. The agent sees the same tools and the same schemas. Nothing looks different until a limit is hit -- then the call is blocked and logged.

How is this different from system prompts? +

Prompts tell the agent what it should do. Intercept defines what it is allowed to do. A prompt is a best-effort instruction. A policy is a hard limit. You can't cap spend with a prompt. You can't make a tool genuinely read-only with a prompt. With Intercept, either the call is within policy or it isn't. No probability involved.

How does approval work? +

Add action: require_approval to any rule. When the agent triggers it, the call is held and the agent is told to wait. A human approves or denies via the CLI (intercept approvals approve <id>) or a local HTTP API. After approval, the agent retries and the call goes through exactly once. Different arguments require a new approval.

policylayer/intercept

Scan the risk.
Ship the agent.

See your exposed tools, generate a policy, and enforce hard limits in minutes. Open source.

npx -y @policylayer/intercept

github.com/policylayer/intercept →