MCP architecture is the client-host-server design the Model Context Protocol uses to connect AI applications to external tools and data. An MCP host, such as Claude Desktop or Cursor, runs one MCP client per MCP server, each client keeps a one-to-one connection with its server, and every message is a JSON-RPC 2.0 request carried over stdio or Streamable HTTP.
Anthropic introduced MCP in November 2024, and the Model Context Protocol is now governed by the Agentic AI Foundation under the Linux Foundation. Its current architecture specification, revision 2026-07-28, made the protocol stateless: every request carries its own version and capabilities, and servers no longer send requests to clients. Many published diagrams still show the older handshake.
Bifrost, the open-source AI gateway, sits inside this architecture as an MCP server to hosts and an MCP client to upstream servers.
How does MCP architecture work?
MCP architecture works by splitting an AI integration into three roles. The host is the AI application that runs the large language model (LLM) and creates one MCP client per configured MCP server. Each server exposes tools, resources and prompts for one system, and the client exchanges JSON-RPC messages with it.

Figure 1: The host owns the model and the conversation; each client holds a one-to-one link to a single server, whatever transport that server uses.
A tool call crosses the architecture in five steps:
- Discover. The client can send
server/discoverto learn the server's supported versions and capabilities, thentools/listto fetch each tool's name, description and input JSON Schema. - Register. The host merges the tool lists from every client into one set and passes it to the model in the provider's tool-calling format.
- Select. The model returns a tool call with arguments. The host checks consent and policy before anything runs.
- Invoke. The client that owns that tool sends
tools/callto its server, which runs the work against the system behind it, such as a database or a GitHub repository. - Return. The server's result goes back through the client to the host, which adds it to the model's context.
The official architecture overview notes that local servers on stdio typically serve one client, while remote servers on Streamable HTTP typically serve many.
MCP hosts, clients and servers
MCP hosts, clients and servers are the three participants the specification defines. The host is the application a person uses, the client is a connector object inside the host, and the server is a separate program that provides context. A host connected to five servers runs five clients, even when two of them reach the same remote server.
| Participant | What it is | Responsibilities | Examples |
|---|---|---|---|
| MCP host | The AI application | Creates and manages clients, runs the LLM, enforces consent and security policy, aggregates context | Claude Desktop, Claude Code, Cursor, VS Code, a custom agent |
| MCP client | A connector inside the host, one per server | Talks to exactly one server, attaches protocol version and capabilities to every request, manages subscriptions | One client object per configured server |
| MCP server | A program that exposes one system | Serves tools, resources and prompts; runs locally or remotely; asks for user input only inside a reply | Filesystem, Postgres, GitHub or Sentry servers |
MCP host
The MCP host is the container and coordinator. It decides which servers to connect, starts their clients, holds the conversation history and handles user authorization decisions, so it is the only participant that sees results from every server.
MCP client
The MCP client is the protocol endpoint on the application side. It keeps a dedicated connection to one server, so a failure or a misbehaving server stays isolated to that client. Under revision 2026-07-28, the client adds the protocol version and its capabilities to the _meta field of every request rather than negotiating them once.
MCP server
The MCP server is the program that serves context, wherever it runs. A server on the user's machine launched over stdio is called a local server; one reached at a URL over Streamable HTTP is a remote server. Servers are meant to be small and focused, and many wrap an existing API.
The MCP data layer and transport layer
The MCP data layer and transport layer split what a message means from how it travels. The data layer is the inner layer: a JSON-RPC 2.0 protocol that defines discovery, primitives and notifications. The transport layer is the outer layer: it frames messages, delivers them and carries authorization. The same JSON-RPC message works unchanged on every transport.
The data layer defines what servers and clients can offer each other. MCP tools are the only primitive the model controls:
| Primitive | Offered by | Discovery | Use | Purpose |
|---|---|---|---|---|
| Tools | Server | tools/list | tools/call | Functions the model can invoke |
| Resources | Server | resources/list | resources/read | Data the host can load into context, addressed by URI |
| Prompts | Server | prompts/list | prompts/get | Reusable templates a user selects |
| Elicitation | Client | Client capabilities | elicitation/create | A server asks the user for missing input |
Sampling and logging, two older client features, are deprecated as of revision 2026-07-28. List results now carry ttlMs and cacheScope caching hints, so a host can reuse a tool list instead of fetching it on every turn.
Every request in the data layer has the same shape. This tools/call follows the 2026-07-28 schema, with version and capabilities in _meta:
{"jsonrpc": "2.0", "id": 4, "method": "tools/call",
"params": {"name": "query_orders", "arguments": {"status": "open"},
"_meta": {"io.modelcontextprotocol/protocolVersion": "2026-07-28",
"io.modelcontextprotocol/clientCapabilities": {"elicitation": {}}}}}
How do stdio and Streamable HTTP transports differ?
Stdio and Streamable HTTP differ in where the MCP server runs. With stdio, the client launches the server as a subprocess and exchanges newline-delimited JSON-RPC over standard input and output. With Streamable HTTP, the server is an independent service, and each message is an HTTP POST to one endpoint that answers with JSON or a short server-sent events stream.
| Dimension | stdio | Streamable HTTP |
|---|---|---|
| Where the server runs | Subprocess of the client, same machine | Independent service behind a URL |
| Framing | One JSON-RPC message per line on stdin and stdout | One HTTP POST per message to a single MCP endpoint |
| Request metadata | Only in the JSON body | In the body, mirrored into MCP-Protocol-Version, Mcp-Method and Mcp-Name headers |
| Authentication | None per call; credentials come from the environment | OAuth 2.1 bearer tokens, API keys or custom headers |
| Cancellation | notifications/cancelled | Client closes the response stream |
| Clients per server | Usually one | Usually many |
| Logging | Server may write to stderr; stdout carries only MCP messages | Server logs on its own infrastructure |
The transports specification treats each transport as a binding that changes delivery, never meaning. The older HTTP+SSE transport is deprecated; MCP SSE vs Streamable HTTP covers the migration.
What changed in the stateless specification
The stateless specification, revision 2026-07-28, removed the initialize handshake and protocol sessions. A client now sends any request directly, with version and capabilities in _meta, and servers must answer server/discover for up-front discovery. A server that does not support the requested version returns UnsupportedProtocolVersionError and the supported list, and the client retries.
The change also fixed the direction of every message. Clients send requests and notifications; servers send responses and notifications. Servers no longer initiate JSON-RPC requests, so a server that needs user input returns an InputRequiredResult inside its reply, and the client re-sends the original request with the answer. Change notifications, such as a new tool list, arrive on a subscriptions/listen stream the client opens.
For architecture, that means any server instance can answer any request, which lets remote servers scale behind a plain load balancer. Servers that need state across calls return an explicit handle as a tool result and accept it as an argument later. The specification topic covers how older and newer revisions interoperate.
MCP security boundaries and authorization
MCP security boundaries follow from one design principle: servers should not read the whole conversation or see into other servers. The host keeps the full history, sends each server only the arguments for its own tools, and must get user consent before invoking a tool.
Authorization sits in the transport layer. The authorization specification makes it optional, and when used over HTTP the MCP server acts as an OAuth 2.1 resource server and the client obtains a token through the MCP OAuth flow. Stdio servers skip that flow and read credentials from the environment, the split that MCP authentication covers, which means they run with the launching user's permissions.
The architecture cannot enforce its own rules. A host that passes untrusted tool descriptions straight to the model, or a server holding one shared token for every user, breaks the boundaries the specification describes. Teams close those gaps with tool allow-lists, per-user credentials, guardrails on tool calls and an audit record for every call, the controls that MCP security maps to each risk.
Scaling MCP architecture across many servers
MCP architecture scales poorly when every host connects to every server directly. Ten developers each configuring eight servers means 80 client connections, 80 sets of credentials and no shared view of which tools are in use. Each connected tool's definition is also sent to the model on every turn, so large tool sets add tokens and wrong tool choices.
The common fix is an MCP gateway: one service that is an MCP server to every host and an MCP client to every upstream server. Hosts configure one endpoint; the gateway holds upstream credentials, filters tools per caller and logs each call. The Model Context Protocol overview places this layer next to the hosts, clients and servers it connects.
MCP architecture with Bifrost
Bifrost, the open-source AI gateway built by Maxim AI, takes both roles in the MCP architecture as an MCP gateway. As an MCP client, Bifrost connects to upstream servers over STDIO, HTTP or SSE, or generates a server from an OpenAPI document (beta). As an MCP server, it exposes the connected tools at one /mcp endpoint.

