Skip to content

Commit 32330ba

Browse files
Merge branch 'production' of github.com:cloudflare/cloudflare-docs into production
2 parents 0fedbda + 5df73da commit 32330ba

File tree

8 files changed

+375
-79
lines changed

8 files changed

+375
-79
lines changed

src/components/FieldCatalog.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ const FieldCatalog = ({ fields }: { fields: Fields }) => {
9999

100100
<div className="mb-8! hidden md:block">
101101
<span className="text-sm font-bold text-gray-600 uppercase dark:text-gray-200">
102-
Categories
102+
Categories
103103
</span>
104104

105105
{categories.map((category) => (

src/components/ModelCatalog.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -183,7 +183,7 @@ const ModelCatalog = ({ models }: { models: WorkersAIModelsSchema[] }) => {
183183

184184
<div className="mb-8! hidden md:block">
185185
<span className="text-sm font-bold text-gray-600 uppercase dark:text-gray-200">
186-
Tasks
186+
Tasks
187187
</span>
188188

189189
{tasks.map((task) => (
@@ -216,7 +216,7 @@ const ModelCatalog = ({ models }: { models: WorkersAIModelsSchema[] }) => {
216216

217217
<div className="mb-8! hidden md:block">
218218
<span className="text-sm font-bold text-gray-600 uppercase dark:text-gray-200">
219-
Capabilities
219+
Capabilities
220220
</span>
221221

222222
{capabilities.map((capability) => (
@@ -251,7 +251,7 @@ const ModelCatalog = ({ models }: { models: WorkersAIModelsSchema[] }) => {
251251

252252
<div className="hidden md:block">
253253
<span className="text-sm font-bold text-gray-600 uppercase dark:text-gray-200">
254-
Authors
254+
Authors
255255
</span>
256256

257257
{authors.map((author) => (

src/components/ResourcesBySelector.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export default function ResourcesBySelector({
8181
)}
8282

8383
<div
84-
className={`grid ${columns === 2 ? "grid-cols-2" : "grid-cols-3"} gap-4`}
84+
className={`grid ${columns === 2 ? "md:grid-cols-2" : "md:grid-cols-3"} grid-cols-1 gap-4`}
8585
>
8686
{visibleResources.map((page) => {
8787
const href =

src/components/Stream.astro

Lines changed: 61 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -39,66 +39,68 @@ if (thumbnail) {
3939
}
4040
---
4141

42-
<stream-player data-id={id} data-title={title}>
43-
<div style="position: relative; padding-top: 56.25%">
44-
<iframe
45-
src={url.toString()}
46-
style="border: none; position: absolute; top: 0; left: 0; height: 100%; width: 100%;"
47-
allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;"
48-
allowfullscreen="true"
49-
title={title}
50-
id={id}></iframe>
51-
</div>
52-
53-
{
54-
chapters && (
55-
<p>
56-
<strong>Chapters</strong>
57-
<ul class="flex list-none gap-4 overflow-x-scroll pb-4 pl-0">
58-
{Object.entries(chapters).map(([chapter, time]) => {
59-
const totalSeconds = parse(time, "s");
60-
61-
const thumbnail = new URL(thumbnailUrl);
62-
thumbnail.searchParams.set("fit", "crop");
63-
thumbnail.searchParams.set("time", `${totalSeconds}s`);
64-
65-
return (
66-
<li class="mt-0!">
67-
<button
68-
class="flex h-full w-36 cursor-pointer flex-col rounded-sm border border-gray-200 bg-transparent p-4 dark:border-gray-700"
69-
data-chapter={chapter}
70-
data-time={totalSeconds}
71-
>
72-
<img
73-
src={thumbnail.toString()}
74-
alt={chapter}
75-
width="120"
76-
height="64"
77-
class="border-accent bg-accent/10 rounded-sm border"
78-
/>
79-
<div class="flex h-full flex-col items-center justify-between">
80-
<strong class="line-clamp-2 text-xs" title={chapter}>
81-
{chapter}
82-
</strong>
83-
<Badge text={time} variant="tip" class="w-fit" />
84-
</div>
85-
</button>
86-
</li>
87-
);
88-
})}
89-
</ul>
90-
</p>
91-
)
92-
}
42+
<div>
43+
<stream-player data-id={id} data-title={title}>
44+
<div style="position: relative; padding-top: 56.25%">
45+
<iframe
46+
src={url.toString()}
47+
style="border: none; position: absolute; top: 0; left: 0; height: 100%; width: 100%;"
48+
allow="accelerometer; gyroscope; autoplay; encrypted-media; picture-in-picture;"
49+
allowfullscreen="true"
50+
title={title}
51+
id={id}></iframe>
52+
</div>
53+
54+
{
55+
chapters && (
56+
<p>
57+
<strong>Chapters</strong>
58+
<ul class="flex list-none gap-4 overflow-x-scroll pb-4 pl-0">
59+
{Object.entries(chapters).map(([chapter, time]) => {
60+
const totalSeconds = parse(time, "s");
61+
62+
const thumbnail = new URL(thumbnailUrl);
63+
thumbnail.searchParams.set("fit", "crop");
64+
thumbnail.searchParams.set("time", `${totalSeconds}s`);
65+
66+
return (
67+
<li class="mt-0!">
68+
<button
69+
class="flex h-full w-36 cursor-pointer flex-col rounded-sm border border-gray-200 bg-transparent p-4 dark:border-gray-700"
70+
data-chapter={chapter}
71+
data-time={totalSeconds}
72+
>
73+
<img
74+
src={thumbnail.toString()}
75+
alt={chapter}
76+
width="120"
77+
height="64"
78+
class="border-accent bg-accent/10 rounded-sm border"
79+
/>
80+
<div class="flex h-full flex-col items-center justify-between">
81+
<strong class="line-clamp-2 text-xs" title={chapter}>
82+
{chapter}
83+
</strong>
84+
<Badge text={time} variant="tip" class="w-fit" />
85+
</div>
86+
</button>
87+
</li>
88+
);
89+
})}
90+
</ul>
91+
</p>
92+
)
93+
}
9394

94-
{
95-
showMoreVideos && (
96-
<a href="https://www.youtube.com/@CloudflareDevelopers" target="_blank">
97-
Watch more videos on our Developer Channel
98-
</a>
99-
)
100-
}
101-
</stream-player>
95+
{
96+
showMoreVideos && (
97+
<a href="https://www.youtube.com/@CloudflareDevelopers" target="_blank">
98+
Watch more videos on our Developer Channel
99+
</a>
100+
)
101+
}
102+
</stream-player>
103+
</div>
102104

103105
<script is:inline src="https://embed.cloudflarestream.com/embed/sdk.latest.js"
104106
></script>
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
---
2+
title: Agents SDK adds MCP Elicitation support, http-streamable suppport, task queues, email integration and more
3+
description: Major update brings MCP elicitation, enhanced transport options,auto transport selection, improved error handling, and reliable prop updates, task queues, and email support
4+
products:
5+
- agents
6+
- workers
7+
date: 2025-08-05
8+
---
9+
10+
The latest releases of [@cloudflare/agents](https://github.com/cloudflare/agents) brings major improvements to MCP transport protocols support and agents connectivity. Key updates include:
11+
12+
### MCP elicitation support
13+
14+
MCP servers can now request user input during tool execution, enabling interactive workflows like confirmations, forms, and multi-step processes. This feature uses durable storage to preserve elicitation state even during agent hibernation, ensuring seamless user interactions across agent lifecycle events.
15+
16+
```ts
17+
// Request user confirmation via elicitation
18+
const confirmation = await this.elicitInput({
19+
message: `Are you sure you want to increment the counter by ${amount}?`,
20+
requestedSchema: {
21+
type: "object",
22+
properties: {
23+
confirmed: {
24+
type: "boolean",
25+
title: "Confirm increment",
26+
description: "Check to confirm the increment",
27+
},
28+
},
29+
required: ["confirmed"],
30+
},
31+
});
32+
```
33+
34+
Check out our [demo](https://github.com/whoiskatrin/agents/tree/main/examples/mcp-elicitation-demo) to see elicitation in action.
35+
36+
### HTTP streamable transport for MCP
37+
38+
MCP now supports HTTP streamable transport which is recommended over SSE. This transport type offers:
39+
40+
- **Better performance**: More efficient data streaming and reduced overhead
41+
- **Improved reliability**: Enhanced connection stability and error recover- **Automatic fallback**: If streamable transport is not available, it gracefully falls back to SSE
42+
43+
```ts
44+
export default MyMCP.serve("/mcp", {
45+
binding: "MyMCP",
46+
});
47+
```
48+
49+
The SDK automatically selects the best available transport method, gracefully falling back from streamable-http to SSE when needed.
50+
51+
### Enhanced MCP connectivity
52+
53+
Significant improvements to MCP server connections and transport reliability:
54+
55+
- **Auto transport selection**: Automatically determines the best transport method, falling back from streamable-http to SSE as needed
56+
- **Improved error handling**: Better connection state management and error reporting for MCP servers
57+
- **Reliable prop updates**: Centralized agent property updates ensure consistency across different contexts
58+
59+
### Lightweight .queue for fast task deferral
60+
61+
You can use `.queue()` to enqueue background work — ideal for tasks like processing user messages, sending notifications etc.
62+
63+
```ts
64+
class MyAgent extends Agent {
65+
doSomethingExpensive(payload) {
66+
// a long running process that you want to run in the background
67+
}
68+
69+
queueSomething() {
70+
await this.queue("doSomethingExpensive", somePayload); // this will NOT block further execution, and runs in the background
71+
await this.queue("doSomethingExpensive", someOtherPayload); // the callback will NOT run until the previous callback is complete
72+
// ... call as many times as you want
73+
}
74+
}
75+
```
76+
77+
Want to try it yourself? Just define a method like processMessage in your agent, and you’re ready to scale.
78+
79+
### New email adapter
80+
81+
Want to build an AI agent that can receive and respond to emails automatically? With the new email adapter and onEmail lifecycle method, now you can.
82+
83+
```ts
84+
export class EmailAgent extends Agent {
85+
async onEmail(email: AgentEmail) {
86+
const raw = await email.getRaw();
87+
const parsed = await PostalMime.parse(raw);
88+
89+
// create a response based on the email contents
90+
// and then send a reply
91+
92+
await this.replyToEmail(email, {
93+
fromName: "Email Agent",
94+
body: `Thanks for your email! You've sent us "${parsed.subject}". We'll process it shortly.`,
95+
});
96+
}
97+
}
98+
```
99+
100+
You route incoming mail like this:
101+
102+
```ts
103+
export default {
104+
async email(email, env) {
105+
await routeAgentEmail(email, env, {
106+
resolver: createAddressBasedEmailResolver("EmailAgent"),
107+
});
108+
},
109+
};
110+
```
111+
112+
You can find a full example [here](https://github.com/cloudflare/agents/tree/main/examples/email-agent).
113+
114+
### Automatic context wrapping for custom methods
115+
116+
Custom methods are now automatically wrapped with the agent's context, so calling `getCurrentAgent()` should work regardless of where in an agent's lifecycle it's called. Previously this would not work on RPC calls, but now just works out of the box.
117+
118+
```ts
119+
export class MyAgent extends Agent {
120+
async suggestReply(message) {
121+
// getCurrentAgent() now correctly works, even when called inside an RPC method
122+
const { agent } = getCurrentAgent()!;
123+
return generateText({
124+
prompt: `Suggest a reply to: "${message}" from "${agent.name}"`,
125+
tools: [replyWithEmoji],
126+
});
127+
}
128+
}
129+
```
130+
131+
Try it out and tell us what you build!

0 commit comments

Comments
 (0)