agents 0.0.0-62d4e85 → 0.0.0-63d8af8

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.
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../node_modules/@modelcontextprotocol/sdk/src/shared/protocol.ts","../../../../node_modules/@modelcontextprotocol/sdk/src/client/index.ts","../../src/mcp/client-connection.ts","../../src/mcp/client.ts"],"sourcesContent":[null,null,"import { SSEEdgeClientTransport } from \"./sse-edge\";\n\nimport {\n ToolListChangedNotificationSchema,\n type ClientCapabilities,\n type Resource,\n type Tool,\n type Prompt,\n ResourceListChangedNotificationSchema,\n PromptListChangedNotificationSchema,\n type ListToolsResult,\n type ListResourcesResult,\n type ListPromptsResult,\n type ServerCapabilities,\n type ResourceTemplate,\n type ListResourceTemplatesResult,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type {\n SSEClientTransport,\n SSEClientTransportOptions,\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\n\nexport class MCPClientConnection {\n client: Client;\n transport: SSEClientTransport;\n connected: boolean;\n instructions?: string;\n tools: Tool[];\n prompts: Prompt[];\n resources: Resource[];\n resourceTemplates: ResourceTemplate[];\n serverCapabilities: ServerCapabilities | undefined;\n\n constructor(\n url: URL,\n private info: ConstructorParameters<typeof Client>[0],\n opts: {\n transport: SSEClientTransportOptions;\n client: ConstructorParameters<typeof Client>[1];\n capabilities: ClientCapabilities;\n } = { transport: {}, client: {}, capabilities: {} }\n ) {\n this.transport = new SSEEdgeClientTransport(url, opts.transport);\n this.client = new Client(info, opts.client);\n this.client.registerCapabilities(opts.capabilities);\n this.connected = false;\n this.tools = [];\n this.prompts = [];\n this.resources = [];\n this.resourceTemplates = [];\n }\n\n async init() {\n await this.client.connect(this.transport);\n\n this.serverCapabilities = await this.client.getServerCapabilities();\n if (!this.serverCapabilities) {\n throw new Error(\n `The MCP Server ${this.info.name} failed to return server capabilities`\n );\n }\n\n const [instructions, tools, resources, prompts, resourceTemplates] =\n await Promise.all([\n this.client.getInstructions(),\n this.registerTools(),\n this.registerResources(),\n this.registerPrompts(),\n this.registerResourceTemplates(),\n ]);\n\n this.instructions = instructions;\n this.tools = tools;\n this.resources = resources;\n this.prompts = prompts;\n this.resourceTemplates = resourceTemplates;\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.listTools({\n cursor: toolsResult.nextCursor,\n });\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.listResources({\n cursor: resourcesResult.nextCursor,\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.listPrompts({\n cursor: promptsResult.nextCursor,\n });\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.listResourceTemplates({\n cursor: templatesResult.nextCursor,\n });\n templatesAgg = templatesAgg.concat(templatesResult.resourceTemplates);\n } while (templatesResult.nextCursor);\n return templatesAgg;\n }\n}\n","import { MCPClientConnection } from \"./client-connection\";\n\nimport type {\n ClientCapabilities,\n CallToolRequest,\n CallToolResultSchema,\n CompatibilityCallToolResultSchema,\n ReadResourceRequest,\n GetPromptRequest,\n Tool,\n Resource,\n ResourceTemplate,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { SSEClientTransportOptions } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport type { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { RequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\n\n/**\n * Utility class that aggregates multiple MCP clients into one\n */\nexport class MCPClientManager {\n public mcpConnections: Record<string, MCPClientConnection> = {};\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 connectToServer(\n url: URL,\n info: ConstructorParameters<typeof Client>[0],\n opts: {\n transport: SSEClientTransportOptions;\n client: ConstructorParameters<typeof Client>[1];\n capabilities: ClientCapabilities;\n } = { transport: {}, client: {}, capabilities: {} }\n ) {\n if (info.name in this.mcpConnections) {\n throw new Error(\n `An existing MCP client has already been registered under the name \"${info.name}\". The MCP client name must be unique.`\n );\n }\n\n this.mcpConnections[info.name] = new MCPClientConnection(url, info, opts);\n await this.mcpConnections[info.name].init();\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 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 callTool(\n params: CallToolRequest[\"params\"] & { serverName: string },\n resultSchema:\n | typeof CallToolResultSchema\n | typeof CompatibilityCallToolResultSchema,\n options: RequestOptions\n ) {\n const unqualifiedName = params.name.replace(`${params.serverName}.`, \"\");\n return this.mcpConnections[params.serverName].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\"] & { serverName: string },\n options: RequestOptions\n ) {\n return this.mcpConnections[params.serverName].client.readResource(\n params,\n options\n );\n }\n\n /**\n * Namespaced version of getPrompt\n */\n getPrompt(\n params: GetPromptRequest[\"params\"] & { serverName: string },\n options: RequestOptions\n ) {\n return this.mcpConnections[params.serverName].client.getPrompt(\n params,\n options\n );\n }\n}\n\ntype NamespacedData = {\n tools: (Tool & { serverName: string })[];\n prompts: (Prompt & { serverName: string })[];\n resources: (Resource & { serverName: string })[];\n resourceTemplates: (ResourceTemplate & { serverName: 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 { name, data: conn[type] };\n });\n\n const namespacedData = sets.flatMap(({ name: serverName, data }) => {\n return data.map((item) => {\n return {\n ...item,\n // we add a servername so we can easily pull it out and convert between qualified<->unqualified name\n // just in case the server name or item name includes a \".\"\n serverName: `${serverName}`,\n // qualified name\n name: `${serverName}.${item.name}`,\n };\n });\n });\n\n return namespacedData as NamespacedData[T]; // Type assertion needed due to TS limitations with conditional return types\n}\n"],"mappings":"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","names":["_a","_b"]}
1
+ {"version":3,"sources":["../../src/mcp/sse-edge.ts","../../src/mcp/client-connection.ts","../../src/mcp/do-oauth-client-provider.ts","../../src/mcp/client.ts"],"sourcesContent":["import {\n SSEClientTransport,\n type SSEClientTransportOptions,\n} from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.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 ...fetchInit?.headers,\n ...headers,\n },\n };\n\n // Remove unsupported properties\n // biome-ignore lint/performance/noDelete: workaround for workers environment\n delete workerOptions.mode;\n\n // Call the original fetch with fixed options\n return fetch(fetchUrl, workerOptions);\n };\n\n super(url, {\n ...options,\n 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 { SSEEdgeClientTransport } from \"./sse-edge\";\n\nimport {\n ToolListChangedNotificationSchema,\n type ClientCapabilities,\n type Resource,\n type Tool,\n type Prompt,\n ResourceListChangedNotificationSchema,\n PromptListChangedNotificationSchema,\n type ListToolsResult,\n type ListResourcesResult,\n type ListPromptsResult,\n type ServerCapabilities,\n type ResourceTemplate,\n type ListResourceTemplatesResult,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { SSEClientTransportOptions } from \"@modelcontextprotocol/sdk/client/sse.js\";\n\nexport class MCPClientConnection {\n client: Client;\n connectionState:\n | \"authenticating\"\n | \"connecting\"\n | \"ready\"\n | \"discovering\"\n | \"failed\" = \"connecting\";\n instructions?: string;\n tools: Tool[] = [];\n prompts: Prompt[] = [];\n resources: Resource[] = [];\n resourceTemplates: ResourceTemplate[] = [];\n serverCapabilities: ServerCapabilities | undefined;\n\n constructor(\n public url: URL,\n private info: ConstructorParameters<typeof Client>[0],\n private options: {\n transport: SSEClientTransportOptions;\n client: ConstructorParameters<typeof Client>[1];\n capabilities: ClientCapabilities;\n } = { transport: {}, client: {}, capabilities: {} }\n ) {\n this.client = new Client(info, options.client);\n this.client.registerCapabilities(options.capabilities);\n }\n\n /**\n * Initialize a client connection\n *\n * @param code Optional OAuth code to initialize the connection with if auth hasn't been initialized\n * @returns\n */\n async init(code?: string, clientId?: string) {\n try {\n const transport = new SSEEdgeClientTransport(\n this.url,\n this.options.transport\n );\n if (code) {\n await transport.finishAuth(code);\n }\n await this.client.connect(transport);\n // biome-ignore lint/suspicious/noExplicitAny: allow for the error check here\n } catch (e: any) {\n if (e.toString().includes(\"Unauthorized\")) {\n // unauthorized, we should wait for the user to authenticate\n this.connectionState = \"authenticating\";\n return;\n }\n this.connectionState = \"failed\";\n throw e;\n }\n\n this.connectionState = \"discovering\";\n\n this.serverCapabilities = await this.client.getServerCapabilities();\n if (!this.serverCapabilities) {\n throw new Error(\"The MCP Server failed to return server capabilities\");\n }\n\n const [instructions, tools, resources, prompts, resourceTemplates] =\n await Promise.all([\n this.client.getInstructions(),\n this.registerTools(),\n this.registerResources(),\n this.registerPrompts(),\n this.registerResourceTemplates(),\n ]);\n\n this.instructions = instructions;\n this.tools = tools;\n this.resources = resources;\n this.prompts = prompts;\n this.resourceTemplates = resourceTemplates;\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.listTools({\n cursor: toolsResult.nextCursor,\n });\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.listResources({\n cursor: resourcesResult.nextCursor,\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.listPrompts({\n cursor: promptsResult.nextCursor,\n });\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.listResourceTemplates({\n cursor: templatesResult.nextCursor,\n });\n templatesAgg = templatesAgg.concat(templatesResult.resourceTemplates);\n } while (templatesResult.nextCursor);\n return templatesAgg;\n }\n}\n","import type { OAuthClientProvider } from \"@modelcontextprotocol/sdk/client/auth.js\";\nimport type {\n OAuthTokens,\n OAuthClientMetadata,\n OAuthClientInformation,\n OAuthClientInformationFull,\n} from \"@modelcontextprotocol/sdk/shared/auth.js\";\n\n// A slight extension to the standard OAuthClientProvider interface because `redirectToAuthorization` doesn't give us the interface we need\nexport interface AgentsOAuthProvider extends OAuthClientProvider {\n authUrl: string | undefined;\n clientId: string | undefined;\n}\n\nexport class DurableObjectOAuthClientProvider implements AgentsOAuthProvider {\n private authUrl_: string | undefined;\n\n constructor(\n public storage: DurableObjectStorage,\n public clientName: string,\n public sessionId: string,\n public redirectUrl: string,\n private clientId_?: string\n ) {}\n\n get clientMetadata(): OAuthClientMetadata {\n return {\n redirect_uris: [this.redirectUrl],\n token_endpoint_auth_method: \"none\",\n grant_types: [\"authorization_code\", \"refresh_token\"],\n response_types: [\"code\"],\n client_name: this.clientName,\n client_uri: \"example.com\",\n };\n }\n\n get clientId() {\n if (!this.clientId_) {\n throw new Error(\"no clientId\");\n }\n return this.clientId_;\n }\n\n set clientId(clientId_: string) {\n this.clientId_ = clientId_;\n }\n\n keyPrefix(clientId: string) {\n return `/${this.clientName}/${this.sessionId}/${clientId}`;\n }\n\n clientInfoKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/client_info/`;\n }\n\n async clientInformation(): Promise<OAuthClientInformation | undefined> {\n if (!this.clientId_) {\n return undefined;\n }\n return (\n (await this.storage.get<OAuthClientInformation>(\n this.clientInfoKey(this.clientId)\n )) ?? undefined\n );\n }\n\n async saveClientInformation(\n clientInformation: OAuthClientInformationFull\n ): Promise<void> {\n await this.storage.put(\n this.clientInfoKey(clientInformation.client_id),\n clientInformation\n );\n this.clientId = clientInformation.client_id;\n }\n\n tokenKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/token`;\n }\n\n async tokens(): Promise<OAuthTokens | undefined> {\n if (!this.clientId_) {\n return undefined;\n }\n return (\n (await this.storage.get<OAuthTokens>(this.tokenKey(this.clientId))) ??\n undefined\n );\n }\n\n async saveTokens(tokens: OAuthTokens): Promise<void> {\n await this.storage.put(this.tokenKey(this.clientId), tokens);\n }\n\n get authUrl() {\n return this.authUrl_;\n }\n\n /**\n * Because this operates on the server side (but we need browser auth), we send this url back to the user\n * and require user interact to initiate the redirect flow\n */\n async redirectToAuthorization(authUrl: URL): Promise<void> {\n // We want to track the client ID in state here because the typescript SSE client sometimes does\n // a dynamic client registration AFTER generating this redirect URL.\n const client_id = authUrl.searchParams.get(\"client_id\");\n if (client_id) {\n authUrl.searchParams.append(\"state\", client_id);\n }\n this.authUrl_ = authUrl.toString();\n }\n\n codeVerifierKey(clientId: string) {\n return `${this.keyPrefix(clientId)}/code_verifier`;\n }\n\n async saveCodeVerifier(verifier: string): Promise<void> {\n await this.storage.put(this.codeVerifierKey(this.clientId), verifier);\n }\n\n async codeVerifier(): Promise<string> {\n const codeVerifier = await this.storage.get<string>(\n this.codeVerifierKey(this.clientId)\n );\n if (!codeVerifier) {\n throw new Error(\"No code verifier found\");\n }\n return codeVerifier;\n }\n}\n","import { MCPClientConnection } from \"./client-connection\";\n\nimport type {\n ClientCapabilities,\n CallToolRequest,\n CallToolResultSchema,\n CompatibilityCallToolResultSchema,\n ReadResourceRequest,\n GetPromptRequest,\n Tool,\n Resource,\n Prompt,\n ResourceTemplate,\n} from \"@modelcontextprotocol/sdk/types.js\";\nimport type { SSEClientTransportOptions } from \"@modelcontextprotocol/sdk/client/sse.js\";\nimport type { Client } from \"@modelcontextprotocol/sdk/client/index.js\";\nimport type { RequestOptions } from \"@modelcontextprotocol/sdk/shared/protocol.js\";\nimport {\n DurableObjectOAuthClientProvider,\n type AgentsOAuthProvider,\n} from \"./do-oauth-client-provider\";\n\n/**\n * Utility class that aggregates multiple MCP clients into one\n */\nexport class MCPClientManager {\n public mcpConnections: Record<string, MCPClientConnection> = {};\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 private auth?: { baseCallbackUri: string; storage: DurableObjectStorage }\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 opts: {\n // Allows you to reconnect to a server (in the case of a auth reconnect)\n // Doesn't handle session reconnection\n reconnect?: {\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?: SSEClientTransportOptions & {\n authProvider: AgentsOAuthProvider;\n };\n client?: ConstructorParameters<typeof Client>[1];\n capabilities?: ClientCapabilities;\n } = {}\n ): Promise<{ id: string; authUrl: string | undefined }> {\n const id = opts.reconnect?.id ?? crypto.randomUUID();\n\n // if we have global auth for the manager AND there's no authProvider override\n // then let's setup an auth provider\n\n if (this.auth) {\n console.warn(\n \"Using .auth configuration to generate an oauth provider, this is temporary and will be removed in the next version. Instead use transport.authProvider to provide an auth provider\"\n );\n }\n\n const authProvider: AgentsOAuthProvider | undefined = this.auth\n ? new DurableObjectOAuthClientProvider(\n this.auth.storage,\n this.name,\n id,\n `${this.auth.baseCallbackUri}/${id}`,\n opts.reconnect?.oauthClientId\n )\n : opts.transport?.authProvider;\n\n this.mcpConnections[id] = new MCPClientConnection(\n new URL(url),\n {\n name: this.name,\n version: this.version,\n },\n {\n transport: {\n ...opts.transport,\n authProvider,\n },\n client: opts.client ?? {},\n capabilities: opts.client ?? {},\n }\n );\n\n await this.mcpConnections[id].init(\n opts.reconnect?.oauthCode,\n opts.reconnect?.oauthClientId\n );\n\n return {\n id,\n authUrl: authProvider?.authUrl,\n };\n }\n\n isCallbackRequest(req: Request): boolean {\n if (this.auth?.baseCallbackUri) {\n return (\n req.url.startsWith(this.auth.baseCallbackUri) && req.method === \"GET\"\n );\n }\n return false;\n }\n\n async handleCallbackRequest(req: Request) {\n const url = new URL(req.url);\n const code = url.searchParams.get(\"code\");\n const clientId = url.searchParams.get(\"state\");\n let serverId = req.url\n .replace(this.auth!.baseCallbackUri, \"\")\n .split(\"?\")[0];\n serverId = serverId.replaceAll(\"/\", \"\");\n if (!code) {\n throw new Error(\"Unauthorized: no code provided\");\n }\n if (!clientId) {\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 // reconnect to server with authorization\n const serverUrl = this.mcpConnections[serverId].url.toString();\n await this.connect(serverUrl, {\n reconnect: {\n id: serverId,\n oauthClientId: clientId,\n oauthCode: code,\n },\n });\n\n if (this.mcpConnections[serverId].connectionState === \"authenticating\") {\n throw new Error(\"Failed to authenticate: client failed to initialize\");\n }\n\n return { serverId };\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 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 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 { name, data: conn[type] };\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"],"mappings":"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","names":[]}
@@ -19,22 +19,26 @@ declare abstract class McpAgent<Env = unknown, State = unknown, Props extends Re
19
19
  sql<T = Record<string, string | number | boolean | null>>(strings: TemplateStringsArray, ...values: (string | number | boolean | null)[]): T[];
