agents 0.0.0-7c40201 → 0.0.0-7e0777b

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 (45) hide show
  1. package/dist/ai-chat-agent.d.ts +50 -5
  2. package/dist/ai-chat-agent.js +150 -79
  3. package/dist/ai-chat-agent.js.map +1 -1
  4. package/dist/ai-react.d.ts +17 -4
  5. package/dist/ai-react.js +62 -48
  6. package/dist/ai-react.js.map +1 -1
  7. package/dist/ai-types.d.ts +5 -0
  8. package/dist/chunk-767EASBA.js +106 -0
  9. package/dist/chunk-767EASBA.js.map +1 -0
  10. package/dist/chunk-E3LCYPCB.js +469 -0
  11. package/dist/chunk-E3LCYPCB.js.map +1 -0
  12. package/dist/chunk-NKZZ66QY.js +116 -0
  13. package/dist/chunk-NKZZ66QY.js.map +1 -0
  14. package/dist/{chunk-KRBQHBPA.js → chunk-ZRRXJUAA.js} +357 -168
  15. package/dist/chunk-ZRRXJUAA.js.map +1 -0
  16. package/dist/client.d.ts +15 -1
  17. package/dist/client.js +6 -133
  18. package/dist/client.js.map +1 -1
  19. package/dist/index.d.ts +123 -21
  20. package/dist/index.js +8 -8
  21. package/dist/mcp/client.d.ts +783 -0
  22. package/dist/mcp/client.js +9 -0
  23. package/dist/mcp/do-oauth-client-provider.d.ts +41 -0
  24. package/dist/mcp/do-oauth-client-provider.js +7 -0
  25. package/dist/mcp/do-oauth-client-provider.js.map +1 -0
  26. package/dist/mcp/index.d.ts +84 -0
  27. package/dist/mcp/index.js +783 -0
  28. package/dist/mcp/index.js.map +1 -0
  29. package/dist/react.d.ts +85 -5
  30. package/dist/react.js +50 -31
  31. package/dist/react.js.map +1 -1
  32. package/dist/schedule.d.ts +2 -2
  33. package/dist/schedule.js +4 -6
  34. package/dist/schedule.js.map +1 -1
  35. package/dist/serializable.d.ts +32 -0
  36. package/dist/serializable.js +1 -0
  37. package/dist/serializable.js.map +1 -0
  38. package/package.json +79 -51
  39. package/src/index.ts +429 -99
  40. package/dist/chunk-HMLY7DHA.js +0 -16
  41. package/dist/chunk-KRBQHBPA.js.map +0 -1
  42. package/dist/mcp.d.ts +0 -58
  43. package/dist/mcp.js +0 -945
  44. package/dist/mcp.js.map +0 -1
  45. /package/dist/{chunk-HMLY7DHA.js.map → mcp/client.js.map} +0 -0
@@ -1,20 +1,22 @@
1
1
  import {
2
- __privateAdd,
3
- __privateGet,
4
- __privateMethod,
5
- __privateSet
6
- } from "./chunk-HMLY7DHA.js";
2
+ MCPClientManager
3
+ } from "./chunk-E3LCYPCB.js";
4
+ import {
5
+ DurableObjectOAuthClientProvider
6
+ } from "./chunk-767EASBA.js";
7
+ import {
8
+ camelCaseToKebabCase
9
+ } from "./chunk-NKZZ66QY.js";
7
10
 
8
11
  // src/index.ts
12
+ import { AsyncLocalStorage } from "async_hooks";
13
+ import { parseCronExpression } from "cron-schedule";
14
+ import { nanoid } from "nanoid";
9
15
  import {
10
- Server,
16
+ getServerByName,
11
17
  routePartykitRequest,
12
- getServerByName
18
+ Server
13
19
  } from "partyserver";
14
- import { parseCronExpression } from "cron-schedule";
15
- import { nanoid } from "nanoid";
16
- import { AsyncLocalStorage } from "node:async_hooks";
17
- import { WorkflowEntrypoint as CFWorkflowEntrypoint } from "cloudflare:workers";
18
20
  function isRPCRequest(msg) {
19
21
  return typeof msg === "object" && msg !== null && "type" in msg && msg.type === "rpc" && "id" in msg && typeof msg.id === "string" && "method" in msg && typeof msg.method === "string" && "args" in msg && Array.isArray(msg.args);
20
22
  }
