@agent-native/core 0.20.9 → 0.21.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 (88) 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 +13 -0
  16. package/dist/cli/connect.d.ts.map +1 -1
  17. package/dist/cli/connect.js +492 -4
  18. package/dist/cli/connect.js.map +1 -1
  19. package/dist/client/AssistantChat.d.ts.map +1 -1
  20. package/dist/client/AssistantChat.js +6 -5
  21. package/dist/client/AssistantChat.js.map +1 -1
  22. package/dist/client/code-agent-chat-adapter.js +1 -0
  23. package/dist/client/code-agent-chat-adapter.js.map +1 -1
  24. package/dist/client/conversation/AgentConversation.d.ts.map +1 -1
  25. package/dist/client/conversation/AgentConversation.js +3 -2
  26. package/dist/client/conversation/AgentConversation.js.map +1 -1
  27. package/dist/client/conversation/code-agent-transcript.js +1 -0
  28. package/dist/client/conversation/code-agent-transcript.js.map +1 -1
  29. package/dist/client/conversation/types.d.ts +2 -0
  30. package/dist/client/conversation/types.d.ts.map +1 -1
  31. package/dist/client/conversation/types.js.map +1 -1
  32. package/dist/client/index.d.ts +1 -0
  33. package/dist/client/index.d.ts.map +1 -1
  34. package/dist/client/index.js +1 -0
  35. package/dist/client/index.js.map +1 -1
  36. package/dist/client/mcp-apps/McpAppRenderer.d.ts +10 -0
  37. package/dist/client/mcp-apps/McpAppRenderer.d.ts.map +1 -0
  38. package/dist/client/mcp-apps/McpAppRenderer.js +296 -0
  39. package/dist/client/mcp-apps/McpAppRenderer.js.map +1 -0
  40. package/dist/client/sse-event-processor.d.ts +3 -0
  41. package/dist/client/sse-event-processor.d.ts.map +1 -1
  42. package/dist/client/sse-event-processor.js +2 -0
  43. package/dist/client/sse-event-processor.js.map +1 -1
  44. package/dist/code-agents/transcript-normalizer.d.ts +2 -0
  45. package/dist/code-agents/transcript-normalizer.d.ts.map +1 -1
  46. package/dist/code-agents/transcript-normalizer.js +17 -0
  47. package/dist/code-agents/transcript-normalizer.js.map +1 -1
  48. package/dist/db/client.d.ts.map +1 -1
  49. package/dist/db/client.js +22 -20
  50. package/dist/db/client.js.map +1 -1
  51. package/dist/index.browser.d.ts +1 -1
  52. package/dist/index.browser.d.ts.map +1 -1
  53. package/dist/index.browser.js +1 -1
  54. package/dist/index.browser.js.map +1 -1
  55. package/dist/index.d.ts +1 -1
  56. package/dist/index.d.ts.map +1 -1
  57. package/dist/index.js +1 -1
  58. package/dist/index.js.map +1 -1
  59. package/dist/mcp/build-server.d.ts.map +1 -1
  60. package/dist/mcp/build-server.js +154 -4
  61. package/dist/mcp/build-server.js.map +1 -1
  62. package/dist/mcp/stdio.d.ts +2 -2
  63. package/dist/mcp/stdio.d.ts.map +1 -1
  64. package/dist/mcp/stdio.js +26 -8
  65. package/dist/mcp/stdio.js.map +1 -1
  66. package/dist/mcp-client/app-result.d.ts +40 -0
  67. package/dist/mcp-client/app-result.d.ts.map +1 -0
  68. package/dist/mcp-client/app-result.js +19 -0
  69. package/dist/mcp-client/app-result.js.map +1 -0
  70. package/dist/mcp-client/index.d.ts +5 -2
  71. package/dist/mcp-client/index.d.ts.map +1 -1
  72. package/dist/mcp-client/index.js +185 -23
  73. package/dist/mcp-client/index.js.map +1 -1
  74. package/dist/mcp-client/manager.d.ts +16 -0
  75. package/dist/mcp-client/manager.d.ts.map +1 -1
  76. package/dist/mcp-client/manager.js +58 -1
  77. package/dist/mcp-client/manager.js.map +1 -1
  78. package/dist/mcp-client/routes.d.ts +4 -1
  79. package/dist/mcp-client/routes.d.ts.map +1 -1
  80. package/dist/mcp-client/routes.js +146 -0
  81. package/dist/mcp-client/routes.js.map +1 -1
  82. package/dist/styles/agent-conversation.css +53 -0
  83. package/docs/content/actions.md +25 -2
  84. package/docs/content/external-agents.md +62 -8
  85. package/docs/content/key-concepts.md +1 -1
  86. package/docs/content/mcp-clients.md +1 -1
  87. package/docs/content/mcp-protocol.md +16 -11
  88. package/package.json +2 -1
