Skip to content

All posts

AIEngineering

MCP gateway vs policy enforcement: what's the difference?

Ritesh Patel

AI: MCP gateway vs policy enforcement: what's the difference?

An MCP gateway is a proxy on the path between an agent and its MCP servers. It routes, logs and can check credentials. Policy enforcement decides allow, deny or hold on each tool call, based on the caller, the tool and its arguments. A gateway can carry enforcement, but sitting in the path does not make it enforce anything.

Checked against the MCP specification revision 2026-07-28 and the Claude Code docs on code.claude.com, fetched 2026-10-29. The settings in this post are the ones those docs describe.

Placement versus decision

The two terms describe different things. A gateway describes where a component sits. Enforcement describes what that component decides. Each one alone leaves a gap. A gateway that sees every call but decides nothing is a logging point. A policy that nothing sits in front of only works if the client obeys it.

The MCP specification draws the same line. Its security overview says that MCP “itself cannot enforce these security principles at the protocol level”, and it asks implementors to build consent and authorization flows themselves. The protocol defines the messages and the rules a server must follow. It does not define a decision point. You place that yourself, and the rest of this post shows where each option can go. For the wider set of controls, see the MCP security pillar.

MCP gateway vs policy enforcement at a glance

MCP gateway Policy enforcement
Main job Route, log and authenticate MCP traffic Decide allow, deny or hold for each tool call
Unit it judges A connection or request One tool call: server, tool name, arguments, caller
Where it runs On the network path to HTTP MCP servers In the client (rules, hooks) or on the server
Stdio servers Out of reach, because they run as local processes Covered by client rules and hooks
Can the developer switch it off? Yes, by pointing the client somewhere else Not when the policy sits in a managed settings source
What it leaves you A record of what ran A refusal before the call runs, with a reason

Read the table by its last two rows. They decide whether you can rely on the control. A gateway that a developer can route around is useful for visibility. A rule that a developer can edit in their own settings is a default, not a control. Both have a place, but they answer different questions.

Where a gateway sees MCP traffic

An MCP client invokes a tool by sending a tools/call request, with the tool name and arguments in params. A gateway on that path can read the message before the server acts on it. That is the first condition for enforcement. The second is that the server is reachable only through the gateway, and the client’s configuration makes sure of that.

Local servers break the first condition. The Claude Code MCP docs say: “Stdio servers run as local processes on your machine.” There is no network hop to intercept. The MCP authorization spec adds that “Implementations using an STDIO transport SHOULD NOT follow this specification, and instead retrieve credentials from the environment”, so the HTTP authorization model does not reach them either.

Model gateways are a different path. Claude Code’s gateway page lists what a gateway provides: credentials, usage tracking, cost controls and audit logging, where the log covers “every model request”. That record shows what the model asked for. It does not, by itself, show that an MCP server ran the call.

Where policy enforcement runs

Enforcement has three possible homes: the client, the server, and a gateway between them. In the client, Claude Code’s permission rules and hooks decide before a call runs. A deny rule for one MCP tool uses the form mcp__<server>__<tool>, and a PreToolUse hook can return a deny decision with a reason.

On the server, the spec places access control. Its tools security section lists server duties: validate all tool inputs, implement proper access controls, rate limit tool invocations and sanitize tool outputs. HTTP servers also have to check that each access token was issued for them as the intended audience. Invalid or expired tokens get an HTTP 401.

A gateway is the third home. It gives you one checkpoint in front of HTTP servers. It does not remove the server’s duty. The spec says MCP servers “MUST NOT accept or transit any other tokens”, so a gateway in front of a server still leaves the token check with that server.

Steps: place the control on each path

  1. List every path an agent uses to reach a tool: local stdio servers, HTTP servers, direct API calls from code, and shell commands.
  2. Mark the paths that pass through a gateway. Every other path is covered only by client rules, hooks and the server’s own checks.
  3. Put the server allowlist in a managed source, with allowManagedMcpServersOnly set to true. The example below is from the managed MCP docs. Replace the example URLs with your own servers. The restrict-servers post covers the match rules in full.
{
  "allowManagedMcpServersOnly": true,
  "allowedMcpServers": [
    { "serverUrl": "https://api.githubcopilot.com/*" },
    { "serverUrl": "https://*.internal.example.com/*" }
  ]
}
  1. Add deny rules for individual tools that you must block on every server. Use the mcp__<server>__<tool> form. The example below uses a placeholder tool name.
{
  "permissions": {
    "deny": [
      "mcp__github__delete_repository"
    ]
  }
}
  1. For each HTTP server, confirm it rejects an access token issued for a different audience with an HTTP 401. A gateway in front of the server does not replace this check.
  2. Log each decision in a store the developer cannot edit. The audit post covers the Claude Code signals to use.
  3. Test each rule from a managed test machine. Call one blocked server and one blocked tool, and confirm that both are refused.

