What Is MCP Policy Enforcement (And Why Every Agent Needs It)
MCP policy enforcement intercepts every tool call an AI agent makes over the Model Context Protocol and evaluates it against a set of deterministic rules before the call reaches the server. The result is one of three outcomes: allow, deny, or hold for human approval.
If you run AI agents in production — agents that can send emails, move money, delete records, or modify infrastructure — this is the control layer that decides what they are actually permitted to do. Not what they were prompted to do. What they are allowed to do.
This post explains what MCP policy enforcement is, how it works architecturally, how it differs from other approaches, and when you need it.
What Is MCP (Model Context Protocol)
The Model Context Protocol is an open standard, originally published by Anthropic, that defines how AI agents discover and invoke external tools. An MCP server exposes a set of tools — send_email, create_charge, delete_repository — and an MCP client (the agent) calls them.
MCP is a transport protocol. It defines the shape of the communication: how tools are listed, how arguments are passed, how results come back. It does not define access controls. There is no built-in concept of permissions, rate limits, spend caps, or approval workflows.
The server exposes tools. The agent calls them. Whatever the agent decides to call, the server executes.
The problem: unrestricted tool access by default
When you connect an AI agent to an MCP server, the agent gets access to every tool that server exposes. A Stripe MCP server exposes create_charge, create_refund, delete_customer, and dozens more. A GitHub server exposes delete_repository, create_issue, push_code. A database server exposes execute_query.
There is no permission model. No scoping. No limits.
The agent decides what to call based on its prompt, its reasoning, and whatever context it has accumulated during the session. If the prompt says “process this refund”, the agent calls the refund tool. If the agent hallucinates, misinterprets, or gets manipulated through prompt injection, it calls whatever tool it thinks is appropriate — and the server executes it.
This is the structural gap. The protocol handles communication. Nobody handles authorisation.
What policy enforcement means in this context
MCP policy enforcement fills that gap. A policy enforcement layer sits between the agent and the MCP server. Every tool call passes through it. Every call is evaluated against a policy — a set of rules defined as code — before being forwarded to the server.
The evaluation is rule-based. No LLM in the loop. No probabilistic judgement. The rules are explicit: this tool is allowed with these constraints, this tool is denied, this tool requires human approval when the amount exceeds a threshold.
Every tool call produces one of three outcomes:
- Allow — the call meets all policy constraints and is forwarded to the server.
- Deny — the call violates a rule and is blocked. The agent receives a structured denial with a reason.
- Require approval — the call is held until a human approves or rejects it, with a configurable timeout.
The agent never sees the policy. It cannot reason around it, negotiate with it, or inject past it. The enforcement happens at the transport layer, below the level where the agent operates.
How it differs from other approaches
Several approaches look similar but solve different problems.
Prompt guardrails operate at the input layer. They filter what goes into the model — blocking toxic prompts, enforcing topic boundaries, redacting sensitive data. They do not control what the model does after it decides to act. An agent that passes every prompt filter can still call delete_database if the tool is available.
LLM-as-judge uses a second model to evaluate the first model’s outputs. It is probabilistic by design. It can be fooled by the same adversarial techniques that fool the primary model. It adds latency proportional to inference time. And it cannot enforce stateful constraints like “this agent has already spent $4,800 today against a $5,000 daily limit”.
Observability tools record what happened. They are essential for debugging and auditing. They do not prevent anything. By the time you see the log entry, the tool call has already executed.
API gateways enforce policies on HTTP endpoints — rate limiting, authentication, IP allowlisting. They operate at the API level, not the tool-call level. An MCP server might expose 40 tools over a single connection. An API gateway sees one connection. Policy enforcement sees 40 distinct tools, each with its own rules.
Policy enforcement is preventive, rule-based, tool-granular, and stateful. It is the only approach that answers the question “should this specific agent be allowed to call this specific tool with these specific arguments right now” before the call executes.
MCP Policy Enforcement Architecture
The enforcement architecture is a proxy pattern:
Agent → Policy Enforcement Proxy → MCP Server
The proxy speaks MCP on both sides. To the agent, it looks like an MCP server. To the server, it looks like an MCP client. The proxy intercepts every message in both directions.
On tools/list, the proxy can filter which tools the agent even sees. If a tool is denied by policy, it is removed from the tool list entirely. The agent cannot call a tool it does not know exists.
On tools/call, the proxy evaluates the call against the policy. It checks:
- Is this tool allowed at all?
- Does the call exceed rate limits?
- Do the arguments pass validation rules?
- Does the spend amount exceed per-call or cumulative caps?
- Does this tool require human approval?
If the call passes, it is forwarded. If not, a structured denial is returned to the agent. The server never receives the call.
State is maintained across calls. Rate limit counters, spend totals, and approval decisions persist. This is what makes cumulative constraints possible — you cannot enforce a daily spend cap without tracking what has already been spent.
Properties of Effective Policy Enforcement
Not all policy enforcement is equal. The properties that matter:
Deterministic. The same call with the same state produces the same decision every time. No randomness, no model inference, no temperature parameter. If the policy says the rate limit is 10 calls per hour, call number 11 is denied. Always.
Fail-closed. If the policy engine crashes, calls are blocked — not forwarded. If the policy file is missing, all calls are denied. The safe default is denial, not permission.
Policy-as-code. Policies are defined in version-controlled files, not configured through a UI that only one person has access to. They can be reviewed in pull requests, diffed between environments, and rolled back with a git revert.
Stateful. Enforcement tracks state across calls within a session and across sessions. Rate limits need counters. Spend caps need running totals. Approval workflows need pending-call registries. Stateless evaluation cannot enforce cumulative constraints.
Tool-granular. Rules apply per tool, not per server or per agent. One tool can be allowed freely while another on the same server requires approval. Arguments can be validated per-tool with different constraints.
Transport-layer. Enforcement happens below the application layer. The agent’s framework, model provider, and prompt engineering are irrelevant. Whether the agent runs on Claude, GPT, or a local model, the same policy applies.
MCP Policy Enforcement Example
Here is a YAML policy for an agent that interacts with a financial services MCP server.
version: "1"
default: deny
tools:
# Read operations -- allow freely with rate limiting
get_balance:
rules:
- rate_limit: 60/minute
list_transactions:
rules:
- rate_limit: 30/minute
# Payments -- spend caps and argument validation
create_payment:
rules:
- name: "per-call-cap"
spend:
per_call: 500.00
daily: 5000.00
- name: "validate-currency"
arguments:
currency:
enum: ["GBP", "USD", "EUR"]
# Refunds -- lower limits, stricter rate
create_refund:
rules:
- name: "refund-limits"
spend:
per_call: 100.00
daily: 1000.00
rate_limit: 10/day
on_deny: "Refund limit reached. Escalate to human operator."
# Destructive operations -- human approval required
close_account:
rules:
- name: "require-human"
action: require_approval
approval_timeout: "30m"
on_deny: "Account closure requires human approval"
# Everything else is denied by default.
# The agent cannot call delete_all_records, transfer_to_external,
# or any other tool not listed here.
The default: deny line is the most important. Any tool not explicitly listed is blocked. The agent only has access to the five tools defined in the policy. If the MCP server exposes 50 tools, the agent sees five.
When you need it
Not every agent needs policy enforcement. A local coding assistant that reads files and suggests edits is low-risk. The blast radius of a mistake is limited.
You need policy enforcement when:
The agent handles financial operations. Creating charges, processing refunds, moving funds between accounts. Mistakes cost money.
The agent performs destructive operations. Deleting records, dropping tables, removing repositories, revoking access. Irreversible operations need a gate.
The agent runs in production without human supervision. If no one is watching every tool call in real time, you need rules doing the watching instead.
The agent interacts with third-party services. Sending emails, posting to social media, creating support tickets, modifying CRM records. Actions that affect external systems and real people.
Compliance requires auditability. If you need to prove that an agent operated within defined boundaries — to auditors, regulators, or customers — you need a policy layer that logs every decision with the rule that produced it.
Multiple agents share infrastructure. Different agents should have different permissions. An analytics agent should not have the same tool access as a payments agent. Policy enforcement is how you scope access per agent.
The general rule: if the agent can cause harm that costs more to fix than to prevent, you need enforcement.
Getting started with Intercept
Intercept is the open-source implementation of MCP policy enforcement. It is a single binary that proxies MCP traffic and enforces YAML-defined policies. Apache 2.0 licensed.
# Scan a server to see what tools it exposes
intercept scan -- npx -y @stripe/mcp-server
# Enforce a policy on every tool call
intercept -c policy.yaml -- npx -y @stripe/mcp-server
# Set up policies interactively for all your MCP servers
npx -y @policylayer/intercept init
Pre-built policy templates for 130+ MCP servers are available at policylayer.com/policies.
MCP gave agents a standard way to use tools. Policy enforcement gives operators a standard way to control them. The protocol handles the communication. The policy layer handles the authorisation.
Protect your agent in 30 seconds
Scans your MCP config and generates enforcement policies for every server.
npx -y @policylayer/intercept init