20
20
  setState(state: State): void;
21
21
  onStateUpdate(state: State | undefined, source: Connection | "server"): void;
22
+ onStart(): Promise<void>;
22
23
  /**
23
24
  * McpAgent API
24
25
  */
25
26
  abstract server: McpServer;
26
- private transport;
27
27
  props: Props;
28
28
  initRun: boolean;
29
29
  abstract init(): Promise<void>;
30
30
  _init(props: Props): Promise<void>;
31
- onSSE(path: string): Promise<Response>;
32
- onMCPMessage(request: Request): Promise<Response>;
31
+ fetch(request: Request): Promise<Response>;
32
+ getWebSocket(): WebSocket | null;
33
+ onMCPMessage(sessionId: string, request: Request): Promise<Response>;
34
+ webSocketMessage(ws: WebSocket, event: ArrayBuffer | string): Promise<void>;
35
+ webSocketError(ws: WebSocket, error: unknown): Promise<void>;
36
+ webSocketClose(ws: WebSocket, code: number, reason: string, wasClean: boolean): Promise<void>;
33
37
  static mount(path: string, { binding, corsOptions, }?: {
34
38
  binding?: string;
35
39
  corsOptions?: CORSOptions;
36
40
  }): {
37
- fetch: (request: Request, env: Record<string, DurableObjectNamespace<McpAgent>>, ctx: ExecutionContext) => Promise<Response>;
41
+ fetch: (request: Request, env: Record<string, DurableObjectNamespace<McpAgent>>, ctx: ExecutionContext) => Promise<Response | undefined>;
38
42
  };
