Model Context Protocol Deep Dive (English Translation)
The main content of this article is to deeply understand and compare the evolution and feature sets of the current (February 19, 2026) version of the Model Con…
The main content of this article is to deeply understand and compare the evolution and feature sets of the current (February 19, 2026) version of the Model Context Protocol (MCP), as well as the level of support for the standard by MCP server/client frameworks. The primary purpose of this article is to support team decision-making when using MCP, including which feature sets should be adopted, which should be prohibited, and the degree of compatibility with other non-AI-specific communication protocols, such as gRPC. The implementation aspect mainly covers the Python and C# ecosystems.
MCP Protocol #
Background Introduction #
MCP (Model Context Protocol) was born after the explosion of large model applications in 2024. At that time, various models, Agent frameworks, and IDEs were customizing tool invocation and context injection methods, resulting in a highly fragmented ecosystem that was difficult to reuse. MCP attempts to provide a model-agnostic standard protocol to unify the interaction between models and external capabilities (tools, resources, environments), establishing a stable infrastructure layer for LLM engineering.
Basic Structure #
From the bottom up, the MCP protocol can be broken down into the following layers:
- Transport Layer (Streamable HTTP): MCP defines a streaming transport protocol based on HTTP, supporting bidirectional communication and persistent connections, suitable for real-time interaction between models and tools.
- RPC Layer: On top of the transport layer, MCP continues to use the JSON-RPC 2.0 message format, defining request-response patterns and notification patterns, supporting asynchronous calls. However, MCP subsequently removed support for JSON-RPC 2.0 Batch mode, switching to single message processing.
- Session Layer: MCP defines the concept of a Session and also supports message retransmission.
- Application Layer: This is mainly about the definition of business capabilities and will not be discussed in detail.
Based on the Streamable HTTP transport layer, it supports an OAuth 2.0-based authentication mechanism, ensuring security and extensibility. However, the transport layer based on stdio does not support authentication mechanisms.
The module division in the official MCP documentation is as follows:
The Model Context Protocol consists of several key components that work together:
- Base Protocol: Core JSON-RPC message types
- Lifecycle Management: Connection initialization, capability negotiation, and session control
- Authorization: Authentication and authorization framework for HTTP-based transports
- Server Features: Resources, prompts, and tools exposed by servers
- Client Features: Sampling and root directory lists provided by clients
- Utilities: Cross-cutting concerns like logging and argument completion
Transport Layer Protocol: Streamable HTTP #
The transport layer protocol is actually not just Streamable HTTP. MCP also supports a transport layer protocol based on stdio, suitable for local inter-process communication. Historically, MCP also supported an HTTP + SSE dual endpoint transport layer protocol, but it was deprecated in subsequent versions. It is now 2026, and we are mainly concerned with the current version of the Streamable HTTP protocol.
Strictly speaking, Streamable HTTP is an application protocol defined on top of the standard HTTP protocol, but for MCP, Streamable HTTP belongs to the transport layer protocol in the MCP stack.
Streamable HTTP mainly has 3 patterns:
- Single message request + single response
- Single message request + streaming response
- Server actively pushes messages
Streamable HTTP seems to be a rather strange protocol in my opinion. Its upstream channel (client request to server) is (logically) short-lived, but the downstream channel is persistent, and the two are not symmetric. The downstream persistent connection of Streamable HTTP is further divided into two types: POST-SSE and GET-SSE. SSE is the abbreviation for Server-Sent Events. POST-SSE is where the client initiates a POST request, and the server continuously sends SSE messages on this request until all messages related to this request have been sent, at which point the request is ended. GET-SSE is where the client initiates a GET request, and the server continuously sends SSE messages on this request until the client closes the connection. POST-SSE is used for result pushing related to requests, while GET-SSE is used for message pushing unrelated to POST requests. The SSE protocol existed long before MCP was invented (see Server-Sent Events is a W3C Recommendation), and MCP simply applied it to communication between models and tools. SSE mainly solves the message boundary problem on HTTP streams, ensuring message integrity and order.
Designing Streamable HTTP in this way seems to maximize the use of existing HTTP infrastructure and ecosystems while meeting the real-time interaction needs between models and tools. For example, although gRPC also supports bidirectional streaming communication, its protocol complexity results in very limited support on the browser side, whereas Streamable HTTP can directly use the browser’s native Fetch API and EventSource API to implement client functionality.
Transport Layer Protocol: stdio #
There isn’t much to say about this; it simply uses stdin/stdout to transmit JSON-RPC messages, suitable for local inter-process communication. Since stdio is a simple byte stream, MCP needs to add some boundary markers between messages to ensure message integrity and order. Because newlines are used to delimit message boundaries, messages are required not to contain newlines.
Since stdio cannot accept OAuth authentication, sensitive information is generally passed to the MCP Server started in stdio mode via environment variables.
RPC Layer: JSON-RPC 2.0 #
This is the standard JSON-RPC 2.0 protocol. MCP briefly supported the JSON-RPC 2.0 Batch mode, but it was later deprecated. Now MCP only supports single message processing.
Session Layer: Session #
Because the upstream is “one POST per message”, we cannot rely on “the same TCP connection” to represent a session, so MCP allows the server to send an Mcp-Session-Id during initialization. Afterwards, the client brings this header back in every HTTP request.
MCP also does not assume that the SSE stream will not be interrupted in the middle, so it allows the client to use Last-Event-Id to bring the ID of the last message received when reconnecting, and the server can decide where to resume sending messages based on this ID.
Server-Side Features #
MCP has several important concepts:
| Primitive | Control | Description | Example |
|---|---|---|---|
| Prompts | User-controlled | Interactive templates invoked by user choice | Slash commands, menu options |
| Resources | Application-controlled | Contextual data attached and managed by the client | File contents, git history |
| Tools | Model-controlled | Functions exposed to the LLM to take actions | API POST requests, file writing |
The meanings are quite direct, so I won’t expand on them.
Client-Side Features #
I have modeled this after the server-side features and created a summary table, as there isn’t one in the official documentation.
| Feature | Control | Description | Example |
|---|---|---|---|
| Roots | Client-controlled (Usually configured by user in client/workspace) | The client exposes the file system “root directory/boundaries” it can operate on to the server. The server can query the roots list and receive notifications when roots change, thus knowing “within what directory scope am I allowed to work”. (modelcontextprotocol.io) | An text editor/IDE client asks the user to select one or more project directories as workspace roots; the code server only reads/writes/indexes within these directories. (modelcontextprotocol.io) |
| Sampling | User-in-the-loop (client manages model access & auth) | The server requests a single LLM generation/completion (text/image/audio, etc.) through the client. The client controls model selection, permissions, and execution; the spec emphasizes there should be a “human-in-the-loop” review process (can view/edit prompt, review output), and the server does not need to hold the model API key. (modelcontextprotocol.io) | An MCP server executing a toolchain wants the LLM to write an explanation or plan first: it initiates sampling/createMessage to the client, and the user confirms before sending the generated result back to the server. (modelcontextprotocol.io) |
| Elicitation | User-controlled (client manages interaction & data egress) | The server supplements necessary information from the user during the process, which is presented and collected by the client; supports Form mode (structured input with JSON Schema) and URL mode (redirects to external URL, for sensitive interactions that must not pass through the MCP client, like login/payment); the spec requires that form mode cannot ask for sensitive information, and sensitive interactions must use URL mode. (modelcontextprotocol.io) | Booking travel: using form mode to ask for seat preference/room type; connecting a third-party account: using URL mode to open an OAuth authorization page (client displays domain and gets consent before navigating). (modelcontextprotocol.io) |
MCP Server-Side Frameworks #
- Python: Official SDK, FastMCP
- C#: Official SDK
- TypeScript: Official SDK
Note that the official Python SDK internally encapsulates FastMCP and then implements higher-level wrapping based on it.
Python SDK #
The following is the relationship between Python Official SDK versions and supported protocol versions:
| Python SDK Version | MCP Protocol Version Supported |
|---|---|
| 1.0.0 | 2024-11-05 |
| 1.9.0 | 2025-03-26 |
| 1.10.0 | 2025-06-18 |
| 1.24.0 | 2025-11-25 |
The following is the relationship between FastMCP versions and supported protocol versions:
| FastMCP Version | MCP Protocol Version Supported |
|---|---|
| 2.0.0 | [2024-11-05] |
| 2.7.1 | [2024-11-05, 2025-03-26] |
| 2.10.0 | [2024-11-05, 2025-03-26, 2025-06-18] |
| 2.14.0 | [2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25] |
| 3.0.0 | [2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25] |
C# SDK #
The following is the relationship between C# Official SDK versions and supported protocol versions:
| C# SDK Version | MCP Protocol Version Supported |
|---|---|
| 0.2.0-preview.3 | [2024-11-05, 2025-03-26] |
| 0.3.0-preview.1 | [2024-11-05, 2025-03-26, 2025-06-18] |
| 0.7.0-preview.1 | [2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25] |
TypeScript SDK #
The following is the relationship between TypeScript Official SDK versions and supported protocol versions:
| TypeScript SDK Version | MCP Protocol Version Supported |
|---|---|
| 0.4.0 | [2024-10-07, 2024-11-05] |
| 1.11.0 | [2024-10-07, 2024-11-05, 2025-03-26] |
| 1.13.0 | [2024-10-07, 2024-11-05, 2025-03-26, 2025-06-18] |
| 1.24.1 | [2024-10-07, 2024-11-05, 2025-03-26, 2025-06-18, 2025-11-25] |
MCP Client-Side Frameworks #
OpenAI SDK #
According to the OpenAI Agents SDK (for Python) documentation, the current ways to connect to MCP are:
- HostedMCPTool: Allows the OpenAI server to directly call the MCP Endpoint.
- MCPServerStreamableHttp: Connects to the MCP Server locally via the Streamable HTTP protocol.
- MCPServerSse: Connects to the MCP Server locally via the SSE protocol (deprecated).
- MCPServerStdio: Connects to the MCP Server locally via the stdio protocol.
Using HostedMCPTool requires that the Endpoint must be accessible from the public internet.
In other cases, it is essentially equivalent to traditional function calling, where the OpenAI SDK acts as a client connecting to a local MCP Server to invoke tools.
The SDKs for C#/Python/TypeScript all rely on the official MCP SDK to implement MCP client functionality, so the MCP protocol versions they support are completely consistent with the official SDK.
Anthropic SDK #
According to the Claude Agent SDK (for Python) documentation, the situation with the Claude Agent SDK is similar to OpenAI, also supporting both server-side connection and local connection modes.
The Anthropic SDKs for C#/TypeScript both rely on the official MCP SDK to implement MCP client functionality, so the MCP protocol versions they support are completely consistent with the official SDK.
The Python SDK does not have native support and requires users to adapt it themselves based on the official MCP SDK.