@@ -1 +1 @@
1
- {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/mcp-client/routes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HTTP routes for user- and org-scope remote MCP server management.\n *\n * Mounted under `/_agent-native/mcp/servers` by `agent-chat-plugin` —\n * requires a reference to the running `McpClientManager` so mutations can\n * hot-reload the configured server set.\n *\n * GET /_agent-native/mcp/servers list user + org servers\n * POST /_agent-native/mcp/servers add a server\n * DELETE /_agent-native/mcp/servers/:id remove a server (scope via ?scope=)\n * POST /_agent-native/mcp/servers/:id/test dry-run connect (no persist)\n * POST /_agent-native/mcp/servers/test dry-run a URL before persisting\n * GET /_agent-native/mcp/builtin list built-in capability toggles\n * POST /_agent-native/mcp/builtin update built-in capability toggles\n */\n\nimport {\n defineEventHandler,\n getMethod,\n getQuery,\n setResponseHeader,\n setResponseStatus,\n type H3Event,\n} from \"h3\";\nimport { getH3App } from \"../server/framework-request-handler.js\";\nimport { readBody } from \"../server/h3-helpers.js\";\nimport { getOrgContext } from \"../org/context.js\";\nimport { getSession } from \"../server/auth.js\";\nimport { getAllSettings } from \"../settings/store.js\";\nimport type { McpClientManager } from \"./manager.js\";\nimport type { McpConfig, McpServerConfig } from \"./config.js\";\nimport { loadMcpConfig, autoDetectMcpConfig } from \"./config.js\";\nimport { formatMcpConnectError } from \"./errors.js\";\nimport {\n BUILTIN_MCP_CAPABILITIES,\n getBuiltinMcpCapability,\n isBuiltinMcpCapabilityAvailable,\n normalizeBuiltinMcpCapabilityIds,\n toBuiltinMcpServerConfig,\n type BuiltinMcpCapability,\n type BuiltinMcpCapabilityId,\n} from \"./builtin-capabilities.js\";\nimport {\n builtinMcpCapabilitiesSettingsKey,\n listEnabledBuiltinMcpCapabilities,\n setBuiltinMcpCapabilityEnabled,\n setEnabledBuiltinMcpCapabilities,\n} from \"./builtin-store.js\";\nimport {\n addRemoteServer,\n listRemoteServers,\n mergedConfigKey,\n removeRemoteServer,\n toHttpServerConfigAsync,\n validateRemoteUrl,\n type RemoteMcpScope,\n type StoredRemoteMcpServer,\n} from \"./remote-store.js\";\nimport { fetchHubServers } from \"./hub-client.js\";\n\nexport { formatMcpConnectError } from \"./errors.js\";\n\n/** Redact obvious auth header values before sending to the client. */\nfunction redactHeaders(\n headers?: Record<string, string>,\n): Record<string, { set: true }> | undefined {\n if (!headers) return undefined;\n const out: Record<string, { set: true }> = {};\n for (const k of Object.keys(headers)) out[k] = { set: true };\n return out;\n}\n\nfunction projectForClient(\n stored: StoredRemoteMcpServer,\n scope: RemoteMcpScope,\n ownerId: string,\n status: ServerStatus,\n): ClientServer {\n return {\n id: stored.id,\n scope,\n name: stored.name,\n url: stored.url,\n headers: redactHeaders(stored.headers),\n description: stored.description,\n createdAt: stored.createdAt,\n mergedId: mergedConfigKey(scope, stored, ownerId),\n status,\n };\n}\n\nexport interface ClientServer {\n id: string;\n scope: RemoteMcpScope;\n name: string;\n url: string;\n headers?: Record<string, { set: true }>;\n description?: string;\n createdAt: number;\n /** The key under which this server is registered in the running MCP manager. */\n mergedId: string;\n status: ServerStatus;\n}\n\nexport interface ClientBuiltinCapability {\n id: BuiltinMcpCapabilityId;\n serverId: string;\n name: string;\n description: string;\n command: string;\n args: string[];\n exclusiveGroup?: string;\n available: boolean;\n unavailableReason?: string;\n notes?: string;\n enabled: { user: boolean; org: boolean };\n mergedIds: { user?: string; org?: string };\n status: { user?: ServerStatus; org?: ServerStatus };\n}\n\ntype ServerStatus =\n | { state: \"connected\"; toolCount: number }\n | { state: \"error\"; error: string }\n | { state: \"unknown\" };\n\nfunction statusFor(manager: McpClientManager, mergedId: string): ServerStatus {\n const snap = manager.getStatus();\n if (snap.connectedServers.includes(mergedId)) {\n const toolCount = snap.tools.filter((t) => t.source === mergedId).length;\n return { state: \"connected\", toolCount };\n }\n if (snap.errors[mergedId]) {\n return { state: \"error\", error: snap.errors[mergedId] };\n }\n if (snap.configuredServers.includes(mergedId)) {\n return { state: \"unknown\" };\n }\n return { state: \"unknown\" };\n}\n\nfunction pseudoStoredBuiltin(\n capability: BuiltinMcpCapability,\n): StoredRemoteMcpServer {\n return {\n id: `builtin_${capability.id}`,\n name: capability.serverId,\n url: `builtin:${capability.id}`,\n description: capability.description,\n createdAt: 0,\n };\n}\n\nexport function builtinMergedConfigKey(\n scope: RemoteMcpScope,\n capability: BuiltinMcpCapability,\n ownerId: string,\n): string {\n return mergedConfigKey(scope, pseudoStoredBuiltin(capability), ownerId);\n}\n\n/**\n * Build the merged MCP config the manager should run with: file/env config\n * plus **every** user-scope and org-scope remote server persisted in the\n * settings store. Scanning all scopes means a mutation from one user's\n * session never drops another user's servers from the running manager.\n *\n * Each persisted server's merged key includes its owner discriminator\n * (`user_<emailhash>_<name>` or `org_<orgId>_<name>`) so two users' servers\n * with the same name coexist; the request-time gate in\n * `isMcpToolAllowedForRequest` then scopes tool visibility back down to the\n * calling user.\n */\nexport async function buildMergedConfig(): Promise<McpConfig | null> {\n const base = loadMcpConfig() ?? autoDetectMcpConfig();\n const servers: Record<string, McpServerConfig> = { ...(base?.servers ?? {}) };\n\n const all = await getAllSettings().catch(() => ({}));\n for (const [fullKey, value] of Object.entries(all)) {\n const userMatch = /^u:([^:]+):mcp-servers-remote$/.exec(fullKey);\n const orgMatch = /^o:([^:]+):mcp-servers-remote$/.exec(fullKey);\n let scope: RemoteMcpScope | null = null;\n let ownerId: string | null = null;\n if (userMatch) {\n scope = \"user\";\n ownerId = userMatch[1];\n } else if (orgMatch) {\n scope = \"org\";\n ownerId = orgMatch[1];\n }\n if (!scope || !ownerId) continue;\n const list = (value as { servers?: StoredRemoteMcpServer[] }).servers;\n if (!Array.isArray(list)) continue;\n for (const stored of list) {\n if (!stored || typeof stored.url !== \"string\" || !stored.name) continue;\n // Async resolve: decrypts `headerSecretKey` from app_secrets so the\n // running MCP client gets the cleartext bearer at request time.\n // Stored row contains only the secret-key reference, never the value.\n servers[mergedConfigKey(scope, stored, ownerId)] =\n await toHttpServerConfigAsync(scope, ownerId, stored);\n }\n }\n for (const [fullKey, value] of Object.entries(all)) {\n const settingsKey = builtinMcpCapabilitiesSettingsKey();\n const userMatch = new RegExp(`^u:([^:]+):${settingsKey}$`).exec(fullKey);\n const orgMatch = new RegExp(`^o:([^:]+):${settingsKey}$`).exec(fullKey);\n let scope: RemoteMcpScope | null = null;\n let ownerId: string | null = null;\n if (userMatch) {\n scope = \"user\";\n ownerId = userMatch[1];\n } else if (orgMatch) {\n scope = \"org\";\n ownerId = orgMatch[1];\n }\n if (!scope || !ownerId) continue;\n const enabledIds = normalizeBuiltinMcpCapabilityIds(\n Array.isArray((value as any).enabledIds)\n ? (value as any).enabledIds.map(String)\n : [],\n );\n for (const id of enabledIds) {\n const capability = getBuiltinMcpCapability(id);\n if (!capability || !isBuiltinMcpCapabilityAvailable(capability)) {\n continue;\n }\n servers[builtinMergedConfigKey(scope, capability, ownerId)] =\n toBuiltinMcpServerConfig(capability);\n }\n }\n\n // Hub-consume: if this app is configured to consume from a remote hub\n // (AGENT_NATIVE_MCP_HUB_URL + AGENT_NATIVE_MCP_HUB_TOKEN), pull its\n // org-scope servers and merge. Hub entries use `hub_<orgId>_<name>` so\n // they never collide with local `org_<orgId>_<name>` rows.\n try {\n const hubServers = await fetchHubServers();\n for (const [mergedKey, cfg] of Object.entries(hubServers)) {\n servers[mergedKey] = cfg;\n }\n } catch (err: any) {\n console.warn(\n `[mcp-client] hub merge failed: ${err?.message ?? err}. Continuing with local config.`,\n );\n }\n\n if (Object.keys(servers).length === 0) return null;\n return { servers, source: base?.source ?? \"merged\" };\n}\n\nasync function resolveContextForRequest(event: H3Event): Promise<{\n email: string | null;\n orgId: string | null;\n role: string | null;\n}> {\n let email: string | null = null;\n try {\n const session = await getSession(event);\n email = session?.email ?? null;\n } catch {\n email = null;\n }\n let orgId: string | null = null;\n let role: string | null = null;\n try {\n const ctx = await getOrgContext(event);\n orgId = ctx.orgId;\n role = ctx.role;\n if (!email) email = ctx.email;\n } catch {\n // ignore — no org context\n }\n // No silent `local@localhost` fallback — if `getSession` returns nothing in\n // production (misconfigured deploy, expired token), the caller must reject\n // rather than silently pool every unauthenticated request under one identity.\n return { email, orgId, role };\n}\n\nasync function reconfigureManager(manager: McpClientManager): Promise<void> {\n const merged = await buildMergedConfig();\n await manager.reconfigure(merged);\n}\n\nexport function mountMcpServersRoutes(\n nitroApp: any,\n manager: McpClientManager,\n): void {\n const mountedApps: WeakSet<object> = ((\n globalThis as any\n ).__agentNativeMcpServersMountedApps ??= new WeakSet<object>());\n if (mountedApps.has(nitroApp)) return;\n mountedApps.add(nitroApp);\n\n try {\n getH3App(nitroApp).use(\n \"/_agent-native/mcp/servers\",\n defineEventHandler(async (event: H3Event) => {\n const method = getMethod(event);\n const pathname = (event.url?.pathname || \"\")\n .replace(/^\\/+/, \"\")\n .replace(/\\/+$/, \"\");\n const parts = pathname ? pathname.split(\"/\") : [];\n\n setResponseHeader(event, \"Content-Type\", \"application/json\");\n\n // POST /servers/test — dry-run a URL+headers before persisting\n if (method === \"POST\" && parts.length === 1 && parts[0] === \"test\") {\n return handleTestUrl(event);\n }\n\n // Collection root\n if (parts.length === 0) {\n if (method === \"GET\") return handleList(event, manager);\n if (method === \"POST\") return handleAdd(event, manager);\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n\n // /:id / /:id/test\n if (parts.length === 1 || parts.length === 2) {\n const id = parts[0];\n if (parts.length === 2 && parts[1] === \"test\" && method === \"POST\") {\n return handleTestExisting(event, manager, id);\n }\n if (parts.length === 1 && method === \"DELETE\") {\n return handleDelete(event, manager, id);\n }\n }\n\n setResponseStatus(event, 404);\n return { error: \"Not found\" };\n }),\n );\n getH3App(nitroApp).use(\n \"/_agent-native/mcp/builtin\",\n defineEventHandler(async (event: H3Event) => {\n const method = getMethod(event);\n const pathname = (event.url?.pathname || \"\")\n .replace(/^\\/+/, \"\")\n .replace(/\\/+$/, \"\");\n const parts = pathname ? pathname.split(\"/\") : [];\n\n setResponseHeader(event, \"Content-Type\", \"application/json\");\n if (parts.length === 0) {\n if (method === \"GET\") return handleBuiltinList(event, manager);\n if (method === \"POST\") return handleBuiltinUpdate(event, manager);\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n\n setResponseStatus(event, 404);\n return { error: \"Not found\" };\n }),\n );\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to mount MCP routes: ${err?.message ?? err}`,\n );\n }\n}\n\nasync function handleBuiltinList(\n event: H3Event,\n manager: McpClientManager,\n): Promise<{\n capabilities: ClientBuiltinCapability[];\n user: { enabledIds: BuiltinMcpCapabilityId[] };\n org: {\n enabledIds: BuiltinMcpCapabilityId[];\n orgId: string | null;\n role: string | null;\n };\n}> {\n const { email, orgId, role } = await resolveContextForRequest(event);\n const userEnabled = email\n ? await listEnabledBuiltinMcpCapabilities(\"user\", email)\n : [];\n const orgEnabled = orgId\n ? await listEnabledBuiltinMcpCapabilities(\"org\", orgId)\n : [];\n\n return {\n capabilities: BUILTIN_MCP_CAPABILITIES.map((capability) => {\n const available = isBuiltinMcpCapabilityAvailable(capability);\n const userMergedId = email\n ? builtinMergedConfigKey(\"user\", capability, email)\n : undefined;\n const orgMergedId = orgId\n ? builtinMergedConfigKey(\"org\", capability, orgId)\n : undefined;\n return {\n id: capability.id,\n serverId: capability.serverId,\n name: capability.name,\n description: capability.description,\n command: capability.command,\n args: capability.args,\n exclusiveGroup: capability.exclusiveGroup,\n available,\n unavailableReason: available\n ? undefined\n : `Only available on ${capability.platforms?.join(\", \")}`,\n notes: capability.notes,\n enabled: {\n user: userEnabled.includes(capability.id),\n org: orgEnabled.includes(capability.id),\n },\n mergedIds: {\n user: userMergedId,\n org: orgMergedId,\n },\n status: {\n user:\n userMergedId && userEnabled.includes(capability.id)\n ? statusFor(manager, userMergedId)\n : undefined,\n org:\n orgMergedId && orgEnabled.includes(capability.id)\n ? statusFor(manager, orgMergedId)\n : undefined,\n },\n };\n }),\n user: { enabledIds: userEnabled },\n org: { enabledIds: orgEnabled, orgId, role },\n };\n}\n\nasync function handleBuiltinUpdate(event: H3Event, manager: McpClientManager) {\n const body = (await readBody(event).catch(() => ({}))) as {\n scope?: unknown;\n enabledIds?: unknown;\n id?: unknown;\n enabled?: unknown;\n };\n const scope =\n body.scope === \"org\" ? \"org\" : body.scope === \"user\" ? \"user\" : null;\n if (!scope) {\n setResponseStatus(event, 400);\n return { error: 'scope must be \"user\" or \"org\"' };\n }\n\n const { email, orgId, role } = await resolveContextForRequest(event);\n let scopeId: string | null = null;\n if (scope === \"user\") {\n scopeId = email;\n } else {\n if (!orgId) {\n setResponseStatus(event, 400);\n return {\n error:\n \"You must belong to an organization to change org-scope built-ins\",\n };\n }\n if (role !== \"owner\" && role !== \"admin\") {\n setResponseStatus(event, 403);\n return {\n error: \"Only owners and admins can change org-scope MCP built-ins\",\n };\n }\n scopeId = orgId;\n }\n if (!scopeId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n\n if (Array.isArray(body.enabledIds)) {\n for (const rawId of body.enabledIds) {\n const error = validateBuiltinCapabilityForEnable(String(rawId));\n if (error) {\n setResponseStatus(event, 400);\n return { error };\n }\n }\n await setEnabledBuiltinMcpCapabilities(\n scope,\n scopeId,\n body.enabledIds.map(String),\n );\n } else if (typeof body.id === \"string\" && typeof body.enabled === \"boolean\") {\n if (body.enabled) {\n const error = validateBuiltinCapabilityForEnable(body.id);\n if (error) {\n setResponseStatus(event, 400);\n return { error };\n }\n } else if (!getBuiltinMcpCapability(body.id)) {\n setResponseStatus(event, 400);\n return { error: `Unknown built-in MCP capability \"${body.id}\"` };\n }\n const result = await setBuiltinMcpCapabilityEnabled(\n scope,\n scopeId,\n body.id,\n body.enabled,\n );\n if (!result) {\n setResponseStatus(event, 400);\n return { error: `Unknown built-in MCP capability \"${body.id}\"` };\n }\n } else {\n setResponseStatus(event, 400);\n return { error: \"Provide enabledIds or id + enabled\" };\n }\n\n await reconfigureManager(manager);\n return handleBuiltinList(event, manager);\n}\n\nfunction validateBuiltinCapabilityForEnable(id: string): string | null {\n const capability = getBuiltinMcpCapability(id);\n if (!capability) return `Unknown built-in MCP capability \"${id}\"`;\n if (!isBuiltinMcpCapabilityAvailable(capability)) {\n return `${capability.name} is only available on ${capability.platforms?.join(\", \")}`;\n }\n return null;\n}\n\nasync function handleList(\n event: H3Event,\n manager: McpClientManager,\n): Promise<{\n user: ClientServer[];\n org: ClientServer[];\n orgId: string | null;\n role: string | null;\n}> {\n const { email, orgId, role } = await resolveContextForRequest(event);\n const userServers = email ? await listRemoteServers(\"user\", email) : [];\n const orgServers = orgId ? await listRemoteServers(\"org\", orgId) : [];\n return {\n user: userServers.map((s) =>\n projectForClient(\n s,\n \"user\",\n email ?? \"\",\n statusFor(manager, mergedConfigKey(\"user\", s, email ?? \"\")),\n ),\n ),\n org: orgServers.map((s) =>\n projectForClient(\n s,\n \"org\",\n orgId ?? \"\",\n statusFor(manager, mergedConfigKey(\"org\", s, orgId ?? \"\")),\n ),\n ),\n orgId,\n role,\n };\n}\n\nasync function handleAdd(event: H3Event, manager: McpClientManager) {\n const body = (await readBody(event).catch(() => ({}))) as {\n scope?: unknown;\n name?: unknown;\n url?: unknown;\n headers?: unknown;\n description?: unknown;\n };\n const scope =\n body.scope === \"org\" ? \"org\" : body.scope === \"user\" ? \"user\" : null;\n if (!scope) {\n setResponseStatus(event, 400);\n return { error: 'scope must be \"user\" or \"org\"' };\n }\n const name = typeof body.name === \"string\" ? body.name : \"\";\n const url = typeof body.url === \"string\" ? body.url : \"\";\n if (!name.trim() || !url.trim()) {\n setResponseStatus(event, 400);\n return { error: \"name and url are required\" };\n }\n const headers = normalizeHeaders(body.headers);\n const description =\n typeof body.description === \"string\" ? body.description : undefined;\n\n const { email, orgId, role } = await resolveContextForRequest(event);\n\n let scopeId: string | null = null;\n if (scope === \"user\") {\n scopeId = email;\n } else {\n if (!orgId) {\n setResponseStatus(event, 400);\n return {\n error: \"You must belong to an organization to add an org-scope server\",\n };\n }\n if (role !== \"owner\" && role !== \"admin\") {\n setResponseStatus(event, 403);\n return { error: \"Only owners and admins can add org-scope MCP servers\" };\n }\n scopeId = orgId;\n }\n if (!scopeId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n\n const result = await addRemoteServer(scope, scopeId, {\n name,\n url,\n headers,\n description,\n });\n if (result.ok !== true) {\n setResponseStatus(event, 400);\n return { error: result.error };\n }\n\n await reconfigureManager(manager);\n const mergedId = mergedConfigKey(scope, result.server, scopeId);\n return {\n ok: true,\n server: projectForClient(\n result.server,\n scope,\n scopeId,\n statusFor(manager, mergedId),\n ),\n };\n}\n\nasync function handleDelete(\n event: H3Event,\n manager: McpClientManager,\n id: string,\n) {\n const scope = getQuery(event).scope;\n const parsedScope =\n scope === \"org\" ? \"org\" : scope === \"user\" ? \"user\" : null;\n if (!parsedScope) {\n setResponseStatus(event, 400);\n return { error: 'scope query param must be \"user\" or \"org\"' };\n }\n const { email, orgId, role } = await resolveContextForRequest(event);\n\n let scopeId: string | null = null;\n if (parsedScope === \"user\") {\n scopeId = email;\n } else {\n if (!orgId) {\n setResponseStatus(event, 400);\n return { error: \"No active organization\" };\n }\n if (role !== \"owner\" && role !== \"admin\") {\n setResponseStatus(event, 403);\n return {\n error: \"Only owners and admins can remove org-scope MCP servers\",\n };\n }\n scopeId = orgId;\n }\n if (!scopeId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n\n const removed = await removeRemoteServer(parsedScope, scopeId, id);\n if (!removed) {\n setResponseStatus(event, 404);\n return { error: \"Server not found\" };\n }\n await reconfigureManager(manager);\n return { ok: true };\n}\n\nasync function handleTestUrl(event: H3Event) {\n const { email, orgId } = await resolveContextForRequest(event);\n if (!email && !orgId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n\n const body = (await readBody(event).catch(() => ({}))) as {\n url?: unknown;\n headers?: unknown;\n };\n const url = typeof body.url === \"string\" ? body.url : \"\";\n const check = validateRemoteUrl(url);\n if (!check.ok) {\n setResponseStatus(event, 400);\n return { ok: false, error: check.error };\n }\n const headers = normalizeHeaders(body.headers);\n const result = await tryConnect(check.url!.toString(), headers);\n if (result.ok !== true) {\n setResponseStatus(event, 400);\n return { ok: false, error: result.error };\n }\n return { ok: true, toolCount: result.toolCount, tools: result.tools };\n}\n\nasync function handleTestExisting(\n event: H3Event,\n manager: McpClientManager,\n id: string,\n) {\n const scope = getQuery(event).scope;\n const parsedScope =\n scope === \"org\" ? \"org\" : scope === \"user\" ? \"user\" : null;\n if (!parsedScope) {\n setResponseStatus(event, 400);\n return { error: 'scope query param must be \"user\" or \"org\"' };\n }\n const { email, orgId } = await resolveContextForRequest(event);\n const scopeId = parsedScope === \"user\" ? email : orgId;\n if (!scopeId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n const list = await listRemoteServers(parsedScope, scopeId);\n const server = list.find((s) => s.id === id);\n if (!server) {\n setResponseStatus(event, 404);\n return { error: \"Server not found\" };\n }\n const result = await tryConnect(server.url, server.headers);\n if (result.ok !== true) {\n setResponseStatus(event, 400);\n return { ok: false, error: result.error };\n }\n return { ok: true, toolCount: result.toolCount, tools: result.tools };\n}\n\nasync function tryConnect(\n url: string,\n headers?: Record<string, string>,\n): Promise<\n | { ok: true; toolCount: number; tools: string[] }\n | { ok: false; error: string }\n> {\n try {\n const [{ Client }, { StreamableHTTPClientTransport }] = await Promise.all([\n import(\"@modelcontextprotocol/sdk/client/index.js\"),\n import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\"),\n ]);\n const requestInit: Record<string, unknown> = {};\n if (headers && Object.keys(headers).length > 0) {\n requestInit.headers = headers;\n }\n const transport = new StreamableHTTPClientTransport(new URL(url), {\n requestInit,\n });\n const client = new Client(\n { name: \"agent-native-mcp-client-test\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n try {\n await client.connect(transport);\n const listed = await client.listTools();\n const names = ((listed?.tools ?? []) as Array<{ name: string }>).map(\n (t) => t.name,\n );\n return { ok: true, toolCount: names.length, tools: names };\n } finally {\n try {\n await client.close();\n } catch {}\n try {\n await transport.close();\n } catch {}\n }\n } catch (err: any) {\n return { ok: false, error: formatMcpConnectError(err) };\n }\n}\n\nfunction normalizeHeaders(input: unknown): Record<string, string> | undefined {\n if (!input || typeof input !== \"object\") return undefined;\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(input as Record<string, unknown>)) {\n if (typeof k !== \"string\" || !k.trim()) continue;\n if (typeof v !== \"string\") continue;\n out[k.trim()] = v;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n"]}
1
+ {"version":3,"file":"routes.js","sourceRoot":"","sources":["../../src/mcp-client/routes.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * HTTP routes for user- and org-scope remote MCP server management.\n *\n * Mounted under `/_agent-native/mcp/servers` by `agent-chat-plugin` —\n * requires a reference to the running `McpClientManager` so mutations can\n * hot-reload the configured server set.\n *\n * GET /_agent-native/mcp/servers list user + org servers\n * POST /_agent-native/mcp/servers add a server\n * DELETE /_agent-native/mcp/servers/:id remove a server (scope via ?scope=)\n * POST /_agent-native/mcp/servers/:id/test dry-run connect (no persist)\n * POST /_agent-native/mcp/servers/test dry-run a URL before persisting\n * GET /_agent-native/mcp/builtin list built-in capability toggles\n * POST /_agent-native/mcp/builtin update built-in capability toggles\n * POST /_agent-native/mcp/apps/call-tool mediated same-server app tool call\n * POST /_agent-native/mcp/apps/list-tools list tools visible to an app iframe\n * POST /_agent-native/mcp/apps/read-resource read a ui:// app resource\n */\n\nimport {\n defineEventHandler,\n getMethod,\n getQuery,\n setResponseHeader,\n setResponseStatus,\n type H3Event,\n} from \"h3\";\nimport { getH3App } from \"../server/framework-request-handler.js\";\nimport { readBody } from \"../server/h3-helpers.js\";\nimport { getOrgContext } from \"../org/context.js\";\nimport { getSession } from \"../server/auth.js\";\nimport { runWithRequestContext } from \"../server/request-context.js\";\nimport { getAllSettings } from \"../settings/store.js\";\nimport {\n buildMcpToolName,\n parseMcpToolName,\n type McpClientManager,\n type McpTool,\n} from \"./manager.js\";\nimport type { McpConfig, McpServerConfig } from \"./config.js\";\nimport { loadMcpConfig, autoDetectMcpConfig } from \"./config.js\";\nimport { formatMcpConnectError } from \"./errors.js\";\nimport {\n BUILTIN_MCP_CAPABILITIES,\n getBuiltinMcpCapability,\n isBuiltinMcpCapabilityAvailable,\n normalizeBuiltinMcpCapabilityIds,\n toBuiltinMcpServerConfig,\n type BuiltinMcpCapability,\n type BuiltinMcpCapabilityId,\n} from \"./builtin-capabilities.js\";\nimport {\n builtinMcpCapabilitiesSettingsKey,\n listEnabledBuiltinMcpCapabilities,\n setBuiltinMcpCapabilityEnabled,\n setEnabledBuiltinMcpCapabilities,\n} from \"./builtin-store.js\";\nimport {\n addRemoteServer,\n listRemoteServers,\n mergedConfigKey,\n removeRemoteServer,\n toHttpServerConfigAsync,\n validateRemoteUrl,\n type RemoteMcpScope,\n type StoredRemoteMcpServer,\n} from \"./remote-store.js\";\nimport { fetchHubServers } from \"./hub-client.js\";\nimport { isMcpToolAllowedForRequest } from \"./visibility.js\";\nimport { isToolVisibilityModelOnly } from \"@modelcontextprotocol/ext-apps/app-bridge\";\n\nexport { formatMcpConnectError } from \"./errors.js\";\n\n/** Redact obvious auth header values before sending to the client. */\nfunction redactHeaders(\n headers?: Record<string, string>,\n): Record<string, { set: true }> | undefined {\n if (!headers) return undefined;\n const out: Record<string, { set: true }> = {};\n for (const k of Object.keys(headers)) out[k] = { set: true };\n return out;\n}\n\nfunction projectForClient(\n stored: StoredRemoteMcpServer,\n scope: RemoteMcpScope,\n ownerId: string,\n status: ServerStatus,\n): ClientServer {\n return {\n id: stored.id,\n scope,\n name: stored.name,\n url: stored.url,\n headers: redactHeaders(stored.headers),\n description: stored.description,\n createdAt: stored.createdAt,\n mergedId: mergedConfigKey(scope, stored, ownerId),\n status,\n };\n}\n\nexport interface ClientServer {\n id: string;\n scope: RemoteMcpScope;\n name: string;\n url: string;\n headers?: Record<string, { set: true }>;\n description?: string;\n createdAt: number;\n /** The key under which this server is registered in the running MCP manager. */\n mergedId: string;\n status: ServerStatus;\n}\n\nexport interface ClientBuiltinCapability {\n id: BuiltinMcpCapabilityId;\n serverId: string;\n name: string;\n description: string;\n command: string;\n args: string[];\n exclusiveGroup?: string;\n available: boolean;\n unavailableReason?: string;\n notes?: string;\n enabled: { user: boolean; org: boolean };\n mergedIds: { user?: string; org?: string };\n status: { user?: ServerStatus; org?: ServerStatus };\n}\n\ntype ServerStatus =\n | { state: \"connected\"; toolCount: number }\n | { state: \"error\"; error: string }\n | { state: \"unknown\" };\n\nfunction statusFor(manager: McpClientManager, mergedId: string): ServerStatus {\n const snap = manager.getStatus();\n if (snap.connectedServers.includes(mergedId)) {\n const toolCount = snap.tools.filter((t) => t.source === mergedId).length;\n return { state: \"connected\", toolCount };\n }\n if (snap.errors[mergedId]) {\n return { state: \"error\", error: snap.errors[mergedId] };\n }\n if (snap.configuredServers.includes(mergedId)) {\n return { state: \"unknown\" };\n }\n return { state: \"unknown\" };\n}\n\nfunction pseudoStoredBuiltin(\n capability: BuiltinMcpCapability,\n): StoredRemoteMcpServer {\n return {\n id: `builtin_${capability.id}`,\n name: capability.serverId,\n url: `builtin:${capability.id}`,\n description: capability.description,\n createdAt: 0,\n };\n}\n\nexport function builtinMergedConfigKey(\n scope: RemoteMcpScope,\n capability: BuiltinMcpCapability,\n ownerId: string,\n): string {\n return mergedConfigKey(scope, pseudoStoredBuiltin(capability), ownerId);\n}\n\n/**\n * Build the merged MCP config the manager should run with: file/env config\n * plus **every** user-scope and org-scope remote server persisted in the\n * settings store. Scanning all scopes means a mutation from one user's\n * session never drops another user's servers from the running manager.\n *\n * Each persisted server's merged key includes its owner discriminator\n * (`user_<emailhash>_<name>` or `org_<orgId>_<name>`) so two users' servers\n * with the same name coexist; the request-time gate in\n * `isMcpToolAllowedForRequest` then scopes tool visibility back down to the\n * calling user.\n */\nexport async function buildMergedConfig(): Promise<McpConfig | null> {\n const base = loadMcpConfig() ?? autoDetectMcpConfig();\n const servers: Record<string, McpServerConfig> = { ...(base?.servers ?? {}) };\n\n const all = await getAllSettings().catch(() => ({}));\n for (const [fullKey, value] of Object.entries(all)) {\n const userMatch = /^u:([^:]+):mcp-servers-remote$/.exec(fullKey);\n const orgMatch = /^o:([^:]+):mcp-servers-remote$/.exec(fullKey);\n let scope: RemoteMcpScope | null = null;\n let ownerId: string | null = null;\n if (userMatch) {\n scope = \"user\";\n ownerId = userMatch[1];\n } else if (orgMatch) {\n scope = \"org\";\n ownerId = orgMatch[1];\n }\n if (!scope || !ownerId) continue;\n const list = (value as { servers?: StoredRemoteMcpServer[] }).servers;\n if (!Array.isArray(list)) continue;\n for (const stored of list) {\n if (!stored || typeof stored.url !== \"string\" || !stored.name) continue;\n // Async resolve: decrypts `headerSecretKey` from app_secrets so the\n // running MCP client gets the cleartext bearer at request time.\n // Stored row contains only the secret-key reference, never the value.\n servers[mergedConfigKey(scope, stored, ownerId)] =\n await toHttpServerConfigAsync(scope, ownerId, stored);\n }\n }\n for (const [fullKey, value] of Object.entries(all)) {\n const settingsKey = builtinMcpCapabilitiesSettingsKey();\n const userMatch = new RegExp(`^u:([^:]+):${settingsKey}$`).exec(fullKey);\n const orgMatch = new RegExp(`^o:([^:]+):${settingsKey}$`).exec(fullKey);\n let scope: RemoteMcpScope | null = null;\n let ownerId: string | null = null;\n if (userMatch) {\n scope = \"user\";\n ownerId = userMatch[1];\n } else if (orgMatch) {\n scope = \"org\";\n ownerId = orgMatch[1];\n }\n if (!scope || !ownerId) continue;\n const enabledIds = normalizeBuiltinMcpCapabilityIds(\n Array.isArray((value as any).enabledIds)\n ? (value as any).enabledIds.map(String)\n : [],\n );\n for (const id of enabledIds) {\n const capability = getBuiltinMcpCapability(id);\n if (!capability || !isBuiltinMcpCapabilityAvailable(capability)) {\n continue;\n }\n servers[builtinMergedConfigKey(scope, capability, ownerId)] =\n toBuiltinMcpServerConfig(capability);\n }\n }\n\n // Hub-consume: if this app is configured to consume from a remote hub\n // (AGENT_NATIVE_MCP_HUB_URL + AGENT_NATIVE_MCP_HUB_TOKEN), pull its\n // org-scope servers and merge. Hub entries use `hub_<orgId>_<name>` so\n // they never collide with local `org_<orgId>_<name>` rows.\n try {\n const hubServers = await fetchHubServers();\n for (const [mergedKey, cfg] of Object.entries(hubServers)) {\n servers[mergedKey] = cfg;\n }\n } catch (err: any) {\n console.warn(\n `[mcp-client] hub merge failed: ${err?.message ?? err}. Continuing with local config.`,\n );\n }\n\n if (Object.keys(servers).length === 0) return null;\n return { servers, source: base?.source ?? \"merged\" };\n}\n\nasync function resolveContextForRequest(event: H3Event): Promise<{\n email: string | null;\n orgId: string | null;\n role: string | null;\n}> {\n let email: string | null = null;\n try {\n const session = await getSession(event);\n email = session?.email ?? null;\n } catch {\n email = null;\n }\n let orgId: string | null = null;\n let role: string | null = null;\n try {\n const ctx = await getOrgContext(event);\n orgId = ctx.orgId;\n role = ctx.role;\n if (!email) email = ctx.email;\n } catch {\n // ignore — no org context\n }\n // No silent `local@localhost` fallback — if `getSession` returns nothing in\n // production (misconfigured deploy, expired token), the caller must reject\n // rather than silently pool every unauthenticated request under one identity.\n return { email, orgId, role };\n}\n\nasync function reconfigureManager(manager: McpClientManager): Promise<void> {\n const merged = await buildMergedConfig();\n await manager.reconfigure(merged);\n}\n\nexport function mountMcpServersRoutes(\n nitroApp: any,\n manager: McpClientManager,\n): void {\n const mountedApps: WeakSet<object> = ((\n globalThis as any\n ).__agentNativeMcpServersMountedApps ??= new WeakSet<object>());\n if (mountedApps.has(nitroApp)) return;\n mountedApps.add(nitroApp);\n\n try {\n getH3App(nitroApp).use(\n \"/_agent-native/mcp/servers\",\n defineEventHandler(async (event: H3Event) => {\n const method = getMethod(event);\n const pathname = (event.url?.pathname || \"\")\n .replace(/^\\/+/, \"\")\n .replace(/\\/+$/, \"\");\n const parts = pathname ? pathname.split(\"/\") : [];\n\n setResponseHeader(event, \"Content-Type\", \"application/json\");\n\n // POST /servers/test — dry-run a URL+headers before persisting\n if (method === \"POST\" && parts.length === 1 && parts[0] === \"test\") {\n return handleTestUrl(event);\n }\n\n // Collection root\n if (parts.length === 0) {\n if (method === \"GET\") return handleList(event, manager);\n if (method === \"POST\") return handleAdd(event, manager);\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n\n // /:id / /:id/test\n if (parts.length === 1 || parts.length === 2) {\n const id = parts[0];\n if (parts.length === 2 && parts[1] === \"test\" && method === \"POST\") {\n return handleTestExisting(event, manager, id);\n }\n if (parts.length === 1 && method === \"DELETE\") {\n return handleDelete(event, manager, id);\n }\n }\n\n setResponseStatus(event, 404);\n return { error: \"Not found\" };\n }),\n );\n getH3App(nitroApp).use(\n \"/_agent-native/mcp/builtin\",\n defineEventHandler(async (event: H3Event) => {\n const method = getMethod(event);\n const pathname = (event.url?.pathname || \"\")\n .replace(/^\\/+/, \"\")\n .replace(/\\/+$/, \"\");\n const parts = pathname ? pathname.split(\"/\") : [];\n\n setResponseHeader(event, \"Content-Type\", \"application/json\");\n if (parts.length === 0) {\n if (method === \"GET\") return handleBuiltinList(event, manager);\n if (method === \"POST\") return handleBuiltinUpdate(event, manager);\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n\n setResponseStatus(event, 404);\n return { error: \"Not found\" };\n }),\n );\n getH3App(nitroApp).use(\n \"/_agent-native/mcp/apps\",\n defineEventHandler(async (event: H3Event) => {\n const method = getMethod(event);\n const pathname = (event.url?.pathname || \"\")\n .replace(/^\\/+/, \"\")\n .replace(/\\/+$/, \"\");\n const parts = pathname ? pathname.split(\"/\") : [];\n\n setResponseHeader(event, \"Content-Type\", \"application/json\");\n if (method !== \"POST\") {\n setResponseStatus(event, 405);\n return { error: \"Method not allowed\" };\n }\n\n if (parts.length === 1 && parts[0] === \"call-tool\") {\n return handleMcpAppCallTool(event, manager);\n }\n if (parts.length === 1 && parts[0] === \"list-tools\") {\n return handleMcpAppListTools(event, manager);\n }\n if (parts.length === 1 && parts[0] === \"read-resource\") {\n return handleMcpAppReadResource(event, manager);\n }\n\n setResponseStatus(event, 404);\n return { error: \"Not found\" };\n }),\n );\n } catch (err: any) {\n console.warn(\n `[mcp-client] Failed to mount MCP routes: ${err?.message ?? err}`,\n );\n }\n}\n\nasync function withMcpAppRequestContext<T>(\n event: H3Event,\n fn: () => Promise<T>,\n): Promise<T | { error: string }> {\n const { email, orgId } = await resolveContextForRequest(event);\n if (!email && process.env.NODE_ENV === \"production\") {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n return runWithRequestContext(\n {\n userEmail: email ?? undefined,\n orgId: orgId ?? undefined,\n },\n fn,\n ) as Promise<T>;\n}\n\nfunction serverHasVisibleTools(\n manager: McpClientManager,\n serverId: string,\n): boolean {\n return manager\n .getToolsForServer(serverId)\n .some((tool) => isMcpToolAllowedForRequest(tool.name));\n}\n\nfunction normalizeSameServerToolName(\n serverId: string,\n rawName: unknown,\n): string | null {\n if (typeof rawName !== \"string\" || !rawName.trim()) return null;\n const name = rawName.trim();\n const parsed = parseMcpToolName(name);\n if (!parsed) return name;\n if (parsed.serverId !== serverId) return null;\n return parsed.toolName;\n}\n\nfunction isVisibleToMcpApp(tool: McpTool): boolean {\n try {\n return !isToolVisibilityModelOnly(tool.raw as any);\n } catch {\n return true;\n }\n}\n\nfunction mcpToolForClient(tool: McpTool) {\n return {\n name: tool.originalName,\n ...(tool.title ? { title: tool.title } : {}),\n description: tool.description,\n inputSchema: tool.inputSchema,\n ...(tool.outputSchema ? { outputSchema: tool.outputSchema } : {}),\n ...(tool.annotations ? { annotations: tool.annotations } : {}),\n ...(tool._meta ? { _meta: tool._meta } : {}),\n };\n}\n\nasync function handleMcpAppCallTool(event: H3Event, manager: McpClientManager) {\n const body = (await readBody(event).catch(() => ({}))) as {\n serverId?: unknown;\n toolName?: unknown;\n arguments?: unknown;\n };\n const serverId = typeof body.serverId === \"string\" ? body.serverId : \"\";\n const originalToolName = normalizeSameServerToolName(serverId, body.toolName);\n if (!serverId || !originalToolName) {\n setResponseStatus(event, 400);\n return { error: \"serverId and same-server toolName are required\" };\n }\n const prefixedName = buildMcpToolName(serverId, originalToolName);\n\n return withMcpAppRequestContext(event, async () => {\n if (!isMcpToolAllowedForRequest(prefixedName)) {\n setResponseStatus(event, 403);\n return { error: \"MCP tool is not available in this request scope\" };\n }\n try {\n return await manager.callTool(\n prefixedName,\n body.arguments && typeof body.arguments === \"object\"\n ? (body.arguments as Record<string, unknown>)\n : {},\n );\n } catch (err: any) {\n setResponseStatus(event, 400);\n return { error: err?.message ?? \"MCP tool call failed\" };\n }\n });\n}\n\nasync function handleMcpAppListTools(\n event: H3Event,\n manager: McpClientManager,\n) {\n const body = (await readBody(event).catch(() => ({}))) as {\n serverId?: unknown;\n };\n const serverId = typeof body.serverId === \"string\" ? body.serverId : \"\";\n if (!serverId) {\n setResponseStatus(event, 400);\n return { error: \"serverId is required\" };\n }\n return withMcpAppRequestContext(event, async () => {\n if (\n !manager.hasServer(serverId) ||\n !serverHasVisibleTools(manager, serverId)\n ) {\n setResponseStatus(event, 403);\n return { error: \"MCP server is not available in this request scope\" };\n }\n return {\n tools: manager\n .getToolsForServer(serverId)\n .filter((tool) => isMcpToolAllowedForRequest(tool.name))\n .filter(isVisibleToMcpApp)\n .map(mcpToolForClient),\n };\n });\n}\n\nasync function handleMcpAppReadResource(\n event: H3Event,\n manager: McpClientManager,\n) {\n const body = (await readBody(event).catch(() => ({}))) as {\n serverId?: unknown;\n uri?: unknown;\n };\n const serverId = typeof body.serverId === \"string\" ? body.serverId : \"\";\n const uri = typeof body.uri === \"string\" ? body.uri : \"\";\n if (!serverId || !uri.startsWith(\"ui://\")) {\n setResponseStatus(event, 400);\n return { error: \"serverId and ui:// uri are required\" };\n }\n return withMcpAppRequestContext(event, async () => {\n if (\n !manager.hasServer(serverId) ||\n !serverHasVisibleTools(manager, serverId)\n ) {\n setResponseStatus(event, 403);\n return { error: \"MCP server is not available in this request scope\" };\n }\n try {\n return await manager.readResource(serverId, uri);\n } catch (err: any) {\n setResponseStatus(event, 400);\n return { error: err?.message ?? \"MCP resource read failed\" };\n }\n });\n}\n\nasync function handleBuiltinList(\n event: H3Event,\n manager: McpClientManager,\n): Promise<{\n capabilities: ClientBuiltinCapability[];\n user: { enabledIds: BuiltinMcpCapabilityId[] };\n org: {\n enabledIds: BuiltinMcpCapabilityId[];\n orgId: string | null;\n role: string | null;\n };\n}> {\n const { email, orgId, role } = await resolveContextForRequest(event);\n const userEnabled = email\n ? await listEnabledBuiltinMcpCapabilities(\"user\", email)\n : [];\n const orgEnabled = orgId\n ? await listEnabledBuiltinMcpCapabilities(\"org\", orgId)\n : [];\n\n return {\n capabilities: BUILTIN_MCP_CAPABILITIES.map((capability) => {\n const available = isBuiltinMcpCapabilityAvailable(capability);\n const userMergedId = email\n ? builtinMergedConfigKey(\"user\", capability, email)\n : undefined;\n const orgMergedId = orgId\n ? builtinMergedConfigKey(\"org\", capability, orgId)\n : undefined;\n return {\n id: capability.id,\n serverId: capability.serverId,\n name: capability.name,\n description: capability.description,\n command: capability.command,\n args: capability.args,\n exclusiveGroup: capability.exclusiveGroup,\n available,\n unavailableReason: available\n ? undefined\n : `Only available on ${capability.platforms?.join(\", \")}`,\n notes: capability.notes,\n enabled: {\n user: userEnabled.includes(capability.id),\n org: orgEnabled.includes(capability.id),\n },\n mergedIds: {\n user: userMergedId,\n org: orgMergedId,\n },\n status: {\n user:\n userMergedId && userEnabled.includes(capability.id)\n ? statusFor(manager, userMergedId)\n : undefined,\n org:\n orgMergedId && orgEnabled.includes(capability.id)\n ? statusFor(manager, orgMergedId)\n : undefined,\n },\n };\n }),\n user: { enabledIds: userEnabled },\n org: { enabledIds: orgEnabled, orgId, role },\n };\n}\n\nasync function handleBuiltinUpdate(event: H3Event, manager: McpClientManager) {\n const body = (await readBody(event).catch(() => ({}))) as {\n scope?: unknown;\n enabledIds?: unknown;\n id?: unknown;\n enabled?: unknown;\n };\n const scope =\n body.scope === \"org\" ? \"org\" : body.scope === \"user\" ? \"user\" : null;\n if (!scope) {\n setResponseStatus(event, 400);\n return { error: 'scope must be \"user\" or \"org\"' };\n }\n\n const { email, orgId, role } = await resolveContextForRequest(event);\n let scopeId: string | null = null;\n if (scope === \"user\") {\n scopeId = email;\n } else {\n if (!orgId) {\n setResponseStatus(event, 400);\n return {\n error:\n \"You must belong to an organization to change org-scope built-ins\",\n };\n }\n if (role !== \"owner\" && role !== \"admin\") {\n setResponseStatus(event, 403);\n return {\n error: \"Only owners and admins can change org-scope MCP built-ins\",\n };\n }\n scopeId = orgId;\n }\n if (!scopeId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n\n if (Array.isArray(body.enabledIds)) {\n for (const rawId of body.enabledIds) {\n const error = validateBuiltinCapabilityForEnable(String(rawId));\n if (error) {\n setResponseStatus(event, 400);\n return { error };\n }\n }\n await setEnabledBuiltinMcpCapabilities(\n scope,\n scopeId,\n body.enabledIds.map(String),\n );\n } else if (typeof body.id === \"string\" && typeof body.enabled === \"boolean\") {\n if (body.enabled) {\n const error = validateBuiltinCapabilityForEnable(body.id);\n if (error) {\n setResponseStatus(event, 400);\n return { error };\n }\n } else if (!getBuiltinMcpCapability(body.id)) {\n setResponseStatus(event, 400);\n return { error: `Unknown built-in MCP capability \"${body.id}\"` };\n }\n const result = await setBuiltinMcpCapabilityEnabled(\n scope,\n scopeId,\n body.id,\n body.enabled,\n );\n if (!result) {\n setResponseStatus(event, 400);\n return { error: `Unknown built-in MCP capability \"${body.id}\"` };\n }\n } else {\n setResponseStatus(event, 400);\n return { error: \"Provide enabledIds or id + enabled\" };\n }\n\n await reconfigureManager(manager);\n return handleBuiltinList(event, manager);\n}\n\nfunction validateBuiltinCapabilityForEnable(id: string): string | null {\n const capability = getBuiltinMcpCapability(id);\n if (!capability) return `Unknown built-in MCP capability \"${id}\"`;\n if (!isBuiltinMcpCapabilityAvailable(capability)) {\n return `${capability.name} is only available on ${capability.platforms?.join(\", \")}`;\n }\n return null;\n}\n\nasync function handleList(\n event: H3Event,\n manager: McpClientManager,\n): Promise<{\n user: ClientServer[];\n org: ClientServer[];\n orgId: string | null;\n role: string | null;\n}> {\n const { email, orgId, role } = await resolveContextForRequest(event);\n const userServers = email ? await listRemoteServers(\"user\", email) : [];\n const orgServers = orgId ? await listRemoteServers(\"org\", orgId) : [];\n return {\n user: userServers.map((s) =>\n projectForClient(\n s,\n \"user\",\n email ?? \"\",\n statusFor(manager, mergedConfigKey(\"user\", s, email ?? \"\")),\n ),\n ),\n org: orgServers.map((s) =>\n projectForClient(\n s,\n \"org\",\n orgId ?? \"\",\n statusFor(manager, mergedConfigKey(\"org\", s, orgId ?? \"\")),\n ),\n ),\n orgId,\n role,\n };\n}\n\nasync function handleAdd(event: H3Event, manager: McpClientManager) {\n const body = (await readBody(event).catch(() => ({}))) as {\n scope?: unknown;\n name?: unknown;\n url?: unknown;\n headers?: unknown;\n description?: unknown;\n };\n const scope =\n body.scope === \"org\" ? \"org\" : body.scope === \"user\" ? \"user\" : null;\n if (!scope) {\n setResponseStatus(event, 400);\n return { error: 'scope must be \"user\" or \"org\"' };\n }\n const name = typeof body.name === \"string\" ? body.name : \"\";\n const url = typeof body.url === \"string\" ? body.url : \"\";\n if (!name.trim() || !url.trim()) {\n setResponseStatus(event, 400);\n return { error: \"name and url are required\" };\n }\n const headers = normalizeHeaders(body.headers);\n const description =\n typeof body.description === \"string\" ? body.description : undefined;\n\n const { email, orgId, role } = await resolveContextForRequest(event);\n\n let scopeId: string | null = null;\n if (scope === \"user\") {\n scopeId = email;\n } else {\n if (!orgId) {\n setResponseStatus(event, 400);\n return {\n error: \"You must belong to an organization to add an org-scope server\",\n };\n }\n if (role !== \"owner\" && role !== \"admin\") {\n setResponseStatus(event, 403);\n return { error: \"Only owners and admins can add org-scope MCP servers\" };\n }\n scopeId = orgId;\n }\n if (!scopeId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n\n const result = await addRemoteServer(scope, scopeId, {\n name,\n url,\n headers,\n description,\n });\n if (result.ok !== true) {\n setResponseStatus(event, 400);\n return { error: result.error };\n }\n\n await reconfigureManager(manager);\n const mergedId = mergedConfigKey(scope, result.server, scopeId);\n return {\n ok: true,\n server: projectForClient(\n result.server,\n scope,\n scopeId,\n statusFor(manager, mergedId),\n ),\n };\n}\n\nasync function handleDelete(\n event: H3Event,\n manager: McpClientManager,\n id: string,\n) {\n const scope = getQuery(event).scope;\n const parsedScope =\n scope === \"org\" ? \"org\" : scope === \"user\" ? \"user\" : null;\n if (!parsedScope) {\n setResponseStatus(event, 400);\n return { error: 'scope query param must be \"user\" or \"org\"' };\n }\n const { email, orgId, role } = await resolveContextForRequest(event);\n\n let scopeId: string | null = null;\n if (parsedScope === \"user\") {\n scopeId = email;\n } else {\n if (!orgId) {\n setResponseStatus(event, 400);\n return { error: \"No active organization\" };\n }\n if (role !== \"owner\" && role !== \"admin\") {\n setResponseStatus(event, 403);\n return {\n error: \"Only owners and admins can remove org-scope MCP servers\",\n };\n }\n scopeId = orgId;\n }\n if (!scopeId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n\n const removed = await removeRemoteServer(parsedScope, scopeId, id);\n if (!removed) {\n setResponseStatus(event, 404);\n return { error: \"Server not found\" };\n }\n await reconfigureManager(manager);\n return { ok: true };\n}\n\nasync function handleTestUrl(event: H3Event) {\n const { email, orgId } = await resolveContextForRequest(event);\n if (!email && !orgId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n\n const body = (await readBody(event).catch(() => ({}))) as {\n url?: unknown;\n headers?: unknown;\n };\n const url = typeof body.url === \"string\" ? body.url : \"\";\n const check = validateRemoteUrl(url);\n if (!check.ok) {\n setResponseStatus(event, 400);\n return { ok: false, error: check.error };\n }\n const headers = normalizeHeaders(body.headers);\n const result = await tryConnect(check.url!.toString(), headers);\n if (result.ok !== true) {\n setResponseStatus(event, 400);\n return { ok: false, error: result.error };\n }\n return { ok: true, toolCount: result.toolCount, tools: result.tools };\n}\n\nasync function handleTestExisting(\n event: H3Event,\n manager: McpClientManager,\n id: string,\n) {\n const scope = getQuery(event).scope;\n const parsedScope =\n scope === \"org\" ? \"org\" : scope === \"user\" ? \"user\" : null;\n if (!parsedScope) {\n setResponseStatus(event, 400);\n return { error: 'scope query param must be \"user\" or \"org\"' };\n }\n const { email, orgId } = await resolveContextForRequest(event);\n const scopeId = parsedScope === \"user\" ? email : orgId;\n if (!scopeId) {\n setResponseStatus(event, 401);\n return { error: \"Authentication required\" };\n }\n const list = await listRemoteServers(parsedScope, scopeId);\n const server = list.find((s) => s.id === id);\n if (!server) {\n setResponseStatus(event, 404);\n return { error: \"Server not found\" };\n }\n const result = await tryConnect(server.url, server.headers);\n if (result.ok !== true) {\n setResponseStatus(event, 400);\n return { ok: false, error: result.error };\n }\n return { ok: true, toolCount: result.toolCount, tools: result.tools };\n}\n\nasync function tryConnect(\n url: string,\n headers?: Record<string, string>,\n): Promise<\n | { ok: true; toolCount: number; tools: string[] }\n | { ok: false; error: string }\n> {\n try {\n const [{ Client }, { StreamableHTTPClientTransport }] = await Promise.all([\n import(\"@modelcontextprotocol/sdk/client/index.js\"),\n import(\"@modelcontextprotocol/sdk/client/streamableHttp.js\"),\n ]);\n const requestInit: Record<string, unknown> = {};\n if (headers && Object.keys(headers).length > 0) {\n requestInit.headers = headers;\n }\n const transport = new StreamableHTTPClientTransport(new URL(url), {\n requestInit,\n });\n const client = new Client(\n { name: \"agent-native-mcp-client-test\", version: \"1.0.0\" },\n { capabilities: {} },\n );\n try {\n await client.connect(transport);\n const listed = await client.listTools();\n const names = ((listed?.tools ?? []) as Array<{ name: string }>).map(\n (t) => t.name,\n );\n return { ok: true, toolCount: names.length, tools: names };\n } finally {\n try {\n await client.close();\n } catch {}\n try {\n await transport.close();\n } catch {}\n }\n } catch (err: any) {\n return { ok: false, error: formatMcpConnectError(err) };\n }\n}\n\nfunction normalizeHeaders(input: unknown): Record<string, string> | undefined {\n if (!input || typeof input !== \"object\") return undefined;\n const out: Record<string, string> = {};\n for (const [k, v] of Object.entries(input as Record<string, unknown>)) {\n if (typeof k !== \"string\" || !k.trim()) continue;\n if (typeof v !== \"string\") continue;\n out[k.trim()] = v;\n }\n return Object.keys(out).length > 0 ? out : undefined;\n}\n"]}
@@ -286,6 +286,59 @@
286
286
  font-size: 10px;
