agents 0.30.1 → 0.31.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. package/README.md +2 -1
  2. package/dist/{agent-routing-CDbpVjYq.d.ts → agent-routing-wS1TimZ_.d.ts} +64 -603
  3. package/dist/agent-routing.d.ts +1 -1
  4. package/dist/agent-tool-types.d.ts +1 -1
  5. package/dist/{agent-tools-C8DH8Yii.d.ts → agent-tools-Bamxxb6Y.d.ts} +2 -2
  6. package/dist/agent-tools.d.ts +1 -1
  7. package/dist/{ai-iXw0uOGj.d.ts → ai-CDn3Abax.d.ts} +30 -4
  8. package/dist/{ai-sdk-DRPh2rRa.js → ai-sdk-Kon40i0q.js} +2 -36
  9. package/dist/ai-sdk-Kon40i0q.js.map +1 -0
  10. package/dist/ai-sdk-hW3vntnk.d.ts +72 -0
  11. package/dist/browser/ai.d.ts +1 -1
  12. package/dist/browser/ai.js +16 -3
  13. package/dist/browser/ai.js.map +1 -1
  14. package/dist/browser/index.d.ts +64 -16
  15. package/dist/browser/index.js +4 -4
  16. package/dist/browser/tools/ai-sdk.d.ts +7 -70
  17. package/dist/browser/tools/ai-sdk.js +4 -4
  18. package/dist/browser/tools/ai-sdk.js.map +1 -1
  19. package/dist/browser/tools/pi.d.ts +9 -15
  20. package/dist/browser/tools/pi.js +6 -14
  21. package/dist/browser/tools/pi.js.map +1 -1
  22. package/dist/browser/tools/tanstack-ai.d.ts +46 -23
  23. package/dist/browser/tools/tanstack-ai.js +8 -4
  24. package/dist/browser/tools/tanstack-ai.js.map +1 -1
  25. package/dist/{browser-DccPw_wW.js → browser-1eUbPvC2.js} +413 -14
  26. package/dist/browser-1eUbPvC2.js.map +1 -0
  27. package/dist/{browser-DlXhSAdf.d.ts → browser-D9RNpJuT.d.ts} +254 -20
  28. package/dist/browser-tool-BhjCcNVE.d.ts +71 -0
  29. package/dist/browser-tool-lGnvEBLJ.js +497 -0
  30. package/dist/browser-tool-lGnvEBLJ.js.map +1 -0
  31. package/dist/capability-id-B3J8Nok_.js +13 -0
  32. package/dist/capability-id-B3J8Nok_.js.map +1 -0
  33. package/dist/chat/index.d.ts +2 -2
  34. package/dist/chat-sdk/index.d.ts +3 -3
  35. package/dist/chat-sdk/index.js +1 -1
  36. package/dist/client-4OlMIJx-.js.map +1 -1
  37. package/dist/{client-BnYbNT3z.js → client-DMWujQJ1.js} +68 -244
  38. package/dist/client-DMWujQJ1.js.map +1 -0
  39. package/dist/{client-C27CtRZr.d.ts → client-wn4-yqGz.d.ts} +9 -7
  40. package/dist/client.d.ts +1 -1
  41. package/dist/{connector-DAXBOIIi.js → connector-CM-uuxKM.js} +96 -8
  42. package/dist/connector-CM-uuxKM.js.map +1 -0
  43. package/dist/{connector-20DJ6p4k.d.ts → connector-DZ71EjE-.d.ts} +109 -9
  44. package/dist/experimental/webmcp.js +1 -1
  45. package/dist/{handler-stateless-Bly_nSH3.js → handler-stateless-B5hU3dxK.js} +35 -2
  46. package/dist/handler-stateless-B5hU3dxK.js.map +1 -0
  47. package/dist/{handler-stateless-DxYpJ_XF.d.ts → handler-stateless-C90kD5_R.d.ts} +3 -47
  48. package/dist/harness/container/index.d.ts +15 -15
  49. package/dist/harness/opencode/index.js.map +1 -1
  50. package/dist/harness/pi/index.d.ts +4 -3
  51. package/dist/harness/pi/index.js +31 -10
  52. package/dist/harness/pi/index.js.map +1 -1
  53. package/dist/harness/think/index.d.ts +2 -1
  54. package/dist/{images-xaDv2Fqe.js → images-CfuRCjwq.js} +1 -5
  55. package/dist/images-CfuRCjwq.js.map +1 -0
  56. package/dist/{index-DCxk3OSJ.d.ts → index-8k4qsX1T.d.ts} +2 -28
  57. package/dist/index.d.ts +14 -14
  58. package/dist/index.js +2 -2
  59. package/dist/internal-hosts-Kfp5A392.d.ts +230 -0
  60. package/dist/internal-kmw70xwR.js.map +1 -1
  61. package/dist/invoker-BC1SZ3q1.js +26 -0
  62. package/dist/invoker-BC1SZ3q1.js.map +1 -0
  63. package/dist/invoker-DoLFPJZV.d.ts +21 -0
  64. package/dist/mcp/client/index.d.ts +15 -1
  65. package/dist/mcp/client/index.js +2 -2
  66. package/dist/mcp/client/x402.d.ts +7 -5
  67. package/dist/mcp/client/x402.js +34 -1
  68. package/dist/mcp/client/x402.js.map +1 -1
  69. package/dist/mcp/index.d.ts +561 -27
  70. package/dist/mcp/index.js +180 -3
  71. package/dist/mcp/index.js.map +1 -1
  72. package/dist/mcp/server/index.d.ts +1 -1
  73. package/dist/mcp/server/index.js +1 -1
  74. package/dist/models/ai-sdk/index.d.ts +2 -2
  75. package/dist/models/ai-sdk/index.js +1 -1
  76. package/dist/models/opencode/index.d.ts +2 -2
  77. package/dist/models/opencode/index.js +1 -1
  78. package/dist/models/pi-ai/index.d.ts +3 -28
  79. package/dist/models/pi-ai/index.js +31 -16
  80. package/dist/models/pi-ai/index.js.map +1 -1
  81. package/dist/protocol-BEgrJYC5.d.ts +29 -29
  82. package/dist/react.d.ts +2 -2
  83. package/dist/routing/index.d.ts +1 -1
  84. package/dist/serializable.d.ts +1 -1
  85. package/dist/{session-store-yvwq1f9x.js → session-7CDgVE0z.js} +455 -33
  86. package/dist/session-7CDgVE0z.js.map +1 -0
  87. package/dist/{session-store-_IK6dV-w.d.ts → session-store-B7Ca-u1t.d.ts} +8 -1
  88. package/dist/settings-Dk2il2Hf.js.map +1 -1
  89. package/dist/{src-DfLzdwlK.js → src-BGolXG_H.js} +18 -2
  90. package/dist/src-BGolXG_H.js.map +1 -0
  91. package/dist/sub-routing.d.ts +12 -12
  92. package/dist/tool-CTp72Jb_.d.ts +10 -10
  93. package/dist/tool-DoVberpN.d.ts +22 -22
  94. package/dist/tool-helpers-BodWi4gd.js +256 -0
  95. package/dist/tool-helpers-BodWi4gd.js.map +1 -0
  96. package/dist/{transport-CPh7YGiw.d.ts → transport-5moD2pW5.d.ts} +1 -43
  97. package/dist/types-D2naO3rA.d.ts +49 -0
  98. package/dist/voice/index.d.ts +1 -1
  99. package/dist/workflow-types.d.ts +1 -1
  100. package/dist/workflows.d.ts +1 -1
  101. package/dist/workflows.js +1 -1
  102. package/docs/browse-the-web.md +247 -413
  103. package/docs/harnesses/pi.md +27 -27
  104. package/docs/index.md +4 -4
  105. package/docs/mcp-client.md +2 -0
  106. package/docs/mcp-servers.md +25 -6
  107. package/docs/models-pi-ai.md +9 -11
  108. package/docs/models.md +1 -8
  109. package/docs/securing-mcp-servers.md +113 -302
  110. package/package.json +8 -3
  111. package/dist/ai-sdk-DRPh2rRa.js.map +0 -1
  112. package/dist/browser-DccPw_wW.js.map +0 -1
  113. package/dist/browser-tool-B1mhifin.js +0 -616
  114. package/dist/browser-tool-B1mhifin.js.map +0 -1
  115. package/dist/browser-tool-Cxjk5sgG.d.ts +0 -92
  116. package/dist/client-BnYbNT3z.js.map +0 -1
  117. package/dist/connector-DAXBOIIi.js.map +0 -1
  118. package/dist/handler-stateless-Bly_nSH3.js.map +0 -1
  119. package/dist/images-xaDv2Fqe.js.map +0 -1
  120. package/dist/invoker-CG0_p_Wq.d.ts +0 -20
  121. package/dist/invoker-CHMnoxIA.js +0 -57
  122. package/dist/invoker-CHMnoxIA.js.map +0 -1
  123. package/dist/session-store-yvwq1f9x.js.map +0 -1
  124. package/dist/src-DfLzdwlK.js.map +0 -1
  125. package/dist/tool-helpers-O5BDVEAY.js +0 -58
  126. package/dist/tool-helpers-O5BDVEAY.js.map +0 -1