Figure 2: Hosts configure one endpoint instead of one client per server, and credentials, tool access and logs live in one place.
On the upstream side, Bifrost runs the client duties the specification assigns:
- Connections. HTTP connections open per call by default; SSE and STDIO connections stay open. Bifrost health-checks each server every 10 seconds and retries transient failures up to 5 times with backoff from 1 to 30 seconds.
- Versions. A max protocol version setting,
auto(currently 2026-07-28), can pin one server to 2025-11-25 or 2025-06-18. - Server instructions. Bifrost forwards each server's usage instructions in a tagged block, capped at 4,096 bytes per server and 16,384 bytes in total.
On the host side, gateway authentication accepts virtual keys or OAuth 2.1, and tool filtering scopes tools per key, per client and per request.
By default, Bifrost does not run tool calls the model returns; the application approves each one through a separate tool execution request. For large tool sets, Code Mode cut input tokens from 75.1M to 5.4M (92.8%) with 508 tools across 16 servers.
The same gateway routes model traffic to 25+ providers and 10,000+ models with 11 microseconds of overhead at 5,000 RPS. To put one endpoint in front of your MCP servers, start with the gateway quickstart.
Frequently asked questions
Is MCP a client-server or peer-to-peer protocol?
MCP is a client-server protocol with a host coordinating the clients. Each MCP client connects to exactly one MCP server, and since revision 2026-07-28 messages flow in fixed directions: clients send requests, servers send responses and notifications. Servers do not connect to each other; any interaction between servers passes through the host, which keeps them isolated.
What is the difference between an MCP host and an MCP client?
An MCP host is the AI application a person uses, such as Claude Desktop or Cursor, and it runs the model and holds the conversation. An MCP client is a connector object the host creates for one MCP server. A host connected to four servers contains four MCP clients, and each client handles only its own server's messages.
Can one MCP server serve multiple clients?
Yes. A remote MCP server on Streamable HTTP usually serves many clients, from many hosts and users, at one endpoint. A local server on stdio is usually launched by one client as a subprocess and serves only that client.
What protocol does MCP use underneath?
MCP uses JSON-RPC 2.0, a lightweight remote procedure call (RPC) format in JSON, for every message. Those messages travel over one of two standard transports: stdio for local subprocesses, or Streamable HTTP for remote servers. The message format is identical on both, and the specification allows custom transports that keep the same JSON-RPC messages.
Does MCP need a gateway?
MCP does not require a gateway; the specification only defines hosts, clients and servers. A gateway becomes useful once many hosts share many servers, because it centralizes credentials, tool access and logs. To each host it is one MCP server, and to each upstream server it is one MCP client.
- mcp architecture
- model context protocol architecture
- mcp clients



