MCP in depth
The Model Context Protocol (MCP) is an open standard designed to decouple AI applications from the external tools, data sources, and services they interact with. Rather than building bespoke integrations between every tool and every assistant, MCP establishes a client-server architecture: servers publish their capabilities, clients connect to discover and invoke them, and neither side needs bespoke knowledge of the other. This guide examines how the protocol works, its architectural roles and network transports, session initialization mechanics, authentication patterns, and real-world operational costs.
The integration problem
Historically, connecting an AI application to external systems required writing tailored integrations for every combination of client and service. Supporting five development environments across eight enterprise tools—such as ticket trackers, wikis, source control platforms, and databases—demanded forty independent integrations. Each connector had its own lifecycle, configuration quirks, and maintenance overhead. Adding a ninth system meant writing and maintaining five more custom connectors. This exponential growth made tool ecosystems fragile and expensive to scale.
The Model Context Protocolan open protocol, using JSON-RPC, for connecting AI applications to external tools and data, so each integration is written once rather than once per application.Full glossary entryIntroduced in MCP in depth replaces this $M \times N$ integration burden with an $M + N$ architecture. Each backend service exposes an MCP server implementing a single, standardized JSON-RPC interface. In turn, every AI host application implements an MCP client. Connecting the eight backend systems to five applications requires thirteen components rather than forty. When a ninth system implements an MCP server, every compatible AI tool gains access immediately without application-level updates.
Architectural roles
The MCP specification defines three distinct roles. Understanding where each boundary sits is critical when debugging connectivity, permissions, and tool execution.
The MCP hostthe application the user interacts with, which holds the model connection, owns the conversation, and decides what is allowed to run.Full glossary entryIntroduced in MCP in depth is the user-facing application orchestrating the session, such as an IDE, a desktop chat assistant, or a terminal CLI agent. The host manages conversation state, controls the connection to the LLM, and enforces security boundaries determining what operations may run.
The MCP clienta connector inside the host that speaks the protocol to exactly one server. A host with three servers holds three clients.Full glossary entryIntroduced in MCP in depth is an internal adapter residing inside the host. It is not an external daemon or standalone process. Its responsibility is maintaining a protocol session with exactly one MCP server. When a host connects to three independent servers, it instantiates three distinct internal client instances rather than routing traffic through a single multiplexed connection.
The MCP servera separate program exposing tools, resources, and prompts over the protocol. It never sees the conversation and never talks to the model.Full glossary entryIntroduced in MCP in depth is an independent program that exposes data and capabilities. It can run locally as a child process launched by the host or remotely as an enterprise web service reached over HTTPS. Crucially, the server is completely decoupled from the model; it never communicates directly with the LLM and does not observe the surrounding conversation history. It simply receives structured JSON-RPC requests from the client and returns results.
The model sits entirely behind the host. When the LLM emits a tool call requesting create_issue, the host inspects its registered tools, routes the request to the client managing the ticketing server, and that client dispatches the invocation across the wire.
Transport layers
The MCP specification standardizes two transport layers, which dictate how servers are deployed, secured, and operated:
The stdio transporta server run as a local subprocess, exchanging newline-delimited JSON-RPC over its standard input and output, with credentials taken from its environment.Full glossary entryIntroduced in MCP in depth runs the server as a local child process. The client launches the executable directly, exchanging newline-delimited JSON-RPC messages across the standard input and output (stdin/stdout) streams. The process inherits environment variables passed by the client for authentication and typically runs under the local user's operating system privileges. Because it requires no network listeners or exposed ports, stdio is straightforward to run, isolated from outside network traffic, and ideal for local filesystem access or developer tooling. However, state cannot be shared across machines or users, as each host instance manages its own child process.
The Streamable HTTP transporta server reached over HTTP, where each message is a POST to one endpoint and the reply is a JSON object or a request-scoped stream.Full glossary entryIntroduced in MCP in depth deploys the server as an independent network service. Clients submit JSON-RPC messages via HTTP POST requests to a designated endpoint, receiving responses as standard JSON payloads or as Server-Sent Events (SSE) streams for long-running operations. This architecture allows a centralized deployment to serve multiple users and teams across the organization, enabling shared state, centralized logging, and access to private network resources. In exchange, it requires operational infrastructure: host provisioning, health monitoring, network ingress controls, and robust authentication.
As a general pattern, operations scoped strictly to the developer's workstation favor the stdio transport, whereas shared enterprise systems and sensitive centralized credentials belong behind Streamable HTTP.
Core primitives
An MCP server can expose three core primitives, each governed by different control mechanisms:
- Tools are controlled by the model. The server advertises tool definitions including names, schemas, and descriptions. During inference, the LLM inspects these definitions and decides when to invoke them. The host receives the request, executes it via
tools/call, and returns the output to the conversation. Tools act like standard function calls sourced dynamically from external processes. - An MCP resourcedata a server exposes at a URI for the client to read. The application decides what to attach, rather than the model fetching it.Full glossary entryIntroduced in MCP in depth is controlled by the application. Resources represent read-only context addressed by standardized URIs—such as source files, system documentation, database schemas, or logs. Unlike tools, the model does not autonomously fetch resources. Instead, the host or user explicitly attaches resources to the context window prior to prompting.
- An MCP prompta template a server publishes for the user to invoke, often surfaced by a host as a slash command.Full glossary entryIntroduced in MCP in depth is controlled by the user. Servers can publish parameterized prompt templates, which host applications frequently expose as slash commands. For example, a code review server might expose a
review-prprompt template that injects standardized instructions, criteria, and diff arguments directly into the conversation.
Complex workflows occasionally require intermediate feedback before completing an operation—such as requesting user confirmation, prompting for multi-factor credentials, or invoking secondary model passes. The 2026-07-28 protocol revision unified these scenarios into a predictable pattern: multi round-trip requests.
Instead of having the server initiate asynchronous callbacks to the client, the server responds to the initial request with an interim payload marked input_required containing an inputRequests array. The client evaluates the requirement, collects the necessary input (for example, prompting the user), and then retries the original request with an inputResponses payload attached. Responses explicitly declare a resultType (complete or input_required), ensuring deterministic request-reply semantics where the client always initiates traffic.
This mechanism handles elicitation, prompting users for missing parameters or redirecting them to an out-of-band URL for credential entry so secrets never enter the LLM context. It also supports server-initiated sampling, though sampling has been deprecated in recent specifications in favor of servers calling model providers directly.
Session lifecycle and negotiation
Before exchanging commands, clients and servers participate in Capability negotiationthe declaration of which optional features each side supports, so neither a client nor a server uses one the other lacks.Full glossary entryIntroduced in MCP in depth to establish mutual compatibility. The server advertises its available primitives (tools, resources, prompts), while the client declares support for features like elicitation or experimental extensions. Neither participant invokes features the other has not explicitly advertised, enabling forward and backward compatibility across versions.
In the 2026-07-28 revision, this negotiation shifted from a stateful, connection-oriented initialize handshake to a stateless architecture. Every outgoing JSON-RPC request includes the active protocol version and supported capabilities in a _meta field. If a server receives a version it cannot support, it returns an UnsupportedProtocolVersionError detailing supported revisions. Clients can also issue a server/discover probe upon connection to determine compatibility up front.
Because MCP versions are date-stamped rather than sequentially numbered, version mismatches between newer servers and older hosts can cause silent connection failures. Verifying protocol revision compatibility between host and server should always be the first diagnostic step when troubleshooting connection issues.
Securing remote servers
Local stdio servers rely on operating system process isolation and local environment variables for security. Remote servers running over HTTP require comprehensive identity and access management.
In the HTTP transport model, the MCP server acts as an OAuth 2.1 resource server, and the MCP client acts as an OAuth client. This implementation extends standard OAuth flows with two key standards:
- RFC 9728 (Protected Resource Metadata): The server publishes authorization metadata at a standard
.well-knownendpoint. When an unauthenticated client encounters an HTTP 401 Unauthorized response, it inspects this endpoint to discover the appropriate identity provider without requiring prior manual configuration. - RFC 8707 (Resource Indicators): Clients explicitly supply a
resourceidentifier when requesting authorization tokens. The server validates that incoming tokens were issued specifically for its own resource URI, preventing token reuse attacks where credentials minted for one internal service are replayed against another.
MCP servers must never forward client bearer tokens to upstream third-party services. If an MCP server needs to communicate with external APIs (such as Jira or GitHub), it must conduct an independent backend authentication flow and store those credentials securely on the server.
Operational considerations
While MCP simplifies tool integration, operating multiple servers introduces concrete technical trade-offs:
- Context window overhead: Every tool exposed by an active MCP server contributes its JSON schema and description to the model's context window on every interaction. Enabling multiple servers with dozens of tools can consume thousands of tokens before user input is even evaluated, driving up latency and per-turn inference costs.
- Namespace collisions and ambiguity: Different servers often expose identically named tools, such as
search,get_user, orstatus. While host applications can disambiguate collisions by prepending server namespaces, the model must still infer which tool to select based purely on tool descriptions written independently by different maintainers. - Security boundaries and prompt injection: MCP servers execute real actions using ambient credentials. A compromised server or vulnerable endpoint can exfiltrate sensitive data supplied in prompts. Furthermore, tool descriptions returned by untrusted servers enter the prompt directly; malicious descriptions can execute indirect prompt injections, manipulating the model's behavior. Host applications must treat all dynamic server metadata as untrusted user input.
Read the server's source or its publisher before you install it.
- Prefer a server your organisation runs or a publisher you already trust.
- Choose stdio for anything that touches only the local machine.
- Choose HTTP for anything shared or anything holding a credential.
- Give the server its own credential. Do not reuse a personal token.
- Grant the narrowest scope the server needs.
- List the server's tools before you enable it. Count them.
- Restrict the tool list where the host supports it.
- Turn the server off when the project no longer needs it.
- Review the server again after every version bump.
These operational checks are manageable when configuring two or three local servers. However, managing dozens of servers across enterprise engineering teams quickly requires centralized coordination. Implementing MCP gateways provides the necessary proxy layer to handle unified authentication, tool filtering, and namespace resolution.
Terms introduced
- Model Context Protocol: an open protocol, using JSON-RPC, for connecting AI applications to external tools and data.
- MCP host: the application the user interacts with, which holds the model connection and decides what runs.
- MCP client: a connector inside the host that speaks the protocol to exactly one server.
- MCP server: a separate program exposing tools, resources, and prompts over the protocol.
- stdio transport: a server run as a local subprocess, exchanging newline-delimited JSON-RPC over standard input and output.
- Streamable HTTP transport: a server reached over HTTP, where each message is a POST to one endpoint and replies may stream back.
- MCP resource: data a server exposes at a URI for the client to read, attached by the application rather than fetched by the model.
- MCP prompt: a template a server publishes for the user to invoke, often surfaced by a host as a slash command.
- Capability negotiation: the declaration of which optional features each side supports, so neither uses one the other lacks.
How providers do it
The two model providers reach servers as a tool from their own API. The two harness vendors run clients on the user's machine. That difference decides whether stdio is available at all.
| Question | Anthropic | OpenAI | Cursor | |
|---|---|---|---|---|
| How a server is reached | MCP connector from the Messages API; Claude Code as host | Tool of "type": "mcp" | Tool of "type": "mcp_server" | Client in the editor |
| Local stdio servers | Yes, in Claude Code | No; a Secure MCP Tunnel instead | No | Yes |
| Remote transports | HTTP | Streamable HTTP and HTTP/SSE | Streamable HTTP only | SSE and Streamable HTTP |
| Where servers are configured | claude mcp, or .mcp.json in a plugin | Per request, or Codex config.toml | Per request, or a CLI extension | .cursor/mcp.json, project or global |
| Trimming the tool list | Tool search tool | allowed_tools | allowed_tools | Per-server settings |
| Acts as a server too | Not checked | Not checked | Google Cloud publishes servers | No, client only |
Configuration paths, transports and tool-filter fields are confirmed. Whether any of these vendors ships a first-party server, and Cursor's protocol revision, are unconfirmed in the tabs below.
The row that decides a design is the stdio one. A server that reads local files can only be used by a harness running on the user's machine, so the same server cannot simply be pointed at a model provider's API and expected to work.
- Anthropic
- OpenAI
- Cursor
What this maps to: Anthropic published MCP and uses it at both ends. Claude Code is an MCP host, and the Messages API has an MCP connector so a server can be reached from a plain API call with no client of your own.
| Question | Answer | Status |
|---|---|---|
| Is MCP supported | Yes. Anthropic publishes the specification and Claude Code acts as a host | confirmed |
| Can the API reach a server directly | Yes, through the MCP connector, which connects to remote MCP servers from the Messages API without a separate MCP client | confirmed |
| Which transports does Claude Code support | stdio and HTTP. The exact set of HTTP variants was not read today | unconfirmed; does it still accept the deprecated HTTP+SSE transport? |
| Where are servers configured in Claude Code | .mcp.json at a plugin root for a plugin's servers; project and user scopes are configured through claude mcp | unconfirmed; the scope precedence rules were not read today |
| Can a plugin ship server configuration | Yes. .mcp.json at the plugin root, applied when the plugin is enabled | confirmed |
| Does reloading pick up server changes | /reload-plugins reloads plugin MCP servers. In a session with no interactive terminal the change waits for the next session | confirmed |
| Can Claude act as an MCP server | Not read today | unconfirmed; does Claude Code expose itself as a server? |
| What is the alternative for very large tool sets | The tool search tool, a server tool that discovers and loads tool definitions on demand rather than sending all of them every call | confirmed |
Their vocabulary
| Standard term | Their term |
|---|---|
| Reaching a server from the API | MCP connector |
| Server configuration in a plugin | .mcp.json at the plugin root |
| Loading tool definitions on demand | Tool search tool |
Where to look
The /plugin Errors tab reports a plugin MCP server that failed to start. For the token side, the usage block on each response is where a large connected tool set shows up.
Last verified: 2026-09-09 against platform.claude.com/docs/en/agents-and-tools/tool-use/overview and code.claude.com/docs/en/plugins.
What this maps to: The Responses API takes an MCP server as a tool. Add an entry with "type": "mcp" and the platform connects to the server itself, so there is no client running in your application.
| Question | Answer | Status |
|---|---|---|
| How is a server connected | A tool of "type": "mcp" in the tools array | confirmed |
| What fields does it take | server_label, server_url, server_description, an optional authorization holding an OAuth access token, allowed_tools to filter, and require_approval | confirmed |
| What are the approval settings | "never", "always", or a filtered form | confirmed |
| Which transports are supported | Remote servers on Streamable HTTP or the HTTP/SSE transport | confirmed |
| Are stdio and local servers supported | Not directly. For a private or on-premises server, OpenAI documents a Secure MCP Tunnel so the server need not be exposed to the public internet | confirmed |
| What does OpenAI say about trust | You must trust any remote server you connect, because a malicious one can exfiltrate sensitive data from the model's context | confirmed |
| Can OpenAI products act as a server | Not read today | unconfirmed; is there a first-party MCP server for ChatGPT or Codex? |
| How does Codex configure servers | Through config.toml, and through plugins that bundle a server | unconfirmed; the exact key was not read today |
Their vocabulary
| Standard term | Their term |
|---|---|
| Connecting a server | The mcp tool type |
| Server name | server_label |
| Tool filter | allowed_tools |
| Approval policy | require_approval |
| Tunnel to a private server | Secure MCP Tunnel |
Where to look
allowed_tools is the lever for the context cost on this platform: it trims which of a server's tools reach the model, and so which definitions are sent on every call.
Last verified: 2026-09-09 against developers.openai.com/api/docs/guides/tools-connectors-mcp.
What this maps to: The Interactions API takes a remote MCP server as a tool entry, alongside the built-in ones. Google also publishes a public documentation server of its own for coding agents to connect to.
| Question | Answer | Status |
|---|---|---|
| How is a server connected | A tool entry with "type": "mcp_server", requiring name and url | confirmed |
| What optional fields are there | headers, for authentication, and allowed_tools to restrict which tools reach the model | confirmed |
| Which transports are supported | Streamable HTTP only. The documentation states that SSE servers are not supported | confirmed |
| Is there SDK support for a local client session | No built-in session management for local servers is documented; remote MCP is the supported route | confirmed |
| Does Google run a first-party server | Yes, a Gemini API documentation server at https://gemini-api-docs-mcp.dev, exposing a search_documentation tool | confirmed |
| Does Google publish skills alongside it | Yes, in the google-gemini/gemini-skills repository, installed with npx skills add or through Context7. The documented pair is gemini-api-dev and gemini-live-api-dev | confirmed |
| Can Gemini CLI act as a host | Yes. Gemini CLI extensions package prompts, MCP servers, custom commands, themes, hooks, sub-agents and agent skills | confirmed |
| Where does Gemini CLI configure a server | Not read today | unconfirmed; which settings file, and what is the key? |
| Can a Google product act as an MCP server | Google Cloud publishes MCP servers for its own platforms | unconfirmed; not read against a Google Cloud page today |
Their vocabulary
| Standard term | Their term |
|---|---|
| Connecting a server | The mcp_server tool type |
| Tool filter | allowed_tools |
| A bundle for the CLI | Extension |
Where to look
allowed_tools on the server entry is where the tool count gets trimmed. For the CLI, the extension is the unit that carries a server's configuration to a team.
Last verified: 2026-09-09 against ai.google.dev/gemini-api/docs/function-calling, ai.google.dev/gemini-api/docs/coding-agents and the Gemini CLI extensions documentation.
What this maps to: Cursor is an MCP host and supports the widest set of primitives of the four vendors on this page, including the client-side features that other hosts skip.
| Question | Answer | Status |
|---|---|---|
| Is MCP supported | Yes, as a client. Cursor connects to external servers | confirmed |
| Which transports are supported | stdio for local single-user servers, plus SSE and Streamable HTTP for local or remote multi-user servers | confirmed |
| Where are servers configured | .cursor/mcp.json for a project and ~/.cursor/mcp.json globally. Servers can also be installed from the Cursor Marketplace with one-click set-up | confirmed |
| Which primitives are supported | Tools, prompts, resources, roots, elicitation, and the Apps extension | confirmed |
| Can a plugin carry server configuration | Yes. MCP servers are one of the components a Cursor plugin can bundle | confirmed |
| Can Cursor act as an MCP server | Not documented. The documentation describes Cursor as a client only | confirmed |
| Is there a limit on connected tools | Not stated in the MCP documentation | unconfirmed; is there a cap on tools per server or in total? |
| Which protocol revision does Cursor implement | Not read today | unconfirmed; roots and elicitation are supported, but the revision was not stated on the page read |
Their vocabulary
| Standard term | Their term |
|---|---|
| Project server configuration | .cursor/mcp.json |
| Global server configuration | ~/.cursor/mcp.json |
| Server directory | Cursor Marketplace |
Where to look
Cursor's settings list every configured server and its tools, which is the place to count how many definitions a project is actually sending.
Last verified: 2026-09-09 against cursor.com/docs/context/mcp and cursor.com/docs/plugins.