@@ -12,7 +12,7 @@ The protocol currently defines two standard transport mechanisms for client-serv
12
12
communication:
13
13
14
14
1 . [ stdio] ( #stdio ) , communication over standard in and standard out
15
- 2 . [ HTTP with Server-Sent Events ] ( #http-with-sse ) (SSE )
15
+ 2 . [ Streamable HTTP ] ( #streamable-http )
16
16
17
17
Clients ** SHOULD** support stdio whenever possible.
18
18
@@ -48,38 +48,210 @@ sequenceDiagram
48
48
deactivate Server Process
49
49
```
50
50
51
- ## HTTP with SSE
51
+ ## Streamable HTTP
52
52
53
- In the ** SSE** transport, the server operates as an independent process that can handle
54
- multiple client connections.
53
+ {{< callout type="info" >}} This replaces the [ HTTP+SSE
54
+ transport] ({{< ref "/specification/2024-11-05/basic/transports#http-with-sse" >}}) from
55
+ protocol version 2024-11-05. See the [ backwards compatibility] ( #backwards-compatibility )
56
+ guide below. {{< /callout >}}
55
57
56
- The server ** MUST** provide two endpoints:
58
+ In the ** Streamable HTTP** transport, the server operates as an independent process that
59
+ can handle multiple client connections. This transport uses HTTP POST and GET requests.
60
+ Server can optionally make use of
61
+ [ Server-Sent Events] ( https://en.wikipedia.org/wiki/Server-sent_events ) (SSE) to stream
62
+ multiple server messages. This permits basic MCP servers, as well as more feature-rich
63
+ servers supporting streaming and server-to-client notifications and requests.
57
64
58
- 1 . An SSE endpoint, for clients to establish a connection and receive messages from the
59
- server
60
- 2 . A regular HTTP POST endpoint for clients to send messages to the server
65
+ The server ** MUST ** provide a single HTTP endpoint path (hereafter referred to as the
66
+ ** MCP endpoint ** ) that supports both POST and GET methods. For example, this could be a
67
+ URL like ` https://example.com/mcp ` .
61
68
62
- When a client connects, the server ** MUST** send an ` endpoint ` event containing a URI for
63
- the client to use for sending messages. All subsequent client messages ** MUST** be sent
64
- as HTTP POST requests to this endpoint.
69
+ ### Message Exchange
65
70
66
- Server messages are sent as SSE ` message ` events, with the message content encoded as
67
- JSON in the event data.
71
+ 1 . Every JSON-RPC message sent from the client ** MUST** be a new HTTP POST request to the
72
+ MCP endpoint.
73
+
74
+ 2 . When the client sends a JSON-RPC _ request_ to the MCP endpoint via POST:
75
+
76
+ - The client ** MUST** include an ` Accept ` header, listing both ` application/json ` and
77
+ ` text/event-stream ` as supported content types.
78
+ - The server ** MUST** either return ` Content-Type: text/event-stream ` , to initiate an
79
+ SSE stream, or ` Content-Type: application/json ` , to return a single JSON-RPC
80
+ _ response_ . The client ** MUST** support both these cases.
81
+ - If the server initiates an SSE stream:
82
+ - The SSE stream ** SHOULD** eventually include a JSON-RPC _ response_ message.
83
+ - The server ** MAY** send JSON-RPC _ requests_ and _ notifications_ before sending a
84
+ JSON-RPC _ response_ . These messages ** SHOULD** relate to the originating client
85
+ _ request_ .
86
+ - The server ** SHOULD NOT** close the SSE stream before sending the JSON-RPC
87
+ _ response_ , unless the [ session] ( #session-management ) expires.
88
+ - After the JSON-RPC _ response_ has been sent, the server ** MAY** close the SSE
89
+ stream at any time.
90
+ - Disconnection ** MAY** occur at any time (e.g., due to network conditions).
91
+ Therefore:
92
+ - Disconnection ** SHOULD NOT** be interpreted as the client cancelling its
93
+ request.
94
+ - To cancel, the client ** SHOULD** explicitly send an MCP ` CancelledNotification ` .
95
+ - To avoid message loss due to disconnection, the server ** MAY** make the stream
96
+ [ resumable] ( #resumability-and-redelivery ) .
97
+
98
+ 3 . When the client sends a JSON-RPC _ notification_ or _ response_ to the MCP endpoint via
99
+ POST:
100
+
101
+ - If the server accepts the message, it ** MUST** return HTTP status code 202 Accepted
102
+ with no body.
103
+ - If the server cannot accept the message, it ** MUST** return an HTTP error status
104
+ code (e.g., 400 Bad Request). The HTTP response body ** MAY** comprise a JSON-RPC
105
+ _ error response_ that has no ` id ` .
106
+
107
+ 4 . The client ** MAY** also issue an HTTP GET to the MCP endpoint. This can be used to
108
+ open an SSE stream, allowing the server to communicate to the client without the
109
+ client first sending a JSON-RPC _ request_ .
110
+ - The client ** MUST** include an ` Accept ` header, listing ` text/event-stream ` as a
111
+ supported content type.
112
+ - The server ** MUST** either return ` Content-Type: text/event-stream ` in response to
113
+ this HTTP GET, or else return HTTP 405 Method Not Allowed, indicating that the
114
+ server does not offer an SSE stream at this endpoint.
115
+ - If the server initiates an SSE stream:
116
+ - The server ** MAY** send JSON-RPC _ requests_ and _ notifications_ on the stream.
117
+ These messages ** SHOULD** be unrelated to any concurrently-running JSON-RPC
118
+ _ request_ from the client.
119
+ - The server ** MUST NOT** send a JSON-RPC _ response_ on the stream ** unless**
120
+ [ resuming] ( #resumability-and-redelivery ) a stream associated with a previous
121
+ client request.
122
+ - The server ** MAY** close the SSE stream at any time.
123
+ - The client ** MAY** close the SSE stream at any time.
124
+
125
+ ### Multiple Connections
126
+
127
+ 1 . The client ** MAY** remain connected to multiple SSE streams simultaneously.
128
+ 2 . The server ** MUST** send each of its JSON-RPC messages on only one of the connected
129
+ streams; that is, it ** MUST NOT** broadcast the same message across multiple streams.
130
+ - The risk of message loss ** MAY** be mitigated by making the stream
131
+ [ resumable] ( #resumability-and-redelivery ) .
132
+
133
+ ### Resumability and Redelivery
134
+
135
+ To support resuming broken connections, and redelivering messages that might otherwise be
136
+ lost:
137
+
138
+ 1 . Servers ** MAY** attach an ` id ` field to their SSE events, as described in the
139
+ [ SSE standard] ( https://html.spec.whatwg.org/multipage/server-sent-events.html#event-stream-interpretation ) .
140
+ - If present, the ID ** MUST** be globally unique across all streams within that
141
+ [ session] ( #session-management ) —or all streams with that specific client, if session
142
+ management is not in use.
143
+ 2 . If the client wishes to resume after a broken connection, it ** SHOULD** issue an HTTP
144
+ GET to the MCP endpoint, and include the
145
+ [ ` Last-Event-ID ` ] ( https://html.spec.whatwg.org/multipage/server-sent-events.html#the-last-event-id-header )
146
+ header to indicate the last event ID it received.
147
+ - The server ** MAY** use this header to replay messages that would have been sent
148
+ after the last event ID, _ on the stream that was disconnected_ , and to resume the
149
+ stream from that point.
150
+ - The server ** MUST NOT** replay messages that would have been delivered on a
151
+ different stream.
152
+
153
+ In other words, these event IDs should be assigned by servers on a _ per-stream_ basis, to
154
+ act as a cursor within that particular stream.
155
+
156
+ ### Session Management
157
+
158
+ An MCP "session" consists of logically related interactions between a client and a
159
+ server, beginning with the [ initialization phase] ({{< ref "lifecycle" >}}). To support
160
+ servers which want to establish stateful sessions:
161
+
162
+ 1 . A server using the Streamable HTTP transport ** MAY** assign a session ID at
163
+ initialization time, by including it in an ` Mcp-Session-Id ` header on the HTTP
164
+ response containing the ` InitializeResult ` .
165
+ - The session ID ** SHOULD** be globally unique and cryptographically secure (e.g., a
166
+ securely generated UUID, a JWT, or a cryptographic hash).
167
+ - The session ID ** MUST** only contain visible ASCII characters (ranging from 0x21 to
168
+ 0x7E).
169
+ 2 . If an ` Mcp-Session-Id ` is returned by the server during initialization, clients using
170
+ the Streamable HTTP transport ** MUST** include it in the ` Mcp-Session-Id ` header on
171
+ all of their subsequent HTTP requests.
172
+ - Servers that require a session ID ** SHOULD** respond to requests without an
173
+ ` Mcp-Session-Id ` header (other than initialization) with HTTP 400 Bad Request.
174
+ 3 . The server ** MAY** terminate the session at any time, after which it ** MUST** respond
175
+ to requests containing that session ID with HTTP 404 Not Found.
176
+ 4 . When a client receives HTTP 404 in response to a request containing an
177
+ ` Mcp-Session-Id ` , it ** MUST** start a new session by sending a new ` InitializeRequest `
178
+ without a session ID attached.
179
+ 5 . Clients that no longer need a particular session (e.g., because the user is leaving
180
+ the client application) ** SHOULD** send an HTTP DELETE to the MCP endpoint with the
181
+ ` Mcp-Session-Id ` header, to explicitly terminate the session.
182
+ - The server ** MAY** respond to this request with HTTP 405 Method Not Allowed,
183
+ indicating that the server does not allow clients to terminate sessions.
184
+
185
+ ### Sequence Diagram
68
186
69
187
``` mermaid
70
188
sequenceDiagram
71
189
participant Client
72
190
participant Server
73
191
74
- Client->>Server: Open SSE connection
75
- Server->>Client: endpoint event
76
- loop Message Exchange
77
- Client->>Server: HTTP POST messages
78
- Server->>Client: SSE message events
192
+ note over Client, Server: initialization
193
+
194
+ Client->>+Server: POST InitializeRequest
195
+ Server->>-Client: InitializeResponse<br>Mcp-Session-Id: 1868a90c...
196
+
197
+ Client->>+Server: POST InitializedNotification<br>Mcp-Session-Id: 1868a90c...
198
+ Server->>-Client: 202 Accepted
199
+
200
+ note over Client, Server: client requests
201
+ Client->>+Server: POST ... request ...<br>Mcp-Session-Id: 1868a90c...
202
+
203
+ alt single HTTP response
204
+ Server->>Client: ... response ...
205
+ else server opens SSE stream
206
+ loop while connection remains open
207
+ Server-)Client: ... SSE messages from server ...
208
+ end
209
+ Server-)Client: SSE event: ... response ...
210
+ end
211
+ deactivate Server
212
+
213
+ note over Client, Server: client notifications/responses
214
+ Client->>+Server: POST ... notification/response ...<br>Mcp-Session-Id: 1868a90c...
215
+ Server->>-Client: 202 Accepted
216
+
217
+ note over Client, Server: server requests
218
+ Client->>+Server: GET<br>Mcp-Session-Id: 1868a90c...
219
+ loop while connection remains open
220
+ Server-)Client: ... SSE messages from server ...
79
221
end
80
- Client->>Server: Close SSE connection
222
+ deactivate Server
223
+
81
224
```
82
225
226
+ ### Backwards Compatibility
227
+
228
+ Clients and servers can maintain backwards compatibility with the deprecated [ HTTP+SSE
229
+ transport] ({{< ref "/specification/2024-11-05/basic/transports#http-with-sse" >}}) (from
230
+ protocol version 2024-11-05) as follows:
231
+
232
+ ** Servers** wanting to support older clients should:
233
+
234
+ - Continue to host both the SSE and POST endpoints of the old transport, alongside the
235
+ new "MCP endpoint" defined for the Streamable HTTP transport.
236
+ - It is also possible to combine the old POST endpoint and the new MCP endpoint, but
237
+ this may introduce unneeded complexity.
238
+
239
+ ** Clients** wanting to support older servers should:
240
+
241
+ 1 . Accept an MCP server URL from the user, which may point to either a server using the
242
+ old transport or the new transport.
243
+ 2 . Attempt to POST an ` InitializeRequest ` to the server URL, with an ` Accept ` header as
244
+ defined above:
245
+ - If it succeeds, the client can assume this is a server supporting the new Streamable
246
+ HTTP transport.
247
+ - If it fails with an HTTP 4xx status code (e.g., 405 Method Not Allowed or 404 Not
248
+ Found):
249
+ - Issue a GET request to the server URL, expecting that this will open an SSE stream
250
+ and return an ` endpoint ` event as the first event.
251
+ - When the ` endpoint ` event arrives, the client can assume this is a server running
252
+ the old HTTP+SSE transport, and should use that transport for all subsequent
253
+ communication.
254
+
83
255
## Custom Transports
84
256
85
257
Clients and servers ** MAY** implement additional custom transport mechanisms to suit
0 commit comments