287
287
  }
288
288
 
289
+ .agent-mcp-app {
290
+ position: relative;
291
+ overflow: hidden;
292
+ width: 100%;
293
+ min-height: 220px;
294
+ border: 1px solid hsl(var(--border) / 0.9);
295
+ border-radius: var(--radius);
296
+ background: hsl(var(--background));
297
+ box-sizing: border-box;
298
+ }
299
+
300
+ .agent-mcp-app--flush {
301
+ border-color: transparent;
302
+ background: transparent;
303
+ }
304
+
305
+ .agent-mcp-app iframe {
306
+ display: block;
307
+ width: 100%;
308
+ min-height: 220px;
309
+ border: 0;
310
+ background: transparent;
311
+ }
312
+
313
+ .agent-mcp-app__loading,
314
+ .agent-mcp-app__error {
315
+ position: absolute;
316
+ inset: 0;
317
+ z-index: 1;
318
+ display: flex;
319
+ align-items: center;
320
+ justify-content: center;
321
+ gap: 8px;
322
+ padding: 14px;
323
+ background: hsl(var(--background) / 0.92);
324
+ color: hsl(var(--muted-foreground));
325
+ font-size: 12px;
326
+ }
327
+
328
+ .agent-mcp-app__error,
329
+ .agent-mcp-app--error {
330
+ color: hsl(var(--destructive));
331
+ }
332
+
333
+ .agent-mcp-app--error {
334
+ display: flex;
335
+ align-items: center;
336
+ justify-content: center;
337
+ gap: 8px;
338
+ min-height: 64px;
339
+ padding: 12px;
340
+ }
341
+
289
342
  .agent-conversation-notice,
