@agent-native/core 0.20.9 → 0.22.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 (196) hide show
  1. package/dist/action.d.ts +61 -0
  2. package/dist/action.d.ts.map +1 -1
  3. package/dist/action.js +14 -0
  4. package/dist/action.js.map +1 -1
  5. package/dist/agent/production-agent.d.ts +4 -0
  6. package/dist/agent/production-agent.d.ts.map +1 -1
  7. package/dist/agent/production-agent.js +19 -7
  8. package/dist/agent/production-agent.js.map +1 -1
  9. package/dist/agent/types.d.ts +2 -0
  10. package/dist/agent/types.d.ts.map +1 -1
  11. package/dist/agent/types.js.map +1 -1
  12. package/dist/cli/code-agent-executor.d.ts.map +1 -1
  13. package/dist/cli/code-agent-executor.js +1 -0
  14. package/dist/cli/code-agent-executor.js.map +1 -1
  15. package/dist/cli/connect.d.ts +18 -3
  16. package/dist/cli/connect.d.ts.map +1 -1
  17. package/dist/cli/connect.js +619 -19
  18. package/dist/cli/connect.js.map +1 -1
  19. package/dist/client/AgentPanel.d.ts.map +1 -1
  20. package/dist/client/AgentPanel.js +6 -2
  21. package/dist/client/AgentPanel.js.map +1 -1
  22. package/dist/client/AssistantChat.d.ts.map +1 -1
  23. package/dist/client/AssistantChat.js +13 -6
  24. package/dist/client/AssistantChat.js.map +1 -1
  25. package/dist/client/NewWorkspaceAppFlow.js +1 -1
  26. package/dist/client/NewWorkspaceAppFlow.js.map +1 -1
  27. package/dist/client/agent-chat.d.ts.map +1 -1
  28. package/dist/client/agent-chat.js +13 -8
  29. package/dist/client/agent-chat.js.map +1 -1
  30. package/dist/client/agent-sidebar-state.d.ts +2 -0
  31. package/dist/client/agent-sidebar-state.d.ts.map +1 -1
  32. package/dist/client/agent-sidebar-state.js +40 -0
  33. package/dist/client/agent-sidebar-state.js.map +1 -1
  34. package/dist/client/code-agent-chat-adapter.js +1 -0
  35. package/dist/client/code-agent-chat-adapter.js.map +1 -1
  36. package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
  37. package/dist/client/conversation/AgentConversation.js +3 -2
  38. package/dist/client/conversation/AgentConversation.js.map +1 -1
  39. package/dist/client/conversation/code-agent-transcript.js +1 -0
  40. package/dist/client/conversation/code-agent-transcript.js.map +1 -1
  41. package/dist/client/conversation/types.d.ts +2 -0
  42. package/dist/client/conversation/types.d.ts.map +1 -1
  43. package/dist/client/conversation/types.js.map +1 -1
  44. package/dist/client/index.d.ts +1 -0
  45. package/dist/client/index.d.ts.map +1 -1
  46. package/dist/client/index.js +1 -0
  47. package/dist/client/index.js.map +1 -1
  48. package/dist/client/mcp-apps/McpAppRenderer.d.ts +10 -0
  49. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -0
  50. package/dist/client/mcp-apps/McpAppRenderer.js +301 -0
  51. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -0
  52. package/dist/client/sse-event-processor.d.ts +3 -0
  53. package/dist/client/sse-event-processor.d.ts.map +1 -1
  54. package/dist/client/sse-event-processor.js +2 -0
  55. package/dist/client/sse-event-processor.js.map +1 -1
  56. package/dist/client/use-db-sync.d.ts +5 -5
  57. package/dist/client/use-db-sync.d.ts.map +1 -1
  58. package/dist/client/use-db-sync.js +15 -5
  59. package/dist/client/use-db-sync.js.map +1 -1
  60. package/dist/client/use-db-sync.spec.d.ts +2 -0
  61. package/dist/client/use-db-sync.spec.d.ts.map +1 -0
  62. package/dist/client/use-db-sync.spec.js +80 -0
  63. package/dist/client/use-db-sync.spec.js.map +1 -0
  64. package/dist/code-agents/transcript-normalizer.d.ts +2 -0
  65. package/dist/code-agents/transcript-normalizer.d.ts.map +1 -1
  66. package/dist/code-agents/transcript-normalizer.js +17 -0
  67. package/dist/code-agents/transcript-normalizer.js.map +1 -1
  68. package/dist/db/client.d.ts.map +1 -1
  69. package/dist/db/client.js +29 -21
  70. package/dist/db/client.js.map +1 -1
  71. package/dist/extensions/actions.d.ts.map +1 -1
  72. package/dist/extensions/actions.js +62 -3
  73. package/dist/extensions/actions.js.map +1 -1
  74. package/dist/extensions/content-patch.d.ts +71 -0
  75. package/dist/extensions/content-patch.d.ts.map +1 -0
  76. package/dist/extensions/content-patch.js +251 -0
  77. package/dist/extensions/content-patch.js.map +1 -0
  78. package/dist/extensions/routes.js +6 -1
  79. package/dist/extensions/routes.js.map +1 -1
  80. package/dist/extensions/store.d.ts +4 -4
  81. package/dist/extensions/store.d.ts.map +1 -1
  82. package/dist/extensions/store.js +14 -18
  83. package/dist/extensions/store.js.map +1 -1
  84. package/dist/index.browser.d.ts +1 -1
  85. package/dist/index.browser.d.ts.map +1 -1
  86. package/dist/index.browser.js +1 -1
  87. package/dist/index.browser.js.map +1 -1
  88. package/dist/index.d.ts +1 -1
  89. package/dist/index.d.ts.map +1 -1
  90. package/dist/index.js +1 -1
  91. package/dist/index.js.map +1 -1
  92. package/dist/mcp/build-server.d.ts +3 -0
  93. package/dist/mcp/build-server.d.ts.map +1 -1
  94. package/dist/mcp/build-server.js +207 -8
  95. package/dist/mcp/build-server.js.map +1 -1
  96. package/dist/mcp/oauth-route.d.ts +22 -0
  97. package/dist/mcp/oauth-route.d.ts.map +1 -0
  98. package/dist/mcp/oauth-route.js +618 -0
  99. package/dist/mcp/oauth-route.js.map +1 -0
  100. package/dist/mcp/oauth-store.d.ts +89 -0
  101. package/dist/mcp/oauth-store.d.ts.map +1 -0
  102. package/dist/mcp/oauth-store.js +391 -0
  103. package/dist/mcp/oauth-store.js.map +1 -0
  104. package/dist/mcp/oauth-token.d.ts +28 -0
  105. package/dist/mcp/oauth-token.d.ts.map +1 -0
  106. package/dist/mcp/oauth-token.js +83 -0
  107. package/dist/mcp/oauth-token.js.map +1 -0
  108. package/dist/mcp/server.d.ts.map +1 -1
  109. package/dist/mcp/server.js +5 -2
  110. package/dist/mcp/server.js.map +1 -1
  111. package/dist/mcp/stdio.d.ts +2 -2
  112. package/dist/mcp/stdio.d.ts.map +1 -1
  113. package/dist/mcp/stdio.js +26 -8
  114. package/dist/mcp/stdio.js.map +1 -1
  115. package/dist/mcp-client/app-result.d.ts +40 -0
  116. package/dist/mcp-client/app-result.d.ts.map +1 -0
  117. package/dist/mcp-client/app-result.js +19 -0
  118. package/dist/mcp-client/app-result.js.map +1 -0
  119. package/dist/mcp-client/index.d.ts +5 -2
  120. package/dist/mcp-client/index.d.ts.map +1 -1
  121. package/dist/mcp-client/index.js +201 -25
  122. package/dist/mcp-client/index.js.map +1 -1
  123. package/dist/mcp-client/manager.d.ts +16 -0
  124. package/dist/mcp-client/manager.d.ts.map +1 -1
  125. package/dist/mcp-client/manager.js +58 -1
  126. package/dist/mcp-client/manager.js.map +1 -1
  127. package/dist/mcp-client/routes.d.ts +4 -1
  128. package/dist/mcp-client/routes.d.ts.map +1 -1
  129. package/dist/mcp-client/routes.js +159 -0
  130. package/dist/mcp-client/routes.js.map +1 -1
  131. package/dist/scripts/dev/shell.d.ts.map +1 -1
  132. package/dist/scripts/dev/shell.js +24 -1
  133. package/dist/scripts/dev/shell.js.map +1 -1
  134. package/dist/server/agent-chat-plugin.d.ts.map +1 -1
  135. package/dist/server/agent-chat-plugin.js +3 -2
  136. package/dist/server/agent-chat-plugin.js.map +1 -1
  137. package/dist/server/auth.d.ts.map +1 -1
  138. package/dist/server/auth.js +14 -8
  139. package/dist/server/auth.js.map +1 -1
  140. package/dist/server/builder-browser.d.ts +6 -0
  141. package/dist/server/builder-browser.d.ts.map +1 -1
  142. package/dist/server/builder-browser.js +15 -0
  143. package/dist/server/builder-browser.js.map +1 -1
  144. package/dist/server/core-routes-plugin.d.ts +5 -4
  145. package/dist/server/core-routes-plugin.d.ts.map +1 -1
  146. package/dist/server/core-routes-plugin.js +17 -2
  147. package/dist/server/core-routes-plugin.js.map +1 -1
  148. package/dist/styles/agent-conversation.css +53 -0
  149. package/dist/templates/default/.agents/skills/actions/SKILL.md +193 -72
  150. package/dist/templates/default/.agents/skills/real-time-sync/SKILL.md +88 -38
  151. package/dist/templates/default/AGENTS.md +3 -3
  152. package/dist/templates/default/actions/hello.ts +13 -20
  153. package/dist/templates/default/actions/navigate.ts +19 -51
  154. package/dist/templates/default/actions/view-screen.ts +16 -33
  155. package/dist/templates/default/app/hooks/use-navigation-state.ts +13 -3
  156. package/dist/templates/default/app/lib/tab-id.ts +1 -0
  157. package/dist/templates/default/app/root.tsx +2 -1
  158. package/dist/templates/default/app/routes/_index.tsx +11 -0
  159. package/dist/templates/default/package.json +2 -1
  160. package/dist/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +9 -1
  161. package/dist/templates/workspace-core/AGENTS.md +8 -0
  162. package/dist/templates/workspace-root/AGENTS.md +7 -0
  163. package/dist/vite/client.d.ts.map +1 -1
  164. package/dist/vite/client.js +2 -2
  165. package/dist/vite/client.js.map +1 -1
  166. package/docs/content/actions.md +26 -3
  167. package/docs/content/authentication.md +16 -1
  168. package/docs/content/client.md +11 -8
  169. package/docs/content/context-awareness.md +2 -3
  170. package/docs/content/creating-templates.md +2 -2
  171. package/docs/content/external-agents.md +106 -19
  172. package/docs/content/faq.md +2 -2
  173. package/docs/content/key-concepts.md +31 -23
  174. package/docs/content/mcp-clients.md +1 -1
  175. package/docs/content/mcp-protocol.md +65 -27
  176. package/docs/content/template-starter.md +3 -3
  177. package/docs/content/what-is-agent-native.md +4 -2
  178. package/package.json +3 -1
  179. package/src/templates/default/.agents/skills/actions/SKILL.md +193 -72
  180. package/src/templates/default/.agents/skills/real-time-sync/SKILL.md +88 -38
  181. package/src/templates/default/AGENTS.md +3 -3
  182. package/src/templates/default/actions/hello.ts +13 -20
  183. package/src/templates/default/actions/navigate.ts +19 -51
  184. package/src/templates/default/actions/view-screen.ts +16 -33
  185. package/src/templates/default/app/hooks/use-navigation-state.ts +13 -3
  186. package/src/templates/default/app/lib/tab-id.ts +1 -0
  187. package/src/templates/default/app/root.tsx +2 -1
  188. package/src/templates/default/app/routes/_index.tsx +11 -0
  189. package/src/templates/default/package.json +2 -1
  190. package/src/templates/workspace-core/.agents/skills/real-time-sync/SKILL.md +9 -1
  191. package/src/templates/workspace-core/AGENTS.md +8 -0
  192. package/src/templates/workspace-root/AGENTS.md +7 -0
  193. package/dist/templates/default/server/routes/api/hello.get.ts +0 -5
  194. package/dist/templates/default/shared/api.ts +0 -6
  195. package/src/templates/default/server/routes/api/hello.get.ts +0 -5
  196. package/src/templates/default/shared/api.ts +0 -6