@@ -30,8 +32,6 @@ function unstable_callable(metadata = {}) {
30
32
  return target;
31
33
  };
32
34
  }
33
- var WorkflowEntrypoint = class extends CFWorkflowEntrypoint {
34
- };
35
35
  function getNextCronTime(cron) {
36
36
  const interval = parseCronExpression(cron);
37
37
  return interval.getNextDate();
@@ -39,18 +39,72 @@ function getNextCronTime(cron) {
39
39
  var STATE_ROW_ID = "cf_state_row_id";
40
40
  var STATE_WAS_CHANGED = "cf_state_was_changed";
41
41
  var DEFAULT_STATE = {};
42
- var unstable_context = new AsyncLocalStorage();
43
- var _state, _Agent_instances, setStateInternal_fn, tryCatch_fn, scheduleNextAlarm_fn, isCallable_fn;
42
+ var agentContext = new AsyncLocalStorage();
43
+ function getCurrentAgent() {
44
+ const store = agentContext.getStore();
45
+ if (!store) {
46
+ return {
47
+ agent: void 0,
48
+ connection: void 0,
49
+ request: void 0
50
+ };
51
+ }
52
+ return store;
53
+ }
44
54
  var Agent = class extends Server {
45
55
  constructor(ctx, env) {
46
56
  super(ctx, env);
47
- __privateAdd(this, _Agent_instances);
48
- __privateAdd(this, _state, DEFAULT_STATE);
57
+ this._state = DEFAULT_STATE;
58
+ this._ParentClass = Object.getPrototypeOf(this).constructor;
59
+ this.mcp = new MCPClientManager(this._ParentClass.name, "0.0.1");
49
60
  /**
50
61
  * Initial state for the Agent
51
62
  * Override to provide default state values
52
63
  */
53
64
  this.initialState = DEFAULT_STATE;
65
+ /**
66
+ * Method called when an alarm fires.
67
+ * Executes any scheduled tasks that are due.
68
+ *
69
+ * @remarks
70
+ * To schedule a task, please use the `this.schedule` method instead.
71
+ * See {@link https://developers.cloudflare.com/agents/api-reference/schedule-tasks/}
72
+ */
73
+ this.alarm = async () => {
74
+ const now = Math.floor(Date.now() / 1e3);
75
+ const result = this.sql`
76
+ SELECT * FROM cf_agents_schedules WHERE time <= ${now}
77
+ `;
78
+ for (const row of result || []) {
79
+ const callback = this[row.callback];
80
+ if (!callback) {
81
+ console.error(`callback ${row.callback} not found`);
82
+ continue;
83
+ }
84
+ await agentContext.run(
85
+ { agent: this, connection: void 0, request: void 0 },
86
+ async () => {
87
+ try {
88
+ await callback.bind(this)(JSON.parse(row.payload), row);
89
+ } catch (e) {
90
+ console.error(`error executing callback "${row.callback}"`, e);
91
+ }
92
+ }
93
+ );
94
+ if (row.type === "cron") {
95
+ const nextExecutionTime = getNextCronTime(row.cron);
96
+ const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
97
+ this.sql`
98
+ UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
99
+ `;
100
+ } else {
101
+ this.sql`
102
+ DELETE FROM cf_agents_schedules WHERE id = ${row.id}
103
+ `;
104
+ }
105
+ }
106
+ await this._scheduleNextAlarm();
107
+ };
54
108
  this.sql`
55
109
  CREATE TABLE IF NOT EXISTS cf_agents_state (
56
110
  id TEXT PRIMARY KEY NOT NULL,
@@ -58,7 +112,7 @@ var Agent = class extends Server {
58
112
  )
59
113
  `;
60
114
  void this.ctx.blockConcurrencyWhile(async () => {
61
- return __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, async () => {
115
+ return this._tryCatch(async () => {
62
116
  this.sql`
63
117
  CREATE TABLE IF NOT EXISTS cf_agents_schedules (
64
118
  id TEXT PRIMARY KEY NOT NULL DEFAULT (randomblob(9)),
@@ -74,22 +128,55 @@ var Agent = class extends Server {
74
128
  await this.alarm();
75
129
  });
76
130
  });
131
+ this.sql`
132
+ CREATE TABLE IF NOT EXISTS cf_agents_mcp_servers (
133
+ id TEXT PRIMARY KEY NOT NULL,
134
+ name TEXT NOT NULL,
135
+ server_url TEXT NOT NULL,
136
+ callback_url TEXT NOT NULL,
137
+ client_id TEXT,
138
+ auth_url TEXT,
139
+ server_options TEXT
140
+ )
141
+ `;
142
+ const _onRequest = this.onRequest.bind(this);
143
+ this.onRequest = (request) => {
144
+ return agentContext.run(
145
+ { agent: this, connection: void 0, request },
146
+ async () => {
147
+ if (this.mcp.isCallbackRequest(request)) {
148
+ await this.mcp.handleCallbackRequest(request);
149
+ this.broadcast(
150
+ JSON.stringify({
151
+ mcp: this.getMcpServers(),
152
+ type: "cf_agent_mcp_servers"
153
+ })
154
+ );
155
+ return new Response("<script>window.close();</script>", {
156
+ headers: { "content-type": "text/html" },
157
+ status: 200
158
+ });
159
+ }
160
+ return this._tryCatch(() => _onRequest(request));
161
+ }
162
+ );
163
+ };
77
164
  const _onMessage = this.onMessage.bind(this);
78
165
  this.onMessage = async (connection, message) => {
79
- return unstable_context.run(
166
+ return agentContext.run(
80
167
  { agent: this, connection, request: void 0 },
81
168
  async () => {
82
169
  if (typeof message !== "string") {
83
- return __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, () => _onMessage(connection, message));
170
+ return this._tryCatch(() => _onMessage(connection, message));
84
171
  }
85
172
  let parsed;
86
173
  try {
87
174
  parsed = JSON.parse(message);
88
- } catch (e) {
89
- return __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, () => _onMessage(connection, message));
175
+ } catch (_e) {
176
+ return this._tryCatch(() => _onMessage(connection, message));
90
177
  }
91
178
  if (isStateUpdateMessage(parsed)) {
92
- __privateMethod(this, _Agent_instances, setStateInternal_fn).call(this, parsed.state, connection);
179
+ this._setStateInternal(parsed.state, connection);
93
180
  return;
94
181
  }
95
182
  if (isRPCRequest(parsed)) {
@@ -99,7 +186,7 @@ var Agent = class extends Server {
99
186
  if (typeof methodFn !== "function") {
100
187
  throw new Error(`Method ${method} does not exist`);
101
188
  }
102
- if (!__privateMethod(this, _Agent_instances, isCallable_fn).call(this, method)) {
189
+ if (!this._isCallable(method)) {
103
190
  throw new Error(`Method ${method} is not callable`);
104
191
  }
105
192
  const metadata = callableMetadata.get(methodFn);
@@ -110,55 +197,93 @@ var Agent = class extends Server {
110
197
  }
111
198
  const result = await methodFn.apply(this, args);
112
199
  const response = {
113
- type: "rpc",
200
+ done: true,
114
201
  id,
115
- success: true,
116
202
  result,
117
- done: true
203
+ success: true,
204
+ type: "rpc"
118
205
  };
119
206
  connection.send(JSON.stringify(response));
120
207
  } catch (e) {
121
208
  const response = {
122
- type: "rpc",
209
+ error: e instanceof Error ? e.message : "Unknown error occurred",
123
210
  id: parsed.id,
124
211
  success: false,
125
- error: e instanceof Error ? e.message : "Unknown error occurred"
212
+ type: "rpc"
126
213
  };
127
214
  connection.send(JSON.stringify(response));
128
215
  console.error("RPC error:", e);
129
216
  }
130
217
  return;
131
218
  }
132
- return __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, () => _onMessage(connection, message));
219
+ return this._tryCatch(() => _onMessage(connection, message));
133
220
  }
134
221
  );
135
222
  };
136
223
  const _onConnect = this.onConnect.bind(this);
137
224
  this.onConnect = (connection, ctx2) => {
138
- return unstable_context.run(
225
+ return agentContext.run(
139
226
  { agent: this, connection, request: ctx2.request },
140
227
  async () => {
141
228
  setTimeout(() => {
142
229
  if (this.state) {
143
230
  connection.send(
144
231
  JSON.stringify({
145
- type: "cf_agent_state",
146
- state: this.state
232
+ state: this.state,
233
+ type: "cf_agent_state"
147
234
  })
148
235
  );
149
236
  }
150
- return __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, () => _onConnect(connection, ctx2));
237
+ connection.send(
238
+ JSON.stringify({
239
+ mcp: this.getMcpServers(),
240
+ type: "cf_agent_mcp_servers"
241
+ })
242
+ );
243
+ return this._tryCatch(() => _onConnect(connection, ctx2));
151
244
  }, 20);
152
245
  }
153
246
  );
154
247
  };
248
+ const _onStart = this.onStart.bind(this);
249
+ this.onStart = async () => {
250
+ return agentContext.run(
251
+ { agent: this, connection: void 0, request: void 0 },
252
+ async () => {
253
+ const servers = this.sql`
254
+ SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
255
+ `;
256
+ await Promise.allSettled(
257
+ servers.filter((server) => server.auth_url === null).map((server) => {
258
+ return this._connectToMcpServerInternal(
259
+ server.name,
260
+ server.server_url,
261
+ server.callback_url,
262
+ server.server_options ? JSON.parse(server.server_options) : void 0,
263
+ {
264
+ id: server.id,
265
+ oauthClientId: server.client_id ?? void 0
266
+ }
267
+ );
268
+ })
269
+ );
270
+ this.broadcast(
271
+ JSON.stringify({
272
+ mcp: this.getMcpServers(),
273
+ type: "cf_agent_mcp_servers"
274
+ })
275
+ );
276
+ await this._tryCatch(() => _onStart());
277
+ }
278
+ );
279
+ };
155
280
  }
156
281
  /**
157
282
  * Current state of the Agent
158
283
  */
159
284
  get state() {
160
- if (__privateGet(this, _state) !== DEFAULT_STATE) {
161
- return __privateGet(this, _state);
285
+ if (this._state !== DEFAULT_STATE) {
286
+ return this._state;
162
287
  }
163
288
  const wasChanged = this.sql`
164
289
  SELECT state FROM cf_agents_state WHERE id = ${STATE_WAS_CHANGED}
@@ -169,8 +294,8 @@ var Agent = class extends Server {
169
294
  if (wasChanged[0]?.state === "true" || // we do this check for people who updated their code before we shipped wasChanged
170
295
  result[0]?.state) {
171
296
  const state = result[0]?.state;
172
- __privateSet(this, _state, JSON.parse(state));
173
- return __privateGet(this, _state);
297
+ this._state = JSON.parse(state);
298
+ return this._state;
174
299
  }
175
300
  if (this.initialState === DEFAULT_STATE) {
176
301
  return void 0;
@@ -198,32 +323,68 @@ var Agent = class extends Server {
198
323
  throw this.onError(e);
199
324
  }
200
325
  }
326
+ _setStateInternal(state, source = "server") {
327
+ this._state = state;
328
+ this.sql`
329
+ INSERT OR REPLACE INTO cf_agents_state (id, state)
330
+ VALUES (${STATE_ROW_ID}, ${JSON.stringify(state)})
331
+ `;
332
+ this.sql`
333
+ INSERT OR REPLACE INTO cf_agents_state (id, state)
334
+ VALUES (${STATE_WAS_CHANGED}, ${JSON.stringify(true)})
335
+ `;
336
+ this.broadcast(
337
+ JSON.stringify({
338
+ state,
339
+ type: "cf_agent_state"
340
+ }),
341
+ source !== "server" ? [source.id] : []
342
+ );
343
+ return this._tryCatch(() => {
344
+ const { connection, request } = agentContext.getStore() || {};
345
+ return agentContext.run(
346
+ { agent: this, connection, request },
347
+ async () => {
348
+ return this.onStateUpdate(state, source);
349
+ }
350
+ );
351
+ });
352
+ }
201
353
  /**
202
354
  * Update the Agent's state
203
355
  * @param state New state to set
204
356
  */
205
357
  setState(state) {
206
- __privateMethod(this, _Agent_instances, setStateInternal_fn).call(this, state, "server");
358
+ this._setStateInternal(state, "server");
207
359
  }
208
360
  /**
209
361
  * Called when the Agent's state is updated
210
362
  * @param state Updated state
211
363
  * @param source Source of the state update ("server" or a client connection)
212
364
  */
365
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
213
366
  onStateUpdate(state, source) {
214
367
  }
215
368
  /**
216
369
  * Called when the Agent receives an email
217
370
  * @param email Email message to process
218
371
  */
372
+ // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later
219
373
  onEmail(email) {
220
- return unstable_context.run(
374
+ return agentContext.run(
221
375
  { agent: this, connection: void 0, request: void 0 },
222
376
  async () => {
223
377
  console.error("onEmail not implemented");
224
378
  }
225
379
  );
226
380
  }
381
+ async _tryCatch(fn) {
382
+ try {
383
+ return await fn();
384
+ } catch (e) {
385
+ throw this.onError(e);
386
+ }
387
+ }
227
388
  onError(connectionOrError, error) {
228
389
  let theError;
229
390
  if (connectionOrError && error) {
@@ -273,10 +434,10 @@ var Agent = class extends Server {
273
434
  payload
274
435
  )}, 'scheduled', ${timestamp})
275
436
  `;
276
- await __privateMethod(this, _Agent_instances, scheduleNextAlarm_fn).call(this);
437
+ await this._scheduleNextAlarm();
277
438
  return {
278
- id,
279
439
  callback,
440
+ id,
280
441
  payload,
281
442
  time: timestamp,
282
443
  type: "scheduled"
@@ -291,12 +452,12 @@ var Agent = class extends Server {
291
452
  payload
292
453
  )}, 'delayed', ${when}, ${timestamp})
293
454
  `;
294
- await __privateMethod(this, _Agent_instances, scheduleNextAlarm_fn).call(this);
455
+ await this._scheduleNextAlarm();
295
456
  return {
296
- id,
297
457
  callback,
298
- payload,
299
458
  delayInSeconds: when,
459
+ id,
460
+ payload,
300
461
  time: timestamp,
301
462
  type: "delayed"
302
463
  };
@@ -310,12 +471,12 @@ var Agent = class extends Server {
310
471
  payload
311
472
  )}, 'cron', ${when}, ${timestamp})
312
473
  `;
313
- await __privateMethod(this, _Agent_instances, scheduleNextAlarm_fn).call(this);
474
+ await this._scheduleNextAlarm();
314
475
  return {
315
- id,
316
476
  callback,
317
- payload,
318
477
  cron: when,
478
+ id,
479
+ payload,
319
480
  time: timestamp,
320
481
  type: "cron"
321
482
  };
@@ -351,10 +512,6 @@ var Agent = class extends Server {
351
512
  query += " AND id = ?";
352
513
  params.push(criteria.id);
353
514
  }
354
- if (criteria.description) {
355
- query += " AND description = ?";
356
- params.push(criteria.description);
357
- }
358
515
  if (criteria.type) {
359
516
  query += " AND type = ?";
360
517
  params.push(criteria.type);
@@ -381,47 +538,21 @@ var Agent = class extends Server {
381
538
  */
382
539
  async cancelSchedule(id) {
383
540
  this.sql`DELETE FROM cf_agents_schedules WHERE id = ${id}`;
384
- await __privateMethod(this, _Agent_instances, scheduleNextAlarm_fn).call(this);
541
+ await this._scheduleNextAlarm();
385
542
  return true;
386
543
  }
387
- /**
388
- * Method called when an alarm fires
389
- * Executes any scheduled tasks that are due
390
- */
391
- async alarm() {
392
- const now = Math.floor(Date.now() / 1e3);
544
+ async _scheduleNextAlarm() {
393
545
  const result = this.sql`
394
- SELECT * FROM cf_agents_schedules WHERE time <= ${now}
546
+ SELECT time FROM cf_agents_schedules
547
+ WHERE time > ${Math.floor(Date.now() / 1e3)}
548
+ ORDER BY time ASC
549
+ LIMIT 1
395
550
  `;
396
- for (const row of result || []) {
397
- const callback = this[row.callback];
398
- if (!callback) {
399
- console.error(`callback ${row.callback} not found`);
400
- continue;
401
- }
402
- await unstable_context.run(
403
- { agent: this, connection: void 0, request: void 0 },
404
- async () => {
405
- try {
406
- await callback.bind(this)(JSON.parse(row.payload), row);
407
- } catch (e) {
408
- console.error(`error executing callback "${row.callback}"`, e);
409
- }
410
- }
411
- );
412
- if (row.type === "cron") {
413
- const nextExecutionTime = getNextCronTime(row.cron);
414
- const nextTimestamp = Math.floor(nextExecutionTime.getTime() / 1e3);
415
- this.sql`
416
- UPDATE cf_agents_schedules SET time = ${nextTimestamp} WHERE id = ${row.id}
417
- `;
418
- } else {
419
- this.sql`
420
- DELETE FROM cf_agents_schedules WHERE id = ${row.id}
421
- `;
422
- }
551
+ if (!result) return;
552
+ if (result.length > 0 && "time" in result[0]) {
553
+ const nextTime = result[0].time * 1e3;
554
+ await this.ctx.storage.setAlarm(nextTime);
423
555
  }
424
- await __privateMethod(this, _Agent_instances, scheduleNextAlarm_fn).call(this);
425
556
  }
426
557
  /**
427
558
  * Destroy the Agent, removing all state and scheduled tasks
@@ -429,66 +560,131 @@ var Agent = class extends Server {
429
560
  async destroy() {
430
561
  this.sql`DROP TABLE IF EXISTS cf_agents_state`;
431
562
  this.sql`DROP TABLE IF EXISTS cf_agents_schedules`;
563
+ this.sql`DROP TABLE IF EXISTS cf_agents_mcp_servers`;
432
564
  await this.ctx.storage.deleteAlarm();
433
565
  await this.ctx.storage.deleteAll();
566
+ this.ctx.abort("destroyed");
434
567
  }
435
- };
436
- _state = new WeakMap();
437
- _Agent_instances = new WeakSet();
438
- setStateInternal_fn = function(state, source = "server") {
439
- __privateSet(this, _state, state);
440
- this.sql`
441
- INSERT OR REPLACE INTO cf_agents_state (id, state)
442
- VALUES (${STATE_ROW_ID}, ${JSON.stringify(state)})
443
- `;
444
- this.sql`
445
- INSERT OR REPLACE INTO cf_agents_state (id, state)
446
- VALUES (${STATE_WAS_CHANGED}, ${JSON.stringify(true)})
447
- `;
448
- this.broadcast(
449
- JSON.stringify({
450
- type: "cf_agent_state",
451
- state
452
- }),
453
- source !== "server" ? [source.id] : []
454
- );
455
- return __privateMethod(this, _Agent_instances, tryCatch_fn).call(this, () => {
456
- const { connection, request } = unstable_context.getStore() || {};
457
- return unstable_context.run(
458
- { agent: this, connection, request },
459
- async () => {
460
- return this.onStateUpdate(state, source);
568
+ /**
569
+ * Get all methods marked as callable on this Agent
570
+ * @returns A map of method names to their metadata
571
+ */
572
+ _isCallable(method) {
573
+ return callableMetadata.has(this[method]);
574
+ }
575
+ /**
576
+ * Connect to a new MCP Server
577
+ *
578
+ * @param url MCP Server SSE URL
579
+ * @param callbackHost Base host for the agent, used for the redirect URI.
580
+ * @param agentsPrefix agents routing prefix if not using `agents`
581
+ * @param options MCP client and transport (header) options
582
+ * @returns authUrl
583
+ */
584
+ async addMcpServer(serverName, url, callbackHost, agentsPrefix = "agents", options) {
585
+ const callbackUrl = `${callbackHost}/${agentsPrefix}/${camelCaseToKebabCase(this._ParentClass.name)}/${this.name}/callback`;
586
+ const result = await this._connectToMcpServerInternal(
587
+ serverName,
588
+ url,
589
+ callbackUrl,
590
+ options
591
+ );
592
+ this.broadcast(
593
+ JSON.stringify({
594
+ mcp: this.getMcpServers(),
595
+ type: "cf_agent_mcp_servers"
596
+ })
597
+ );
598
+ return result;
599
+ }
600
+ async _connectToMcpServerInternal(serverName, url, callbackUrl, options, reconnect) {
601
+ const authProvider = new DurableObjectOAuthClientProvider(
602
+ this.ctx.storage,
603
+ this.name,
604
+ callbackUrl
605
+ );
606
+ if (reconnect) {
607
+ authProvider.serverId = reconnect.id;
608
+ if (reconnect.oauthClientId) {
609
+ authProvider.clientId = reconnect.oauthClientId;
461
610
  }
611
+ }
612
+ let headerTransportOpts = {};
613
+ if (options?.transport?.headers) {
614
+ headerTransportOpts = {
615
+ eventSourceInit: {
616
+ fetch: (url2, init) => fetch(url2, {
617
+ ...init,
618
+ headers: options?.transport?.headers
619
+ })
620
+ },
621
+ requestInit: {
622
+ headers: options?.transport?.headers
623
+ }
624
+ };
625
+ }
626
+ const { id, authUrl, clientId } = await this.mcp.connect(url, {
627
+ client: options?.client,
628
+ reconnect,
629
+ transport: {
630
+ ...headerTransportOpts,
631
+ authProvider
632
+ }
633
+ });
634
+ this.sql`
635
+ INSERT OR REPLACE INTO cf_agents_mcp_servers (id, name, server_url, client_id, auth_url, callback_url, server_options)
636
+ VALUES (
637
+ ${id},
638
+ ${serverName},
639
+ ${url},
640
+ ${clientId ?? null},
641
+ ${authUrl ?? null},
642
+ ${callbackUrl},
643
+ ${options ? JSON.stringify(options) : null}
644
+ );
645
+ `;
646
+ return {
647
+ authUrl,
648
+ id
649
+ };
650
+ }
651
+ async removeMcpServer(id) {
652
+ this.mcp.closeConnection(id);
653
+ this.sql`
654
+ DELETE FROM cf_agents_mcp_servers WHERE id = ${id};
655
+ `;
656
+ this.broadcast(
657
+ JSON.stringify({
658
+ mcp: this.getMcpServers(),
659
+ type: "cf_agent_mcp_servers"
660
+ })
462
661
  );
463
- });
464
- };
465
- tryCatch_fn = async function(fn) {
466
- try {
467
- return await fn();
468
- } catch (e) {
469
- throw this.onError(e);
470
662
  }
471
- };
472
- scheduleNextAlarm_fn = async function() {
473
- const result = this.sql`
474
- SELECT time FROM cf_agents_schedules
475
- WHERE time > ${Math.floor(Date.now() / 1e3)}
476
- ORDER BY time ASC
477
- LIMIT 1
663
+ getMcpServers() {
664
+ const mcpState = {
665
+ prompts: this.mcp.listPrompts(),
666
+ resources: this.mcp.listResources(),
667
+ servers: {},
668
+ tools: this.mcp.listTools()
669
+ };
670
+ const servers = this.sql`
671
+ SELECT id, name, server_url, client_id, auth_url, callback_url, server_options FROM cf_agents_mcp_servers;
478
672
  `;
479
- if (!result) return;
480
- if (result.length > 0 && "time" in result[0]) {
481
- const nextTime = result[0].time * 1e3;
482
- await this.ctx.storage.setAlarm(nextTime);
673
+ for (const server of servers) {
674
+ const serverConn = this.mcp.mcpConnections[server.id];
675
+ mcpState.servers[server.id] = {
676
+ auth_url: server.auth_url,
677
+ capabilities: serverConn?.serverCapabilities ?? null,
678
+ instructions: serverConn?.instructions ?? null,
679
+ name: server.name,
680
+ server_url: server.server_url,
681
+ // mark as "authenticating" because the server isn't automatically connected, so it's pending authenticating
682
+ state: serverConn?.connectionState ?? "authenticating"
683
+ };
684
+ }
685
+ return mcpState;
483
686
  }
484
687
  };
485
- /**
486
- * Get all methods marked as callable on this Agent
487
- * @returns A map of method names to their metadata
488
- */
489
- isCallable_fn = function(method) {
490
- return callableMetadata.has(this[method]);
491
- };
492
688
  /**
493
689
  * Agent configuration options
494
690
  */
@@ -499,9 +695,9 @@ Agent.options = {
499
695
  };
500
696
  async function routeAgentRequest(request, env, options) {
501
697
  const corsHeaders = options?.cors === true ? {
502
- "Access-Control-Allow-Origin": "*",
503
- "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
504
698
  "Access-Control-Allow-Credentials": "true",
699
+ "Access-Control-Allow-Methods": "GET, POST, HEAD, OPTIONS",
700
+ "Access-Control-Allow-Origin": "*",
505
701
  "Access-Control-Max-Age": "86400"
506
702
  } : options?.cors;
507
703
  if (request.method === "OPTIONS") {
@@ -532,68 +728,61 @@ async function routeAgentRequest(request, env, options) {
532
728
  }
533
729
  return response;
534
730
  }
535
- async function routeAgentEmail(email, env, options) {
731
+ async function routeAgentEmail(_email, _env, _options) {
536
732
  }
537
- function getAgentByName(namespace, name, options) {
733
+ async function getAgentByName(namespace, name, options) {
538
734
  return getServerByName(namespace, name, options);
539
735
  }
540
- var _connection, _id, _closed;
541
736
  var StreamingResponse = class {
542
737
  constructor(connection, id) {
543
- __privateAdd(this, _connection);
544
- __privateAdd(this, _id);
545
- __privateAdd(this, _closed, false);
546
- __privateSet(this, _connection, connection);
547
- __privateSet(this, _id, id);
738
+ this._closed = false;
739
+ this._connection = connection;
740
+ this._id = id;
548
741
  }
549
742
  /**
550
743
  * Send a chunk of data to the client
551
744
  * @param chunk The data to send
552
745
  */
553
746
  send(chunk) {
554
- if (__privateGet(this, _closed)) {
747
+ if (this._closed) {
555
748
  throw new Error("StreamingResponse is already closed");
556
749
  }
557
750
  const response = {
558
- type: "rpc",
559
- id: __privateGet(this, _id),
560
- success: true,
751
+ done: false,
752
+ id: this._id,
561
753
  result: chunk,
562
- done: false
754
+ success: true,
755
+ type: "rpc"
563
756
  };
564
- __privateGet(this, _connection).send(JSON.stringify(response));
757
+ this._connection.send(JSON.stringify(response));
565
758
  }
566
759
  /**
567
760
  * End the stream and send the final chunk (if any)
568
761
  * @param finalChunk Optional final chunk of data to send
569
762
  */
570
763
  end(finalChunk) {
571
- if (__privateGet(this, _closed)) {
764
+ if (this._closed) {
572
765
  throw new Error("StreamingResponse is already closed");
573
766
  }
574
- __privateSet(this, _closed, true);
767
+ this._closed = true;
575
768
  const response = {
576
- type: "rpc",
577
- id: __privateGet(this, _id),
578
- success: true,
769
+ done: true,
770
+ id: this._id,
579
771
  result: finalChunk,
580
- done: true
772
+ success: true,
773
+ type: "rpc"
581
774
  };
582
- __privateGet(this, _connection).send(JSON.stringify(response));
775
+ this._connection.send(JSON.stringify(response));
583
776
  }
584
777
  };
585
- _connection = new WeakMap();
586
- _id = new WeakMap();
587
- _closed = new WeakMap();
588
778
 
589
779
  export {
590
780
  unstable_callable,
591
- WorkflowEntrypoint,
592
- unstable_context,
781
+ getCurrentAgent,
593
782
  Agent,
594
783
  routeAgentRequest,
595
784
  routeAgentEmail,
596
785
  getAgentByName,
597
786
  StreamingResponse
598
787
  };
599
- //# sourceMappingURL=chunk-KRBQHBPA.js.map
788
+ //# sourceMappingURL=chunk-ZRRXJUAA.js.map