Gotchas in the fine print

The docs’ fine print changes what a rule does.

  • An unset allowlist is not an empty one. Leave allowedMcpServers unset and every server is allowed. Set it to an empty array and no server is allowed, except those that skip the check.
  • An allowlist alone is a default. Without allowManagedMcpServersOnly, allowlists from user and project settings merge in, so a developer can broaden what you allowed.
  • A serverName entry is a label, not a control. Any user can name a server github. Match on serverCommand or serverUrl to control what actually runs.
  • A deny rule matches the name a server is registered under. The same endpoint registered as github2 produces mcp__github2__... tools, which the mcp__github__... rule does not match. Pin the server names in managed-mcp.json and deny each fixed server and tool pair, or enforce the operation at the gateway.
  • A failing hook does not block by default. A non-blocking error lets the action go ahead, unless the hook’s failure is set to block.

Enforcing this with AIControls

AIControls covers the model path and the identity layer. Its confirmed capabilities are: Claude Code through the gateway, in the CLI and in VS Code; per-user tokens; per-user and per-session cost and budget limits; PII held for approval, redacted or blocked; and identity provider integration for Cross App Access (XAA). Check those against your requirements first, and ask any vendor, including us, which layer each claim covers. The buyer’s guide lists the questions to ask. The product page is at AIControls.

Frequently asked questions

Is an MCP gateway the same thing as policy enforcement?

No. A gateway is where traffic passes: a proxy in front of MCP servers that can route, authenticate and log requests. Policy enforcement is the decision on each tool call. It can run in the gateway, in the client's permission rules and hooks, or on the server. A gateway that only logs gives you a record after the call has run. Enforcement has to refuse the call before it runs, from a layer the developer cannot switch off.

Do I still need a gateway if Claude Code has managed settings?

Not always. Managed settings can limit which MCP servers load and deny individual tools, and those rules apply on the developer's machine. A gateway adds one checkpoint for HTTP servers, central logs and a place for server-side checks. Stdio servers run as local processes, so a gateway in the network path does not see them. Decide per path: client rules cover local servers, and a gateway covers the HTTP traffic that is routed through it.

Does a deny rule still block a call when a PreToolUse hook returns allow?

Yes. Claude Code evaluates deny and ask rules whatever a PreToolUse hook returns, so a matching deny rule blocks the call. A hook that exits with code 2 blocks the call. An allow rule cannot carve an exception out of a deny rule. Confirm the order in your own settings with a test call before you rely on it.

What happens if my enforcement hook fails?

By default the action goes ahead. The hooks reference says that a non-blocking error, such as a hook that does not start or prints invalid JSON, lets the action continue. The exception is a hook whose failure is set to block. Test the failure path on purpose by stopping the script and checking that the call is refused. Only then count the hook as a control.

Can a developer turn off an MCP allowlist that comes from managed settings?

Not when allowManagedMcpServersOnly is true in a managed settings source. Without that flag, allowlists from user and project settings merge in, so a developer can broaden your list. Denylists merge from every scope, so a developer can always block more for themselves. Put the allowlist in a managed source, then check on a test machine that an unlisted server is refused.

Ritesh Patel, Founder & VP Product, Nirmata

Ritesh Patel is a founder of Nirmata and leads its products. He writes about governing AI coding agents, MCP security and Kubernetes policy as code.

LinkedIn

Govern AI agents with AIControlsControl what AI agents do, and prove it.
ShareXLinkedIn

Stay up-to-date with the latest in AI, governance, and infrastructure

Subscribe to our free monthly newsletter to get industry news, DevOps tips, and articles right to your inbox on Kyverno, containerization, Kubernetes deployment & management and more.