@@ -1 +1 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/mcp-client/manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * McpClientManager — connects to configured MCP servers (stdio or remote\n * Streamable HTTP), enumerates their tools, and exposes a flat tool registry\n * prefixed with `mcp__<server-id>__` so the agent's tool-use loop can call them.\n *\n * Stdio servers are a strict no-op in non-Node runtimes (Cloudflare Workers,\n * browsers). HTTP servers work in any runtime with `fetch`; `reconfigure()`\n * lets callers add or remove servers at runtime without restarting the process.\n */\n\nimport type { McpConfig, McpServerConfig } from \"./config.js\";\nimport { formatMcpConnectError } from \"./errors.js\";\n\nexport const MCP_TOOL_PREFIX = \"mcp__\";\n\nexport interface McpTool {\n /** Server id the tool belongs to */\n source: string;\n /** Prefixed tool name (e.g. \"mcp__claude-in-chrome__navigate\") */\n name: string;\n /** Original name as reported by the MCP server */\n originalName: string;\n /** Human-readable description */\n description: string;\n /** JSON-Schema input spec forwarded verbatim from the server */\n inputSchema: Record<string, unknown>;\n}\n\ninterface ServerEntry {\n id: string;\n config: McpServerConfig;\n client: any | null;\n transport: any | null;\n tools: McpTool[];\n error?: string;\n}\n\ntype ErrorSink = (error: unknown) => void;\n\nfunction isNode(): boolean {\n return (\n typeof process !== \"undefined\" &&\n !!(process as any).versions?.node &&\n typeof (process as any).versions.node === \"string\"\n );\n}\n\nfunction buildPrefixedName(serverId: string, toolName: string): string {\n return `${MCP_TOOL_PREFIX}${serverId}__${toolName}`;\n}\n\n/**\n * Parse a prefixed tool name back into its server id and original tool name.\n * Returns `null` if the name doesn't match the MCP prefix convention.\n */\nexport function parseMcpToolName(\n prefixedName: string,\n): { serverId: string; toolName: string } | null {\n if (!prefixedName.startsWith(MCP_TOOL_PREFIX)) return null;\n const rest = prefixedName.slice(MCP_TOOL_PREFIX.length);\n const idx = rest.indexOf(\"__\");\n if (idx < 0) return null;\n return {\n serverId: rest.slice(0, idx),\n toolName: rest.slice(idx + 2),\n };\n}\n\nexport interface McpClientManagerOptions {\n /** Emit debug logs on startup */\n debug?: boolean;\n}\n\nfunction sameServerConfig(a: McpServerConfig, b: McpServerConfig): boolean {\n const typeA = a.type ?? \"stdio\";\n const typeB = b.type ?? \"stdio\";\n if (typeA !== typeB) return false;\n if (typeA === \"http\" && b.type === \"http\" && a.type === \"http\") {\n return (\n a.url === b.url &&\n JSON.stringify(a.headers ?? {}) === JSON.stringify(b.headers ?? {})\n );\n }\n if (a.type !== \"http\" && b.type !== \"http\") {\n return (\n a.command === b.command &&\n JSON.stringify(a.args ?? []) === JSON.stringify(b.args ?? []) &&\n JSON.stringify(a.env ?? {}) === JSON.stringify(b.env ?? {}) &&\n (a.cwd ?? \"\") === (b.cwd ?? \"\")\n );\n }\n return false;\n}\n\nasync function safelyClose(value: any, recordError?: ErrorSink): Promise<void> {\n try {\n if (value?.close) await value.close();\n } catch (err) {\n recordError?.(err);\n }\n}\n\nfunction guardClose(\n value: any,\n recordError: ErrorSink,\n): (() => void) | undefined {\n if (!value || typeof value.close !== \"function\") return undefined;\n const originalClose = value.close.bind(value);\n value.close = async (...args: unknown[]) => {\n try {\n return await originalClose(...args);\n } catch (err) {\n recordError(err);\n return undefined;\n }\n };\n return () => {\n value.close = originalClose;\n };\n}\n\ntype SdkModules = {\n Client: any;\n StdioClientTransport: any | null;\n StreamableHTTPClientTransport: any | null;\n};\n\nexport class McpClientManager {\n private readonly servers: Map<string, ServerEntry> = new Map();\n private readonly debug: boolean;\n private started = false;\n private config: McpConfig | null;\n private sdk: SdkModules | null = null;\n private readonly listeners: Set<() => void> = new Set();\n /** Serialises reconfigure()/start() — two concurrent callers would\n * otherwise race on `this.config` and on connect/disconnect ordering. */\n private reconfigureQueue: Promise<unknown> = Promise.resolve();\n\n constructor(config: McpConfig | null, options: McpClientManagerOptions = {}) {\n this.config = config;\n this.debug = !!options.debug;\n }\n\n /** True when the manager has any configured servers. */\n get enabled(): boolean {\n return !!this.config && Object.keys(this.config.servers).length > 0;\n }\n\n /** Return the current config (read-only snapshot for callers that need to\n * merge new servers into the existing set before calling reconfigure). */\n getConfig(): McpConfig | null {\n return this.config;\n }\n\n /** List of configured server ids (whether or not they're connected). */\n get configuredServers(): string[] {\n if (!this.config) return [];\n return Object.keys(this.config.servers);\n }\n\n /** List of server ids that successfully connected and enumerated tools. */\n get connectedServers(): string[] {\n return Array.from(this.servers.values())\n .filter((s) => s.client && !s.error)\n .map((s) => s.id);\n }\n\n /**\n * Load MCP SDK modules lazily so non-Node bundles don't pull them in.\n * Stdio transport is only loaded when a stdio server is actually configured.\n */\n private async loadSdk(needStdio: boolean): Promise<SdkModules | null> {\n if (this.sdk) {\n // If we previously loaded without stdio and now need it, top up.\n if (needStdio && !this.sdk.StdioClientTransport && isNode()) {\n try {\n const stdioMod =\n await import(\"@modelcontextprotocol/sdk/client/stdio.js\");\n this.sdk.StdioClientTransport = stdioMod.StdioClientTransport;\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to load stdio transport: ${err?.message ?? err}.`,\n );\n }\n }\n return this.sdk;\n }\n try {\n const clientMod =\n await import(\"@modelcontextprotocol/sdk/client/index.js\");\n const httpMod =\n await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n let StdioClientTransport: any = null;\n if (needStdio && isNode()) {\n try {\n const stdioMod =\n await import(\"@modelcontextprotocol/sdk/client/stdio.js\");\n StdioClientTransport = stdioMod.StdioClientTransport;\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to load stdio transport: ${err?.message ?? err}.`,\n );\n }\n }\n this.sdk = {\n Client: clientMod.Client,\n StdioClientTransport,\n StreamableHTTPClientTransport: httpMod.StreamableHTTPClientTransport,\n };\n return this.sdk;\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to load MCP SDK: ${err?.message ?? err}. MCP tools disabled.`,\n );\n return null;\n }\n }\n\n /**\n * Subscribe to tool-set changes (e.g. after `reconfigure()` adds/removes\n * servers). The listener is called *after* connect/disconnect completes.\n * Returns an unsubscribe function.\n */\n onChange(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private emitChange(): void {\n for (const l of this.listeners) {\n try {\n l();\n } catch (err: any) {\n console.warn(\n `[mcp-client] onChange listener threw: ${err?.message ?? err}`,\n );\n }\n }\n }\n\n /**\n * Connect to each configured MCP server (stdio or http) and enumerate tools.\n * Individual server failures are logged and skipped — the manager stays\n * usable with whichever servers did come up.\n *\n * Queued against `reconfigure()` so a `reconfigure` that lands before\n * `start()` finishes can't race on `this.started` / `this.servers`.\n */\n async start(): Promise<void> {\n const task = this.reconfigureQueue.then(() => this.startInternal());\n this.reconfigureQueue = task.catch(() => {\n /* failures surface on the caller, not on the queue */\n });\n return task;\n }\n\n private async startInternal(): Promise<void> {\n if (this.started) return;\n this.started = true;\n if (!this.enabled) return;\n\n const needStdio = Object.values(this.config!.servers).some(\n (cfg) => (cfg.type ?? \"stdio\") === \"stdio\",\n );\n const sdk = await this.loadSdk(needStdio);\n if (!sdk) return;\n\n const entries = Object.entries(this.config!.servers);\n await Promise.all(\n entries.map(async ([id, cfg]) => this.addServer(id, cfg, sdk)),\n );\n this.emitChange();\n }\n\n /**\n * Create a new ServerEntry and attempt to connect. Logs and records errors\n * on the entry rather than throwing — callers iterate many servers.\n */\n private async addServer(\n id: string,\n cfg: McpServerConfig,\n sdk: SdkModules,\n ): Promise<void> {\n if (this.servers.has(id)) {\n console.warn(\n `[mcp-client] Duplicate server ID '${id}' — overwriting previous registration`,\n );\n }\n const entry: ServerEntry = {\n id,\n config: cfg,\n client: null,\n transport: null,\n tools: [],\n };\n this.servers.set(id, entry);\n try {\n await this.connectServer(entry, sdk);\n console.log(\n `[mcp-client] connected to ${id}: ${entry.tools.length} tools`,\n );\n } catch (err: any) {\n entry.error = formatMcpConnectError(err);\n console.warn(`[mcp-client] failed to connect to ${id}: ${entry.error}`);\n }\n }\n\n private async connectServer(\n entry: ServerEntry,\n sdk: SdkModules,\n ): Promise<void> {\n const cfg = entry.config;\n const { Client } = sdk;\n\n let transport: any;\n if (cfg.type === \"http\") {\n if (!sdk.StreamableHTTPClientTransport) {\n throw new Error(\"HTTP transport not available\");\n }\n const requestInit: Record<string, unknown> = {};\n if (cfg.headers && Object.keys(cfg.headers).length > 0) {\n requestInit.headers = cfg.headers;\n }\n transport = new sdk.StreamableHTTPClientTransport(new URL(cfg.url), {\n requestInit,\n });\n } else {\n if (!sdk.StdioClientTransport) {\n throw new Error(\n \"Stdio transport not available (needs Node runtime with MCP SDK)\",\n );\n }\n const { command, args = [], env, cwd } = cfg;\n // SECURITY: stdio MCP servers run as child processes that inherit\n // their environment from us. We previously merged the entire\n // `process.env` into the child, which exposed every deployment\n // secret (A2A_SECRET, ANTHROPIC_API_KEY, BUILDER_PRIVATE_KEY, all\n // database URLs, all platform tokens) to any MCP server in\n // `mcp.config.json` — a malicious npx-fetched server could exfil\n // them by reading its own env. Instead, only forward a minimal\n // baseline plus the keys explicitly listed in `cfg.env`. See\n // finding #10 in /tmp/security-audit/12-mcp-a2a-agent.md.\n const ENV_ALLOWLIST = [\n \"PATH\",\n \"HOME\",\n \"TMPDIR\",\n \"LANG\",\n \"LC_ALL\",\n \"USER\",\n \"SHELL\",\n ];\n const baseline: Record<string, string> = {};\n for (const k of ENV_ALLOWLIST) {\n const v = process.env[k];\n if (typeof v === \"string\") baseline[k] = v;\n }\n const mergedEnv = env ? { ...baseline, ...env } : baseline;\n transport = new sdk.StdioClientTransport({\n command,\n args,\n env: mergedEnv as Record<string, string>,\n cwd,\n });\n }\n\n const client = new Client(\n { name: \"agent-native-mcp-client\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n const recordConnectionError: ErrorSink = () => {};\n const restoreClientClose = guardClose(client, recordConnectionError);\n const restoreTransportClose = guardClose(transport, recordConnectionError);\n client.onerror = recordConnectionError;\n // Attach a transport-level error handler before connect() so the SDK's\n // internal fire-and-forget paths (initial SSE stream open, scheduled\n // reconnects, message-handler-triggered reconnects — see processStream()\n // in @modelcontextprotocol/sdk/client/streamableHttp.js) cannot leak as\n // unhandled promise rejections. On AWS Lambda the long-lived socket\n // gets reaped ~60s after the function returns; without this handler the\n // resulting `socket hang up` surfaces as an unhandledRejection and\n // pollutes Sentry. Client.connect() chains its own onerror on top of\n // ours (see protocol.js: const _onerror = transport.onerror; ...).\n transport.onerror = recordConnectionError;\n\n // If connect or listTools throws, we still need to release the child\n // process (stdio) or pending HTTP session — otherwise repeated failures\n // leak transports. Assign to the entry only after the handshake succeeds.\n try {\n await client.connect(transport);\n const listed = await client.listTools();\n const rawTools: Array<{\n name: string;\n description?: string;\n inputSchema?: Record<string, unknown>;\n }> = (listed?.tools ?? []) as any[];\n\n entry.client = client;\n entry.transport = transport;\n entry.tools = rawTools.map((t) => ({\n source: entry.id,\n name: buildPrefixedName(entry.id, t.name),\n originalName: t.name,\n description: t.description ?? t.name,\n inputSchema: (t.inputSchema ?? {\n type: \"object\",\n properties: {},\n }) as Record<string, unknown>,\n }));\n client.onerror = (error: unknown) => {\n entry.error = formatMcpConnectError(error);\n if (this.debug) {\n console.warn(\n `[mcp-client] runtime error from ${entry.id}: ${entry.error}`,\n );\n }\n };\n } catch (err) {\n await safelyClose(client, recordConnectionError);\n await safelyClose(transport, recordConnectionError);\n throw err;\n } finally {\n restoreClientClose?.();\n restoreTransportClose?.();\n }\n }\n\n /**\n * Replace the configured server set. Servers that appear in the new config\n * under a different shape are reconnected; unchanged entries stay live;\n * removed entries are disconnected. Safe to call while `start()` is in\n * flight or after it has completed.\n *\n * Serialised against `start()` and any other `reconfigure()` call via the\n * internal queue — two concurrent mutations would otherwise interleave on\n * `this.config` and on connect/disconnect ordering.\n *\n * Returns a summary describing what happened for logging / UI feedback.\n */\n async reconfigure(newConfig: McpConfig | null): Promise<{\n added: string[];\n removed: string[];\n unchanged: string[];\n reconnected: string[];\n }> {\n const task = this.reconfigureQueue.then(() =>\n this.reconfigureInternal(newConfig),\n );\n this.reconfigureQueue = task.catch(() => {\n /* failures surface on the caller, not on the queue */\n });\n return task;\n }\n\n private async reconfigureInternal(newConfig: McpConfig | null): Promise<{\n added: string[];\n removed: string[];\n unchanged: string[];\n reconnected: string[];\n }> {\n const prev = this.config;\n this.config = newConfig;\n\n const prevServers = prev?.servers ?? {};\n const nextServers = newConfig?.servers ?? {};\n\n const added: string[] = [];\n const removed: string[] = [];\n const unchanged: string[] = [];\n const reconnected: string[] = [];\n\n // Remove entries that vanished or changed shape.\n for (const id of Object.keys(prevServers)) {\n if (!(id in nextServers)) {\n removed.push(id);\n } else if (!sameServerConfig(prevServers[id], nextServers[id])) {\n reconnected.push(id);\n } else {\n unchanged.push(id);\n }\n }\n for (const id of Object.keys(nextServers)) {\n if (!(id in prevServers)) added.push(id);\n }\n\n const toDisconnect = [...removed, ...reconnected];\n await Promise.all(\n toDisconnect.map(async (id) => {\n const entry = this.servers.get(id);\n if (!entry) return;\n this.servers.delete(id);\n try {\n if (entry.client?.close) await entry.client.close();\n } catch {\n // ignore\n }\n try {\n if (entry.transport?.close) await entry.transport.close();\n } catch {\n // ignore\n }\n }),\n );\n\n const toConnect = [...added, ...reconnected];\n if (toConnect.length > 0) {\n const needStdio = toConnect.some(\n (id) => (nextServers[id].type ?? \"stdio\") === \"stdio\",\n );\n const sdk = await this.loadSdk(needStdio);\n if (sdk) {\n await Promise.all(\n toConnect.map((id) => this.addServer(id, nextServers[id], sdk)),\n );\n }\n }\n\n // If the manager was never started (e.g. empty initial config) but now has\n // servers, mark it started so subsequent start() calls don't duplicate work.\n if (!this.started && Object.keys(nextServers).length > 0) {\n this.started = true;\n }\n\n this.emitChange();\n return { added, removed, unchanged, reconnected };\n }\n\n /** Flattened tool list across all connected servers. */\n getTools(): McpTool[] {\n if (!this.enabled) return [];\n const out: McpTool[] = [];\n for (const entry of this.servers.values()) {\n for (const tool of entry.tools) out.push(tool);\n }\n return out;\n }\n\n /**\n * Invoke an MCP tool by prefixed name. Routes to the owning server based on\n * the `mcp__<serverId>__` prefix.\n */\n async callTool(prefixedName: string, args: unknown): Promise<unknown> {\n const parsed = parseMcpToolName(prefixedName);\n if (!parsed) {\n throw new Error(\n `Tool name \"${prefixedName}\" does not look like an MCP tool (expected mcp__<server>__<tool>)`,\n );\n }\n const entry = this.servers.get(parsed.serverId);\n if (!entry || !entry.client) {\n throw new Error(\n `MCP server \"${parsed.serverId}\" is not connected${\n entry?.error ? `: ${entry.error}` : \"\"\n }`,\n );\n }\n // Look up the tool so we fail loud for unknown names instead of forwarding\n // garbage through to the server.\n const known = entry.tools.find((t) => t.name === prefixedName);\n if (!known) {\n throw new Error(\n `MCP server \"${parsed.serverId}\" does not expose tool \"${parsed.toolName}\"`,\n );\n }\n const result = await entry.client.callTool({\n name: parsed.toolName,\n arguments:\n args && typeof args === \"object\"\n ? (args as Record<string, unknown>)\n : {},\n });\n return result;\n }\n\n /** Cleanly close all MCP clients and child processes. */\n async stop(): Promise<void> {\n const entries = Array.from(this.servers.values());\n this.servers.clear();\n this.started = false;\n await Promise.all(\n entries.map(async (entry) => {\n try {\n if (entry.client?.close) await entry.client.close();\n } catch {\n // ignore\n }\n try {\n if (entry.transport?.close) await entry.transport.close();\n } catch {\n // ignore\n }\n }),\n );\n }\n\n /** Diagnostic snapshot used by `/_agent-native/mcp/status`. */\n getStatus(): {\n configuredServers: string[];\n connectedServers: string[];\n totalTools: number;\n tools: Array<{ source: string; name: string; description: string }>;\n errors: Record<string, string>;\n } {\n const tools = this.getTools().map((t) => ({\n source: t.source,\n name: t.name,\n description: t.description,\n }));\n const errors: Record<string, string> = {};\n for (const entry of this.servers.values()) {\n if (entry.error) errors[entry.id] = entry.error;\n }\n return {\n configuredServers: this.configuredServers,\n connectedServers: this.connectedServers,\n totalTools: tools.length,\n tools,\n errors,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/mcp-client/manager.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * McpClientManager — connects to configured MCP servers (stdio or remote\n * Streamable HTTP), enumerates their tools, and exposes a flat tool registry\n * prefixed with `mcp__<server-id>__` so the agent's tool-use loop can call them.\n *\n * Stdio servers are a strict no-op in non-Node runtimes (Cloudflare Workers,\n * browsers). HTTP servers work in any runtime with `fetch`; `reconfigure()`\n * lets callers add or remove servers at runtime without restarting the process.\n */\n\nimport type { McpConfig, McpServerConfig } from \"./config.js\";\nimport { formatMcpConnectError } from \"./errors.js\";\nimport { MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE } from \"../action.js\";\n\nexport const MCP_TOOL_PREFIX = \"mcp__\";\n\nexport interface McpTool {\n /** Server id the tool belongs to */\n source: string;\n /** Prefixed tool name (e.g. \"mcp__claude-in-chrome__navigate\") */\n name: string;\n /** Original name as reported by the MCP server */\n originalName: string;\n /** Human-readable description */\n description: string;\n /** JSON-Schema input spec forwarded verbatim from the server */\n inputSchema: Record<string, unknown>;\n /** Optional title as reported by the MCP server */\n title?: string;\n /** JSON-Schema output spec forwarded verbatim from the server */\n outputSchema?: Record<string, unknown>;\n /** MCP tool annotations forwarded verbatim from the server */\n annotations?: Record<string, unknown>;\n /** MCP metadata forwarded verbatim from the server */\n _meta?: Record<string, unknown>;\n /** Full raw tool object for extensions that depend on fields core does not know yet. */\n raw: Record<string, unknown>;\n}\n\ninterface ServerEntry {\n id: string;\n config: McpServerConfig;\n client: any | null;\n transport: any | null;\n tools: McpTool[];\n error?: string;\n}\n\ntype ErrorSink = (error: unknown) => void;\n\nfunction isNode(): boolean {\n return (\n typeof process !== \"undefined\" &&\n !!(process as any).versions?.node &&\n typeof (process as any).versions.node === \"string\"\n );\n}\n\nfunction buildPrefixedName(serverId: string, toolName: string): string {\n return `${MCP_TOOL_PREFIX}${serverId}__${toolName}`;\n}\n\nexport function buildMcpToolName(serverId: string, toolName: string): string {\n return buildPrefixedName(serverId, toolName);\n}\n\n/**\n * Parse a prefixed tool name back into its server id and original tool name.\n * Returns `null` if the name doesn't match the MCP prefix convention.\n */\nexport function parseMcpToolName(\n prefixedName: string,\n): { serverId: string; toolName: string } | null {\n if (!prefixedName.startsWith(MCP_TOOL_PREFIX)) return null;\n const rest = prefixedName.slice(MCP_TOOL_PREFIX.length);\n const idx = rest.indexOf(\"__\");\n if (idx < 0) return null;\n return {\n serverId: rest.slice(0, idx),\n toolName: rest.slice(idx + 2),\n };\n}\n\nexport interface McpClientManagerOptions {\n /** Emit debug logs on startup */\n debug?: boolean;\n}\n\nfunction sameServerConfig(a: McpServerConfig, b: McpServerConfig): boolean {\n const typeA = a.type ?? \"stdio\";\n const typeB = b.type ?? \"stdio\";\n if (typeA !== typeB) return false;\n if (typeA === \"http\" && b.type === \"http\" && a.type === \"http\") {\n return (\n a.url === b.url &&\n JSON.stringify(a.headers ?? {}) === JSON.stringify(b.headers ?? {})\n );\n }\n if (a.type !== \"http\" && b.type !== \"http\") {\n return (\n a.command === b.command &&\n JSON.stringify(a.args ?? []) === JSON.stringify(b.args ?? []) &&\n JSON.stringify(a.env ?? {}) === JSON.stringify(b.env ?? {}) &&\n (a.cwd ?? \"\") === (b.cwd ?? \"\")\n );\n }\n return false;\n}\n\nasync function safelyClose(value: any, recordError?: ErrorSink): Promise<void> {\n try {\n if (value?.close) await value.close();\n } catch (err) {\n recordError?.(err);\n }\n}\n\nfunction guardClose(\n value: any,\n recordError: ErrorSink,\n): (() => void) | undefined {\n if (!value || typeof value.close !== \"function\") return undefined;\n const originalClose = value.close.bind(value);\n value.close = async (...args: unknown[]) => {\n try {\n return await originalClose(...args);\n } catch (err) {\n recordError(err);\n return undefined;\n }\n };\n return () => {\n value.close = originalClose;\n };\n}\n\ntype SdkModules = {\n Client: any;\n StdioClientTransport: any | null;\n StreamableHTTPClientTransport: any | null;\n};\n\nexport class McpClientManager {\n private readonly servers: Map<string, ServerEntry> = new Map();\n private readonly debug: boolean;\n private started = false;\n private config: McpConfig | null;\n private sdk: SdkModules | null = null;\n private readonly listeners: Set<() => void> = new Set();\n /** Serialises reconfigure()/start() — two concurrent callers would\n * otherwise race on `this.config` and on connect/disconnect ordering. */\n private reconfigureQueue: Promise<unknown> = Promise.resolve();\n\n constructor(config: McpConfig | null, options: McpClientManagerOptions = {}) {\n this.config = config;\n this.debug = !!options.debug;\n }\n\n /** True when the manager has any configured servers. */\n get enabled(): boolean {\n return !!this.config && Object.keys(this.config.servers).length > 0;\n }\n\n /** Return the current config (read-only snapshot for callers that need to\n * merge new servers into the existing set before calling reconfigure). */\n getConfig(): McpConfig | null {\n return this.config;\n }\n\n /** List of configured server ids (whether or not they're connected). */\n get configuredServers(): string[] {\n if (!this.config) return [];\n return Object.keys(this.config.servers);\n }\n\n /** List of server ids that successfully connected and enumerated tools. */\n get connectedServers(): string[] {\n return Array.from(this.servers.values())\n .filter((s) => s.client && !s.error)\n .map((s) => s.id);\n }\n\n /**\n * Load MCP SDK modules lazily so non-Node bundles don't pull them in.\n * Stdio transport is only loaded when a stdio server is actually configured.\n */\n private async loadSdk(needStdio: boolean): Promise<SdkModules | null> {\n if (this.sdk) {\n // If we previously loaded without stdio and now need it, top up.\n if (needStdio && !this.sdk.StdioClientTransport && isNode()) {\n try {\n const stdioMod =\n await import(\"@modelcontextprotocol/sdk/client/stdio.js\");\n this.sdk.StdioClientTransport = stdioMod.StdioClientTransport;\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to load stdio transport: ${err?.message ?? err}.`,\n );\n }\n }\n return this.sdk;\n }\n try {\n const clientMod =\n await import(\"@modelcontextprotocol/sdk/client/index.js\");\n const httpMod =\n await import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\");\n let StdioClientTransport: any = null;\n if (needStdio && isNode()) {\n try {\n const stdioMod =\n await import(\"@modelcontextprotocol/sdk/client/stdio.js\");\n StdioClientTransport = stdioMod.StdioClientTransport;\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to load stdio transport: ${err?.message ?? err}.`,\n );\n }\n }\n this.sdk = {\n Client: clientMod.Client,\n StdioClientTransport,\n StreamableHTTPClientTransport: httpMod.StreamableHTTPClientTransport,\n };\n return this.sdk;\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to load MCP SDK: ${err?.message ?? err}. MCP tools disabled.`,\n );\n return null;\n }\n }\n\n /**\n * Subscribe to tool-set changes (e.g. after `reconfigure()` adds/removes\n * servers). The listener is called *after* connect/disconnect completes.\n * Returns an unsubscribe function.\n */\n onChange(listener: () => void): () => void {\n this.listeners.add(listener);\n return () => {\n this.listeners.delete(listener);\n };\n }\n\n private emitChange(): void {\n for (const l of this.listeners) {\n try {\n l();\n } catch (err: any) {\n console.warn(\n `[mcp-client] onChange listener threw: ${err?.message ?? err}`,\n );\n }\n }\n }\n\n /**\n * Connect to each configured MCP server (stdio or http) and enumerate tools.\n * Individual server failures are logged and skipped — the manager stays\n * usable with whichever servers did come up.\n *\n * Queued against `reconfigure()` so a `reconfigure` that lands before\n * `start()` finishes can't race on `this.started` / `this.servers`.\n */\n async start(): Promise<void> {\n const task = this.reconfigureQueue.then(() => this.startInternal());\n this.reconfigureQueue = task.catch(() => {\n /* failures surface on the caller, not on the queue */\n });\n return task;\n }\n\n private async startInternal(): Promise<void> {\n if (this.started) return;\n this.started = true;\n if (!this.enabled) return;\n\n const needStdio = Object.values(this.config!.servers).some(\n (cfg) => (cfg.type ?? \"stdio\") === \"stdio\",\n );\n const sdk = await this.loadSdk(needStdio);\n if (!sdk) return;\n\n const entries = Object.entries(this.config!.servers);\n await Promise.all(\n entries.map(async ([id, cfg]) => this.addServer(id, cfg, sdk)),\n );\n this.emitChange();\n }\n\n /**\n * Create a new ServerEntry and attempt to connect. Logs and records errors\n * on the entry rather than throwing — callers iterate many servers.\n */\n private async addServer(\n id: string,\n cfg: McpServerConfig,\n sdk: SdkModules,\n ): Promise<void> {\n if (this.servers.has(id)) {\n console.warn(\n `[mcp-client] Duplicate server ID '${id}' — overwriting previous registration`,\n );\n }\n const entry: ServerEntry = {\n id,\n config: cfg,\n client: null,\n transport: null,\n tools: [],\n };\n this.servers.set(id, entry);\n try {\n await this.connectServer(entry, sdk);\n console.log(\n `[mcp-client] connected to ${id}: ${entry.tools.length} tools`,\n );\n } catch (err: any) {\n entry.error = formatMcpConnectError(err);\n console.warn(`[mcp-client] failed to connect to ${id}: ${entry.error}`);\n }\n }\n\n private async connectServer(\n entry: ServerEntry,\n sdk: SdkModules,\n ): Promise<void> {\n const cfg = entry.config;\n const { Client } = sdk;\n\n let transport: any;\n if (cfg.type === \"http\") {\n if (!sdk.StreamableHTTPClientTransport) {\n throw new Error(\"HTTP transport not available\");\n }\n const requestInit: Record<string, unknown> = {};\n if (cfg.headers && Object.keys(cfg.headers).length > 0) {\n requestInit.headers = cfg.headers;\n }\n transport = new sdk.StreamableHTTPClientTransport(new URL(cfg.url), {\n requestInit,\n });\n } else {\n if (!sdk.StdioClientTransport) {\n throw new Error(\n \"Stdio transport not available (needs Node runtime with MCP SDK)\",\n );\n }\n const { command, args = [], env, cwd } = cfg;\n // SECURITY: stdio MCP servers run as child processes that inherit\n // their environment from us. We previously merged the entire\n // `process.env` into the child, which exposed every deployment\n // secret (A2A_SECRET, ANTHROPIC_API_KEY, BUILDER_PRIVATE_KEY, all\n // database URLs, all platform tokens) to any MCP server in\n // `mcp.config.json` — a malicious npx-fetched server could exfil\n // them by reading its own env. Instead, only forward a minimal\n // baseline plus the keys explicitly listed in `cfg.env`. See\n // finding #10 in /tmp/security-audit/12-mcp-a2a-agent.md.\n const ENV_ALLOWLIST = [\n \"PATH\",\n \"HOME\",\n \"TMPDIR\",\n \"LANG\",\n \"LC_ALL\",\n \"USER\",\n \"SHELL\",\n ];\n const baseline: Record<string, string> = {};\n for (const k of ENV_ALLOWLIST) {\n const v = process.env[k];\n if (typeof v === \"string\") baseline[k] = v;\n }\n const mergedEnv = env ? { ...baseline, ...env } : baseline;\n transport = new sdk.StdioClientTransport({\n command,\n args,\n env: mergedEnv as Record<string, string>,\n cwd,\n });\n }\n\n const client = new Client(\n { name: \"agent-native-mcp-client\", version: \"1.0.0\" },\n {\n capabilities: {\n extensions: {\n [MCP_APP_EXTENSION_ID]: {\n mimeTypes: [MCP_APP_MIME_TYPE],\n },\n },\n },\n } as any,\n );\n const recordConnectionError: ErrorSink = () => {};\n const restoreClientClose = guardClose(client, recordConnectionError);\n const restoreTransportClose = guardClose(transport, recordConnectionError);\n client.onerror = recordConnectionError;\n // Attach a transport-level error handler before connect() so the SDK's\n // internal fire-and-forget paths (initial SSE stream open, scheduled\n // reconnects, message-handler-triggered reconnects — see processStream()\n // in @modelcontextprotocol/sdk/client/streamableHttp.js) cannot leak as\n // unhandled promise rejections. On AWS Lambda the long-lived socket\n // gets reaped ~60s after the function returns; without this handler the\n // resulting `socket hang up` surfaces as an unhandledRejection and\n // pollutes Sentry. Client.connect() chains its own onerror on top of\n // ours (see protocol.js: const _onerror = transport.onerror; ...).\n transport.onerror = recordConnectionError;\n\n // If connect or listTools throws, we still need to release the child\n // process (stdio) or pending HTTP session — otherwise repeated failures\n // leak transports. Assign to the entry only after the handshake succeeds.\n try {\n await client.connect(transport);\n const listed = await client.listTools();\n const rawTools: Array<{\n name: string;\n title?: string;\n description?: string;\n inputSchema?: Record<string, unknown>;\n outputSchema?: Record<string, unknown>;\n annotations?: Record<string, unknown>;\n _meta?: Record<string, unknown>;\n }> = (listed?.tools ?? []) as any[];\n\n entry.client = client;\n entry.transport = transport;\n entry.tools = rawTools.map((t) => ({\n source: entry.id,\n name: buildPrefixedName(entry.id, t.name),\n originalName: t.name,\n ...(t.title ? { title: t.title } : {}),\n description: t.description ?? t.name,\n inputSchema: (t.inputSchema ?? {\n type: \"object\",\n properties: {},\n }) as Record<string, unknown>,\n ...(t.outputSchema ? { outputSchema: t.outputSchema } : {}),\n ...(t.annotations ? { annotations: t.annotations } : {}),\n ...(t._meta ? { _meta: t._meta } : {}),\n raw: { ...t },\n }));\n client.onerror = (error: unknown) => {\n entry.error = formatMcpConnectError(error);\n if (this.debug) {\n console.warn(\n `[mcp-client] runtime error from ${entry.id}: ${entry.error}`,\n );\n }\n };\n } catch (err) {\n await safelyClose(client, recordConnectionError);\n await safelyClose(transport, recordConnectionError);\n throw err;\n } finally {\n restoreClientClose?.();\n restoreTransportClose?.();\n }\n }\n\n /**\n * Replace the configured server set. Servers that appear in the new config\n * under a different shape are reconnected; unchanged entries stay live;\n * removed entries are disconnected. Safe to call while `start()` is in\n * flight or after it has completed.\n *\n * Serialised against `start()` and any other `reconfigure()` call via the\n * internal queue — two concurrent mutations would otherwise interleave on\n * `this.config` and on connect/disconnect ordering.\n *\n * Returns a summary describing what happened for logging / UI feedback.\n */\n async reconfigure(newConfig: McpConfig | null): Promise<{\n added: string[];\n removed: string[];\n unchanged: string[];\n reconnected: string[];\n }> {\n const task = this.reconfigureQueue.then(() =>\n this.reconfigureInternal(newConfig),\n );\n this.reconfigureQueue = task.catch(() => {\n /* failures surface on the caller, not on the queue */\n });\n return task;\n }\n\n private async reconfigureInternal(newConfig: McpConfig | null): Promise<{\n added: string[];\n removed: string[];\n unchanged: string[];\n reconnected: string[];\n }> {\n const prev = this.config;\n this.config = newConfig;\n\n const prevServers = prev?.servers ?? {};\n const nextServers = newConfig?.servers ?? {};\n\n const added: string[] = [];\n const removed: string[] = [];\n const unchanged: string[] = [];\n const reconnected: string[] = [];\n\n // Remove entries that vanished or changed shape.\n for (const id of Object.keys(prevServers)) {\n if (!(id in nextServers)) {\n removed.push(id);\n } else if (!sameServerConfig(prevServers[id], nextServers[id])) {\n reconnected.push(id);\n } else {\n unchanged.push(id);\n }\n }\n for (const id of Object.keys(nextServers)) {\n if (!(id in prevServers)) added.push(id);\n }\n\n const toDisconnect = [...removed, ...reconnected];\n await Promise.all(\n toDisconnect.map(async (id) => {\n const entry = this.servers.get(id);\n if (!entry) return;\n this.servers.delete(id);\n try {\n if (entry.client?.close) await entry.client.close();\n } catch {\n // ignore\n }\n try {\n if (entry.transport?.close) await entry.transport.close();\n } catch {\n // ignore\n }\n }),\n );\n\n const toConnect = [...added, ...reconnected];\n if (toConnect.length > 0) {\n const needStdio = toConnect.some(\n (id) => (nextServers[id].type ?? \"stdio\") === \"stdio\",\n );\n const sdk = await this.loadSdk(needStdio);\n if (sdk) {\n await Promise.all(\n toConnect.map((id) => this.addServer(id, nextServers[id], sdk)),\n );\n }\n }\n\n // If the manager was never started (e.g. empty initial config) but now has\n // servers, mark it started so subsequent start() calls don't duplicate work.\n if (!this.started && Object.keys(nextServers).length > 0) {\n this.started = true;\n }\n\n this.emitChange();\n return { added, removed, unchanged, reconnected };\n }\n\n /** Flattened tool list across all connected servers. */\n getTools(): McpTool[] {\n if (!this.enabled) return [];\n const out: McpTool[] = [];\n for (const entry of this.servers.values()) {\n for (const tool of entry.tools) out.push(tool);\n }\n return out;\n }\n\n getTool(prefixedName: string): McpTool | null {\n const parsed = parseMcpToolName(prefixedName);\n if (!parsed) return null;\n const entry = this.servers.get(parsed.serverId);\n return entry?.tools.find((t) => t.name === prefixedName) ?? null;\n }\n\n getToolsForServer(serverId: string): McpTool[] {\n return [...(this.servers.get(serverId)?.tools ?? [])];\n }\n\n hasServer(serverId: string): boolean {\n const entry = this.servers.get(serverId);\n return !!entry?.client && !entry.error;\n }\n\n /**\n * Invoke an MCP tool by prefixed name. Routes to the owning server based on\n * the `mcp__<serverId>__` prefix.\n */\n async callTool(prefixedName: string, args: unknown): Promise<unknown> {\n const parsed = parseMcpToolName(prefixedName);\n if (!parsed) {\n throw new Error(\n `Tool name \"${prefixedName}\" does not look like an MCP tool (expected mcp__<server>__<tool>)`,\n );\n }\n const entry = this.servers.get(parsed.serverId);\n if (!entry || !entry.client) {\n throw new Error(\n `MCP server \"${parsed.serverId}\" is not connected${\n entry?.error ? `: ${entry.error}` : \"\"\n }`,\n );\n }\n // Look up the tool so we fail loud for unknown names instead of forwarding\n // garbage through to the server.\n const known = entry.tools.find((t) => t.name === prefixedName);\n if (!known) {\n throw new Error(\n `MCP server \"${parsed.serverId}\" does not expose tool \"${parsed.toolName}\"`,\n );\n }\n const result = await entry.client.callTool({\n name: parsed.toolName,\n arguments:\n args && typeof args === \"object\"\n ? (args as Record<string, unknown>)\n : {},\n });\n return result;\n }\n\n async readResource(serverId: string, uri: string): Promise<unknown> {\n if (!uri.startsWith(\"ui://\")) {\n throw new Error(`Only ui:// MCP App resources can be read by this host`);\n }\n const entry = this.servers.get(serverId);\n if (!entry || !entry.client) {\n throw new Error(\n `MCP server \"${serverId}\" is not connected${\n entry?.error ? `: ${entry.error}` : \"\"\n }`,\n );\n }\n if (typeof entry.client.readResource === \"function\") {\n return entry.client.readResource({ uri });\n }\n if (typeof entry.client.request === \"function\") {\n return entry.client.request({\n method: \"resources/read\",\n params: { uri },\n });\n }\n throw new Error(`MCP server \"${serverId}\" does not support resources/read`);\n }\n\n async readResourceForTool(\n prefixedName: string,\n uri: string,\n ): Promise<unknown> {\n const parsed = parseMcpToolName(prefixedName);\n if (!parsed) {\n throw new Error(\n `Tool name \"${prefixedName}\" does not look like an MCP tool (expected mcp__<server>__<tool>)`,\n );\n }\n return this.readResource(parsed.serverId, uri);\n }\n\n /** Cleanly close all MCP clients and child processes. */\n async stop(): Promise<void> {\n const entries = Array.from(this.servers.values());\n this.servers.clear();\n this.started = false;\n await Promise.all(\n entries.map(async (entry) => {\n try {\n if (entry.client?.close) await entry.client.close();\n } catch {\n // ignore\n }\n try {\n if (entry.transport?.close) await entry.transport.close();\n } catch {\n // ignore\n }\n }),\n );\n }\n\n /** Diagnostic snapshot used by `/_agent-native/mcp/status`. */\n getStatus(): {\n configuredServers: string[];\n connectedServers: string[];\n totalTools: number;\n tools: Array<{ source: string; name: string; description: string }>;\n errors: Record<string, string>;\n } {\n const tools = this.getTools().map((t) => ({\n source: t.source,\n name: t.name,\n description: t.description,\n }));\n const errors: Record<string, string> = {};\n for (const entry of this.servers.values()) {\n if (entry.error) errors[entry.id] = entry.error;\n }\n return {\n configuredServers: this.configuredServers,\n connectedServers: this.connectedServers,\n totalTools: tools.length,\n tools,\n errors,\n };\n }\n}\n"]}
@@ -12,8 +12,11 @@
12
12
  * POST /_agent-native/mcp/servers/test dry-run a URL before persisting