39
43
  }
40
44
 
package/dist/mcp/index.js CHANGED
@@ -1,12 +1,17 @@
1
1
  import {
2
2
  Agent
3
- } from "../chunk-SZEXGW6W.js";
3
+ } from "../chunk-YMUU7QHV.js";
4
4
  import {
5
- SSEEdgeServerTransport
6
- } from "../chunk-EZ76ZGDB.js";
5
+ __privateAdd,
6
+ __privateGet,
7
+ __privateMethod,
8
+ __privateSet
9
+ } from "../chunk-HMLY7DHA.js";
7
10
 
8
11
  // src/mcp/index.ts
9
12
  import { DurableObject } from "cloudflare:workers";
13
+ import { JSONRPCMessageSchema } from "@modelcontextprotocol/sdk/types.js";
14
+ var MAXIMUM_MESSAGE_SIZE = 4 * 1024 * 1024;
10
15
  function handleCORS(request, corsOptions) {
11
16
  const origin = request.headers.get("Origin") || "*";
12
17
  const corsHeaders = {
@@ -20,68 +25,208 @@ function handleCORS(request, corsOptions) {
20
25
  }
21
26
  return null;
22
27
  }
28
+ var _getWebSocket, _started;
29
+ var McpTransport = class {
30
+ constructor(getWebSocket) {
31
+ __privateAdd(this, _getWebSocket);
32
+ __privateAdd(this, _started, false);
33
+ __privateSet(this, _getWebSocket, getWebSocket);
34
+ }
35
+ async start() {
36
+ if (__privateGet(this, _started)) {
37
+ throw new Error("Transport already started");
38
+ }
39
+ __privateSet(this, _started, true);
40
+ }
41
+ async send(message) {
42
+ if (!__privateGet(this, _started)) {
43
+ throw new Error("Transport not started");
44
+ }
45
+ const websocket = __privateGet(this, _getWebSocket).call(this);
46
+ if (!websocket) {
47
+ throw new Error("WebSocket not connected");
48
+ }
49
+ try {
50
+ websocket.send(JSON.stringify(message));
51
+ } catch (error) {
52
+ this.onerror?.(error);
53
+ throw error;
54
+ }
55
+ }
56
+ async close() {
57
+ this.onclose?.();
58
+ }
59
+ };
60
+ _getWebSocket = new WeakMap();
61
+ _started = new WeakMap();
62
+ var _status, _transport, _connected, _agent, _McpAgent_instances, initialize_fn;
23
63
  var McpAgent = class extends DurableObject {
24
- /**
25
- * Since McpAgent's _aren't_ yet real "Agents" (they route differently, don't support
26
- * websockets, don't support hibernation), let's only expose a couple of the methods
27
- * to the outer class: initialState/state/setState/onStateUpdate/sql
28
- */
29
- #agent;
30
64
  constructor(ctx, env) {
65
+ var _a;
31
66
  super(ctx, env);
67
+ __privateAdd(this, _McpAgent_instances);
68
+ __privateAdd(this, _status, "zero");
69
+ __privateAdd(this, _transport);
70
+ __privateAdd(this, _connected, false);
71
+ /**
72
+ * Since McpAgent's _aren't_ yet real "Agents" (they route differently, don't support
73
+ * websockets, don't support hibernation), let's only expose a couple of the methods
74
+ * to the outer class: initialState/state/setState/onStateUpdate/sql
75
+ */
76
+ __privateAdd(this, _agent);
77
+ this.initRun = false;
32
78
  const self = this;
33
- this.#agent = new class extends Agent {
34
- static options = {
35
- hibernate: false
36
- };
79
+ __privateSet(this, _agent, new (_a = class extends Agent {
37
80
  onStateUpdate(state, source) {
38
81
  return self.onStateUpdate(state, source);
39
82
  }
40
- }(ctx, env);
83
+ }, _a.options = {
84
+ hibernate: true
85
+ }, _a)(ctx, env));
41
86
  }
42
- /**
43
- * Agents API allowlist
44
- */
45
- initialState;
46
87
  get state() {
47
- if (this.initialState) this.#agent.initialState = this.initialState;
48
- return this.#agent.state;
88
+ return __privateGet(this, _agent).state;
49
89
  }
50
90
  sql(strings, ...values) {
51
- return this.#agent.sql(strings, ...values);
91
+ return __privateGet(this, _agent).sql(strings, ...values);
52
92
  }
53
93
  setState(state) {
54
- return this.#agent.setState(state);
94
+ return __privateGet(this, _agent).setState(state);
55
95
  }
56
96
  onStateUpdate(state, source) {
57
97
  }
58
- transport;
59
- props;
60
- initRun = false;
98
+ async onStart() {
99
+ var _a;
100
+ const self = this;
101
+ __privateSet(this, _agent, new (_a = class extends Agent {
102
+ constructor() {
103
+ super(...arguments);
104
+ this.initialState = self.initialState;
105
+ }
106
+ onStateUpdate(state, source) {
107
+ return self.onStateUpdate(state, source);
108
+ }
109
+ }, _a.options = {
110
+ hibernate: true
111
+ }, _a)(this.ctx, this.env));
112
+ this.props = await this.ctx.storage.get("props");
113
+ this.init?.();
114
+ __privateSet(this, _transport, new McpTransport(() => this.getWebSocket()));
115
+ await this.server.connect(__privateGet(this, _transport));
116
+ }
61
117
  async _init(props) {
118
+ await this.ctx.storage.put("props", props);
62
119
  this.props = props;
63
120
  if (!this.initRun) {
64
121
  this.initRun = true;
65
122
  await this.init();
66
123
  }
67
124
  }
68
- async onSSE(path) {
69
- this.transport = new SSEEdgeServerTransport(
70
- `${path}/message`,
71
- this.ctx.id.toString()
72
- );
73
- await this.server.connect(this.transport);
74
- return this.transport.sseResponse;
125
+ // Allow the worker to fetch a websocket connection to the agent
126
+ async fetch(request) {
127
+ if (__privateGet(this, _status) !== "started") {
128
+ await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
129
+ }
130
+ if (request.headers.get("Upgrade") !== "websocket") {
131
+ return new Response("Expected WebSocket Upgrade request", {
132
+ status: 400
133
+ });
134
+ }
135
+ const url = new URL(request.url);
136
+ const sessionId = url.searchParams.get("sessionId");
137
+ if (!sessionId) {
138
+ return new Response("Missing sessionId", { status: 400 });
139
+ }
140
+ if (__privateGet(this, _connected)) {
141
+ return new Response("WebSocket already connected", { status: 400 });
142
+ }
143
+ const response = await __privateGet(this, _agent).fetch(request);
144
+ __privateSet(this, _connected, true);
145
+ __privateSet(this, _transport, new McpTransport(() => this.getWebSocket()));
146
+ await this.server.connect(__privateGet(this, _transport));
147
+ return response;
75
148
  }
76
- async onMCPMessage(request) {
77
- return this.transport.handlePostMessage(request);
149
+ getWebSocket() {
150
+ const websockets = this.ctx.getWebSockets();
151
+ if (websockets.length === 0) {
152
+ return null;
153
+ }
154
+ return websockets[0];
155
+ }
156
+ async onMCPMessage(sessionId, request) {
157
+ if (__privateGet(this, _status) !== "started") {
158
+ await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
159
+ }
160
+ try {
161
+ const contentType = request.headers.get("content-type") || "";
162
+ if (!contentType.includes("application/json")) {
163
+ return new Response(`Unsupported content-type: ${contentType}`, {
164
+ status: 400
165
+ });
166
+ }
167
+ const contentLength = Number.parseInt(
168
+ request.headers.get("content-length") || "0",
169
+ 10
170
+ );
171
+ if (contentLength > MAXIMUM_MESSAGE_SIZE) {
172
+ return new Response(`Request body too large: ${contentLength} bytes`, {
173
+ status: 400
174
+ });
175
+ }
176
+ const message = await request.json();
177
+ let parsedMessage;
178
+ try {
179
+ parsedMessage = JSONRPCMessageSchema.parse(message);
180
+ } catch (error) {
181
+ __privateGet(this, _transport)?.onerror?.(error);
182
+ throw error;
183
+ }
184
+ __privateGet(this, _transport)?.onmessage?.(parsedMessage);
185
+ return new Response("Accepted", { status: 202 });
186
+ } catch (error) {
187
+ __privateGet(this, _transport)?.onerror?.(error);
188
+ return new Response(String(error), { status: 400 });
189
+ }
190
+ }
191
+ // This is unused since there are no incoming websocket messages
192
+ async webSocketMessage(ws, event) {
193
+ let message;
194
+ try {
195
+ const data = typeof event === "string" ? event : new TextDecoder().decode(event);
196
+ message = JSONRPCMessageSchema.parse(JSON.parse(data));
197
+ } catch (error) {
198
+ __privateGet(this, _transport)?.onerror?.(error);
199
+ return;
200
+ }
201
+ if (__privateGet(this, _status) !== "started") {
202
+ await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
203
+ }
204
+ __privateGet(this, _transport)?.onmessage?.(message);
205
+ }
206
+ // WebSocket event handlers for hibernation support
207
+ async webSocketError(ws, error) {
208
+ if (__privateGet(this, _status) !== "started") {
209
+ await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
210
+ }
211
+ __privateGet(this, _transport)?.onerror?.(error);
212
+ }
213
+ async webSocketClose(ws, code, reason, wasClean) {
214
+ if (__privateGet(this, _status) !== "started") {
215
+ await __privateMethod(this, _McpAgent_instances, initialize_fn).call(this);
216
+ }
217
+ __privateGet(this, _transport)?.onclose?.();
218
+ __privateSet(this, _connected, false);
78
219
  }
79
220
  static mount(path, {
80
221
  binding = "MCP_OBJECT",
81
222
  corsOptions
82
223
  } = {}) {
83
- const basePattern = new URLPattern({ pathname: path });
84
- const messagePattern = new URLPattern({ pathname: `${path}/message` });
224
+ let pathname = path;
225
+ if (path === "/") {
226
+ pathname = "/*";
227
+ }
228
+ const basePattern = new URLPattern({ pathname });
229
+ const messagePattern = new URLPattern({ pathname: `${pathname}/message` });
85
230
  return {
86
231
  fetch: async (request, env, ctx) => {
87
232
  const corsResponse = handleCORS(request, corsOptions);
@@ -89,39 +234,96 @@ var McpAgent = class extends DurableObject {
89
234
  const url = new URL(request.url);
90
235
  const namespace = env[binding];
91
236
  if (request.method === "GET" && basePattern.test(url)) {
92
- const object = namespace.get(namespace.newUniqueId());
93
- await object._init(ctx.props);
94
- const response = await object.onSSE(path);
95
- const headerObj = {};
96
- response.headers.forEach((value, key) => {
97
- headerObj[key] = value;
237
+ const sessionId = url.searchParams.get("sessionId") || namespace.newUniqueId().toString();
238
+ const { readable, writable } = new TransformStream();
239
+ const writer = writable.getWriter();
240
+ const encoder = new TextEncoder();
241
+ const endpointMessage = `event: endpoint
242
+ data: ${encodeURI(`${pathname}/message`)}?sessionId=${sessionId}
243
+
244
+ `;
245
+ writer.write(encoder.encode(endpointMessage));
246
+ const id = namespace.idFromString(sessionId);
247
+ const doStub = namespace.get(id);
248
+ await doStub._init(ctx.props);
249
+ const upgradeUrl = new URL(request.url);
250
+ upgradeUrl.searchParams.set("sessionId", sessionId);
251
+ const response = await doStub.fetch(
252
+ new Request(upgradeUrl, {
253
+ headers: {
254
+ Upgrade: "websocket",
255
+ // Required by PartyServer
256
+ "x-partykit-room": sessionId
257
+ }
258
+ })
259
+ );
260
+ const ws = response.webSocket;
261
+ if (!ws) {
262
+ console.error("Failed to establish WebSocket connection");
263
+ await writer.close();
264
+ return;
265
+ }
266
+ ws.accept();
267
+ ws.addEventListener("message", async (event) => {
268
+ try {
269
+ const message = JSON.parse(event.data);
270
+ const result = JSONRPCMessageSchema.safeParse(message);
271
+ if (!result.success) {
272
+ return;
273
+ }
274
+ const messageText = `event: message
275
+ data: ${JSON.stringify(result.data)}
276
+
277
+ `;
278
+ await writer.write(encoder.encode(messageText));
279
+ } catch (error) {
280
+ console.error("Error forwarding message to SSE:", error);
281
+ }
98
282
  });
99
- headerObj["Access-Control-Allow-Origin"] = corsOptions?.origin || "*";
100
- return new Response(response.body, {
101
- status: response.status,
102
- statusText: response.statusText,
103
- headers: headerObj
283
+ ws.addEventListener("error", async (error) => {
284
+ try {
285
+ await writer.close();
286
+ } catch (e) {
287
+ }
288
+ });
289
+ ws.addEventListener("close", async () => {
290
+ try {
291
+ await writer.close();
292
+ } catch (error) {
293
+ console.error("Error closing SSE connection:", error);
294
+ }
295
+ });
296
+ return new Response(readable, {
297
+ headers: {
298
+ "Content-Type": "text/event-stream",
299
+ "Cache-Control": "no-cache",
300
+ Connection: "keep-alive",
301
+ "Access-Control-Allow-Origin": corsOptions?.origin || "*"
302
+ }
104
303
  });
105
304
  }
106
305
  if (request.method === "POST" && messagePattern.test(url)) {
107
306
  const sessionId = url.searchParams.get("sessionId");
108
307
  if (!sessionId) {
109
308
  return new Response(
110
- `Missing sessionId. Expected POST to ${path} to initiate new one`,
309
+ `Missing sessionId. Expected POST to ${pathname} to initiate new one`,
111
310
  { status: 400 }
112
311
  );
113
312
  }
114
313
  const object = namespace.get(namespace.idFromString(sessionId));
115
- const response = await object.onMCPMessage(request);
116
- const headerObj = {};
117
- response.headers.forEach((value, key) => {
118
- headerObj[key] = value;
314
+ const response = await object.onMCPMessage(sessionId, request);
315
+ const headers = new Headers();
316
+ response.headers.forEach?.((value, key) => {
317
+ headers.set(key, value);
119
318
  });
120
- headerObj["Access-Control-Allow-Origin"] = corsOptions?.origin || "*";
319
+ headers.set(
320
+ "Access-Control-Allow-Origin",
321
+ corsOptions?.origin || "*"
322
+ );
121
323
  return new Response(response.body, {
122
324
  status: response.status,
123
325
  statusText: response.statusText,
124
- headers: headerObj
326
+ headers
125
327
  });
126
328
  }
127
329
  return new Response("Not Found", { status: 404 });
@@ -129,6 +331,18 @@ var McpAgent = class extends DurableObject {
129
331
  };
130
332
  }
131
333
  };
334
+ _status = new WeakMap();
335
+ _transport = new WeakMap();
336
+ _connected = new WeakMap();
337
+ _agent = new WeakMap();
338
+ _McpAgent_instances = new WeakSet();
339
+ initialize_fn = async function() {
340
+ await this.ctx.blockConcurrencyWhile(async () => {
341
+ __privateSet(this, _status, "starting");
342
+ await this.onStart();
343
+ __privateSet(this, _status, "started");
344
+ });
345
+ };
132
346
  export {
133
347
  McpAgent
134
348
  };
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/index.ts"],"sourcesContent":["import { DurableObject } from \"cloudflare:workers\";\nimport { Agent } from \"../\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport { SSEEdgeServerTransport } from \"./sse-edge\";\nimport type { Connection } from \"../\";\n\n// CORS helper function\nfunction handleCORS(\n request: Request,\n corsOptions?: CORSOptions\n): Response | null {\n const origin = request.headers.get(\"Origin\") || \"*\";\n const corsHeaders = {\n \"Access-Control-Allow-Origin\": corsOptions?.origin || origin,\n \"Access-Control-Allow-Methods\":\n corsOptions?.methods || \"GET, POST, OPTIONS\",\n \"Access-Control-Allow-Headers\": corsOptions?.headers || \"Content-Type\",\n \"Access-Control-Max-Age\": (corsOptions?.maxAge || 86400).toString(),\n };\n\n if (request.method === \"OPTIONS\") {\n return new Response(null, { headers: corsHeaders });\n }\n\n return null;\n}\n\ninterface CORSOptions {\n origin?: string;\n methods?: string;\n headers?: string;\n maxAge?: number;\n}\n\nexport abstract class McpAgent<\n Env = unknown,\n State = unknown,\n Props extends Record<string, unknown> = Record<string, unknown>,\n> extends DurableObject<Env> {\n /**\n * Since McpAgent's _aren't_ yet real \"Agents\" (they route differently, don't support\n * websockets, don't support hibernation), let's only expose a couple of the methods\n * to the outer class: initialState/state/setState/onStateUpdate/sql\n */\n readonly #agent: Agent<Env, State>;\n protected constructor(ctx: DurableObjectState, env: Env) {\n super(ctx, env);\n const self = this;\n\n // Since McpAgent's _aren't_ yet real \"Agents\" (they route differently, they don't support\n // websockets, hibernation, scheduling etc), let's only expose a couple of the methods\n // to the outer class for now.\n this.#agent = new (class extends Agent<Env, State> {\n static options = {\n hibernate: false,\n };\n\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n return self.onStateUpdate(state, source);\n }\n })(ctx, env);\n }\n\n /**\n * Agents API allowlist\n */\n initialState!: State;\n get state() {\n if (this.initialState) this.#agent.initialState = this.initialState;\n return this.#agent.state;\n }\n sql<T = Record<string, string | number | boolean | null>>(\n strings: TemplateStringsArray,\n ...values: (string | number | boolean | null)[]\n ) {\n return this.#agent.sql<T>(strings, ...values);\n }\n\n setState(state: State) {\n return this.#agent.setState(state);\n }\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n // override this to handle state updates\n }\n\n /**\n * McpAgent API\n */\n abstract server: McpServer;\n private transport!: SSEEdgeServerTransport;\n props!: Props;\n initRun = false;\n\n abstract init(): Promise<void>;\n\n async _init(props: Props) {\n this.props = props;\n if (!this.initRun) {\n this.initRun = true;\n await this.init();\n }\n }\n\n async onSSE(path: string): Promise<Response> {\n this.transport = new SSEEdgeServerTransport(\n `${path}/message`,\n this.ctx.id.toString()\n );\n await this.server.connect(this.transport);\n return this.transport.sseResponse;\n }\n\n async onMCPMessage(request: Request): Promise<Response> {\n return this.transport.handlePostMessage(request);\n }\n\n static mount(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n }: {\n binding?: string;\n corsOptions?: CORSOptions;\n } = {}\n ) {\n const basePattern = new URLPattern({ pathname: path });\n const messagePattern = new URLPattern({ pathname: `${path}/message` });\n\n return {\n fetch: async (\n request: Request,\n env: Record<string, DurableObjectNamespace<McpAgent>>,\n ctx: ExecutionContext\n ) => {\n // Handle CORS preflight\n const corsResponse = handleCORS(request, corsOptions);\n if (corsResponse) return corsResponse;\n\n const url = new URL(request.url);\n const namespace = env[binding];\n\n if (request.method === \"GET\" && basePattern.test(url)) {\n const object = namespace.get(namespace.newUniqueId());\n // @ts-ignore\n await object._init(ctx.props);\n const response = await object.onSSE(path);\n\n // Convert headers to a plain object\n const headerObj: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n headerObj[key] = value;\n });\n headerObj[\"Access-Control-Allow-Origin\"] = corsOptions?.origin || \"*\";\n\n // Clone the response to get a new body stream\n // const clonedResponse = response.clone();\n return new Response(response.body as unknown as BodyInit, {\n status: response.status,\n statusText: response.statusText,\n headers: headerObj,\n });\n }\n\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 ${path} to initiate new one`,\n { status: 400 }\n );\n }\n const object = namespace.get(namespace.idFromString(sessionId));\n const response = await object.onMCPMessage(request);\n\n // Convert headers to a plain object\n const headerObj: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n headerObj[key] = value;\n });\n headerObj[\"Access-Control-Allow-Origin\"] = corsOptions?.origin || \"*\";\n\n return new Response(response.body as unknown as BodyInit, {\n status: response.status,\n statusText: response.statusText,\n headers: headerObj,\n });\n }\n\n return new Response(\"Not Found\", { status: 404 });\n },\n };\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/mcp/index.ts"],"sourcesContent":["import { DurableObject } from \"cloudflare:workers\";\nimport { Agent } from \"../\";\nimport type { McpServer } from \"@modelcontextprotocol/sdk/server/mcp.js\";\nimport type { Connection } from \"../\";\nimport type { JSONRPCMessage } from \"@modelcontextprotocol/sdk/types.js\";\nimport { JSONRPCMessageSchema } from \"@modelcontextprotocol/sdk/types.js\";\nimport type { Transport } from \"@modelcontextprotocol/sdk/shared/transport.js\";\n\nconst MAXIMUM_MESSAGE_SIZE = 4 * 1024 * 1024; // 4MB\n\n// CORS helper function\nfunction handleCORS(\n request: Request,\n corsOptions?: CORSOptions\n): Response | null {\n const origin = request.headers.get(\"Origin\") || \"*\";\n const corsHeaders = {\n \"Access-Control-Allow-Origin\": corsOptions?.origin || origin,\n \"Access-Control-Allow-Methods\":\n corsOptions?.methods || \"GET, POST, OPTIONS\",\n \"Access-Control-Allow-Headers\": corsOptions?.headers || \"Content-Type\",\n \"Access-Control-Max-Age\": (corsOptions?.maxAge || 86400).toString(),\n };\n\n if (request.method === \"OPTIONS\") {\n return new Response(null, { headers: corsHeaders });\n }\n\n return null;\n}\n\ninterface CORSOptions {\n origin?: string;\n methods?: string;\n headers?: string;\n maxAge?: number;\n}\n\nclass McpTransport implements Transport {\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n sessionId?: string;\n\n #getWebSocket: () => WebSocket | null;\n #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 throw 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 abstract class McpAgent<\n Env = unknown,\n State = unknown,\n Props extends Record<string, unknown> = Record<string, unknown>,\n> extends DurableObject<Env> {\n #status: \"zero\" | \"starting\" | \"started\" = \"zero\";\n #transport?: McpTransport;\n #connected = false;\n\n /**\n * Since McpAgent's _aren't_ yet real \"Agents\" (they route differently, don't support\n * websockets, don't support hibernation), let's only expose a couple of the methods\n * to the outer class: initialState/state/setState/onStateUpdate/sql\n */\n #agent: Agent<Env, State>;\n\n protected constructor(ctx: DurableObjectState, env: Env) {\n super(ctx, env);\n const self = this;\n\n this.#agent = new (class extends Agent<Env, State> {\n static options = {\n hibernate: true,\n };\n\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n return self.onStateUpdate(state, source);\n }\n })(ctx, env);\n }\n\n /**\n * Agents API allowlist\n */\n initialState!: State;\n get state() {\n return this.#agent.state;\n }\n sql<T = Record<string, string | number | boolean | null>>(\n strings: TemplateStringsArray,\n ...values: (string | number | boolean | null)[]\n ) {\n return this.#agent.sql<T>(strings, ...values);\n }\n\n setState(state: State) {\n return this.#agent.setState(state);\n }\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n // override this to handle state updates\n }\n async onStart() {\n const self = this;\n\n this.#agent = new (class extends Agent<Env, State> {\n initialState: State = self.initialState;\n static options = {\n hibernate: true,\n };\n\n onStateUpdate(state: State | undefined, source: Connection | \"server\") {\n return self.onStateUpdate(state, source);\n }\n })(this.ctx, this.env);\n\n this.props = (await this.ctx.storage.get(\"props\")) as Props;\n this.init?.();\n\n // Connect to the MCP server\n this.#transport = new McpTransport(() => this.getWebSocket());\n await this.server.connect(this.#transport);\n }\n\n /**\n * McpAgent API\n */\n abstract server: McpServer;\n props!: Props;\n initRun = false;\n\n abstract init(): Promise<void>;\n\n async _init(props: Props) {\n await this.ctx.storage.put(\"props\", props);\n this.props = props;\n if (!this.initRun) {\n this.initRun = true;\n await this.init();\n }\n }\n\n async #initialize(): Promise<void> {\n await this.ctx.blockConcurrencyWhile(async () => {\n this.#status = \"starting\";\n await this.onStart();\n this.#status = \"started\";\n });\n }\n\n // Allow the worker to fetch a websocket connection to the agent\n async fetch(request: Request): Promise<Response> {\n if (this.#status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this.#initialize();\n }\n\n // Only handle WebSocket upgrade requests\n if (request.headers.get(\"Upgrade\") !== \"websocket\") {\n return new Response(\"Expected WebSocket Upgrade request\", {\n status: 400,\n });\n }\n\n const url = new URL(request.url);\n const sessionId = url.searchParams.get(\"sessionId\");\n if (!sessionId) {\n return new Response(\"Missing sessionId\", { status: 400 });\n }\n\n // For now, each agent can only have one connection\n // If we get an upgrade while already connected, we should error\n if (this.#connected) {\n return new Response(\"WebSocket already connected\", { status: 400 });\n }\n\n // Defer to the Agent's fetch method to handle the WebSocket connection\n // PartyServer does a lot to manage the connections under the hood\n const response = await this.#agent.fetch(request);\n\n this.#connected = true;\n\n // Connect to the MCP server\n this.#transport = new McpTransport(() => this.getWebSocket());\n await this.server.connect(this.#transport);\n\n return response;\n }\n\n getWebSocket() {\n const websockets = this.ctx.getWebSockets();\n if (websockets.length === 0) {\n return null;\n }\n return websockets[0];\n }\n\n async onMCPMessage(sessionId: string, request: Request): Promise<Response> {\n if (this.#status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this.#initialize();\n }\n try {\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) {\n return new Response(`Request body too large: ${contentLength} bytes`, {\n status: 400,\n });\n }\n\n // Clone the request before reading the body to avoid stream issues\n const message = await request.json();\n let parsedMessage: JSONRPCMessage;\n try {\n parsedMessage = JSONRPCMessageSchema.parse(message);\n } catch (error) {\n this.#transport?.onerror?.(error as Error);\n throw error;\n }\n\n this.#transport?.onmessage?.(parsedMessage);\n return new Response(\"Accepted\", { status: 202 });\n } catch (error) {\n this.#transport?.onerror?.(error as Error);\n return new Response(String(error), { status: 400 });\n }\n }\n\n // This is unused since there are no incoming websocket messages\n async webSocketMessage(ws: WebSocket, event: ArrayBuffer | string) {\n let message: JSONRPCMessage;\n try {\n // Ensure event is a string\n const data =\n typeof event === \"string\" ? event : new TextDecoder().decode(event);\n message = JSONRPCMessageSchema.parse(JSON.parse(data));\n } catch (error) {\n this.#transport?.onerror?.(error as Error);\n return;\n }\n\n if (this.#status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this.#initialize();\n }\n\n this.#transport?.onmessage?.(message);\n }\n\n // WebSocket event handlers for hibernation support\n async webSocketError(ws: WebSocket, error: unknown): Promise<void> {\n if (this.#status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this.#initialize();\n }\n this.#transport?.onerror?.(error as Error);\n }\n\n async webSocketClose(\n ws: WebSocket,\n code: number,\n reason: string,\n wasClean: boolean\n ): Promise<void> {\n if (this.#status !== \"started\") {\n // This means the server \"woke up\" after hibernation\n // so we need to hydrate it again\n await this.#initialize();\n }\n this.#transport?.onclose?.();\n this.#connected = false;\n }\n\n static mount(\n path: string,\n {\n binding = \"MCP_OBJECT\",\n corsOptions,\n }: {\n binding?: string;\n corsOptions?: CORSOptions;\n } = {}\n ) {\n let pathname = path;\n if (path === \"/\") {\n pathname = \"/*\";\n }\n const basePattern = new URLPattern({ pathname });\n const messagePattern = new URLPattern({ pathname: `${pathname}/message` });\n\n return {\n fetch: async (\n request: Request,\n env: Record<string, DurableObjectNamespace<McpAgent>>,\n ctx: ExecutionContext\n ) => {\n // Handle CORS preflight\n const corsResponse = handleCORS(request, corsOptions);\n if (corsResponse) return corsResponse;\n\n const url = new URL(request.url);\n const namespace = env[binding];\n\n // Handle SSE connections\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\") ||\n 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 endpointMessage = `event: endpoint\\ndata: ${encodeURI(`${pathname}/message`)}?sessionId=${sessionId}\\n\\n`;\n writer.write(encoder.encode(endpointMessage));\n\n // Get the Durable Object\n const id = namespace.idFromString(sessionId);\n const doStub = namespace.get(id);\n\n // Initialize the object\n await doStub._init(ctx.props);\n\n // Connect to the Durable Object via WebSocket\n const upgradeUrl = new URL(request.url);\n upgradeUrl.searchParams.set(\"sessionId\", sessionId);\n const response = await doStub.fetch(\n new Request(upgradeUrl, {\n headers: {\n Upgrade: \"websocket\",\n // Required by PartyServer\n \"x-partykit-room\": sessionId,\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;\n }\n\n // Accept the WebSocket\n ws.accept();\n\n // Handle messages from the Durable Object\n ws.addEventListener(\"message\", async (event) => {\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\n // Handle WebSocket errors\n ws.addEventListener(\"error\", async (error) => {\n try {\n await writer.close();\n } catch (e) {\n // Ignore errors when closing\n }\n });\n\n // Handle WebSocket closure\n ws.addEventListener(\"close\", async () => {\n try {\n await writer.close();\n } catch (error) {\n console.error(\"Error closing SSE connection:\", error);\n }\n });\n\n // Return the SSE response\n return new Response(readable, {\n headers: {\n \"Content-Type\": \"text/event-stream\",\n \"Cache-Control\": \"no-cache\",\n Connection: \"keep-alive\",\n \"Access-Control-Allow-Origin\": corsOptions?.origin || \"*\",\n },\n });\n }\n\n // Handle MCP messages\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 ${pathname} to initiate new one`,\n { status: 400 }\n );\n }\n\n // Get the Durable Object\n const object = namespace.get(namespace.idFromString(sessionId));\n\n // Forward the request to the Durable Object\n const response = await object.onMCPMessage(sessionId, request);\n\n // Add CORS headers\n const headers = new Headers();\n response.headers.forEach?.((value, key) => {\n headers.set(key, value);\n });\n headers.set(\n \"Access-Control-Allow-Origin\",\n corsOptions?.origin || \"*\"\n );\n\n return new Response(response.body as unknown as BodyInit, {\n status: response.status,\n statusText: response.statusText,\n headers,\n });\n }\n\n return new Response(\"Not Found\", { status: 404 });\n },\n };\n }\n}\n"],"mappings":"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","names":[]}