agents 0.2.9 → 0.2.10

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.
@@ -3,20 +3,29 @@ import {
3
3
  } from "./chunk-UJVEAURM.js";
4
4
  import {
5
5
  Agent
6
- } from "./chunk-XGMKNUJA.js";
7
- import "./chunk-ZMMHNOMZ.js";
6
+ } from "./chunk-2Y6KNRNP.js";
7
+ import "./chunk-QUOGV3WN.js";
8
8
  import "./chunk-C2OEBJZ2.js";
9
9
  import "./chunk-QEVM4BVL.js";
10
10
  import "./chunk-BER7KXUJ.js";
11
- import "./chunk-PR4QN5HX.js";
11
+ import {
12
+ __require
13
+ } from "./chunk-PR4QN5HX.js";
12
14
 
13
15
  // src/ai-chat-agent.ts
14
- import {
15
- getToolName,
16
- isToolUIPart,
17
- parsePartialJson
18
- } from "ai";
19
16
  var decoder = new TextDecoder();
17
+ var aiSDK;
18
+ function getAISDK() {
19
+ if (!aiSDK) {
20
+ const { getToolName, isToolUIPart, parsePartialJson } = __require("ai");
21
+ aiSDK = {
22
+ getToolName,
23
+ isToolUIPart,
24
+ parsePartialJson
25
+ };
26
+ }
27
+ return aiSDK;
28
+ }
20
29
  var AIChatAgent = class extends Agent {
21
30
  constructor(ctx, env) {
22
31
  super(ctx, env);
@@ -249,6 +258,7 @@ var AIChatAgent = class extends Agent {
249
258
  }
250
259
  }
251
260
  function updateToolPart(options) {
261
+ const { isToolUIPart } = getAISDK();
252
262
  const part = message.parts.find(
253
263
  (part2) => isToolUIPart(part2) && part2.toolCallId === options.toolCallId
254
264
  );
@@ -386,6 +396,7 @@ var AIChatAgent = class extends Agent {
386
396
  break;
387
397
  }
388
398
  case "tool-input-start": {
399
+ const { isToolUIPart } = getAISDK();
389
400
  const toolInvocations = message.parts.filter(isToolUIPart);
390
401
  partialToolCalls[data.toolCallId] = {
391
402
  text: "",
@@ -413,9 +424,11 @@ var AIChatAgent = class extends Agent {
413
424
  case "tool-input-delta": {
414
425
  const partialToolCall = partialToolCalls[data.toolCallId];
415
426
  partialToolCall.text += data.inputTextDelta;
416
- const { value: partialArgs } = await parsePartialJson(
427
+ const { parsePartialJson } = getAISDK();
428
+ const partialArgsResult = await parsePartialJson(
417
429
  partialToolCall.text
418
430
  );
431
+ const partialArgs = partialArgsResult.value;
419
432
  if (partialToolCall.dynamic) {
420
433
  updateDynamicToolPart({
421
434
  toolCallId: data.toolCallId,
@@ -497,7 +510,10 @@ var AIChatAgent = class extends Agent {
497
510
  preliminary: data.preliminary
498
511
  });
499
512
  } else {
500
- const toolInvocations = message.parts.filter(isToolUIPart);
513
+ const { isToolUIPart, getToolName } = getAISDK();
514
+ const toolInvocations = message.parts.filter(
515
+ isToolUIPart
516
+ );
501
517
  const toolInvocation = toolInvocations.find(
502
518
  (invocation) => invocation.toolCallId === data.toolCallId
503
519
  );
@@ -533,7 +549,10 @@ var AIChatAgent = class extends Agent {
533
549
  errorText: data.errorText
534
550
  });
535
551
  } else {
536
- const toolInvocations = message.parts.filter(isToolUIPart);
552
+ const { isToolUIPart, getToolName } = getAISDK();
553
+ const toolInvocations = message.parts.filter(
554
+ isToolUIPart
555
+ );
537
556
  const toolInvocation = toolInvocations.find(
538
557
  (invocation) => invocation.toolCallId === data.toolCallId
539
558
  );
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/ai-chat-agent.ts"],"sourcesContent":["import {\n getToolName,\n isToolUIPart,\n parsePartialJson,\n type UIMessage as ChatMessage,\n type DynamicToolUIPart,\n type ProviderMetadata,\n type ReasoningUIPart,\n type StreamTextOnFinishCallback,\n type TextUIPart,\n type ToolSet,\n type ToolUIPart,\n type UIMessageChunk\n} from \"ai\";\nimport { Agent, type AgentContext, type Connection, type WSMessage } from \"./\";\nimport {\n MessageType,\n type IncomingMessage,\n type OutgoingMessage\n} from \"./ai-types\";\nimport { autoTransformMessages } from \"./ai-chat-v5-migration\";\n\nconst decoder = new TextDecoder();\n\n/**\n * Extension of Agent with built-in chat capabilities\n * @template Env Environment type containing bindings\n */\nexport class AIChatAgent<Env = unknown, State = unknown> extends Agent<\n Env,\n State\n> {\n /**\n * Map of message `id`s to `AbortController`s\n * useful to propagate request cancellation signals for any external calls made by the agent\n */\n private _chatMessageAbortControllers: Map<string, AbortController>;\n /** Array of chat messages for the current conversation */\n messages: ChatMessage[];\n constructor(ctx: AgentContext, env: Env) {\n super(ctx, env);\n this.sql`create table if not exists cf_ai_chat_agent_messages (\n id text primary key,\n message text not null,\n created_at datetime default current_timestamp\n )`;\n\n // Load messages and automatically transform them to v5 format\n const rawMessages = this._loadMessagesFromDb();\n\n // Automatic migration following https://jhak.im/blog/ai-sdk-migration-handling-previously-saved-messages\n this.messages = autoTransformMessages(rawMessages);\n\n this._chatMessageAbortControllers = new Map();\n }\n\n private _broadcastChatMessage(message: OutgoingMessage, exclude?: string[]) {\n this.broadcast(JSON.stringify(message), exclude);\n }\n\n private _loadMessagesFromDb(): ChatMessage[] {\n const rows =\n this.sql`select * from cf_ai_chat_agent_messages order by created_at` ||\n [];\n return rows\n .map((row) => {\n try {\n return JSON.parse(row.message as string);\n } catch (error) {\n console.error(`Failed to parse message ${row.id}:`, error);\n return null;\n }\n })\n .filter((msg): msg is ChatMessage => msg !== null);\n }\n\n override async onMessage(connection: Connection, message: WSMessage) {\n if (typeof message === \"string\") {\n let data: IncomingMessage;\n try {\n data = JSON.parse(message) as IncomingMessage;\n } catch (_error) {\n // silently ignore invalid messages for now\n // TODO: log errors with log levels\n return;\n }\n if (\n data.type === MessageType.CF_AGENT_USE_CHAT_REQUEST &&\n data.init.method === \"POST\"\n ) {\n const {\n // method,\n // keepalive,\n // headers,\n body // we're reading this\n //\n // // these might not exist?\n // dispatcher,\n // duplex\n } = data.init;\n const { messages } = JSON.parse(body as string);\n\n // Automatically transform any incoming messages\n const transformedMessages = autoTransformMessages(messages);\n\n this._broadcastChatMessage(\n {\n messages: transformedMessages,\n type: MessageType.CF_AGENT_CHAT_MESSAGES\n },\n [connection.id]\n );\n\n await this.persistMessages(transformedMessages, [connection.id]);\n\n this.observability?.emit(\n {\n displayMessage: \"Chat message request\",\n id: data.id,\n payload: {},\n timestamp: Date.now(),\n type: \"message:request\"\n },\n this.ctx\n );\n\n const chatMessageId = data.id;\n const abortSignal = this._getAbortSignal(chatMessageId);\n\n return this._tryCatchChat(async () => {\n const response = await this.onChatMessage(\n async (_finishResult) => {\n this._removeAbortController(chatMessageId);\n\n this.observability?.emit(\n {\n displayMessage: \"Chat message response\",\n id: data.id,\n payload: {},\n timestamp: Date.now(),\n type: \"message:response\"\n },\n this.ctx\n );\n\n // Note: Message persistence now happens in the _reply method\n // after the complete response text has been accumulated\n },\n abortSignal ? { abortSignal } : undefined\n );\n\n if (response) {\n await this._reply(data.id, response);\n } else {\n // Log a warning for observability\n console.warn(\n `[AIChatAgent] onChatMessage returned no response for chatMessageId: ${chatMessageId}`\n );\n // Send a fallback message to the client\n this._broadcastChatMessage(\n {\n body: \"No response was generated by the agent.\",\n done: true,\n id: data.id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n },\n [connection.id]\n );\n }\n });\n }\n if (data.type === MessageType.CF_AGENT_CHAT_CLEAR) {\n this._destroyAbortControllers();\n this.sql`delete from cf_ai_chat_agent_messages`;\n this.messages = [];\n this._broadcastChatMessage(\n {\n type: MessageType.CF_AGENT_CHAT_CLEAR\n },\n [connection.id]\n );\n } else if (data.type === MessageType.CF_AGENT_CHAT_MESSAGES) {\n // replace the messages with the new ones, automatically transformed\n const transformedMessages = autoTransformMessages(data.messages);\n await this.persistMessages(transformedMessages, [connection.id]);\n } else if (data.type === MessageType.CF_AGENT_CHAT_REQUEST_CANCEL) {\n // propagate an abort signal for the associated request\n this._cancelChatRequest(data.id);\n }\n }\n }\n\n override async onRequest(request: Request): Promise<Response> {\n return this._tryCatchChat(() => {\n const url = new URL(request.url);\n if (url.pathname.endsWith(\"/get-messages\")) {\n const messages = this._loadMessagesFromDb();\n return Response.json(messages);\n }\n return super.onRequest(request);\n });\n }\n\n private async _tryCatchChat<T>(fn: () => T | Promise<T>) {\n try {\n return await fn();\n } catch (e) {\n throw this.onError(e);\n }\n }\n\n /**\n * Handle incoming chat messages and generate a response\n * @param onFinish Callback to be called when the response is finished\n * @param options.signal A signal to pass to any child requests which can be used to cancel them\n * @returns Response to send to the client or undefined\n */\n async onChatMessage(\n // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later\n onFinish: StreamTextOnFinishCallback<ToolSet>,\n // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later\n options?: { abortSignal: AbortSignal | undefined }\n ): Promise<Response | undefined> {\n throw new Error(\n \"recieved a chat message, override onChatMessage and return a Response to send to the client\"\n );\n }\n\n /**\n * Save messages on the server side\n * @param messages Chat messages to save\n */\n async saveMessages(messages: ChatMessage[]) {\n await this.persistMessages(messages);\n await this._tryCatchChat(async () => {\n const response = await this.onChatMessage(() => {});\n if (response) this._reply(crypto.randomUUID(), response);\n });\n }\n\n async persistMessages(\n messages: ChatMessage[],\n excludeBroadcastIds: string[] = []\n ) {\n for (const message of messages) {\n this.sql`\n insert into cf_ai_chat_agent_messages (id, message)\n values (${message.id}, ${JSON.stringify(message)})\n on conflict(id) do update set message = excluded.message\n `;\n }\n\n // refresh in-memory messages\n const persisted = this._loadMessagesFromDb();\n this.messages = autoTransformMessages(persisted);\n this._broadcastChatMessage(\n {\n messages: messages,\n type: MessageType.CF_AGENT_CHAT_MESSAGES\n },\n excludeBroadcastIds\n );\n }\n\n private async _reply(id: string, response: Response) {\n return this._tryCatchChat(async () => {\n if (!response.body) {\n // Send empty response if no body\n this._broadcastChatMessage({\n body: \"\",\n done: true,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n return;\n }\n\n const reader = response.body.getReader();\n\n // Parsing state adapted from:\n // https://github.com/vercel/ai/blob/main/packages/ai/src/ui-message-stream/ui-message-chunks.ts#L295\n const message: ChatMessage = {\n id: `assistant_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`, // default\n role: \"assistant\",\n parts: []\n };\n let activeTextParts: Record<string, TextUIPart> = {};\n let activeReasoningParts: Record<string, ReasoningUIPart> = {};\n const partialToolCalls: Record<\n string,\n { text: string; index: number; toolName: string; dynamic?: boolean }\n > = {};\n\n function updateDynamicToolPart(\n options: {\n toolName: string;\n toolCallId: string;\n providerExecuted?: boolean;\n } & (\n | {\n state: \"input-streaming\";\n input: unknown;\n }\n | {\n state: \"input-available\";\n input: unknown;\n providerMetadata?: ProviderMetadata;\n }\n | {\n state: \"output-available\";\n input: unknown;\n output: unknown;\n preliminary: boolean | undefined;\n }\n | {\n state: \"output-error\";\n input: unknown;\n errorText: string;\n providerMetadata?: ProviderMetadata;\n }\n )\n ) {\n const part = message.parts.find(\n (part) =>\n part.type === \"dynamic-tool\" &&\n part.toolCallId === options.toolCallId\n ) as DynamicToolUIPart | undefined;\n\n const anyOptions = options as Record<string, unknown>;\n const anyPart = part as Record<string, unknown>;\n\n if (part != null) {\n part.state = options.state;\n anyPart.toolName = options.toolName;\n anyPart.input = anyOptions.input;\n anyPart.output = anyOptions.output;\n anyPart.errorText = anyOptions.errorText;\n anyPart.rawInput = anyOptions.rawInput ?? anyPart.rawInput;\n anyPart.preliminary = anyOptions.preliminary;\n\n if (\n anyOptions.providerMetadata != null &&\n part.state === \"input-available\"\n ) {\n part.callProviderMetadata =\n anyOptions.providerMetadata as ProviderMetadata;\n }\n } else {\n message.parts.push({\n type: \"dynamic-tool\",\n toolName: options.toolName,\n toolCallId: options.toolCallId,\n state: options.state,\n input: anyOptions.input,\n output: anyOptions.output,\n errorText: anyOptions.errorText,\n preliminary: anyOptions.preliminary,\n ...(anyOptions.providerMetadata != null\n ? { callProviderMetadata: anyOptions.providerMetadata }\n : {})\n } as DynamicToolUIPart);\n }\n }\n\n function updateToolPart(\n options: {\n toolName: string;\n toolCallId: string;\n providerExecuted?: boolean;\n } & (\n | {\n state: \"input-streaming\";\n input: unknown;\n providerExecuted?: boolean;\n }\n | {\n state: \"input-available\";\n input: unknown;\n providerExecuted?: boolean;\n providerMetadata?: ProviderMetadata;\n }\n | {\n state: \"output-available\";\n input: unknown;\n output: unknown;\n providerExecuted?: boolean;\n preliminary?: boolean;\n }\n | {\n state: \"output-error\";\n input: unknown;\n rawInput?: unknown;\n errorText: string;\n providerExecuted?: boolean;\n providerMetadata?: ProviderMetadata;\n }\n )\n ) {\n const part = message.parts.find(\n (part) => isToolUIPart(part) && part.toolCallId === options.toolCallId\n ) as ToolUIPart | undefined;\n\n const anyOptions = options as Record<string, unknown>;\n const anyPart = part as Record<string, unknown>;\n\n if (part != null) {\n part.state = options.state;\n anyPart.input = anyOptions.input;\n anyPart.output = anyOptions.output;\n anyPart.errorText = anyOptions.errorText;\n anyPart.rawInput = anyOptions.rawInput;\n anyPart.preliminary = anyOptions.preliminary;\n\n // once providerExecuted is set, it stays for streaming\n anyPart.providerExecuted =\n anyOptions.providerExecuted ?? part.providerExecuted;\n\n if (\n anyOptions.providerMetadata != null &&\n part.state === \"input-available\"\n ) {\n part.callProviderMetadata =\n anyOptions.providerMetadata as ProviderMetadata;\n }\n } else {\n message.parts.push({\n type: `tool-${options.toolName}`,\n toolCallId: options.toolCallId,\n state: options.state,\n input: anyOptions.input,\n output: anyOptions.output,\n rawInput: anyOptions.rawInput,\n errorText: anyOptions.errorText,\n providerExecuted: anyOptions.providerExecuted,\n preliminary: anyOptions.preliminary,\n ...(anyOptions.providerMetadata != null\n ? { callProviderMetadata: anyOptions.providerMetadata }\n : {})\n } as ToolUIPart);\n }\n }\n\n async function updateMessageMetadata(metadata: unknown) {\n if (metadata != null) {\n const mergedMetadata =\n message.metadata != null\n ? { ...message.metadata, ...metadata } // TODO: do proper merging\n : metadata;\n\n message.metadata = mergedMetadata;\n }\n }\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n // Send final completion signal\n this._broadcastChatMessage({\n body: \"\",\n done: true,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n break;\n }\n\n const chunk = decoder.decode(value);\n\n // Determine response format based on content-type\n const contentType = response.headers.get(\"content-type\") || \"\";\n const isSSE = contentType.includes(\"text/event-stream\");\n\n // After streaming is complete, persist the complete assistant's response\n if (isSSE) {\n // Parse AI SDK v5 SSE format and extract text deltas\n const lines = chunk.split(\"\\n\");\n for (const line of lines) {\n if (line.startsWith(\"data: \") && line !== \"data: [DONE]\") {\n try {\n const data: UIMessageChunk = JSON.parse(line.slice(6)); // Remove 'data: ' prefix\n switch (data.type) {\n case \"text-start\": {\n const textPart: TextUIPart = {\n type: \"text\",\n text: \"\",\n providerMetadata: data.providerMetadata,\n state: \"streaming\"\n };\n activeTextParts[data.id] = textPart;\n message.parts.push(textPart);\n break;\n }\n\n case \"text-delta\": {\n const textPart = activeTextParts[data.id];\n textPart.text += data.delta;\n textPart.providerMetadata =\n data.providerMetadata ?? textPart.providerMetadata;\n break;\n }\n\n case \"text-end\": {\n const textPart = activeTextParts[data.id];\n textPart.state = \"done\";\n textPart.providerMetadata =\n data.providerMetadata ?? textPart.providerMetadata;\n delete activeTextParts[data.id];\n break;\n }\n\n case \"reasoning-start\": {\n const reasoningPart: ReasoningUIPart = {\n type: \"reasoning\",\n text: \"\",\n providerMetadata: data.providerMetadata,\n state: \"streaming\"\n };\n activeReasoningParts[data.id] = reasoningPart;\n message.parts.push(reasoningPart);\n break;\n }\n\n case \"reasoning-delta\": {\n const reasoningPart = activeReasoningParts[data.id];\n reasoningPart.text += data.delta;\n reasoningPart.providerMetadata =\n data.providerMetadata ?? reasoningPart.providerMetadata;\n break;\n }\n\n case \"reasoning-end\": {\n const reasoningPart = activeReasoningParts[data.id];\n reasoningPart.providerMetadata =\n data.providerMetadata ?? reasoningPart.providerMetadata;\n reasoningPart.state = \"done\";\n delete activeReasoningParts[data.id];\n\n break;\n }\n\n case \"file\": {\n message.parts.push({\n type: \"file\",\n mediaType: data.mediaType,\n url: data.url\n });\n\n break;\n }\n\n case \"source-url\": {\n message.parts.push({\n type: \"source-url\",\n sourceId: data.sourceId,\n url: data.url,\n title: data.title,\n providerMetadata: data.providerMetadata\n });\n\n break;\n }\n\n case \"source-document\": {\n message.parts.push({\n type: \"source-document\",\n sourceId: data.sourceId,\n mediaType: data.mediaType,\n title: data.title,\n filename: data.filename,\n providerMetadata: data.providerMetadata\n });\n\n break;\n }\n\n case \"tool-input-start\": {\n const toolInvocations =\n message.parts.filter(isToolUIPart);\n\n // add the partial tool call to the map\n partialToolCalls[data.toolCallId] = {\n text: \"\",\n toolName: data.toolName,\n index: toolInvocations.length,\n dynamic: data.dynamic\n };\n\n if (data.dynamic) {\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"input-streaming\",\n input: undefined\n });\n } else {\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"input-streaming\",\n input: undefined\n });\n }\n\n break;\n }\n\n case \"tool-input-delta\": {\n const partialToolCall = partialToolCalls[data.toolCallId];\n\n partialToolCall.text += data.inputTextDelta;\n\n const { value: partialArgs } = await parsePartialJson(\n partialToolCall.text\n );\n\n if (partialToolCall.dynamic) {\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: partialToolCall.toolName,\n state: \"input-streaming\",\n input: partialArgs\n });\n } else {\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: partialToolCall.toolName,\n state: \"input-streaming\",\n input: partialArgs\n });\n }\n\n break;\n }\n\n case \"tool-input-available\": {\n if (data.dynamic) {\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"input-available\",\n input: data.input,\n providerMetadata: data.providerMetadata\n });\n } else {\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"input-available\",\n input: data.input,\n providerExecuted: data.providerExecuted,\n providerMetadata: data.providerMetadata\n });\n }\n\n // TODO: Do we want to expose onToolCall?\n\n // invoke the onToolCall callback if it exists. This is blocking.\n // In the future we should make this non-blocking, which\n // requires additional state management for error handling etc.\n // Skip calling onToolCall for provider-executed tools since they are already executed\n // if (onToolCall && !data.providerExecuted) {\n // await onToolCall({\n // toolCall: data\n // });\n // }\n break;\n }\n\n case \"tool-input-error\": {\n if (data.dynamic) {\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"output-error\",\n input: data.input,\n errorText: data.errorText,\n providerMetadata: data.providerMetadata\n });\n } else {\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"output-error\",\n input: undefined,\n rawInput: data.input,\n errorText: data.errorText,\n providerExecuted: data.providerExecuted,\n providerMetadata: data.providerMetadata\n });\n }\n\n break;\n }\n\n case \"tool-output-available\": {\n if (data.dynamic) {\n const toolInvocations = message.parts.filter(\n (part) => part.type === \"dynamic-tool\"\n ) as DynamicToolUIPart[];\n\n const toolInvocation = toolInvocations.find(\n (invocation) =>\n invocation.toolCallId === data.toolCallId\n );\n\n if (!toolInvocation)\n throw new Error(\"Tool invocation not found\");\n\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: toolInvocation.toolName,\n state: \"output-available\",\n input: toolInvocation.input,\n output: data.output,\n preliminary: data.preliminary\n });\n } else {\n const toolInvocations =\n message.parts.filter(isToolUIPart);\n\n const toolInvocation = toolInvocations.find(\n (invocation) =>\n invocation.toolCallId === data.toolCallId\n );\n\n if (!toolInvocation)\n throw new Error(\"Tool invocation not found\");\n\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: getToolName(toolInvocation),\n state: \"output-available\",\n input: toolInvocation.input,\n output: data.output,\n providerExecuted: data.providerExecuted,\n preliminary: data.preliminary\n });\n }\n\n break;\n }\n\n case \"tool-output-error\": {\n if (data.dynamic) {\n const toolInvocations = message.parts.filter(\n (part) => part.type === \"dynamic-tool\"\n ) as DynamicToolUIPart[];\n\n const toolInvocation = toolInvocations.find(\n (invocation) =>\n invocation.toolCallId === data.toolCallId\n );\n\n if (!toolInvocation)\n throw new Error(\"Tool invocation not found\");\n\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: toolInvocation.toolName,\n state: \"output-error\",\n input: toolInvocation.input,\n errorText: data.errorText\n });\n } else {\n const toolInvocations =\n message.parts.filter(isToolUIPart);\n\n const toolInvocation = toolInvocations.find(\n (invocation) =>\n invocation.toolCallId === data.toolCallId\n );\n\n if (!toolInvocation)\n throw new Error(\"Tool invocation not found\");\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: getToolName(toolInvocation),\n state: \"output-error\",\n input: toolInvocation.input,\n rawInput:\n \"rawInput\" in toolInvocation\n ? toolInvocation.rawInput\n : undefined,\n errorText: data.errorText\n });\n }\n\n break;\n }\n\n case \"start-step\": {\n // add a step boundary part to the message\n message.parts.push({ type: \"step-start\" });\n break;\n }\n\n case \"finish-step\": {\n // reset the current text and reasoning parts\n activeTextParts = {};\n activeReasoningParts = {};\n break;\n }\n\n case \"start\": {\n if (data.messageId != null) {\n message.id = data.messageId;\n }\n\n await updateMessageMetadata(data.messageMetadata);\n\n break;\n }\n\n case \"finish\": {\n await updateMessageMetadata(data.messageMetadata);\n break;\n }\n\n case \"message-metadata\": {\n await updateMessageMetadata(data.messageMetadata);\n break;\n }\n\n case \"error\": {\n this._broadcastChatMessage({\n error: true,\n body: data.errorText ?? JSON.stringify(data),\n done: false,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n\n break;\n }\n // Do we want to handle data parts?\n }\n\n // Always forward the raw part to the client\n this._broadcastChatMessage({\n body: JSON.stringify(data),\n done: false,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n } catch (_e) {\n // Skip malformed JSON lines silently\n }\n }\n }\n } else {\n // Handle plain text responses (e.g., from generateText)\n // Treat the entire chunk as a text delta to preserve exact formatting\n if (chunk.length > 0) {\n message.parts.push({ type: \"text\", text: chunk });\n // Synthesize a text-delta event so clients can stream-render\n this._broadcastChatMessage({\n body: JSON.stringify({ type: \"text-delta\", delta: chunk }),\n done: false,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n if (message.parts.length > 0) {\n await this.persistMessages([...this.messages, message]);\n }\n });\n }\n\n /**\n * For the given message id, look up its associated AbortController\n * If the AbortController does not exist, create and store one in memory\n *\n * returns the AbortSignal associated with the AbortController\n */\n private _getAbortSignal(id: string): AbortSignal | undefined {\n // Defensive check, since we're coercing message types at the moment\n if (typeof id !== \"string\") {\n return undefined;\n }\n\n if (!this._chatMessageAbortControllers.has(id)) {\n this._chatMessageAbortControllers.set(id, new AbortController());\n }\n\n return this._chatMessageAbortControllers.get(id)?.signal;\n }\n\n /**\n * Remove an abort controller from the cache of pending message responses\n */\n private _removeAbortController(id: string) {\n this._chatMessageAbortControllers.delete(id);\n }\n\n /**\n * Propagate an abort signal for any requests associated with the given message id\n */\n private _cancelChatRequest(id: string) {\n if (this._chatMessageAbortControllers.has(id)) {\n const abortController = this._chatMessageAbortControllers.get(id);\n abortController?.abort();\n }\n }\n\n /**\n * Abort all pending requests and clear the cache of AbortControllers\n */\n private _destroyAbortControllers() {\n for (const controller of this._chatMessageAbortControllers.values()) {\n controller?.abort();\n }\n this._chatMessageAbortControllers.clear();\n }\n\n /**\n * When the DO is destroyed, cancel all pending requests\n */\n async destroy() {\n this._destroyAbortControllers();\n await super.destroy();\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OAUK;AASP,IAAM,UAAU,IAAI,YAAY;AAMzB,IAAM,cAAN,cAA0D,MAG/D;AAAA,EAQA,YAAY,KAAmB,KAAU;AACvC,UAAM,KAAK,GAAG;AACd,SAAK;AAAA;AAAA;AAAA;AAAA;AAOL,UAAM,cAAc,KAAK,oBAAoB;AAG7C,SAAK,WAAW,sBAAsB,WAAW;AAEjD,SAAK,+BAA+B,oBAAI,IAAI;AAAA,EAC9C;AAAA,EAEQ,sBAAsB,SAA0B,SAAoB;AAC1E,SAAK,UAAU,KAAK,UAAU,OAAO,GAAG,OAAO;AAAA,EACjD;AAAA,EAEQ,sBAAqC;AAC3C,UAAM,OACJ,KAAK,oEACL,CAAC;AACH,WAAO,KACJ,IAAI,CAAC,QAAQ;AACZ,UAAI;AACF,eAAO,KAAK,MAAM,IAAI,OAAiB;AAAA,MACzC,SAAS,OAAO;AACd,gBAAQ,MAAM,2BAA2B,IAAI,EAAE,KAAK,KAAK;AACzD,eAAO;AAAA,MACT;AAAA,IACF,CAAC,EACA,OAAO,CAAC,QAA4B,QAAQ,IAAI;AAAA,EACrD;AAAA,EAEA,MAAe,UAAU,YAAwB,SAAoB;AACnE,QAAI,OAAO,YAAY,UAAU;AAC/B,UAAI;AACJ,UAAI;AACF,eAAO,KAAK,MAAM,OAAO;AAAA,MAC3B,SAAS,QAAQ;AAGf;AAAA,MACF;AACA,UACE,KAAK,wEACL,KAAK,KAAK,WAAW,QACrB;AACA,cAAM;AAAA;AAAA;AAAA;AAAA,UAIJ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAKF,IAAI,KAAK;AACT,cAAM,EAAE,SAAS,IAAI,KAAK,MAAM,IAAc;AAG9C,cAAM,sBAAsB,sBAAsB,QAAQ;AAE1D,aAAK;AAAA,UACH;AAAA,YACE,UAAU;AAAA,YACV;AAAA,UACF;AAAA,UACA,CAAC,WAAW,EAAE;AAAA,QAChB;AAEA,cAAM,KAAK,gBAAgB,qBAAqB,CAAC,WAAW,EAAE,CAAC;AAE/D,aAAK,eAAe;AAAA,UAClB;AAAA,YACE,gBAAgB;AAAA,YAChB,IAAI,KAAK;AAAA,YACT,SAAS,CAAC;AAAA,YACV,WAAW,KAAK,IAAI;AAAA,YACpB,MAAM;AAAA,UACR;AAAA,UACA,KAAK;AAAA,QACP;AAEA,cAAM,gBAAgB,KAAK;AAC3B,cAAM,cAAc,KAAK,gBAAgB,aAAa;AAEtD,eAAO,KAAK,cAAc,YAAY;AACpC,gBAAM,WAAW,MAAM,KAAK;AAAA,YAC1B,OAAO,kBAAkB;AACvB,mBAAK,uBAAuB,aAAa;AAEzC,mBAAK,eAAe;AAAA,gBAClB;AAAA,kBACE,gBAAgB;AAAA,kBAChB,IAAI,KAAK;AAAA,kBACT,SAAS,CAAC;AAAA,kBACV,WAAW,KAAK,IAAI;AAAA,kBACpB,MAAM;AAAA,gBACR;AAAA,gBACA,KAAK;AAAA,cACP;AAAA,YAIF;AAAA,YACA,cAAc,EAAE,YAAY,IAAI;AAAA,UAClC;AAEA,cAAI,UAAU;AACZ,kBAAM,KAAK,OAAO,KAAK,IAAI,QAAQ;AAAA,UACrC,OAAO;AAEL,oBAAQ;AAAA,cACN,uEAAuE,aAAa;AAAA,YACtF;AAEA,iBAAK;AAAA,cACH;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,IAAI,KAAK;AAAA,gBACT;AAAA,cACF;AAAA,cACA,CAAC,WAAW,EAAE;AAAA,YAChB;AAAA,UACF;AAAA,QACF,CAAC;AAAA,MACH;AACA,UAAI,KAAK,0DAA0C;AACjD,aAAK,yBAAyB;AAC9B,aAAK;AACL,aAAK,WAAW,CAAC;AACjB,aAAK;AAAA,UACH;AAAA,YACE;AAAA,UACF;AAAA,UACA,CAAC,WAAW,EAAE;AAAA,QAChB;AAAA,MACF,WAAW,KAAK,gEAA6C;AAE3D,cAAM,sBAAsB,sBAAsB,KAAK,QAAQ;AAC/D,cAAM,KAAK,gBAAgB,qBAAqB,CAAC,WAAW,EAAE,CAAC;AAAA,MACjE,WAAW,KAAK,4EAAmD;AAEjE,aAAK,mBAAmB,KAAK,EAAE;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAe,UAAU,SAAqC;AAC5D,WAAO,KAAK,cAAc,MAAM;AAC9B,YAAM,MAAM,IAAI,IAAI,QAAQ,GAAG;AAC/B,UAAI,IAAI,SAAS,SAAS,eAAe,GAAG;AAC1C,cAAM,WAAW,KAAK,oBAAoB;AAC1C,eAAO,SAAS,KAAK,QAAQ;AAAA,MAC/B;AACA,aAAO,MAAM,UAAU,OAAO;AAAA,IAChC,CAAC;AAAA,EACH;AAAA,EAEA,MAAc,cAAiB,IAA0B;AACvD,QAAI;AACF,aAAO,MAAM,GAAG;AAAA,IAClB,SAAS,GAAG;AACV,YAAM,KAAK,QAAQ,CAAC;AAAA,IACtB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,MAAM,cAEJ,UAEA,SAC+B;AAC/B,UAAM,IAAI;AAAA,MACR;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,aAAa,UAAyB;AAC1C,UAAM,KAAK,gBAAgB,QAAQ;AACnC,UAAM,KAAK,cAAc,YAAY;AACnC,YAAM,WAAW,MAAM,KAAK,cAAc,MAAM;AAAA,MAAC,CAAC;AAClD,UAAI,SAAU,MAAK,OAAO,OAAO,WAAW,GAAG,QAAQ;AAAA,IACzD,CAAC;AAAA,EACH;AAAA,EAEA,MAAM,gBACJ,UACA,sBAAgC,CAAC,GACjC;AACA,eAAW,WAAW,UAAU;AAC9B,WAAK;AAAA;AAAA,kBAEO,QAAQ,EAAE,KAAK,KAAK,UAAU,OAAO,CAAC;AAAA;AAAA;AAAA,IAGpD;AAGA,UAAM,YAAY,KAAK,oBAAoB;AAC3C,SAAK,WAAW,sBAAsB,SAAS;AAC/C,SAAK;AAAA,MACH;AAAA,QACE;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAc,OAAO,IAAY,UAAoB;AACnD,WAAO,KAAK,cAAc,YAAY;AACpC,UAAI,CAAC,SAAS,MAAM;AAElB,aAAK,sBAAsB;AAAA,UACzB,MAAM;AAAA,UACN,MAAM;AAAA,UACN;AAAA,UACA;AAAA,QACF,CAAC;AACD;AAAA,MACF;AAEA,YAAM,SAAS,SAAS,KAAK,UAAU;AAIvC,YAAM,UAAuB;AAAA,QAC3B,IAAI,aAAa,KAAK,IAAI,CAAC,IAAI,KAAK,OAAO,EAAE,SAAS,EAAE,EAAE,MAAM,GAAG,EAAE,CAAC;AAAA;AAAA,QACtE,MAAM;AAAA,QACN,OAAO,CAAC;AAAA,MACV;AACA,UAAI,kBAA8C,CAAC;AACnD,UAAI,uBAAwD,CAAC;AAC7D,YAAM,mBAGF,CAAC;AAEL,eAAS,sBACP,SA2BA;AACA,cAAM,OAAO,QAAQ,MAAM;AAAA,UACzB,CAACA,UACCA,MAAK,SAAS,kBACdA,MAAK,eAAe,QAAQ;AAAA,QAChC;AAEA,cAAM,aAAa;AACnB,cAAM,UAAU;AAEhB,YAAI,QAAQ,MAAM;AAChB,eAAK,QAAQ,QAAQ;AACrB,kBAAQ,WAAW,QAAQ;AAC3B,kBAAQ,QAAQ,WAAW;AAC3B,kBAAQ,SAAS,WAAW;AAC5B,kBAAQ,YAAY,WAAW;AAC/B,kBAAQ,WAAW,WAAW,YAAY,QAAQ;AAClD,kBAAQ,cAAc,WAAW;AAEjC,cACE,WAAW,oBAAoB,QAC/B,KAAK,UAAU,mBACf;AACA,iBAAK,uBACH,WAAW;AAAA,UACf;AAAA,QACF,OAAO;AACL,kBAAQ,MAAM,KAAK;AAAA,YACjB,MAAM;AAAA,YACN,UAAU,QAAQ;AAAA,YAClB,YAAY,QAAQ;AAAA,YACpB,OAAO,QAAQ;AAAA,YACf,OAAO,WAAW;AAAA,YAClB,QAAQ,WAAW;AAAA,YACnB,WAAW,WAAW;AAAA,YACtB,aAAa,WAAW;AAAA,YACxB,GAAI,WAAW,oBAAoB,OAC/B,EAAE,sBAAsB,WAAW,iBAAiB,IACpD,CAAC;AAAA,UACP,CAAsB;AAAA,QACxB;AAAA,MACF;AAEA,eAAS,eACP,SAgCA;AACA,cAAM,OAAO,QAAQ,MAAM;AAAA,UACzB,CAACA,UAAS,aAAaA,KAAI,KAAKA,MAAK,eAAe,QAAQ;AAAA,QAC9D;AAEA,cAAM,aAAa;AACnB,cAAM,UAAU;AAEhB,YAAI,QAAQ,MAAM;AAChB,eAAK,QAAQ,QAAQ;AACrB,kBAAQ,QAAQ,WAAW;AAC3B,kBAAQ,SAAS,WAAW;AAC5B,kBAAQ,YAAY,WAAW;AAC/B,kBAAQ,WAAW,WAAW;AAC9B,kBAAQ,cAAc,WAAW;AAGjC,kBAAQ,mBACN,WAAW,oBAAoB,KAAK;AAEtC,cACE,WAAW,oBAAoB,QAC/B,KAAK,UAAU,mBACf;AACA,iBAAK,uBACH,WAAW;AAAA,UACf;AAAA,QACF,OAAO;AACL,kBAAQ,MAAM,KAAK;AAAA,YACjB,MAAM,QAAQ,QAAQ,QAAQ;AAAA,YAC9B,YAAY,QAAQ;AAAA,YACpB,OAAO,QAAQ;AAAA,YACf,OAAO,WAAW;AAAA,YAClB,QAAQ,WAAW;AAAA,YACnB,UAAU,WAAW;AAAA,YACrB,WAAW,WAAW;AAAA,YACtB,kBAAkB,WAAW;AAAA,YAC7B,aAAa,WAAW;AAAA,YACxB,GAAI,WAAW,oBAAoB,OAC/B,EAAE,sBAAsB,WAAW,iBAAiB,IACpD,CAAC;AAAA,UACP,CAAe;AAAA,QACjB;AAAA,MACF;AAEA,qBAAe,sBAAsB,UAAmB;AACtD,YAAI,YAAY,MAAM;AACpB,gBAAM,iBACJ,QAAQ,YAAY,OAChB,EAAE,GAAG,QAAQ,UAAU,GAAG,SAAS,IACnC;AAEN,kBAAQ,WAAW;AAAA,QACrB;AAAA,MACF;AAEA,UAAI;AACF,eAAO,MAAM;AACX,gBAAM,EAAE,MAAM,MAAM,IAAI,MAAM,OAAO,KAAK;AAC1C,cAAI,MAAM;AAER,iBAAK,sBAAsB;AAAA,cACzB,MAAM;AAAA,cACN,MAAM;AAAA,cACN;AAAA,cACA;AAAA,YACF,CAAC;AACD;AAAA,UACF;AAEA,gBAAM,QAAQ,QAAQ,OAAO,KAAK;AAGlC,gBAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,gBAAM,QAAQ,YAAY,SAAS,mBAAmB;AAGtD,cAAI,OAAO;AAET,kBAAM,QAAQ,MAAM,MAAM,IAAI;AAC9B,uBAAW,QAAQ,OAAO;AACxB,kBAAI,KAAK,WAAW,QAAQ,KAAK,SAAS,gBAAgB;AACxD,oBAAI;AACF,wBAAM,OAAuB,KAAK,MAAM,KAAK,MAAM,CAAC,CAAC;AACrD,0BAAQ,KAAK,MAAM;AAAA,oBACjB,KAAK,cAAc;AACjB,4BAAM,WAAuB;AAAA,wBAC3B,MAAM;AAAA,wBACN,MAAM;AAAA,wBACN,kBAAkB,KAAK;AAAA,wBACvB,OAAO;AAAA,sBACT;AACA,sCAAgB,KAAK,EAAE,IAAI;AAC3B,8BAAQ,MAAM,KAAK,QAAQ;AAC3B;AAAA,oBACF;AAAA,oBAEA,KAAK,cAAc;AACjB,4BAAM,WAAW,gBAAgB,KAAK,EAAE;AACxC,+BAAS,QAAQ,KAAK;AACtB,+BAAS,mBACP,KAAK,oBAAoB,SAAS;AACpC;AAAA,oBACF;AAAA,oBAEA,KAAK,YAAY;AACf,4BAAM,WAAW,gBAAgB,KAAK,EAAE;AACxC,+BAAS,QAAQ;AACjB,+BAAS,mBACP,KAAK,oBAAoB,SAAS;AACpC,6BAAO,gBAAgB,KAAK,EAAE;AAC9B;AAAA,oBACF;AAAA,oBAEA,KAAK,mBAAmB;AACtB,4BAAM,gBAAiC;AAAA,wBACrC,MAAM;AAAA,wBACN,MAAM;AAAA,wBACN,kBAAkB,KAAK;AAAA,wBACvB,OAAO;AAAA,sBACT;AACA,2CAAqB,KAAK,EAAE,IAAI;AAChC,8BAAQ,MAAM,KAAK,aAAa;AAChC;AAAA,oBACF;AAAA,oBAEA,KAAK,mBAAmB;AACtB,4BAAM,gBAAgB,qBAAqB,KAAK,EAAE;AAClD,oCAAc,QAAQ,KAAK;AAC3B,oCAAc,mBACZ,KAAK,oBAAoB,cAAc;AACzC;AAAA,oBACF;AAAA,oBAEA,KAAK,iBAAiB;AACpB,4BAAM,gBAAgB,qBAAqB,KAAK,EAAE;AAClD,oCAAc,mBACZ,KAAK,oBAAoB,cAAc;AACzC,oCAAc,QAAQ;AACtB,6BAAO,qBAAqB,KAAK,EAAE;AAEnC;AAAA,oBACF;AAAA,oBAEA,KAAK,QAAQ;AACX,8BAAQ,MAAM,KAAK;AAAA,wBACjB,MAAM;AAAA,wBACN,WAAW,KAAK;AAAA,wBAChB,KAAK,KAAK;AAAA,sBACZ,CAAC;AAED;AAAA,oBACF;AAAA,oBAEA,KAAK,cAAc;AACjB,8BAAQ,MAAM,KAAK;AAAA,wBACjB,MAAM;AAAA,wBACN,UAAU,KAAK;AAAA,wBACf,KAAK,KAAK;AAAA,wBACV,OAAO,KAAK;AAAA,wBACZ,kBAAkB,KAAK;AAAA,sBACzB,CAAC;AAED;AAAA,oBACF;AAAA,oBAEA,KAAK,mBAAmB;AACtB,8BAAQ,MAAM,KAAK;AAAA,wBACjB,MAAM;AAAA,wBACN,UAAU,KAAK;AAAA,wBACf,WAAW,KAAK;AAAA,wBAChB,OAAO,KAAK;AAAA,wBACZ,UAAU,KAAK;AAAA,wBACf,kBAAkB,KAAK;AAAA,sBACzB,CAAC;AAED;AAAA,oBACF;AAAA,oBAEA,KAAK,oBAAoB;AACvB,4BAAM,kBACJ,QAAQ,MAAM,OAAO,YAAY;AAGnC,uCAAiB,KAAK,UAAU,IAAI;AAAA,wBAClC,MAAM;AAAA,wBACN,UAAU,KAAK;AAAA,wBACf,OAAO,gBAAgB;AAAA,wBACvB,SAAS,KAAK;AAAA,sBAChB;AAEA,0BAAI,KAAK,SAAS;AAChB,8CAAsB;AAAA,0BACpB,YAAY,KAAK;AAAA,0BACjB,UAAU,KAAK;AAAA,0BACf,OAAO;AAAA,0BACP,OAAO;AAAA,wBACT,CAAC;AAAA,sBACH,OAAO;AACL,uCAAe;AAAA,0BACb,YAAY,KAAK;AAAA,0BACjB,UAAU,KAAK;AAAA,0BACf,OAAO;AAAA,0BACP,OAAO;AAAA,wBACT,CAAC;AAAA,sBACH;AAEA;AAAA,oBACF;AAAA,oBAEA,KAAK,oBAAoB;AACvB,4BAAM,kBAAkB,iBAAiB,KAAK,UAAU;AAExD,sCAAgB,QAAQ,KAAK;AAE7B,4BAAM,EAAE,OAAO,YAAY,IAAI,MAAM;AAAA,wBACnC,gBAAgB;AAAA,sBAClB;AAEA,0BAAI,gBAAgB,SAAS;AAC3B,8CAAsB;AAAA,0BACpB,YAAY,KAAK;AAAA,0BACjB,UAAU,gBAAgB;AAAA,0BAC1B,OAAO;AAAA,0BACP,OAAO;AAAA,wBACT,CAAC;AAAA,sBACH,OAAO;AACL,uCAAe;AAAA,0BACb,YAAY,KAAK;AAAA,0BACjB,UAAU,gBAAgB;AAAA,0BAC1B,OAAO;AAAA,0BACP,OAAO;AAAA,wBACT,CAAC;AAAA,sBACH;AAEA;AAAA,oBACF;AAAA,oBAEA,KAAK,wBAAwB;AAC3B,0BAAI,KAAK,SAAS;AAChB,8CAAsB;AAAA,0BACpB,YAAY,KAAK;AAAA,0BACjB,UAAU,KAAK;AAAA,0BACf,OAAO;AAAA,0BACP,OAAO,KAAK;AAAA,0BACZ,kBAAkB,KAAK;AAAA,wBACzB,CAAC;AAAA,sBACH,OAAO;AACL,uCAAe;AAAA,0BACb,YAAY,KAAK;AAAA,0BACjB,UAAU,KAAK;AAAA,0BACf,OAAO;AAAA,0BACP,OAAO,KAAK;AAAA,0BACZ,kBAAkB,KAAK;AAAA,0BACvB,kBAAkB,KAAK;AAAA,wBACzB,CAAC;AAAA,sBACH;AAaA;AAAA,oBACF;AAAA,oBAEA,KAAK,oBAAoB;AACvB,0BAAI,KAAK,SAAS;AAChB,8CAAsB;AAAA,0BACpB,YAAY,KAAK;AAAA,0BACjB,UAAU,KAAK;AAAA,0BACf,OAAO;AAAA,0BACP,OAAO,KAAK;AAAA,0BACZ,WAAW,KAAK;AAAA,0BAChB,kBAAkB,KAAK;AAAA,wBACzB,CAAC;AAAA,sBACH,OAAO;AACL,uCAAe;AAAA,0BACb,YAAY,KAAK;AAAA,0BACjB,UAAU,KAAK;AAAA,0BACf,OAAO;AAAA,0BACP,OAAO;AAAA,0BACP,UAAU,KAAK;AAAA,0BACf,WAAW,KAAK;AAAA,0BAChB,kBAAkB,KAAK;AAAA,0BACvB,kBAAkB,KAAK;AAAA,wBACzB,CAAC;AAAA,sBACH;AAEA;AAAA,oBACF;AAAA,oBAEA,KAAK,yBAAyB;AAC5B,0BAAI,KAAK,SAAS;AAChB,8BAAM,kBAAkB,QAAQ,MAAM;AAAA,0BACpC,CAAC,SAAS,KAAK,SAAS;AAAA,wBAC1B;AAEA,8BAAM,iBAAiB,gBAAgB;AAAA,0BACrC,CAAC,eACC,WAAW,eAAe,KAAK;AAAA,wBACnC;AAEA,4BAAI,CAAC;AACH,gCAAM,IAAI,MAAM,2BAA2B;AAE7C,8CAAsB;AAAA,0BACpB,YAAY,KAAK;AAAA,0BACjB,UAAU,eAAe;AAAA,0BACzB,OAAO;AAAA,0BACP,OAAO,eAAe;AAAA,0BACtB,QAAQ,KAAK;AAAA,0BACb,aAAa,KAAK;AAAA,wBACpB,CAAC;AAAA,sBACH,OAAO;AACL,8BAAM,kBACJ,QAAQ,MAAM,OAAO,YAAY;AAEnC,8BAAM,iBAAiB,gBAAgB;AAAA,0BACrC,CAAC,eACC,WAAW,eAAe,KAAK;AAAA,wBACnC;AAEA,4BAAI,CAAC;AACH,gCAAM,IAAI,MAAM,2BAA2B;AAE7C,uCAAe;AAAA,0BACb,YAAY,KAAK;AAAA,0BACjB,UAAU,YAAY,cAAc;AAAA,0BACpC,OAAO;AAAA,0BACP,OAAO,eAAe;AAAA,0BACtB,QAAQ,KAAK;AAAA,0BACb,kBAAkB,KAAK;AAAA,0BACvB,aAAa,KAAK;AAAA,wBACpB,CAAC;AAAA,sBACH;AAEA;AAAA,oBACF;AAAA,oBAEA,KAAK,qBAAqB;AACxB,0BAAI,KAAK,SAAS;AAChB,8BAAM,kBAAkB,QAAQ,MAAM;AAAA,0BACpC,CAAC,SAAS,KAAK,SAAS;AAAA,wBAC1B;AAEA,8BAAM,iBAAiB,gBAAgB;AAAA,0BACrC,CAAC,eACC,WAAW,eAAe,KAAK;AAAA,wBACnC;AAEA,4BAAI,CAAC;AACH,gCAAM,IAAI,MAAM,2BAA2B;AAE7C,8CAAsB;AAAA,0BACpB,YAAY,KAAK;AAAA,0BACjB,UAAU,eAAe;AAAA,0BACzB,OAAO;AAAA,0BACP,OAAO,eAAe;AAAA,0BACtB,WAAW,KAAK;AAAA,wBAClB,CAAC;AAAA,sBACH,OAAO;AACL,8BAAM,kBACJ,QAAQ,MAAM,OAAO,YAAY;AAEnC,8BAAM,iBAAiB,gBAAgB;AAAA,0BACrC,CAAC,eACC,WAAW,eAAe,KAAK;AAAA,wBACnC;AAEA,4BAAI,CAAC;AACH,gCAAM,IAAI,MAAM,2BAA2B;AAC7C,uCAAe;AAAA,0BACb,YAAY,KAAK;AAAA,0BACjB,UAAU,YAAY,cAAc;AAAA,0BACpC,OAAO;AAAA,0BACP,OAAO,eAAe;AAAA,0BACtB,UACE,cAAc,iBACV,eAAe,WACf;AAAA,0BACN,WAAW,KAAK;AAAA,wBAClB,CAAC;AAAA,sBACH;AAEA;AAAA,oBACF;AAAA,oBAEA,KAAK,cAAc;AAEjB,8BAAQ,MAAM,KAAK,EAAE,MAAM,aAAa,CAAC;AACzC;AAAA,oBACF;AAAA,oBAEA,KAAK,eAAe;AAElB,wCAAkB,CAAC;AACnB,6CAAuB,CAAC;AACxB;AAAA,oBACF;AAAA,oBAEA,KAAK,SAAS;AACZ,0BAAI,KAAK,aAAa,MAAM;AAC1B,gCAAQ,KAAK,KAAK;AAAA,sBACpB;AAEA,4BAAM,sBAAsB,KAAK,eAAe;AAEhD;AAAA,oBACF;AAAA,oBAEA,KAAK,UAAU;AACb,4BAAM,sBAAsB,KAAK,eAAe;AAChD;AAAA,oBACF;AAAA,oBAEA,KAAK,oBAAoB;AACvB,4BAAM,sBAAsB,KAAK,eAAe;AAChD;AAAA,oBACF;AAAA,oBAEA,KAAK,SAAS;AACZ,2BAAK,sBAAsB;AAAA,wBACzB,OAAO;AAAA,wBACP,MAAM,KAAK,aAAa,KAAK,UAAU,IAAI;AAAA,wBAC3C,MAAM;AAAA,wBACN;AAAA,wBACA;AAAA,sBACF,CAAC;AAED;AAAA,oBACF;AAAA,kBAEF;AAGA,uBAAK,sBAAsB;AAAA,oBACzB,MAAM,KAAK,UAAU,IAAI;AAAA,oBACzB,MAAM;AAAA,oBACN;AAAA,oBACA;AAAA,kBACF,CAAC;AAAA,gBACH,SAAS,IAAI;AAAA,gBAEb;AAAA,cACF;AAAA,YACF;AAAA,UACF,OAAO;AAGL,gBAAI,MAAM,SAAS,GAAG;AACpB,sBAAQ,MAAM,KAAK,EAAE,MAAM,QAAQ,MAAM,MAAM,CAAC;AAEhD,mBAAK,sBAAsB;AAAA,gBACzB,MAAM,KAAK,UAAU,EAAE,MAAM,cAAc,OAAO,MAAM,CAAC;AAAA,gBACzD,MAAM;AAAA,gBACN;AAAA,gBACA;AAAA,cACF,CAAC;AAAA,YACH;AAAA,UACF;AAAA,QACF;AAAA,MACF,UAAE;AACA,eAAO,YAAY;AAAA,MACrB;AAEA,UAAI,QAAQ,MAAM,SAAS,GAAG;AAC5B,cAAM,KAAK,gBAAgB,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC;AAAA,MACxD;AAAA,IACF,CAAC;AAAA,EACH;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQQ,gBAAgB,IAAqC;AAE3D,QAAI,OAAO,OAAO,UAAU;AAC1B,aAAO;AAAA,IACT;AAEA,QAAI,CAAC,KAAK,6BAA6B,IAAI,EAAE,GAAG;AAC9C,WAAK,6BAA6B,IAAI,IAAI,IAAI,gBAAgB,CAAC;AAAA,IACjE;AAEA,WAAO,KAAK,6BAA6B,IAAI,EAAE,GAAG;AAAA,EACpD;AAAA;AAAA;AAAA;AAAA,EAKQ,uBAAuB,IAAY;AACzC,SAAK,6BAA6B,OAAO,EAAE;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKQ,mBAAmB,IAAY;AACrC,QAAI,KAAK,6BAA6B,IAAI,EAAE,GAAG;AAC7C,YAAM,kBAAkB,KAAK,6BAA6B,IAAI,EAAE;AAChE,uBAAiB,MAAM;AAAA,IACzB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,2BAA2B;AACjC,eAAW,cAAc,KAAK,6BAA6B,OAAO,GAAG;AACnE,kBAAY,MAAM;AAAA,IACpB;AACA,SAAK,6BAA6B,MAAM;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU;AACd,SAAK,yBAAyB;AAC9B,UAAM,MAAM,QAAQ;AAAA,EACtB;AACF;","names":["part"]}
1
+ {"version":3,"sources":["../src/ai-chat-agent.ts"],"sourcesContent":["import type {\n UIMessage as ChatMessage,\n DynamicToolUIPart,\n ProviderMetadata,\n ReasoningUIPart,\n StreamTextOnFinishCallback,\n TextUIPart,\n ToolSet,\n ToolUIPart,\n UIMessageChunk\n} from \"ai\";\nimport { Agent, type AgentContext, type Connection, type WSMessage } from \"./\";\nimport {\n MessageType,\n type IncomingMessage,\n type OutgoingMessage\n} from \"./ai-types\";\nimport { autoTransformMessages } from \"./ai-chat-v5-migration\";\n\nconst decoder = new TextDecoder();\n\n// Lazy-load AI SDK utilities\ntype AISDK = {\n getToolName: typeof import(\"ai\").getToolName;\n isToolUIPart: typeof import(\"ai\").isToolUIPart;\n parsePartialJson: typeof import(\"ai\").parsePartialJson;\n};\nlet aiSDK: AISDK | undefined;\nfunction getAISDK() {\n if (!aiSDK) {\n // Use destructuring to help with tree-shaking\n const { getToolName, isToolUIPart, parsePartialJson } = require(\"ai\");\n aiSDK = {\n getToolName,\n isToolUIPart,\n parsePartialJson\n };\n }\n return aiSDK!;\n}\n\n/**\n * Extension of Agent with built-in chat capabilities\n * @template Env Environment type containing bindings\n */\nexport class AIChatAgent<Env = unknown, State = unknown> extends Agent<\n Env,\n State\n> {\n /**\n * Map of message `id`s to `AbortController`s\n * useful to propagate request cancellation signals for any external calls made by the agent\n */\n private _chatMessageAbortControllers: Map<string, AbortController>;\n /** Array of chat messages for the current conversation */\n messages: ChatMessage[];\n constructor(ctx: AgentContext, env: Env) {\n super(ctx, env);\n this.sql`create table if not exists cf_ai_chat_agent_messages (\n id text primary key,\n message text not null,\n created_at datetime default current_timestamp\n )`;\n\n // Load messages and automatically transform them to v5 format\n const rawMessages = this._loadMessagesFromDb();\n\n // Automatic migration following https://jhak.im/blog/ai-sdk-migration-handling-previously-saved-messages\n this.messages = autoTransformMessages(rawMessages);\n\n this._chatMessageAbortControllers = new Map();\n }\n\n private _broadcastChatMessage(message: OutgoingMessage, exclude?: string[]) {\n this.broadcast(JSON.stringify(message), exclude);\n }\n\n private _loadMessagesFromDb(): ChatMessage[] {\n const rows =\n this.sql`select * from cf_ai_chat_agent_messages order by created_at` ||\n [];\n return rows\n .map((row) => {\n try {\n return JSON.parse(row.message as string);\n } catch (error) {\n console.error(`Failed to parse message ${row.id}:`, error);\n return null;\n }\n })\n .filter((msg): msg is ChatMessage => msg !== null);\n }\n\n override async onMessage(connection: Connection, message: WSMessage) {\n if (typeof message === \"string\") {\n let data: IncomingMessage;\n try {\n data = JSON.parse(message) as IncomingMessage;\n } catch (_error) {\n // silently ignore invalid messages for now\n // TODO: log errors with log levels\n return;\n }\n if (\n data.type === MessageType.CF_AGENT_USE_CHAT_REQUEST &&\n data.init.method === \"POST\"\n ) {\n const {\n // method,\n // keepalive,\n // headers,\n body // we're reading this\n //\n // // these might not exist?\n // dispatcher,\n // duplex\n } = data.init;\n const { messages } = JSON.parse(body as string);\n\n // Automatically transform any incoming messages\n const transformedMessages = autoTransformMessages(messages);\n\n this._broadcastChatMessage(\n {\n messages: transformedMessages,\n type: MessageType.CF_AGENT_CHAT_MESSAGES\n },\n [connection.id]\n );\n\n await this.persistMessages(transformedMessages, [connection.id]);\n\n this.observability?.emit(\n {\n displayMessage: \"Chat message request\",\n id: data.id,\n payload: {},\n timestamp: Date.now(),\n type: \"message:request\"\n },\n this.ctx\n );\n\n const chatMessageId = data.id;\n const abortSignal = this._getAbortSignal(chatMessageId);\n\n return this._tryCatchChat(async () => {\n const response = await this.onChatMessage(\n async (_finishResult) => {\n this._removeAbortController(chatMessageId);\n\n this.observability?.emit(\n {\n displayMessage: \"Chat message response\",\n id: data.id,\n payload: {},\n timestamp: Date.now(),\n type: \"message:response\"\n },\n this.ctx\n );\n\n // Note: Message persistence now happens in the _reply method\n // after the complete response text has been accumulated\n },\n abortSignal ? { abortSignal } : undefined\n );\n\n if (response) {\n await this._reply(data.id, response);\n } else {\n // Log a warning for observability\n console.warn(\n `[AIChatAgent] onChatMessage returned no response for chatMessageId: ${chatMessageId}`\n );\n // Send a fallback message to the client\n this._broadcastChatMessage(\n {\n body: \"No response was generated by the agent.\",\n done: true,\n id: data.id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n },\n [connection.id]\n );\n }\n });\n }\n if (data.type === MessageType.CF_AGENT_CHAT_CLEAR) {\n this._destroyAbortControllers();\n this.sql`delete from cf_ai_chat_agent_messages`;\n this.messages = [];\n this._broadcastChatMessage(\n {\n type: MessageType.CF_AGENT_CHAT_CLEAR\n },\n [connection.id]\n );\n } else if (data.type === MessageType.CF_AGENT_CHAT_MESSAGES) {\n // replace the messages with the new ones, automatically transformed\n const transformedMessages = autoTransformMessages(data.messages);\n await this.persistMessages(transformedMessages, [connection.id]);\n } else if (data.type === MessageType.CF_AGENT_CHAT_REQUEST_CANCEL) {\n // propagate an abort signal for the associated request\n this._cancelChatRequest(data.id);\n }\n }\n }\n\n override async onRequest(request: Request): Promise<Response> {\n return this._tryCatchChat(() => {\n const url = new URL(request.url);\n if (url.pathname.endsWith(\"/get-messages\")) {\n const messages = this._loadMessagesFromDb();\n return Response.json(messages);\n }\n return super.onRequest(request);\n });\n }\n\n private async _tryCatchChat<T>(fn: () => T | Promise<T>) {\n try {\n return await fn();\n } catch (e) {\n throw this.onError(e);\n }\n }\n\n /**\n * Handle incoming chat messages and generate a response\n * @param onFinish Callback to be called when the response is finished\n * @param options.signal A signal to pass to any child requests which can be used to cancel them\n * @returns Response to send to the client or undefined\n */\n async onChatMessage(\n // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later\n onFinish: StreamTextOnFinishCallback<ToolSet>,\n // biome-ignore lint/correctness/noUnusedFunctionParameters: overridden later\n options?: { abortSignal: AbortSignal | undefined }\n ): Promise<Response | undefined> {\n throw new Error(\n \"recieved a chat message, override onChatMessage and return a Response to send to the client\"\n );\n }\n\n /**\n * Save messages on the server side\n * @param messages Chat messages to save\n */\n async saveMessages(messages: ChatMessage[]) {\n await this.persistMessages(messages);\n await this._tryCatchChat(async () => {\n const response = await this.onChatMessage(() => {});\n if (response) this._reply(crypto.randomUUID(), response);\n });\n }\n\n async persistMessages(\n messages: ChatMessage[],\n excludeBroadcastIds: string[] = []\n ) {\n for (const message of messages) {\n this.sql`\n insert into cf_ai_chat_agent_messages (id, message)\n values (${message.id}, ${JSON.stringify(message)})\n on conflict(id) do update set message = excluded.message\n `;\n }\n\n // refresh in-memory messages\n const persisted = this._loadMessagesFromDb();\n this.messages = autoTransformMessages(persisted);\n this._broadcastChatMessage(\n {\n messages: messages,\n type: MessageType.CF_AGENT_CHAT_MESSAGES\n },\n excludeBroadcastIds\n );\n }\n\n private async _reply(id: string, response: Response) {\n return this._tryCatchChat(async () => {\n if (!response.body) {\n // Send empty response if no body\n this._broadcastChatMessage({\n body: \"\",\n done: true,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n return;\n }\n\n const reader = response.body.getReader();\n\n // Parsing state adapted from:\n // https://github.com/vercel/ai/blob/main/packages/ai/src/ui-message-stream/ui-message-chunks.ts#L295\n const message: ChatMessage = {\n id: `assistant_${Date.now()}_${Math.random().toString(36).slice(2, 11)}`, // default\n role: \"assistant\",\n parts: []\n };\n let activeTextParts: Record<string, TextUIPart> = {};\n let activeReasoningParts: Record<string, ReasoningUIPart> = {};\n const partialToolCalls: Record<\n string,\n { text: string; index: number; toolName: string; dynamic?: boolean }\n > = {};\n\n function updateDynamicToolPart(\n options: {\n toolName: string;\n toolCallId: string;\n providerExecuted?: boolean;\n } & (\n | {\n state: \"input-streaming\";\n input: unknown;\n }\n | {\n state: \"input-available\";\n input: unknown;\n providerMetadata?: ProviderMetadata;\n }\n | {\n state: \"output-available\";\n input: unknown;\n output: unknown;\n preliminary: boolean | undefined;\n }\n | {\n state: \"output-error\";\n input: unknown;\n errorText: string;\n providerMetadata?: ProviderMetadata;\n }\n )\n ) {\n const part = message.parts.find(\n (part) =>\n part.type === \"dynamic-tool\" &&\n part.toolCallId === options.toolCallId\n ) as DynamicToolUIPart | undefined;\n\n const anyOptions = options as Record<string, unknown>;\n const anyPart = part as Record<string, unknown>;\n\n if (part != null) {\n part.state = options.state;\n anyPart.toolName = options.toolName;\n anyPart.input = anyOptions.input;\n anyPart.output = anyOptions.output;\n anyPart.errorText = anyOptions.errorText;\n anyPart.rawInput = anyOptions.rawInput ?? anyPart.rawInput;\n anyPart.preliminary = anyOptions.preliminary;\n\n if (\n anyOptions.providerMetadata != null &&\n part.state === \"input-available\"\n ) {\n part.callProviderMetadata =\n anyOptions.providerMetadata as ProviderMetadata;\n }\n } else {\n message.parts.push({\n type: \"dynamic-tool\",\n toolName: options.toolName,\n toolCallId: options.toolCallId,\n state: options.state,\n input: anyOptions.input,\n output: anyOptions.output,\n errorText: anyOptions.errorText,\n preliminary: anyOptions.preliminary,\n ...(anyOptions.providerMetadata != null\n ? { callProviderMetadata: anyOptions.providerMetadata }\n : {})\n } as DynamicToolUIPart);\n }\n }\n\n function updateToolPart(\n options: {\n toolName: string;\n toolCallId: string;\n providerExecuted?: boolean;\n } & (\n | {\n state: \"input-streaming\";\n input: unknown;\n providerExecuted?: boolean;\n }\n | {\n state: \"input-available\";\n input: unknown;\n providerExecuted?: boolean;\n providerMetadata?: ProviderMetadata;\n }\n | {\n state: \"output-available\";\n input: unknown;\n output: unknown;\n providerExecuted?: boolean;\n preliminary?: boolean;\n }\n | {\n state: \"output-error\";\n input: unknown;\n rawInput?: unknown;\n errorText: string;\n providerExecuted?: boolean;\n providerMetadata?: ProviderMetadata;\n }\n )\n ) {\n const { isToolUIPart } = getAISDK();\n const part = message.parts.find(\n (part) =>\n isToolUIPart(part) &&\n (part as ToolUIPart).toolCallId === options.toolCallId\n ) as ToolUIPart | undefined;\n\n const anyOptions = options as Record<string, unknown>;\n const anyPart = part as Record<string, unknown>;\n\n if (part != null) {\n part.state = options.state;\n anyPart.input = anyOptions.input;\n anyPart.output = anyOptions.output;\n anyPart.errorText = anyOptions.errorText;\n anyPart.rawInput = anyOptions.rawInput;\n anyPart.preliminary = anyOptions.preliminary;\n\n // once providerExecuted is set, it stays for streaming\n anyPart.providerExecuted =\n anyOptions.providerExecuted ?? part.providerExecuted;\n\n if (\n anyOptions.providerMetadata != null &&\n part.state === \"input-available\"\n ) {\n part.callProviderMetadata =\n anyOptions.providerMetadata as ProviderMetadata;\n }\n } else {\n message.parts.push({\n type: `tool-${options.toolName}`,\n toolCallId: options.toolCallId,\n state: options.state,\n input: anyOptions.input,\n output: anyOptions.output,\n rawInput: anyOptions.rawInput,\n errorText: anyOptions.errorText,\n providerExecuted: anyOptions.providerExecuted,\n preliminary: anyOptions.preliminary,\n ...(anyOptions.providerMetadata != null\n ? { callProviderMetadata: anyOptions.providerMetadata }\n : {})\n } as ToolUIPart);\n }\n }\n\n async function updateMessageMetadata(metadata: unknown) {\n if (metadata != null) {\n const mergedMetadata =\n message.metadata != null\n ? { ...message.metadata, ...metadata } // TODO: do proper merging\n : metadata;\n\n message.metadata = mergedMetadata;\n }\n }\n\n try {\n while (true) {\n const { done, value } = await reader.read();\n if (done) {\n // Send final completion signal\n this._broadcastChatMessage({\n body: \"\",\n done: true,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n break;\n }\n\n const chunk = decoder.decode(value);\n\n // Determine response format based on content-type\n const contentType = response.headers.get(\"content-type\") || \"\";\n const isSSE = contentType.includes(\"text/event-stream\");\n\n // After streaming is complete, persist the complete assistant's response\n if (isSSE) {\n // Parse AI SDK v5 SSE format and extract text deltas\n const lines = chunk.split(\"\\n\");\n for (const line of lines) {\n if (line.startsWith(\"data: \") && line !== \"data: [DONE]\") {\n try {\n const data: UIMessageChunk = JSON.parse(line.slice(6)); // Remove 'data: ' prefix\n switch (data.type) {\n case \"text-start\": {\n const textPart: TextUIPart = {\n type: \"text\",\n text: \"\",\n providerMetadata: data.providerMetadata,\n state: \"streaming\"\n };\n activeTextParts[data.id] = textPart;\n message.parts.push(textPart);\n break;\n }\n\n case \"text-delta\": {\n const textPart = activeTextParts[data.id];\n textPart.text += data.delta;\n textPart.providerMetadata =\n data.providerMetadata ?? textPart.providerMetadata;\n break;\n }\n\n case \"text-end\": {\n const textPart = activeTextParts[data.id];\n textPart.state = \"done\";\n textPart.providerMetadata =\n data.providerMetadata ?? textPart.providerMetadata;\n delete activeTextParts[data.id];\n break;\n }\n\n case \"reasoning-start\": {\n const reasoningPart: ReasoningUIPart = {\n type: \"reasoning\",\n text: \"\",\n providerMetadata: data.providerMetadata,\n state: \"streaming\"\n };\n activeReasoningParts[data.id] = reasoningPart;\n message.parts.push(reasoningPart);\n break;\n }\n\n case \"reasoning-delta\": {\n const reasoningPart = activeReasoningParts[data.id];\n reasoningPart.text += data.delta;\n reasoningPart.providerMetadata =\n data.providerMetadata ?? reasoningPart.providerMetadata;\n break;\n }\n\n case \"reasoning-end\": {\n const reasoningPart = activeReasoningParts[data.id];\n reasoningPart.providerMetadata =\n data.providerMetadata ?? reasoningPart.providerMetadata;\n reasoningPart.state = \"done\";\n delete activeReasoningParts[data.id];\n\n break;\n }\n\n case \"file\": {\n message.parts.push({\n type: \"file\",\n mediaType: data.mediaType,\n url: data.url\n });\n\n break;\n }\n\n case \"source-url\": {\n message.parts.push({\n type: \"source-url\",\n sourceId: data.sourceId,\n url: data.url,\n title: data.title,\n providerMetadata: data.providerMetadata\n });\n\n break;\n }\n\n case \"source-document\": {\n message.parts.push({\n type: \"source-document\",\n sourceId: data.sourceId,\n mediaType: data.mediaType,\n title: data.title,\n filename: data.filename,\n providerMetadata: data.providerMetadata\n });\n\n break;\n }\n\n case \"tool-input-start\": {\n const { isToolUIPart } = getAISDK();\n const toolInvocations =\n message.parts.filter(isToolUIPart);\n\n // add the partial tool call to the map\n partialToolCalls[data.toolCallId] = {\n text: \"\",\n toolName: data.toolName,\n index: toolInvocations.length,\n dynamic: data.dynamic\n };\n\n if (data.dynamic) {\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"input-streaming\",\n input: undefined\n });\n } else {\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"input-streaming\",\n input: undefined\n });\n }\n\n break;\n }\n\n case \"tool-input-delta\": {\n const partialToolCall = partialToolCalls[data.toolCallId];\n\n partialToolCall.text += data.inputTextDelta;\n\n const { parsePartialJson } = getAISDK();\n const partialArgsResult = await parsePartialJson(\n partialToolCall.text\n );\n const partialArgs = (\n partialArgsResult as { value: Record<string, unknown> }\n ).value;\n\n if (partialToolCall.dynamic) {\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: partialToolCall.toolName,\n state: \"input-streaming\",\n input: partialArgs\n });\n } else {\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: partialToolCall.toolName,\n state: \"input-streaming\",\n input: partialArgs\n });\n }\n\n break;\n }\n\n case \"tool-input-available\": {\n if (data.dynamic) {\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"input-available\",\n input: data.input,\n providerMetadata: data.providerMetadata\n });\n } else {\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"input-available\",\n input: data.input,\n providerExecuted: data.providerExecuted,\n providerMetadata: data.providerMetadata\n });\n }\n\n // TODO: Do we want to expose onToolCall?\n\n // invoke the onToolCall callback if it exists. This is blocking.\n // In the future we should make this non-blocking, which\n // requires additional state management for error handling etc.\n // Skip calling onToolCall for provider-executed tools since they are already executed\n // if (onToolCall && !data.providerExecuted) {\n // await onToolCall({\n // toolCall: data\n // });\n // }\n break;\n }\n\n case \"tool-input-error\": {\n if (data.dynamic) {\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"output-error\",\n input: data.input,\n errorText: data.errorText,\n providerMetadata: data.providerMetadata\n });\n } else {\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: data.toolName,\n state: \"output-error\",\n input: undefined,\n rawInput: data.input,\n errorText: data.errorText,\n providerExecuted: data.providerExecuted,\n providerMetadata: data.providerMetadata\n });\n }\n\n break;\n }\n\n case \"tool-output-available\": {\n if (data.dynamic) {\n const toolInvocations = message.parts.filter(\n (part) => part.type === \"dynamic-tool\"\n ) as DynamicToolUIPart[];\n\n const toolInvocation = toolInvocations.find(\n (invocation) =>\n invocation.toolCallId === data.toolCallId\n );\n\n if (!toolInvocation)\n throw new Error(\"Tool invocation not found\");\n\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: toolInvocation.toolName,\n state: \"output-available\",\n input: toolInvocation.input,\n output: data.output,\n preliminary: data.preliminary\n });\n } else {\n const { isToolUIPart, getToolName } = getAISDK();\n const toolInvocations = message.parts.filter(\n isToolUIPart\n ) as ToolUIPart[];\n\n const toolInvocation = toolInvocations.find(\n (invocation) =>\n invocation.toolCallId === data.toolCallId\n );\n\n if (!toolInvocation)\n throw new Error(\"Tool invocation not found\");\n\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: getToolName(toolInvocation),\n state: \"output-available\",\n input: toolInvocation.input,\n output: data.output,\n providerExecuted: data.providerExecuted,\n preliminary: data.preliminary\n });\n }\n\n break;\n }\n\n case \"tool-output-error\": {\n if (data.dynamic) {\n const toolInvocations = message.parts.filter(\n (part) => part.type === \"dynamic-tool\"\n ) as DynamicToolUIPart[];\n\n const toolInvocation = toolInvocations.find(\n (invocation) =>\n invocation.toolCallId === data.toolCallId\n );\n\n if (!toolInvocation)\n throw new Error(\"Tool invocation not found\");\n\n updateDynamicToolPart({\n toolCallId: data.toolCallId,\n toolName: toolInvocation.toolName,\n state: \"output-error\",\n input: toolInvocation.input,\n errorText: data.errorText\n });\n } else {\n const { isToolUIPart, getToolName } = getAISDK();\n const toolInvocations = message.parts.filter(\n isToolUIPart\n ) as ToolUIPart[];\n\n const toolInvocation = toolInvocations.find(\n (invocation) =>\n invocation.toolCallId === data.toolCallId\n );\n\n if (!toolInvocation)\n throw new Error(\"Tool invocation not found\");\n updateToolPart({\n toolCallId: data.toolCallId,\n toolName: getToolName(toolInvocation),\n state: \"output-error\",\n input: toolInvocation.input,\n rawInput:\n \"rawInput\" in toolInvocation\n ? toolInvocation.rawInput\n : undefined,\n errorText: data.errorText\n });\n }\n\n break;\n }\n\n case \"start-step\": {\n // add a step boundary part to the message\n message.parts.push({ type: \"step-start\" });\n break;\n }\n\n case \"finish-step\": {\n // reset the current text and reasoning parts\n activeTextParts = {};\n activeReasoningParts = {};\n break;\n }\n\n case \"start\": {\n if (data.messageId != null) {\n message.id = data.messageId;\n }\n\n await updateMessageMetadata(data.messageMetadata);\n\n break;\n }\n\n case \"finish\": {\n await updateMessageMetadata(data.messageMetadata);\n break;\n }\n\n case \"message-metadata\": {\n await updateMessageMetadata(data.messageMetadata);\n break;\n }\n\n case \"error\": {\n this._broadcastChatMessage({\n error: true,\n body: data.errorText ?? JSON.stringify(data),\n done: false,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n\n break;\n }\n // Do we want to handle data parts?\n }\n\n // Always forward the raw part to the client\n this._broadcastChatMessage({\n body: JSON.stringify(data),\n done: false,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n } catch (_e) {\n // Skip malformed JSON lines silently\n }\n }\n }\n } else {\n // Handle plain text responses (e.g., from generateText)\n // Treat the entire chunk as a text delta to preserve exact formatting\n if (chunk.length > 0) {\n message.parts.push({ type: \"text\", text: chunk });\n // Synthesize a text-delta event so clients can stream-render\n this._broadcastChatMessage({\n body: JSON.stringify({ type: \"text-delta\", delta: chunk }),\n done: false,\n id,\n type: MessageType.CF_AGENT_USE_CHAT_RESPONSE\n });\n }\n }\n }\n } finally {\n reader.releaseLock();\n }\n\n if (message.parts.length > 0) {\n await this.persistMessages([...this.messages, message]);\n }\n });\n }\n\n /**\n * For the given message id, look up its associated AbortController\n * If the AbortController does not exist, create and store one in memory\n *\n * returns the AbortSignal associated with the AbortController\n */\n private _getAbortSignal(id: string): AbortSignal | undefined {\n // Defensive check, since we're coercing message types at the moment\n if (typeof id !== \"string\") {\n return undefined;\n }\n\n if (!this._chatMessageAbortControllers.has(id)) {\n this._chatMessageAbortControllers.set(id, new AbortController());\n }\n\n return this._chatMessageAbortControllers.get(id)?.signal;\n }\n\n /**\n * Remove an abort controller from the cache of pending message responses\n */\n private _removeAbortController(id: string) {\n this._chatMessageAbortControllers.delete(id);\n }\n\n /**\n * Propagate an abort signal for any requests associated with the given message id\n */\n private _cancelChatRequest(id: string) {\n if (this._chatMessageAbortControllers.has(id)) {\n const abortController = this._chatMessageAbortControllers.get(id);\n abortController?.abort();\n }\n }\n\n /**\n * Abort all pending requests and clear the cache of AbortControllers\n */\n private _destroyAbortControllers() {\n for (const controller of this._chatMessageAbortControllers.values()) {\n controller?.abort();\n }\n this._chatMessageAbortControllers.clear();\n }\n\n /**\n * When the DO is destroyed, cancel all pending requests\n */\n async destroy() {\n this._destroyAbortControllers();\n await super.destroy();\n }\n}\n"],"mappings":"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","names":["part"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  DisposableStore,
3
3
  MCPClientManager
4
- } from "./chunk-ZMMHNOMZ.js";
4
+ } from "./chunk-QUOGV3WN.js";
5
5
  import {
6
6
  DurableObjectOAuthClientProvider
7
7
  } from "./chunk-C2OEBJZ2.js";
@@ -1340,4 +1340,4 @@ export {
1340
1340
  getAgentByName,
1341
1341
  StreamingResponse
1342
1342
  };
1343
- //# sourceMappingURL=chunk-XGMKNUJA.js.map
1343
+ //# sourceMappingURL=chunk-2Y6KNRNP.js.map
@@ -1,5 +1,8 @@
1
+ import {
2
+ __require
3
+ } from "./chunk-PR4QN5HX.js";
4
+
1
5
  // src/mcp/client.ts
2
- import { jsonSchema } from "ai";
3
6
  import { nanoid as nanoid2 } from "nanoid";
4
7
 
5
8
  // src/core/events.ts
@@ -550,6 +553,14 @@ var MCPClientConnection = class {
550
553
  };
551
554
 
552
555
  // src/mcp/client.ts
556
+ var jsonSchemaFn;
557
+ function getJsonSchema() {
558
+ if (!jsonSchemaFn) {
559
+ const { jsonSchema } = __require("ai");
560
+ jsonSchemaFn = jsonSchema;
561
+ }
562
+ return jsonSchemaFn;
563
+ }
553
564
  var MCPClientManager = class {
554
565
  /**
555
566
  * @param _name Name of the MCP client
@@ -799,12 +810,8 @@ var MCPClientManager = class {
799
810
  }
800
811
  return result;
801
812
  },
802
- // @ts-expect-error drift between ai and mcp types
803
- inputSchema: jsonSchema(tool.inputSchema),
804
- outputSchema: tool.outputSchema ? (
805
- // @ts-expect-error drift between ai and mcp types
806
- jsonSchema(tool.outputSchema)
807
- ) : void 0
813
+ inputSchema: getJsonSchema()(tool.inputSchema),
814
+ outputSchema: tool.outputSchema ? getJsonSchema()(tool.outputSchema) : void 0
808
815
  }
809
816
  ];
810
817
  })
@@ -939,4 +946,4 @@ export {
939
946
  MCPClientManager,
940
947
  getNamespacedData
941
948
  };
942
- //# sourceMappingURL=chunk-ZMMHNOMZ.js.map
949
+ //# sourceMappingURL=chunk-QUOGV3WN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/mcp/client.ts","../src/core/events.ts","../src/mcp/client-connection.ts","../src/mcp/errors.ts","../src/mcp/sse-edge.ts","../src/mcp/streamable-http-edge.ts"],"sourcesContent":["import type { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { RequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolRequest,\n CallToolResultSchema,\n CompatibilityCallToolResultSchema,\n GetPromptRequest,\n Prompt,\n ReadResourceRequest,\n Resource,\n ResourceTemplate,\n Tool\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { ToolSet } from \"ai\";\nimport type { JSONSchema7 } from \"json-schema\";\nimport { nanoid } from \"nanoid\";\nimport { Emitter, type Event, DisposableStore } from \"../core/events\";\nimport type { MCPObservabilityEvent } from \"../observability/mcp\";\nimport {\n MCPClientConnection,\n type MCPTransportOptions\n} from \"./client-connection\";\nimport { toErrorMessage } from \"./errors\";\nimport type { TransportType } from \"./types\";\n\nlet jsonSchemaFn: typeof import(\"ai\").jsonSchema | undefined;\nfunction getJsonSchema() {\n if (!jsonSchemaFn) {\n const { jsonSchema } = require(\"ai\");\n jsonSchemaFn = jsonSchema;\n }\n return jsonSchemaFn;\n}\n\nexport type MCPClientOAuthCallbackConfig = {\n successRedirect?: string;\n errorRedirect?: string;\n customHandler?: (result: MCPClientOAuthResult) => Response;\n};\n\nexport type MCPClientOAuthResult = {\n serverId: string;\n authSuccess: boolean;\n authError?: string;\n};\n\n/**\n * Utility class that aggregates multiple MCP clients into one\n */\nexport class MCPClientManager {\n public mcpConnections: Record<string, MCPClientConnection> = {};\n private _callbackUrls: string[] = [];\n private _didWarnAboutUnstableGetAITools = false;\n private _oauthCallbackConfig?: MCPClientOAuthCallbackConfig;\n private _connectionDisposables = new Map<string, DisposableStore>();\n\n private readonly _onObservabilityEvent = new Emitter<MCPObservabilityEvent>();\n public readonly onObservabilityEvent: Event<MCPObservabilityEvent> =\n this._onObservabilityEvent.event;\n\n private readonly _onConnected = new Emitter<string>();\n public readonly onConnected: Event<string> = this._onConnected.event;\n\n /**\n * @param _name Name of the MCP client\n * @param _version Version of the MCP Client\n * @param auth Auth paramters if being used to create a DurableObjectOAuthClientProvider\n */\n constructor(\n private _name: string,\n private _version: string\n ) {}\n\n /**\n * Connect to and register an MCP server\n *\n * @param transportConfig Transport config\n * @param clientConfig Client config\n * @param capabilities Client capabilities (i.e. if the client supports roots/sampling)\n */\n async connect(\n url: string,\n options: {\n // Allows you to reconnect to a server (in the case of an auth reconnect)\n reconnect?: {\n // server id\n id: string;\n oauthClientId?: string;\n oauthCode?: string;\n };\n // we're overriding authProvider here because we want to be able to access the auth URL\n transport?: MCPTransportOptions;\n client?: ConstructorParameters<typeof Client>[1];\n } = {}\n ): Promise<{\n id: string;\n authUrl?: string;\n clientId?: string;\n }> {\n const id = options.reconnect?.id ?? nanoid(8);\n\n if (options.transport?.authProvider) {\n options.transport.authProvider.serverId = id;\n // reconnect with auth\n if (options.reconnect?.oauthClientId) {\n options.transport.authProvider.clientId =\n options.reconnect?.oauthClientId;\n }\n }\n\n // During OAuth reconnect, reuse existing connection to preserve state\n if (!options.reconnect?.oauthCode || !this.mcpConnections[id]) {\n const normalizedTransport = {\n ...options.transport,\n type: options.transport?.type ?? (\"auto\" as TransportType)\n };\n\n this.mcpConnections[id] = new MCPClientConnection(\n new URL(url),\n {\n name: this._name,\n version: this._version\n },\n {\n client: options.client ?? {},\n transport: normalizedTransport\n }\n );\n\n // Pipe connection-level observability events to the manager-level emitter\n // and track the subscription for cleanup.\n const store = new DisposableStore();\n // If we somehow already had disposables for this id, clear them first\n const existing = this._connectionDisposables.get(id);\n if (existing) existing.dispose();\n this._connectionDisposables.set(id, store);\n store.add(\n this.mcpConnections[id].onObservabilityEvent((event) => {\n this._onObservabilityEvent.fire(event);\n })\n );\n }\n\n // Initialize connection first\n await this.mcpConnections[id].init();\n\n // Handle OAuth completion if we have a reconnect code\n if (options.reconnect?.oauthCode) {\n try {\n await this.mcpConnections[id].completeAuthorization(\n options.reconnect.oauthCode\n );\n await this.mcpConnections[id].establishConnection();\n } catch (error) {\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Failed to complete OAuth reconnection for ${id} for ${url}`,\n payload: {\n url: url,\n transport: options.transport?.type ?? \"auto\",\n state: this.mcpConnections[id].connectionState,\n error: toErrorMessage(error)\n },\n timestamp: Date.now(),\n id\n });\n // Re-throw to signal failure to the caller\n throw error;\n }\n }\n\n // If connection is in authenticating state, return auth URL for OAuth flow\n const authUrl = options.transport?.authProvider?.authUrl;\n if (\n this.mcpConnections[id].connectionState === \"authenticating\" &&\n authUrl &&\n options.transport?.authProvider?.redirectUrl\n ) {\n this._callbackUrls.push(\n options.transport.authProvider.redirectUrl.toString()\n );\n return {\n authUrl,\n clientId: options.transport?.authProvider?.clientId,\n id\n };\n }\n\n return {\n id\n };\n }\n\n isCallbackRequest(req: Request): boolean {\n return (\n req.method === \"GET\" &&\n !!this._callbackUrls.find((url) => {\n return req.url.startsWith(url);\n })\n );\n }\n\n async handleCallbackRequest(req: Request) {\n const url = new URL(req.url);\n const urlMatch = this._callbackUrls.find((url) => {\n return req.url.startsWith(url);\n });\n if (!urlMatch) {\n throw new Error(\n `No callback URI match found for the request url: ${req.url}. Was the request matched with \\`isCallbackRequest()\\`?`\n );\n }\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const urlParams = urlMatch.split(\"/\");\n const serverId = urlParams[urlParams.length - 1];\n if (!code) {\n throw new Error(\"Unauthorized: no code provided\");\n }\n if (!state) {\n throw new Error(\"Unauthorized: no state provided\");\n }\n\n if (this.mcpConnections[serverId] === undefined) {\n throw new Error(`Could not find serverId: ${serverId}`);\n }\n\n if (this.mcpConnections[serverId].connectionState !== \"authenticating\") {\n throw new Error(\n \"Failed to authenticate: the client isn't in the `authenticating` state\"\n );\n }\n\n const conn = this.mcpConnections[serverId];\n if (!conn.options.transport.authProvider) {\n throw new Error(\n \"Trying to finalize authentication for a server connection without an authProvider\"\n );\n }\n\n // Get clientId from auth provider (stored during redirectToAuthorization) or fallback to state for backward compatibility\n const clientId = conn.options.transport.authProvider.clientId || state;\n\n // Set the OAuth credentials\n conn.options.transport.authProvider.clientId = clientId;\n conn.options.transport.authProvider.serverId = serverId;\n\n try {\n await conn.completeAuthorization(code);\n return {\n serverId,\n authSuccess: true\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n\n return {\n serverId,\n authSuccess: false,\n authError: errorMessage\n };\n }\n }\n\n /**\n * Establish connection in the background after OAuth completion\n * This method is called asynchronously and doesn't block the OAuth callback response\n * @param serverId The server ID to establish connection for\n */\n async establishConnection(serverId: string): Promise<void> {\n const conn = this.mcpConnections[serverId];\n if (!conn) {\n this._onObservabilityEvent.fire({\n type: \"mcp:client:preconnect\",\n displayMessage: `Connection not found for serverId: ${serverId}`,\n payload: { serverId },\n timestamp: Date.now(),\n id: nanoid()\n });\n return;\n }\n\n try {\n await conn.establishConnection();\n this._onConnected.fire(serverId);\n } catch (error) {\n const url = conn.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Failed to establish connection to server ${serverId} with url ${url}`,\n payload: {\n url,\n transport: conn.options.transport.type ?? \"auto\",\n state: conn.connectionState,\n error: toErrorMessage(error)\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n }\n }\n\n /**\n * Register a callback URL for OAuth handling\n * @param url The callback URL to register\n */\n registerCallbackUrl(url: string): void {\n if (!this._callbackUrls.includes(url)) {\n this._callbackUrls.push(url);\n }\n }\n\n /**\n * Unregister a callback URL\n * @param serverId The server ID whose callback URL should be removed\n */\n unregisterCallbackUrl(serverId: string): void {\n // Remove callback URLs that end with this serverId\n this._callbackUrls = this._callbackUrls.filter(\n (url) => !url.endsWith(`/${serverId}`)\n );\n }\n\n /**\n * Configure OAuth callback handling\n * @param config OAuth callback configuration\n */\n configureOAuthCallback(config: MCPClientOAuthCallbackConfig): void {\n this._oauthCallbackConfig = config;\n }\n\n /**\n * Get the current OAuth callback configuration\n * @returns The current OAuth callback configuration\n */\n getOAuthCallbackConfig(): MCPClientOAuthCallbackConfig | undefined {\n return this._oauthCallbackConfig;\n }\n\n /**\n * @returns namespaced list of tools\n */\n listTools(): NamespacedData[\"tools\"] {\n return getNamespacedData(this.mcpConnections, \"tools\");\n }\n\n /**\n * @returns a set of tools that you can use with the AI SDK\n */\n getAITools(): ToolSet {\n return Object.fromEntries(\n getNamespacedData(this.mcpConnections, \"tools\").map((tool) => {\n return [\n `tool_${tool.serverId.replace(/-/g, \"\")}_${tool.name}`,\n {\n description: tool.description,\n execute: async (args) => {\n const result = await this.callTool({\n arguments: args,\n name: tool.name,\n serverId: tool.serverId\n });\n if (result.isError) {\n // @ts-expect-error TODO we should fix this\n throw new Error(result.content[0].text);\n }\n return result;\n },\n inputSchema: getJsonSchema()!(tool.inputSchema as JSONSchema7),\n outputSchema: tool.outputSchema\n ? getJsonSchema()!(tool.outputSchema as JSONSchema7)\n : undefined\n }\n ];\n })\n );\n }\n\n /**\n * @deprecated this has been renamed to getAITools(), and unstable_getAITools will be removed in the next major version\n * @returns a set of tools that you can use with the AI SDK\n */\n unstable_getAITools(): ToolSet {\n if (!this._didWarnAboutUnstableGetAITools) {\n this._didWarnAboutUnstableGetAITools = true;\n console.warn(\n \"unstable_getAITools is deprecated, use getAITools instead. unstable_getAITools will be removed in the next major version.\"\n );\n }\n return this.getAITools();\n }\n\n /**\n * Closes all connections to MCP servers\n */\n async closeAllConnections() {\n const ids = Object.keys(this.mcpConnections);\n await Promise.all(\n ids.map(async (id) => {\n await this.mcpConnections[id].client.close();\n })\n );\n // Dispose all per-connection subscriptions\n for (const id of ids) {\n const store = this._connectionDisposables.get(id);\n if (store) store.dispose();\n this._connectionDisposables.delete(id);\n delete this.mcpConnections[id];\n }\n }\n\n /**\n * Closes a connection to an MCP server\n * @param id The id of the connection to close\n */\n async closeConnection(id: string) {\n if (!this.mcpConnections[id]) {\n throw new Error(`Connection with id \"${id}\" does not exist.`);\n }\n await this.mcpConnections[id].client.close();\n delete this.mcpConnections[id];\n\n const store = this._connectionDisposables.get(id);\n if (store) store.dispose();\n this._connectionDisposables.delete(id);\n }\n\n /**\n * Dispose the manager and all resources.\n */\n async dispose(): Promise<void> {\n try {\n await this.closeAllConnections();\n } finally {\n // Dispose manager-level emitters\n this._onConnected.dispose();\n this._onObservabilityEvent.dispose();\n }\n }\n\n /**\n * @returns namespaced list of prompts\n */\n listPrompts(): NamespacedData[\"prompts\"] {\n return getNamespacedData(this.mcpConnections, \"prompts\");\n }\n\n /**\n * @returns namespaced list of tools\n */\n listResources(): NamespacedData[\"resources\"] {\n return getNamespacedData(this.mcpConnections, \"resources\");\n }\n\n /**\n * @returns namespaced list of resource templates\n */\n listResourceTemplates(): NamespacedData[\"resourceTemplates\"] {\n return getNamespacedData(this.mcpConnections, \"resourceTemplates\");\n }\n\n /**\n * Namespaced version of callTool\n */\n async callTool(\n params: CallToolRequest[\"params\"] & { serverId: string },\n resultSchema?:\n | typeof CallToolResultSchema\n | typeof CompatibilityCallToolResultSchema,\n options?: RequestOptions\n ) {\n const unqualifiedName = params.name.replace(`${params.serverId}.`, \"\");\n return this.mcpConnections[params.serverId].client.callTool(\n {\n ...params,\n name: unqualifiedName\n },\n resultSchema,\n options\n );\n }\n\n /**\n * Namespaced version of readResource\n */\n readResource(\n params: ReadResourceRequest[\"params\"] & { serverId: string },\n options: RequestOptions\n ) {\n return this.mcpConnections[params.serverId].client.readResource(\n params,\n options\n );\n }\n\n /**\n * Namespaced version of getPrompt\n */\n getPrompt(\n params: GetPromptRequest[\"params\"] & { serverId: string },\n options: RequestOptions\n ) {\n return this.mcpConnections[params.serverId].client.getPrompt(\n params,\n options\n );\n }\n}\n\ntype NamespacedData = {\n tools: (Tool & { serverId: string })[];\n prompts: (Prompt & { serverId: string })[];\n resources: (Resource & { serverId: string })[];\n resourceTemplates: (ResourceTemplate & { serverId: string })[];\n};\n\nexport function getNamespacedData<T extends keyof NamespacedData>(\n mcpClients: Record<string, MCPClientConnection>,\n type: T\n): NamespacedData[T] {\n const sets = Object.entries(mcpClients).map(([name, conn]) => {\n return { data: conn[type], name };\n });\n\n const namespacedData = sets.flatMap(({ name: serverId, data }) => {\n return data.map((item) => {\n return {\n ...item,\n // we add a serverId so we can easily pull it out and send the tool call to the right server\n serverId\n };\n });\n });\n\n return namespacedData as NamespacedData[T]; // Type assertion needed due to TS limitations with conditional return types\n}\n","export interface Disposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): Disposable {\n return { dispose: fn };\n}\n\nexport class DisposableStore implements Disposable {\n private readonly _items: Disposable[] = [];\n\n add<T extends Disposable>(d: T): T {\n this._items.push(d);\n return d;\n }\n\n dispose(): void {\n while (this._items.length) {\n try {\n this._items.pop()!.dispose();\n } catch {\n // best-effort cleanup\n }\n }\n }\n}\n\nexport type Event<T> = (listener: (e: T) => void) => Disposable;\n\nexport class Emitter<T> implements Disposable {\n private _listeners: Set<(e: T) => void> = new Set();\n\n readonly event: Event<T> = (listener) => {\n this._listeners.add(listener);\n return toDisposable(() => this._listeners.delete(listener));\n };\n\n fire(data: T): void {\n for (const listener of [...this._listeners]) {\n try {\n listener(data);\n } catch (err) {\n // do not let one bad listener break others\n console.error(\"Emitter listener error:\", err);\n }\n }\n }\n\n dispose(): void {\n this._listeners.clear();\n }\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { SSEClientTransportOptions } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport type { StreamableHTTPClientTransportOptions } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\n// Import types directly from MCP SDK\nimport type {\n Prompt,\n Resource,\n Tool\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n type ClientCapabilities,\n type ElicitRequest,\n ElicitRequestSchema,\n type ElicitResult,\n type ListPromptsResult,\n type ListResourceTemplatesResult,\n type ListResourcesResult,\n type ListToolsResult,\n PromptListChangedNotificationSchema,\n ResourceListChangedNotificationSchema,\n type ResourceTemplate,\n type ServerCapabilities,\n ToolListChangedNotificationSchema\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { nanoid } from \"nanoid\";\nimport { Emitter, type Event } from \"../core/events\";\nimport type { MCPObservabilityEvent } from \"../observability/mcp\";\nimport type { AgentsOAuthProvider } from \"./do-oauth-client-provider\";\nimport {\n isTransportNotImplemented,\n isUnauthorized,\n toErrorMessage\n} from \"./errors\";\nimport { SSEEdgeClientTransport } from \"./sse-edge\";\nimport { StreamableHTTPEdgeClientTransport } from \"./streamable-http-edge\";\nimport type { BaseTransportType, TransportType } from \"./types\";\n\n/**\n * Connection state for MCP client connections\n */\nexport type MCPConnectionState =\n | \"authenticating\"\n | \"connecting\"\n | \"ready\"\n | \"discovering\"\n | \"failed\";\n\nexport type MCPTransportOptions = (\n | SSEClientTransportOptions\n | StreamableHTTPClientTransportOptions\n) & {\n authProvider?: AgentsOAuthProvider;\n type?: TransportType;\n};\n\nexport class MCPClientConnection {\n client: Client;\n connectionState: MCPConnectionState = \"connecting\";\n lastConnectedTransport: BaseTransportType | undefined;\n instructions?: string;\n tools: Tool[] = [];\n prompts: Prompt[] = [];\n resources: Resource[] = [];\n resourceTemplates: ResourceTemplate[] = [];\n serverCapabilities: ServerCapabilities | undefined;\n\n private readonly _onObservabilityEvent = new Emitter<MCPObservabilityEvent>();\n public readonly onObservabilityEvent: Event<MCPObservabilityEvent> =\n this._onObservabilityEvent.event;\n\n constructor(\n public url: URL,\n info: ConstructorParameters<typeof Client>[0],\n public options: {\n transport: MCPTransportOptions;\n client: ConstructorParameters<typeof Client>[1];\n } = { client: {}, transport: {} }\n ) {\n const clientOptions = {\n ...options.client,\n capabilities: {\n ...options.client?.capabilities,\n elicitation: {}\n } as ClientCapabilities\n };\n\n this.client = new Client(info, clientOptions);\n }\n\n /**\n * Initialize a client connection\n *\n * @returns\n */\n async init() {\n const transportType = this.options.transport.type;\n if (!transportType) {\n throw new Error(\"Transport type must be specified\");\n }\n\n try {\n await this.tryConnect(transportType);\n } catch (e) {\n if (isUnauthorized(e)) {\n // unauthorized, we should wait for the user to authenticate\n this.connectionState = \"authenticating\";\n return;\n }\n // For explicit transport mismatches or other errors, mark as failed\n // and do not throw to avoid bubbling errors to the client runtime.\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Connection initialization failed for ${this.url.toString()}`,\n payload: {\n url: this.url.toString(),\n transport: transportType,\n state: this.connectionState,\n error: toErrorMessage(e)\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n this.connectionState = \"failed\";\n return;\n }\n\n await this.discoverAndRegister();\n }\n\n /**\n * Finish OAuth by probing transports based on configured type.\n * - Explicit: finish on that transport\n * - Auto: try streamable-http, then sse on 404/405/Not Implemented\n */\n private async finishAuthProbe(code: string): Promise<void> {\n if (!this.options.transport.authProvider) {\n throw new Error(\"No auth provider configured\");\n }\n\n const configuredType = this.options.transport.type;\n if (!configuredType) {\n throw new Error(\"Transport type must be specified\");\n }\n\n const finishAuth = async (base: BaseTransportType) => {\n const transport = this.getTransport(base);\n await transport.finishAuth(code);\n };\n\n if (configuredType === \"sse\" || configuredType === \"streamable-http\") {\n await finishAuth(configuredType);\n return;\n }\n\n // For \"auto\" mode, try streamable-http first, then fall back to SSE\n try {\n await finishAuth(\"streamable-http\");\n } catch (e) {\n if (isTransportNotImplemented(e)) {\n await finishAuth(\"sse\");\n return;\n }\n throw e;\n }\n }\n\n /**\n * Complete OAuth authorization\n */\n async completeAuthorization(code: string): Promise<void> {\n if (this.connectionState !== \"authenticating\") {\n throw new Error(\n \"Connection must be in authenticating state to complete authorization\"\n );\n }\n\n try {\n // Finish OAuth by probing transports per configuration\n await this.finishAuthProbe(code);\n\n // Mark as connecting\n this.connectionState = \"connecting\";\n } catch (error) {\n this.connectionState = \"failed\";\n throw error;\n }\n }\n\n /**\n * Establish connection after successful authorization\n */\n async establishConnection(): Promise<void> {\n if (this.connectionState !== \"connecting\") {\n throw new Error(\n \"Connection must be in connecting state to establish connection\"\n );\n }\n\n try {\n const transportType = this.options.transport.type;\n if (!transportType) {\n throw new Error(\"Transport type must be specified\");\n }\n await this.tryConnect(transportType);\n\n await this.discoverAndRegister();\n } catch (error) {\n this.connectionState = \"failed\";\n throw error;\n }\n }\n\n /**\n * Discover server capabilities and register tools, resources, prompts, and templates\n */\n private async discoverAndRegister(): Promise<void> {\n this.connectionState = \"discovering\";\n\n this.serverCapabilities = this.client.getServerCapabilities();\n if (!this.serverCapabilities) {\n throw new Error(\"The MCP Server failed to return server capabilities\");\n }\n\n const [\n instructionsResult,\n toolsResult,\n resourcesResult,\n promptsResult,\n resourceTemplatesResult\n ] = await Promise.allSettled([\n this.client.getInstructions(),\n this.registerTools(),\n this.registerResources(),\n this.registerPrompts(),\n this.registerResourceTemplates()\n ]);\n\n const operations = [\n { name: \"instructions\", result: instructionsResult },\n { name: \"tools\", result: toolsResult },\n { name: \"resources\", result: resourcesResult },\n { name: \"prompts\", result: promptsResult },\n { name: \"resource templates\", result: resourceTemplatesResult }\n ];\n\n for (const { name, result } of operations) {\n if (result.status === \"rejected\") {\n const url = this.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:discover\",\n displayMessage: `Failed to discover ${name} for ${url}`,\n payload: {\n url,\n capability: name,\n error: result.reason\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n }\n }\n\n this.instructions =\n instructionsResult.status === \"fulfilled\"\n ? instructionsResult.value\n : undefined;\n this.tools = toolsResult.status === \"fulfilled\" ? toolsResult.value : [];\n this.resources =\n resourcesResult.status === \"fulfilled\" ? resourcesResult.value : [];\n this.prompts =\n promptsResult.status === \"fulfilled\" ? promptsResult.value : [];\n this.resourceTemplates =\n resourceTemplatesResult.status === \"fulfilled\"\n ? resourceTemplatesResult.value\n : [];\n\n this.connectionState = \"ready\";\n }\n\n /**\n * Notification handler registration\n */\n async registerTools(): Promise<Tool[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.tools) {\n return [];\n }\n\n if (this.serverCapabilities.tools.listChanged) {\n this.client.setNotificationHandler(\n ToolListChangedNotificationSchema,\n async (_notification) => {\n this.tools = await this.fetchTools();\n }\n );\n }\n\n return this.fetchTools();\n }\n\n async registerResources(): Promise<Resource[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.resources) {\n return [];\n }\n\n if (this.serverCapabilities.resources.listChanged) {\n this.client.setNotificationHandler(\n ResourceListChangedNotificationSchema,\n async (_notification) => {\n this.resources = await this.fetchResources();\n }\n );\n }\n\n return this.fetchResources();\n }\n\n async registerPrompts(): Promise<Prompt[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.prompts) {\n return [];\n }\n\n if (this.serverCapabilities.prompts.listChanged) {\n this.client.setNotificationHandler(\n PromptListChangedNotificationSchema,\n async (_notification) => {\n this.prompts = await this.fetchPrompts();\n }\n );\n }\n\n return this.fetchPrompts();\n }\n\n async registerResourceTemplates(): Promise<ResourceTemplate[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.resources) {\n return [];\n }\n\n return this.fetchResourceTemplates();\n }\n\n async fetchTools() {\n let toolsAgg: Tool[] = [];\n let toolsResult: ListToolsResult = { tools: [] };\n do {\n toolsResult = await this.client\n .listTools({\n cursor: toolsResult.nextCursor\n })\n .catch(this._capabilityErrorHandler({ tools: [] }, \"tools/list\"));\n toolsAgg = toolsAgg.concat(toolsResult.tools);\n } while (toolsResult.nextCursor);\n return toolsAgg;\n }\n\n async fetchResources() {\n let resourcesAgg: Resource[] = [];\n let resourcesResult: ListResourcesResult = { resources: [] };\n do {\n resourcesResult = await this.client\n .listResources({\n cursor: resourcesResult.nextCursor\n })\n .catch(\n this._capabilityErrorHandler({ resources: [] }, \"resources/list\")\n );\n resourcesAgg = resourcesAgg.concat(resourcesResult.resources);\n } while (resourcesResult.nextCursor);\n return resourcesAgg;\n }\n\n async fetchPrompts() {\n let promptsAgg: Prompt[] = [];\n let promptsResult: ListPromptsResult = { prompts: [] };\n do {\n promptsResult = await this.client\n .listPrompts({\n cursor: promptsResult.nextCursor\n })\n .catch(this._capabilityErrorHandler({ prompts: [] }, \"prompts/list\"));\n promptsAgg = promptsAgg.concat(promptsResult.prompts);\n } while (promptsResult.nextCursor);\n return promptsAgg;\n }\n\n async fetchResourceTemplates() {\n let templatesAgg: ResourceTemplate[] = [];\n let templatesResult: ListResourceTemplatesResult = {\n resourceTemplates: []\n };\n do {\n templatesResult = await this.client\n .listResourceTemplates({\n cursor: templatesResult.nextCursor\n })\n .catch(\n this._capabilityErrorHandler(\n { resourceTemplates: [] },\n \"resources/templates/list\"\n )\n );\n templatesAgg = templatesAgg.concat(templatesResult.resourceTemplates);\n } while (templatesResult.nextCursor);\n return templatesAgg;\n }\n\n /**\n * Handle elicitation request from server\n * Automatically uses the Agent's built-in elicitation handling if available\n */\n async handleElicitationRequest(\n _request: ElicitRequest\n ): Promise<ElicitResult> {\n // Elicitation handling must be implemented by the platform\n // For MCP servers, this should be handled by McpAgent.elicitInput()\n throw new Error(\n \"Elicitation handler must be implemented for your platform. Override handleElicitationRequest method.\"\n );\n }\n /**\n * Get the transport for the client\n * @param transportType - The transport type to get\n * @returns The transport for the client\n */\n getTransport(transportType: BaseTransportType) {\n switch (transportType) {\n case \"streamable-http\":\n return new StreamableHTTPEdgeClientTransport(\n this.url,\n this.options.transport as StreamableHTTPClientTransportOptions\n );\n case \"sse\":\n return new SSEEdgeClientTransport(\n this.url,\n this.options.transport as SSEClientTransportOptions\n );\n default:\n throw new Error(`Unsupported transport type: ${transportType}`);\n }\n }\n\n private async tryConnect(transportType: TransportType) {\n const transports: BaseTransportType[] =\n transportType === \"auto\" ? [\"streamable-http\", \"sse\"] : [transportType];\n\n for (const currentTransportType of transports) {\n const isLastTransport =\n currentTransportType === transports[transports.length - 1];\n const hasFallback =\n transportType === \"auto\" &&\n currentTransportType === \"streamable-http\" &&\n !isLastTransport;\n\n const transport = this.getTransport(currentTransportType);\n\n try {\n await this.client.connect(transport);\n this.lastConnectedTransport = currentTransportType;\n const url = this.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Connected successfully using ${currentTransportType} transport for ${url}`,\n payload: {\n url,\n transport: currentTransportType,\n state: this.connectionState\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n break;\n } catch (e) {\n const error = e instanceof Error ? e : new Error(String(e));\n\n // If unauthorized, bubble up for proper auth handling\n if (isUnauthorized(error)) {\n throw e;\n }\n\n if (hasFallback && isTransportNotImplemented(error)) {\n // Try the next transport silently\n const url = this.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `${currentTransportType} transport not available, trying ${transports[transports.indexOf(currentTransportType) + 1]} for ${url}`,\n payload: {\n url,\n transport: currentTransportType,\n state: this.connectionState\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n continue;\n }\n\n throw e;\n }\n }\n\n // Set up elicitation request handler\n this.client.setRequestHandler(\n ElicitRequestSchema,\n async (request: ElicitRequest) => {\n return await this.handleElicitationRequest(request);\n }\n );\n }\n\n private _capabilityErrorHandler<T>(empty: T, method: string) {\n return (e: { code: number }) => {\n // server is badly behaved and returning invalid capabilities. This commonly occurs for resource templates\n if (e.code === -32601) {\n const url = this.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:discover\",\n displayMessage: `The server advertised support for the capability ${method.split(\"/\")[0]}, but returned \"Method not found\" for '${method}' for ${url}`,\n payload: {\n url,\n capability: method.split(\"/\")[0],\n error: toErrorMessage(e)\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n return empty;\n }\n throw e;\n };\n }\n}\n","export function toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function isUnauthorized(error: unknown): boolean {\n const msg = toErrorMessage(error);\n return msg.includes(\"Unauthorized\") || msg.includes(\"401\");\n}\n\nexport function isTransportNotImplemented(error: unknown): boolean {\n const msg = toErrorMessage(error);\n // Treat common \"not implemented\" surfaces as transport not supported\n return (\n msg.includes(\"404\") ||\n msg.includes(\"405\") ||\n msg.includes(\"Not Implemented\") ||\n msg.includes(\"not implemented\")\n );\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport {\n SSEClientTransport,\n type SSEClientTransportOptions\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\n\nexport class SSEEdgeClientTransport extends SSEClientTransport {\n private authProvider: OAuthClientProvider | undefined;\n /**\n * Creates a new EdgeSSEClientTransport, which overrides fetch to be compatible with the CF workers environment\n */\n constructor(url: URL, options: SSEClientTransportOptions) {\n const fetchOverride: typeof fetch = async (\n fetchUrl: RequestInfo | URL,\n fetchInit: RequestInit = {}\n ) => {\n // add auth headers\n const headers = await this.authHeaders();\n const workerOptions = {\n ...fetchInit,\n headers: {\n ...options.requestInit?.headers,\n ...fetchInit?.headers,\n ...headers\n }\n };\n\n // Remove unsupported properties\n delete workerOptions.mode;\n\n // Call the original fetch with fixed options\n return (\n (options.eventSourceInit?.fetch?.(\n fetchUrl as URL | string,\n // @ts-expect-error Expects FetchLikeInit from EventSource but is compatible with RequestInit\n workerOptions\n ) as Promise<Response>) || fetch(fetchUrl, workerOptions)\n );\n };\n\n super(url, {\n ...options,\n eventSourceInit: {\n ...options.eventSourceInit,\n fetch: fetchOverride\n }\n });\n this.authProvider = options.authProvider;\n }\n\n async authHeaders() {\n if (this.authProvider) {\n const tokens = await this.authProvider.tokens();\n if (tokens) {\n return {\n Authorization: `Bearer ${tokens.access_token}`\n };\n }\n }\n }\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport {\n StreamableHTTPClientTransport,\n type StreamableHTTPClientTransportOptions\n} from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\n\nexport class StreamableHTTPEdgeClientTransport extends StreamableHTTPClientTransport {\n private authProvider: OAuthClientProvider | undefined;\n\n /**\n * Creates a new StreamableHTTPEdgeClientTransport, which overrides fetch to be compatible with the CF workers environment\n */\n constructor(url: URL, options: StreamableHTTPClientTransportOptions) {\n const fetchOverride: typeof fetch = async (\n fetchUrl: RequestInfo | URL,\n fetchInit: RequestInit = {}\n ) => {\n // add auth headers\n const headers = await this.authHeaders();\n const workerOptions = {\n ...fetchInit,\n headers: {\n ...options.requestInit?.headers,\n ...fetchInit?.headers,\n ...headers\n }\n };\n\n // Remove unsupported properties\n delete workerOptions.mode;\n\n // Call the original fetch with fixed options\n return (\n // @ts-expect-error Custom fetch function for Cloudflare Workers compatibility\n (options.requestInit?.fetch?.(\n fetchUrl as URL | string,\n workerOptions\n ) as Promise<Response>) || fetch(fetchUrl, workerOptions)\n );\n };\n\n super(url, {\n ...options,\n requestInit: {\n ...options.requestInit,\n // @ts-expect-error Custom fetch override for Cloudflare Workers\n fetch: fetchOverride\n }\n });\n this.authProvider = options.authProvider;\n }\n\n async authHeaders() {\n if (this.authProvider) {\n const tokens = await this.authProvider.tokens();\n if (tokens) {\n return {\n Authorization: `Bearer ${tokens.access_token}`\n };\n }\n }\n }\n}\n"],"mappings":"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","names":["nanoid","nanoid","url"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  getAgentByName
3
- } from "../chunk-XGMKNUJA.js";
4
- import "../chunk-ZMMHNOMZ.js";
3
+ } from "../chunk-2Y6KNRNP.js";
4
+ import "../chunk-QUOGV3WN.js";
5
5
  import "../chunk-C2OEBJZ2.js";
6
6
  import "../chunk-QEVM4BVL.js";
7
7
  import "../chunk-BER7KXUJ.js";
package/dist/index.js CHANGED
@@ -10,8 +10,8 @@ import {
10
10
  routeAgentEmail,
11
11
  routeAgentRequest,
12
12
  unstable_callable
13
- } from "./chunk-XGMKNUJA.js";
14
- import "./chunk-ZMMHNOMZ.js";
13
+ } from "./chunk-2Y6KNRNP.js";
14
+ import "./chunk-QUOGV3WN.js";
15
15
  import "./chunk-C2OEBJZ2.js";
16
16
  import "./chunk-QEVM4BVL.js";
17
17
  import "./chunk-BER7KXUJ.js";
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  MCPClientManager,
3
3
  getNamespacedData
4
- } from "../chunk-ZMMHNOMZ.js";
4
+ } from "../chunk-QUOGV3WN.js";
5
5
  import "../chunk-PR4QN5HX.js";
6
6
  export {
7
7
  MCPClientManager,
package/dist/mcp/index.js CHANGED
@@ -2,11 +2,11 @@ import {
2
2
  Agent,
3
3
  getAgentByName,
4
4
  getCurrentAgent
5
- } from "../chunk-XGMKNUJA.js";
5
+ } from "../chunk-2Y6KNRNP.js";
6
6
  import {
7
7
  SSEEdgeClientTransport,
8
8
  StreamableHTTPEdgeClientTransport
9
- } from "../chunk-ZMMHNOMZ.js";
9
+ } from "../chunk-QUOGV3WN.js";
10
10
  import "../chunk-C2OEBJZ2.js";
11
11
  import "../chunk-QEVM4BVL.js";
12
12
  import "../chunk-BER7KXUJ.js";
@@ -179,7 +179,9 @@ var createStreamingHttpHandler = (basePath, namespace, corsOptions) => {
179
179
  headers: {
180
180
  ...existingHeaders,
181
181
  [MCP_HTTP_METHOD_HEADER]: "POST",
182
- [MCP_MESSAGE_HEADER]: JSON.stringify(messages),
182
+ [MCP_MESSAGE_HEADER]: Buffer.from(
183
+ JSON.stringify(messages)
184
+ ).toString("base64"),
183
185
  Upgrade: "websocket"
184
186
  }
185
187
  });
@@ -896,7 +898,21 @@ var McpAgent = class _McpAgent extends Agent {
896
898
  switch (req.headers.get(MCP_HTTP_METHOD_HEADER)) {
897
899
  case "POST": {
898
900
  const payloadHeader = req.headers.get(MCP_MESSAGE_HEADER);
899
- const parsedBody = await JSON.parse(payloadHeader ?? "{}");
901
+ let rawPayload;
902
+ if (!payloadHeader) {
903
+ rawPayload = "{}";
904
+ } else {
905
+ try {
906
+ rawPayload = Buffer.from(payloadHeader, "base64").toString(
907
+ "utf-8"
908
+ );
909
+ } catch (_error) {
910
+ throw new Error(
911
+ "Internal Server Error: Failed to decode MCP message header"
912
+ );
913
+ }
914
+ }
915
+ const parsedBody = JSON.parse(rawPayload);
900
916
  this._transport?.handlePostRequest(req, parsedBody);
901
917
  break;
902
918
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/index.ts","../../src/mcp/utils.ts","../../src/mcp/transport.ts"],"sourcesContent":["import type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n JSONRPCMessageSchema,\n isJSONRPCError,\n isJSONRPCResponse,\n type ElicitResult\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Connection, ConnectionContext } from \"../\";\nimport { Agent } from \"../index\";\nimport type { BaseTransportType, MaybePromise, ServeOptions } from \"./types\";\nimport {\n createLegacySseHandler,\n createStreamingHttpHandler,\n handleCORS,\n isDurableObjectNamespace,\n MCP_HTTP_METHOD_HEADER,\n MCP_MESSAGE_HEADER\n} from \"./utils\";\nimport { McpSSETransport, StreamableHTTPServerTransport } from \"./transport\";\n\nexport abstract class McpAgent<\n Env = unknown,\n State = unknown,\n Props extends Record<string, unknown> = Record<string, unknown>\n> extends Agent<Env, State, Props> {\n private _transport?: Transport;\n props?: Props;\n\n abstract server: MaybePromise<McpServer | Server>;\n abstract init(): Promise<void>;\n\n /*\n * Helpers\n */\n\n async setInitializeRequest(initializeRequest: JSONRPCMessage) {\n await this.ctx.storage.put(\"initializeRequest\", initializeRequest);\n }\n\n async getInitializeRequest() {\n return this.ctx.storage.get<JSONRPCMessage>(\"initializeRequest\");\n }\n\n /** Read the transport type for this agent.\n * This relies on the naming scheme being `sse:${sessionId}`\n * or `streamable-http:${sessionId}`.\n */\n getTransportType(): BaseTransportType {\n const [t, ..._] = this.name.split(\":\");\n switch (t) {\n case \"sse\":\n return \"sse\";\n case \"streamable-http\":\n return \"streamable-http\";\n default:\n throw new Error(\n \"Invalid transport type. McpAgent must be addressed with a valid protocol.\"\n );\n }\n }\n\n /** Read the sessionId for this agent.\n * This relies on the naming scheme being `sse:${sessionId}`\n * or `streamable-http:${sessionId}`.\n */\n getSessionId(): string {\n const [_, sessionId] = this.name.split(\":\");\n if (!sessionId) {\n throw new Error(\n \"Invalid session id. McpAgent must be addressed with a valid session id.\"\n );\n }\n return sessionId;\n }\n\n /** Get the unique WebSocket. SSE transport only. */\n private getWebSocket() {\n const websockets = Array.from(this.getConnections());\n if (websockets.length === 0) {\n return null;\n }\n return websockets[0];\n }\n\n /** Returns a new transport matching the type of the Agent. */\n private initTransport() {\n switch (this.getTransportType()) {\n case \"sse\": {\n return new McpSSETransport(() => this.getWebSocket());\n }\n case \"streamable-http\": {\n return new StreamableHTTPServerTransport({});\n }\n }\n }\n\n /** Update and store the props */\n async updateProps(props?: Props) {\n await this.ctx.storage.put(\"props\", props ?? {});\n this.props = props;\n }\n\n async reinitializeServer() {\n // If the agent was previously initialized, we have to populate\n // the server again by sending the initialize request to make\n // client information available to the server.\n const initializeRequest = await this.getInitializeRequest();\n if (initializeRequest) {\n this._transport?.onmessage?.(initializeRequest);\n }\n }\n\n /*\n * Base Agent / Parykit Server overrides\n */\n\n /** Sets up the MCP transport and server every time the Agent is started.*/\n async onStart(props?: Props) {\n // If onStart was passed props, save them in storage\n if (props) await this.updateProps(props);\n this.props = await this.ctx.storage.get(\"props\");\n\n await this.init();\n const server = await this.server;\n // Connect to the MCP server\n this._transport = this.initTransport();\n await server.connect(this._transport);\n await this.reinitializeServer();\n }\n\n /** Validates new WebSocket connections. */\n async onConnect(\n conn: Connection,\n { request: req }: ConnectionContext\n ): Promise<void> {\n switch (this.getTransportType()) {\n case \"sse\": {\n // For SSE connections, we can only have one open connection per session\n // If we get an upgrade while already connected, we should error\n const websockets = Array.from(this.getConnections());\n if (websockets.length > 1) {\n conn.close(1008, \"Websocket already connected\");\n return;\n }\n break;\n }\n case \"streamable-http\":\n if (this._transport instanceof StreamableHTTPServerTransport) {\n switch (req.headers.get(MCP_HTTP_METHOD_HEADER)) {\n case \"POST\": {\n // This returns the repsonse directly to the client\n const payloadHeader = req.headers.get(MCP_MESSAGE_HEADER);\n const parsedBody = await JSON.parse(payloadHeader ?? \"{}\");\n this._transport?.handlePostRequest(req, parsedBody);\n break;\n }\n case \"GET\":\n this._transport?.handleGetRequest(req);\n break;\n }\n }\n }\n }\n\n /*\n * Transport ingress and routing\n */\n\n /** Handles MCP Messages for the legacy SSE transport. */\n async onSSEMcpMessage(\n _sessionId: string,\n messageBody: unknown\n ): Promise<Error | null> {\n // Since we address the DO via both the protocol and the session id,\n // this should never happen, but let's enforce it just in case\n if (this.getTransportType() !== \"sse\") {\n return new Error(\"Internal Server Error: Expected SSE transport\");\n }\n\n try {\n let parsedMessage: JSONRPCMessage;\n try {\n parsedMessage = JSONRPCMessageSchema.parse(messageBody);\n } catch (error) {\n this._transport?.onerror?.(error as Error);\n throw error;\n }\n\n // Check if this is an elicitation response before passing to transport\n if (await this._handleElicitationResponse(parsedMessage)) {\n return null; // Message was handled by elicitation system\n }\n\n this._transport?.onmessage?.(parsedMessage);\n return null;\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n this._transport?.onerror?.(error as Error);\n return error as Error;\n }\n }\n\n /** Elicit user input with a message and schema */\n async elicitInput(params: {\n message: string;\n requestedSchema: unknown;\n }): Promise<ElicitResult> {\n const requestId = `elicit_${Math.random().toString(36).substring(2, 11)}`;\n\n // Store pending request in durable storage\n await this.ctx.storage.put(`elicitation:${requestId}`, {\n message: params.message,\n requestedSchema: params.requestedSchema,\n timestamp: Date.now()\n });\n\n const elicitRequest = {\n jsonrpc: \"2.0\" as const,\n id: requestId,\n method: \"elicitation/create\",\n params: {\n message: params.message,\n requestedSchema: params.requestedSchema\n }\n };\n\n // Send through MCP transport\n if (this._transport) {\n await this._transport.send(elicitRequest);\n } else {\n const connections = this.getConnections();\n if (!connections || Array.from(connections).length === 0) {\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n throw new Error(\"No active connections available for elicitation\");\n }\n\n const connectionList = Array.from(connections);\n for (const connection of connectionList) {\n try {\n connection.send(JSON.stringify(elicitRequest));\n } catch (error) {\n console.error(\"Failed to send elicitation request:\", error);\n }\n }\n }\n\n // Wait for response through MCP\n return this._waitForElicitationResponse(requestId);\n }\n\n /** Wait for elicitation response through storage polling */\n private async _waitForElicitationResponse(\n requestId: string\n ): Promise<ElicitResult> {\n const startTime = Date.now();\n const timeout = 60000; // 60 second timeout\n\n try {\n while (Date.now() - startTime < timeout) {\n // Check if response has been stored\n const response = await this.ctx.storage.get<ElicitResult>(\n `elicitation:response:${requestId}`\n );\n if (response) {\n // Immediately clean up both request and response\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n await this.ctx.storage.delete(`elicitation:response:${requestId}`);\n return response;\n }\n\n // Sleep briefly before checking again\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n throw new Error(\"Elicitation request timed out\");\n } finally {\n // Always clean up on timeout or error\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n await this.ctx.storage.delete(`elicitation:response:${requestId}`);\n }\n }\n\n /** Handle elicitation responses */\n private async _handleElicitationResponse(\n message: JSONRPCMessage\n ): Promise<boolean> {\n // Check if this is a response to an elicitation request\n if (isJSONRPCResponse(message) && message.result) {\n const requestId = message.id?.toString();\n if (!requestId || !requestId.startsWith(\"elicit_\")) return false;\n\n // Check if we have a pending request for this ID\n const pendingRequest = await this.ctx.storage.get(\n `elicitation:${requestId}`\n );\n if (!pendingRequest) return false;\n\n // Store the response in durable storage\n await this.ctx.storage.put(\n `elicitation:response:${requestId}`,\n message.result as ElicitResult\n );\n return true;\n }\n\n // Check if this is an error response to an elicitation request\n if (isJSONRPCError(message)) {\n const requestId = message.id?.toString();\n if (!requestId || !requestId.startsWith(\"elicit_\")) return false;\n\n // Check if we have a pending request for this ID\n const pendingRequest = await this.ctx.storage.get(\n `elicitation:${requestId}`\n );\n if (!pendingRequest) return false;\n\n // Store error response\n const errorResult: ElicitResult = {\n action: \"cancel\",\n content: {\n error: message.error.message || \"Elicitation request failed\"\n }\n };\n await this.ctx.storage.put(\n `elicitation:response:${requestId}`,\n errorResult\n );\n return true;\n }\n\n return false;\n }\n\n /** Return a handler for the given path for this MCP.\n * Defaults to Streamable HTTP transport.\n */\n static serve(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n transport = \"streamable-http\"\n }: ServeOptions = {}\n ) {\n return {\n async fetch<Env>(\n this: void,\n request: Request,\n env: Env,\n ctx: ExecutionContext\n ): Promise<Response> {\n // Handle CORS preflight\n const corsResponse = handleCORS(request, corsOptions);\n if (corsResponse) {\n return corsResponse;\n }\n\n const bindingValue = env[binding as keyof typeof env] as unknown;\n\n // Ensure we have a binding of some sort\n if (bindingValue == null || typeof bindingValue !== \"object\") {\n throw new Error(\n `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`\n );\n }\n\n // Ensure that the binding is to a DurableObject\n if (!isDurableObjectNamespace(bindingValue)) {\n throw new Error(\n `Invalid McpAgent binding for ${binding}. Make sure it's a Durable Object binding.`\n );\n }\n\n const namespace =\n bindingValue satisfies DurableObjectNamespace<McpAgent>;\n\n switch (transport) {\n case \"streamable-http\": {\n // Streamable HTTP transport handling\n const handleStreamableHttp = createStreamingHttpHandler(\n path,\n namespace,\n corsOptions\n );\n return handleStreamableHttp(request, ctx);\n }\n case \"sse\": {\n // Legacy SSE transport handling\n const handleLegacySse = createLegacySseHandler(\n path,\n namespace,\n corsOptions\n );\n return handleLegacySse(request, ctx);\n }\n default:\n return new Response(\n \"Invalid MCP transport mode. Only `streamable-http` or `sse` are allowed.\",\n { status: 500 }\n );\n }\n }\n };\n }\n /**\n * Legacy api\n **/\n static mount(path: string, opts: Omit<ServeOptions, \"transport\"> = {}) {\n return McpAgent.serveSSE(path, opts);\n }\n\n static serveSSE(path: string, opts: Omit<ServeOptions, \"transport\"> = {}) {\n return McpAgent.serve(path, { ...opts, transport: \"sse\" });\n }\n}\n\n// Export client transport classes\nexport { SSEEdgeClientTransport } from \"./sse-edge\";\nexport { StreamableHTTPEdgeClientTransport } from \"./streamable-http-edge\";\n\n// Export elicitation types and schemas\nexport {\n ElicitRequestSchema,\n type ElicitRequest,\n type ElicitResult\n} from \"@modelcontextprotocol/sdk/types.js\";\n\n// Export OAuth-related types\nexport type {\n MCPClientOAuthResult,\n MCPClientOAuthCallbackConfig\n} from \"./client\";\n","import {\n JSONRPCMessageSchema,\n type JSONRPCMessage,\n InitializeRequestSchema,\n isJSONRPCResponse,\n isJSONRPCNotification\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpAgent } from \".\";\nimport { getAgentByName } from \"..\";\nimport type { CORSOptions } from \"./types\";\nimport { MessageType } from \"../ai-types\";\n\n/**\n * Since we use WebSockets to bridge the client to the\n * MCP transport in the Agent, we use this header to signal\n * the method of the original request the user made, while\n * leaving the WS Upgrade request as GET.\n */\nexport const MCP_HTTP_METHOD_HEADER = \"cf-mcp-method\";\n\n/**\n * Since we use WebSockets to bridge the client to the\n * MCP transport in the Agent, we use this header to include\n * the original request body.\n */\nexport const MCP_MESSAGE_HEADER = \"cf-mcp-message\";\n\nconst MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024; // 4MB\n\nexport const createStreamingHttpHandler = (\n basePath: string,\n namespace: DurableObjectNamespace<McpAgent>,\n corsOptions?: CORSOptions\n) => {\n let pathname = basePath;\n if (basePath === \"/\") pathname = \"/*\";\n\n const basePattern = new URLPattern({ pathname });\n return async (request: Request, ctx: ExecutionContext) => {\n const url = new URL(request.url);\n if (basePattern.test(url)) {\n if (request.method === \"POST\") {\n // Validate the Accept header\n const acceptHeader = request.headers.get(\"accept\");\n // The client MUST include an Accept header, listing both application/json and text/event-stream as supported content types.\n if (\n !acceptHeader?.includes(\"application/json\") ||\n !acceptHeader.includes(\"text/event-stream\")\n ) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message:\n \"Not Acceptable: Client must accept both application/json and text/event-stream\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 406 });\n }\n\n const ct = request.headers.get(\"content-type\");\n if (!ct || !ct.includes(\"application/json\")) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message:\n \"Unsupported Media Type: Content-Type must be application/json\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 415 });\n }\n\n // Check content length against maximum allowed size\n const contentLength = Number.parseInt(\n request.headers.get(\"content-length\") ?? \"0\",\n 10\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 413 });\n }\n\n let sessionId = request.headers.get(\"mcp-session-id\");\n let rawMessage: unknown;\n\n try {\n rawMessage = await request.json();\n } catch (_error) {\n const body = JSON.stringify({\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n\n // Make sure the message is an array to simplify logic\n let arrayMessage: unknown[];\n if (Array.isArray(rawMessage)) {\n arrayMessage = rawMessage;\n } else {\n arrayMessage = [rawMessage];\n }\n\n let messages: JSONRPCMessage[] = [];\n\n // Try to parse each message as JSON RPC. Fail if any message is invalid\n for (const msg of arrayMessage) {\n if (!JSONRPCMessageSchema.safeParse(msg).success) {\n const body = JSON.stringify({\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON-RPC message\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n }\n\n messages = arrayMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n\n // Before we pass the messages to the agent, there's another error condition we need to enforce\n // Check if this is an initialization request\n // https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/lifecycle/\n const maybeInitializeRequest = messages.find(\n (msg) => InitializeRequestSchema.safeParse(msg).success\n );\n\n if (!!maybeInitializeRequest && sessionId) {\n const body = JSON.stringify({\n error: {\n code: -32600,\n message:\n \"Invalid Request: Initialization requests must not include a sessionId\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n\n // The initialization request must be the only request in the batch\n if (!!maybeInitializeRequest && messages.length > 1) {\n const body = JSON.stringify({\n error: {\n code: -32600,\n message:\n \"Invalid Request: Only one initialization request is allowed\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n\n // If an Mcp-Session-Id is returned by the server during initialization,\n // clients using the Streamable HTTP transport MUST include it\n // in the Mcp-Session-Id header on all of their subsequent HTTP requests.\n if (!maybeInitializeRequest && !sessionId) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: \"Bad Request: Mcp-Session-Id header is required\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n\n // If we don't have a sessionId, we are serving an initialization request\n // and need to generate a new sessionId\n sessionId = sessionId ?? namespace.newUniqueId().toString();\n\n // Get the agent and set props\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`,\n { props: ctx.props as Record<string, unknown> | undefined }\n );\n const isInitialized = await agent.getInitializeRequest();\n\n if (maybeInitializeRequest) {\n await agent.setInitializeRequest(maybeInitializeRequest);\n } else if (!isInitialized) {\n // if we have gotten here, then a session id that was never initialized\n // was provided\n const body = JSON.stringify({\n error: {\n code: -32001,\n message: \"Session not found\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 404 });\n }\n\n // We've evaluated all the error conditions! Now it's time to establish\n // all the streams\n\n // Create a Transform Stream for SSE\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n // Connect to the Durable Object via WebSocket\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n const req = new Request(request.url, {\n headers: {\n ...existingHeaders,\n [MCP_HTTP_METHOD_HEADER]: \"POST\",\n [MCP_MESSAGE_HEADER]: JSON.stringify(messages),\n Upgrade: \"websocket\"\n }\n });\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(req);\n\n // Get the WebSocket\n const ws = response.webSocket;\n if (!ws) {\n console.error(\"Failed to establish WebSocket connection\");\n\n await writer.close();\n const body = JSON.stringify({\n error: {\n code: -32001,\n message: \"Failed to establish WebSocket connection\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 500 });\n }\n\n // Accept the WebSocket\n ws.accept();\n\n // Handle messages from the Durable Object\n ws.addEventListener(\"message\", (event) => {\n async function onMessage(event: MessageEvent) {\n try {\n const data =\n typeof event.data === \"string\"\n ? event.data\n : new TextDecoder().decode(event.data);\n const message = JSON.parse(data);\n\n // We only forward events from the MCP server\n if (message.type !== MessageType.CF_MCP_AGENT_EVENT) {\n return;\n }\n\n // Send the message as an SSE event\n await writer.write(encoder.encode(message.event));\n\n // If we have received all the responses, close the connection\n if (message.close) {\n ws?.close();\n await writer.close().catch(() => {});\n }\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n }\n }\n onMessage(event).catch(console.error);\n });\n\n // Handle WebSocket errors\n ws.addEventListener(\"error\", (error) => {\n async function onError(_error: Event) {\n await writer.close().catch(() => {});\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n await writer.close().catch(() => {});\n }\n onClose().catch(console.error);\n });\n\n // If there are no requests, we send the messages to the agent and acknowledge the request with a 202\n // since we don't expect any responses back through this connection\n const hasOnlyNotificationsOrResponses = messages.every(\n (msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg)\n );\n if (hasOnlyNotificationsOrResponses) {\n // closing the websocket will also close the SSE connection\n ws.close();\n\n return new Response(null, {\n headers: corsHeaders(request, corsOptions),\n status: 202\n });\n }\n\n // Return the SSE response. We handle closing the stream in the ws \"message\"\n // handler\n return new Response(readable, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n \"mcp-session-id\": sessionId,\n ...corsHeaders(request, corsOptions)\n },\n status: 200\n });\n } else if (request.method === \"GET\") {\n // Validate the Accept header\n const acceptHeader = request.headers.get(\"accept\");\n // The client MUST include an Accept header, listing both application/json and text/event-stream as supported content types.\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Not Acceptable: Client must accept text/event-stream\"\n },\n id: null\n });\n return new Response(body, { status: 406 });\n }\n\n // Require sessionId\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (!sessionId)\n return new Response(\n JSON.stringify({\n error: {\n code: -32000,\n message: \"Bad Request: Mcp-Session-Id header is required\"\n },\n id: null,\n jsonrpc: \"2.0\"\n }),\n { status: 400 }\n );\n\n // Create SSE stream\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`,\n { props: ctx.props as Record<string, unknown> | undefined }\n );\n const isInitialized = await agent.getInitializeRequest();\n if (!isInitialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32001, message: \"Session not found\" },\n id: null\n }),\n { status: 404 }\n );\n }\n\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((v, k) => {\n existingHeaders[k] = v;\n });\n\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(\n new Request(request.url, {\n headers: {\n ...existingHeaders,\n [MCP_HTTP_METHOD_HEADER]: \"GET\",\n Upgrade: \"websocket\"\n }\n })\n );\n\n const ws = response.webSocket;\n if (!ws) {\n await writer.close();\n return new Response(\"Failed to establish WS to DO\", {\n status: 500\n });\n }\n ws.accept();\n\n // Forward DO messages as SSE\n ws.addEventListener(\"message\", (event) => {\n try {\n async function onMessage(ev: MessageEvent) {\n const data =\n typeof ev.data === \"string\"\n ? ev.data\n : new TextDecoder().decode(ev.data);\n const message = JSON.parse(data);\n\n // We only forward events from the MCP server\n if (message.type !== MessageType.CF_MCP_AGENT_EVENT) {\n return;\n }\n await writer.write(encoder.encode(message.event));\n }\n onMessage(event).catch(console.error);\n } catch (e) {\n console.error(\"Error forwarding message to SSE:\", e);\n }\n });\n\n ws.addEventListener(\"error\", () => {\n writer.close().catch(() => {});\n });\n ws.addEventListener(\"close\", () => {\n writer.close().catch(() => {});\n });\n\n return new Response(readable, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n \"mcp-session-id\": sessionId,\n ...corsHeaders(request, corsOptions)\n },\n status: 200\n });\n } else if (request.method === \"DELETE\") {\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (!sessionId) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Bad Request: Mcp-Session-Id header is required\"\n },\n id: null\n }),\n { status: 400, headers: corsHeaders(request, corsOptions) }\n );\n }\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`\n );\n const isInitialized = await agent.getInitializeRequest();\n if (!isInitialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32001, message: \"Session not found\" },\n id: null\n }),\n { status: 404, headers: corsHeaders(request, corsOptions) }\n );\n }\n // .destroy() passes an uncatchable Error, so we make sure we first return\n // the response to the client.\n ctx.waitUntil(\n agent.destroy().catch(() => {\n /* This will always throw. We silently catch here */\n })\n );\n return new Response(null, {\n status: 204,\n headers: corsHeaders(request, corsOptions)\n });\n }\n }\n\n // Route not found\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: \"Not found\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 404 });\n };\n};\n\nexport const createLegacySseHandler = (\n basePath: string,\n namespace: DurableObjectNamespace<McpAgent>,\n corsOptions?: CORSOptions\n) => {\n let pathname = basePath;\n if (basePath === \"/\") pathname = \"/*\";\n\n const basePattern = new URLPattern({ pathname });\n const messagePattern = new URLPattern({ pathname: `${basePath}/message` }); // SSE only\n return async (request: Request, ctx: ExecutionContext) => {\n const url = new URL(request.url);\n // Handle initial SSE connection\n if (request.method === \"GET\" && basePattern.test(url)) {\n // Use a session ID if one is passed in, or create a unique\n // session ID for this connection\n const sessionId =\n url.searchParams.get(\"sessionId\") || namespace.newUniqueId().toString();\n\n // Create a Transform Stream for SSE\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n // Send the endpoint event\n const endpointUrl = new URL(request.url);\n endpointUrl.pathname = encodeURI(`${basePath}/message`);\n endpointUrl.searchParams.set(\"sessionId\", sessionId);\n const relativeUrlWithSession =\n endpointUrl.pathname + endpointUrl.search + endpointUrl.hash;\n const endpointMessage = `event: endpoint\\ndata: ${relativeUrlWithSession}\\n\\n`;\n writer.write(encoder.encode(endpointMessage));\n\n // Get the Durable Object\n const agent = await getAgentByName(namespace, `sse:${sessionId}`, {\n props: ctx.props as Record<string, unknown> | undefined\n });\n\n // Connect to the Durable Object via WebSocket\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(\n new Request(request.url, {\n headers: {\n ...existingHeaders,\n Upgrade: \"websocket\"\n }\n })\n );\n\n // Get the WebSocket\n const ws = response.webSocket;\n if (!ws) {\n console.error(\"Failed to establish WebSocket connection\");\n await writer.close();\n return new Response(\"Failed to establish WebSocket connection\", {\n status: 500\n });\n }\n\n // Accept the WebSocket\n ws.accept();\n\n // Handle messages from the Durable Object\n ws.addEventListener(\"message\", (event) => {\n async function onMessage(event: MessageEvent) {\n try {\n const message = JSON.parse(event.data);\n\n // validate that the message is a valid JSONRPC message\n const result = JSONRPCMessageSchema.safeParse(message);\n if (!result.success) {\n // The message was not a valid JSONRPC message, so we will drop it\n // PartyKit will broadcast state change messages to all connected clients\n // and we need to filter those out so they are not passed to MCP clients\n return;\n }\n\n // Send the message as an SSE event\n const messageText = `event: message\\ndata: ${JSON.stringify(result.data)}\\n\\n`;\n await writer.write(encoder.encode(messageText));\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n }\n }\n onMessage(event).catch(console.error);\n });\n\n // Handle WebSocket errors\n ws.addEventListener(\"error\", (error) => {\n async function onError(_error: Event) {\n try {\n await writer.close();\n } catch (_e) {\n // Ignore errors when closing\n }\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n try {\n await writer.close();\n } catch (error) {\n console.error(\"Error closing SSE connection:\", error);\n }\n }\n onClose().catch(console.error);\n });\n\n // Return the SSE response\n return new Response(readable, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n ...corsHeaders(request, corsOptions)\n }\n });\n }\n\n // Handle incoming MCP messages. These will be passed to McpAgent\n // but the response will be sent back via the open SSE connection\n // so we only need to return a 202 Accepted response for success\n if (request.method === \"POST\" && messagePattern.test(url)) {\n const sessionId = url.searchParams.get(\"sessionId\");\n if (!sessionId) {\n return new Response(\n `Missing sessionId. Expected POST to ${basePath} to initiate new one`,\n { status: 400 }\n );\n }\n\n const contentType = request.headers.get(\"content-type\") || \"\";\n if (!contentType.includes(\"application/json\")) {\n return new Response(`Unsupported content-type: ${contentType}`, {\n status: 400\n });\n }\n\n // check if the request body is too large\n const contentLength = Number.parseInt(\n request.headers.get(\"content-length\") || \"0\",\n 10\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {\n return new Response(`Request body too large: ${contentLength} bytes`, {\n status: 400\n });\n }\n\n // Get the Durable Object\n const agent = await getAgentByName(namespace, `sse:${sessionId}`, {\n props: ctx.props as Record<string, unknown> | undefined\n });\n\n const messageBody = await request.json();\n const error = await agent.onSSEMcpMessage(sessionId, messageBody);\n\n if (error) {\n return new Response(error.message, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n ...corsHeaders(request, corsOptions)\n },\n status: 400\n });\n }\n\n return new Response(\"Accepted\", {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n ...corsHeaders(request, corsOptions)\n },\n status: 202\n });\n }\n\n return new Response(\"Not Found\", { status: 404 });\n };\n};\n\n// CORS helper functions\nfunction corsHeaders(_request: Request, corsOptions: CORSOptions = {}) {\n const origin = \"*\";\n return {\n \"Access-Control-Allow-Headers\":\n corsOptions.headers ||\n \"Content-Type, Accept, mcp-session-id, mcp-protocol-version\",\n \"Access-Control-Allow-Methods\":\n corsOptions.methods || \"GET, POST, DELETE, OPTIONS\",\n \"Access-Control-Allow-Origin\": corsOptions.origin || origin,\n \"Access-Control-Expose-Headers\":\n corsOptions.exposeHeaders || \"mcp-session-id\",\n \"Access-Control-Max-Age\": (corsOptions.maxAge || 86400).toString()\n };\n}\n\nexport function handleCORS(\n request: Request,\n corsOptions?: CORSOptions\n): Response | null {\n if (request.method === \"OPTIONS\") {\n return new Response(null, { headers: corsHeaders(request, corsOptions) });\n }\n\n return null;\n}\n\nexport function isDurableObjectNamespace(\n namespace: unknown\n): namespace is DurableObjectNamespace<McpAgent> {\n return (\n typeof namespace === \"object\" &&\n namespace !== null &&\n \"newUniqueId\" in namespace &&\n typeof namespace.newUniqueId === \"function\" &&\n \"idFromName\" in namespace &&\n typeof namespace.idFromName === \"function\"\n );\n}\n","import type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport {\n type MessageExtraInfo,\n type RequestInfo,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n type JSONRPCMessage,\n JSONRPCMessageSchema,\n type RequestId\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport { getCurrentAgent, type Connection } from \"..\";\nimport type { McpAgent } from \".\";\nimport { MessageType } from \"../ai-types\";\nimport { MCP_HTTP_METHOD_HEADER, MCP_MESSAGE_HEADER } from \"./utils\";\n\nexport class McpSSETransport implements Transport {\n sessionId?: string;\n // Set by the server in `server.connect(transport)`\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n private _getWebSocket: () => WebSocket | null;\n private _started = false;\n constructor(getWebSocket: () => WebSocket | null) {\n this._getWebSocket = getWebSocket;\n }\n\n async start() {\n // The transport does not manage the WebSocket connection since it's terminated\n // by the Durable Object in order to allow hibernation. There's nothing to initialize.\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n async send(message: JSONRPCMessage) {\n if (!this._started) {\n throw new Error(\"Transport not started\");\n }\n const websocket = this._getWebSocket();\n if (!websocket) {\n throw new Error(\"WebSocket not connected\");\n }\n try {\n websocket.send(JSON.stringify(message));\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n\n async close() {\n // Similar to start, the only thing to do is to pass the event on to the server\n this.onclose?.();\n }\n}\n\nexport type StreamId = string;\nexport type EventId = string;\n\n// TODO: Implement this and make it opt-in?\n/**\n * Interface for resumability support via event storage\n */\nexport interface EventStore {\n /**\n * Stores an event for later retrieval\n * @param streamId ID of the stream the event belongs to\n * @param message The JSON-RPC message to store\n * @returns The generated event ID for the stored event\n */\n storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;\n\n replayEventsAfter(\n lastEventId: EventId,\n {\n send\n }: {\n send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;\n }\n ): Promise<StreamId>;\n}\n\n/**\n * Configuration options for StreamableHTTPServerTransport\n */\nexport interface StreamableHTTPServerTransportOptions {\n /**\n * Event store for resumability support\n * If provided, resumability will be enabled, allowing clients to reconnect and resume messages\n */\n eventStore?: EventStore;\n}\n\n/**\n * Adapted from: https://github.com/modelcontextprotocol/typescript-sdk/blob/main/src/client/streamableHttp.ts\n * - Validation and initialization are removed as they're handled in `McpAgent.serve()` handler.\n * - Replaces the Node-style `req`/`res` with Worker's `Request`.\n * - Writes events as WS messages that the Worker forwards to the client as SSE events.\n * - Replaces the in-memory maps that track requestID/stream by using `connection.setState()` and `agent.getConnections()`.\n *\n * Besides these points, the implementation is the same and should be updated to match the original as new features are added.\n */\nexport class StreamableHTTPServerTransport implements Transport {\n private _started = false;\n private _eventStore?: EventStore;\n\n // This is to keep track whether all messages from a single POST request have been answered.\n // I's fine that we don't persist this since it's only for backwards compatibility as clients\n // should no longer batch requests, per the spec.\n private _requestResponseMap: Map<RequestId, JSONRPCMessage> = new Map();\n\n sessionId: string;\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n\n constructor(options: StreamableHTTPServerTransportOptions) {\n const { agent } = getCurrentAgent<McpAgent>();\n if (!agent)\n throw new Error(\"McpAgent was not found in Transport constructor\");\n\n // Initialization is handled in `McpAgent.serve()` and agents are addressed by sessionId,\n // so we'll always have this available.\n this.sessionId = agent.getSessionId();\n this._eventStore = options.eventStore;\n }\n\n /**\n * Starts the transport. This is required by the Transport interface but is a no-op\n * for the Streamable HTTP transport as connections are managed per-request.\n */\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n /**\n * Handles GET requests for SSE stream\n */\n async handleGetRequest(req: Request): Promise<void> {\n // Get the WS connection so we can tag it as the standalone stream\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not found in handleGetRequest\");\n\n // Handle resumability: check for Last-Event-ID header\n if (this._eventStore) {\n const lastEventId = req.headers.get(\"last-event-id\");\n if (lastEventId) {\n await this.replayEvents(lastEventId);\n return;\n }\n }\n\n connection.setState({\n _standaloneSse: true\n });\n }\n\n /**\n * Replays events that would have been sent after the specified event ID\n * Only used when resumability is enabled\n */\n private async replayEvents(lastEventId: string): Promise<void> {\n if (!this._eventStore) {\n return;\n }\n\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not available in replayEvents\");\n\n try {\n await this._eventStore?.replayEventsAfter(lastEventId, {\n send: async (eventId: string, message: JSONRPCMessage) => {\n try {\n this.writeSSEEvent(connection, message, eventId);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n });\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n\n /**\n * Writes an event to the SSE stream with proper formatting\n */\n private writeSSEEvent(\n connection: Connection,\n message: JSONRPCMessage,\n eventId?: string,\n close?: boolean\n ) {\n let eventData = \"event: message\\n\";\n // Include event ID if provided - this is important for resumability\n if (eventId) {\n eventData += `id: ${eventId}\\n`;\n }\n eventData += `data: ${JSON.stringify(message)}\\n\\n`;\n\n return connection.send(\n JSON.stringify({\n type: MessageType.CF_MCP_AGENT_EVENT,\n event: eventData,\n close\n })\n );\n }\n\n /**\n * Handles POST requests containing JSON-RPC messages\n */\n async handlePostRequest(\n req: Request & { auth?: AuthInfo },\n parsedBody: unknown\n ): Promise<void> {\n const authInfo: AuthInfo | undefined = req.auth;\n const requestInfo: RequestInfo = {\n headers: Object.fromEntries(req.headers.entries())\n };\n // Remove headers that are not part of the original request\n delete requestInfo.headers[MCP_HTTP_METHOD_HEADER];\n delete requestInfo.headers[MCP_MESSAGE_HEADER];\n delete requestInfo.headers.upgrade;\n\n const rawMessage = parsedBody;\n let messages: JSONRPCMessage[];\n\n // handle batch and single messages\n if (Array.isArray(rawMessage)) {\n messages = rawMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n } else {\n messages = [JSONRPCMessageSchema.parse(rawMessage)];\n }\n\n // check if it contains requests\n const hasRequests = messages.some(isJSONRPCRequest);\n\n if (!hasRequests) {\n // We process without sending anything\n for (const message of messages) {\n this.onmessage?.(message, { authInfo, requestInfo });\n }\n } else if (hasRequests) {\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not found in handlePostRequest\");\n\n // We need to track by request ID to maintain the connection\n const requestIds = messages\n .filter(isJSONRPCRequest)\n .map((message) => message.id);\n\n connection.setState({\n requestIds\n });\n\n // handle each message\n for (const message of messages) {\n this.onmessage?.(message, { authInfo, requestInfo });\n }\n // The server SHOULD NOT close the SSE stream before sending all JSON-RPC responses\n // This will be handled by the send() method when responses are ready\n }\n }\n\n async close(): Promise<void> {\n // Close all SSE connections\n const { agent } = getCurrentAgent();\n if (!agent) throw new Error(\"Agent was not found in close\");\n\n for (const conn of agent.getConnections()) {\n conn.close(1000, \"Session closed\");\n }\n this.onclose?.();\n }\n\n async send(\n message: JSONRPCMessage,\n options?: { relatedRequestId?: RequestId }\n ): Promise<void> {\n const { agent } = getCurrentAgent();\n if (!agent) throw new Error(\"Agent was not found in send\");\n\n let requestId = options?.relatedRequestId;\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n // If the message is a response, use the request ID from the message\n requestId = message.id;\n }\n\n // Check if this message should be sent on the standalone SSE stream (no request ID)\n // Ignore notifications from tools (which have relatedRequestId set)\n // Those will be sent via dedicated response SSE streams\n if (requestId === undefined) {\n // For standalone SSE streams, we can only send requests and notifications\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n throw new Error(\n \"Cannot send a response on a standalone SSE stream unless resuming a previous client request\"\n );\n }\n\n let standaloneConnection: Connection | undefined;\n for (const conn of agent.getConnections<{ _standaloneSse?: boolean }>()) {\n if (conn.state?._standaloneSse) standaloneConnection = conn;\n }\n\n if (standaloneConnection === undefined) {\n // The spec says the server MAY send messages on the stream, so it's ok to discard if no stream\n return;\n }\n\n // Generate and store event ID if event store is provided\n let eventId: string | undefined;\n if (this._eventStore) {\n // Stores the event and gets the generated event ID\n eventId = await this._eventStore.storeEvent(\n standaloneConnection.id,\n message\n );\n }\n\n // Send the message to the standalone SSE stream\n this.writeSSEEvent(standaloneConnection, message, eventId);\n return;\n }\n\n // Get the response for this request\n const connection = Array.from(\n agent.getConnections<{ requestIds?: number[] }>()\n ).find((conn) => conn.state?.requestIds?.includes(requestId as number));\n if (!connection) {\n throw new Error(\n `No connection established for request ID: ${String(requestId)}`\n );\n }\n\n let eventId: string | undefined;\n\n if (this._eventStore) {\n eventId = await this._eventStore.storeEvent(connection.id, message);\n }\n\n let shouldClose = false;\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n this._requestResponseMap.set(requestId, message);\n const relatedIds = connection.state?.requestIds ?? [];\n // Check if we have responses for all requests using this connection\n shouldClose = relatedIds.every((id) => this._requestResponseMap.has(id));\n\n if (shouldClose) {\n // Clean up\n for (const id of relatedIds) {\n this._requestResponseMap.delete(id);\n }\n }\n }\n this.writeSSEEvent(connection, message, eventId, shouldClose);\n }\n}\n"],"mappings":"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","names":["JSONRPCMessageSchema","isJSONRPCError","isJSONRPCResponse","body","event","isJSONRPCResponse","JSONRPCMessageSchema","JSONRPCMessageSchema","isJSONRPCResponse","eventId","JSONRPCMessageSchema","isJSONRPCResponse","isJSONRPCError"]}
1
+ {"version":3,"sources":["../../src/mcp/index.ts","../../src/mcp/utils.ts","../../src/mcp/transport.ts"],"sourcesContent":["import type { Server } from \"@modelcontextprotocol/sdk/server/index.js\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n JSONRPCMessageSchema,\n isJSONRPCError,\n isJSONRPCResponse,\n type ElicitResult\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Connection, ConnectionContext } from \"../\";\nimport { Agent } from \"../index\";\nimport type { BaseTransportType, MaybePromise, ServeOptions } from \"./types\";\nimport {\n createLegacySseHandler,\n createStreamingHttpHandler,\n handleCORS,\n isDurableObjectNamespace,\n MCP_HTTP_METHOD_HEADER,\n MCP_MESSAGE_HEADER\n} from \"./utils\";\nimport { McpSSETransport, StreamableHTTPServerTransport } from \"./transport\";\n\nexport abstract class McpAgent<\n Env = unknown,\n State = unknown,\n Props extends Record<string, unknown> = Record<string, unknown>\n> extends Agent<Env, State, Props> {\n private _transport?: Transport;\n props?: Props;\n\n abstract server: MaybePromise<McpServer | Server>;\n abstract init(): Promise<void>;\n\n /*\n * Helpers\n */\n\n async setInitializeRequest(initializeRequest: JSONRPCMessage) {\n await this.ctx.storage.put(\"initializeRequest\", initializeRequest);\n }\n\n async getInitializeRequest() {\n return this.ctx.storage.get<JSONRPCMessage>(\"initializeRequest\");\n }\n\n /** Read the transport type for this agent.\n * This relies on the naming scheme being `sse:${sessionId}`\n * or `streamable-http:${sessionId}`.\n */\n getTransportType(): BaseTransportType {\n const [t, ..._] = this.name.split(\":\");\n switch (t) {\n case \"sse\":\n return \"sse\";\n case \"streamable-http\":\n return \"streamable-http\";\n default:\n throw new Error(\n \"Invalid transport type. McpAgent must be addressed with a valid protocol.\"\n );\n }\n }\n\n /** Read the sessionId for this agent.\n * This relies on the naming scheme being `sse:${sessionId}`\n * or `streamable-http:${sessionId}`.\n */\n getSessionId(): string {\n const [_, sessionId] = this.name.split(\":\");\n if (!sessionId) {\n throw new Error(\n \"Invalid session id. McpAgent must be addressed with a valid session id.\"\n );\n }\n return sessionId;\n }\n\n /** Get the unique WebSocket. SSE transport only. */\n private getWebSocket() {\n const websockets = Array.from(this.getConnections());\n if (websockets.length === 0) {\n return null;\n }\n return websockets[0];\n }\n\n /** Returns a new transport matching the type of the Agent. */\n private initTransport() {\n switch (this.getTransportType()) {\n case \"sse\": {\n return new McpSSETransport(() => this.getWebSocket());\n }\n case \"streamable-http\": {\n return new StreamableHTTPServerTransport({});\n }\n }\n }\n\n /** Update and store the props */\n async updateProps(props?: Props) {\n await this.ctx.storage.put(\"props\", props ?? {});\n this.props = props;\n }\n\n async reinitializeServer() {\n // If the agent was previously initialized, we have to populate\n // the server again by sending the initialize request to make\n // client information available to the server.\n const initializeRequest = await this.getInitializeRequest();\n if (initializeRequest) {\n this._transport?.onmessage?.(initializeRequest);\n }\n }\n\n /*\n * Base Agent / Parykit Server overrides\n */\n\n /** Sets up the MCP transport and server every time the Agent is started.*/\n async onStart(props?: Props) {\n // If onStart was passed props, save them in storage\n if (props) await this.updateProps(props);\n this.props = await this.ctx.storage.get(\"props\");\n\n await this.init();\n const server = await this.server;\n // Connect to the MCP server\n this._transport = this.initTransport();\n await server.connect(this._transport);\n await this.reinitializeServer();\n }\n\n /** Validates new WebSocket connections. */\n async onConnect(\n conn: Connection,\n { request: req }: ConnectionContext\n ): Promise<void> {\n switch (this.getTransportType()) {\n case \"sse\": {\n // For SSE connections, we can only have one open connection per session\n // If we get an upgrade while already connected, we should error\n const websockets = Array.from(this.getConnections());\n if (websockets.length > 1) {\n conn.close(1008, \"Websocket already connected\");\n return;\n }\n break;\n }\n case \"streamable-http\":\n if (this._transport instanceof StreamableHTTPServerTransport) {\n switch (req.headers.get(MCP_HTTP_METHOD_HEADER)) {\n case \"POST\": {\n // This returns the response directly to the client\n const payloadHeader = req.headers.get(MCP_MESSAGE_HEADER);\n let rawPayload: string;\n\n if (!payloadHeader) {\n rawPayload = \"{}\";\n } else {\n try {\n rawPayload = Buffer.from(payloadHeader, \"base64\").toString(\n \"utf-8\"\n );\n } catch (_error) {\n throw new Error(\n \"Internal Server Error: Failed to decode MCP message header\"\n );\n }\n }\n\n const parsedBody = JSON.parse(rawPayload);\n this._transport?.handlePostRequest(req, parsedBody);\n break;\n }\n case \"GET\":\n this._transport?.handleGetRequest(req);\n break;\n }\n }\n }\n }\n\n /*\n * Transport ingress and routing\n */\n\n /** Handles MCP Messages for the legacy SSE transport. */\n async onSSEMcpMessage(\n _sessionId: string,\n messageBody: unknown\n ): Promise<Error | null> {\n // Since we address the DO via both the protocol and the session id,\n // this should never happen, but let's enforce it just in case\n if (this.getTransportType() !== \"sse\") {\n return new Error(\"Internal Server Error: Expected SSE transport\");\n }\n\n try {\n let parsedMessage: JSONRPCMessage;\n try {\n parsedMessage = JSONRPCMessageSchema.parse(messageBody);\n } catch (error) {\n this._transport?.onerror?.(error as Error);\n throw error;\n }\n\n // Check if this is an elicitation response before passing to transport\n if (await this._handleElicitationResponse(parsedMessage)) {\n return null; // Message was handled by elicitation system\n }\n\n this._transport?.onmessage?.(parsedMessage);\n return null;\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n this._transport?.onerror?.(error as Error);\n return error as Error;\n }\n }\n\n /** Elicit user input with a message and schema */\n async elicitInput(params: {\n message: string;\n requestedSchema: unknown;\n }): Promise<ElicitResult> {\n const requestId = `elicit_${Math.random().toString(36).substring(2, 11)}`;\n\n // Store pending request in durable storage\n await this.ctx.storage.put(`elicitation:${requestId}`, {\n message: params.message,\n requestedSchema: params.requestedSchema,\n timestamp: Date.now()\n });\n\n const elicitRequest = {\n jsonrpc: \"2.0\" as const,\n id: requestId,\n method: \"elicitation/create\",\n params: {\n message: params.message,\n requestedSchema: params.requestedSchema\n }\n };\n\n // Send through MCP transport\n if (this._transport) {\n await this._transport.send(elicitRequest);\n } else {\n const connections = this.getConnections();\n if (!connections || Array.from(connections).length === 0) {\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n throw new Error(\"No active connections available for elicitation\");\n }\n\n const connectionList = Array.from(connections);\n for (const connection of connectionList) {\n try {\n connection.send(JSON.stringify(elicitRequest));\n } catch (error) {\n console.error(\"Failed to send elicitation request:\", error);\n }\n }\n }\n\n // Wait for response through MCP\n return this._waitForElicitationResponse(requestId);\n }\n\n /** Wait for elicitation response through storage polling */\n private async _waitForElicitationResponse(\n requestId: string\n ): Promise<ElicitResult> {\n const startTime = Date.now();\n const timeout = 60000; // 60 second timeout\n\n try {\n while (Date.now() - startTime < timeout) {\n // Check if response has been stored\n const response = await this.ctx.storage.get<ElicitResult>(\n `elicitation:response:${requestId}`\n );\n if (response) {\n // Immediately clean up both request and response\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n await this.ctx.storage.delete(`elicitation:response:${requestId}`);\n return response;\n }\n\n // Sleep briefly before checking again\n await new Promise((resolve) => setTimeout(resolve, 100));\n }\n\n throw new Error(\"Elicitation request timed out\");\n } finally {\n // Always clean up on timeout or error\n await this.ctx.storage.delete(`elicitation:${requestId}`);\n await this.ctx.storage.delete(`elicitation:response:${requestId}`);\n }\n }\n\n /** Handle elicitation responses */\n private async _handleElicitationResponse(\n message: JSONRPCMessage\n ): Promise<boolean> {\n // Check if this is a response to an elicitation request\n if (isJSONRPCResponse(message) && message.result) {\n const requestId = message.id?.toString();\n if (!requestId || !requestId.startsWith(\"elicit_\")) return false;\n\n // Check if we have a pending request for this ID\n const pendingRequest = await this.ctx.storage.get(\n `elicitation:${requestId}`\n );\n if (!pendingRequest) return false;\n\n // Store the response in durable storage\n await this.ctx.storage.put(\n `elicitation:response:${requestId}`,\n message.result as ElicitResult\n );\n return true;\n }\n\n // Check if this is an error response to an elicitation request\n if (isJSONRPCError(message)) {\n const requestId = message.id?.toString();\n if (!requestId || !requestId.startsWith(\"elicit_\")) return false;\n\n // Check if we have a pending request for this ID\n const pendingRequest = await this.ctx.storage.get(\n `elicitation:${requestId}`\n );\n if (!pendingRequest) return false;\n\n // Store error response\n const errorResult: ElicitResult = {\n action: \"cancel\",\n content: {\n error: message.error.message || \"Elicitation request failed\"\n }\n };\n await this.ctx.storage.put(\n `elicitation:response:${requestId}`,\n errorResult\n );\n return true;\n }\n\n return false;\n }\n\n /** Return a handler for the given path for this MCP.\n * Defaults to Streamable HTTP transport.\n */\n static serve(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n transport = \"streamable-http\"\n }: ServeOptions = {}\n ) {\n return {\n async fetch<Env>(\n this: void,\n request: Request,\n env: Env,\n ctx: ExecutionContext\n ): Promise<Response> {\n // Handle CORS preflight\n const corsResponse = handleCORS(request, corsOptions);\n if (corsResponse) {\n return corsResponse;\n }\n\n const bindingValue = env[binding as keyof typeof env] as unknown;\n\n // Ensure we have a binding of some sort\n if (bindingValue == null || typeof bindingValue !== \"object\") {\n throw new Error(\n `Could not find McpAgent binding for ${binding}. Did you update your wrangler configuration?`\n );\n }\n\n // Ensure that the binding is to a DurableObject\n if (!isDurableObjectNamespace(bindingValue)) {\n throw new Error(\n `Invalid McpAgent binding for ${binding}. Make sure it's a Durable Object binding.`\n );\n }\n\n const namespace =\n bindingValue satisfies DurableObjectNamespace<McpAgent>;\n\n switch (transport) {\n case \"streamable-http\": {\n // Streamable HTTP transport handling\n const handleStreamableHttp = createStreamingHttpHandler(\n path,\n namespace,\n corsOptions\n );\n return handleStreamableHttp(request, ctx);\n }\n case \"sse\": {\n // Legacy SSE transport handling\n const handleLegacySse = createLegacySseHandler(\n path,\n namespace,\n corsOptions\n );\n return handleLegacySse(request, ctx);\n }\n default:\n return new Response(\n \"Invalid MCP transport mode. Only `streamable-http` or `sse` are allowed.\",\n { status: 500 }\n );\n }\n }\n };\n }\n /**\n * Legacy api\n **/\n static mount(path: string, opts: Omit<ServeOptions, \"transport\"> = {}) {\n return McpAgent.serveSSE(path, opts);\n }\n\n static serveSSE(path: string, opts: Omit<ServeOptions, \"transport\"> = {}) {\n return McpAgent.serve(path, { ...opts, transport: \"sse\" });\n }\n}\n\n// Export client transport classes\nexport { SSEEdgeClientTransport } from \"./sse-edge\";\nexport { StreamableHTTPEdgeClientTransport } from \"./streamable-http-edge\";\n\n// Export elicitation types and schemas\nexport {\n ElicitRequestSchema,\n type ElicitRequest,\n type ElicitResult\n} from \"@modelcontextprotocol/sdk/types.js\";\n\n// Export OAuth-related types\nexport type {\n MCPClientOAuthResult,\n MCPClientOAuthCallbackConfig\n} from \"./client\";\n","import {\n JSONRPCMessageSchema,\n type JSONRPCMessage,\n InitializeRequestSchema,\n isJSONRPCResponse,\n isJSONRPCNotification\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { McpAgent } from \".\";\nimport { getAgentByName } from \"..\";\nimport type { CORSOptions } from \"./types\";\nimport { MessageType } from \"../ai-types\";\n\n/**\n * Since we use WebSockets to bridge the client to the\n * MCP transport in the Agent, we use this header to signal\n * the method of the original request the user made, while\n * leaving the WS Upgrade request as GET.\n */\nexport const MCP_HTTP_METHOD_HEADER = \"cf-mcp-method\";\n\n/**\n * Since we use WebSockets to bridge the client to the\n * MCP transport in the Agent, we use this header to include\n * the original request body.\n */\nexport const MCP_MESSAGE_HEADER = \"cf-mcp-message\";\n\nconst MAXIMUM_MESSAGE_SIZE_BYTES = 4 * 1024 * 1024; // 4MB\n\nexport const createStreamingHttpHandler = (\n basePath: string,\n namespace: DurableObjectNamespace<McpAgent>,\n corsOptions?: CORSOptions\n) => {\n let pathname = basePath;\n if (basePath === \"/\") pathname = \"/*\";\n\n const basePattern = new URLPattern({ pathname });\n return async (request: Request, ctx: ExecutionContext) => {\n const url = new URL(request.url);\n if (basePattern.test(url)) {\n if (request.method === \"POST\") {\n // Validate the Accept header\n const acceptHeader = request.headers.get(\"accept\");\n // The client MUST include an Accept header, listing both application/json and text/event-stream as supported content types.\n if (\n !acceptHeader?.includes(\"application/json\") ||\n !acceptHeader.includes(\"text/event-stream\")\n ) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message:\n \"Not Acceptable: Client must accept both application/json and text/event-stream\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 406 });\n }\n\n const ct = request.headers.get(\"content-type\");\n if (!ct || !ct.includes(\"application/json\")) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message:\n \"Unsupported Media Type: Content-Type must be application/json\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 415 });\n }\n\n // Check content length against maximum allowed size\n const contentLength = Number.parseInt(\n request.headers.get(\"content-length\") ?? \"0\",\n 10\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: `Request body too large. Maximum size is ${MAXIMUM_MESSAGE_SIZE_BYTES} bytes`\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 413 });\n }\n\n let sessionId = request.headers.get(\"mcp-session-id\");\n let rawMessage: unknown;\n\n try {\n rawMessage = await request.json();\n } catch (_error) {\n const body = JSON.stringify({\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n\n // Make sure the message is an array to simplify logic\n let arrayMessage: unknown[];\n if (Array.isArray(rawMessage)) {\n arrayMessage = rawMessage;\n } else {\n arrayMessage = [rawMessage];\n }\n\n let messages: JSONRPCMessage[] = [];\n\n // Try to parse each message as JSON RPC. Fail if any message is invalid\n for (const msg of arrayMessage) {\n if (!JSONRPCMessageSchema.safeParse(msg).success) {\n const body = JSON.stringify({\n error: {\n code: -32700,\n message: \"Parse error: Invalid JSON-RPC message\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n }\n\n messages = arrayMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n\n // Before we pass the messages to the agent, there's another error condition we need to enforce\n // Check if this is an initialization request\n // https://spec.modelcontextprotocol.io/specification/2025-03-26/basic/lifecycle/\n const maybeInitializeRequest = messages.find(\n (msg) => InitializeRequestSchema.safeParse(msg).success\n );\n\n if (!!maybeInitializeRequest && sessionId) {\n const body = JSON.stringify({\n error: {\n code: -32600,\n message:\n \"Invalid Request: Initialization requests must not include a sessionId\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n\n // The initialization request must be the only request in the batch\n if (!!maybeInitializeRequest && messages.length > 1) {\n const body = JSON.stringify({\n error: {\n code: -32600,\n message:\n \"Invalid Request: Only one initialization request is allowed\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n\n // If an Mcp-Session-Id is returned by the server during initialization,\n // clients using the Streamable HTTP transport MUST include it\n // in the Mcp-Session-Id header on all of their subsequent HTTP requests.\n if (!maybeInitializeRequest && !sessionId) {\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: \"Bad Request: Mcp-Session-Id header is required\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 400 });\n }\n\n // If we don't have a sessionId, we are serving an initialization request\n // and need to generate a new sessionId\n sessionId = sessionId ?? namespace.newUniqueId().toString();\n\n // Get the agent and set props\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`,\n { props: ctx.props as Record<string, unknown> | undefined }\n );\n const isInitialized = await agent.getInitializeRequest();\n\n if (maybeInitializeRequest) {\n await agent.setInitializeRequest(maybeInitializeRequest);\n } else if (!isInitialized) {\n // if we have gotten here, then a session id that was never initialized\n // was provided\n const body = JSON.stringify({\n error: {\n code: -32001,\n message: \"Session not found\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 404 });\n }\n\n // We've evaluated all the error conditions! Now it's time to establish\n // all the streams\n\n // Create a Transform Stream for SSE\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n // Connect to the Durable Object via WebSocket\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n\n const req = new Request(request.url, {\n headers: {\n ...existingHeaders,\n [MCP_HTTP_METHOD_HEADER]: \"POST\",\n [MCP_MESSAGE_HEADER]: Buffer.from(\n JSON.stringify(messages)\n ).toString(\"base64\"),\n Upgrade: \"websocket\"\n }\n });\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(req);\n\n // Get the WebSocket\n const ws = response.webSocket;\n if (!ws) {\n console.error(\"Failed to establish WebSocket connection\");\n\n await writer.close();\n const body = JSON.stringify({\n error: {\n code: -32001,\n message: \"Failed to establish WebSocket connection\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 500 });\n }\n\n // Accept the WebSocket\n ws.accept();\n\n // Handle messages from the Durable Object\n ws.addEventListener(\"message\", (event) => {\n async function onMessage(event: MessageEvent) {\n try {\n const data =\n typeof event.data === \"string\"\n ? event.data\n : new TextDecoder().decode(event.data);\n const message = JSON.parse(data);\n\n // We only forward events from the MCP server\n if (message.type !== MessageType.CF_MCP_AGENT_EVENT) {\n return;\n }\n\n // Send the message as an SSE event\n await writer.write(encoder.encode(message.event));\n\n // If we have received all the responses, close the connection\n if (message.close) {\n ws?.close();\n await writer.close().catch(() => {});\n }\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n }\n }\n onMessage(event).catch(console.error);\n });\n\n // Handle WebSocket errors\n ws.addEventListener(\"error\", (error) => {\n async function onError(_error: Event) {\n await writer.close().catch(() => {});\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n await writer.close().catch(() => {});\n }\n onClose().catch(console.error);\n });\n\n // If there are no requests, we send the messages to the agent and acknowledge the request with a 202\n // since we don't expect any responses back through this connection\n const hasOnlyNotificationsOrResponses = messages.every(\n (msg) => isJSONRPCNotification(msg) || isJSONRPCResponse(msg)\n );\n if (hasOnlyNotificationsOrResponses) {\n // closing the websocket will also close the SSE connection\n ws.close();\n\n return new Response(null, {\n headers: corsHeaders(request, corsOptions),\n status: 202\n });\n }\n\n // Return the SSE response. We handle closing the stream in the ws \"message\"\n // handler\n return new Response(readable, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n \"mcp-session-id\": sessionId,\n ...corsHeaders(request, corsOptions)\n },\n status: 200\n });\n } else if (request.method === \"GET\") {\n // Validate the Accept header\n const acceptHeader = request.headers.get(\"accept\");\n // The client MUST include an Accept header, listing both application/json and text/event-stream as supported content types.\n if (!acceptHeader?.includes(\"text/event-stream\")) {\n const body = JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Not Acceptable: Client must accept text/event-stream\"\n },\n id: null\n });\n return new Response(body, { status: 406 });\n }\n\n // Require sessionId\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (!sessionId)\n return new Response(\n JSON.stringify({\n error: {\n code: -32000,\n message: \"Bad Request: Mcp-Session-Id header is required\"\n },\n id: null,\n jsonrpc: \"2.0\"\n }),\n { status: 400 }\n );\n\n // Create SSE stream\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`,\n { props: ctx.props as Record<string, unknown> | undefined }\n );\n const isInitialized = await agent.getInitializeRequest();\n if (!isInitialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32001, message: \"Session not found\" },\n id: null\n }),\n { status: 404 }\n );\n }\n\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((v, k) => {\n existingHeaders[k] = v;\n });\n\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(\n new Request(request.url, {\n headers: {\n ...existingHeaders,\n [MCP_HTTP_METHOD_HEADER]: \"GET\",\n Upgrade: \"websocket\"\n }\n })\n );\n\n const ws = response.webSocket;\n if (!ws) {\n await writer.close();\n return new Response(\"Failed to establish WS to DO\", {\n status: 500\n });\n }\n ws.accept();\n\n // Forward DO messages as SSE\n ws.addEventListener(\"message\", (event) => {\n try {\n async function onMessage(ev: MessageEvent) {\n const data =\n typeof ev.data === \"string\"\n ? ev.data\n : new TextDecoder().decode(ev.data);\n const message = JSON.parse(data);\n\n // We only forward events from the MCP server\n if (message.type !== MessageType.CF_MCP_AGENT_EVENT) {\n return;\n }\n await writer.write(encoder.encode(message.event));\n }\n onMessage(event).catch(console.error);\n } catch (e) {\n console.error(\"Error forwarding message to SSE:\", e);\n }\n });\n\n ws.addEventListener(\"error\", () => {\n writer.close().catch(() => {});\n });\n ws.addEventListener(\"close\", () => {\n writer.close().catch(() => {});\n });\n\n return new Response(readable, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n \"mcp-session-id\": sessionId,\n ...corsHeaders(request, corsOptions)\n },\n status: 200\n });\n } else if (request.method === \"DELETE\") {\n const sessionId = request.headers.get(\"mcp-session-id\");\n if (!sessionId) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: {\n code: -32000,\n message: \"Bad Request: Mcp-Session-Id header is required\"\n },\n id: null\n }),\n { status: 400, headers: corsHeaders(request, corsOptions) }\n );\n }\n const agent = await getAgentByName(\n namespace,\n `streamable-http:${sessionId}`\n );\n const isInitialized = await agent.getInitializeRequest();\n if (!isInitialized) {\n return new Response(\n JSON.stringify({\n jsonrpc: \"2.0\",\n error: { code: -32001, message: \"Session not found\" },\n id: null\n }),\n { status: 404, headers: corsHeaders(request, corsOptions) }\n );\n }\n // .destroy() passes an uncatchable Error, so we make sure we first return\n // the response to the client.\n ctx.waitUntil(\n agent.destroy().catch(() => {\n /* This will always throw. We silently catch here */\n })\n );\n return new Response(null, {\n status: 204,\n headers: corsHeaders(request, corsOptions)\n });\n }\n }\n\n // Route not found\n const body = JSON.stringify({\n error: {\n code: -32000,\n message: \"Not found\"\n },\n id: null,\n jsonrpc: \"2.0\"\n });\n return new Response(body, { status: 404 });\n };\n};\n\nexport const createLegacySseHandler = (\n basePath: string,\n namespace: DurableObjectNamespace<McpAgent>,\n corsOptions?: CORSOptions\n) => {\n let pathname = basePath;\n if (basePath === \"/\") pathname = \"/*\";\n\n const basePattern = new URLPattern({ pathname });\n const messagePattern = new URLPattern({ pathname: `${basePath}/message` }); // SSE only\n return async (request: Request, ctx: ExecutionContext) => {\n const url = new URL(request.url);\n // Handle initial SSE connection\n if (request.method === \"GET\" && basePattern.test(url)) {\n // Use a session ID if one is passed in, or create a unique\n // session ID for this connection\n const sessionId =\n url.searchParams.get(\"sessionId\") || namespace.newUniqueId().toString();\n\n // Create a Transform Stream for SSE\n const { readable, writable } = new TransformStream();\n const writer = writable.getWriter();\n const encoder = new TextEncoder();\n\n // Send the endpoint event\n const endpointUrl = new URL(request.url);\n endpointUrl.pathname = encodeURI(`${basePath}/message`);\n endpointUrl.searchParams.set(\"sessionId\", sessionId);\n const relativeUrlWithSession =\n endpointUrl.pathname + endpointUrl.search + endpointUrl.hash;\n const endpointMessage = `event: endpoint\\ndata: ${relativeUrlWithSession}\\n\\n`;\n writer.write(encoder.encode(endpointMessage));\n\n // Get the Durable Object\n const agent = await getAgentByName(namespace, `sse:${sessionId}`, {\n props: ctx.props as Record<string, unknown> | undefined\n });\n\n // Connect to the Durable Object via WebSocket\n const existingHeaders: Record<string, string> = {};\n request.headers.forEach((value, key) => {\n existingHeaders[key] = value;\n });\n if (ctx.props) agent.updateProps(ctx.props as Record<string, unknown>);\n const response = await agent.fetch(\n new Request(request.url, {\n headers: {\n ...existingHeaders,\n Upgrade: \"websocket\"\n }\n })\n );\n\n // Get the WebSocket\n const ws = response.webSocket;\n if (!ws) {\n console.error(\"Failed to establish WebSocket connection\");\n await writer.close();\n return new Response(\"Failed to establish WebSocket connection\", {\n status: 500\n });\n }\n\n // Accept the WebSocket\n ws.accept();\n\n // Handle messages from the Durable Object\n ws.addEventListener(\"message\", (event) => {\n async function onMessage(event: MessageEvent) {\n try {\n const message = JSON.parse(event.data);\n\n // validate that the message is a valid JSONRPC message\n const result = JSONRPCMessageSchema.safeParse(message);\n if (!result.success) {\n // The message was not a valid JSONRPC message, so we will drop it\n // PartyKit will broadcast state change messages to all connected clients\n // and we need to filter those out so they are not passed to MCP clients\n return;\n }\n\n // Send the message as an SSE event\n const messageText = `event: message\\ndata: ${JSON.stringify(result.data)}\\n\\n`;\n await writer.write(encoder.encode(messageText));\n } catch (error) {\n console.error(\"Error forwarding message to SSE:\", error);\n }\n }\n onMessage(event).catch(console.error);\n });\n\n // Handle WebSocket errors\n ws.addEventListener(\"error\", (error) => {\n async function onError(_error: Event) {\n try {\n await writer.close();\n } catch (_e) {\n // Ignore errors when closing\n }\n }\n onError(error).catch(console.error);\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", () => {\n async function onClose() {\n try {\n await writer.close();\n } catch (error) {\n console.error(\"Error closing SSE connection:\", error);\n }\n }\n onClose().catch(console.error);\n });\n\n // Return the SSE response\n return new Response(readable, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n ...corsHeaders(request, corsOptions)\n }\n });\n }\n\n // Handle incoming MCP messages. These will be passed to McpAgent\n // but the response will be sent back via the open SSE connection\n // so we only need to return a 202 Accepted response for success\n if (request.method === \"POST\" && messagePattern.test(url)) {\n const sessionId = url.searchParams.get(\"sessionId\");\n if (!sessionId) {\n return new Response(\n `Missing sessionId. Expected POST to ${basePath} to initiate new one`,\n { status: 400 }\n );\n }\n\n const contentType = request.headers.get(\"content-type\") || \"\";\n if (!contentType.includes(\"application/json\")) {\n return new Response(`Unsupported content-type: ${contentType}`, {\n status: 400\n });\n }\n\n // check if the request body is too large\n const contentLength = Number.parseInt(\n request.headers.get(\"content-length\") || \"0\",\n 10\n );\n if (contentLength > MAXIMUM_MESSAGE_SIZE_BYTES) {\n return new Response(`Request body too large: ${contentLength} bytes`, {\n status: 400\n });\n }\n\n // Get the Durable Object\n const agent = await getAgentByName(namespace, `sse:${sessionId}`, {\n props: ctx.props as Record<string, unknown> | undefined\n });\n\n const messageBody = await request.json();\n const error = await agent.onSSEMcpMessage(sessionId, messageBody);\n\n if (error) {\n return new Response(error.message, {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n ...corsHeaders(request, corsOptions)\n },\n status: 400\n });\n }\n\n return new Response(\"Accepted\", {\n headers: {\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Content-Type\": \"text/event-stream\",\n ...corsHeaders(request, corsOptions)\n },\n status: 202\n });\n }\n\n return new Response(\"Not Found\", { status: 404 });\n };\n};\n\n// CORS helper functions\nfunction corsHeaders(_request: Request, corsOptions: CORSOptions = {}) {\n const origin = \"*\";\n return {\n \"Access-Control-Allow-Headers\":\n corsOptions.headers ||\n \"Content-Type, Accept, mcp-session-id, mcp-protocol-version\",\n \"Access-Control-Allow-Methods\":\n corsOptions.methods || \"GET, POST, DELETE, OPTIONS\",\n \"Access-Control-Allow-Origin\": corsOptions.origin || origin,\n \"Access-Control-Expose-Headers\":\n corsOptions.exposeHeaders || \"mcp-session-id\",\n \"Access-Control-Max-Age\": (corsOptions.maxAge || 86400).toString()\n };\n}\n\nexport function handleCORS(\n request: Request,\n corsOptions?: CORSOptions\n): Response | null {\n if (request.method === \"OPTIONS\") {\n return new Response(null, { headers: corsHeaders(request, corsOptions) });\n }\n\n return null;\n}\n\nexport function isDurableObjectNamespace(\n namespace: unknown\n): namespace is DurableObjectNamespace<McpAgent> {\n return (\n typeof namespace === \"object\" &&\n namespace !== null &&\n \"newUniqueId\" in namespace &&\n typeof namespace.newUniqueId === \"function\" &&\n \"idFromName\" in namespace &&\n typeof namespace.idFromName === \"function\"\n );\n}\n","import type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\nimport {\n type MessageExtraInfo,\n type RequestInfo,\n isJSONRPCError,\n isJSONRPCRequest,\n isJSONRPCResponse,\n type JSONRPCMessage,\n JSONRPCMessageSchema,\n type RequestId\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { AuthInfo } from \"@modelcontextprotocol/sdk/server/auth/types.js\";\nimport { getCurrentAgent, type Connection } from \"..\";\nimport type { McpAgent } from \".\";\nimport { MessageType } from \"../ai-types\";\nimport { MCP_HTTP_METHOD_HEADER, MCP_MESSAGE_HEADER } from \"./utils\";\n\nexport class McpSSETransport implements Transport {\n sessionId?: string;\n // Set by the server in `server.connect(transport)`\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n private _getWebSocket: () => WebSocket | null;\n private _started = false;\n constructor(getWebSocket: () => WebSocket | null) {\n this._getWebSocket = getWebSocket;\n }\n\n async start() {\n // The transport does not manage the WebSocket connection since it's terminated\n // by the Durable Object in order to allow hibernation. There's nothing to initialize.\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n async send(message: JSONRPCMessage) {\n if (!this._started) {\n throw new Error(\"Transport not started\");\n }\n const websocket = this._getWebSocket();\n if (!websocket) {\n throw new Error(\"WebSocket not connected\");\n }\n try {\n websocket.send(JSON.stringify(message));\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n\n async close() {\n // Similar to start, the only thing to do is to pass the event on to the server\n this.onclose?.();\n }\n}\n\nexport type StreamId = string;\nexport type EventId = string;\n\n// TODO: Implement this and make it opt-in?\n/**\n * Interface for resumability support via event storage\n */\nexport interface EventStore {\n /**\n * Stores an event for later retrieval\n * @param streamId ID of the stream the event belongs to\n * @param message The JSON-RPC message to store\n * @returns The generated event ID for the stored event\n */\n storeEvent(streamId: StreamId, message: JSONRPCMessage): Promise<EventId>;\n\n replayEventsAfter(\n lastEventId: EventId,\n {\n send\n }: {\n send: (eventId: EventId, message: JSONRPCMessage) => Promise<void>;\n }\n ): Promise<StreamId>;\n}\n\n/**\n * Configuration options for StreamableHTTPServerTransport\n */\nexport interface StreamableHTTPServerTransportOptions {\n /**\n * Event store for resumability support\n * If provided, resumability will be enabled, allowing clients to reconnect and resume messages\n */\n eventStore?: EventStore;\n}\n\n/**\n * Adapted from: https://github.com/modelcontextprotocol/typescript-sdk/blob/main/src/client/streamableHttp.ts\n * - Validation and initialization are removed as they're handled in `McpAgent.serve()` handler.\n * - Replaces the Node-style `req`/`res` with Worker's `Request`.\n * - Writes events as WS messages that the Worker forwards to the client as SSE events.\n * - Replaces the in-memory maps that track requestID/stream by using `connection.setState()` and `agent.getConnections()`.\n *\n * Besides these points, the implementation is the same and should be updated to match the original as new features are added.\n */\nexport class StreamableHTTPServerTransport implements Transport {\n private _started = false;\n private _eventStore?: EventStore;\n\n // This is to keep track whether all messages from a single POST request have been answered.\n // I's fine that we don't persist this since it's only for backwards compatibility as clients\n // should no longer batch requests, per the spec.\n private _requestResponseMap: Map<RequestId, JSONRPCMessage> = new Map();\n\n sessionId: string;\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage, extra?: MessageExtraInfo) => void;\n\n constructor(options: StreamableHTTPServerTransportOptions) {\n const { agent } = getCurrentAgent<McpAgent>();\n if (!agent)\n throw new Error(\"McpAgent was not found in Transport constructor\");\n\n // Initialization is handled in `McpAgent.serve()` and agents are addressed by sessionId,\n // so we'll always have this available.\n this.sessionId = agent.getSessionId();\n this._eventStore = options.eventStore;\n }\n\n /**\n * Starts the transport. This is required by the Transport interface but is a no-op\n * for the Streamable HTTP transport as connections are managed per-request.\n */\n async start(): Promise<void> {\n if (this._started) {\n throw new Error(\"Transport already started\");\n }\n this._started = true;\n }\n\n /**\n * Handles GET requests for SSE stream\n */\n async handleGetRequest(req: Request): Promise<void> {\n // Get the WS connection so we can tag it as the standalone stream\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not found in handleGetRequest\");\n\n // Handle resumability: check for Last-Event-ID header\n if (this._eventStore) {\n const lastEventId = req.headers.get(\"last-event-id\");\n if (lastEventId) {\n await this.replayEvents(lastEventId);\n return;\n }\n }\n\n connection.setState({\n _standaloneSse: true\n });\n }\n\n /**\n * Replays events that would have been sent after the specified event ID\n * Only used when resumability is enabled\n */\n private async replayEvents(lastEventId: string): Promise<void> {\n if (!this._eventStore) {\n return;\n }\n\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not available in replayEvents\");\n\n try {\n await this._eventStore?.replayEventsAfter(lastEventId, {\n send: async (eventId: string, message: JSONRPCMessage) => {\n try {\n this.writeSSEEvent(connection, message, eventId);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n });\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n\n /**\n * Writes an event to the SSE stream with proper formatting\n */\n private writeSSEEvent(\n connection: Connection,\n message: JSONRPCMessage,\n eventId?: string,\n close?: boolean\n ) {\n let eventData = \"event: message\\n\";\n // Include event ID if provided - this is important for resumability\n if (eventId) {\n eventData += `id: ${eventId}\\n`;\n }\n eventData += `data: ${JSON.stringify(message)}\\n\\n`;\n\n return connection.send(\n JSON.stringify({\n type: MessageType.CF_MCP_AGENT_EVENT,\n event: eventData,\n close\n })\n );\n }\n\n /**\n * Handles POST requests containing JSON-RPC messages\n */\n async handlePostRequest(\n req: Request & { auth?: AuthInfo },\n parsedBody: unknown\n ): Promise<void> {\n const authInfo: AuthInfo | undefined = req.auth;\n const requestInfo: RequestInfo = {\n headers: Object.fromEntries(req.headers.entries())\n };\n // Remove headers that are not part of the original request\n delete requestInfo.headers[MCP_HTTP_METHOD_HEADER];\n delete requestInfo.headers[MCP_MESSAGE_HEADER];\n delete requestInfo.headers.upgrade;\n\n const rawMessage = parsedBody;\n let messages: JSONRPCMessage[];\n\n // handle batch and single messages\n if (Array.isArray(rawMessage)) {\n messages = rawMessage.map((msg) => JSONRPCMessageSchema.parse(msg));\n } else {\n messages = [JSONRPCMessageSchema.parse(rawMessage)];\n }\n\n // check if it contains requests\n const hasRequests = messages.some(isJSONRPCRequest);\n\n if (!hasRequests) {\n // We process without sending anything\n for (const message of messages) {\n this.onmessage?.(message, { authInfo, requestInfo });\n }\n } else if (hasRequests) {\n const { connection } = getCurrentAgent();\n if (!connection)\n throw new Error(\"Connection was not found in handlePostRequest\");\n\n // We need to track by request ID to maintain the connection\n const requestIds = messages\n .filter(isJSONRPCRequest)\n .map((message) => message.id);\n\n connection.setState({\n requestIds\n });\n\n // handle each message\n for (const message of messages) {\n this.onmessage?.(message, { authInfo, requestInfo });\n }\n // The server SHOULD NOT close the SSE stream before sending all JSON-RPC responses\n // This will be handled by the send() method when responses are ready\n }\n }\n\n async close(): Promise<void> {\n // Close all SSE connections\n const { agent } = getCurrentAgent();\n if (!agent) throw new Error(\"Agent was not found in close\");\n\n for (const conn of agent.getConnections()) {\n conn.close(1000, \"Session closed\");\n }\n this.onclose?.();\n }\n\n async send(\n message: JSONRPCMessage,\n options?: { relatedRequestId?: RequestId }\n ): Promise<void> {\n const { agent } = getCurrentAgent();\n if (!agent) throw new Error(\"Agent was not found in send\");\n\n let requestId = options?.relatedRequestId;\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n // If the message is a response, use the request ID from the message\n requestId = message.id;\n }\n\n // Check if this message should be sent on the standalone SSE stream (no request ID)\n // Ignore notifications from tools (which have relatedRequestId set)\n // Those will be sent via dedicated response SSE streams\n if (requestId === undefined) {\n // For standalone SSE streams, we can only send requests and notifications\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n throw new Error(\n \"Cannot send a response on a standalone SSE stream unless resuming a previous client request\"\n );\n }\n\n let standaloneConnection: Connection | undefined;\n for (const conn of agent.getConnections<{ _standaloneSse?: boolean }>()) {\n if (conn.state?._standaloneSse) standaloneConnection = conn;\n }\n\n if (standaloneConnection === undefined) {\n // The spec says the server MAY send messages on the stream, so it's ok to discard if no stream\n return;\n }\n\n // Generate and store event ID if event store is provided\n let eventId: string | undefined;\n if (this._eventStore) {\n // Stores the event and gets the generated event ID\n eventId = await this._eventStore.storeEvent(\n standaloneConnection.id,\n message\n );\n }\n\n // Send the message to the standalone SSE stream\n this.writeSSEEvent(standaloneConnection, message, eventId);\n return;\n }\n\n // Get the response for this request\n const connection = Array.from(\n agent.getConnections<{ requestIds?: number[] }>()\n ).find((conn) => conn.state?.requestIds?.includes(requestId as number));\n if (!connection) {\n throw new Error(\n `No connection established for request ID: ${String(requestId)}`\n );\n }\n\n let eventId: string | undefined;\n\n if (this._eventStore) {\n eventId = await this._eventStore.storeEvent(connection.id, message);\n }\n\n let shouldClose = false;\n\n if (isJSONRPCResponse(message) || isJSONRPCError(message)) {\n this._requestResponseMap.set(requestId, message);\n const relatedIds = connection.state?.requestIds ?? [];\n // Check if we have responses for all requests using this connection\n shouldClose = relatedIds.every((id) => this._requestResponseMap.has(id));\n\n if (shouldClose) {\n // Clean up\n for (const id of relatedIds) {\n this._requestResponseMap.delete(id);\n }\n }\n }\n this.writeSSEEvent(connection, message, eventId, shouldClose);\n }\n}\n"],"mappings":"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","names":["JSONRPCMessageSchema","isJSONRPCError","isJSONRPCResponse","body","event","isJSONRPCResponse","JSONRPCMessageSchema","JSONRPCMessageSchema","isJSONRPCResponse","eventId","JSONRPCMessageSchema","isJSONRPCResponse","isJSONRPCError"]}
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  genericObservability
3
- } from "../chunk-XGMKNUJA.js";
4
- import "../chunk-ZMMHNOMZ.js";
3
+ } from "../chunk-2Y6KNRNP.js";
4
+ import "../chunk-QUOGV3WN.js";
5
5
  import "../chunk-C2OEBJZ2.js";
6
6
  import "../chunk-QEVM4BVL.js";
7
7
  import "../chunk-BER7KXUJ.js";
package/package.json CHANGED
@@ -130,5 +130,5 @@
130
130
  },
131
131
  "type": "module",
132
132
  "types": "dist/index.d.ts",
133
- "version": "0.2.9"
133
+ "version": "0.2.10"
134
134
  }
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/mcp/client.ts","../src/core/events.ts","../src/mcp/client-connection.ts","../src/mcp/errors.ts","../src/mcp/sse-edge.ts","../src/mcp/streamable-http-edge.ts"],"sourcesContent":["import type { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { RequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport type {\n CallToolRequest,\n CallToolResultSchema,\n CompatibilityCallToolResultSchema,\n GetPromptRequest,\n Prompt,\n ReadResourceRequest,\n Resource,\n ResourceTemplate,\n Tool\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { type ToolSet, jsonSchema } from \"ai\";\nimport { nanoid } from \"nanoid\";\nimport { Emitter, type Event, DisposableStore } from \"../core/events\";\nimport type { MCPObservabilityEvent } from \"../observability/mcp\";\nimport {\n MCPClientConnection,\n type MCPTransportOptions\n} from \"./client-connection\";\nimport { toErrorMessage } from \"./errors\";\nimport type { TransportType } from \"./types\";\n\nexport type MCPClientOAuthCallbackConfig = {\n successRedirect?: string;\n errorRedirect?: string;\n customHandler?: (result: MCPClientOAuthResult) => Response;\n};\n\nexport type MCPClientOAuthResult = {\n serverId: string;\n authSuccess: boolean;\n authError?: string;\n};\n\n/**\n * Utility class that aggregates multiple MCP clients into one\n */\nexport class MCPClientManager {\n public mcpConnections: Record<string, MCPClientConnection> = {};\n private _callbackUrls: string[] = [];\n private _didWarnAboutUnstableGetAITools = false;\n private _oauthCallbackConfig?: MCPClientOAuthCallbackConfig;\n private _connectionDisposables = new Map<string, DisposableStore>();\n\n private readonly _onObservabilityEvent = new Emitter<MCPObservabilityEvent>();\n public readonly onObservabilityEvent: Event<MCPObservabilityEvent> =\n this._onObservabilityEvent.event;\n\n private readonly _onConnected = new Emitter<string>();\n public readonly onConnected: Event<string> = this._onConnected.event;\n\n /**\n * @param _name Name of the MCP client\n * @param _version Version of the MCP Client\n * @param auth Auth paramters if being used to create a DurableObjectOAuthClientProvider\n */\n constructor(\n private _name: string,\n private _version: string\n ) {}\n\n /**\n * Connect to and register an MCP server\n *\n * @param transportConfig Transport config\n * @param clientConfig Client config\n * @param capabilities Client capabilities (i.e. if the client supports roots/sampling)\n */\n async connect(\n url: string,\n options: {\n // Allows you to reconnect to a server (in the case of an auth reconnect)\n reconnect?: {\n // server id\n id: string;\n oauthClientId?: string;\n oauthCode?: string;\n };\n // we're overriding authProvider here because we want to be able to access the auth URL\n transport?: MCPTransportOptions;\n client?: ConstructorParameters<typeof Client>[1];\n } = {}\n ): Promise<{\n id: string;\n authUrl?: string;\n clientId?: string;\n }> {\n const id = options.reconnect?.id ?? nanoid(8);\n\n if (options.transport?.authProvider) {\n options.transport.authProvider.serverId = id;\n // reconnect with auth\n if (options.reconnect?.oauthClientId) {\n options.transport.authProvider.clientId =\n options.reconnect?.oauthClientId;\n }\n }\n\n // During OAuth reconnect, reuse existing connection to preserve state\n if (!options.reconnect?.oauthCode || !this.mcpConnections[id]) {\n const normalizedTransport = {\n ...options.transport,\n type: options.transport?.type ?? (\"auto\" as TransportType)\n };\n\n this.mcpConnections[id] = new MCPClientConnection(\n new URL(url),\n {\n name: this._name,\n version: this._version\n },\n {\n client: options.client ?? {},\n transport: normalizedTransport\n }\n );\n\n // Pipe connection-level observability events to the manager-level emitter\n // and track the subscription for cleanup.\n const store = new DisposableStore();\n // If we somehow already had disposables for this id, clear them first\n const existing = this._connectionDisposables.get(id);\n if (existing) existing.dispose();\n this._connectionDisposables.set(id, store);\n store.add(\n this.mcpConnections[id].onObservabilityEvent((event) => {\n this._onObservabilityEvent.fire(event);\n })\n );\n }\n\n // Initialize connection first\n await this.mcpConnections[id].init();\n\n // Handle OAuth completion if we have a reconnect code\n if (options.reconnect?.oauthCode) {\n try {\n await this.mcpConnections[id].completeAuthorization(\n options.reconnect.oauthCode\n );\n await this.mcpConnections[id].establishConnection();\n } catch (error) {\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Failed to complete OAuth reconnection for ${id} for ${url}`,\n payload: {\n url: url,\n transport: options.transport?.type ?? \"auto\",\n state: this.mcpConnections[id].connectionState,\n error: toErrorMessage(error)\n },\n timestamp: Date.now(),\n id\n });\n // Re-throw to signal failure to the caller\n throw error;\n }\n }\n\n // If connection is in authenticating state, return auth URL for OAuth flow\n const authUrl = options.transport?.authProvider?.authUrl;\n if (\n this.mcpConnections[id].connectionState === \"authenticating\" &&\n authUrl &&\n options.transport?.authProvider?.redirectUrl\n ) {\n this._callbackUrls.push(\n options.transport.authProvider.redirectUrl.toString()\n );\n return {\n authUrl,\n clientId: options.transport?.authProvider?.clientId,\n id\n };\n }\n\n return {\n id\n };\n }\n\n isCallbackRequest(req: Request): boolean {\n return (\n req.method === \"GET\" &&\n !!this._callbackUrls.find((url) => {\n return req.url.startsWith(url);\n })\n );\n }\n\n async handleCallbackRequest(req: Request) {\n const url = new URL(req.url);\n const urlMatch = this._callbackUrls.find((url) => {\n return req.url.startsWith(url);\n });\n if (!urlMatch) {\n throw new Error(\n `No callback URI match found for the request url: ${req.url}. Was the request matched with \\`isCallbackRequest()\\`?`\n );\n }\n const code = url.searchParams.get(\"code\");\n const state = url.searchParams.get(\"state\");\n const urlParams = urlMatch.split(\"/\");\n const serverId = urlParams[urlParams.length - 1];\n if (!code) {\n throw new Error(\"Unauthorized: no code provided\");\n }\n if (!state) {\n throw new Error(\"Unauthorized: no state provided\");\n }\n\n if (this.mcpConnections[serverId] === undefined) {\n throw new Error(`Could not find serverId: ${serverId}`);\n }\n\n if (this.mcpConnections[serverId].connectionState !== \"authenticating\") {\n throw new Error(\n \"Failed to authenticate: the client isn't in the `authenticating` state\"\n );\n }\n\n const conn = this.mcpConnections[serverId];\n if (!conn.options.transport.authProvider) {\n throw new Error(\n \"Trying to finalize authentication for a server connection without an authProvider\"\n );\n }\n\n // Get clientId from auth provider (stored during redirectToAuthorization) or fallback to state for backward compatibility\n const clientId = conn.options.transport.authProvider.clientId || state;\n\n // Set the OAuth credentials\n conn.options.transport.authProvider.clientId = clientId;\n conn.options.transport.authProvider.serverId = serverId;\n\n try {\n await conn.completeAuthorization(code);\n return {\n serverId,\n authSuccess: true\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n\n return {\n serverId,\n authSuccess: false,\n authError: errorMessage\n };\n }\n }\n\n /**\n * Establish connection in the background after OAuth completion\n * This method is called asynchronously and doesn't block the OAuth callback response\n * @param serverId The server ID to establish connection for\n */\n async establishConnection(serverId: string): Promise<void> {\n const conn = this.mcpConnections[serverId];\n if (!conn) {\n this._onObservabilityEvent.fire({\n type: \"mcp:client:preconnect\",\n displayMessage: `Connection not found for serverId: ${serverId}`,\n payload: { serverId },\n timestamp: Date.now(),\n id: nanoid()\n });\n return;\n }\n\n try {\n await conn.establishConnection();\n this._onConnected.fire(serverId);\n } catch (error) {\n const url = conn.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Failed to establish connection to server ${serverId} with url ${url}`,\n payload: {\n url,\n transport: conn.options.transport.type ?? \"auto\",\n state: conn.connectionState,\n error: toErrorMessage(error)\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n }\n }\n\n /**\n * Register a callback URL for OAuth handling\n * @param url The callback URL to register\n */\n registerCallbackUrl(url: string): void {\n if (!this._callbackUrls.includes(url)) {\n this._callbackUrls.push(url);\n }\n }\n\n /**\n * Unregister a callback URL\n * @param serverId The server ID whose callback URL should be removed\n */\n unregisterCallbackUrl(serverId: string): void {\n // Remove callback URLs that end with this serverId\n this._callbackUrls = this._callbackUrls.filter(\n (url) => !url.endsWith(`/${serverId}`)\n );\n }\n\n /**\n * Configure OAuth callback handling\n * @param config OAuth callback configuration\n */\n configureOAuthCallback(config: MCPClientOAuthCallbackConfig): void {\n this._oauthCallbackConfig = config;\n }\n\n /**\n * Get the current OAuth callback configuration\n * @returns The current OAuth callback configuration\n */\n getOAuthCallbackConfig(): MCPClientOAuthCallbackConfig | undefined {\n return this._oauthCallbackConfig;\n }\n\n /**\n * @returns namespaced list of tools\n */\n listTools(): NamespacedData[\"tools\"] {\n return getNamespacedData(this.mcpConnections, \"tools\");\n }\n\n /**\n * @returns a set of tools that you can use with the AI SDK\n */\n getAITools(): ToolSet {\n return Object.fromEntries(\n getNamespacedData(this.mcpConnections, \"tools\").map((tool) => {\n return [\n `tool_${tool.serverId.replace(/-/g, \"\")}_${tool.name}`,\n {\n description: tool.description,\n execute: async (args) => {\n const result = await this.callTool({\n arguments: args,\n name: tool.name,\n serverId: tool.serverId\n });\n if (result.isError) {\n // @ts-expect-error TODO we should fix this\n throw new Error(result.content[0].text);\n }\n return result;\n },\n // @ts-expect-error drift between ai and mcp types\n inputSchema: jsonSchema(tool.inputSchema),\n\n outputSchema: tool.outputSchema\n ? // @ts-expect-error drift between ai and mcp types\n jsonSchema(tool.outputSchema)\n : undefined\n }\n ];\n })\n );\n }\n\n /**\n * @deprecated this has been renamed to getAITools(), and unstable_getAITools will be removed in the next major version\n * @returns a set of tools that you can use with the AI SDK\n */\n unstable_getAITools(): ToolSet {\n if (!this._didWarnAboutUnstableGetAITools) {\n this._didWarnAboutUnstableGetAITools = true;\n console.warn(\n \"unstable_getAITools is deprecated, use getAITools instead. unstable_getAITools will be removed in the next major version.\"\n );\n }\n return this.getAITools();\n }\n\n /**\n * Closes all connections to MCP servers\n */\n async closeAllConnections() {\n const ids = Object.keys(this.mcpConnections);\n await Promise.all(\n ids.map(async (id) => {\n await this.mcpConnections[id].client.close();\n })\n );\n // Dispose all per-connection subscriptions\n for (const id of ids) {\n const store = this._connectionDisposables.get(id);\n if (store) store.dispose();\n this._connectionDisposables.delete(id);\n delete this.mcpConnections[id];\n }\n }\n\n /**\n * Closes a connection to an MCP server\n * @param id The id of the connection to close\n */\n async closeConnection(id: string) {\n if (!this.mcpConnections[id]) {\n throw new Error(`Connection with id \"${id}\" does not exist.`);\n }\n await this.mcpConnections[id].client.close();\n delete this.mcpConnections[id];\n\n const store = this._connectionDisposables.get(id);\n if (store) store.dispose();\n this._connectionDisposables.delete(id);\n }\n\n /**\n * Dispose the manager and all resources.\n */\n async dispose(): Promise<void> {\n try {\n await this.closeAllConnections();\n } finally {\n // Dispose manager-level emitters\n this._onConnected.dispose();\n this._onObservabilityEvent.dispose();\n }\n }\n\n /**\n * @returns namespaced list of prompts\n */\n listPrompts(): NamespacedData[\"prompts\"] {\n return getNamespacedData(this.mcpConnections, \"prompts\");\n }\n\n /**\n * @returns namespaced list of tools\n */\n listResources(): NamespacedData[\"resources\"] {\n return getNamespacedData(this.mcpConnections, \"resources\");\n }\n\n /**\n * @returns namespaced list of resource templates\n */\n listResourceTemplates(): NamespacedData[\"resourceTemplates\"] {\n return getNamespacedData(this.mcpConnections, \"resourceTemplates\");\n }\n\n /**\n * Namespaced version of callTool\n */\n async callTool(\n params: CallToolRequest[\"params\"] & { serverId: string },\n resultSchema?:\n | typeof CallToolResultSchema\n | typeof CompatibilityCallToolResultSchema,\n options?: RequestOptions\n ) {\n const unqualifiedName = params.name.replace(`${params.serverId}.`, \"\");\n return this.mcpConnections[params.serverId].client.callTool(\n {\n ...params,\n name: unqualifiedName\n },\n resultSchema,\n options\n );\n }\n\n /**\n * Namespaced version of readResource\n */\n readResource(\n params: ReadResourceRequest[\"params\"] & { serverId: string },\n options: RequestOptions\n ) {\n return this.mcpConnections[params.serverId].client.readResource(\n params,\n options\n );\n }\n\n /**\n * Namespaced version of getPrompt\n */\n getPrompt(\n params: GetPromptRequest[\"params\"] & { serverId: string },\n options: RequestOptions\n ) {\n return this.mcpConnections[params.serverId].client.getPrompt(\n params,\n options\n );\n }\n}\n\ntype NamespacedData = {\n tools: (Tool & { serverId: string })[];\n prompts: (Prompt & { serverId: string })[];\n resources: (Resource & { serverId: string })[];\n resourceTemplates: (ResourceTemplate & { serverId: string })[];\n};\n\nexport function getNamespacedData<T extends keyof NamespacedData>(\n mcpClients: Record<string, MCPClientConnection>,\n type: T\n): NamespacedData[T] {\n const sets = Object.entries(mcpClients).map(([name, conn]) => {\n return { data: conn[type], name };\n });\n\n const namespacedData = sets.flatMap(({ name: serverId, data }) => {\n return data.map((item) => {\n return {\n ...item,\n // we add a serverId so we can easily pull it out and send the tool call to the right server\n serverId\n };\n });\n });\n\n return namespacedData as NamespacedData[T]; // Type assertion needed due to TS limitations with conditional return types\n}\n","export interface Disposable {\n dispose(): void;\n}\n\nexport function toDisposable(fn: () => void): Disposable {\n return { dispose: fn };\n}\n\nexport class DisposableStore implements Disposable {\n private readonly _items: Disposable[] = [];\n\n add<T extends Disposable>(d: T): T {\n this._items.push(d);\n return d;\n }\n\n dispose(): void {\n while (this._items.length) {\n try {\n this._items.pop()!.dispose();\n } catch {\n // best-effort cleanup\n }\n }\n }\n}\n\nexport type Event<T> = (listener: (e: T) => void) => Disposable;\n\nexport class Emitter<T> implements Disposable {\n private _listeners: Set<(e: T) => void> = new Set();\n\n readonly event: Event<T> = (listener) => {\n this._listeners.add(listener);\n return toDisposable(() => this._listeners.delete(listener));\n };\n\n fire(data: T): void {\n for (const listener of [...this._listeners]) {\n try {\n listener(data);\n } catch (err) {\n // do not let one bad listener break others\n console.error(\"Emitter listener error:\", err);\n }\n }\n }\n\n dispose(): void {\n this._listeners.clear();\n }\n}\n","import { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { SSEClientTransportOptions } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport type { StreamableHTTPClientTransportOptions } from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\n// Import types directly from MCP SDK\nimport type {\n Prompt,\n Resource,\n Tool\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport {\n type ClientCapabilities,\n type ElicitRequest,\n ElicitRequestSchema,\n type ElicitResult,\n type ListPromptsResult,\n type ListResourceTemplatesResult,\n type ListResourcesResult,\n type ListToolsResult,\n PromptListChangedNotificationSchema,\n ResourceListChangedNotificationSchema,\n type ResourceTemplate,\n type ServerCapabilities,\n ToolListChangedNotificationSchema\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { nanoid } from \"nanoid\";\nimport { Emitter, type Event } from \"../core/events\";\nimport type { MCPObservabilityEvent } from \"../observability/mcp\";\nimport type { AgentsOAuthProvider } from \"./do-oauth-client-provider\";\nimport {\n isTransportNotImplemented,\n isUnauthorized,\n toErrorMessage\n} from \"./errors\";\nimport { SSEEdgeClientTransport } from \"./sse-edge\";\nimport { StreamableHTTPEdgeClientTransport } from \"./streamable-http-edge\";\nimport type { BaseTransportType, TransportType } from \"./types\";\n\n/**\n * Connection state for MCP client connections\n */\nexport type MCPConnectionState =\n | \"authenticating\"\n | \"connecting\"\n | \"ready\"\n | \"discovering\"\n | \"failed\";\n\nexport type MCPTransportOptions = (\n | SSEClientTransportOptions\n | StreamableHTTPClientTransportOptions\n) & {\n authProvider?: AgentsOAuthProvider;\n type?: TransportType;\n};\n\nexport class MCPClientConnection {\n client: Client;\n connectionState: MCPConnectionState = \"connecting\";\n lastConnectedTransport: BaseTransportType | undefined;\n instructions?: string;\n tools: Tool[] = [];\n prompts: Prompt[] = [];\n resources: Resource[] = [];\n resourceTemplates: ResourceTemplate[] = [];\n serverCapabilities: ServerCapabilities | undefined;\n\n private readonly _onObservabilityEvent = new Emitter<MCPObservabilityEvent>();\n public readonly onObservabilityEvent: Event<MCPObservabilityEvent> =\n this._onObservabilityEvent.event;\n\n constructor(\n public url: URL,\n info: ConstructorParameters<typeof Client>[0],\n public options: {\n transport: MCPTransportOptions;\n client: ConstructorParameters<typeof Client>[1];\n } = { client: {}, transport: {} }\n ) {\n const clientOptions = {\n ...options.client,\n capabilities: {\n ...options.client?.capabilities,\n elicitation: {}\n } as ClientCapabilities\n };\n\n this.client = new Client(info, clientOptions);\n }\n\n /**\n * Initialize a client connection\n *\n * @returns\n */\n async init() {\n const transportType = this.options.transport.type;\n if (!transportType) {\n throw new Error(\"Transport type must be specified\");\n }\n\n try {\n await this.tryConnect(transportType);\n } catch (e) {\n if (isUnauthorized(e)) {\n // unauthorized, we should wait for the user to authenticate\n this.connectionState = \"authenticating\";\n return;\n }\n // For explicit transport mismatches or other errors, mark as failed\n // and do not throw to avoid bubbling errors to the client runtime.\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Connection initialization failed for ${this.url.toString()}`,\n payload: {\n url: this.url.toString(),\n transport: transportType,\n state: this.connectionState,\n error: toErrorMessage(e)\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n this.connectionState = \"failed\";\n return;\n }\n\n await this.discoverAndRegister();\n }\n\n /**\n * Finish OAuth by probing transports based on configured type.\n * - Explicit: finish on that transport\n * - Auto: try streamable-http, then sse on 404/405/Not Implemented\n */\n private async finishAuthProbe(code: string): Promise<void> {\n if (!this.options.transport.authProvider) {\n throw new Error(\"No auth provider configured\");\n }\n\n const configuredType = this.options.transport.type;\n if (!configuredType) {\n throw new Error(\"Transport type must be specified\");\n }\n\n const finishAuth = async (base: BaseTransportType) => {\n const transport = this.getTransport(base);\n await transport.finishAuth(code);\n };\n\n if (configuredType === \"sse\" || configuredType === \"streamable-http\") {\n await finishAuth(configuredType);\n return;\n }\n\n // For \"auto\" mode, try streamable-http first, then fall back to SSE\n try {\n await finishAuth(\"streamable-http\");\n } catch (e) {\n if (isTransportNotImplemented(e)) {\n await finishAuth(\"sse\");\n return;\n }\n throw e;\n }\n }\n\n /**\n * Complete OAuth authorization\n */\n async completeAuthorization(code: string): Promise<void> {\n if (this.connectionState !== \"authenticating\") {\n throw new Error(\n \"Connection must be in authenticating state to complete authorization\"\n );\n }\n\n try {\n // Finish OAuth by probing transports per configuration\n await this.finishAuthProbe(code);\n\n // Mark as connecting\n this.connectionState = \"connecting\";\n } catch (error) {\n this.connectionState = \"failed\";\n throw error;\n }\n }\n\n /**\n * Establish connection after successful authorization\n */\n async establishConnection(): Promise<void> {\n if (this.connectionState !== \"connecting\") {\n throw new Error(\n \"Connection must be in connecting state to establish connection\"\n );\n }\n\n try {\n const transportType = this.options.transport.type;\n if (!transportType) {\n throw new Error(\"Transport type must be specified\");\n }\n await this.tryConnect(transportType);\n\n await this.discoverAndRegister();\n } catch (error) {\n this.connectionState = \"failed\";\n throw error;\n }\n }\n\n /**\n * Discover server capabilities and register tools, resources, prompts, and templates\n */\n private async discoverAndRegister(): Promise<void> {\n this.connectionState = \"discovering\";\n\n this.serverCapabilities = this.client.getServerCapabilities();\n if (!this.serverCapabilities) {\n throw new Error(\"The MCP Server failed to return server capabilities\");\n }\n\n const [\n instructionsResult,\n toolsResult,\n resourcesResult,\n promptsResult,\n resourceTemplatesResult\n ] = await Promise.allSettled([\n this.client.getInstructions(),\n this.registerTools(),\n this.registerResources(),\n this.registerPrompts(),\n this.registerResourceTemplates()\n ]);\n\n const operations = [\n { name: \"instructions\", result: instructionsResult },\n { name: \"tools\", result: toolsResult },\n { name: \"resources\", result: resourcesResult },\n { name: \"prompts\", result: promptsResult },\n { name: \"resource templates\", result: resourceTemplatesResult }\n ];\n\n for (const { name, result } of operations) {\n if (result.status === \"rejected\") {\n const url = this.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:discover\",\n displayMessage: `Failed to discover ${name} for ${url}`,\n payload: {\n url,\n capability: name,\n error: result.reason\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n }\n }\n\n this.instructions =\n instructionsResult.status === \"fulfilled\"\n ? instructionsResult.value\n : undefined;\n this.tools = toolsResult.status === \"fulfilled\" ? toolsResult.value : [];\n this.resources =\n resourcesResult.status === \"fulfilled\" ? resourcesResult.value : [];\n this.prompts =\n promptsResult.status === \"fulfilled\" ? promptsResult.value : [];\n this.resourceTemplates =\n resourceTemplatesResult.status === \"fulfilled\"\n ? resourceTemplatesResult.value\n : [];\n\n this.connectionState = \"ready\";\n }\n\n /**\n * Notification handler registration\n */\n async registerTools(): Promise<Tool[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.tools) {\n return [];\n }\n\n if (this.serverCapabilities.tools.listChanged) {\n this.client.setNotificationHandler(\n ToolListChangedNotificationSchema,\n async (_notification) => {\n this.tools = await this.fetchTools();\n }\n );\n }\n\n return this.fetchTools();\n }\n\n async registerResources(): Promise<Resource[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.resources) {\n return [];\n }\n\n if (this.serverCapabilities.resources.listChanged) {\n this.client.setNotificationHandler(\n ResourceListChangedNotificationSchema,\n async (_notification) => {\n this.resources = await this.fetchResources();\n }\n );\n }\n\n return this.fetchResources();\n }\n\n async registerPrompts(): Promise<Prompt[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.prompts) {\n return [];\n }\n\n if (this.serverCapabilities.prompts.listChanged) {\n this.client.setNotificationHandler(\n PromptListChangedNotificationSchema,\n async (_notification) => {\n this.prompts = await this.fetchPrompts();\n }\n );\n }\n\n return this.fetchPrompts();\n }\n\n async registerResourceTemplates(): Promise<ResourceTemplate[]> {\n if (!this.serverCapabilities || !this.serverCapabilities.resources) {\n return [];\n }\n\n return this.fetchResourceTemplates();\n }\n\n async fetchTools() {\n let toolsAgg: Tool[] = [];\n let toolsResult: ListToolsResult = { tools: [] };\n do {\n toolsResult = await this.client\n .listTools({\n cursor: toolsResult.nextCursor\n })\n .catch(this._capabilityErrorHandler({ tools: [] }, \"tools/list\"));\n toolsAgg = toolsAgg.concat(toolsResult.tools);\n } while (toolsResult.nextCursor);\n return toolsAgg;\n }\n\n async fetchResources() {\n let resourcesAgg: Resource[] = [];\n let resourcesResult: ListResourcesResult = { resources: [] };\n do {\n resourcesResult = await this.client\n .listResources({\n cursor: resourcesResult.nextCursor\n })\n .catch(\n this._capabilityErrorHandler({ resources: [] }, \"resources/list\")\n );\n resourcesAgg = resourcesAgg.concat(resourcesResult.resources);\n } while (resourcesResult.nextCursor);\n return resourcesAgg;\n }\n\n async fetchPrompts() {\n let promptsAgg: Prompt[] = [];\n let promptsResult: ListPromptsResult = { prompts: [] };\n do {\n promptsResult = await this.client\n .listPrompts({\n cursor: promptsResult.nextCursor\n })\n .catch(this._capabilityErrorHandler({ prompts: [] }, \"prompts/list\"));\n promptsAgg = promptsAgg.concat(promptsResult.prompts);\n } while (promptsResult.nextCursor);\n return promptsAgg;\n }\n\n async fetchResourceTemplates() {\n let templatesAgg: ResourceTemplate[] = [];\n let templatesResult: ListResourceTemplatesResult = {\n resourceTemplates: []\n };\n do {\n templatesResult = await this.client\n .listResourceTemplates({\n cursor: templatesResult.nextCursor\n })\n .catch(\n this._capabilityErrorHandler(\n { resourceTemplates: [] },\n \"resources/templates/list\"\n )\n );\n templatesAgg = templatesAgg.concat(templatesResult.resourceTemplates);\n } while (templatesResult.nextCursor);\n return templatesAgg;\n }\n\n /**\n * Handle elicitation request from server\n * Automatically uses the Agent's built-in elicitation handling if available\n */\n async handleElicitationRequest(\n _request: ElicitRequest\n ): Promise<ElicitResult> {\n // Elicitation handling must be implemented by the platform\n // For MCP servers, this should be handled by McpAgent.elicitInput()\n throw new Error(\n \"Elicitation handler must be implemented for your platform. Override handleElicitationRequest method.\"\n );\n }\n /**\n * Get the transport for the client\n * @param transportType - The transport type to get\n * @returns The transport for the client\n */\n getTransport(transportType: BaseTransportType) {\n switch (transportType) {\n case \"streamable-http\":\n return new StreamableHTTPEdgeClientTransport(\n this.url,\n this.options.transport as StreamableHTTPClientTransportOptions\n );\n case \"sse\":\n return new SSEEdgeClientTransport(\n this.url,\n this.options.transport as SSEClientTransportOptions\n );\n default:\n throw new Error(`Unsupported transport type: ${transportType}`);\n }\n }\n\n private async tryConnect(transportType: TransportType) {\n const transports: BaseTransportType[] =\n transportType === \"auto\" ? [\"streamable-http\", \"sse\"] : [transportType];\n\n for (const currentTransportType of transports) {\n const isLastTransport =\n currentTransportType === transports[transports.length - 1];\n const hasFallback =\n transportType === \"auto\" &&\n currentTransportType === \"streamable-http\" &&\n !isLastTransport;\n\n const transport = this.getTransport(currentTransportType);\n\n try {\n await this.client.connect(transport);\n this.lastConnectedTransport = currentTransportType;\n const url = this.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `Connected successfully using ${currentTransportType} transport for ${url}`,\n payload: {\n url,\n transport: currentTransportType,\n state: this.connectionState\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n break;\n } catch (e) {\n const error = e instanceof Error ? e : new Error(String(e));\n\n // If unauthorized, bubble up for proper auth handling\n if (isUnauthorized(error)) {\n throw e;\n }\n\n if (hasFallback && isTransportNotImplemented(error)) {\n // Try the next transport silently\n const url = this.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:connect\",\n displayMessage: `${currentTransportType} transport not available, trying ${transports[transports.indexOf(currentTransportType) + 1]} for ${url}`,\n payload: {\n url,\n transport: currentTransportType,\n state: this.connectionState\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n continue;\n }\n\n throw e;\n }\n }\n\n // Set up elicitation request handler\n this.client.setRequestHandler(\n ElicitRequestSchema,\n async (request: ElicitRequest) => {\n return await this.handleElicitationRequest(request);\n }\n );\n }\n\n private _capabilityErrorHandler<T>(empty: T, method: string) {\n return (e: { code: number }) => {\n // server is badly behaved and returning invalid capabilities. This commonly occurs for resource templates\n if (e.code === -32601) {\n const url = this.url.toString();\n this._onObservabilityEvent.fire({\n type: \"mcp:client:discover\",\n displayMessage: `The server advertised support for the capability ${method.split(\"/\")[0]}, but returned \"Method not found\" for '${method}' for ${url}`,\n payload: {\n url,\n capability: method.split(\"/\")[0],\n error: toErrorMessage(e)\n },\n timestamp: Date.now(),\n id: nanoid()\n });\n return empty;\n }\n throw e;\n };\n }\n}\n","export function toErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function isUnauthorized(error: unknown): boolean {\n const msg = toErrorMessage(error);\n return msg.includes(\"Unauthorized\") || msg.includes(\"401\");\n}\n\nexport function isTransportNotImplemented(error: unknown): boolean {\n const msg = toErrorMessage(error);\n // Treat common \"not implemented\" surfaces as transport not supported\n return (\n msg.includes(\"404\") ||\n msg.includes(\"405\") ||\n msg.includes(\"Not Implemented\") ||\n msg.includes(\"not implemented\")\n );\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport {\n SSEClientTransport,\n type SSEClientTransportOptions\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\n\nexport class SSEEdgeClientTransport extends SSEClientTransport {\n private authProvider: OAuthClientProvider | undefined;\n /**\n * Creates a new EdgeSSEClientTransport, which overrides fetch to be compatible with the CF workers environment\n */\n constructor(url: URL, options: SSEClientTransportOptions) {\n const fetchOverride: typeof fetch = async (\n fetchUrl: RequestInfo | URL,\n fetchInit: RequestInit = {}\n ) => {\n // add auth headers\n const headers = await this.authHeaders();\n const workerOptions = {\n ...fetchInit,\n headers: {\n ...options.requestInit?.headers,\n ...fetchInit?.headers,\n ...headers\n }\n };\n\n // Remove unsupported properties\n delete workerOptions.mode;\n\n // Call the original fetch with fixed options\n return (\n (options.eventSourceInit?.fetch?.(\n fetchUrl as URL | string,\n // @ts-expect-error Expects FetchLikeInit from EventSource but is compatible with RequestInit\n workerOptions\n ) as Promise<Response>) || fetch(fetchUrl, workerOptions)\n );\n };\n\n super(url, {\n ...options,\n eventSourceInit: {\n ...options.eventSourceInit,\n fetch: fetchOverride\n }\n });\n this.authProvider = options.authProvider;\n }\n\n async authHeaders() {\n if (this.authProvider) {\n const tokens = await this.authProvider.tokens();\n if (tokens) {\n return {\n Authorization: `Bearer ${tokens.access_token}`\n };\n }\n }\n }\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport {\n StreamableHTTPClientTransport,\n type StreamableHTTPClientTransportOptions\n} from \"@modelcontextprotocol/sdk/client/streamableHttp.js\";\n\nexport class StreamableHTTPEdgeClientTransport extends StreamableHTTPClientTransport {\n private authProvider: OAuthClientProvider | undefined;\n\n /**\n * Creates a new StreamableHTTPEdgeClientTransport, which overrides fetch to be compatible with the CF workers environment\n */\n constructor(url: URL, options: StreamableHTTPClientTransportOptions) {\n const fetchOverride: typeof fetch = async (\n fetchUrl: RequestInfo | URL,\n fetchInit: RequestInit = {}\n ) => {\n // add auth headers\n const headers = await this.authHeaders();\n const workerOptions = {\n ...fetchInit,\n headers: {\n ...options.requestInit?.headers,\n ...fetchInit?.headers,\n ...headers\n }\n };\n\n // Remove unsupported properties\n delete workerOptions.mode;\n\n // Call the original fetch with fixed options\n return (\n // @ts-expect-error Custom fetch function for Cloudflare Workers compatibility\n (options.requestInit?.fetch?.(\n fetchUrl as URL | string,\n workerOptions\n ) as Promise<Response>) || fetch(fetchUrl, workerOptions)\n );\n };\n\n super(url, {\n ...options,\n requestInit: {\n ...options.requestInit,\n // @ts-expect-error Custom fetch override for Cloudflare Workers\n fetch: fetchOverride\n }\n });\n this.authProvider = options.authProvider;\n }\n\n async authHeaders() {\n if (this.authProvider) {\n const tokens = await this.authProvider.tokens();\n if (tokens) {\n return {\n Authorization: `Bearer ${tokens.access_token}`\n };\n }\n }\n }\n}\n"],"mappings":"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","names":["nanoid","nanoid","url"]}