13
13
  * GET /_agent-native/mcp/builtin list built-in capability toggles
14
14
  * POST /_agent-native/mcp/builtin update built-in capability toggles
15
+ * POST /_agent-native/mcp/apps/call-tool mediated same-server app tool call
16
+ * POST /_agent-native/mcp/apps/list-tools list tools visible to an app iframe
17
+ * POST /_agent-native/mcp/apps/read-resource read a ui:// app resource
15
18
  */
16
- import type { McpClientManager } from "./manager.js";
19
+ import { type McpClientManager } from "./manager.js";
17
20
  import type { McpConfig } from "./config.js";
18
21
  import { type BuiltinMcpCapability, type BuiltinMcpCapabilityId } from "./builtin-capabilities.js";
19
22
  import { type RemoteMcpScope } from "./remote-store.js";
@@ -1 +1 @@
1
- {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/mcp-client/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAeH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,aAAa,CAAC;AAG9D,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC5B,MAAM,2BAA2B,CAAC;AAOnC,OAAO,EAOL,KAAK,cAAc,EAEpB,MAAM,mBAAmB,CAAC;AAG3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AA+BpD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,sBAAsB,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,CAAC;IACzC,SAAS,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,YAAY,CAAC;QAAC,GAAG,CAAC,EAAE,YAAY,CAAA;KAAE,CAAC;CACrD;AAED,KAAK,YAAY,GACb;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AA6BzB,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EACrB,UAAU,EAAE,oBAAoB,EAChC,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA2EnE;AAmCD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,GAAG,EACb,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAyEN"}
1
+ {"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/mcp-client/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAgBH,OAAO,EAGL,KAAK,gBAAgB,EAEtB,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,EAAE,SAAS,EAAmB,MAAM,aAAa,CAAC;AAG9D,OAAO,EAML,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC5B,MAAM,2BAA2B,CAAC;AAOnC,OAAO,EAOL,KAAK,cAAc,EAEpB,MAAM,mBAAmB,CAAC;AAK3B,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AA+BpD,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,cAAc,CAAC;IACtB,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,GAAG,EAAE,IAAI,CAAA;KAAE,CAAC,CAAC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,sBAAsB,CAAC;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,OAAO,CAAC;IACnB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE;QAAE,IAAI,EAAE,OAAO,CAAC;QAAC,GAAG,EAAE,OAAO,CAAA;KAAE,CAAC;IACzC,SAAS,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,MAAM,EAAE;QAAE,IAAI,CAAC,EAAE,YAAY,CAAC;QAAC,GAAG,CAAC,EAAE,YAAY,CAAA;KAAE,CAAC;CACrD;AAED,KAAK,YAAY,GACb;IAAE,KAAK,EAAE,WAAW,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,KAAK,EAAE,SAAS,CAAA;CAAE,CAAC;AA6BzB,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EACrB,UAAU,EAAE,oBAAoB,EAChC,OAAO,EAAE,MAAM,GACd,MAAM,CAER;AAED;;;;;;;;;;;GAWG;AACH,wBAAsB,iBAAiB,IAAI,OAAO,CAAC,SAAS,GAAG,IAAI,CAAC,CA2EnE;AAmCD,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,GAAG,EACb,OAAO,EAAE,gBAAgB,GACxB,IAAI,CAsGN"}
@@ -12,19 +12,26 @@
12
12
  * POST /_agent-native/mcp/servers/test dry-run a URL before persisting
13
13
  * GET /_agent-native/mcp/builtin list built-in capability toggles
14
14
  * POST /_agent-native/mcp/builtin update built-in capability toggles
15
+ * POST /_agent-native/mcp/apps/call-tool mediated same-server app tool call
16
+ * POST /_agent-native/mcp/apps/list-tools list tools visible to an app iframe
17
+ * POST /_agent-native/mcp/apps/read-resource read a ui:// app resource
15
18
  */
16
19
  import { defineEventHandler, getMethod, getQuery, setResponseHeader, setResponseStatus, } from "h3";
17
20
  import { getH3App } from "../server/framework-request-handler.js";
18
21
  import { readBody } from "../server/h3-helpers.js";
19
22
  import { getOrgContext } from "../org/context.js";
20
23
  import { getSession } from "../server/auth.js";
24
+ import { runWithRequestContext } from "../server/request-context.js";
21
25
  import { getAllSettings } from "../settings/store.js";
26
+ import { buildMcpToolName, parseMcpToolName, } from "./manager.js";
22
27
  import { loadMcpConfig, autoDetectMcpConfig } from "./config.js";
23
28
  import { formatMcpConnectError } from "./errors.js";
24
29
  import { BUILTIN_MCP_CAPABILITIES, getBuiltinMcpCapability, isBuiltinMcpCapabilityAvailable, normalizeBuiltinMcpCapabilityIds, toBuiltinMcpServerConfig, } from "./builtin-capabilities.js";
25
30
  import { builtinMcpCapabilitiesSettingsKey, listEnabledBuiltinMcpCapabilities, setBuiltinMcpCapabilityEnabled, setEnabledBuiltinMcpCapabilities, } from "./builtin-store.js";
26
31
  import { addRemoteServer, listRemoteServers, mergedConfigKey, removeRemoteServer, toHttpServerConfigAsync, validateRemoteUrl, } from "./remote-store.js";
27
32
  import { fetchHubServers } from "./hub-client.js";
33
+ import { isMcpToolAllowedForRequest } from "./visibility.js";
34
+ import { isToolVisibilityModelOnly } from "@modelcontextprotocol/ext-apps/app-bridge";
28
35
  export { formatMcpConnectError } from "./errors.js";
29
36
  /** Redact obvious auth header values before sending to the client. */
30
37
  function redactHeaders(headers) {
@@ -250,11 +257,163 @@ export function mountMcpServersRoutes(nitroApp, manager) {
250
257
  setResponseStatus(event, 404);
251
258
  return { error: "Not found" };
252
259
  }));
