MCP is a connectivity protocol: it tells a model how to discover and call tools. As our CEO argued, it was never designed to be a security boundary. Once an agent holds a token for GitHub or Linear, it can call every tool that token allows, and the server sees the token, not the employee who started the agent.

What is an MCP gateway?

An MCP gateway is a proxy between MCP clients (Claude, ChatGPT, Claude Code, Codex, Cursor) and the MCP servers they call. Clients connect to the gateway instead of the server. The gateway checks who is calling, decides whether each tool call is allowed, adds the credential the server expects and logs the call. You’ll also see it called an MCP proxy or MCP firewall.

In Formal, the MCP gateway runs on the Connector, the reverse proxy you deploy in your VPC. Each server you add to the Catalog gets its own address, such as https://linear.<connector-hostname>/mcp. Policies see the MCP method, the tool name and its parameters, not just an HTTPS request to a host.

On laptops, a network rule lets the Formal Endpoint forward MCP traffic from AI agents to the same gateway and add the user’s identity, so people keep the server’s original URL. The gateway covers remote MCP servers reached over HTTPS. It doesn’t cover local servers that a client starts as a subprocess over stdio.

What MCP security risks does a gateway address?

Most MCP server security problems come down to authentication and authorization: an agent acts with more access than the task needs, and nobody can say afterwards who asked for it. The MCP specification’s security best practices cover protocol-level attacks such as confused deputy and token passthrough. A gateway handles the access side:

  • Over-broad tokens. A GitHub token that can create pull requests can usually merge them too. A tool-level policy allows the PR and blocks the merge, the case our CISO walked through in the permission pitfall of MCP.
  • Prompt injection through tool output. A malicious issue can tell the agent to call another tool. The gateway can’t read intent, but the injected instruction only reaches the tools the policy allows.
  • Tokens on laptops. With linked accounts or shared credentials, the upstream credential stays with Formal.
  • Unapproved servers. The Endpoint flags or blocks MCP servers outside your Catalog.
  • No audit trail. Every call through the gateway is logged with the user, server and tool.

Here’s the catch: MCP tool poisoning hides instructions in a tool’s description, and Formal’s MCP policy fields describe tool calls (method, tool name, parameters), not descriptions. What limits a poisoned tool is reviewing a server before it enters the Catalog and allowing only the tools the job needs.

MCP authentication and authorization: how do clients sign in?

Authentication happens on two sides, configured separately. Downstream, the client proves to the Connector who the user is, with Formal OAuth or with identity headers added by the Endpoint. Upstream, the Connector sends the MCP server the credential it expects. Formal uses the downstream identity for policies, logs and picking the upstream credential.

With Formal OAuth, the Connector acts as an OAuth protected resource, as the MCP authorization specification describes. It accepts public clients that use PKCE S256 and a Client ID Metadata Document, and doesn’t support Dynamic Client Registration: DCR-only clients go through the Endpoint instead. Policies can also check which OAuth client is acting, for example to allow only clients you pre-registered.

Upstream, you pick one of three options per server:

  • Linked accounts: each user links their own account once. Formal stores the OAuth token encrypted and refreshes it when the server supports refresh.
  • Shared credentials: one API key or service account token, stored as a native user. Selection rules can send different credentials to different people.
  • Pass through: the client’s own credential goes upstream unchanged, so Formal can attribute the call only when it comes through the Endpoint. These servers get no Connector address.

How do you control which MCP tools each person can call?

Each Catalog server’s Access Controls set who can use it and which tools they can call, and Formal saves them as a policy named MCP access controls: <server-name>. The Connector blocks requests from anyone outside the allowed users and groups, and blocks tools/call for tools outside the list. Clients may still list those tools, but calls fail with the block message.

That’s MCP access control at the tool level, not just on or off per server. For rules the tab doesn’t cover, write a policy in Rego on the tool name and parameters. At the request stage, a policy can allow, block or rewrite the call before the server sees it.

MCP governance: approved servers, shadow MCP and access requests

MCP governance starts with a list of what’s approved. The Catalog is your private registry of MCP servers and skills, and it lives in the shared control plane with policies and logs. Employees use it at catalog.formal.ai to browse servers, follow setup steps for their client, link accounts and request access.

Servers outside the Catalog fall to Guardrails, which allow and log them for review or block them with a list of approved alternatives. Only the Endpoint sees servers with no Formal Resource, so Guardrails apply on devices running it in Transparent Mode. Finding those servers in the first place is covered on shadow AI detection.

Access Requests close the loop. An employee can ask for a new server, for access to one in the Catalog, or for a one-time, time-bound (30 minutes to 7 days) or permanent exception to a policy that blocked them. An admin approves in the Control Plane, and Formal applies the change.

Which MCP clients work with the gateway?

Client runsConnects to
In the vendor’s cloud: Claude, ChatGPT, Dots, Cursor Cloud Agents, Grok BotThe server’s Connector address
On a device with the Formal EndpointThe server’s original URL, such as https://mcp.linear.app/mcp
On a device without the EndpointThe server’s Connector address

For Claude and ChatGPT, an admin adds each server once with the Add to Claude or Add to ChatGPT button in the Catalog. These apps call MCP servers from Anthropic’s and OpenAI’s clouds, so the Connector’s listener must be reachable from the internet, and the Endpoint never sees those calls. Claude Code and Codex connect with claude mcp add or codex mcp add, and Cursor Cloud Agents take the Connector address as a custom MCP server. One gateway covers cloud apps and laptop agents with the same policies and logs.

MCP audit logging: what does each tool call record?

Every tool call through the gateway appears in Logs with the user, the server and the tool name. Each server’s Usage tab breaks requests down by tool and by user, and the MCPs page lists the tools agents call against the tools each server offers. For MCP observability next to your other security data, log integrations forward logs to S3, Google Cloud Storage, Azure Blob Storage, Datadog, Splunk or Panther.

MCP security best practices: what should you look for in an MCP gateway?

  • Per-user identity on every call, not one shared service token.
  • Tool-level authorization enforced on tools/call, not only allow or deny per server.
  • Upstream credentials kept off devices, added by the proxy after policy allows the call.
  • Coverage for cloud apps and local agents, since Claude and ChatGPT call MCP servers from their vendors’ clouds.
  • A path for unknown servers: discovery, a default action and an approval flow.
  • Stated limits. For Formal: local stdio servers, and DCR-only clients unless they run behind the Endpoint.