You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Document relatedRequestId routing for bidirectional MCP streams
Add comprehensive documentation for the relatedRequestId routing feature
that enables proper server-to-client request routing in Streamable HTTP
transport. This feature is essential for bidirectional communication
patterns like elicitation where the server needs to send requests back
to the client while maintaining proper request-response pairing.
Related: cloudflare/agents#654
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <[email protected]>
Copy file name to clipboardExpand all lines: src/content/docs/agents/model-context-protocol/transport.mdx
+65Lines changed: 65 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -109,3 +109,68 @@ With these few changes, your MCP server will support both transport methods, mak
109
109
While most MCP clients have not yet adopted the new Streamable HTTP transport, you can start testing it today using [`mcp-remote`](https://www.npmjs.com/package/mcp-remote), an adapter that lets MCP clients that otherwise only support local connections work with remote MCP servers.
110
110
111
111
Follow [this guide](/agents/guides/test-remote-mcp-server/) for instructions on how to connect to your remote MCP server from Claude Desktop, Cursor, Windsurf, and other local MCP clients, using the [`mcp-remote` local proxy](https://www.npmjs.com/package/mcp-remote).
112
+
113
+
## Bidirectional streams with relatedRequestId
114
+
115
+
The Streamable HTTP transport enables true bidirectional communication between MCP clients and servers, allowing servers to initiate requests back to clients while maintaining the correct request-response pairing. This is essential for features like [elicitation](/agents/concepts/human-in-the-loop/), where the server needs to request input from the user during tool execution.
116
+
117
+
### How relatedRequestId routing works
118
+
119
+
When a client sends a request to an MCP server over Streamable HTTP, the server maintains a mapping between the request ID and the HTTP stream. If the server needs to send a server-to-client request (such as `elicitation/create`) while processing the original request, it can use the `relatedRequestId` option to route that message through the same stream.
120
+
121
+
The `WorkerTransport` class automatically handles this routing by:
122
+
123
+
1. Mapping each client request ID to its originating HTTP stream
124
+
2. Using the `relatedRequestId` option from `TransportSendOptions` to determine which stream should receive server-initiated requests
125
+
3. Falling back to a standalone GET stream for messages without a `relatedRequestId`
126
+
127
+
### When to use relatedRequestId
128
+
129
+
Use `relatedRequestId` when your MCP server needs to:
130
+
131
+
- Request user input during tool execution (elicitation)
132
+
- Send progress updates related to a specific client request
133
+
- Make callbacks to the client in response to an ongoing operation
134
+
135
+
Without `relatedRequestId`, server-initiated messages are sent through a separate standalone stream, which may not maintain the proper context for request-response pairing.
136
+
137
+
### Implementation example
138
+
139
+
The Agents SDK handles `relatedRequestId` routing automatically when using `McpAgent`. Here is how the transport layer routes messages:
// Check relatedRequestId first to route server-to-client requests
156
+
// through the same stream as the originating client request
157
+
let requestId=options?.relatedRequestId;
158
+
159
+
// Then override with message.id for responses/errors
160
+
if (isJSONRPCResponse(message) || isJSONRPCError(message)) {
161
+
requestId=message.id;
162
+
}
163
+
164
+
// Route to the appropriate stream based on requestId
165
+
const stream=this.getStreamForRequest(requestId);
166
+
await stream.send(message);
167
+
}
168
+
```
169
+
170
+
</TypeScriptExample>
171
+
172
+
This routing mechanism ensures that server-initiated requests maintain the proper context and are delivered through the correct bidirectional stream, enabling seamless request-response flows for complex interactions like elicitation.
173
+
174
+
:::note
175
+
The `relatedRequestId` routing feature is specific to Streamable HTTP transport and is handled automatically by the `WorkerTransport` class in the Agents SDK. SSE transport does not support this bidirectional routing pattern.
0 commit comments