260
+ getH3App(nitroApp).use("/_agent-native/mcp/apps", defineEventHandler(async (event) => {
261
+ const method = getMethod(event);
262
+ const pathname = (event.url?.pathname || "")
263
+ .replace(/^\/+/, "")
264
+ .replace(/\/+$/, "");
265
+ const parts = pathname ? pathname.split("/") : [];
266
+ setResponseHeader(event, "Content-Type", "application/json");
267
+ if (method !== "POST") {
268
+ setResponseStatus(event, 405);
269
+ return { error: "Method not allowed" };
270
+ }
271
+ if (parts.length === 1 && parts[0] === "call-tool") {
272
+ return handleMcpAppCallTool(event, manager);
273
+ }
274
+ if (parts.length === 1 && parts[0] === "list-tools") {
275
+ return handleMcpAppListTools(event, manager);
276
+ }
277
+ if (parts.length === 1 && parts[0] === "read-resource") {
278
+ return handleMcpAppReadResource(event, manager);
279
+ }
280
+ setResponseStatus(event, 404);
281
+ return { error: "Not found" };
282
+ }));
253
283
  }
254
284
  catch (err) {
255
285
  console.warn(`[mcp-client] Failed to mount MCP routes: ${err?.message ?? err}`);
256
286
  }
257
287
  }
