Intercept is an open-source proxy between AI agents and MCP servers. It enforces YAML-defined policies on every tool call: rate limits, spend caps, access controls, argument validation, human-in-the-loop approval. The call passes, gets held for approval, or gets blocked.
See every tool your AI agent has access to, before adding any rules:
npx -y @policylayer/intercept scan -- npx -y @modelcontextprotocol/server-githubConnects to the server, discovers all tools, and shows the full attack surface. Add a policy to lock it down.
| System prompt | Intercept | |
|---|---|---|
| Enforcement | Probabilistic | Deterministic, blocked at transport layer |
| Bypassable | Injection, reasoning, context overflow | Agent never sees the rules |
| Stateful | No memory of previous calls | Counters, spend tracking, sliding windows |
| Auditable | No structured log | Every decision logged (deny/approval includes reason) |
| Latency | N/A | Sub-millisecond per evaluation (p95) |
Prompts tell the agent what it should do. Intercept defines what it is allowed to do.
- Block tool calls. Deny dangerous tools unconditionally (e.g.
delete_repository) - Validate arguments. Enforce constraints on tool arguments (
amount <= 500,currency in [usd, eur]) - Rate limit. Cap calls per minute, hour, or day with
rate_limit: 5/hourshorthand - Track spend. Stateful counters with dynamic increments (e.g. sum
args.amountacross calls) - Hide tools. Strip tools from
tools/listso the agent never sees them, saving context window tokens - Require approval. Hold tool calls for human approval via CLI or admin API (
--enable-admin-api) before execution - Idempotent enforcement. Prevent duplicate actions from agent retries with
idempotency_window: 5m - Default deny. Allowlist mode where only explicitly listed tools are permitted
- Hot reload. Edit the policy file while running; changes apply immediately without restart
- Validate policies.
intercept validate -c policy.yamlcatches errors before deployment
It drained a $230,000 treasury in six minutes
create_refund:
rules:
- name: "cap-refunds"
rate_limit: "10/day"
on_deny: "Daily refund limit reached"It deleted a production config
delete_file:
rules:
- name: "block-delete"
action: deny
on_deny: "File deletion blocked by policy"It provisioned infrastructure in a retry loop
create_resource:
rules:
- name: "limit-resource-creation"
rate_limit: "10/hour"
on_deny: "Resource creation rate limit reached"It issued a $4,200 refund without asking anyone
create_refund:
rules:
- name: "large-refund-approval"
action: require_approval
conditions:
- path: "args.amount"
op: "gt"
value: 100000
on_deny: "Refunds over $1,000.00 require human approval"
approval_timeout: "30m"It emailed 400,000 customers a test template
messages_send:
rules:
- name: "limit-sends"
rate_limit: "5/hour"
on_deny: "Email send rate limit reached"349 ready-made policy templates
npx -y @policylayer/interceptOr install permanently:
npm install -g @policylayer/intercept # npm
go install github.com/policylayer/intercept@latest # GoPre-built binaries available on GitHub Releases.
1. Generate a policy scaffold from a running MCP server:
intercept scan -o policy.yaml -- npx -y @modelcontextprotocol/server-stripeConnects to the server, discovers all tools, and writes a commented YAML file listing each tool with its parameters.
2. Edit the policy to add rules:
version: "1"
description: "Stripe MCP server policies"
hide:
- delete_customer
- delete_product
- delete_invoice
tools:
create_charge:
rules:
- name: "max single charge"
conditions:
- path: "args.amount"
op: "lte"
value: 50000
on_deny: "Single charge cannot exceed $500.00"
- name: "daily spend cap"
conditions:
- path: "state.create_charge.daily_spend"
op: "lte"
value: 1000000
on_deny: "Daily spending cap of $10,000.00 reached"
state:
counter: "daily_spend"
window: "day"
increment_from: "args.amount"
- name: "allowed currencies"
conditions:
- path: "args.currency"
op: "in"
value: ["usd", "eur"]
on_deny: "Only USD and EUR charges are permitted"
create_refund:
rules:
- name: "refund limit"
rate_limit: 10/day
on_deny: "Daily refund limit (10) reached"3. Run the proxy:
intercept -c policy.yaml --upstream https://mcp.stripe.com --header "Authorization: Bearer sk_live_..."Hidden tools are stripped from the agent's view. Everything else is evaluated against your policy.
The policies/ directory contains scaffolds for 349 MCP servers including GitHub, Stripe, AWS, Notion, and Slack. Each file lists every tool with its description, grouped by risk category.
Copy one as a starting point:
cp policies/stripe.yaml policy.yaml
# edit to add your rules, then:
intercept -c policy.yaml --upstream https://mcp.stripe.comBrowse all policies: policies/
To use Intercept with Claude Code (or any MCP client that reads .mcp.json), point the server command at Intercept:
{
"mcpServers": {
"github": {
"command": "intercept",
"args": [
"-c", "/path/to/policy.yaml",
"--",
"npx", "-y", "@modelcontextprotocol/server-github"
],
"env": {
"GITHUB_PERSONAL_ACCESS_TOKEN": "..."
}
}
}
}For remote HTTP servers, use --upstream instead of a command:
{
"mcpServers": {
"stripe": {
"command": "intercept",
"args": [
"-c", "/path/to/policy.yaml",
"--upstream", "https://mcp.stripe.com",
"--header", "Authorization: Bearer tok"
]
}
}
}Rate limits and counters persist across restarts. SQLite is the default (zero config). Redis is supported for multi-instance deployments:
intercept -c policy.yaml --state-dsn redis://localhost:6379 --upstream https://mcp.stripe.comIntercept governs tool calls that pass through the proxy. It does not govern:
- Direct API calls or HTTP requests the agent makes outside the MCP path
- Model reasoning, prompt content, or response generation
- Actions taken by tools after they receive the forwarded call
If a tool call is routed through Intercept, enforcement is hard: the call is physically blocked before reaching upstream. If traffic bypasses the proxy, Intercept has no visibility.
- CLI reference: all commands, flags, transport modes, state backends, event logging
- Policy reference: YAML format, conditions, operators, stateful counters, examples
- Example policies: ready-made scaffolds for 349 MCP servers
Contributions welcome. Open an issue to discuss what you'd like to change.
make build # build binary -> dist/
make test # go test ./...
make lint # golangci-lint (skips if not installed)Key packages: internal/engine/ (rule evaluation), internal/proxy/ (request handler), internal/state/ (counters and persistence), internal/transport/ (stdio, SSE, HTTP), internal/approvals/ (approval store and fingerprinting).
