@particle-academy/agent-integrations 0.41.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/README.md +29 -0
  2. package/dist/bridges/artboard.d.cts +2 -2
  3. package/dist/bridges/artboard.d.ts +2 -2
  4. package/dist/bridges/catalog.d.cts +2 -2
  5. package/dist/bridges/catalog.d.ts +2 -2
  6. package/dist/bridges/charts.d.cts +2 -2
  7. package/dist/bridges/charts.d.ts +2 -2
  8. package/dist/bridges/cms.d.cts +2 -2
  9. package/dist/bridges/cms.d.ts +2 -2
  10. package/dist/bridges/code.d.cts +2 -2
  11. package/dist/bridges/code.d.ts +2 -2
  12. package/dist/bridges/doc.d.cts +2 -2
  13. package/dist/bridges/doc.d.ts +2 -2
  14. package/dist/bridges/features.d.cts +2 -2
  15. package/dist/bridges/features.d.ts +2 -2
  16. package/dist/bridges/files.d.cts +2 -2
  17. package/dist/bridges/files.d.ts +2 -2
  18. package/dist/bridges/flow.d.cts +2 -2
  19. package/dist/bridges/flow.d.ts +2 -2
  20. package/dist/bridges/forms.d.cts +2 -2
  21. package/dist/bridges/forms.d.ts +2 -2
  22. package/dist/bridges/git.d.cts +2 -2
  23. package/dist/bridges/git.d.ts +2 -2
  24. package/dist/bridges/grid.d.cts +2 -2
  25. package/dist/bridges/grid.d.ts +2 -2
  26. package/dist/bridges/map.d.cts +2 -2
  27. package/dist/bridges/map.d.ts +2 -2
  28. package/dist/bridges/passkeys.d.cts +2 -2
  29. package/dist/bridges/passkeys.d.ts +2 -2
  30. package/dist/bridges/scene.d.cts +2 -2
  31. package/dist/bridges/scene.d.ts +2 -2
  32. package/dist/bridges/screens.d.cts +2 -2
  33. package/dist/bridges/screens.d.ts +2 -2
  34. package/dist/bridges/sheets.d.cts +2 -2
  35. package/dist/bridges/sheets.d.ts +2 -2
  36. package/dist/bridges/slides.d.cts +2 -2
  37. package/dist/bridges/slides.d.ts +2 -2
  38. package/dist/bridges/terminal.d.cts +2 -2
  39. package/dist/bridges/terminal.d.ts +2 -2
  40. package/dist/bridges/tui.d.cts +1 -1
  41. package/dist/bridges/tui.d.ts +1 -1
  42. package/dist/bridges/whiteboard.d.cts +2 -2
  43. package/dist/bridges/whiteboard.d.ts +2 -2
  44. package/dist/bridges-artboard.cjs.map +1 -1
  45. package/dist/bridges-artboard.js +2 -2
  46. package/dist/bridges-catalog.cjs.map +1 -1
  47. package/dist/bridges-catalog.js +3 -3
  48. package/dist/bridges-charts.cjs.map +1 -1
  49. package/dist/bridges-charts.js +3 -3
  50. package/dist/bridges-cms.cjs.map +1 -1
  51. package/dist/bridges-cms.js +4 -4
  52. package/dist/bridges-code.cjs.map +1 -1
  53. package/dist/bridges-code.js +3 -3
  54. package/dist/bridges-doc.cjs.map +1 -1
  55. package/dist/bridges-doc.js +3 -3
  56. package/dist/bridges-features.cjs.map +1 -1
  57. package/dist/bridges-features.js +3 -3
  58. package/dist/bridges-files.cjs.map +1 -1
  59. package/dist/bridges-files.js +3 -3
  60. package/dist/bridges-flow.cjs.map +1 -1
  61. package/dist/bridges-flow.js +2 -2
  62. package/dist/bridges-forms.cjs.map +1 -1
  63. package/dist/bridges-forms.js +3 -3
  64. package/dist/bridges-git.cjs.map +1 -1
  65. package/dist/bridges-git.js +3 -3
  66. package/dist/bridges-grid.cjs.map +1 -1
  67. package/dist/bridges-grid.js +3 -3
  68. package/dist/bridges-map.cjs.map +1 -1
  69. package/dist/bridges-map.js +3 -3
  70. package/dist/bridges-passkeys.cjs.map +1 -1
  71. package/dist/bridges-passkeys.js +3 -3
  72. package/dist/bridges-scene.cjs.map +1 -1
  73. package/dist/bridges-scene.js +3 -3
  74. package/dist/bridges-screens.cjs.map +1 -1
  75. package/dist/bridges-screens.js +3 -3
  76. package/dist/bridges-sheets.cjs.map +1 -1
  77. package/dist/bridges-sheets.js +3 -3
  78. package/dist/bridges-slides.cjs.map +1 -1
  79. package/dist/bridges-slides.js +3 -3
  80. package/dist/bridges-terminal.cjs.map +1 -1
  81. package/dist/bridges-terminal.js +3 -3
  82. package/dist/bridges-tui.cjs.map +1 -1
  83. package/dist/bridges-tui.js +2 -2
  84. package/dist/bridges-whiteboard.cjs.map +1 -1
  85. package/dist/bridges-whiteboard.js +3 -3
  86. package/dist/{chunk-2U5JB6ZA.js → chunk-2LSU3NFO.js} +4 -4
  87. package/dist/{chunk-2U5JB6ZA.js.map → chunk-2LSU3NFO.js.map} +1 -1
  88. package/dist/{chunk-PR4SXFZH.js → chunk-2Q4EGZHJ.js} +4 -4
  89. package/dist/{chunk-PR4SXFZH.js.map → chunk-2Q4EGZHJ.js.map} +1 -1
  90. package/dist/{chunk-G5EZNWXJ.js → chunk-5W6YOXLT.js} +4 -4
  91. package/dist/{chunk-G5EZNWXJ.js.map → chunk-5W6YOXLT.js.map} +1 -1
  92. package/dist/{chunk-CA7GIJJC.js → chunk-7LLMILTM.js} +4 -4
  93. package/dist/{chunk-CA7GIJJC.js.map → chunk-7LLMILTM.js.map} +1 -1
  94. package/dist/{chunk-MFMBR6LN.js → chunk-E2I3YVKC.js} +3 -3
  95. package/dist/{chunk-MFMBR6LN.js.map → chunk-E2I3YVKC.js.map} +1 -1
  96. package/dist/{chunk-USQGA672.js → chunk-EIBV76IB.js} +4 -4
  97. package/dist/{chunk-USQGA672.js.map → chunk-EIBV76IB.js.map} +1 -1
  98. package/dist/{chunk-WCKSDFTM.js → chunk-GT63LSPJ.js} +4 -4
  99. package/dist/{chunk-WCKSDFTM.js.map → chunk-GT63LSPJ.js.map} +1 -1
  100. package/dist/{chunk-CT3LRNH7.js → chunk-HVDHT7DM.js} +3 -3
  101. package/dist/{chunk-CT3LRNH7.js.map → chunk-HVDHT7DM.js.map} +1 -1
  102. package/dist/{chunk-7THGQUX3.js → chunk-LOD77NCD.js} +4 -4
  103. package/dist/{chunk-7THGQUX3.js.map → chunk-LOD77NCD.js.map} +1 -1
  104. package/dist/{chunk-BHQJJ2YG.js → chunk-MZ74LLDS.js} +4 -4
  105. package/dist/{chunk-BHQJJ2YG.js.map → chunk-MZ74LLDS.js.map} +1 -1
  106. package/dist/{chunk-D756GBMQ.js → chunk-N5VOPV64.js} +4 -4
  107. package/dist/{chunk-D756GBMQ.js.map → chunk-N5VOPV64.js.map} +1 -1
  108. package/dist/{chunk-ZNGTC4CO.js → chunk-NIFPRC7P.js} +4 -4
  109. package/dist/{chunk-ZNGTC4CO.js.map → chunk-NIFPRC7P.js.map} +1 -1
  110. package/dist/{chunk-JJUABMAP.js → chunk-NIXOY473.js} +3 -3
  111. package/dist/{chunk-JJUABMAP.js.map → chunk-NIXOY473.js.map} +1 -1
  112. package/dist/{chunk-OAFJ53X3.js → chunk-NKAH67JK.js} +4 -4
  113. package/dist/{chunk-OAFJ53X3.js.map → chunk-NKAH67JK.js.map} +1 -1
  114. package/dist/{chunk-RIXYCFDO.js → chunk-PCFRBVKS.js} +4 -4
  115. package/dist/{chunk-RIXYCFDO.js.map → chunk-PCFRBVKS.js.map} +1 -1
  116. package/dist/{chunk-4D3II37O.js → chunk-PUMQDV67.js} +4 -4
  117. package/dist/{chunk-4D3II37O.js.map → chunk-PUMQDV67.js.map} +1 -1
  118. package/dist/{chunk-DF3PLL2E.js → chunk-QJYRWEXD.js} +28 -5
  119. package/dist/chunk-QJYRWEXD.js.map +1 -0
  120. package/dist/{chunk-GRHPEK6M.js → chunk-QOANLXSW.js} +53 -8
  121. package/dist/chunk-QOANLXSW.js.map +1 -0
  122. package/dist/{chunk-XY2TDE6E.js → chunk-SXVRIIXW.js} +4 -4
  123. package/dist/{chunk-XY2TDE6E.js.map → chunk-SXVRIIXW.js.map} +1 -1
  124. package/dist/{chunk-6YUBWQTS.js → chunk-TEB5U6Y5.js} +4 -4
  125. package/dist/{chunk-6YUBWQTS.js.map → chunk-TEB5U6Y5.js.map} +1 -1
  126. package/dist/{chunk-MJ2S25ON.js → chunk-VJD3Y7E5.js} +4 -4
  127. package/dist/{chunk-MJ2S25ON.js.map → chunk-VJD3Y7E5.js.map} +1 -1
  128. package/dist/{chunk-BT7HM5I6.js → chunk-WEXMZMJH.js} +3 -3
  129. package/dist/{chunk-BT7HM5I6.js.map → chunk-WEXMZMJH.js.map} +1 -1
  130. package/dist/{chunk-UZHNKUER.js → chunk-Z4L2GOAK.js} +4 -4
  131. package/dist/{chunk-UZHNKUER.js.map → chunk-Z4L2GOAK.js.map} +1 -1
  132. package/dist/components-shared-whiteboard.cjs +26 -3
  133. package/dist/components-shared-whiteboard.cjs.map +1 -1
  134. package/dist/components-shared-whiteboard.js +3 -3
  135. package/dist/index.cjs +88 -3
  136. package/dist/index.cjs.map +1 -1
  137. package/dist/index.d.cts +88 -8
  138. package/dist/index.d.ts +88 -8
  139. package/dist/index.js +87 -26
  140. package/dist/index.js.map +1 -1
  141. package/dist/mcp/index.d.cts +3 -3
  142. package/dist/mcp/index.d.ts +3 -3
  143. package/dist/mcp.cjs +26 -3
  144. package/dist/mcp.cjs.map +1 -1
  145. package/dist/mcp.js +1 -1
  146. package/dist/relay-server/index.d.cts +36 -1
  147. package/dist/relay-server/index.d.ts +36 -1
  148. package/dist/relay-server-cli.cjs +51 -6
  149. package/dist/relay-server-cli.cjs.map +1 -1
  150. package/dist/relay-server-cli.js +1 -1
  151. package/dist/relay-server.cjs +51 -6
  152. package/dist/relay-server.cjs.map +1 -1
  153. package/dist/relay-server.js +1 -1
  154. package/dist/{server-DDD3IZ56.d.cts → server-BJNF7pQe.d.cts} +1 -1
  155. package/dist/{server-CDX643Kz.d.ts → server-Dt97UxuD.d.ts} +1 -1
  156. package/dist/sharing/index.d.cts +2 -2
  157. package/dist/sharing/index.d.ts +2 -2
  158. package/dist/sheets-adapter.d.cts +2 -2
  159. package/dist/sheets-adapter.d.ts +2 -2
  160. package/dist/{tool-host-EuYHYSSH.d.cts → tool-host-BpEBqf5u.d.cts} +17 -0
  161. package/dist/{tool-host-CWTOJEm2.d.ts → tool-host-xY5F-eqG.d.ts} +17 -0
  162. package/dist/{types-NFGP769G.d.cts → types-C4NaIW6B.d.cts} +1 -1
  163. package/dist/{types-BKD6uf86.d.ts → types-DSwsNTBG.d.ts} +1 -1
  164. package/dist/undo/index.d.cts +1 -1
  165. package/dist/undo/index.d.ts +1 -1
  166. package/dist/undo.cjs.map +1 -1
  167. package/dist/undo.js +3 -3
  168. package/docs/relay-server.md +34 -0
  169. package/package.json +1 -1
  170. package/dist/chunk-DF3PLL2E.js.map +0 -1
  171. package/dist/chunk-GRHPEK6M.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/mcp/types.ts","../src/mcp/tool-host.ts","../src/mcp/server.ts"],"names":[],"mappings":"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","file":"chunk-DF3PLL2E.js","sourcesContent":["/**\n * Minimal MCP (Model Context Protocol) types — covers the subset this\n * package implements: initialize, tools/list, tools/call, plus JSON-RPC.\n *\n * Aligned with the public MCP spec but trimmed to v0.1 needs. See\n * https://spec.modelcontextprotocol.io/ for the full surface.\n */\n\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | { [key: string]: JsonValue }\n | JsonValue[];\n\nexport type JsonObject = { [key: string]: JsonValue };\n\nexport type JsonRpcId = string | number | null;\n\nexport type JsonRpcRequest = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n method: string;\n params?: JsonObject;\n};\n\nexport type JsonRpcNotification = {\n jsonrpc: \"2.0\";\n method: string;\n params?: JsonObject;\n};\n\nexport type JsonRpcSuccess = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n result: JsonValue;\n};\n\nexport type JsonRpcError = {\n jsonrpc: \"2.0\";\n id: JsonRpcId;\n error: { code: number; message: string; data?: JsonValue };\n};\n\nexport type JsonRpcMessage = JsonRpcRequest | JsonRpcNotification | JsonRpcSuccess | JsonRpcError;\n\nexport const JSONRPC_PARSE_ERROR = -32700;\nexport const JSONRPC_INVALID_REQUEST = -32600;\nexport const JSONRPC_METHOD_NOT_FOUND = -32601;\nexport const JSONRPC_INVALID_PARAMS = -32602;\nexport const JSONRPC_INTERNAL_ERROR = -32603;\n\nexport type ServerCapabilities = {\n tools?: { listChanged?: boolean };\n resources?: { listChanged?: boolean; subscribe?: boolean };\n prompts?: { listChanged?: boolean };\n logging?: Record<string, never>;\n experimental?: Record<string, JsonValue>;\n};\n\nexport type ServerInfo = {\n name: string;\n version: string;\n title?: string;\n};\n\nexport type InitializeResult = {\n protocolVersion: string;\n capabilities: ServerCapabilities;\n serverInfo: ServerInfo;\n instructions?: string;\n};\n\nexport type ToolInputSchema = {\n type: \"object\";\n properties?: Record<string, JsonValue>;\n required?: string[];\n additionalProperties?: boolean;\n};\n\nexport type ToolDefinition = {\n name: string;\n title?: string;\n description?: string;\n inputSchema: ToolInputSchema;\n};\n\nexport type ContentBlock =\n | { type: \"text\"; text: string }\n | { type: \"image\"; data: string; mimeType: string }\n | { type: \"resource\"; resource: { uri: string; text?: string; mimeType?: string } };\n\nexport type CallToolResult = {\n content: ContentBlock[];\n isError?: boolean;\n /** Structured tool output — non-spec but useful for typed bridges. */\n structuredContent?: JsonValue;\n};\n\n/** Handler signature for a tool registered on the MicroMcpServer. */\nexport type ToolCallContext = { transport?: unknown };\nexport type ToolHandler = (args: JsonObject, context?: ToolCallContext) => Promise<CallToolResult> | CallToolResult;\n\n/** Internal record kept by the server. */\nexport type RegisteredTool = {\n definition: ToolDefinition;\n handler: ToolHandler;\n};\n\nexport const MCP_PROTOCOL_VERSION = \"2025-06-18\";\n","import type {\n CallToolResult,\n JsonObject,\n RegisteredTool,\n ToolDefinition,\n ToolHandler,\n} from \"./types\";\n\n/**\n * ToolHost — the minimal surface a bridge needs to register its tools.\n *\n * Bridges (whiteboard, flow, sheets, code, charts, screens, scene, form)\n * speak only through this interface. The MCP server implements it\n * alongside its transport / JSON-RPC duties, and the standalone\n * {@link ToolRegistry} implements it for in-process agents that don't\n * need any of MCP's wire framing.\n *\n * Net effect: every bridge works equally well behind an MCP server\n * (browser ↔ external agents over SSE) or behind a plain registry\n * (in-process agent calling `host.callTool(\"sheet_set_cell\", { … })`).\n */\nexport interface ToolHost {\n /** Register a tool. Returns a disposer that unregisters it. */\n registerTool(definition: ToolDefinition, handler: ToolHandler): () => void;\n\n /** Look up an already-registered tool's definition + handler, or null. */\n getTool(name: string): RegisteredTool | null;\n\n /** Snapshot of all currently-registered tool definitions. */\n listTools(): ToolDefinition[];\n\n /**\n * Invoke a registered tool directly, bypassing any transport layer.\n * Throws if no tool is registered under `name`.\n *\n * This is the single entry point in-process agents use to drive the\n * surface — no JSON-RPC framing, no transport plumbing.\n */\n callTool(name: string, args?: JsonObject): Promise<CallToolResult>;\n}\n\n/**\n * Standalone in-memory ToolHost. Use this when no MCP server is needed —\n * e.g. an in-process agent that just wants to register the same bridges\n * and call them directly.\n *\n * Example:\n *\n * const host = new ToolRegistry();\n * registerSheetsBridge(host, { adapter });\n * const result = await host.callTool(\"sheet_set_cell\", { address: \"B3\", value: 42 });\n *\n * Pair with a MicroMcpServer in the same app to expose the same tools\n * to remote agents over SSE while in-process agents still get\n * zero-overhead direct calls.\n */\nexport class ToolRegistry implements ToolHost {\n protected readonly tools = new Map<string, RegisteredTool>();\n\n registerTool(definition: ToolDefinition, handler: ToolHandler): () => void {\n this.tools.set(definition.name, { definition, handler });\n this.onToolsChanged();\n return () => {\n if (this.tools.delete(definition.name)) this.onToolsChanged();\n };\n }\n\n getTool(name: string): RegisteredTool | null {\n return this.tools.get(name) ?? null;\n }\n\n listTools(): ToolDefinition[] {\n return Array.from(this.tools.values()).map((t) => t.definition);\n }\n\n async callTool(name: string, args: JsonObject = {}): Promise<CallToolResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n throw new Error(`Unknown tool: ${name}`);\n }\n return tool.handler(args);\n }\n\n /**\n * Hook for subclasses (e.g. MicroMcpServer) to notify subscribers\n * when the tool catalog changes. Default no-op.\n */\n protected onToolsChanged(): void {}\n}\n","import {\n type CallToolResult,\n type JsonObject,\n type JsonRpcMessage,\n type JsonRpcRequest,\n type JsonRpcId,\n type RegisteredTool,\n type ServerCapabilities,\n type ServerInfo,\n type ToolDefinition,\n type ToolHandler,\n JSONRPC_INTERNAL_ERROR,\n JSONRPC_INVALID_PARAMS,\n JSONRPC_METHOD_NOT_FOUND,\n MCP_PROTOCOL_VERSION,\n} from \"./types\";\nimport { ToolRegistry } from \"./tool-host\";\n\nexport type McpServerOptions = {\n info: ServerInfo;\n /** Defaults to { tools: { listChanged: true } } */\n capabilities?: ServerCapabilities;\n /** Free-text instructions surfaced to clients during initialize. */\n instructions?: string;\n};\n\nexport type Transport = {\n /** Called by the server when it has a message to deliver to the client. */\n send: (message: JsonRpcMessage) => void;\n /** Called by the server when it's torn down so the transport can clean up. */\n close?: () => void;\n};\n\n/**\n * MicroMcpServer — protocol-level MCP server, transport-agnostic.\n *\n * Use it like:\n *\n * const server = new MicroMcpServer({ info: { name: \"session\", version: \"0.1\" } });\n * server.registerTool({ name: \"...\", inputSchema: { type: \"object\" } }, async (args) => ({...}));\n * const transport = new InProcessTransport();\n * server.attach(transport);\n * transport.deliver({ ... }); // client → server frames\n *\n * The same server can serve multiple transports (e.g. an in-process agent\n * AND a relayed external client) by attaching each one.\n */\nexport class MicroMcpServer extends ToolRegistry {\n private transports = new Set<Transport>();\n private notifyListChangedScheduled = false;\n\n readonly info: ServerInfo;\n readonly capabilities: ServerCapabilities;\n readonly instructions?: string;\n\n constructor(options: McpServerOptions) {\n super();\n this.info = options.info;\n this.capabilities = options.capabilities ?? { tools: { listChanged: true } };\n this.instructions = options.instructions;\n }\n\n attach(transport: Transport): () => void {\n this.transports.add(transport);\n return () => this.detach(transport);\n }\n\n detach(transport: Transport): void {\n if (this.transports.delete(transport)) {\n transport.close?.();\n }\n }\n\n unregisterTool(name: string): void {\n if (this.tools.delete(name)) {\n this.scheduleListChangedNotification();\n }\n }\n\n protected onToolsChanged(): void {\n this.scheduleListChangedNotification();\n }\n\n /**\n * Receive a JSON-RPC frame from a client (called by the transport).\n * The transport is responsible for sending the response back.\n */\n async receive(transport: Transport, message: JsonRpcMessage): Promise<void> {\n if (!(\"method\" in message)) return; // It's a response, not a request — ignore.\n\n const isNotification = !(\"id\" in message);\n if (isNotification) {\n // Notifications are fire-and-forget. We ignore unknown methods.\n return;\n }\n\n const request = message as JsonRpcRequest;\n try {\n const result = await this.handle(request, transport);\n transport.send({ jsonrpc: \"2.0\", id: request.id, result });\n } catch (err) {\n transport.send({\n jsonrpc: \"2.0\",\n id: request.id,\n error: this.toRpcError(err),\n });\n }\n }\n\n private async handle(request: JsonRpcRequest, transport: Transport): Promise<any> {\n const { method, params } = request;\n switch (method) {\n case \"initialize\":\n return {\n protocolVersion: MCP_PROTOCOL_VERSION,\n capabilities: this.capabilities,\n serverInfo: this.info,\n ...(this.instructions ? { instructions: this.instructions } : {}),\n };\n\n case \"tools/list\":\n return { tools: this.listTools() };\n\n case \"tools/call\": {\n const name = params?.name;\n const args = (params?.arguments ?? {}) as JsonObject;\n if (typeof name !== \"string\") {\n throw rpcError(JSONRPC_INVALID_PARAMS, \"tools/call requires `name`\");\n }\n const tool = this.tools.get(name);\n if (!tool) {\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unknown tool: ${name}`);\n }\n const result = await tool.handler(args, { transport });\n return result satisfies CallToolResult;\n }\n\n case \"ping\":\n return {};\n\n default:\n throw rpcError(JSONRPC_METHOD_NOT_FOUND, `Unsupported method: ${method}`);\n }\n }\n\n private scheduleListChangedNotification(): void {\n if (this.notifyListChangedScheduled) return;\n this.notifyListChangedScheduled = true;\n queueMicrotask(() => {\n this.notifyListChangedScheduled = false;\n this.broadcast({ jsonrpc: \"2.0\", method: \"notifications/tools/list_changed\" });\n });\n }\n\n /** Send an application notification to every client, or one attached transport. */\n notify(message: JsonRpcMessage, transport?: Transport): void {\n if (transport) transport.send(message);\n else this.broadcast(message);\n }\n\n private broadcast(message: JsonRpcMessage): void {\n for (const t of this.transports) t.send(message);\n }\n\n private toRpcError(err: unknown): { code: number; message: string; data?: any } {\n if (err && typeof err === \"object\" && \"code\" in err && \"message\" in err) {\n return err as any;\n }\n return {\n code: JSONRPC_INTERNAL_ERROR,\n message: err instanceof Error ? err.message : String(err),\n };\n }\n}\n\nexport function rpcError(code: number, message: string, data?: any) {\n return { code, message, ...(data !== undefined ? { data } : {}) };\n}\n\n/**\n * Helper to build a CallToolResult from a string or structured value.\n */\nexport function textResult(text: string, structured?: any): CallToolResult {\n return {\n content: [{ type: \"text\", text }],\n ...(structured !== undefined ? { structuredContent: structured } : {}),\n };\n}\n\nexport function errorResult(text: string): CallToolResult {\n return { content: [{ type: \"text\", text }], isError: true };\n}\n\n// Internal helper so the JsonRpcId import isn't dropped by tsup\ntype _KeepIdImport = JsonRpcId;\n"]}
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/relay-server/core.ts","../src/relay-server/node.ts"],"names":["next","ok"],"mappings":"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","file":"chunk-GRHPEK6M.js","sourcesContent":["import { createHash, randomBytes, timingSafeEqual } from \"node:crypto\";\n\n/**\n * RelayBroker — pure logic for the SSE+POST tunnel described in\n * docs/relay-protocol.md, hostable in any Node-compatible runtime\n * (Node, Bun, Deno-with-Node-compat, Cloudflare Workers via the Web\n * standards subset). No HTTP framework opinions; this class just\n * stores sessions, validates tokens, enqueues frames, and produces\n * SSE event payloads ready to flush.\n *\n * const broker = new RelayBroker();\n * const reg = broker.register(\"session-id\", \"token\"); // ok / error\n * broker.inbox(\"session-id\", \"token\", '{\"jsonrpc\":\"2.0\",…}'); // enqueue inbound\n * const sub = broker.subscribe(\"session-id\", \"token\", \"inbound\");\n * for await (const payload of sub.frames()) yield encodeSse(payload);\n *\n * Storage is an in-memory Map by default — fine for a single relay\n * process. To run multiple instances behind a load balancer, swap\n * `MemoryStore` for a Redis-backed equivalent (same Store interface).\n */\n\nexport type Direction = \"inbound\" | \"outbound\";\n\nexport type Session = {\n id: string;\n /** SHA-256 hex of the original token. Compared with timing-safe equals. */\n tokenHash: string;\n /** Last touched (ms since epoch). Used for TTL cleanup. */\n lastSeen: number;\n};\n\nexport type Subscriber = {\n id: string;\n direction: Direction;\n queue: string[];\n resolveNext: ((frame: string | null) => void) | null;\n};\n\nexport type RelayBrokerOptions = {\n /** Sessions auto-expire after this many ms of inactivity. Default 4h. */\n ttlMs?: number;\n /** Cleanup tick interval in ms. Default 60 000. */\n reapIntervalMs?: number;\n /** Bring-your-own storage layer (redis, etc.). Defaults to in-memory. */\n store?: Store;\n};\n\nexport interface Store {\n putSession(s: Session): void;\n getSession(id: string): Session | undefined;\n deleteSession(id: string): void;\n /** Used by the reap tick — return ids whose lastSeen < cutoff. */\n expiredSessionIds(cutoff: number): string[];\n}\n\nclass MemoryStore implements Store {\n private sessions = new Map<string, Session>();\n putSession(s: Session) { this.sessions.set(s.id, s); }\n getSession(id: string) { return this.sessions.get(id); }\n deleteSession(id: string) { this.sessions.delete(id); }\n expiredSessionIds(cutoff: number) {\n const out: string[] = [];\n for (const [id, s] of this.sessions) if (s.lastSeen < cutoff) out.push(id);\n return out;\n }\n}\n\nconst SESSION_ID_PATTERN = /^[A-Za-z0-9_-]{4,64}$/;\n\nexport class RelayBroker {\n private readonly ttlMs: number;\n private readonly store: Store;\n /** Per-session, per-direction subscriber list. */\n private subs: Map<string, Map<string, Map<string, Subscriber>>> = new Map();\n private reaper?: ReturnType<typeof setInterval>;\n\n constructor(opts: RelayBrokerOptions = {}) {\n this.ttlMs = opts.ttlMs ?? 4 * 60 * 60 * 1000; // 4h\n this.store = opts.store ?? new MemoryStore();\n const tick = opts.reapIntervalMs ?? 60_000;\n if (tick > 0) {\n this.reaper = setInterval(() => this.reap(), tick);\n // Don't keep the process alive just for the reaper.\n if (typeof (this.reaper as { unref?: () => void }).unref === \"function\") {\n (this.reaper as { unref: () => void }).unref();\n }\n }\n }\n\n dispose() {\n if (this.reaper) clearInterval(this.reaper);\n this.subs.clear();\n }\n\n /** Register a session id + token. Idempotent — same id+token re-registers,\n * different token fails. */\n register(id: string, token: string): { ok: true } | { ok: false; reason: string } {\n if (!SESSION_ID_PATTERN.test(id)) return { ok: false, reason: \"invalid_session_id\" };\n if (typeof token !== \"string\" || token.length < 16 || token.length > 128) {\n return { ok: false, reason: \"invalid_token\" };\n }\n const existing = this.store.getSession(id);\n const hash = sha256Hex(token);\n if (existing) {\n if (!timingSafeEqualHex(existing.tokenHash, hash)) return { ok: false, reason: \"session_taken\" };\n existing.lastSeen = Date.now();\n this.store.putSession(existing);\n return { ok: true };\n }\n this.store.putSession({ id, tokenHash: hash, lastSeen: Date.now() });\n return { ok: true };\n }\n\n unregister(id: string, token: string): boolean {\n if (!this.validate(id, token)) return false;\n this.store.deleteSession(id);\n this.subs.delete(id);\n return true;\n }\n\n /** Validate an authenticated touch and slide the TTL forward. */\n validate(id: string, token: string): boolean {\n if (!id || !token) return false;\n const s = this.store.getSession(id);\n if (!s) return false;\n if (!timingSafeEqualHex(s.tokenHash, sha256Hex(token))) return false;\n s.lastSeen = Date.now();\n this.store.putSession(s);\n return true;\n }\n\n /** Push a frame onto the inbound queue (external agent → browser). */\n inbox(id: string, token: string, payload: string): boolean {\n if (!this.validate(id, token)) return false;\n if (!this.isFrame(payload)) return false;\n this.fanOut(id, \"inbound\", payload);\n return true;\n }\n\n /** Push a frame onto the outbound queue (browser server → external agents). */\n outbox(id: string, token: string, payload: string): boolean {\n if (!this.validate(id, token)) return false;\n if (!this.isFrame(payload)) return false;\n this.fanOut(id, \"outbound\", payload);\n return true;\n }\n\n /**\n * Subscribe to a session's queue for one direction. Returns an iterable\n * the caller (an HTTP handler) pumps as SSE.\n */\n subscribe(id: string, token: string, direction: Direction): SubscribeResult {\n if (!this.validate(id, token)) return { ok: false, reason: \"invalid_token\" };\n const subscriberId = randomBytes(8).toString(\"hex\");\n const subscriber: Subscriber = { id: subscriberId, direction, queue: [], resolveNext: null };\n this.getDirSubs(id, direction).set(subscriberId, subscriber);\n\n // Notify the inbound side (= browser) that an outbound subscriber\n // (= external agent) just connected.\n if (direction === \"outbound\") {\n this.fanOut(\n id,\n \"inbound\",\n JSON.stringify({\n jsonrpc: \"2.0\",\n method: \"notifications/peer_joined\",\n params: { subscriberId, ts: Date.now() },\n }),\n );\n }\n\n const unsubscribe = () => {\n this.getDirSubs(id, direction).delete(subscriberId);\n if (direction === \"outbound\") {\n this.fanOut(\n id,\n \"inbound\",\n JSON.stringify({\n jsonrpc: \"2.0\",\n method: \"notifications/peer_left\",\n params: { subscriberId, ts: Date.now() },\n }),\n );\n }\n };\n\n /** Async generator the HTTP handler drains. Yields raw frame payloads;\n * the handler is responsible for SSE framing (`event: mcp\\ndata: …`). */\n const frames = async function* (this: Subscriber): AsyncGenerator<string, void, void> {\n while (true) {\n if (this.queue.length > 0) {\n const next = this.queue.shift();\n if (next !== undefined) yield next;\n continue;\n }\n const next = await new Promise<string | null>((resolve) => {\n this.resolveNext = resolve;\n });\n this.resolveNext = null;\n if (next === null) return;\n yield next;\n }\n }.bind(subscriber);\n\n return {\n ok: true,\n subscriberId,\n frames: frames(),\n unsubscribe: () => {\n // Wake the generator and let it return cleanly.\n subscriber.resolveNext?.(null);\n unsubscribe();\n },\n };\n }\n\n // ────────────────────────────────────────────────────────────── internals\n\n private getDirSubs(sessionId: string, direction: Direction): Map<string, Subscriber> {\n let bySession = this.subs.get(sessionId);\n if (!bySession) {\n bySession = new Map();\n this.subs.set(sessionId, bySession);\n }\n let byDir = bySession.get(direction);\n if (!byDir) {\n byDir = new Map();\n bySession.set(direction, byDir);\n }\n return byDir;\n }\n\n private fanOut(sessionId: string, direction: Direction, payload: string) {\n const dir = this.subs.get(sessionId)?.get(direction);\n if (!dir) return;\n for (const sub of dir.values()) {\n sub.queue.push(payload);\n sub.resolveNext?.(sub.queue.shift() ?? null);\n }\n }\n\n /**\n * Validate that a peer-supplied payload is a well-formed JSON-RPC 2.0 frame\n * (or batch) before it is fanned out. Previously this was a substring match on\n * `\"jsonrpc\"`, which let any token holder inject spoofed frames — a forged\n * `notifications/peer_joined` / `peer_left` (broker-reserved presence control),\n * a fake `notifications/agent_activity {source:\"user\"}` (\"human took control\"),\n * or a forged response with a matching id. We now parse + shape-check, and\n * reject the broker-reserved control methods (the broker emits those itself,\n * never a peer).\n */\n private isFrame(payload: string): boolean {\n if (payload.length === 0) return false;\n let parsed: unknown;\n try {\n parsed = JSON.parse(payload);\n } catch {\n return false;\n }\n const frames = Array.isArray(parsed) ? parsed : [parsed];\n return frames.length > 0 && frames.every((f) => this.isValidFrame(f));\n }\n\n private isValidFrame(f: unknown): boolean {\n if (!f || typeof f !== \"object\" || Array.isArray(f)) return false;\n const o = f as Record<string, unknown>;\n if (o.jsonrpc !== \"2.0\") return false;\n const method = typeof o.method === \"string\" ? o.method : undefined;\n // Broker-reserved control frames may never arrive from a peer.\n if (method === \"notifications/peer_joined\" || method === \"notifications/peer_left\") return false;\n if (method !== undefined) return true; // request or notification\n // Response: needs an id and exactly one of result / error.\n const hasResult = \"result\" in o;\n const hasError = \"error\" in o;\n return \"id\" in o && hasResult !== hasError;\n }\n\n private reap() {\n const cutoff = Date.now() - this.ttlMs;\n for (const id of this.store.expiredSessionIds(cutoff)) {\n const dirs = this.subs.get(id);\n if (dirs) {\n for (const dir of dirs.values()) {\n for (const sub of dir.values()) sub.resolveNext?.(null);\n }\n }\n this.subs.delete(id);\n this.store.deleteSession(id);\n }\n }\n}\n\nexport type SubscribeResult =\n | { ok: false; reason: string }\n | {\n ok: true;\n subscriberId: string;\n frames: AsyncGenerator<string, void, void>;\n unsubscribe: () => void;\n };\n\nfunction sha256Hex(input: string): string {\n return createHash(\"sha256\").update(input).digest(\"hex\");\n}\n\nfunction timingSafeEqualHex(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n return timingSafeEqual(Buffer.from(a, \"hex\"), Buffer.from(b, \"hex\"));\n}\n","import type { IncomingMessage, ServerResponse } from \"node:http\";\nimport { URL } from \"node:url\";\nimport { RelayBroker, type RelayBrokerOptions } from \"./core\";\n\n/**\n * Node HTTP adapter for {@link RelayBroker}. Returns a single request\n * handler plus per-route handlers, so you can either drop it into\n * `http.createServer(...)` directly or mount the individual handlers\n * onto your existing Node HTTP framework (Express, Hono w/ node-adapter,\n * native http).\n *\n * const relay = createNodeRelay({ pathPrefix: \"/mcp-relay\" });\n * http.createServer(relay.handler).listen(8787);\n *\n * // Or piecemeal:\n * app.post(\"/mcp-relay/register\", relay.register);\n * app.post(\"/mcp-relay/:s/inbox\", relay.inbox);\n * app.post(\"/mcp-relay/:s/outbox\", relay.outbox);\n * app.get (\"/mcp-relay/:s/events\", relay.events);\n * app.post(\"/mcp-relay/:s/unregister\", relay.unregister);\n */\n\nexport type NodeRelayOptions = RelayBrokerOptions & {\n /** URL path prefix (without trailing slash). Default `\"\"` — handlers\n * expect paths like `/register`, `/{id}/inbox`, etc. directly. */\n pathPrefix?: string;\n /** Comma-separated origins (or `*`) for CORS. Default `*` — relays\n * are typically called cross-origin from the demo host. */\n corsAllowOrigin?: string;\n /**\n * Strict browser-origin allow-list. When set, only these Origins get a\n * matching `Access-Control-Allow-Origin` (the request's own Origin is\n * reflected, never `*`), which blunts DNS-rebinding + hostile cross-origin\n * pages from reading relay responses. Recommended for any browser-facing\n * deployment. When unset, `corsAllowOrigin` (default `*`) is used and the\n * session token is the only auth — pair that with a loopback bind.\n */\n allowedOrigins?: string[];\n};\n\nexport type NodeHandler = (req: IncomingMessage, res: ServerResponse) => unknown | Promise<unknown>;\n\nexport type NodeRelay = {\n broker: RelayBroker;\n /** Single-handler shape — routes internally based on method + URL. */\n handler: NodeHandler;\n /** Per-route handlers. Each handler ignores the URL prefix and\n * acts on the path remainder, so you can mount them under any\n * prefix in your existing app. */\n register: NodeHandler;\n inbox: NodeHandler;\n outbox: NodeHandler;\n events: NodeHandler;\n unregister: NodeHandler;\n};\n\nexport function createNodeRelay(opts: NodeRelayOptions = {}): NodeRelay {\n const broker = new RelayBroker(opts);\n const prefix = (opts.pathPrefix ?? \"\").replace(/\\/$/, \"\");\n const cors = opts.corsAllowOrigin ?? \"*\";\n\n const allowedOrigins = opts.allowedOrigins;\n\n function setCorsHeaders(res: ServerResponse, req?: IncomingMessage) {\n if (allowedOrigins && allowedOrigins.length) {\n // Strict mode: reflect the request Origin only when it's allow-listed;\n // otherwise emit an origin that no browser will match.\n const origin = req?.headers.origin;\n res.setHeader(\"access-control-allow-origin\", origin && allowedOrigins.includes(origin) ? origin : \"null\");\n res.setHeader(\"vary\", \"origin\");\n } else {\n res.setHeader(\"access-control-allow-origin\", cors);\n }\n res.setHeader(\"access-control-allow-methods\", \"GET, POST, OPTIONS\");\n // `authorization` is forward-compat for a header-borne session token.\n res.setHeader(\"access-control-allow-headers\", \"content-type, x-csrf-token, accept, authorization\");\n res.setHeader(\"access-control-max-age\", \"86400\");\n }\n\n function readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolve, reject) => {\n const chunks: Buffer[] = [];\n let bytes = 0;\n req.on(\"data\", (chunk: Buffer) => {\n bytes += chunk.length;\n // Cap individual frames at 256 KB — protect against runaway payloads.\n if (bytes > 256 * 1024) {\n reject(new Error(\"payload_too_large\"));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on(\"end\", () => resolve(Buffer.concat(chunks).toString(\"utf8\")));\n req.on(\"error\", reject);\n });\n }\n\n function json(res: ServerResponse, status: number, body: unknown): void {\n res.statusCode = status;\n res.setHeader(\"content-type\", \"application/json\");\n res.end(JSON.stringify(body));\n }\n\n function getQuery(req: IncomingMessage): URLSearchParams {\n const host = req.headers.host || \"x\";\n const u = new URL(req.url || \"/\", `http://${host}`);\n return u.searchParams;\n }\n\n function getPathname(req: IncomingMessage): string {\n const host = req.headers.host || \"x\";\n const u = new URL(req.url || \"/\", `http://${host}`);\n return u.pathname;\n }\n\n const register: NodeHandler = async (req, res) => {\n setCorsHeaders(res, req);\n if (req.method === \"OPTIONS\") { res.statusCode = 204; return res.end(); }\n if (req.method !== \"POST\") return json(res, 405, { error: \"method_not_allowed\" });\n let body: string;\n try { body = await readBody(req); } catch (e) {\n return json(res, 413, { error: e instanceof Error ? e.message : \"payload_error\" });\n }\n let parsed: unknown;\n try { parsed = JSON.parse(body); } catch { return json(res, 400, { error: \"invalid_json\" }); }\n const { session, token } = (parsed ?? {}) as { session?: string; token?: string };\n if (typeof session !== \"string\" || typeof token !== \"string\") {\n return json(res, 400, { error: \"missing_fields\" });\n }\n const result = broker.register(session, token);\n if (!result.ok) return json(res, 401, { error: result.reason });\n return json(res, 200, { ok: true });\n };\n\n /** Handler for endpoints with a `{session}` segment. The path matcher\n * caller passes the session id explicitly so this works mounted under\n * any route shape. */\n function makeSessionHandler(\n direction: Direction | \"unregister\",\n ): NodeHandler {\n return async (req, res) => {\n setCorsHeaders(res, req);\n if (req.method === \"OPTIONS\") { res.statusCode = 204; return res.end(); }\n if (req.method !== \"POST\") return json(res, 405, { error: \"method_not_allowed\" });\n const session = extractSession(req, prefix);\n if (!session) return json(res, 400, { error: \"missing_session\" });\n const token = getQuery(req).get(\"token\") ?? \"\";\n\n if (direction === \"unregister\") {\n const ok = broker.unregister(session, token);\n return json(res, ok ? 200 : 401, ok ? { ok: true } : { error: \"invalid_token\" });\n }\n\n let body: string;\n try { body = await readBody(req); } catch (e) {\n return json(res, 413, { error: e instanceof Error ? e.message : \"payload_error\" });\n }\n const ok = direction === \"inbound\"\n ? broker.inbox(session, token, body)\n : broker.outbox(session, token, body);\n return json(res, ok ? 200 : 401, ok ? { ok: true } : { error: \"invalid_token_or_frame\" });\n };\n }\n\n const inbox = makeSessionHandler(\"inbound\");\n const outbox = makeSessionHandler(\"outbound\");\n const unregister = makeSessionHandler(\"unregister\");\n\n const events: NodeHandler = async (req, res) => {\n setCorsHeaders(res, req);\n if (req.method === \"OPTIONS\") { res.statusCode = 204; return res.end(); }\n if (req.method !== \"GET\") return json(res, 405, { error: \"method_not_allowed\" });\n const session = extractSession(req, prefix);\n if (!session) return json(res, 400, { error: \"missing_session\" });\n const q = getQuery(req);\n const token = q.get(\"token\") ?? \"\";\n const direction = q.get(\"direction\") === \"outbound\" ? \"outbound\" : \"inbound\";\n\n const sub = broker.subscribe(session, token, direction);\n if (!sub.ok) {\n res.statusCode = 401;\n res.setHeader(\"content-type\", \"text/event-stream\");\n res.write(`event: error\\ndata: ${sub.reason}\\n\\n`);\n return res.end();\n }\n\n res.statusCode = 200;\n res.setHeader(\"content-type\", \"text/event-stream\");\n res.setHeader(\"cache-control\", \"no-cache\");\n res.setHeader(\"connection\", \"keep-alive\");\n res.setHeader(\"x-accel-buffering\", \"no\");\n res.write(\"retry: 2000\\n\\n\");\n flush(res);\n\n let heartbeat: ReturnType<typeof setInterval> | null = setInterval(() => {\n res.write(\": keepalive\\n\\n\");\n flush(res);\n }, 15_000);\n if (heartbeat && typeof (heartbeat as { unref?: () => void }).unref === \"function\") {\n (heartbeat as { unref: () => void }).unref();\n }\n\n const cleanup = () => {\n if (heartbeat) { clearInterval(heartbeat); heartbeat = null; }\n sub.unsubscribe();\n };\n req.on(\"close\", cleanup);\n req.on(\"error\", cleanup);\n\n try {\n for await (const frame of sub.frames) {\n res.write(`event: mcp\\ndata: ${frame}\\n\\n`);\n flush(res);\n }\n } catch {\n /* stream ended */\n } finally {\n cleanup();\n res.end();\n }\n };\n\n /**\n * Single handler — routes based on method + path. Useful for mounting\n * via `http.createServer(relay.handler)` without an Express layer.\n */\n const handler: NodeHandler = async (req, res) => {\n const pathname = getPathname(req);\n if (!pathname.startsWith(prefix + \"/\")) {\n return json(res, 404, { error: \"not_found\" });\n }\n const rest = pathname.slice(prefix.length); // \"/register\", \"/<id>/inbox\", etc.\n if (rest === \"/register\") return register(req, res);\n const m = /^\\/([A-Za-z0-9_-]{4,64})\\/(inbox|outbox|events|unregister)$/.exec(rest);\n if (!m) return json(res, 404, { error: \"not_found\" });\n const route = m[2];\n if (route === \"inbox\") return inbox(req, res);\n if (route === \"outbox\") return outbox(req, res);\n if (route === \"events\") return events(req, res);\n if (route === \"unregister\") return unregister(req, res);\n return json(res, 404, { error: \"not_found\" });\n };\n\n return { broker, handler, register, inbox, outbox, events, unregister };\n}\n\nfunction extractSession(req: IncomingMessage, prefix: string): string | null {\n const host = req.headers.host || \"x\";\n const u = new URL(req.url || \"/\", `http://${host}`);\n const path = u.pathname;\n if (prefix && !path.startsWith(prefix + \"/\")) return null;\n const rest = prefix ? path.slice(prefix.length) : path;\n const m = /^\\/([A-Za-z0-9_-]{4,64})\\//.exec(rest);\n return m ? m[1] : null;\n}\n\nfunction flush(res: ServerResponse) {\n // Node doesn't expose explicit flush, but write returns false when buffered;\n // explicit flushHeaders + write is enough for SSE in practice.\n const r = res as { flush?: () => void };\n r.flush?.();\n}\n\ntype Direction = \"inbound\" | \"outbound\";\n"]}