@@ -1,10 +1,10 @@
1
1
  ---
2
- title: Pi harness (Beta)
2
+ title: Pi harness
3
3
  pcx_content_type: get-started
4
- description: Host pi-durable sessions in a Durable Object with the beta PiHarness lifecycle capability. Connect a pi-ai model, add tools and skills, and keep sessions running across eviction.
4
+ description: Host pi-durable sessions in a Durable Object with the PiHarness lifecycle capability. Connect a pi-ai model, add tools and skills, and keep sessions running across eviction.
5
5
  ---
6
6
 
7
- `PiHarness` hosts [pi-durable](https://github.com/earendil-works/pi/tree/main/packages/durable) in a Durable Object. It opens Pi over the object's SQLite database and connects Pi's sessions to the Agents SDK lifecycle, which wakes sessions with work after eviction. The API is in beta and may change.
7
+ `PiHarness` hosts [pi-durable](https://github.com/earendil-works/pi/tree/main/packages/durable) in a Durable Object. It opens Pi over the object's SQLite database and connects Pi's sessions to the Agents SDK lifecycle, which wakes sessions with work after eviction.
8
8
 
9
9
  Pi owns everything about a run: the transcript, the inbox of steers and follow-ups, generation, tool calls, retries, and crash recovery. `PiHarness` supplies the storage and the wake. It does not provide a chat protocol or user interface. Your application chooses how clients reach sessions, such as WebSockets, HTTP, or RPC.
10
10
 
@@ -21,13 +21,14 @@ The three Pi packages are optional peer dependencies of `agents`, at `~1.4.0`. p
21
21
  `PiHarness` uses a factory function to construct Pi's `Harness` so it can be instantiated lazily:
22
22
 
23
23
  ```ts
24
+ import { DurableObject } from "cloudflare:workers";
24
25
  import { createModels } from "@earendil-works/pi-ai/models";
25
26
  import { createRegistry, Harness } from "@earendil-works/pi-durable";
26
- import { Agent } from "agents";
27
27
  import { PiHarness } from "agents/harness/pi";
28
+ import { Lifecycle } from "agents/lifecycle";
28
29
  import { createAI } from "agents/models/pi-ai";
29
30
 
30
- export class Assistant extends Agent<Env> {
31
+ export class Assistant extends DurableObject<Env> {
31
32
  ai = createAI({ binding: this.env.AI });
32
33
  registry = createRegistry();
33
34
 
@@ -42,15 +43,12 @@ export class Assistant extends Agent<Env> {
42
43
  );
43
44
  },
44
45
  defaults: {
45
- model: this.ai("@cf/zai-org/glm-4.7-flash"),
46
+ model: this.ai("@cf/zai-org/glm-5.3-flash"),
46
47
  thinkingLevel: "low"
47
48
  }
48
49
  });
49
50
 
50
- constructor(ctx: DurableObjectState, env: Env) {
51
- super(ctx, env);
52
- this.lifecycle.use(this.harness);
53
- }
51
+ lifecycle = Lifecycle.install(this).use(this.harness);
54
52
 
55
53
  async ask(prompt: string) {
56
54
  return (await this.harness.prompt(prompt)).text;
@@ -58,6 +56,8 @@ export class Assistant extends Agent<Env> {
58
56
  }
59
57
  ```
60
58
 
59
+ `PiHarness` is a Lifecycle capability, so it runs on a plain Durable Object. `Lifecycle.install(this)` gives the object its startup, alarms and job queue, and `.use(this.harness)` installs the harness on it. The object needs a SQLite migration in your Wrangler configuration, like any Durable Object that uses SQLite storage. To use it from an `Agent`, which already has a lifecycle, call `this.lifecycle.use(this.harness)` in the constructor instead.
60
+
61
61
  | Option | What it is |
62
62
  | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
63
63
  | `harness` | Required. Receives `{ storage, context, onWake }` and returns Pi's `Harness`, usually from `Harness.open`. Pass `onWake` to `Harness.open`, so the object can hibernate while Pi's tasks sleep (see [How recovery works](#how-recovery-works)). Models, the registry, `settings`, `env` and `onReport` are all yours to build here. |
@@ -149,7 +149,7 @@ harness: async ({ storage, context, onWake }) => {
149
149
  this.registry.install({
150
150
  name: "browser",
151
151
  tools: [
152
- browserTool({ ctx: this.ctx, browser: this.browser, loader: this.env.LOADER })
152
+ browserTool({ browser: this.browser, loader: this.env.LOADER })
153
153
  ]
154
154
  });
155
155
  return Harness.open(
@@ -162,7 +162,7 @@ harness: async ({ storage, context, onWake }) => {
162
162
  readonly lifecycle = Lifecycle.install(this).use(this.browser).use(this.harness);
163
163
  ```
164
164
 
165
- It needs a `browser` binding, a `LOADER` Worker Loader binding, and `export { CodemodeRuntime } from "@cloudflare/codemode"` from the Worker entry. Screenshots come back as images, and each conversation works in its own tab. Refer to [Persistent browser](../browse-the-web.md#persistent-browser) for how it behaves.
165
+ It needs a `browser` binding, a `LOADER` Worker Loader binding, and `@cloudflare/codemode` installed (only until the deprecated codemode browser APIs are removed from `agents/browser`). Screenshots come back as images, and each conversation works in its own tab. Refer to [Persistent browser](../browse-the-web.md#persistent-browser) for how it behaves.
166
166
 
167
167
  ## Work with sessions
168
168
 
@@ -174,7 +174,7 @@ const { text } = await this.harness.prompt("What is 47 × 19?");
174
174
 
175
175
  // Another session, on a cheaper model.
176
176
  const session = await this.harness.sessions.create();
177
- await session.setModel(this.ai("@cf/zai-org/glm-4.7-flash"));
177
+ await session.setModel(this.ai("@cf/zai-org/glm-5.3-flash"));
178
178
 
179
179
  // Durable once it returns; the same operation id twice is one submission.
180
180
  const receipt = await session.submit("Summarize the latest report", {
@@ -183,20 +183,20 @@ const receipt = await session.submit("Summarize the latest report", {
183
183
  const result = await session.wait(receipt.operationId);
184
184
  ```
185
185
 
186
- | Call | What it does |
187
- | ------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
188
- | `prompt(input)` | Submits and waits: the answer, and the transcript after it. |
189
- | `submit(input, { operationId, whenBusy, entry })` | Hands the input to Pi and returns as soon as Pi has saved it, without waiting for the model. If the session is already working, the input waits until that work finishes. With `whenBusy: "steer"`, it joins the running work instead, after the current round of tool calls. `entry` records where the input came from (see below). |
190
- | `wait(operationId, signal?)` | The operation's result once Pi settles it. Aborting `signal` stops only the wait, not the work. |
191
- | `steer(input)` | `submit` with `whenBusy: "steer"`. |
192
- | `abort(operationId?)` | Withdraws a queued operation, or with no id, stops everything running in the session. |
193
- | `pending()` | Operations Pi has not settled yet: queued, part of the running work, or `parked` (see [How recovery works](#how-recovery-works)). |
194
- | `retry()` | Runs again the tasks Pi's restart limit parked in the session's work. Resolves `false` when nothing was parked. |
195
- | `messages()` | Pi's transcript entries since the newest reset. |
196
- | `events()` | Pi's agent events: a `snapshot`, then one batch per commit. |
197
- | `reset(handoff?)` | Starts a new context, optionally from a handoff note. |
198
- | `setModel(model)` | Changes this session's model. |
199
- | `busy()` | Whether a run is going. |
186
+ | Call | What it does |
187
+ | ------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
188
+ | `prompt(input)` | Submits and waits: the answer, and the transcript after it. |
189
+ | `submit(input, { operationId, whenBusy, entry })` | Hands the input to Pi and returns as soon as Pi has saved it, without waiting for the model. If the session is already working, the input waits until that work finishes. With `whenBusy: "steer"`, it joins the running work instead, after the current round of tool calls. With `whenBusy: "reject"`, it is not admitted: `submit` rejects with Pi's `ConversationBusy` and nothing is saved, so the same `operationId` can be submitted again later. `entry` records where the input came from (see below). |
190
+ | `wait(operationId, signal?)` | The operation's result once Pi settles it. Aborting `signal` stops only the wait, not the work. |
191
+ | `steer(input)` | `submit` with `whenBusy: "steer"`. |
192
+ | `abort(operationId?)` | Withdraws a queued operation, or with no id, stops everything running in the session. |
193
+ | `pending()` | Operations Pi has not settled yet: queued, part of the running work, or `parked` (see [How recovery works](#how-recovery-works)). |
194
+ | `retry()` | Runs again the tasks Pi's restart limit parked in the session's work. Resolves `false` when nothing was parked. |
195
+ | `messages()` | Pi's transcript entries since the newest reset. |
196
+ | `events()` | Pi's agent events: a `snapshot`, then one batch per commit. |
197
+ | `reset(handoff?)` | Starts a new context, optionally from a handoff note. |
198
+ | `setModel(model)` | Changes this session's model. |
199
+ | `busy()` | Whether a run is going. |
200
200
 
201
201
  `harness.prompt()`, `submit()`, `wait()`, `abort()`, `retry()`, `messages()` and `pending()` act on the root session, or on `{ session }`. `harness.sessions` has `create()`, `fork(from)`, `get(id)` and `list()`, which includes sessions subagents created. `ROOT_SESSION` is the root's id.
202
202
 
package/docs/index.md CHANGED
@@ -49,7 +49,7 @@ The Lifecycle runs startup, routes requests to capabilities, and owns the object
49
49
 
50
50
  ## Harnesses
51
51
 
52
- - [Pi harness (Beta)](./harnesses/pi.md) - Host pi-durable sessions in a Durable Object with durable storage and lifecycle wakeups
52
+ - [Pi harness](./harnesses/pi.md) - Host pi-durable sessions in a Durable Object with durable storage and lifecycle wakeups
53
53
  - [Think harness (Experimental)](./harnesses/think.md) - Run Think's agent loop as a Lifecycle capability, with transcripts in Sessions, output in Streams, and turns that survive eviction
54
54
  - [Think (Experimental)](https://github.com/cloudflare/agents/blob/main/docs/think/index.md) - Opinionated chat agent with built-in memory, tools, and streaming. Extends `Think`, which builds on `Agent`.
55
55
 
@@ -136,12 +136,12 @@ Building your own harness? Sessions stores the conversation, Streams holds durab
136
136
  - TODO: [AI SDK Integration](./ai-sdk.md) - Using Vercel AI SDK with agents
137
137
  - TODO: [TanStack Integration](./tanstack.md) - Using TanStack AI with agents
138
138
  - TODO: [Using AI Models](./using-ai-models.md) - OpenAI, Anthropic, Workers AI, and other providers
139
- - [Models (Experimental)](./models.md) - `createAI` — one AI SDK provider for Workers AI and third-party catalog models, same string space
140
- - [Models for pi-ai (Beta)](./models-pi-ai.md) - `createAI` for pi-ai: Workers AI ids and third-party models through AI Gateway, as a pi-ai provider
139
+ - [Models](./models.md) - `createAI` — one AI SDK provider for Workers AI and third-party catalog models, same string space
140
+ - [Models for pi-ai](./models-pi-ai.md) - `createAI` for pi-ai: Workers AI ids and third-party models through AI Gateway, as a pi-ai provider
141
141
  - [Context (Experimental)](./context.md) - System-prompt blocks, frozen prompts, writable/searchable/loadable providers, and their tools
142
142
  - [Workspace (Experimental)](https://github.com/cloudflare/agents/blob/main/docs/shell/index.md) - Durable virtual filesystem backed by SQLite + R2
143
143
  - [Codemode (Experimental)](./codemode.md) - LLM-generated executable code for tool orchestration
144
- - [Browse the Web (Experimental)](./browse-the-web.md) - Full CDP access for web inspection, scraping, and debugging
144
+ - [Browse the Web](./browse-the-web.md) - Full CDP access for web inspection, scraping, and debugging
145
145
  - [Search the Web (Beta)](./search-the-web.md) - A `websearch` tool over Cloudflare's Web Search API for the pi harness, the AI SDK, and TanStack AI
146
146
  - [Fetch the Web (Beta)](./fetch-the-web.md) - A `web_fetch` tool that reads a URL as Markdown, JSON, or text, with a host-controlled URL policy, for the pi harness, the AI SDK, TanStack AI, and Think
147
147
  - TODO: [Cloudflare Sandboxes](./sandboxes.md) - Isolated environments for coding agents, ffmpeg, and heavy compute
@@ -63,6 +63,8 @@ Install the exact MCP client peer used by this Agents release:
63
63
  pnpm add agents @modelcontextprotocol/client@2.3.1
64
64
  ```
65
65
 
66
+ The MCP client does not need `@modelcontextprotocol/sdk` or `@modelcontextprotocol/server`. Those packages are optional peers used only by the MCP server APIs.
67
+
66
68
  ```typescript
67
69
  import { Agent } from "agents";
68
70
 
@@ -8,7 +8,9 @@ Build an MCP server on Workers with `createMcpHandler` from `agents/mcp/server`
8
8
  pnpm add agents @modelcontextprotocol/server@2.3.1 zod
9
9
  ```
10
10
 
11
- Use the exact `@modelcontextprotocol/server` version required by your installed Agents release.
11
+ `@modelcontextprotocol/server` is an optional peer dependency of `agents`, so your package manager does not install it for you. Use the exact version required by your installed Agents release.
12
+
13
+ Upgrading a server that uses `McpAgent`? See [Upgrading an existing `McpAgent` server](#upgrading-an-existing-mcpagent-server).
12
14
 
13
15
  ## Create a server
14
16
 
@@ -150,6 +152,7 @@ Wrap the handler with `OAuthProvider` from `@cloudflare/workers-oauth-provider`
150
152
  ```typescript
151
153
  import { OAuthProvider } from "@cloudflare/workers-oauth-provider";
152
154
  import { createMcpHandler, getMcpAuthContext } from "agents/mcp/server";
155
+ import { env } from "cloudflare:workers";
153
156
 
154
157
  function createServer() {
155
158
  const server = new McpServer({ name: "Authenticated", version: "1.0.0" });
@@ -189,15 +192,17 @@ export default new OAuthProvider({
189
192
  return mcpHandler(request, env, ctx);
190
193
  }
191
194
  },
192
- defaultHandler: AuthHandler // your consent and login flow
195
+ defaultHandler: AuthHandler, // your consent and login flow
196
+ // The URL MCP clients connect to. Every token is bound to it.
197
+ resourceMetadata: { resource: env.MCP_RESOURCE }
193
198
  });
194
199
  ```
195
200
 
196
201
  `OAuthProvider` needs an object with a `fetch` method, so wrap the handler as shown. Passing the handler function directly throws at startup.
197
202
 
198
- `getMcpAuthContext().props` returns the `props` you passed to `completeAuthorization()` in your auth flow. Tool callbacks also receive the standard SDK v2 `AuthInfo` at `context.http.authInfo`. Do not log or return `context.http.authInfo.token` or `authInfo.extra.props`.
203
+ `getMcpAuthContext().props` returns the `props` you passed to `completeAuthorization()` in your auth flow. Tool callbacks also receive the standard SDK v2 `AuthInfo` at `context.http.authInfo`. `authInfo` is set only when the token has a client ID and `props` is a plain object. Tokens from `resolveExternalToken` have no client ID, so for those only `getMcpAuthContext().props` is available. Do not log or return `context.http.authInfo.token` or `authInfo.extra.props`.
199
204
 
200
- The OAuth flow needs a KV namespace bound as `OAUTH_KV`. For a complete server with a login page, see [`examples/mcp-worker-authenticated`](https://github.com/cloudflare/agents/tree/main/examples/mcp-worker-authenticated). For consent dialogs, CSRF, and proxying to a third-party identity provider, see [Securing MCP Servers](./securing-mcp-servers.md).
205
+ Set `MCP_RESOURCE` in `wrangler.jsonc` to the URL clients connect to: Workers OAuth Provider 1.x binds every token to it. The OAuth flow also needs a KV namespace bound as `OAUTH_KV`. For a complete server with a login page, see [`examples/mcp-worker-authenticated`](https://github.com/cloudflare/agents/tree/main/examples/mcp-worker-authenticated). For the consent page and signing in through a third-party provider, see [Securing MCP Servers](./securing-mcp-servers.md).
201
206
 
202
207
  ## Elicitation
203
208
 
@@ -269,9 +274,23 @@ The handler does not serve the standalone SSE transport.
269
274
 
270
275
  If the handler lifecycle does not fit, use the SDK's `WebStandardStreamableHTTPServerTransport` from `@modelcontextprotocol/server` directly in your Worker.
271
276
 
272
- ## Migrating from `McpAgent`
277
+ ## Upgrading an existing `McpAgent` server
278
+
279
+ `McpAgent` is deprecated, but existing servers keep working. It is built on MCP SDK v1, which is an optional peer dependency of `agents`, so your package manager no longer installs it for you. Add the exact version your Agents release expects before you upgrade:
280
+
281
+ ```sh
282
+ pnpm add agents @modelcontextprotocol/sdk@1.32.1 zod
283
+ ```
284
+
285
+ Keep importing `McpServer` from `@modelcontextprotocol/sdk/server/mcp.js` in an `McpAgent`. An SDK v2 server from `@modelcontextprotocol/server` cannot run inside `McpAgent`. The same applies to `WorkerTransport` and `createLegacyMcpHandler` from `agents/mcp`.
286
+
287
+ `agents/x402` also needs `@modelcontextprotocol/sdk`. It does not load the package at runtime, but its types refer to SDK v1 clients and tools.
288
+
289
+ If your server imported `@modelcontextprotocol/sdk` without listing it in `package.json`, it only worked because `agents` installed the package. After you upgrade, the build fails with an unresolved `@modelcontextprotocol/sdk` import until you add it.
290
+
291
+ Client code does not need the v1 SDK. If you import client helpers such as `RPCClientTransport` or `normalizeServerId` from `agents/mcp`, import them from `agents/mcp/client` instead.
273
292
 
274
- `McpAgent` is deprecated. To move an existing server to `createMcpHandler`, follow [Migrate to MCP SDK v2](https://developers.cloudflare.com/agents/model-context-protocol/guides/migrate-to-mcp-sdk-v2/).
293
+ To move the server itself to `createMcpHandler`, follow [Migrate to MCP SDK v2](https://developers.cloudflare.com/agents/model-context-protocol/guides/migrate-to-mcp-sdk-v2/).
275
294
 
276
295
  ## Examples
277
296
 
@@ -1,4 +1,4 @@
1
- # Models for pi-ai (Beta)
1
+ # Models for pi-ai
2
2
 
3
3
  `agents/models/pi-ai` is the [pi-ai](https://github.com/earendil-works/pi/tree/main/packages/ai)
4
4
  twin of [`agents/models/ai-sdk`](./models.md): the same `createAI` factory, the same options,
@@ -21,7 +21,7 @@ import { getBuiltinModel } from "@earendil-works/pi-ai/providers/all";
21
21
 
22
22
  const ai = createAI({ binding: env.AI, id: "prod", cacheTtl: 60 });
23
23
 
24
- ai("@cf/zai-org/glm-4.7-flash"); // Workers AI: our catalog, our compat layer
24
+ ai("@cf/zai-org/glm-5.3-flash"); // Workers AI: our catalog, our compat layer
25
25
  ai(getBuiltinModel("anthropic", "claude-opus-4-8")); // their model, our transport
26
26
  ```
27
27
 
@@ -47,7 +47,6 @@ design: a model this package cannot name exactly is yours to construct.
47
47
  `env.AI.run`, other model objects through the binding's `fetch` to AI Gateway's
48
48
  provider-native path. With [an account id and API token](#account-id-and-api-token) the
49
49
  same requests go over HTTP instead.
50
- 5. Everything here is in beta and may change in a minor release.
51
50
 
52
51
  ## Quick start
53
52
 
@@ -66,7 +65,7 @@ import { createAI } from "agents/models/pi-ai";
66
65
  export default {
67
66
  async fetch(_request: Request, env: { AI: Ai }) {
68
67
  const ai = createAI({ binding: env.AI });
69
- const reply = await ai.complete(ai("@cf/zai-org/glm-4.7-flash"), {
68
+ const reply = await ai.complete(ai("@cf/zai-org/glm-5.3-flash"), {
70
69
  messages: [{ role: "user", content: "Hello", timestamp: Date.now() }]
71
70
  });
72
71
  // `content` is an array of parts — text, thinking, tool calls.
@@ -103,7 +102,7 @@ Workers AI and catalog models go to AI Gateway's
103
102
 
104
103
  ```ts
105
104
  // 1. Workers AI — ours.
106
- ai("@cf/zai-org/glm-4.7-flash");
105
+ ai("@cf/zai-org/glm-5.3-flash");
107
106
 
108
107
  // 2. pi-ai's Cloudflare AI Gateway catalog — a string, resolved by pi, not us.
109
108
  ai("anthropic/claude-opus-4.8");
@@ -181,7 +180,7 @@ import { createModels } from "@earendil-works/pi-ai/models";
181
180
  const models = createModels();
182
181
  models.setProvider(ai.provider); // provider id: "cloudflare"
183
182
  models.getModel("cloudflare", "anthropic/claude-opus-4.8");
184
- models.streamSimple(ai("@cf/zai-org/glm-4.7-flash"), context);
183
+ models.streamSimple(ai("@cf/zai-org/glm-5.3-flash"), context);
185
184
  ```
186
185
 
187
186
  The provider's static list is every Workers AI id pi-ai knows plus every `<provider>/<id>` in
@@ -206,7 +205,7 @@ ai("anthropic/claude-opus-4.8", {
206
205
  requestTimeoutMs: 30_000,
207
206
  retries: { maxAttempts: 3, backoff: "exponential", retryDelayMs: 500 },
208
207
  byokAlias: "team-a", // which stored BYOK key, by alias
209
- fallback: ["@cf/zai-org/glm-4.7-flash"], // ids or models, in any mix
208
+ fallback: ["@cf/zai-org/glm-5.3-flash"], // ids or models, in any mix
210
209
  headers: { "x-request-source": "docs" },
211
210
  sessionAffinity: "chat-42", // Workers AI prefix-cache routing
212
211
  reasoningEffort: "low", // "low" | "medium" | "high" | null
@@ -336,7 +335,7 @@ and are not resumed. The run id is on the `cloudflare` diagnostic as `runId`.
336
335
  ## Fallback
337
336
 
338
337
  ```ts
339
- ai(claude, { fallback: ["@cf/zai-org/glm-4.7-flash"] });
338
+ ai(claude, { fallback: ["@cf/zai-org/glm-5.3-flash"] });
340
339
  ```
341
340
 
342
341
  Legs may be Workers AI ids or models, in any mix. They are tried in order: a leg is abandoned
@@ -368,11 +367,10 @@ Image generation is Workers AI only. The knobs a model takes are the model's:
368
367
  in a `cloudflare-compat` diagnostic on the result rather than sent and ignored.
369
368
  Every other model in the catalog takes the full set.
370
369
 
371
- ## Beta
370
+ ## Requirements
372
371
 
373
372
  This subpath needs `@earendil-works/pi-ai@~1.4.0`, an optional peer of `agents`. `agents`
374
- takes no vendor package as a dependency, optional or otherwise. The surface is in beta
375
- and may change in a minor release. An unlisted `@cf/` id resolves with default metadata (a
373
+ takes no vendor package as a dependency, optional or otherwise. An unlisted `@cf/` id resolves with default metadata (a
376
374
  128k context window, 8192 output tokens, zero cost); pass overrides when you know better.
377
375
 
378
376
  ## See also
package/docs/models.md CHANGED
@@ -1,4 +1,4 @@
1
- # Models (Experimental)
1
+ # Models
2
2
 
3
3
  `agents/models/ai-sdk` is Cloudflare's AI SDK provider. It takes two call
4
4
  forms, through the `AI` binding or
@@ -557,13 +557,6 @@ try {
557
557
  On a model object this covers the gateway's own failures; a vendor's own error
558
558
  is raised by that vendor's provider in its own error type.
559
559
 
560
- ## Experimental
561
-
562
- This module is experimental. The surface may change in a minor release, and
563
- every exported symbol is tagged `@experimental`. It ships from `agents` first;
564
- the plan is for `cloudflare/ai` to re-export it and deprecate the older
565
- `workers-ai-provider` / `ai-gateway-provider` packages.
566
-
567
560
  ## See also
568
561
 
569
562
  - [Models for pi-ai](./models-pi-ai.md) — the same factory for pi-ai and pi-durable