288
+ async function withMcpAppRequestContext(event, fn) {
289
+ const { email, orgId } = await resolveContextForRequest(event);
290
+ if (!email) {
291
+ setResponseStatus(event, 401);
292
+ return { error: "Authentication required" };
293
+ }
294
+ return runWithRequestContext({
295
+ userEmail: email ?? undefined,
296
+ orgId: orgId ?? undefined,
297
+ }, fn);
298
+ }
299
+ function serverHasVisibleTools(manager, serverId) {
300
+ return manager
301
+ .getToolsForServer(serverId)
302
+ .some((tool) => isMcpToolAllowedForRequest(tool.name) && isVisibleToMcpApp(tool));
303
+ }
304
+ function normalizeSameServerToolName(serverId, rawName) {
305
+ if (typeof rawName !== "string" || !rawName.trim())
306
+ return null;
307
+ const name = rawName.trim();
308
+ const parsed = parseMcpToolName(name);
309
+ if (!parsed)
310
+ return name;
311
+ if (parsed.serverId !== serverId)
312
+ return null;
313
+ return parsed.toolName;
314
+ }
315
+ function isVisibleToMcpApp(tool) {
316
+ try {
317
+ return !isToolVisibilityModelOnly(tool.raw);
318
+ }
319
+ catch {
320
+ return true;
321
+ }
322
+ }
323
+ function mcpToolForClient(tool) {
324
+ return {
325
+ name: tool.originalName,
326
+ ...(tool.title ? { title: tool.title } : {}),
327
+ description: tool.description,
328
+ inputSchema: tool.inputSchema,
329
+ ...(tool.outputSchema ? { outputSchema: tool.outputSchema } : {}),
330
+ ...(tool.annotations ? { annotations: tool.annotations } : {}),
331
+ ...(tool._meta ? { _meta: tool._meta } : {}),
332
+ };
333
+ }
334
+ function mcpAppCallableTool(manager, serverId, originalToolName) {
335
+ const prefixedName = buildMcpToolName(serverId, originalToolName);
336
+ const tool = manager
337
+ .getToolsForServer(serverId)
338
+ .find((candidate) => candidate.name === prefixedName ||
339
+ candidate.originalName === originalToolName) ?? null;
340
+ if (!tool)
341
+ return null;
342
+ if (!isMcpToolAllowedForRequest(tool.name) || !isVisibleToMcpApp(tool)) {
343
+ return null;
344
+ }
345
+ return tool;
346
+ }
347
+ async function handleMcpAppCallTool(event, manager) {
348
+ const body = (await readBody(event).catch(() => ({})));
349
+ const serverId = typeof body.serverId === "string" ? body.serverId : "";
350
+ const originalToolName = normalizeSameServerToolName(serverId, body.toolName);
351
+ if (!serverId || !originalToolName) {
352
+ setResponseStatus(event, 400);
353
+ return { error: "serverId and same-server toolName are required" };
354
+ }
355
+ return withMcpAppRequestContext(event, async () => {
356
+ const tool = mcpAppCallableTool(manager, serverId, originalToolName);
357
+ if (!tool) {
358
+ setResponseStatus(event, 403);
359
+ return { error: "MCP tool is not available in this request scope" };
360
+ }
361
+ try {
362
+ return await manager.callTool(tool.name, body.arguments && typeof body.arguments === "object"
363
+ ? body.arguments
364
+ : {});
365
+ }
366
+ catch (err) {
367
+ setResponseStatus(event, 400);
368
+ return { error: err?.message ?? "MCP tool call failed" };
369
+ }
370
+ });
371
+ }
372
+ async function handleMcpAppListTools(event, manager) {
373
+ const body = (await readBody(event).catch(() => ({})));
374
+ const serverId = typeof body.serverId === "string" ? body.serverId : "";
375
+ if (!serverId) {
376
+ setResponseStatus(event, 400);
377
+ return { error: "serverId is required" };
378
+ }
379
+ return withMcpAppRequestContext(event, async () => {
380
+ if (!manager.hasServer(serverId) ||
381
+ !serverHasVisibleTools(manager, serverId)) {
382
+ setResponseStatus(event, 403);
383
+ return { error: "MCP server is not available in this request scope" };
384
+ }
385
+ return {
386
+ tools: manager
387
+ .getToolsForServer(serverId)
388
+ .filter((tool) => isMcpToolAllowedForRequest(tool.name))
389
+ .filter(isVisibleToMcpApp)
390
+ .map(mcpToolForClient),
391
+ };
392
+ });
393
+ }
394
+ async function handleMcpAppReadResource(event, manager) {
395
+ const body = (await readBody(event).catch(() => ({})));
396
+ const serverId = typeof body.serverId === "string" ? body.serverId : "";
397
+ const uri = typeof body.uri === "string" ? body.uri : "";
398
+ if (!serverId || !uri.startsWith("ui://")) {
399
+ setResponseStatus(event, 400);
400
+ return { error: "serverId and ui:// uri are required" };
401
+ }
402
+ return withMcpAppRequestContext(event, async () => {
403
+ if (!manager.hasServer(serverId) ||
404
+ !serverHasVisibleTools(manager, serverId)) {
405
+ setResponseStatus(event, 403);
406
+ return { error: "MCP server is not available in this request scope" };
407
+ }
408
+ try {
409
+ return await manager.readResource(serverId, uri);
410
+ }
411
+ catch (err) {
412
+ setResponseStatus(event, 400);
413
+ return { error: err?.message ?? "MCP resource read failed" };
414
+ }
415
+ });
416
+ }
258
417
  async function handleBuiltinList(event, manager) {
259
418
  const { email, orgId, role } = await resolveContextForRequest(event);
260
419
  const userEnabled = email