Skip to content

Commit c7157e1

Browse files
Sync documentation for agents v0.2.22
This updates the Cloudflare Agents documentation to reflect changes in version 0.2.22, including: - Added comprehensive changelog entry documenting the release - Added deprecation notice for SSEEdgeClientTransport and StreamableHTTPEdgeClientTransport with migration guide - Documented stateful createMcpHandler usage pattern with WorkerTransport and Durable Objects storage - Added reference to new MCP elicitation example - Updated MCP client and agent API documentation Related to cloudflare/agents#638
1 parent aadeed3 commit c7157e1

File tree

4 files changed

+237
-0
lines changed

4 files changed

+237
-0
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,3 +30,4 @@ pnpm-debug.log*
3030
/worker/functions/
3131

3232
.idea
33+
cloudflare-docs/
Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
---
2+
title: Agents SDK v0.2.22 - MCP client transport deprecation and stateful MCP handler support
3+
description: This release deprecates client edge transports in favor of the official MCP TypeScript SDK transports, adds support for stateful createMcpHandler usage, and includes a new elicitation example demonstrating interactive input collection in MCP servers.
4+
products:
5+
- agents
6+
- workers
7+
date: 2025-11-13
8+
---
9+
10+
We've shipped a new release for the [Agents SDK](https://github.com/cloudflare/agents) that streamlines MCP client transport usage, enhances MCP server capabilities with stateful handlers, and demonstrates best practices for interactive user input.
11+
12+
## MCP Client Transport Deprecation
13+
14+
The custom edge transport implementations (`SSEEdgeClientTransport` and `StreamableHTTPEdgeClientTransport`) have been deprecated in favor of the official transports from the MCP TypeScript SDK.
15+
16+
### Migration Guide
17+
18+
If you're using the deprecated transports, update your imports:
19+
20+
**Before:**
21+
```ts
22+
import { SSEEdgeClientTransport } from "agents/mcp";
23+
import { StreamableHTTPEdgeClientTransport } from "agents/mcp";
24+
```
25+
26+
**After:**
27+
```ts
28+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
29+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
30+
```
31+
32+
The deprecated classes will continue to work with deprecation warnings until the next major version, giving you time to migrate. The official MCP SDK transports provide the same functionality with better compatibility and ongoing support from the MCP community.
33+
34+
## Stateful MCP Handler Support
35+
36+
The `createMcpHandler` function now supports stateful usage patterns, allowing you to build MCP servers that persist state across requests using Durable Objects storage.
37+
38+
This is particularly useful when:
39+
- Building MCP servers with the raw `@modelcontextprotocol/sdk` instead of the `McpAgent` class
40+
- Implementing custom session management
41+
- Supporting MCP features that require persistent state, such as elicitation
42+
43+
### Example: Stateful MCP Server
44+
45+
```ts
46+
import { createMcpHandler, WorkerTransport, type TransportState } from "agents/mcp";
47+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
48+
import { Agent } from "agents";
49+
50+
const STATE_KEY = "mcp_transport_state";
51+
52+
export class MyAgent extends Agent<Env, State> {
53+
server = new McpServer({
54+
name: "stateful-server",
55+
version: "1.0.0"
56+
});
57+
58+
transport = new WorkerTransport({
59+
sessionIdGenerator: () => this.name,
60+
storage: {
61+
get: () => {
62+
return this.ctx.storage.kv.get<TransportState>(STATE_KEY);
63+
},
64+
set: (state: TransportState) => {
65+
this.ctx.storage.kv.put<TransportState>(STATE_KEY, state);
66+
}
67+
}
68+
});
69+
70+
async onMcpRequest(request: Request) {
71+
return createMcpHandler(this.server, {
72+
transport: this.transport
73+
})(request, this.env, {} as ExecutionContext);
74+
}
75+
}
76+
```
77+
78+
The `WorkerTransport` integrates with Durable Objects storage to maintain session state, enabling features like elicitation that require bidirectional communication.
79+
80+
## MCP Elicitation Example
81+
82+
This release includes a new [elicitation example](https://github.com/cloudflare/agents/tree/main/examples/mcp-elicitation) demonstrating how to build interactive MCP tools that collect additional input from users during tool execution.
83+
84+
Elicitation is useful for:
85+
- Collecting user confirmation before performing actions
86+
- Gathering additional parameters not included in the initial request
87+
- Building multi-step workflows with user interaction
88+
- Implementing "human-in-the-loop" patterns
89+
90+
### Example: Interactive Counter Tool
91+
92+
```ts
93+
this.server.registerTool(
94+
"increase-counter",
95+
{
96+
description: "Increase the counter",
97+
inputSchema: {
98+
confirm: z.boolean().describe("Do you want to increase the counter?")
99+
}
100+
},
101+
async ({ confirm }) => {
102+
if (!confirm) {
103+
return {
104+
content: [{ type: "text", text: "Counter increase cancelled." }]
105+
};
106+
}
107+
108+
// Use elicitation to ask for the amount
109+
const basicInfo = await this.server.server.elicitInput({
110+
message: "By how much do you want to increase the counter?",
111+
requestedSchema: {
112+
type: "object",
113+
properties: {
114+
amount: {
115+
type: "number",
116+
title: "Amount",
117+
description: "The amount to increase the counter by",
118+
minLength: 1
119+
}
120+
},
121+
required: ["amount"]
122+
}
123+
});
124+
125+
if (basicInfo.action !== "accept" || !basicInfo.content) {
126+
return {
127+
content: [{ type: "text", text: "Counter increase cancelled." }]
128+
};
129+
}
130+
131+
// Update state with the elicited amount
132+
this.setState({
133+
...this.state,
134+
counter: this.state.counter + Number(basicInfo.content.amount)
135+
});
136+
137+
return {
138+
content: [{
139+
type: "text",
140+
text: `Counter increased by ${basicInfo.content.amount}, current value is ${this.state.counter}`
141+
}]
142+
};
143+
}
144+
);
145+
```
146+
147+
The elicitation example demonstrates how to combine stateful storage with interactive input collection to build sophisticated MCP tools.
148+
149+
## Additional Updates
150+
151+
- Updated dependencies to their latest versions
152+
- Improved compatibility with the MCP TypeScript SDK ecosystem
153+
154+
For more details on these changes, see the [Agents SDK changelog](https://github.com/cloudflare/agents/blob/main/packages/agents/CHANGELOG.md#0222).

src/content/docs/agents/model-context-protocol/mcp-agent-api.mdx

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -133,6 +133,67 @@ export class MyMCP extends McpAgent<Env, State, {}> {
133133

134134
</TypeScriptExample>
135135

136+
### Alternative: Stateful MCP Servers with createMcpHandler
137+
138+
If you need more control over your MCP server implementation or want to use the raw `@modelcontextprotocol/sdk` without extending `McpAgent`, you can use `createMcpHandler` with stateful storage.
139+
140+
This approach is useful when:
141+
- You want to use the MCP SDK directly without the `McpAgent` abstraction
142+
- You need custom session management
143+
- You're implementing MCP features that require persistent state (like elicitation)
144+
145+
<TypeScriptExample>
146+
147+
```ts title="src/index.ts"
148+
import { createMcpHandler, WorkerTransport, type TransportState } from "agents/mcp";
149+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
150+
import { Agent } from "agents";
151+
152+
const STATE_KEY = "mcp_transport_state";
153+
154+
export class MyAgent extends Agent<Env, State> {
155+
server = new McpServer({
156+
name: "stateful-server",
157+
version: "1.0.0"
158+
});
159+
160+
transport = new WorkerTransport({
161+
sessionIdGenerator: () => this.name,
162+
storage: {
163+
get: () => {
164+
return this.ctx.storage.kv.get<TransportState>(STATE_KEY);
165+
},
166+
set: (state: TransportState) => {
167+
this.ctx.storage.kv.put<TransportState>(STATE_KEY, state);
168+
}
169+
}
170+
});
171+
172+
onStart() {
173+
// Register your tools
174+
this.server.registerTool(
175+
"example-tool",
176+
{ description: "An example tool" },
177+
async () => ({
178+
content: [{ type: "text", text: "Hello from stateful MCP!" }]
179+
})
180+
);
181+
}
182+
183+
async onMcpRequest(request: Request) {
184+
return createMcpHandler(this.server, {
185+
transport: this.transport
186+
})(request, this.env, {} as ExecutionContext);
187+
}
188+
}
189+
```
190+
191+
</TypeScriptExample>
192+
193+
The `WorkerTransport` integrates with Durable Objects storage to maintain session state across requests. This enables advanced MCP features like elicitation and persistent tool state.
194+
195+
For a complete example with elicitation support, see the [MCP elicitation example](https://github.com/cloudflare/agents/tree/main/examples/mcp-elicitation).
196+
136197
### Not yet supported APIs
137198

138199
The following APIs from the Agents SDK are not yet available on `McpAgent`:

src/content/docs/agents/model-context-protocol/mcp-client-api.mdx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,6 +272,27 @@ export class MyAgent extends Agent<Env, never> {
272272

273273
</TypeScriptExample>
274274

275+
## Migration from Deprecated Transports
276+
277+
:::note[Deprecated in v0.2.22]
278+
The `SSEEdgeClientTransport` and `StreamableHTTPEdgeClientTransport` classes have been deprecated in favor of the official MCP TypeScript SDK transports. They will be removed in the next major version.
279+
:::
280+
281+
If you're using custom transport classes from `agents/mcp`, update your imports to use the official MCP SDK transports:
282+
283+
**Before:**
284+
```ts
285+
import { SSEEdgeClientTransport, StreamableHTTPEdgeClientTransport } from "agents/mcp";
286+
```
287+
288+
**After:**
289+
```ts
290+
import { SSEClientTransport } from "@modelcontextprotocol/sdk/client/sse.js";
291+
import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js";
292+
```
293+
294+
The official transports provide the same functionality with better compatibility and ongoing support. When using `addMcpServer()`, the transport type is handled automatically, so most applications won't need to specify transports explicitly.
295+
275296
## Next Steps
276297

277298
- [Connect your first MCP server](/agents/guides/connect-mcp-client) — Tutorial to get started

0 commit comments

Comments
 (0)