TL;DR
- An MCP proxy acts as an MCP server to AI clients and as an MCP client to upstream MCP servers, relaying JSON-RPC tool discovery and tool calls between them.
- The MCP specification defines two standard transports, stdio and Streamable HTTP, and bridging a client on one transport to a server on the other is the most common reason to deploy an MCP proxy.
- The MCP specification names confused deputy attacks and token passthrough as specific risks for proxy servers, so credential handling is the first design decision.
- A forwarding MCP proxy has no model of the caller; per-caller tool filtering, per-user upstream credentials, and cost controls require an MCP gateway.
-
Bifrost connects to STDIO, HTTP, and SSE MCP servers and exposes the aggregated tools on one
/mcpendpoint scoped by virtual key.
An MCP proxy is an intermediary that speaks the Model Context Protocol on both sides of a connection: it presents itself as an MCP server to AI clients and connects as an MCP client to the servers that host tools. Teams adopt an MCP proxy to connect clients and servers that use different transports, to put several MCP servers behind one endpoint, or to keep upstream credentials off developer machines. Bifrost, the open-source AI gateway written in Go and built by Maxim AI, performs these proxy functions as an MCP gateway and adds per-caller governance on top. This guide examines the pattern at the protocol level, from request flow to the point where a proxy is no longer enough.
What Is an MCP Proxy?
An MCP proxy is a component that terminates MCP sessions from clients and opens its own sessions to upstream MCP servers, relaying tool discovery and tool calls between them. To the client, the proxy is an ordinary MCP server. To each upstream server, the proxy is an ordinary MCP client, so neither side needs code changes.
The MCP architecture specification describes a host application that creates one client per server, with each client holding a 1:1 session. A proxy changes that topology without breaking the protocol: one client session fans out to many upstream sessions.
| Component | Faces clients as | Faces servers as | Knows who is calling |
|---|---|---|---|
| MCP server | MCP server | Not applicable (hosts the tools) | Only if it implements auth itself |
| MCP proxy | MCP server | MCP client | No, forwards traffic under one identity |
| MCP gateway | MCP server | MCP client | Yes, scopes tools and credentials per caller |
The layered component model behind this pattern is covered in MCP proxy server architecture explained, and the full differences between an MCP gateway, proxy, and server are broken down separately.
How an MCP Proxy Handles a Tool Call
An MCP proxy handles a tool call in four phases: it completes the initialization handshake with the client, merges upstream tool lists on tools/list, resolves each tools/call to the server that owns the tool, and relays the result back. Session state is held separately on each side of the proxy, which keeps client and upstream sessions independent.
-
Initialization. The client sends
initializewith its capabilities and protocol version, and the proxy answers with its own. Over Streamable HTTP, a server can return anMCP-Session-Idheader that the client must send on later requests; a well-designed proxy keeps its upstream session IDs private. -
Discovery. On
tools/list, the proxy returns the union of upstream tools, usually namespaced to prevent collisions. Bifrost prefixes each tool with its MCP client name, such asfilesystem_list_directory, as part of tool execution. -
Invocation. On
tools/call, the proxy maps the tool name to its upstream server, forwards the arguments, and attaches the upstream credential. - Response. The proxy relays the result or JSON-RPC error to the client on the client's transport.
A tool call arriving at the proxy is plain JSON-RPC 2.0:
{"jsonrpc": "2.0", "id": 2, "method": "tools/call",
"params": {"name": "filesystem_read_file", "arguments": {"path": "/tmp/test.txt"}}}
MCP Transport Bridging: stdio, Streamable HTTP, and SSE
Transport bridging is the most common reason teams deploy an MCP proxy. The MCP transport specification defines stdio and Streamable HTTP as its two standard transports, and Streamable HTTP replaced the HTTP+SSE transport from protocol version 2024-11-05. A proxy lets a client on one transport reach a server on another.
| Client side | Server side | Typical scenario | What the proxy does |
|---|---|---|---|
| stdio | Streamable HTTP | Client configured to launch local servers needs a hosted tool | Runs as a local subprocess and forwards messages over HTTPS |
| Streamable HTTP | stdio | Shared service needs a tool packaged only as a CLI | Spawns the server as a subprocess and exposes it on an HTTP endpoint |
| Streamable HTTP | HTTP+SSE | Current client, older server | Translates between the single MCP endpoint and the legacy SSE stream |
| Streamable HTTP | Streamable HTTP | Both remote, central control needed | Terminates and re-originates sessions for auth and logging |
stdio has operational constraints: the server runs as a subprocess, and its stdout may carry only valid MCP messages. Bifrost supports STDIO, HTTP, and SSE connections to upstream servers, and a containerized deployment needs the STDIO server's runtime, such as npx or python, installed in the image.
Bifrost reconnects HTTP and SSE clients make-before-break, so credential rotation causes no downtime; STDIO clients reconnect close-first because STDIO servers often hold lockfiles or bound ports.
Using an MCP Proxy as an Aggregator for Multiple Servers
A proxy used as an aggregator exposes one endpoint and one merged tool list in place of a separate client configuration for each server. The client configures a single URL and credential, and the proxy manages upstream connections, retries, and health checks. The trade-off is that every aggregated tool definition can land in the model's context.
Ten engineers connecting to eight MCP servers means 80 client entries; behind an aggregating proxy, it means ten entries and eight upstream connections, a pattern described in how an MCP gateway centralizes tool access.
Bifrost retries transient failures with exponential backoff (5 retries, 1-second initial backoff, 30-second maximum) and fails authentication and configuration errors immediately. Health monitoring pings each upstream server every 10 seconds by default, with a 5-second timeout, and tracks each connection's state.
Context size is the cost of aggregation. With Code Mode, the model writes Python that calls tools in a sandbox, and in benchmarks across 508 tools on 16 servers, input tokens fell from 75.1M to 5.4M (92.8%) with a 100% pass rate. The MCP gateway benchmark writeup covers methodology.
Connecting Clients to a Remote MCP Server
A remote MCP server runs as an independent network service over Streamable HTTP rather than as a local subprocess. An MCP proxy connects clients to a remote MCP server when the client only launches local servers, when the server sits inside a private network, or when the organization wants one egress point for all tool traffic.
The transport specification requires servers to validate the Origin header to prevent DNS rebinding and recommends that local servers bind only to 127.0.0.1. Placing the proxy inside a private network keeps upstream servers unreachable from the internet; Bifrost supports in-VPC deployments for this layout.
For Claude Code, adding Bifrost as an MCP server is one command:
claude mcp add --transport http bifrost http://localhost:8080/mcp \
--header "Authorization: Bearer your-virtual-key" \
--scope user
A step-by-step setup is in using an MCP gateway with Claude Code.
MCP Authentication and Security Risks for Proxies
MCP authentication is where an MCP proxy carries the most risk, because the proxy holds credentials for upstream systems on behalf of many callers. The MCP security best practices identify two failure modes that apply directly to proxy servers: confused deputy attacks and token passthrough.
- Confused deputy. The specification defines an MCP proxy server as one acting as a single OAuth client to a third-party API. Attackers can combine a static client ID, dynamic client registration, and consent cookies to obtain authorization codes without user consent.
- Token passthrough. A server accepts a client token without validating that it was issued to that server, then passes it downstream. The MCP authorization specification requires servers to validate token audience.
- Shared identity. A proxy that injects one static credential gives every caller the same upstream identity, so upstream logs cannot attribute an action to a person.
Bifrost separates inbound and outbound authentication. Inbound clients authenticate to /mcp with virtual key headers or a browser-based OAuth 2.1 flow in which Bifrost issues a short-lived JWT, as described in gateway authentication. Outbound, each upstream server uses one of six MCP authentication types:
| Auth type | Who authenticates | Fits |
|---|---|---|
| None | No one | Public servers, local STDIO tools |
| Headers | Admin, once | Shared API keys or bearer tokens |
| OAuth 2.0 | Admin, once | Team-wide third-party services |
| Per-User Headers | Each user, on first call | Per-user API keys |
| Per-User OAuth | Each user, on first call | Per-user services such as GitHub or Notion |
| Token Exchange (enterprise) | Each caller, every call | Internal servers that trust the identity provider |
Per-user auth applies to HTTP and SSE connections; STDIO servers inherit their environment from the subprocess. Credential patterns for agents are compared in MCP server authentication for agent tool access.
Common MCP Proxy Use Cases
The most common MCP proxy use cases are transport bridging for desktop and IDE clients, consolidating MCP servers for coding agents, keeping tool traffic inside a private network, and removing credentials from client configuration files. Each case moves a responsibility from every client into one shared component.
- Coding agents across a team. Claude Code, Cursor, and similar clients carry one proxy entry instead of one entry per server.
- Shared internal tools. A platform team publishes database and ticketing tools once for every consumer.
- Credential isolation. API keys stay on the proxy host, which closes the path covered in how to stop MCP secret exfiltration.
-
Curated endpoints per team. Bifrost Virtual MCPs bundle selected tools from several servers at
/mcp/<slug>, reachable only through attached virtual keys. - Regulated environments. Finance and healthcare teams keep tool traffic inside their own infrastructure with Bifrost Enterprise deployments.
More scenarios appear in the MCP proxy server use cases guide.
Where an MCP Proxy Stops and an MCP Gateway Begins
An MCP proxy forwards traffic; an MCP gateway decides what each caller may do with it. The line is crossed when a team needs different tool lists for different callers, upstream actions attributed to individual users, or cost and access controls, because a forwarding proxy has no model of who is calling.
Four signals indicate the move:
- More than one team consumes the same MCP servers.
- Any exposed tool can write to a production system.
- Security or compliance requires a list of the tools each agent can invoke.
- Tool definitions are driving input token costs.
Each threshold is examined in MCP proxy vs MCP gateway, and the MCP gateway resource page shows how the controls fit together.
How Bifrost Handles MCP Proxy Functions as an MCP Gateway
The Bifrost AI gateway acts as an MCP client to upstream servers over STDIO, HTTP, or SSE and as an MCP server to external clients through one /mcp endpoint. Every request to that endpoint is scoped by its credentials, so different clients see different tool lists from the same URL.
-
Deny-by-default filtering. Tool filtering stacks three levels: client configuration, request headers, and virtual key. An empty
tools_to_executelist exposes no tools. -
Per-key tool access. Virtual key MCP tool rules check
tools/callagainst the same allow-list astools/list, and inactive keys receive a403. - Explicit execution. Bifrost does not auto-execute tool calls by default; Agent Mode enables auto-execution for selected tools.
- Tool call logs. Observability records MCP log entries alongside LLM requests.
- Low overhead. Bifrost adds 11 microseconds per request at 5,000 RPS in sustained benchmarks.
The same deployment routes LLM traffic to 25+ providers and 10,000+ models under one set of governance controls.
Frequently Asked Questions
What does MCP stand for?
MCP stands for Model Context Protocol, an open standard for connecting AI applications to external tools, data sources, and prompts. MCP uses JSON-RPC 2.0 messages over stdio or Streamable HTTP, and Bifrost relays those messages as an MCP client and server without changing the protocol either side speaks.
What is an MCP server?
An MCP server is a program that exposes tools, resources, or prompts to AI clients through the Model Context Protocol. It runs as a local subprocess over stdio or as a remote service over Streamable HTTP. An MCP proxy fronts one or more MCP servers and presents them as a single server.
How do you install an MCP proxy?
Open-source MCP proxies ship as npm packages, Python packages, or container images configured with the upstream servers they front. Bifrost starts with npx -y @maximhq/bifrost or docker run -p 8080:8080 maximhq/bifrost, after which upstream MCP servers are added through the dashboard or API, as shown in the gateway setup guide.
Is an MCP proxy the same as an MCP gateway?
No. An MCP proxy relays MCP traffic and often bridges transports, but it treats every caller the same. An MCP gateway adds caller identity, per-caller tool filtering, per-user upstream credentials, and logging. Bifrost covers both roles: it bridges and aggregates servers, then scopes tools per virtual key, as the MCP gateway overview outlines.
Does an MCP proxy add latency to tool calls?
An MCP proxy adds a network hop, but tool execution time on the upstream server usually dominates. Bifrost adds 11 microseconds of overhead per request at 5,000 RPS in sustained benchmarks. STDIO servers run as subprocesses on the proxy host, so they add no network round trip.
Does an MCP proxy work with Claude Code and Cursor?
Yes. Any client that supports HTTP-based MCP servers can connect to a proxy by URL. Claude Code adds Bifrost with claude mcp add --transport http, and Cursor can connect to the same /mcp URL with a virtual key header for scoped tool access. The Cursor integration guide covers model and MCP setup.
Getting Started with Bifrost
An MCP proxy solves transport bridging, server aggregation, and credential placement; an MCP gateway adds the per-caller control production agents need. Bifrost delivers both in one open-source deployment. To see how Bifrost fits your MCP proxy and tool governance requirements, book a demo with the Bifrost team.
Top comments (0)