Model Context Protocol in OCaml

add SPEC mirrors

+178
spec/00-arch.md
···
+
---
+
title: Architecture
+
cascade:
+
type: docs
+
weight: 10
+
---
+
+
The Model Context Protocol (MCP) follows a client-host-server architecture where each
+
host can run multiple client instances. This architecture enables users to integrate AI
+
capabilities across applications while maintaining clear security boundaries and
+
isolating concerns. Built on JSON-RPC, MCP provides a stateful session protocol focused
+
on context exchange and sampling coordination between clients and servers.
+
+
## Core Components
+
+
```mermaid
+
graph LR
+
subgraph "Application Host Process"
+
H[Host]
+
C1[Client 1]
+
C2[Client 2]
+
C3[Client 3]
+
H --> C1
+
H --> C2
+
H --> C3
+
end
+
+
subgraph "Local machine"
+
S1[Server 1<br>Files & Git]
+
S2[Server 2<br>Database]
+
R1[("Local<br>Resource A")]
+
R2[("Local<br>Resource B")]
+
+
C1 --> S1
+
C2 --> S2
+
S1 <--> R1
+
S2 <--> R2
+
end
+
+
subgraph "Internet"
+
S3[Server 3<br>External APIs]
+
R3[("Remote<br>Resource C")]
+
+
C3 --> S3
+
S3 <--> R3
+
end
+
```
+
+
### Host
+
+
The host process acts as the container and coordinator:
+
+
- Creates and manages multiple client instances
+
- Controls client connection permissions and lifecycle
+
- Enforces security policies and consent requirements
+
- Handles user authorization decisions
+
- Coordinates AI/LLM integration and sampling
+
- Manages context aggregation across clients
+
+
### Clients
+
+
Each client is created by the host and maintains an isolated server connection:
+
+
- Establishes one stateful session per server
+
- Handles protocol negotiation and capability exchange
+
- Routes protocol messages bidirectionally
+
- Manages subscriptions and notifications
+
- Maintains security boundaries between servers
+
+
A host application creates and manages multiple clients, with each client having a 1:1
+
relationship with a particular server.
+
+
### Servers
+
+
Servers provide specialized context and capabilities:
+
+
- Expose resources, tools and prompts via MCP primitives
+
- Operate independently with focused responsibilities
+
- Request sampling through client interfaces
+
- Must respect security constraints
+
- Can be local processes or remote services
+
+
## Design Principles
+
+
MCP is built on several key design principles that inform its architecture and
+
implementation:
+
+
1. **Servers should be extremely easy to build**
+
+
- Host applications handle complex orchestration responsibilities
+
- Servers focus on specific, well-defined capabilities
+
- Simple interfaces minimize implementation overhead
+
- Clear separation enables maintainable code
+
+
2. **Servers should be highly composable**
+
+
- Each server provides focused functionality in isolation
+
- Multiple servers can be combined seamlessly
+
- Shared protocol enables interoperability
+
- Modular design supports extensibility
+
+
3. **Servers should not be able to read the whole conversation, nor "see into" other
+
servers**
+
+
- Servers receive only necessary contextual information
+
- Full conversation history stays with the host
+
- Each server connection maintains isolation
+
- Cross-server interactions are controlled by the host
+
- Host process enforces security boundaries
+
+
4. **Features can be added to servers and clients progressively**
+
- Core protocol provides minimal required functionality
+
- Additional capabilities can be negotiated as needed
+
- Servers and clients evolve independently
+
- Protocol designed for future extensibility
+
- Backwards compatibility is maintained
+
+
## Capability Negotiation
+
+
The Model Context Protocol uses a capability-based negotiation system where clients and
+
servers explicitly declare their supported features during initialization. Capabilities
+
determine which protocol features and primitives are available during a session.
+
+
- Servers declare capabilities like resource subscriptions, tool support, and prompt
+
templates
+
- Clients declare capabilities like sampling support and notification handling
+
- Both parties must respect declared capabilities throughout the session
+
- Additional capabilities can be negotiated through extensions to the protocol
+
+
```mermaid
+
sequenceDiagram
+
participant Host
+
participant Client
+
participant Server
+
+
Host->>+Client: Initialize client
+
Client->>+Server: Initialize session with capabilities
+
Server-->>Client: Respond with supported capabilities
+
+
Note over Host,Server: Active Session with Negotiated Features
+
+
loop Client Requests
+
Host->>Client: User- or model-initiated action
+
Client->>Server: Request (tools/resources)
+
Server-->>Client: Response
+
Client-->>Host: Update UI or respond to model
+
end
+
+
loop Server Requests
+
Server->>Client: Request (sampling)
+
Client->>Host: Forward to AI
+
Host-->>Client: AI response
+
Client-->>Server: Response
+
end
+
+
loop Notifications
+
Server--)Client: Resource updates
+
Client--)Server: Status changes
+
end
+
+
Host->>Client: Terminate
+
Client->>-Server: End session
+
deactivate Server
+
```
+
+
Each capability unlocks specific protocol features for use during the session. For
+
example:
+
+
- Implemented [server features]({{< ref "../server" >}}) must be advertised in the
+
server's capabilities
+
- Emitting resource subscription notifications requires the server to declare
+
subscription support
+
- Tool invocation requires the server to declare tool capabilities
+
- [Sampling]({{< ref "../client" >}}) requires the client to declare support in its
+
capabilities
+
+
This capability negotiation ensures clients and servers have a clear understanding of
+
supported functionality while maintaining protocol extensibility.
+4
spec/README.md
···
+
These specifications are snapshots from
+
https://github.com/modelcontextprotocol/specification/tree/main/docs/specification/2025-03-26
+
+
to help with the agentic prompting.
+386
spec/authorization.md
···
+
---
+
title: Authorization
+
type: docs
+
weight: 15
+
---
+
+
{{< callout type="info" >}} **Protocol Revision**: 2025-03-26 {{< /callout >}}
+
+
## 1. Introduction
+
+
### 1.1 Purpose and Scope
+
+
The Model Context Protocol provides authorization capabilities at the transport level,
+
enabling MCP clients to make requests to restricted MCP servers on behalf of resource
+
owners. This specification defines the authorization flow for HTTP-based transports.
+
+
### 1.2 Protocol Requirements
+
+
Authorization is **OPTIONAL** for MCP implementations. When supported:
+
+
- Implementations using an HTTP-based transport **SHOULD** conform to this specification.
+
- Implementations using an STDIO transport **SHOULD NOT** follow this specification, and
+
instead retrieve credentials from the environment.
+
- Implementations using alternative transports **MUST** follow established security best
+
practices for their protocol.
+
+
### 1.3 Standards Compliance
+
+
This authorization mechanism is based on established specifications listed below, but
+
implements a selected subset of their features to ensure security and interoperability
+
while maintaining simplicity:
+
+
- [OAuth 2.1 IETF DRAFT](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12)
+
- OAuth 2.0 Authorization Server Metadata
+
([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414))
+
- OAuth 2.0 Dynamic Client Registration Protocol
+
([RFC7591](https://datatracker.ietf.org/doc/html/rfc7591))
+
+
## 2. Authorization Flow
+
+
### 2.1 Overview
+
+
1. MCP auth implementations **MUST** implement OAuth 2.1 with appropriate security
+
measures for both confidential and public clients.
+
+
2. MCP auth implementations **SHOULD** support the OAuth 2.0 Dynamic Client Registration
+
Protocol ([RFC7591](https://datatracker.ietf.org/doc/html/rfc7591)).
+
+
3. MCP servers **SHOULD** and MCP clients **MUST** implement OAuth 2.0 Authorization
+
Server Metadata ([RFC8414](https://datatracker.ietf.org/doc/html/rfc8414)). Servers
+
that do not support Authorization Server Metadata **MUST** follow the default URI
+
schema.
+
+
### 2.2 Basic OAuth 2.1 Authorization
+
+
When authorization is required and not yet proven by the client, servers **MUST** respond
+
with _HTTP 401 Unauthorized_.
+
+
Clients initiate the
+
[OAuth 2.1 IETF DRAFT](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12)
+
authorization flow after receiving the _HTTP 401 Unauthorized_.
+
+
The following demonstrates the basic OAuth 2.1 for public clients using PKCE.
+
+
```mermaid
+
sequenceDiagram
+
participant B as User-Agent (Browser)
+
participant C as Client
+
participant M as MCP Server
+
+
C->>M: MCP Request
+
M->>C: HTTP 401 Unauthorized
+
Note over C: Generate code_verifier and code_challenge
+
C->>B: Open browser with authorization URL + code_challenge
+
B->>M: GET /authorize
+
Note over M: User logs in and authorizes
+
M->>B: Redirect to callback URL with auth code
+
B->>C: Callback with authorization code
+
C->>M: Token Request with code + code_verifier
+
M->>C: Access Token (+ Refresh Token)
+
C->>M: MCP Request with Access Token
+
Note over C,M: Begin standard MCP message exchange
+
```
+
+
### 2.3 Server Metadata Discovery
+
+
For server capability discovery:
+
+
- MCP clients _MUST_ follow the OAuth 2.0 Authorization Server Metadata protocol defined
+
in [RFC8414](https://datatracker.ietf.org/doc/html/rfc8414).
+
- MCP server _SHOULD_ follow the OAuth 2.0 Authorization Server Metadata protocol.
+
- MCP servers that do not support the OAuth 2.0 Authorization Server Metadata protocol,
+
_MUST_ support fallback URLs.
+
+
The discovery flow is illustrated below:
+
+
```mermaid
+
sequenceDiagram
+
participant C as Client
+
participant S as Server
+
+
C->>S: GET /.well-known/oauth-authorization-server
+
alt Discovery Success
+
S->>C: 200 OK + Metadata Document
+
Note over C: Use endpoints from metadata
+
else Discovery Failed
+
S->>C: 404 Not Found
+
Note over C: Fall back to default endpoints
+
end
+
Note over C: Continue with authorization flow
+
```
+
+
#### 2.3.1 Server Metadata Discovery Headers
+
+
MCP clients _SHOULD_ include the header `MCP-Protocol-Version: <protocol-version>` during
+
Server Metadata Discovery to allow the MCP server to respond based on the MCP protocol
+
version.
+
+
For example: `MCP-Protocol-Version: 2024-11-05`
+
+
#### 2.3.2 Authorization Base URL
+
+
The authorization base URL **MUST** be determined from the MCP server URL by discarding
+
any existing `path` component. For example:
+
+
If the MCP server URL is `https://api.example.com/v1/mcp`, then:
+
+
- The authorization base URL is `https://api.example.com`
+
- The metadata endpoint **MUST** be at
+
`https://api.example.com/.well-known/oauth-authorization-server`
+
+
This ensures authorization endpoints are consistently located at the root level of the
+
domain hosting the MCP server, regardless of any path components in the MCP server URL.
+
+
#### 2.3.3 Fallbacks for Servers without Metadata Discovery
+
+
For servers that do not implement OAuth 2.0 Authorization Server Metadata, clients
+
**MUST** use the following default endpoint paths relative to the authorization base URL
+
(as defined in [Section 2.3.2](#232-authorization-base-url)):
+
+
| Endpoint | Default Path | Description |
+
| ---------------------- | ------------ | ------------------------------------ |
+
| Authorization Endpoint | /authorize | Used for authorization requests |
+
| Token Endpoint | /token | Used for token exchange & refresh |
+
| Registration Endpoint | /register | Used for dynamic client registration |
+
+
For example, with an MCP server hosted at `https://api.example.com/v1/mcp`, the default
+
endpoints would be:
+
+
- `https://api.example.com/authorize`
+
- `https://api.example.com/token`
+
- `https://api.example.com/register`
+
+
Clients **MUST** first attempt to discover endpoints via the metadata document before
+
falling back to default paths. When using default paths, all other protocol requirements
+
remain unchanged.
+
+
### 2.3 Dynamic Client Registration
+
+
MCP clients and servers **SHOULD** support the
+
[OAuth 2.0 Dynamic Client Registration Protocol](https://datatracker.ietf.org/doc/html/rfc7591)
+
to allow MCP clients to obtain OAuth client IDs without user interaction. This provides a
+
standardized way for clients to automatically register with new servers, which is crucial
+
for MCP because:
+
+
- Clients cannot know all possible servers in advance
+
- Manual registration would create friction for users
+
- It enables seamless connection to new servers
+
- Servers can implement their own registration policies
+
+
Any MCP servers that _do not_ support Dynamic Client Registration need to provide
+
alternative ways to obtain a client ID (and, if applicable, client secret). For one of
+
these servers, MCP clients will have to either:
+
+
1. Hardcode a client ID (and, if applicable, client secret) specifically for that MCP
+
server, or
+
2. Present a UI to users that allows them to enter these details, after registering an
+
OAuth client themselves (e.g., through a configuration interface hosted by the
+
server).
+
+
### 2.4 Authorization Flow Steps
+
+
The complete Authorization flow proceeds as follows:
+
+
```mermaid
+
sequenceDiagram
+
participant B as User-Agent (Browser)
+
participant C as Client
+
participant M as MCP Server
+
+
C->>M: GET /.well-known/oauth-authorization-server
+
alt Server Supports Discovery
+
M->>C: Authorization Server Metadata
+
else No Discovery
+
M->>C: 404 (Use default endpoints)
+
end
+
+
alt Dynamic Client Registration
+
C->>M: POST /register
+
M->>C: Client Credentials
+
end
+
+
Note over C: Generate PKCE Parameters
+
C->>B: Open browser with authorization URL + code_challenge
+
B->>M: Authorization Request
+
Note over M: User /authorizes
+
M->>B: Redirect to callback with authorization code
+
B->>C: Authorization code callback
+
C->>M: Token Request + code_verifier
+
M->>C: Access Token (+ Refresh Token)
+
C->>M: API Requests with Access Token
+
```
+
+
#### 2.4.1 Decision Flow Overview
+
+
```mermaid
+
flowchart TD
+
A[Start Auth Flow] --> B{Check Metadata Discovery}
+
B -->|Available| C[Use Metadata Endpoints]
+
B -->|Not Available| D[Use Default Endpoints]
+
+
C --> G{Check Registration Endpoint}
+
D --> G
+
+
G -->|Available| H[Perform Dynamic Registration]
+
G -->|Not Available| I[Alternative Registration Required]
+
+
H --> J[Start OAuth Flow]
+
I --> J
+
+
J --> K[Generate PKCE Parameters]
+
K --> L[Request Authorization]
+
L --> M[User Authorization]
+
M --> N[Exchange Code for Tokens]
+
N --> O[Use Access Token]
+
```
+
+
### 2.5 Access Token Usage
+
+
#### 2.5.1 Token Requirements
+
+
Access token handling **MUST** conform to
+
[OAuth 2.1 Section 5](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5)
+
requirements for resource requests. Specifically:
+
+
1. MCP client **MUST** use the Authorization request header field
+
[Section 5.1.1](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.1.1):
+
+
```
+
Authorization: Bearer <access-token>
+
```
+
+
Note that authorization **MUST** be included in every HTTP request from client to server,
+
even if they are part of the same logical session.
+
+
2. Access tokens **MUST NOT** be included in the URI query string
+
+
Example request:
+
+
```http
+
GET /v1/contexts HTTP/1.1
+
Host: mcp.example.com
+
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
+
```
+
+
#### 2.5.2 Token Handling
+
+
Resource servers **MUST** validate access tokens as described in
+
[Section 5.2](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.2).
+
If validation fails, servers **MUST** respond according to
+
[Section 5.3](https://datatracker.ietf.org/doc/html/draft-ietf-oauth-v2-1-12#section-5.3)
+
error handling requirements. Invalid or expired tokens **MUST** receive a HTTP 401
+
response.
+
+
### 2.6 Security Considerations
+
+
The following security requirements **MUST** be implemented:
+
+
1. Clients **MUST** securely store tokens following OAuth 2.0 best practices
+
2. Servers **SHOULD** enforce token expiration and rotation
+
3. All authorization endpoints **MUST** be served over HTTPS
+
4. Servers **MUST** validate redirect URIs to prevent open redirect vulnerabilities
+
5. Redirect URIs **MUST** be either localhost URLs or HTTPS URLs
+
+
### 2.7 Error Handling
+
+
Servers **MUST** return appropriate HTTP status codes for authorization errors:
+
+
| Status Code | Description | Usage |
+
| ----------- | ------------ | ------------------------------------------ |
+
| 401 | Unauthorized | Authorization required or token invalid |
+
| 403 | Forbidden | Invalid scopes or insufficient permissions |
+
| 400 | Bad Request | Malformed authorization request |
+
+
### 2.8 Implementation Requirements
+
+
1. Implementations **MUST** follow OAuth 2.1 security best practices
+
2. PKCE is **REQUIRED** for all clients
+
3. Token rotation **SHOULD** be implemented for enhanced security
+
4. Token lifetimes **SHOULD** be limited based on security requirements
+
+
### 2.9 Third-Party Authorization Flow
+
+
#### 2.9.1 Overview
+
+
MCP servers **MAY** support delegated authorization through third-party authorization
+
servers. In this flow, the MCP server acts as both an OAuth client (to the third-party
+
auth server) and an OAuth authorization server (to the MCP client).
+
+
#### 2.9.2 Flow Description
+
+
The third-party authorization flow comprises these steps:
+
+
1. MCP client initiates standard OAuth flow with MCP server
+
2. MCP server redirects user to third-party authorization server
+
3. User authorizes with third-party server
+
4. Third-party server redirects back to MCP server with authorization code
+
5. MCP server exchanges code for third-party access token
+
6. MCP server generates its own access token bound to the third-party session
+
7. MCP server completes original OAuth flow with MCP client
+
+
```mermaid
+
sequenceDiagram
+
participant B as User-Agent (Browser)
+
participant C as MCP Client
+
participant M as MCP Server
+
participant T as Third-Party Auth Server
+
+
C->>M: Initial OAuth Request
+
M->>B: Redirect to Third-Party /authorize
+
B->>T: Authorization Request
+
Note over T: User authorizes
+
T->>B: Redirect to MCP Server callback
+
B->>M: Authorization code
+
M->>T: Exchange code for token
+
T->>M: Third-party access token
+
Note over M: Generate bound MCP token
+
M->>B: Redirect to MCP Client callback
+
B->>C: MCP authorization code
+
C->>M: Exchange code for token
+
M->>C: MCP access token
+
```
+
+
#### 2.9.3 Session Binding Requirements
+
+
MCP servers implementing third-party authorization **MUST**:
+
+
1. Maintain secure mapping between third-party tokens and issued MCP tokens
+
2. Validate third-party token status before honoring MCP tokens
+
3. Implement appropriate token lifecycle management
+
4. Handle third-party token expiration and renewal
+
+
#### 2.9.4 Security Considerations
+
+
When implementing third-party authorization, servers **MUST**:
+
+
1. Validate all redirect URIs
+
2. Securely store third-party credentials
+
3. Implement appropriate session timeout handling
+
4. Consider security implications of token chaining
+
5. Implement proper error handling for third-party auth failures
+
+
## 3. Best Practices
+
+
#### 3.1 Local clients as Public OAuth 2.1 Clients
+
+
We strongly recommend that local clients implement OAuth 2.1 as a public client:
+
+
1. Utilizing code challenges (PKCE) for authorization requests to prevent interception
+
attacks
+
2. Implementing secure token storage appropriate for the local system
+
3. Following token refresh best practices to maintain sessions
+
4. Properly handling token expiration and renewal
+
+
#### 3.2 Authorization Metadata Discovery
+
+
We strongly recommend that all clients implement metadata discovery. This reduces the
+
need for users to provide endpoints manually or clients to fallback to the defined
+
defaults.
+
+
#### 3.3 Dynamic Client Registration
+
+
Since clients do not know the set of MCP servers in advance, we strongly recommend the
+
implementation of dynamic client registration. This allows applications to automatically
+
register with the MCP server, and removes the need for users to obtain client ids
+
manually.
+239
spec/lifecycle.md
···
+
---
+
title: Lifecycle
+
type: docs
+
weight: 30
+
---
+
+
{{< callout type="info" >}} **Protocol Revision**: 2025-03-26 {{< /callout >}}
+
+
The Model Context Protocol (MCP) defines a rigorous lifecycle for client-server
+
connections that ensures proper capability negotiation and state management.
+
+
1. **Initialization**: Capability negotiation and protocol version agreement
+
2. **Operation**: Normal protocol communication
+
3. **Shutdown**: Graceful termination of the connection
+
+
```mermaid
+
sequenceDiagram
+
participant Client
+
participant Server
+
+
Note over Client,Server: Initialization Phase
+
activate Client
+
Client->>+Server: initialize request
+
Server-->>Client: initialize response
+
Client--)Server: initialized notification
+
+
Note over Client,Server: Operation Phase
+
rect rgb(200, 220, 250)
+
note over Client,Server: Normal protocol operations
+
end
+
+
Note over Client,Server: Shutdown
+
Client--)-Server: Disconnect
+
deactivate Server
+
Note over Client,Server: Connection closed
+
```
+
+
## Lifecycle Phases
+
+
### Initialization
+
+
The initialization phase **MUST** be the first interaction between client and server.
+
During this phase, the client and server:
+
+
- Establish protocol version compatibility
+
- Exchange and negotiate capabilities
+
- Share implementation details
+
+
The client **MUST** initiate this phase by sending an `initialize` request containing:
+
+
- Protocol version supported
+
- Client capabilities
+
- Client implementation information
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 1,
+
"method": "initialize",
+
"params": {
+
"protocolVersion": "2024-11-05",
+
"capabilities": {
+
"roots": {
+
"listChanged": true
+
},
+
"sampling": {}
+
},
+
"clientInfo": {
+
"name": "ExampleClient",
+
"version": "1.0.0"
+
}
+
}
+
}
+
```
+
+
The initialize request **MUST NOT** be part of a JSON-RPC
+
[batch](https://www.jsonrpc.org/specification#batch), as other requests and notifications
+
are not possible until initialization has completed. This also permits backwards
+
compatibility with prior protocol versions that do not explicitly support JSON-RPC
+
batches.
+
+
The server **MUST** respond with its own capabilities and information:
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 1,
+
"result": {
+
"protocolVersion": "2024-11-05",
+
"capabilities": {
+
"logging": {},
+
"prompts": {
+
"listChanged": true
+
},
+
"resources": {
+
"subscribe": true,
+
"listChanged": true
+
},
+
"tools": {
+
"listChanged": true
+
}
+
},
+
"serverInfo": {
+
"name": "ExampleServer",
+
"version": "1.0.0"
+
}
+
}
+
}
+
```
+
+
After successful initialization, the client **MUST** send an `initialized` notification
+
to indicate it is ready to begin normal operations:
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"method": "notifications/initialized"
+
}
+
```
+
+
- The client **SHOULD NOT** send requests other than
+
[pings]({{< ref "utilities/ping" >}}) before the server has responded to the
+
`initialize` request.
+
- The server **SHOULD NOT** send requests other than
+
[pings]({{< ref "utilities/ping" >}}) and
+
[logging]({{< ref "../server/utilities/logging" >}}) before receiving the `initialized`
+
notification.
+
+
#### Version Negotiation
+
+
In the `initialize` request, the client **MUST** send a protocol version it supports.
+
This **SHOULD** be the _latest_ version supported by the client.
+
+
If the server supports the requested protocol version, it **MUST** respond with the same
+
version. Otherwise, the server **MUST** respond with another protocol version it
+
supports. This **SHOULD** be the _latest_ version supported by the server.
+
+
If the client does not support the version in the server's response, it **SHOULD**
+
disconnect.
+
+
#### Capability Negotiation
+
+
Client and server capabilities establish which optional protocol features will be
+
available during the session.
+
+
Key capabilities include:
+
+
| Category | Capability | Description |
+
| -------- | -------------- | -------------------------------------------------------------------------- |
+
| Client | `roots` | Ability to provide filesystem [roots]({{< ref "../client/roots" >}}) |
+
| Client | `sampling` | Support for LLM [sampling]({{< ref "../client/sampling" >}}) requests |
+
| Client | `experimental` | Describes support for non-standard experimental features |
+
| Server | `prompts` | Offers [prompt templates]({{< ref "../server/prompts" >}}) |
+
| Server | `resources` | Provides readable [resources]({{< ref "../server/resources" >}}) |
+
| Server | `tools` | Exposes callable [tools]({{< ref "../server/tools" >}}) |
+
| Server | `logging` | Emits structured [log messages]({{< ref "../server/utilities/logging" >}}) |
+
| Server | `experimental` | Describes support for non-standard experimental features |
+
+
Capability objects can describe sub-capabilities like:
+
+
- `listChanged`: Support for list change notifications (for prompts, resources, and
+
tools)
+
- `subscribe`: Support for subscribing to individual items' changes (resources only)
+
+
### Operation
+
+
During the operation phase, the client and server exchange messages according to the
+
negotiated capabilities.
+
+
Both parties **SHOULD**:
+
+
- Respect the negotiated protocol version
+
- Only use capabilities that were successfully negotiated
+
+
### Shutdown
+
+
During the shutdown phase, one side (usually the client) cleanly terminates the protocol
+
connection. No specific shutdown messages are defined—instead, the underlying transport
+
mechanism should be used to signal connection termination:
+
+
#### stdio
+
+
For the stdio [transport]({{< ref "transports" >}}), the client **SHOULD** initiate
+
shutdown by:
+
+
1. First, closing the input stream to the child process (the server)
+
2. Waiting for the server to exit, or sending `SIGTERM` if the server does not exit
+
within a reasonable time
+
3. Sending `SIGKILL` if the server does not exit within a reasonable time after `SIGTERM`
+
+
The server **MAY** initiate shutdown by closing its output stream to the client and
+
exiting.
+
+
#### HTTP
+
+
For HTTP [transports]({{< ref "transports" >}}), shutdown is indicated by closing the
+
associated HTTP connection(s).
+
+
## Timeouts
+
+
Implementations **SHOULD** establish timeouts for all sent requests, to prevent hung
+
connections and resource exhaustion. When the request has not received a success or error
+
response within the timeout period, the sender **SHOULD** issue a [cancellation
+
notification]({{< ref "utilities/cancellation" >}}) for that request and stop waiting for
+
a response.
+
+
SDKs and other middleware **SHOULD** allow these timeouts to be configured on a
+
per-request basis.
+
+
Implementations **MAY** choose to reset the timeout clock when receiving a [progress
+
notification]({{< ref "utilities/progress" >}}) corresponding to the request, as this
+
implies that work is actually happening. However, implementations **SHOULD** always
+
enforce a maximum timeout, regardless of progress notifications, to limit the impact of a
+
misbehaving client or server.
+
+
## Error Handling
+
+
Implementations **SHOULD** be prepared to handle these error cases:
+
+
- Protocol version mismatch
+
- Failure to negotiate required capabilities
+
- Request [timeouts](#timeouts)
+
+
Example initialization error:
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 1,
+
"error": {
+
"code": -32602,
+
"message": "Unsupported protocol version",
+
"data": {
+
"supported": ["2024-11-05"],
+
"requested": "1.0.0"
+
}
+
}
+
}
+
```
+265
spec/prompts.md
···
+
---
+
title: Prompts
+
weight: 10
+
---
+
+
{{< callout type="info" >}} **Protocol Revision**: 2025-03-26 {{< /callout >}}
+
+
The Model Context Protocol (MCP) provides a standardized way for servers to expose prompt
+
templates to clients. Prompts allow servers to provide structured messages and
+
instructions for interacting with language models. Clients can discover available
+
prompts, retrieve their contents, and provide arguments to customize them.
+
+
## User Interaction Model
+
+
Prompts are designed to be **user-controlled**, meaning they are exposed from servers to
+
clients with the intention of the user being able to explicitly select them for use.
+
+
Typically, prompts would be triggered through user-initiated commands in the user
+
interface, which allows users to naturally discover and invoke available prompts.
+
+
For example, as slash commands:
+
+
![Example of prompt exposed as slash command](slash-command.png)
+
+
However, implementors are free to expose prompts through any interface pattern that suits
+
their needs&mdash;the protocol itself does not mandate any specific user interaction
+
model.
+
+
## Capabilities
+
+
Servers that support prompts **MUST** declare the `prompts` capability during
+
[initialization]({{< ref "../basic/lifecycle#initialization" >}}):
+
+
/draft`json { "capabilities": { "prompts": { "listChanged": true } } }
+
+
````
+
+
`listChanged` indicates whether the server will emit notifications when the list of
+
available prompts changes.
+
+
## Protocol Messages
+
+
### Listing Prompts
+
+
To retrieve available prompts, clients send a `prompts/list` request. This operation
+
supports [pagination]({{< ref "utilities/pagination" >}}).
+
+
**Request:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 1,
+
"method": "prompts/list",
+
"params": {
+
"cursor": "optional-cursor-value"
+
}
+
}
+
````
+
+
**Response:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 1,
+
"result": {
+
"prompts": [
+
{
+
"name": "code_review",
+
"description": "Asks the LLM to analyze code quality and suggest improvements",
+
"arguments": [
+
{
+
"name": "code",
+
"description": "The code to review",
+
"required": true
+
}
+
]
+
}
+
],
+
"nextCursor": "next-page-cursor"
+
}
+
}
+
```
+
+
### Getting a Prompt
+
+
To retrieve a specific prompt, clients send a `prompts/get` request. Arguments may be
+
auto-completed through [the completion API]({{< ref "utilities/completion" >}}).
+
+
**Request:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 2,
+
"method": "prompts/get",
+
"params": {
+
"name": "code_review",
+
"arguments": {
+
"code": "def hello():\n print('world')"
+
}
+
}
+
}
+
```
+
+
**Response:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 2,
+
"result": {
+
"description": "Code review prompt",
+
"messages": [
+
{
+
"role": "user",
+
"content": {
+
"type": "text",
+
"text": "Please review this Python code:\ndef hello():\n print('world')"
+
}
+
}
+
]
+
}
+
}
+
```
+
+
### List Changed Notification
+
+
When the list of available prompts changes, servers that declared the `listChanged`
+
capability **SHOULD** send a notification:
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"method": "notifications/prompts/list_changed"
+
}
+
```
+
+
## Message Flow
+
+
```mermaid
+
sequenceDiagram
+
participant Client
+
participant Server
+
+
Note over Client,Server: Discovery
+
Client->>Server: prompts/list
+
Server-->>Client: List of prompts
+
+
Note over Client,Server: Usage
+
Client->>Server: prompts/get
+
Server-->>Client: Prompt content
+
+
opt listChanged
+
Note over Client,Server: Changes
+
Server--)Client: prompts/list_changed
+
Client->>Server: prompts/list
+
Server-->>Client: Updated prompts
+
end
+
```
+
+
## Data Types
+
+
### Prompt
+
+
A prompt definition includes:
+
+
- `name`: Unique identifier for the prompt
+
- `description`: Optional human-readable description
+
- `arguments`: Optional list of arguments for customization
+
+
### PromptMessage
+
+
Messages in a prompt can contain:
+
+
- `role`: Either "user" or "assistant" to indicate the speaker
+
- `content`: One of the following content types:
+
+
#### Text Content
+
+
Text content represents plain text messages:
+
+
```json
+
{
+
"type": "text",
+
"text": "The text content of the message"
+
}
+
```
+
+
This is the most common content type used for natural language interactions.
+
+
#### Image Content
+
+
Image content allows including visual information in messages:
+
+
```json
+
{
+
"type": "image",
+
"data": "base64-encoded-image-data",
+
"mimeType": "image/png"
+
}
+
```
+
+
The image data **MUST** be base64-encoded and include a valid MIME type. This enables
+
multi-modal interactions where visual context is important.
+
+
#### Audio Content
+
+
Audio content allows including audio information in messages:
+
+
```json
+
{
+
"type": "audio",
+
"data": "base64-encoded-audio-data",
+
"mimeType": "audio/wav"
+
}
+
```
+
+
The audio data MUST be base64-encoded and include a valid MIME type. This enables
+
multi-modal interactions where audio context is important.
+
+
#### Embedded Resources
+
+
Embedded resources allow referencing server-side resources directly in messages:
+
+
```json
+
{
+
"type": "resource",
+
"resource": {
+
"uri": "resource://example",
+
"mimeType": "text/plain",
+
"text": "Resource content"
+
}
+
}
+
```
+
+
Resources can contain either text or binary (blob) data and **MUST** include:
+
+
- A valid resource URI
+
- The appropriate MIME type
+
- Either text content or base64-encoded blob data
+
+
Embedded resources enable prompts to seamlessly incorporate server-managed content like
+
documentation, code samples, or other reference materials directly into the conversation
+
flow.
+
+
## Error Handling
+
+
Servers **SHOULD** return standard JSON-RPC errors for common failure cases:
+
+
- Invalid prompt name: `-32602` (Invalid params)
+
- Missing required arguments: `-32602` (Invalid params)
+
- Internal errors: `-32603` (Internal error)
+
+
## Implementation Considerations
+
+
1. Servers **SHOULD** validate prompt arguments before processing
+
2. Clients **SHOULD** handle pagination for large prompt lists
+
3. Both parties **SHOULD** respect capability negotiation
+
+
## Security
+
+
Implementations **MUST** carefully validate all prompt inputs and outputs to prevent
+
injection attacks or unauthorized access to resources.
+357
spec/resources.md
···
+
---
+
title: Resources
+
type: docs
+
weight: 20
+
---
+
+
{{< callout type="info" >}} **Protocol Revision**: 2025-03-26 {{< /callout >}}
+
+
The Model Context Protocol (MCP) provides a standardized way for servers to expose
+
resources to clients. Resources allow servers to share data that provides context to
+
language models, such as files, database schemas, or application-specific information.
+
Each resource is uniquely identified by a
+
[URI](https://datatracker.ietf.org/doc/html/rfc3986).
+
+
## User Interaction Model
+
+
Resources in MCP are designed to be **application-driven**, with host applications
+
determining how to incorporate context based on their needs.
+
+
For example, applications could:
+
+
- Expose resources through UI elements for explicit selection, in a tree or list view
+
- Allow the user to search through and filter available resources
+
- Implement automatic context inclusion, based on heuristics or the AI model's selection
+
+
![Example of resource context picker](resource-picker.png)
+
+
However, implementations are free to expose resources through any interface pattern that
+
suits their needs&mdash;the protocol itself does not mandate any specific user
+
interaction model.
+
+
## Capabilities
+
+
Servers that support resources **MUST** declare the `resources` capability:
+
+
```json
+
{
+
"capabilities": {
+
"resources": {
+
"subscribe": true,
+
"listChanged": true
+
}
+
}
+
}
+
```
+
+
The capability supports two optional features:
+
+
- `subscribe`: whether the client can subscribe to be notified of changes to individual
+
resources.
+
- `listChanged`: whether the server will emit notifications when the list of available
+
resources changes.
+
+
Both `subscribe` and `listChanged` are optional&mdash;servers can support neither,
+
either, or both:
+
+
```json
+
{
+
"capabilities": {
+
"resources": {} // Neither feature supported
+
}
+
}
+
```
+
+
```json
+
{
+
"capabilities": {
+
"resources": {
+
"subscribe": true // Only subscriptions supported
+
}
+
}
+
}
+
```
+
+
```json
+
{
+
"capabilities": {
+
"resources": {
+
"listChanged": true // Only list change notifications supported
+
}
+
}
+
}
+
```
+
+
## Protocol Messages
+
+
### Listing Resources
+
+
To discover available resources, clients send a `resources/list` request. This operation
+
supports [pagination]({{< ref "utilities/pagination" >}}).
+
+
**Request:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 1,
+
"method": "resources/list",
+
"params": {
+
"cursor": "optional-cursor-value"
+
}
+
}
+
```
+
+
**Response:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 1,
+
"result": {
+
"resources": [
+
{
+
"uri": "file:///project/src/main.rs",
+
"name": "main.rs",
+
"description": "Primary application entry point",
+
"mimeType": "text/x-rust"
+
}
+
],
+
"nextCursor": "next-page-cursor"
+
}
+
}
+
```
+
+
### Reading Resources
+
+
To retrieve resource contents, clients send a `resources/read` request:
+
+
**Request:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 2,
+
"method": "resources/read",
+
"params": {
+
"uri": "file:///project/src/main.rs"
+
}
+
}
+
```
+
+
**Response:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 2,
+
"result": {
+
"contents": [
+
{
+
"uri": "file:///project/src/main.rs",
+
"mimeType": "text/x-rust",
+
"text": "fn main() {\n println!(\"Hello world!\");\n}"
+
}
+
]
+
}
+
}
+
```
+
+
### Resource Templates
+
+
Resource templates allow servers to expose parameterized resources using
+
[URI templates](https://datatracker.ietf.org/doc/html/rfc6570). Arguments may be
+
auto-completed through [the completion API]({{< ref "utilities/completion" >}}).
+
+
**Request:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 3,
+
"method": "resources/templates/list"
+
}
+
```
+
+
**Response:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 3,
+
"result": {
+
"resourceTemplates": [
+
{
+
"uriTemplate": "file:///{path}",
+
"name": "Project Files",
+
"description": "Access files in the project directory",
+
"mimeType": "application/octet-stream"
+
}
+
]
+
}
+
}
+
```
+
+
### List Changed Notification
+
+
When the list of available resources changes, servers that declared the `listChanged`
+
capability **SHOULD** send a notification:
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"method": "notifications/resources/list_changed"
+
}
+
```
+
+
### Subscriptions
+
+
The protocol supports optional subscriptions to resource changes. Clients can subscribe
+
to specific resources and receive notifications when they change:
+
+
**Subscribe Request:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 4,
+
"method": "resources/subscribe",
+
"params": {
+
"uri": "file:///project/src/main.rs"
+
}
+
}
+
```
+
+
**Update Notification:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"method": "notifications/resources/updated",
+
"params": {
+
"uri": "file:///project/src/main.rs"
+
}
+
}
+
```
+
+
## Message Flow
+
+
```mermaid
+
sequenceDiagram
+
participant Client
+
participant Server
+
+
Note over Client,Server: Resource Discovery
+
Client->>Server: resources/list
+
Server-->>Client: List of resources
+
+
Note over Client,Server: Resource Access
+
Client->>Server: resources/read
+
Server-->>Client: Resource contents
+
+
Note over Client,Server: Subscriptions
+
Client->>Server: resources/subscribe
+
Server-->>Client: Subscription confirmed
+
+
Note over Client,Server: Updates
+
Server--)Client: notifications/resources/updated
+
Client->>Server: resources/read
+
Server-->>Client: Updated contents
+
```
+
+
## Data Types
+
+
### Resource
+
+
A resource definition includes:
+
+
- `uri`: Unique identifier for the resource
+
- `name`: Human-readable name
+
- `description`: Optional description
+
- `mimeType`: Optional MIME type
+
- `size`: Optional size in bytes
+
+
### Resource Contents
+
+
Resources can contain either text or binary data:
+
+
#### Text Content
+
+
```json
+
{
+
"uri": "file:///example.txt",
+
"mimeType": "text/plain",
+
"text": "Resource content"
+
}
+
```
+
+
#### Binary Content
+
+
```json
+
{
+
"uri": "file:///example.png",
+
"mimeType": "image/png",
+
"blob": "base64-encoded-data"
+
}
+
```
+
+
## Common URI Schemes
+
+
The protocol defines several standard URI schemes. This list not
+
exhaustive&mdash;implementations are always free to use additional, custom URI schemes.
+
+
### https://
+
+
Used to represent a resource available on the web.
+
+
Servers **SHOULD** use this scheme only when the client is able to fetch and load the
+
resource directly from the web on its own—that is, it doesn’t need to read the resource
+
via the MCP server.
+
+
For other use cases, servers **SHOULD** prefer to use another URI scheme, or define a
+
custom one, even if the server will itself be downloading resource contents over the
+
internet.
+
+
### file://
+
+
Used to identify resources that behave like a filesystem. However, the resources do not
+
need to map to an actual physical filesystem.
+
+
MCP servers **MAY** identify file:// resources with an
+
[XDG MIME type](https://specifications.freedesktop.org/shared-mime-info-spec/0.14/ar01s02.html#id-1.3.14),
+
like `inode/directory`, to represent non-regular files (such as directories) that don’t
+
otherwise have a standard MIME type.
+
+
### git://
+
+
Git version control integration.
+
+
## Error Handling
+
+
Servers **SHOULD** return standard JSON-RPC errors for common failure cases:
+
+
- Resource not found: `-32002`
+
- Internal errors: `-32603`
+
+
Example error:
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 5,
+
"error": {
+
"code": -32002,
+
"message": "Resource not found",
+
"data": {
+
"uri": "file:///nonexistent.txt"
+
}
+
}
+
}
+
```
+
+
## Security Considerations
+
+
1. Servers **MUST** validate all resource URIs
+
2. Access controls **SHOULD** be implemented for sensitive resources
+
3. Binary data **MUST** be properly encoded
+
4. Resource permissions **SHOULD** be checked before operations
spec/slash-command.png

This is a binary file and will not be displayed.

+299
spec/tools.md
···
+
---
+
title: Tools
+
type: docs
+
weight: 40
+
---
+
+
{{< callout type="info" >}} **Protocol Revision**: 2025-03-26 {{< /callout >}}
+
+
The Model Context Protocol (MCP) allows servers to expose tools that can be invoked by
+
language models. Tools enable models to interact with external systems, such as querying
+
databases, calling APIs, or performing computations. Each tool is uniquely identified by
+
a name and includes metadata describing its schema.
+
+
## User Interaction Model
+
+
Tools in MCP are designed to be **model-controlled**, meaning that the language model can
+
discover and invoke tools automatically based on its contextual understanding and the
+
user's prompts.
+
+
However, implementations are free to expose tools through any interface pattern that
+
suits their needs&mdash;the protocol itself does not mandate any specific user
+
interaction model.
+
+
{{< callout type="warning" >}} For trust & safety and security, there **SHOULD** always
+
be a human in the loop with the ability to deny tool invocations.
+
+
Applications **SHOULD**:
+
+
- Provide UI that makes clear which tools are being exposed to the AI model
+
- Insert clear visual indicators when tools are invoked
+
- Present confirmation prompts to the user for operations, to ensure a human is in the
+
loop {{< /callout >}}
+
+
## Capabilities
+
+
Servers that support tools **MUST** declare the `tools` capability:
+
+
```json
+
{
+
"capabilities": {
+
"tools": {
+
"listChanged": true
+
}
+
}
+
}
+
```
+
+
`listChanged` indicates whether the server will emit notifications when the list of
+
available tools changes.
+
+
## Protocol Messages
+
+
### Listing Tools
+
+
To discover available tools, clients send a `tools/list` request. This operation supports
+
[pagination]({{< ref "utilities/pagination" >}}).
+
+
**Request:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 1,
+
"method": "tools/list",
+
"params": {
+
"cursor": "optional-cursor-value"
+
}
+
}
+
```
+
+
**Response:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 1,
+
"result": {
+
"tools": [
+
{
+
"name": "get_weather",
+
"description": "Get current weather information for a location",
+
"inputSchema": {
+
"type": "object",
+
"properties": {
+
"location": {
+
"type": "string",
+
"description": "City name or zip code"
+
}
+
},
+
"required": ["location"]
+
}
+
}
+
],
+
"nextCursor": "next-page-cursor"
+
}
+
}
+
```
+
+
### Calling Tools
+
+
To invoke a tool, clients send a `tools/call` request:
+
+
**Request:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 2,
+
"method": "tools/call",
+
"params": {
+
"name": "get_weather",
+
"arguments": {
+
"location": "New York"
+
}
+
}
+
}
+
```
+
+
**Response:**
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 2,
+
"result": {
+
"content": [
+
{
+
"type": "text",
+
"text": "Current weather in New York:\nTemperature: 72°F\nConditions: Partly cloudy"
+
}
+
],
+
"isError": false
+
}
+
}
+
```
+
+
### List Changed Notification
+
+
When the list of available tools changes, servers that declared the `listChanged`
+
capability **SHOULD** send a notification:
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"method": "notifications/tools/list_changed"
+
}
+
```
+
+
## Message Flow
+
+
```mermaid
+
sequenceDiagram
+
participant LLM
+
participant Client
+
participant Server
+
+
Note over Client,Server: Discovery
+
Client->>Server: tools/list
+
Server-->>Client: List of tools
+
+
Note over Client,LLM: Tool Selection
+
LLM->>Client: Select tool to use
+
+
Note over Client,Server: Invocation
+
Client->>Server: tools/call
+
Server-->>Client: Tool result
+
Client->>LLM: Process result
+
+
Note over Client,Server: Updates
+
Server--)Client: tools/list_changed
+
Client->>Server: tools/list
+
Server-->>Client: Updated tools
+
```
+
+
## Data Types
+
+
### Tool
+
+
A tool definition includes:
+
+
- `name`: Unique identifier for the tool
+
- `description`: Human-readable description of functionality
+
- `inputSchema`: JSON Schema defining expected parameters
+
- `annotations`: optional properties describing tool behavior
+
+
{{< callout type="warning" >}} For trust & safety and security, clients **MUST** consider
+
tool annotations to be untrusted unless they come from trusted servers. {{< /callout >}}
+
+
### Tool Result
+
+
Tool results can contain multiple content items of different types:
+
+
#### Text Content
+
+
```json
+
{
+
"type": "text",
+
"text": "Tool result text"
+
}
+
```
+
+
#### Image Content
+
+
```json
+
{
+
"type": "image",
+
"data": "base64-encoded-data",
+
"mimeType": "image/png"
+
}
+
```
+
+
#### Audio Content
+
+
```json
+
{
+
"type": "audio",
+
"data": "base64-encoded-audio-data",
+
"mimeType": "audio/wav"
+
}
+
```
+
+
#### Embedded Resources
+
+
[Resources]({{< ref "resources" >}}) **MAY** be embedded, to provide additional context
+
or data, behind a URI that can be subscribed to or fetched again by the client later:
+
+
```json
+
{
+
"type": "resource",
+
"resource": {
+
"uri": "resource://example",
+
"mimeType": "text/plain",
+
"text": "Resource content"
+
}
+
}
+
```
+
+
## Error Handling
+
+
Tools use two error reporting mechanisms:
+
+
1. **Protocol Errors**: Standard JSON-RPC errors for issues like:
+
+
- Unknown tools
+
- Invalid arguments
+
- Server errors
+
+
2. **Tool Execution Errors**: Reported in tool results with `isError: true`:
+
- API failures
+
- Invalid input data
+
- Business logic errors
+
+
Example protocol error:
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 3,
+
"error": {
+
"code": -32602,
+
"message": "Unknown tool: invalid_tool_name"
+
}
+
}
+
```
+
+
Example tool execution error:
+
+
```json
+
{
+
"jsonrpc": "2.0",
+
"id": 4,
+
"result": {
+
"content": [
+
{
+
"type": "text",
+
"text": "Failed to fetch weather data: API rate limit exceeded"
+
}
+
],
+
"isError": true
+
}
+
}
+
```
+
+
## Security Considerations
+
+
1. Servers **MUST**:
+
+
- Validate all tool inputs
+
- Implement proper access controls
+
- Rate limit tool invocations
+
- Sanitize tool outputs
+
+
2. Clients **SHOULD**:
+
- Prompt for user confirmation on sensitive operations
+
- Show tool inputs to the user before calling the server, to avoid malicious or
+
accidental data exfiltration
+
- Validate tool results before passing to LLM
+
- Implement timeouts for tool calls
+
- Log tool usage for audit purposes
+278
spec/transports.md
···
+
---
+
title: Transports
+
type: docs
+
weight: 10
+
---
+
+
{{< callout type="info" >}} **Protocol Revision**: 2025-03-26 {{< /callout >}}
+
+
MCP uses JSON-RPC to encode messages. JSON-RPC messages **MUST** be UTF-8 encoded.
+
+
The protocol currently defines two standard transport mechanisms for client-server
+
communication:
+
+
1. [stdio](#stdio), communication over standard in and standard out
+
2. [Streamable HTTP](#streamable-http)
+
+
Clients **SHOULD** support stdio whenever possible.
+
+
It is also possible for clients and servers to implement
+
[custom transports](#custom-transports) in a pluggable fashion.
+
+
## stdio
+
+
In the **stdio** transport:
+
+
- The client launches the MCP server as a subprocess.
+
- The server reads JSON-RPC messages from its standard input (`stdin`) and sends messages
+
to its standard output (`stdout`).
+
- Messages may be JSON-RPC requests, notifications, responses—or a JSON-RPC
+
[batch](https://www.jsonrpc.org/specification#batch) containing one or more requests
+
and/or notifications.
+
- Messages are delimited by newlines, and **MUST NOT** contain embedded newlines.
+
- The server **MAY** write UTF-8 strings to its standard error (`stderr`) for logging
+
purposes. Clients **MAY** capture, forward, or ignore this logging.
+
- The server **MUST NOT** write anything to its `stdout` that is not a valid MCP message.
+
- The client **MUST NOT** write anything to the server's `stdin` that is not a valid MCP
+
message.
+
+
```mermaid
+
sequenceDiagram
+
participant Client
+
participant Server Process
+
+
Client->>+Server Process: Launch subprocess
+
loop Message Exchange
+
Client->>Server Process: Write to stdin
+
Server Process->>Client: Write to stdout
+
Server Process--)Client: Optional logs on stderr
+
end
+
Client->>Server Process: Close stdin, terminate subprocess
+
deactivate Server Process
+
```
+
+
## Streamable HTTP
+
+
{{< callout type="info" >}} This replaces the [HTTP+SSE
+
transport]({{< ref "/specification/2024-11-05/basic/transports#http-with-sse" >}}) from
+
protocol version 2024-11-05. See the [backwards compatibility](#backwards-compatibility)
+
guide below. {{< /callout >}}
+
+
In the **Streamable HTTP** transport, the server operates as an independent process that
+
can handle multiple client connections. This transport uses HTTP POST and GET requests.
+
Server can optionally make use of
+
[Server-Sent Events](https://en.wikipedia.org/wiki/Server-sent_events) (SSE) to stream
+
multiple server messages. This permits basic MCP servers, as well as more feature-rich
+
servers supporting streaming and server-to-client notifications and requests.
+
+
The server **MUST** provide a single HTTP endpoint path (hereafter referred to as the
+
**MCP endpoint**) that supports both POST and GET methods. For example, this could be a
+
URL like `https://example.com/mcp`.
+
+
### Sending Messages to the Server
+
+
Every JSON-RPC message sent from the client **MUST** be a new HTTP POST request to the
+
MCP endpoint.
+
+
1. The client **MUST** use HTTP POST to send JSON-RPC messages to the MCP endpoint.
+
2. The client **MUST** include an `Accept` header, listing both `application/json` and
+
`text/event-stream` as supported content types.
+
3. The body of the POST request **MUST** be one of the following:
+
- A single JSON-RPC _request_, _notification_, or _response_
+
- An array [batching](https://www.jsonrpc.org/specification#batch) one or more
+
_requests and/or notifications_
+
- An array [batching](https://www.jsonrpc.org/specification#batch) one or more
+
_responses_
+
4. If the input consists solely of (any number of) JSON-RPC _responses_ or
+
_notifications_:
+
- If the server accepts the input, the server **MUST** return HTTP status code 202
+
Accepted with no body.
+
- If the server cannot accept the input, it **MUST** return an HTTP error status code
+
(e.g., 400 Bad Request). The HTTP response body **MAY** comprise a JSON-RPC _error
+
response_ that has no `id`.
+
5. If the input contains any number of JSON-RPC _requests_, the server **MUST** either
+
return `Content-Type: text/event-stream`, to initiate an SSE stream, or
+
`Content-Type: application/json`, to return one JSON object. The client **MUST**
+
support both these cases.
+
6. If the server initiates an SSE stream:
+
- The SSE stream **SHOULD** eventually include one JSON-RPC _response_ per each
+
JSON-RPC _request_ sent in the POST body. These _responses_ **MAY** be
+
[batched](https://www.jsonrpc.org/specification#batch).
+
- The server **MAY** send JSON-RPC _requests_ and _notifications_ before sending a
+
JSON-RPC _response_. These messages **SHOULD** relate to the originating client
+
_request_. These _requests_ and _notifications_ **MAY** be
+
[batched](https://www.jsonrpc.org/specification#batch).
+
- The server **SHOULD NOT** close the SSE stream before sending a JSON-RPC _response_
+
per each received JSON-RPC _request_, unless the [session](#session-management)
+
expires.
+
- After all JSON-RPC _responses_ have been sent, the server **SHOULD** close the SSE
+
stream.
+
- Disconnection **MAY** occur at any time (e.g., due to network conditions).
+
Therefore:
+
- Disconnection **SHOULD NOT** be interpreted as the client cancelling its request.
+
- To cancel, the client **SHOULD** explicitly send an MCP `CancelledNotification`.
+
- To avoid message loss due to disconnection, the server **MAY** make the stream
+
[resumable](#resumability-and-redelivery).
+
+
### Listening for Messages from the Server
+
+
1. The client **MAY** issue an HTTP GET to the MCP endpoint. This can be used to open an
+
SSE stream, allowing the server to communicate to the client, without the client first
+
sending data via HTTP POST.
+
2. The client **MUST** include an `Accept` header, listing `text/event-stream` as a
+
supported content type.
+
3. The server **MUST** either return `Content-Type: text/event-stream` in response to
+
this HTTP GET, or else return HTTP 405 Method Not Allowed, indicating that the server
+
does not offer an SSE stream at this endpoint.
+
4. If the server initiates an SSE stream:
+
- The server **MAY** send JSON-RPC _requests_ and _notifications_ on the stream. These
+
_requests_ and _notifications_ **MAY** be
+
[batched](https://www.jsonrpc.org/specification#batch).
+
- These messages **SHOULD** be unrelated to any concurrently-running JSON-RPC
+
_request_ from the client.
+
- The server **MUST NOT** send a JSON-RPC _response_ on the stream **unless**
+
[resuming](#resumability-and-redelivery) a stream associated with a previous client
+
request.
+
- The server **MAY** close the SSE stream at any time.
+
- The client **MAY** close the SSE stream at any time.
+
+
### Multiple Connections
+
+
1. The client **MAY** remain connected to multiple SSE streams simultaneously.
+
2. The server **MUST** send each of its JSON-RPC messages on only one of the connected
+
streams; that is, it **MUST NOT** broadcast the same message across multiple streams.
+
- The risk of message loss **MAY** be mitigated by making the stream
+
[resumable](#resumability-and-redelivery).
+
+
### Resumability and Redelivery
+
+
To support resuming broken connections, and redelivering messages that might otherwise be
+
lost:
+
+
1. Servers **MAY** attach an `id` field to their SSE events, as described in the
+
[SSE standard](https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation).
+
- If present, the ID **MUST** be globally unique across all streams within that
+
[session](#session-management)—or all streams with that specific client, if session
+
management is not in use.
+
2. If the client wishes to resume after a broken connection, it **SHOULD** issue an HTTP
+
GET to the MCP endpoint, and include the
+
[`Last-Event-ID`](https://html.spec.whatwg.org/multipage/server-sent-events.html#the-last-event-id-header)
+
header to indicate the last event ID it received.
+
- The server **MAY** use this header to replay messages that would have been sent
+
after the last event ID, _on the stream that was disconnected_, and to resume the
+
stream from that point.
+
- The server **MUST NOT** replay messages that would have been delivered on a
+
different stream.
+
+
In other words, these event IDs should be assigned by servers on a _per-stream_ basis, to
+
act as a cursor within that particular stream.
+
+
### Session Management
+
+
An MCP "session" consists of logically related interactions between a client and a
+
server, beginning with the [initialization phase]({{< ref "lifecycle" >}}). To support
+
servers which want to establish stateful sessions:
+
+
1. A server using the Streamable HTTP transport **MAY** assign a session ID at
+
initialization time, by including it in an `Mcp-Session-Id` header on the HTTP
+
response containing the `InitializeResult`.
+
- The session ID **SHOULD** be globally unique and cryptographically secure (e.g., a
+
securely generated UUID, a JWT, or a cryptographic hash).
+
- The session ID **MUST** only contain visible ASCII characters (ranging from 0x21 to
+
0x7E).
+
2. If an `Mcp-Session-Id` is returned by the server during initialization, clients using
+
the Streamable HTTP transport **MUST** include it in the `Mcp-Session-Id` header on
+
all of their subsequent HTTP requests.
+
- Servers that require a session ID **SHOULD** respond to requests without an
+
`Mcp-Session-Id` header (other than initialization) with HTTP 400 Bad Request.
+
3. The server **MAY** terminate the session at any time, after which it **MUST** respond
+
to requests containing that session ID with HTTP 404 Not Found.
+
4. When a client receives HTTP 404 in response to a request containing an
+
`Mcp-Session-Id`, it **MUST** start a new session by sending a new `InitializeRequest`
+
without a session ID attached.
+
5. Clients that no longer need a particular session (e.g., because the user is leaving
+
the client application) **SHOULD** send an HTTP DELETE to the MCP endpoint with the
+
`Mcp-Session-Id` header, to explicitly terminate the session.
+
- The server **MAY** respond to this request with HTTP 405 Method Not Allowed,
+
indicating that the server does not allow clients to terminate sessions.
+
+
### Sequence Diagram
+
+
```mermaid
+
sequenceDiagram
+
participant Client
+
participant Server
+
+
note over Client, Server: initialization
+
+
Client->>+Server: POST InitializeRequest
+
Server->>-Client: InitializeResponse<br>Mcp-Session-Id: 1868a90c...
+
+
Client->>+Server: POST InitializedNotification<br>Mcp-Session-Id: 1868a90c...
+
Server->>-Client: 202 Accepted
+
+
note over Client, Server: client requests
+
Client->>+Server: POST ... request ...<br>Mcp-Session-Id: 1868a90c...
+
+
alt single HTTP response
+
Server->>Client: ... response ...
+
else server opens SSE stream
+
loop while connection remains open
+
Server-)Client: ... SSE messages from server ...
+
end
+
Server-)Client: SSE event: ... response ...
+
end
+
deactivate Server
+
+
note over Client, Server: client notifications/responses
+
Client->>+Server: POST ... notification/response ...<br>Mcp-Session-Id: 1868a90c...
+
Server->>-Client: 202 Accepted
+
+
note over Client, Server: server requests
+
Client->>+Server: GET<br>Mcp-Session-Id: 1868a90c...
+
loop while connection remains open
+
Server-)Client: ... SSE messages from server ...
+
end
+
deactivate Server
+
+
```
+
+
### Backwards Compatibility
+
+
Clients and servers can maintain backwards compatibility with the deprecated [HTTP+SSE
+
transport]({{< ref "/specification/2024-11-05/basic/transports#http-with-sse" >}}) (from
+
protocol version 2024-11-05) as follows:
+
+
**Servers** wanting to support older clients should:
+
+
- Continue to host both the SSE and POST endpoints of the old transport, alongside the
+
new "MCP endpoint" defined for the Streamable HTTP transport.
+
- It is also possible to combine the old POST endpoint and the new MCP endpoint, but
+
this may introduce unneeded complexity.
+
+
**Clients** wanting to support older servers should:
+
+
1. Accept an MCP server URL from the user, which may point to either a server using the
+
old transport or the new transport.
+
2. Attempt to POST an `InitializeRequest` to the server URL, with an `Accept` header as
+
defined above:
+
- If it succeeds, the client can assume this is a server supporting the new Streamable
+
HTTP transport.
+
- If it fails with an HTTP 4xx status code (e.g., 405 Method Not Allowed or 404 Not
+
Found):
+
- Issue a GET request to the server URL, expecting that this will open an SSE stream
+
and return an `endpoint` event as the first event.
+
- When the `endpoint` event arrives, the client can assume this is a server running
+
the old HTTP+SSE transport, and should use that transport for all subsequent
+
communication.
+
+
## Custom Transports
+
+
Clients and servers **MAY** implement additional custom transport mechanisms to suit
+
their specific needs. The protocol is transport-agnostic and can be implemented over any
+
communication channel that supports bidirectional message exchange.
+
+
Implementers who choose to support custom transports **MUST** ensure they preserve the
+
JSON-RPC message format and lifecycle requirements defined by MCP. Custom transports
+
**SHOULD** document their specific connection establishment and message exchange patterns
+
to aid interoperability.