Skip to content

Commit 732fdd2

Browse files
committed
Simplify what goes into which stream; disallow streaming on notifs/responses
1 parent b3364c9 commit 732fdd2

File tree

1 file changed

+39
-41
lines changed

1 file changed

+39
-41
lines changed

docs/specification/draft/basic/transports.md

Lines changed: 39 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ URL like `https://example.com/mcp`.
7171
1. Every JSON-RPC message sent from the client **MUST** be a new HTTP POST request to the
7272
MCP endpoint.
7373

74-
2. When the client sends a JSON-RPC _request_ message to the MCP endpoint via POST:
74+
2. When the client sends a JSON-RPC _request_ to the MCP endpoint via POST:
7575

7676
- The client **MUST** include an `Accept` header, listing both `application/json` and
7777
`text/event-stream` as supported content types.
@@ -80,8 +80,9 @@ URL like `https://example.com/mcp`.
8080
_response_. The client **MUST** support both these cases.
8181
- If the server initiates an SSE stream:
8282
- The SSE stream **SHOULD** eventually include a JSON-RPC _response_ message.
83-
- The server **MAY** send JSON-RPC _requests_ and JSON-RPC _notifications_ before
84-
sending a JSON-RPC _response_.
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_.
8586
- The server **SHOULD NOT** close the SSE stream before sending the JSON-RPC
8687
_response_.
8788
- After the JSON-RPC _response_ has been sent, the server **MAY** close the SSE
@@ -92,59 +93,34 @@ URL like `https://example.com/mcp`.
9293
3. When the client sends a JSON-RPC _notification_ or _response_ to the MCP endpoint via
9394
POST:
9495

95-
- The client **MUST** include an `Accept` header, listing `text/event-stream` as a
96-
supported content type.
97-
- The server **MUST** either return `Content-Type: text/event-stream`, to initiate an
98-
SSE stream, or else HTTP status code 202 Accepted with no body. The client **MUST**
99-
support both these cases.
100-
- If the server initiates an SSE stream:
101-
- The receipt of the message is acknowledged as soon as the HTTP status code is
102-
received (before the SSE stream begins).
103-
- The server **MAY** close the SSE stream at any time.
104-
- The client **MAY** close the SSE stream at any time.
96+
- If the server accepts the message, it **MUST** return HTTP status code 202 Accepted
97+
with no body.
98+
- If the server cannot accept the message, it **MUST** return an HTTP error status
99+
code (e.g., 400 Bad Request). The HTTP response body **MAY** comprise a JSON-RPC
100+
_error response_ that has no `id`.
105101

106102
4. The client **MAY** also issue an HTTP GET to the MCP endpoint. This can be used to
107-
open an SSE stream (allowing the server to communicate to the client) without having
108-
first sent a _request_, _notification_, or _response_.
103+
open an SSE stream, allowing the server to communicate to the client without the
104+
client first sending a JSON-RPC _request_.
109105
- The client **MUST** include an `Accept` header, listing `text/event-stream` as a
110106
supported content type.
111107
- The server **MUST** either return `Content-Type: text/event-stream` in response to
112-
this HTTP GET, or else error out with HTTP 406 Not Acceptable, indicating that the
108+
this HTTP GET, or else return HTTP 405 Method Not Allowed, indicating that the
113109
server does not offer an SSE stream at this endpoint.
114110
- If the server initiates an SSE stream:
111+
- The server **MAY** send JSON-RPC _requests_ and _notifications_ on the stream.
112+
These messages **SHOULD** be unrelated to any concurrently-running JSON-RPC
113+
_request_ from the client.
114+
- The server **MUST NOT** send JSON-RPC _responses_ on the stream.
115115
- The server **MAY** close the SSE stream at any time.
116116
- The client **MAY** close the SSE stream at any time.
117117

118-
### Session Management
119-
120-
Where a client desires to share a single logical session across multiple requests, it
121-
**MAY** attach an `Mcp-Session-Id` HTTP header to its requests. This permits maintenance
122-
of session state across separate POSTs.
123-
124-
1. It is the client's responsibility to generate or select the session ID.
125-
2. This session ID **SHOULD** be globally unique and cryptographically secure (e.g., a
126-
UUID or a JWT), unless it is specifically desired to share a session ID across users
127-
or clients.
128-
3. The server **MAY** use this header to associate state with the logical session.
129-
- If the server agrees to re-establish an existing session, it **MUST** include a
130-
`Mcp-Session-Status: resumed` HTTP header in its response.
131-
- If the server begins a new session associated with the session ID, it **MUST**
132-
include a `Mcp-Session-Status: created` HTTP header in its response.
133-
- The server **MAY** delete session state at any time; however, it **MUST NOT**
134-
prevent the same session ID from creating a new session again in future.
135-
4. If [authorization]({{< ref "authorization" >}}) is used _and_ the server makes use of
136-
the `Mcp-Session-Id` header:
137-
- The server **SHOULD** bind the session ID to the authorization context, and return
138-
an error if the session ID is reused in a different authorization context.
139-
140118
### Multiple Connections
141119

142120
1. The client **MAY** remain connected to multiple SSE streams simultaneously.
143121
2. The server **MUST** send each of its JSON-RPC messages on only one of the connected
144122
streams; that is, it **MUST NOT** broadcast the same message across multiple streams.
145-
The server **MAY** use different streams for _different_ messages.
146-
- The server can mitigate the risk of message loss by supporting
147-
[resumability and redelivery](#resumability-and-redelivery).
123+
- The risk of message loss can be mitigated by making the stream [resumable](#resumability-and-redelivery).
148124

149125
### Resumability and Redelivery
150126

@@ -167,6 +143,28 @@ lost:
167143
other streams which _nominally_ remain open are in fact dead, and should be
168144
terminated.
169145

146+
### Session Management
147+
148+
Where a client desires to share a single logical session across multiple requests, it
149+
**MAY** attach an `Mcp-Session-Id` HTTP header to its requests. This permits maintenance
150+
of session state across separate POSTs.
151+
152+
1. It is the client's responsibility to generate or select the session ID.
153+
2. This session ID **SHOULD** be globally unique and cryptographically secure (e.g., a
154+
UUID or a JWT), unless it is specifically desired to share a session ID across users
155+
or clients.
156+
3. The server **MAY** use this header to associate state with the logical session.
157+
- If the server agrees to re-establish an existing session, it **MUST** include a
158+
`Mcp-Session-Status: resumed` HTTP header in its response.
159+
- If the server begins a new session associated with the session ID, it **MUST**
160+
include a `Mcp-Session-Status: created` HTTP header in its response.
161+
- The server **MAY** delete session state at any time; however, it **MUST NOT**
162+
prevent the same session ID from creating a new session again in future.
163+
4. If [authorization]({{< ref "authorization" >}}) is used _and_ the server makes use of
164+
the `Mcp-Session-Id` header:
165+
- The server **SHOULD** bind the session ID to the authorization context, and return
166+
an error if the session ID is reused in a different authorization context.
167+
170168
### Sequence Diagram
171169

172170
```mermaid

0 commit comments

Comments
 (0)