290
343
  .agent-conversation-artifact {
291
344
  display: flex;
@@ -10,7 +10,7 @@ Actions are the single source of truth for anything your app does. Define an act
10
10
  - **An agent tool** — the agent sees it with a zod-derived JSON Schema and can call it in chat.
11
11
  - **A typesafe React mutation** — `useActionMutation("name")` on the frontend, types inferred from the schema.
12
12
  - **An HTTP endpoint** — `POST /_agent-native/actions/<name>` (auto-mounted by the framework).
13
- - **An MCP tool** — exposed to Claude Desktop, ChatGPT remote-MCP, and any other MCP client.
13
+ - **An MCP tool** — exposed to Claude, ChatGPT custom MCP apps, Claude Desktop/Code, Cursor, Codex, and any other MCP client.
14
14
  - **An A2A tool** — called by other agent-native apps over A2A.
15
15
  - **A CLI command** — `pnpm action <name>` for scripting and dev loops.
16
16
 
@@ -152,7 +152,30 @@ If your app is an [A2A](/docs/a2a-protocol) peer, other agent-native apps discov
152
152
 
153
153
  ## Exposing it over MCP {#mcp}
154
154
 
155
- With MCP enabled, your actions show up in the framework's MCP server at `/_agent-native/mcp`. Any MCP client — Claude Desktop, ChatGPT remote MCP, etc. — can connect and see them as tools. See [MCP Protocol](/docs/mcp-protocol).
155
+ With MCP enabled, your actions show up in the framework's MCP server at `/_agent-native/mcp`. Any MCP client — Claude, ChatGPT custom MCP apps, Claude Desktop/Code, Cursor, Codex, etc. — can connect and see them as tools. See [MCP Protocol](/docs/mcp-protocol).
156
+
157
+ For UI-capable MCP hosts, actions can also attach an optional MCP Apps resource:
158
+
159
+ ```ts
160
+ export default defineAction({
161
+ description: "Create an email draft for review.",
162
+ schema: z.object({ body: z.string() }),
163
+ run: async ({ body }) => ({ body }),
164
+ link: ({ result }) => ({
165
+ label: "Open draft in Mail",
166
+ url: "/_agent-native/open?app=mail&view=inbox",
167
+ }),
168
+ mcpApp: {
169
+ resource: {
170
+ title: "Review draft",
171
+ html: '<!doctype html><html><body><main id="app"></main></body></html>',
172
+ csp: { connectDomains: ["https://mail.agent-native.com"] },
173
+ },
174
+ },
175
+ });
176
+ ```
177
+
178
+ This advertises the MCP Apps extension (`io.modelcontextprotocol/ui`), exposes the HTML via MCP resources, and includes both current and legacy UI resource metadata for compatible hosts. Keep `link` as the fallback for CLI and non-UI MCP clients; see [External Agents](/docs/external-agents#mcp-apps).
156
179
 
157
180
  ## Standard actions {#standard-actions}
158
181
 
@@ -1,14 +1,14 @@
1
1
  ---
2
- title: "External Agents: Claude Code, Codex, Cursor, Cowork"
3
- description: "Connect your own Claude Code, Codex, Cursor, or Claude Cowork to a hosted agent-native app — then round-trip artifacts back into the running UI with deep links."
4
- search: "Claude Code Codex Cursor Claude Cowork agent-native connect MCP local agent tools external agents"
2
+ title: "External Agents: Claude, ChatGPT, Codex, Cursor, Cowork"
3
+ description: "Connect Claude, ChatGPT, Codex, Cursor, Claude Cowork, or any MCP-compatible host to a hosted agent-native app — then round-trip artifacts back into the running UI with MCP Apps and deep links."
4
+ search: "Claude ChatGPT Claude Code Codex Cursor Claude Cowork MCP Apps agent-native connect local agent tools external agents"
5
5
  ---
6
6
 
7
7
  # External Agents
8
8
 
9
- An agent-native app is reachable by any external coding agent — Claude Code (desktop & CLI), Codex, Cursor, Claude Cowork over [MCP](/docs/mcp-protocol). External agents are great at producing artifacts (a draft, an event, a dashboard) but they live in a terminal or another app. Without a bridge, the user gets a wall of JSON and has to go find the thing.
9
+ An agent-native app is reachable by any MCP-compatible host — Claude, Claude Desktop, Claude Code, ChatGPT custom MCP apps, Codex, Cursor, Claude Cowork, VS Code GitHub Copilot, Goose, Postman, MCPJam, and future clients that implement the standard. External agents are great at producing artifacts (a draft, an event, a dashboard) but they often live in a terminal or another app. Without a bridge, the user gets a wall of JSON and has to go find the thing.
10
10
 
11
- The external-agent bridge closes the loop. First you connect your own agent to a **hosted** app — one command, no token copying. Then the agent does the work over MCP and hands the user a single **"Open in &lt;app&gt; →"** link that opens the real app focused on exactly what was produced. It reuses the existing `navigate` / `application_state` contract the UI already drains every 2s (see [Context Awareness](/docs/context-awareness)) — there is no second navigation mechanism.
11
+ The external-agent bridge closes the loop. First you connect your own agent to a **hosted** app — one command, no token copying where we can write the client config, or a standard remote MCP endpoint everywhere else. Then the agent does the work over MCP and hands the user either an inline **MCP App** UI in compatible hosts or a single **"Open in &lt;app&gt; →"** link that opens the real app focused on exactly what was produced. It reuses the existing `navigate` / `application_state` contract the UI already drains every 2s (see [Context Awareness](/docs/context-awareness)) — there is no second navigation mechanism.
12
12
 
13
13
  ## Connect Claude Code, Codex, Cursor, and Cowork {#connect}
14
14
 
@@ -67,7 +67,7 @@ If you'd rather not run a command, open the app in your browser and use its **Co
67
67
 
68
68
  Restart the agent client after connecting so it picks up the new MCP server.
69
69
 
70
- Use this manual block for MCP clients that are not yet written by `agent-native connect`, including Cursor.
70
+ Use this manual block for MCP clients that are not yet written by `agent-native connect`, including Cursor, Claude web/Desktop connector setup, ChatGPT developer-mode custom MCP apps, VS Code GitHub Copilot, Goose, Postman, MCPJam, and any other host that accepts a remote Streamable HTTP MCP endpoint.
71
71
 
72
72
  ## What you can do once connected {#what-you-can-do}
73
73
 
@@ -82,6 +82,14 @@ Claude Code calls: manage-draft(to: "john@example.com", subject: "Q3 Report", bo
82
82
 
83
83
  Click that link and Mail opens with the draft restored — focused exactly where you, the logged-in user, are. The agent never had to know your session; it just produced the artifact.
84
84
 
85
+ ### MCP Apps compatibility {#mcp-apps-compatibility}
86
+
87
+ Agent-native apps also speak the official MCP Apps extension. When any action declares `mcpApp`, the server advertises `extensions["io.modelcontextprotocol/ui"]`, includes both `_meta.ui.resourceUri` and the legacy-compatible `_meta["ui/resourceUri"]` in `tools/list`, and serves the HTML UI through `resources/list` + `resources/read` as `text/html;profile=mcp-app`.
88
+
89
+ That makes the same app surface available to every compatible host rather than building per-client shims. The current official MCP Apps client list includes Claude, Claude Desktop, VS Code GitHub Copilot, Goose, Postman, MCPJam, ChatGPT, and Cursor; host support still varies by plan, release channel, and client version, so check the [MCP extension support matrix](https://modelcontextprotocol.io/extensions/client-matrix). ChatGPT custom MCP apps are available through developer mode for Business and Enterprise/Edu workspaces on ChatGPT web; see OpenAI's [developer mode and MCP apps](https://help.openai.com/en/articles/12584461-developer-mode-and-full-mcp-apps-in-chatgpt-beta) notes.
90
+
91
+ Claude Code and other CLI-first clients still receive the same resources and metadata when they support MCP Apps, but the deep link remains the reliable fallback when a host chooses not to render an iframe. In practice, every agent-native app should be authored with both: MCP Apps for inline review/edit in capable hosts, and `link` for universal round-tripping back to the full app.
92
+
85
93
  ### Generic cross-app verbs {#cross-app}
86
94
 
87
95
  On top of the per-action tools the MCP server exposes a stable verb set, so an external agent has a predictable surface without guessing per-app action names:
@@ -101,7 +109,7 @@ On top of the per-action tools the MCP server exposes a stable verb set, so an e
101
109
  Every allow-listed template that produces or lists a navigable resource ships a `link` builder, and the ingest-heavy ones ship a GET + `publicAgent` action so a connected agent can pull live state:
102
110
 
103
111
  - **Mail** — `manage-draft` returns a `compose`-encoded deep link; clicking it opens the inbox with the draft restored into a `compose-<id>`. `list-emails` / `search-emails` point at a filtered inbox view.
104
- - **Calendar** — `create-event` returns `buildDeepLink({ app: "calendar", view: "calendar", params: { eventId, date } })`; the click lands on the calendar with that event focused on its date.
112
+ - **Calendar** — `manage-event-draft` returns a `calendarDraft` + `eventDraftId` deep link; clicking it opens the New Event form prefilled for review/send. `create-event` still returns `buildDeepLink({ app: "calendar", view: "calendar", params: { eventId, date } })`; the click lands on the calendar with that event focused on its date.
105
113
  - **Analytics** — `update-dashboard` / `save-analysis` return `buildDeepLink({ app: "analytics", view: "adhoc", params: { dashboardId } })`; the agent builds a dashboard over MCP and hands back "Open dashboard in Analytics".
106
114
  - **Design** — `get-design-snapshot` is the GET + `publicAgent` ingest action: it returns the **live** Yjs file contents plus the resolved tweak values so the agent continues from the tuned design, not the original tokens. `apply-tweaks` round-trips back with an "Open design" editor link.
107
115
  - **Content** — `pull-document` is the GET + `publicAgent` ingest action: it flushes any open live collaborative session to SQL first so the external agent ingests exactly what the user sees, then surfaces a deep link to the document.
@@ -142,7 +150,33 @@ export default defineAction({
142
150
  });
143
151
  ```
144
152
 
145
- List/search actions point at a record-focused view the same way — e.g. calendar's `create-event` returns `buildDeepLink({ app: "calendar", view: "calendar", params: { eventId, date } })` with label `"Open event in Calendar"`.
153
+ List/search actions point at a record-focused view the same way — e.g. calendar's `create-event` returns `buildDeepLink({ app: "calendar", view: "calendar", params: { eventId, date } })` with label `"Open event in Calendar"`. Calendar draft actions use the same pattern: `manage-event-draft` returns `buildDeepLink({ app: "calendar", view: "calendar", to: "/", params: { eventDraftId, calendarDraft, date } })` with label `"Review invite in Calendar"`, so external agents can hand back a direct draft-review link without creating the event first.
154
+
155
+ ## Authoring: optional MCP Apps UI {#mcp-apps}
156
+
157
+ For hosts that support the MCP Apps extension, an action can also advertise an inline HTML UI resource with `mcpApp`. This is a progressive enhancement for flows where the external agent should hand the user an interactive surface instead of only text — for example reviewing an email draft, editing a calendar invite, or choosing between generated dashboard variants.
158
+
159
+ ```ts
160
+ export default defineAction({
161
+ // ...description, schema, run, link...
162
+ mcpApp: {
163
+ resource: {
164
+ title: "Review draft",
165
+ description: "Review and send the generated email draft.",
166
+ html: ({ actionName, requestOrigin }) => `<!doctype html>
167
+ <html><body data-action="${actionName}" data-origin="${requestOrigin}">
168
+ <main id="app"></main>
169
+ </body></html>`,
170
+ csp: { connectDomains: ["https://mail.agent-native.com"] },
171
+ prefersBorder: true,
172
+ },
173
+ },
174
+ });
175
+ ```
176
+
177
+ The MCP server advertises extension `io.modelcontextprotocol/ui`, adds `_meta.ui.resourceUri` plus `_meta["ui/resourceUri"]` to `tools/list`, and exposes the HTML through `resources/list` + `resources/read` using MIME `text/html;profile=mcp-app`. The stdio proxy forwards those resource handlers from the live app, so desktop and CLI clients see the same resources as HTTP clients.
178
+
179
+ Keep the existing `link` builder even when adding `mcpApp`. CLI-only clients, older hosts, and any host that does not render MCP Apps will ignore the UI metadata and still need the `"Open in … →"` link. Treat `mcpApp.resource.html` like `link`: synchronous, deterministic, and self-contained; declare external origins in `csp`. Use the full app deep link for heavyweight authenticated workflows that do not fit cleanly in an embedded iframe.
146
180
 
147
181
  ### The `link` contract {#link-contract}
148
182
 
@@ -240,6 +274,26 @@ This is the unmanaged equivalent of what `connect` writes for you. See [MCP Prot
240
274
 
241
275
  In plain local dev (`NODE_ENV=development` and `AGENT_MODE !== "production"`) the MCP `tools/list` deliberately exposes only the generic builtins plus actions with `publicAgent.requiresAuth === false` — the per-app ingest actions (`requiresAuth: true`) and mutating actions (no `publicAgent`) are filtered out (`filterPublicAgentActions`). The full per-app surface appears when the request is authenticated as a real caller: a deployed / `AGENT_MODE=production` app, or a local app reached through `connect` / `agent-native mcp install` (which provisions a token so the caller has an identity). So if `tools/list` looks sparse, you are hitting an unauthenticated dev endpoint — connect (or present a token) rather than assuming the action is missing.
242
276
 
277
+ ### Switching first-party apps between prod and dev {#dev-switch}
278
+
279
+ When you already have first-party hosted apps connected and want to test local framework changes through `pnpm dev:lazy`, use the developer switcher:
280
+
281
+ ```bash
282
+ pnpm dev:lazy -- --apps mail,calendar,analytics
283
+
284
+ agent-native connect dev --apps mail,calendar,analytics --client codex
285
+ ```
286
+
287
+ `connect dev` rewrites the same stable MCP server names (`agent-native-mail`, `agent-native-calendar`, etc.) to the local dev-lazy gateway, so tool names do not change. It backs up the current production entries in `~/.agent-native/connect-profiles.json` before writing dev entries. The default gateway is `http://127.0.0.1:8080`; use `--gateway <url>` or `--port <n>` if your gateway moved.
288
+
289
+ Switch back with:
290
+
291
+ ```bash
292
+ agent-native connect prod --apps mail,calendar,analytics --client codex
293
+ ```
294
+
295
+ If `connect dev` cannot infer your local owner identity from an existing connected JWT, pass `--owner-email you@example.com`; this keeps local dev tools on the full authenticated MCP surface instead of the sparse unauthenticated dev surface.
296
+
243
297
  ## How it works & security {#how-it-works}
244
298
 
245
299
  The hosted `connect` flow never copies the deployment's shared secret. Instead:
@@ -201,7 +201,7 @@ See [Context Awareness](/docs/context-awareness) for the full pattern: navigatio
201
201
  Every action you define automatically becomes available over multiple protocols — you don't pick one. The framework runs both an MCP server and an A2A peer for your app, with actions feeding both.
202
202
 
203
203
  - **Actions first.** Write the logic once as an action. Use `fetch()` and any SDK you want inside — no wrapper layer.
204
- - **MCP for the outside world.** Your actions show up as MCP tools to Claude Desktop, ChatGPT's remote-MCP support, and any other MCP client. Your app also _consumes_ MCP servers — local, remote, or from a workspace hub. See [MCP Clients](/docs/mcp-clients) and [MCP Protocol](/docs/mcp-protocol).
204
+ - **MCP for the outside world.** Your actions show up as MCP tools to Claude, ChatGPT custom MCP apps, Claude Desktop/Code, Cursor, Codex, and any other MCP client. Actions can also expose MCP Apps UI resources so compatible hosts render inline review/edit surfaces, with deep links back to the full app as the universal fallback. Your app also _consumes_ MCP servers — local, remote, or from a workspace hub. See [External Agents](/docs/external-agents), [MCP Clients](/docs/mcp-clients), and [MCP Protocol](/docs/mcp-protocol).
205
205
  - **A2A for other agents.** Other agent-native apps discover and call your actions over [A2A](/docs/a2a-protocol) — same-origin deploys skip JWT entirely.
206
206
  - **CLIs still work.** `pnpm action <name>` and direct shell tools (`ffmpeg`, `gh`, `aws`) remain available whenever they're the simplest path.
207
207
 
@@ -7,7 +7,7 @@ description: "Connect your agent-native app to local MCP servers (claude-in-chro
7
7
 
8
8
  Agent-native apps can also act as MCP **clients** — connecting to locally installed MCP servers and exposing their tools to the agent chat. This is the symmetric counterpart to the [MCP Protocol](./mcp-protocol.md) (which makes your app an MCP server).
9
9
 
10
- Looking for the other direction — connecting Claude Code, Codex, Cursor, or Claude Cowork to an agent-native app? Use [External Agents](/docs/external-agents).
10
+ Looking for the other direction — connecting Claude, ChatGPT, Claude Code, Codex, Cursor, or Claude Cowork to an agent-native app? Use [External Agents](/docs/external-agents).
11
11
 
12
12
  With one config file, every agent-native app in your workspace gains access to tools provided by MCP servers on your machine: `claude-in-chrome` for browser automation, `@modelcontextprotocol/server-filesystem` for reading files, `@playwright/mcp` for browser testing, and anything else that speaks MCP.
13
13
 
@@ -1,13 +1,13 @@
1
1
  ---
2
2
  title: "MCP Protocol"
3
- description: "Expose your agent-native app as a remote MCP server so Claude Code, Cursor, and other AI tools can call your app's actions directly."
3
+ description: "Expose your agent-native app as a remote MCP server so Claude, ChatGPT, Claude Code, Cursor, and other AI tools can call your app's actions directly."
4
4
  ---
5
5
 
6
6
  # MCP Protocol
7
7
 
8
- Every agent-native app automatically exposes a remote MCP (Model Context Protocol) server. This lets external AI tools like Claude Code, Cursor, and Windsurf discover and call your app's actions directly — no extra code needed.
8
+ Every agent-native app automatically exposes a remote MCP (Model Context Protocol) server. This lets external AI tools like Claude, ChatGPT custom MCP apps, Claude Code, Cursor, Codex, VS Code GitHub Copilot, and Windsurf discover and call your app's actions directly — no extra code needed.
9
9
 
10
- If your goal is to connect Claude Code, Codex, Cursor, or Claude Cowork to a hosted agent-native app, start with [External Agents](/docs/external-agents). It documents the one-command `agent-native connect https://mail.agent-native.com` flow, token minting, local client config writes, manual MCP config for clients like Cursor, and deep links back into the UI. This page is the lower-level MCP server reference.
10
+ If your goal is to connect Claude, ChatGPT, Claude Code, Codex, Cursor, or Claude Cowork to a hosted agent-native app, start with [External Agents](/docs/external-agents). It documents the one-command `agent-native connect https://mail.agent-native.com` flow, token minting, local client config writes, manual remote MCP setup for hosts we do not write directly, MCP Apps inline UIs, and deep links back into the UI. This page is the lower-level MCP server reference.
11
11
 
12
12
  ## Overview {#overview}
13
13
 
@@ -19,20 +19,21 @@ Key concepts:
19
19
  - **Streamable HTTP** — uses the modern MCP transport over standard HTTP (POST + SSE)
20
20
  - **Same actions** — the exact same action registry that powers agent chat and A2A
21
21
  - **`ask-agent` tool** — a meta-tool that delegates to the full agent loop for complex tasks
22
+ - **MCP Apps** — actions can advertise inline HTML UIs through the official `io.modelcontextprotocol/ui` extension
22
23
  - **Bearer auth** — uses `ACCESS_TOKEN` or `A2A_SECRET` for authentication
23
24
 
24
25
  ## MCP vs A2A {#mcp-vs-a2a}
25
26
 
26
27
  Both protocols are auto-mounted. Use whichever fits your use case:
27
28
 
28
- | | MCP | A2A |
29
- | ------------------ | ------------------------------------- | -------------------------------------------- |
30
- | **Best for** | External tools calling your app | Agent-to-agent communication |
31
- | **Protocol** | MCP Streamable HTTP | JSON-RPC 2.0 |
32
- | **Tool discovery** | `tools/list` | Agent card at `/.well-known/agent-card.json` |
33
- | **Endpoint** | `/_agent-native/mcp` | `/_agent-native/a2a` |
34
- | **Supported by** | Claude Code, Cursor, Windsurf, Cowork | Other agent-native apps |
35
- | **Execution** | Direct tool calls (no extra LLM) | Full agent loop (LLM reasoning) |
29
+ | | MCP | A2A |
30
+ | ------------------ | ------------------------------------------------------------------------ | -------------------------------------------- |
31
+ | **Best for** | External tools calling your app | Agent-to-agent communication |
32
+ | **Protocol** | MCP Streamable HTTP | JSON-RPC 2.0 |
33
+ | **Tool discovery** | `tools/list` | Agent card at `/.well-known/agent-card.json` |
34
+ | **Endpoint** | `/_agent-native/mcp` | `/_agent-native/a2a` |
35
+ | **Supported by** | Claude, ChatGPT, Claude Code, Cursor, Codex, Cowork, and other MCP hosts | Other agent-native apps |
36
+ | **Execution** | Direct tool calls (no extra LLM) | Full agent loop (LLM reasoning) |
36
37
 
37
38
  You can also use the `ask-agent` MCP tool to get the best of both worlds — call it from Claude Code and let your app's agent reason through complex tasks.
38
39
 
@@ -71,6 +72,8 @@ POST https://your-app.example.com/_agent-native/mcp
71
72
 
72
73
  The server supports the standard MCP handshake: `initialize` → `initialized` → `tools/list` → `tools/call`.
73
74
 
75
+ If an action declares `mcpApp`, the server also advertises the official MCP Apps extension (`io.modelcontextprotocol/ui`) and supports `resources/list`, `resources/templates/list`, and `resources/read` for the app HTML. Hosts that render MCP Apps can show the UI inline; hosts that do not can still call the tool and use the deep-link fallback. The current official extension matrix includes Claude, Claude Desktop, VS Code GitHub Copilot, Goose, Postman, MCPJam, ChatGPT, and Cursor; host support varies by version and plan, so use the [External Agents MCP Apps notes](/docs/external-agents#mcp-apps-compatibility) for the user-facing guidance.
76
+
74
77
  ## Tools {#tools}
75
78
 
76
79
  All actions registered in your app are exposed as MCP tools. The mapping is direct:
@@ -81,6 +84,8 @@ All actions registered in your app are exposed as MCP tools. The mapping is dire
81
84
  | `tool.parameters` | `inputSchema` |
82
85
  | Action name | Tool name |
83
86
 
87
+ When `mcpApp` is present, the tool entry also includes `_meta.ui.resourceUri` and `_meta["ui/resourceUri"]`, and the corresponding `ui://` resource is returned as `text/html;profile=mcp-app`.
88
+
84
89
  ### The `ask-agent` tool {#ask-agent}
85
90
 
86
91
  In addition to individual action tools, every MCP server includes an `ask-agent` meta-tool. This sends a natural-language message to the app's AI agent and returns the response.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agent-native/core",
3
- "version": "0.20.9",
3
+ "version": "0.21.0",
4
4
  "type": "module",
5
5
  "description": "Framework for agent-native application development — where AI agents and UI share state via files",
6
6
  "license": "MIT",
@@ -114,6 +114,7 @@
114
114
  "@assistant-ui/react-markdown": "^0.12.6",
115
115
  "@clack/prompts": "^1.4.0",
116
116
  "@libsql/client": "^0.15.0",
117
+ "@modelcontextprotocol/ext-apps": "1.7.2",
117
118
  "@modelcontextprotocol/sdk": "^1.29.0",
118
119
  "@neondatabase/serverless": "^1.1.0",
119
120
  "@radix-ui/react-dropdown-menu": "^2.1.16",