← Blog

MCP Gateway Setup: Putting a Governed Proxy in Front of Model Context Protocol Traffic

An MCP gateway sits between agents and the MCP servers they call, centralizing authentication, per-tool-call authorization, egress control, and audit. This guide walks the setup on the streamable HTTP transport: terminate the connection, validate the OAuth token audience, authorize each tools/call against role and arguments, propagate identity to downstream servers, and log every decision. It marks where a local stdio server leaves the reach of a network gateway.

ByParminder Singh· Founder & CEO, DeepInspect Inc.
Platform & Architectureai-securityagentic-aillm-securityidentity-and-authorizationarchitecture
MCP Gateway Setup: Putting a Governed Proxy in Front of Model Context Protocol Traffic

An agent that speaks Model Context Protocol opens a session to an MCP server and then issues tools/call requests, each one an instruction to run a tool that reaches a database, an API, or a filesystem. Run more than one MCP server and more than one agent, and you want a single place to authenticate callers, authorize each tool invocation, constrain where servers can reach, and record what happened. That single place is an MCP gateway. This guide walks the setup on the streamable HTTP transport, which is the transport a network gateway can actually sit on, and marks the line where a local stdio server leaves its reach. It builds on MCP gateway security and the server-side checklist in securing MCP servers in production.

The transport decision comes first

A gateway can only govern traffic it sits on. MCP defines two transports, and the choice determines whether a network gateway is even in the path. The stdio transport runs the MCP server as a local child process and exchanges JSON-RPC over stdin and stdout, so nothing crosses a network and a gateway sees nothing. The streamable HTTP transport exchanges JSON-RPC over HTTP with server-sent events for streaming, and that is the transport a gateway terminates. The first setup step is a policy decision: agents reach MCP servers over HTTP through the gateway, and local stdio servers are treated as a separate trust domain the gateway does not claim to cover.

Step one: terminate the connection and validate the token

The gateway is an OAuth 2.1 resource server in front of the MCP servers. The MCP authorization spec makes the server a resource server that validates access tokens, and the load-bearing check is audience. A token minted for one MCP server must not be accepted by another, or you have built a confused-deputy path. Validate issuer, signature, expiry, and audience on every request:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Bind expected_audience to the specific downstream MCP server the request targets, not to the gateway as a whole. A token scoped to the invoices server reaching the HR server is the failure this check exists to stop.

Step two: authorize each tools/call, not just the session

Authenticating the session answers who connected. It does not answer whether this caller may run this tool with these arguments. MCP authorization is per invocation, because a single session can call any tool the server exposes. Gate every tools/call against the caller role and the concrete arguments:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

The argument-level constraint is the part teams skip. A caller permitted to run read_record is not automatically permitted to read every table, and the gateway is where that line is drawn once for every server behind it.

Step three: propagate identity downstream

A gateway that authenticates the caller and then calls the MCP server with a shared service credential erases the identity it just verified. Downstream servers, and their audit logs, see the gateway rather than the human or agent that made the request. Propagate the verified identity, either as a downstream token exchanged for the caller or as a signed header the servers trust only from the gateway:

[@portabletext/react] Unknown block type "code", specify a component for it in the `components.types` prop

Identity that survives to the data boundary is what makes a downstream audit record name the actor instead of the proxy.

Step four: constrain egress and log every decision

Each MCP server reaches something: a SaaS API, an internal service, a data store. The gateway is the place to allowlist those destinations per server, so a compromised or misbehaving server cannot reach beyond its declared dependencies. And every authorization decision the gateway makes, pass or block, becomes an audit record with the caller identity, the tool, the arguments, and the outcome. That record is the forensic trail when an investigator asks which agent called which tool at which moment. The timing bar is real: Google Mandiant's M-Trends 2026 report put median attacker handoff at 22 seconds, so the decision has to fire inline, before the tool runs, and the log has to commit independently of the server that ran it.

Where the gateway stops

A network MCP gateway governs the streamable HTTP path. It does not see a stdio server running as a local child process, it does not stop a tool from doing something unsafe once the call is authorized and executes on the server, and it does not read a config file that wires an agent to a malicious local server. Those are host-side and server-side problems, covered by the MCP server security guide and supply-chain controls in MCP server supply chain security. The gateway owns the network boundary: who connected, what they are allowed to call, where servers may reach, and what got recorded.

DeepInspect

This is where DeepInspect operates. The setup above describes a governed proxy on MCP traffic, and DeepInspect is a stateless proxy that sits on that HTTP request path between agents and the servers and models they call.

DeepInspect validates the caller identity the application supplies, authorizes each tools/call and each model request against role and content, holds no long-lived downstream credentials, and commits a per-decision audit record before the call proceeds, inline and fail-closed. It is model-agnostic and transport-aware, so the same policy layer covers MCP tool traffic and the LLM calls the same agents make, over HTTP where a network control can actually sit. The stdio trust domain stays out of scope by design, and the guide is honest about that line. Book a demo today.

Frequently asked questions

Can an MCP gateway govern stdio servers?

No. The stdio transport runs the MCP server as a local child process communicating over stdin and stdout, so no network traffic exists for a gateway to terminate or inspect. A network MCP gateway governs the streamable HTTP transport only. If your threat model includes local stdio servers, that is a host-hardening and supply-chain problem addressed by controlling which servers get installed and what they are permitted to execute, not by a network gateway. The clean setup routes agent-to-server traffic over HTTP through the gateway and treats stdio as a separate trust domain.

Why authorize every tools/call instead of the session?

Because a single authenticated MCP session can invoke any tool the server exposes, and different tools carry very different risk. Authenticating the session establishes identity once; authorizing each tools/call decides whether this caller may run this specific tool with these specific arguments. A caller allowed to search documents is not automatically allowed to delete records, and a caller allowed to read public tables is not allowed to read every table. Per-invocation authorization with argument-level constraints is what turns a connected session into a governed one.

How is this different from securing the MCP server itself?

Securing the server hardens the code that runs the tools: input validation, least-privilege service accounts, patching, and safe tool implementations. Setting up a gateway centralizes the controls that belong at the network boundary in front of one or more servers: authentication, per-call authorization, identity propagation, egress allowlisting, and audit. You want both. The gateway gives you one enforcement and logging point across every HTTP MCP server, and server hardening covers what happens inside each server once a call is authorized.

Does the gateway add latency to tool calls?

The gateway adds an authorization decision and a log commit to each call. Token validation, policy evaluation, and record writing are measured in single-digit to low-double-digit milliseconds, which is small against the tool's own work of reaching a database or an API and against the model inference the agent is waiting on, generally 500 milliseconds to several seconds. The decision has to be inline to prevent rather than merely observe, and the overhead of an inline check is invisible relative to the latency the agent already absorbs.