@agent-native/core 0.128.3 → 0.129.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.
- package/corpus/README.md +2 -2
- package/corpus/core/CHANGELOG.md +91 -0
- package/corpus/core/docs/content/template-design-collaboration-and-full-apps.mdx +3 -1
- package/corpus/core/package.json +6 -3
- package/corpus/core/src/a2a/client.ts +18 -4
- package/corpus/core/src/a2a/server.ts +19 -3
- package/corpus/core/src/a2a/types.ts +7 -0
- package/corpus/core/src/action.ts +43 -16
- package/corpus/core/src/agent/engine/ai-sdk-engine.ts +14 -10
- package/corpus/core/src/agent/production-agent.ts +41 -3
- package/corpus/core/src/agent/thread-data-builder.ts +5 -0
- package/corpus/core/src/chat-threads/migrations.ts +53 -0
- package/corpus/core/src/cli/create.ts +4 -0
- package/corpus/core/src/cli/skills-content/design-visual-edit-skill.ts +36 -16
- package/corpus/core/src/cli/skills.ts +16 -0
- package/corpus/core/src/client/AgentPanel.tsx +9 -5
- package/corpus/core/src/client/AssistantChat.tsx +138 -46
- package/corpus/core/src/client/MultiTabAssistantChat.tsx +16 -10
- package/corpus/core/src/client/agent-chat-adapter.ts +21 -3
- package/corpus/core/src/client/analytics.ts +159 -102
- package/corpus/core/src/client/chat/legacy-chart-shorthand.tsx +479 -0
- package/corpus/core/src/client/chat/markdown-renderer.tsx +23 -3
- package/corpus/core/src/client/chat/message-components.tsx +12 -5
- package/corpus/core/src/client/chat/runtime.ts +2 -1
- package/corpus/core/src/client/chat/tool-call-display.tsx +25 -2
- package/corpus/core/src/client/chat-model-groups.ts +3 -0
- package/corpus/core/src/client/client-status-requests.ts +161 -0
- package/corpus/core/src/client/settings/VoiceTranscriptionSection.tsx +2 -2
- package/corpus/core/src/client/sse-event-processor.ts +15 -3
- package/corpus/core/src/client/use-agent-engine-configured.ts +54 -50
- package/corpus/core/src/client/use-chat-models.ts +16 -11
- package/corpus/core/src/client/use-chat-threads.ts +32 -9
- package/corpus/core/src/client/use-session.ts +4 -5
- package/corpus/core/src/db/client.ts +83 -8
- package/corpus/core/src/db/ensure-additive-columns.ts +31 -20
- package/corpus/core/src/db/migrations.ts +22 -2
- package/corpus/core/src/extensions/actions.ts +1 -1
- package/corpus/core/src/mcp/approval-store.ts +99 -0
- package/corpus/core/src/mcp/build-server.ts +579 -303
- package/corpus/core/src/mcp/embed-app.ts +1 -1
- package/corpus/core/src/mcp/oauth-client-metadata.ts +380 -0
- package/corpus/core/src/mcp/oauth-route.ts +57 -52
- package/corpus/core/src/mcp/screen-memory-stdio.ts +400 -378
- package/corpus/core/src/mcp/server.ts +29 -145
- package/corpus/core/src/mcp/stdio.ts +72 -80
- package/corpus/core/src/mcp-client/manager.ts +6 -10
- package/corpus/core/src/mcp-client/oauth-client.ts +127 -36
- package/corpus/core/src/mcp-client/oauth-routes.ts +16 -6
- package/corpus/core/src/mcp-client/routes.ts +6 -5
- package/corpus/core/src/server/agent-capabilities.ts +20 -0
- package/corpus/core/src/server/agent-chat/action-filters-a2a.ts +27 -0
- package/corpus/core/src/server/agent-chat-plugin.ts +18 -0
- package/corpus/core/src/server/transcribe-voice.ts +14 -5
- package/corpus/core/src/templates/default/.agents/skills/security/SKILL.md +13 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +5 -2
- package/corpus/core/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +18 -0
- package/corpus/core/src/templates/workspace-core/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/analytics/.agents/skills/data-querying/SKILL.md +12 -0
- package/corpus/templates/analytics/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/analytics/actions/generate-chart.ts +2 -2
- package/corpus/templates/analytics/app/components/dashboard/DashboardPanelSkeleton.tsx +1 -10
- package/corpus/templates/analytics/app/global.css +0 -31
- package/corpus/templates/analytics/app/lib/sql-query.ts +46 -20
- package/corpus/templates/analytics/changelog/2026-07-28-analytics-dashboard-loading-states-now-use-a-simpler-standar.md +6 -0
- package/corpus/templates/analytics/changelog/2026-07-28-analytics-dashboards-now-load-first-party-charts-reliably-in.md +6 -0
- package/corpus/templates/analytics/server/lib/first-party-analytics-cache.ts +42 -16
- package/corpus/templates/analytics/server/lib/first-party-analytics.ts +4 -2
- package/corpus/templates/analytics/shared/sql-query-limits.ts +1 -0
- package/corpus/templates/assets/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/brain/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/calendar/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/chat/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/clips/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/clips/app/components/player/player-controls.tsx +3 -6
- package/corpus/templates/clips/app/routes/r.$recordingId.tsx +6 -2
- package/corpus/templates/clips/app/routes/share.$shareId.tsx +3 -1
- package/corpus/templates/clips/changelog/2026-07-28-copied-share-links-no-longer-leave-an-unnecessary-confirmati.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-28-playback-skip-controls-no-longer-show-overlapping-numbers.md +6 -0
- package/corpus/templates/clips/changelog/2026-07-28-public-clips-share-buttons-now-use-a-clean-text-only-label.md +6 -0
- package/corpus/templates/clips/desktop/src/app.tsx +14 -17
- package/corpus/templates/clips/desktop/src/overlays/live-audio-bars.tsx +3 -1
- package/corpus/templates/clips/desktop/src/styles.css +13 -10
- package/corpus/templates/clips/desktop/src-tauri/src/recording_indicator.rs +2 -2
- package/corpus/templates/clips/desktop/src-tauri/src/whisper_speech.rs +36 -0
- package/corpus/templates/content/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/content/actions/_builder-cms-read-client.ts +155 -34
- package/corpus/templates/content/actions/_builder-docs-client.ts +151 -30
- package/corpus/templates/content/actions/stage-builder-source-bulk-update.ts +5 -2
- package/corpus/templates/content/app/root.tsx +35 -14
- package/corpus/templates/content/changelog/2026-07-28-builder-backed-files-media-fields-now-accept-direct-file-url.md +6 -0
- package/corpus/templates/content/changelog/2026-07-28-builder-content-reads-now-negotiate-the-newest-mcp-protocol-.md +6 -0
- package/corpus/templates/content/changelog/2026-07-28-public-content-pages-load-faster-before-the-optional-ask-sid.md +6 -0
- package/corpus/templates/design/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/design/.agents/skills/visual-edit/SKILL.md +36 -16
- package/corpus/templates/design/.generated/bridge/editor-chrome.generated.ts +42 -3
- package/corpus/templates/design/actions/open-visual-edit.ts +2 -1
- package/corpus/templates/design/app/components/design/CanvasContextMenu.tsx +2 -2
- package/corpus/templates/design/app/components/design/DesignCanvas.tsx +14 -15
- package/corpus/templates/design/app/components/design/ResponsiveInteractBar.tsx +314 -0
- package/corpus/templates/design/app/components/design/bridge/editor-chrome.bridge.ts +88 -3
- package/corpus/templates/design/app/components/design/keyboard-shortcuts.ts +1 -1
- package/corpus/templates/design/app/hooks/useDesignHotkeys.ts +7 -6
- package/corpus/templates/design/app/i18n-data.ts +56 -11
- package/corpus/templates/design/app/i18n-responsive-interact.ts +183 -0
- package/corpus/templates/design/app/lib/agent-chat.ts +60 -0
- package/corpus/templates/design/app/pages/design-editor/responsive-interact.ts +89 -0
- package/corpus/templates/design/changelog/2026-07-28-design-edits-can-be-applied-through-the-host-coding-agent-fr.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-can-preview-designs-in-responsive-device-sizes.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-interact-mode-now-opens-a-full-screen-responsive-preview-wit.md +6 -0
- package/corpus/templates/design/changelog/2026-07-28-show-or-hide-design-editing-chrome-with-cmd-on-apple-devices.md +2 -2
- package/corpus/templates/design/changelog/2026-07-28-visual-edit-now-always-shows-the-live-running-app-in-the-can.md +6 -0
- package/corpus/templates/dispatch/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/forms/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/macros/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/mail/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/plan/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/slides/.agents/skills/security/SKILL.md +13 -2
- package/corpus/templates/tasks/.agents/skills/security/SKILL.md +13 -2
- package/corpus/toolkit/CHANGELOG.md +13 -0
- package/corpus/toolkit/package.json +1 -1
- package/corpus/toolkit/src/chat-history.css +1 -2
- package/corpus/toolkit/src/composer/TiptapComposer.tsx +45 -0
- package/dist/a2a/client.d.ts +7 -0
- package/dist/a2a/client.d.ts.map +1 -1
- package/dist/a2a/client.js +8 -3
- package/dist/a2a/client.js.map +1 -1
- package/dist/a2a/server.d.ts.map +1 -1
- package/dist/a2a/server.js +18 -3
- package/dist/a2a/server.js.map +1 -1
- package/dist/a2a/types.d.ts +7 -0
- package/dist/a2a/types.d.ts.map +1 -1
- package/dist/a2a/types.js.map +1 -1
- package/dist/action.d.ts +15 -1
- package/dist/action.d.ts.map +1 -1
- package/dist/action.js +39 -16
- package/dist/action.js.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.d.ts.map +1 -1
- package/dist/agent/engine/ai-sdk-engine.js +14 -10
- package/dist/agent/engine/ai-sdk-engine.js.map +1 -1
- package/dist/agent/production-agent.d.ts.map +1 -1
- package/dist/agent/production-agent.js +35 -7
- package/dist/agent/production-agent.js.map +1 -1
- package/dist/agent/thread-data-builder.d.ts +2 -0
- package/dist/agent/thread-data-builder.d.ts.map +1 -1
- package/dist/agent/thread-data-builder.js +3 -0
- package/dist/agent/thread-data-builder.js.map +1 -1
- package/dist/chat-threads/migrations.d.ts +21 -0
- package/dist/chat-threads/migrations.d.ts.map +1 -0
- package/dist/chat-threads/migrations.js +45 -0
- package/dist/chat-threads/migrations.js.map +1 -0
- package/dist/cli/create.d.ts.map +1 -1
- package/dist/cli/create.js +4 -0
- package/dist/cli/create.js.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.d.ts.map +1 -1
- package/dist/cli/skills-content/design-visual-edit-skill.js +36 -16
- package/dist/cli/skills-content/design-visual-edit-skill.js.map +1 -1
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +15 -0
- package/dist/cli/skills.js.map +1 -1
- package/dist/client/AgentPanel.d.ts.map +1 -1
- package/dist/client/AgentPanel.js +6 -5
- package/dist/client/AgentPanel.js.map +1 -1
- package/dist/client/AssistantChat.d.ts +37 -0
- package/dist/client/AssistantChat.d.ts.map +1 -1
- package/dist/client/AssistantChat.js +41 -8
- package/dist/client/AssistantChat.js.map +1 -1
- package/dist/client/MultiTabAssistantChat.d.ts.map +1 -1
- package/dist/client/MultiTabAssistantChat.js +11 -10
- package/dist/client/MultiTabAssistantChat.js.map +1 -1
- package/dist/client/agent-chat-adapter.d.ts.map +1 -1
- package/dist/client/agent-chat-adapter.js +19 -3
- package/dist/client/agent-chat-adapter.js.map +1 -1
- package/dist/client/analytics.d.ts.map +1 -1
- package/dist/client/analytics.js +150 -101
- package/dist/client/analytics.js.map +1 -1
- package/dist/client/chat/legacy-chart-shorthand.d.ts +29 -0
- package/dist/client/chat/legacy-chart-shorthand.d.ts.map +1 -0
- package/dist/client/chat/legacy-chart-shorthand.js +330 -0
- package/dist/client/chat/legacy-chart-shorthand.js.map +1 -0
- package/dist/client/chat/markdown-renderer.d.ts.map +1 -1
- package/dist/client/chat/markdown-renderer.js +8 -2
- package/dist/client/chat/markdown-renderer.js.map +1 -1
- package/dist/client/chat/message-components.d.ts +2 -1
- package/dist/client/chat/message-components.d.ts.map +1 -1
- package/dist/client/chat/message-components.js +11 -4
- package/dist/client/chat/message-components.js.map +1 -1
- package/dist/client/chat/runtime.d.ts.map +1 -1
- package/dist/client/chat/runtime.js +2 -1
- package/dist/client/chat/runtime.js.map +1 -1
- package/dist/client/chat/tool-call-display.d.ts +4 -1
- package/dist/client/chat/tool-call-display.d.ts.map +1 -1
- package/dist/client/chat/tool-call-display.js +14 -8
- package/dist/client/chat/tool-call-display.js.map +1 -1
- package/dist/client/chat-model-groups.d.ts.map +1 -1
- package/dist/client/chat-model-groups.js +3 -0
- package/dist/client/chat-model-groups.js.map +1 -1
- package/dist/client/client-status-requests.d.ts +14 -0
- package/dist/client/client-status-requests.d.ts.map +1 -0
- package/dist/client/client-status-requests.js +126 -0
- package/dist/client/client-status-requests.js.map +1 -0
- package/dist/client/settings/VoiceTranscriptionSection.js +1 -1
- package/dist/client/settings/VoiceTranscriptionSection.js.map +1 -1
- package/dist/client/sse-event-processor.d.ts +7 -0
- package/dist/client/sse-event-processor.d.ts.map +1 -1
- package/dist/client/sse-event-processor.js +8 -3
- package/dist/client/sse-event-processor.js.map +1 -1
- package/dist/client/use-agent-engine-configured.d.ts.map +1 -1
- package/dist/client/use-agent-engine-configured.js +29 -43
- package/dist/client/use-agent-engine-configured.js.map +1 -1
- package/dist/client/use-chat-models.d.ts.map +1 -1
- package/dist/client/use-chat-models.js +11 -11
- package/dist/client/use-chat-models.js.map +1 -1
- package/dist/client/use-chat-threads.d.ts.map +1 -1
- package/dist/client/use-chat-threads.js +23 -7
- package/dist/client/use-chat-threads.js.map +1 -1
- package/dist/client/use-session.d.ts.map +1 -1
- package/dist/client/use-session.js +4 -4
- package/dist/client/use-session.js.map +1 -1
- package/dist/collab/awareness.d.ts +2 -2
- package/dist/collab/awareness.d.ts.map +1 -1
- package/dist/db/client.d.ts.map +1 -1
- package/dist/db/client.js +48 -4
- package/dist/db/client.js.map +1 -1
- package/dist/db/ensure-additive-columns.d.ts.map +1 -1
- package/dist/db/ensure-additive-columns.js +32 -21
- package/dist/db/ensure-additive-columns.js.map +1 -1
- package/dist/db/migrations.d.ts +9 -0
- package/dist/db/migrations.d.ts.map +1 -1
- package/dist/db/migrations.js +14 -3
- package/dist/db/migrations.js.map +1 -1
- package/dist/extensions/actions.js +1 -1
- package/dist/extensions/actions.js.map +1 -1
- package/dist/mcp/approval-store.d.ts +16 -0
- package/dist/mcp/approval-store.d.ts.map +1 -0
- package/dist/mcp/approval-store.js +85 -0
- package/dist/mcp/approval-store.js.map +1 -0
- package/dist/mcp/build-server.d.ts +1 -34
- package/dist/mcp/build-server.d.ts.map +1 -1
- package/dist/mcp/build-server.js +220 -23
- package/dist/mcp/build-server.js.map +1 -1
- package/dist/mcp/embed-app.js +1 -1
- package/dist/mcp/embed-app.js.map +1 -1
- package/dist/mcp/oauth-client-metadata.d.ts +15 -0
- package/dist/mcp/oauth-client-metadata.d.ts.map +1 -0
- package/dist/mcp/oauth-client-metadata.js +297 -0
- package/dist/mcp/oauth-client-metadata.js.map +1 -0
- package/dist/mcp/oauth-route.d.ts.map +1 -1
- package/dist/mcp/oauth-route.js +39 -53
- package/dist/mcp/oauth-route.js.map +1 -1
- package/dist/mcp/screen-memory-stdio.d.ts.map +1 -1
- package/dist/mcp/screen-memory-stdio.js +304 -296
- package/dist/mcp/screen-memory-stdio.js.map +1 -1
- package/dist/mcp/server.d.ts +12 -25
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +24 -133
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/stdio.d.ts.map +1 -1
- package/dist/mcp/stdio.js +36 -35
- package/dist/mcp/stdio.js.map +1 -1
- package/dist/mcp-client/manager.d.ts.map +1 -1
- package/dist/mcp-client/manager.js +6 -6
- package/dist/mcp-client/manager.js.map +1 -1
- package/dist/mcp-client/oauth-client.d.ts +13 -17
- package/dist/mcp-client/oauth-client.d.ts.map +1 -1
- package/dist/mcp-client/oauth-client.js +74 -16
- package/dist/mcp-client/oauth-client.js.map +1 -1
- package/dist/mcp-client/oauth-routes.d.ts +2 -2
- package/dist/mcp-client/oauth-routes.d.ts.map +1 -1
- package/dist/mcp-client/oauth-routes.js +16 -6
- package/dist/mcp-client/oauth-routes.js.map +1 -1
- package/dist/mcp-client/routes.js +5 -5
- package/dist/mcp-client/routes.js.map +1 -1
- package/dist/notifications/routes.d.ts +1 -1
- package/dist/progress/routes.d.ts +1 -1
- package/dist/resources/handlers.d.ts +1 -1
- package/dist/secrets/routes.d.ts +9 -9
- package/dist/server/agent-capabilities.d.ts.map +1 -1
- package/dist/server/agent-capabilities.js +21 -0
- package/dist/server/agent-capabilities.js.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.d.ts +14 -0
- package/dist/server/agent-chat/action-filters-a2a.d.ts.map +1 -1
- package/dist/server/agent-chat/action-filters-a2a.js +16 -0
- package/dist/server/agent-chat/action-filters-a2a.js.map +1 -1
- package/dist/server/agent-chat-plugin.d.ts.map +1 -1
- package/dist/server/agent-chat-plugin.js +11 -1
- package/dist/server/agent-chat-plugin.js.map +1 -1
- package/dist/server/transcribe-voice.js +12 -6
- package/dist/server/transcribe-voice.js.map +1 -1
- package/dist/templates/chat/.agents/skills/security/SKILL.md +13 -2
- package/dist/templates/default/.agents/skills/security/SKILL.md +13 -2
- package/dist/templates/workspace-core/.agents/skills/authentication/SKILL.md +5 -2
- package/dist/templates/workspace-core/.agents/skills/external-agents/SKILL.md +18 -0
- package/dist/templates/workspace-core/.agents/skills/security/SKILL.md +13 -2
- package/docs/content/template-design-collaboration-and-full-apps.mdx +3 -1
- package/package.json +7 -4
- package/src/a2a/client.ts +18 -4
- package/src/a2a/server.ts +19 -3
- package/src/a2a/types.ts +7 -0
- package/src/action.ts +43 -16
- package/src/agent/engine/ai-sdk-engine.ts +14 -10
- package/src/agent/production-agent.ts +41 -3
- package/src/agent/thread-data-builder.ts +5 -0
- package/src/chat-threads/migrations.ts +53 -0
- package/src/cli/create.ts +4 -0
- package/src/cli/skills-content/design-visual-edit-skill.ts +36 -16
- package/src/cli/skills.ts +16 -0
- package/src/client/AgentPanel.tsx +9 -5
- package/src/client/AssistantChat.tsx +138 -46
- package/src/client/MultiTabAssistantChat.tsx +16 -10
- package/src/client/agent-chat-adapter.ts +21 -3
- package/src/client/analytics.ts +159 -102
- package/src/client/chat/legacy-chart-shorthand.tsx +479 -0
- package/src/client/chat/markdown-renderer.tsx +23 -3
- package/src/client/chat/message-components.tsx +12 -5
- package/src/client/chat/runtime.ts +2 -1
- package/src/client/chat/tool-call-display.tsx +25 -2
- package/src/client/chat-model-groups.ts +3 -0
- package/src/client/client-status-requests.ts +161 -0
- package/src/client/settings/VoiceTranscriptionSection.tsx +2 -2
- package/src/client/sse-event-processor.ts +15 -3
- package/src/client/use-agent-engine-configured.ts +54 -50
- package/src/client/use-chat-models.ts +16 -11
- package/src/client/use-chat-threads.ts +32 -9
- package/src/client/use-session.ts +4 -5
- package/src/db/client.ts +83 -8
- package/src/db/ensure-additive-columns.ts +31 -20
- package/src/db/migrations.ts +22 -2
- package/src/extensions/actions.ts +1 -1
- package/src/mcp/approval-store.ts +99 -0
- package/src/mcp/build-server.ts +579 -303
- package/src/mcp/embed-app.ts +1 -1
- package/src/mcp/oauth-client-metadata.ts +380 -0
- package/src/mcp/oauth-route.ts +57 -52
- package/src/mcp/screen-memory-stdio.ts +400 -378
- package/src/mcp/server.ts +29 -145
- package/src/mcp/stdio.ts +72 -80
- package/src/mcp-client/manager.ts +6 -10
- package/src/mcp-client/oauth-client.ts +127 -36
- package/src/mcp-client/oauth-routes.ts +16 -6
- package/src/mcp-client/routes.ts +6 -5
- package/src/server/agent-capabilities.ts +20 -0
- package/src/server/agent-chat/action-filters-a2a.ts +27 -0
- package/src/server/agent-chat-plugin.ts +18 -0
- package/src/server/transcribe-voice.ts +14 -5
- package/src/templates/chat/.agents/skills/security/SKILL.md +13 -2
- package/src/templates/default/.agents/skills/security/SKILL.md +13 -2
- package/src/templates/workspace-core/.agents/skills/authentication/SKILL.md +5 -2
- package/src/templates/workspace-core/.agents/skills/external-agents/SKILL.md +18 -0
- package/src/templates/workspace-core/.agents/skills/security/SKILL.md +13 -2
|
@@ -156,7 +156,7 @@ export class McpClientManager {
|
|
|
156
156
|
// If we previously loaded without stdio and now need it, top up.
|
|
157
157
|
if (needStdio && !this.sdk.StdioClientTransport && isNode()) {
|
|
158
158
|
try {
|
|
159
|
-
const stdioMod = await import("@modelcontextprotocol/
|
|
159
|
+
const stdioMod = await import("@modelcontextprotocol/client/stdio");
|
|
160
160
|
this.sdk.StdioClientTransport = stdioMod.StdioClientTransport;
|
|
161
161
|
}
|
|
162
162
|
catch (err) {
|
|
@@ -166,12 +166,11 @@ export class McpClientManager {
|
|
|
166
166
|
return this.sdk;
|
|
167
167
|
}
|
|
168
168
|
try {
|
|
169
|
-
const clientMod = await import("@modelcontextprotocol/
|
|
170
|
-
const httpMod = await import("@modelcontextprotocol/sdk/client/streamableHttp.js");
|
|
169
|
+
const clientMod = await import("@modelcontextprotocol/client");
|
|
171
170
|
let StdioClientTransport = null;
|
|
172
171
|
if (needStdio && isNode()) {
|
|
173
172
|
try {
|
|
174
|
-
const stdioMod = await import("@modelcontextprotocol/
|
|
173
|
+
const stdioMod = await import("@modelcontextprotocol/client/stdio");
|
|
175
174
|
StdioClientTransport = stdioMod.StdioClientTransport;
|
|
176
175
|
}
|
|
177
176
|
catch (err) {
|
|
@@ -181,7 +180,7 @@ export class McpClientManager {
|
|
|
181
180
|
this.sdk = {
|
|
182
181
|
Client: clientMod.Client,
|
|
183
182
|
StdioClientTransport,
|
|
184
|
-
StreamableHTTPClientTransport:
|
|
183
|
+
StreamableHTTPClientTransport: clientMod.StreamableHTTPClientTransport,
|
|
185
184
|
};
|
|
186
185
|
return this.sdk;
|
|
187
186
|
}
|
|
@@ -337,6 +336,7 @@ export class McpClientManager {
|
|
|
337
336
|
},
|
|
338
337
|
},
|
|
339
338
|
},
|
|
339
|
+
versionNegotiation: { mode: "auto" },
|
|
340
340
|
});
|
|
341
341
|
const recordConnectionError = () => { };
|
|
342
342
|
const restoreClientClose = guardClose(client, recordConnectionError);
|
|
@@ -345,7 +345,7 @@ export class McpClientManager {
|
|
|
345
345
|
// Attach a transport-level error handler before connect() so the SDK's
|
|
346
346
|
// internal fire-and-forget paths (initial SSE stream open, scheduled
|
|
347
347
|
// reconnects, message-handler-triggered reconnects — see processStream()
|
|
348
|
-
// in @modelcontextprotocol/
|
|
348
|
+
// in @modelcontextprotocol/client) cannot leak as
|
|
349
349
|
// unhandled promise rejections. On AWS Lambda the long-lived socket
|
|
350
350
|
// gets reaped ~60s after the function returns; without this handler the
|
|
351
351
|
// resulting `socket hang up` surfaces as an unhandledRejection and
|
|
@@ -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 { MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE } from \"../action.js\";\nimport type { McpConfig, McpServerConfig } from \"./config.js\";\nimport { formatMcpConnectError } from \"./errors.js\";\nimport {\n isFirstPartyRemoteEndpointTrusted,\n parseMergedKey,\n} from \"./remote-store.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 a.firstParty === b.firstParty &&\n a.firstPartyAppId === b.firstPartyAppId &&\n a.firstPartyOrgId === b.firstPartyOrgId\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\nconst DEFAULT_MCP_CONNECT_TIMEOUT_MS = 5_000;\n\nfunction mcpConnectTimeoutMs(): number {\n const raw =\n typeof process !== \"undefined\"\n ? process.env.AGENT_NATIVE_MCP_CLIENT_CONNECT_TIMEOUT_MS ||\n process.env.MCP_CLIENT_CONNECT_TIMEOUT_MS\n : undefined;\n const parsed = raw ? Number(raw) : NaN;\n if (Number.isFinite(parsed) && parsed >= 0) return parsed;\n return DEFAULT_MCP_CONNECT_TIMEOUT_MS;\n}\n\nasync function withConnectTimeout<T>(\n work: Promise<T>,\n label: string,\n timeoutMs: number,\n): Promise<T> {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) return work;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n reject(new Error(`${label} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n try {\n return await Promise.race([work, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\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 const staticHeaders = { ...(cfg.headers ?? {}) };\n const transportOptions: Record<string, unknown> = { requestInit };\n if (this.shouldInjectFirstPartyIdentity(entry)) {\n const baselineHeaders = { ...staticHeaders };\n removeAuthorizationHeaders(baselineHeaders);\n if (Object.keys(baselineHeaders).length > 0) {\n requestInit.headers = baselineHeaders;\n }\n if (typeof fetch === \"function\") {\n const nativeFetch = fetch.bind(globalThis);\n transportOptions.fetch = async (input: unknown, init?: unknown) =>\n nativeFetch(\n input as Parameters<typeof fetch>[0],\n await buildFirstPartyRequestInit(\n staticHeaders,\n init,\n this.firstPartyTrust(entry),\n ),\n );\n }\n } else if (Object.keys(staticHeaders).length > 0) {\n requestInit.headers = staticHeaders;\n }\n transport = new sdk.StreamableHTTPClientTransport(\n new URL(cfg.url),\n transportOptions,\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 const timeoutMs = mcpConnectTimeoutMs();\n await withConnectTimeout(\n Promise.resolve(client.connect(transport)),\n `MCP server ${entry.id} connect`,\n timeoutMs,\n );\n const listed = await withConnectTimeout(\n Promise.resolve(client.listTools()),\n `MCP server ${entry.id} tools/list`,\n timeoutMs,\n );\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 const entry = this.servers.get(id);\n if (entry?.error) reconnected.push(id);\n else 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 private shouldInjectFirstPartyIdentity(entry: ServerEntry): boolean {\n return this.firstPartyTrust(entry) !== null;\n }\n\n private firstPartyTrust(\n entry: ServerEntry,\n ): { orgId: string; appId: string; url: string } | null {\n if (entry.config.type !== \"http\" || entry.config.firstParty !== true) {\n return null;\n }\n const parsed = parseMergedKey(entry.id);\n if (parsed?.scope !== \"org\") return null;\n return {\n orgId: entry.config.firstPartyOrgId ?? parsed.owner,\n appId: entry.config.firstPartyAppId ?? parsed.name,\n url: entry.config.url,\n };\n }\n}\n\nfunction removeAuthorizationHeaders(headers: Record<string, string>): void {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === \"authorization\") delete headers[key];\n }\n}\n\nfunction headersToRecord(value: unknown): Record<string, string> {\n if (!value) return {};\n if (typeof Headers !== \"undefined\" && value instanceof Headers) {\n return Object.fromEntries(value.entries());\n }\n if (Array.isArray(value)) {\n return Object.fromEntries(\n value\n .filter((entry) => Array.isArray(entry) && entry.length >= 2)\n .map(([key, headerValue]) => [String(key), String(headerValue)]),\n );\n }\n if (typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(\n ([key, headerValue]) => [key, String(headerValue)],\n ),\n );\n }\n return {};\n}\n\nasync function buildFirstPartyRequestInit(\n staticHeaders: Record<string, string>,\n rawInit: unknown,\n trust: { orgId: string; appId: string; url: string } | null,\n): Promise<RequestInit> {\n const init =\n rawInit && typeof rawInit === \"object\" ? (rawInit as RequestInit) : {};\n const headers = {\n ...headersToRecord(staticHeaders),\n ...headersToRecord(init.headers),\n };\n removeAuthorizationHeaders(headers);\n const token = await mintFirstPartyMcpIdentityToken(trust).catch(() => null);\n if (token) headers.Authorization = `Bearer ${token}`;\n headers[\"x-agent-native-mcp-inline-apps\"] = \"1\";\n return { ...init, headers };\n}\n\nfunction randomJti(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`\n );\n}\n\nconst FIRST_PARTY_TRUST_TTL_MS = 60_000;\nconst FIRST_PARTY_TRUST_FAILURE_TTL_MS = 10_000;\nconst ORG_SIGNING_CONTEXT_TTL_MS = 60_000;\n\nconst firstPartyTrustCache = new Map<\n string,\n { ok: boolean; expiresAt: number }\n>();\nconst orgSigningContextCache = new Map<\n string,\n { orgDomain?: string; orgSecret?: string; expiresAt: number }\n>();\n\nasync function isFirstPartyTrustCached(trust: {\n orgId: string;\n appId: string;\n url: string;\n}): Promise<boolean> {\n const key = `${trust.orgId}\\n${trust.appId}\\n${trust.url}`;\n const cached = firstPartyTrustCache.get(key);\n if (cached && cached.expiresAt > Date.now()) return cached.ok;\n const result = await isFirstPartyRemoteEndpointTrusted(\n trust.orgId,\n trust.appId,\n trust.url,\n );\n const ok = result.ok === true;\n firstPartyTrustCache.set(key, {\n ok,\n expiresAt:\n Date.now() +\n (ok ? FIRST_PARTY_TRUST_TTL_MS : FIRST_PARTY_TRUST_FAILURE_TTL_MS),\n });\n return ok;\n}\n\nasync function resolveOrgSigningContext(orgId: string): Promise<{\n orgDomain?: string;\n orgSecret?: string;\n}> {\n const cached = orgSigningContextCache.get(orgId);\n if (cached && cached.expiresAt > Date.now()) {\n return { orgDomain: cached.orgDomain, orgSecret: cached.orgSecret };\n }\n let orgDomain: string | undefined;\n let orgSecret: string | undefined;\n try {\n const { getOrgDomain, getOrgA2ASecret } = await import(\"../org/context.js\");\n orgDomain = (await getOrgDomain(orgId)) ?? undefined;\n orgSecret = (await getOrgA2ASecret(orgId)) ?? undefined;\n } catch {\n // Global A2A_SECRET remains the hosted/common path.\n }\n orgSigningContextCache.set(orgId, {\n orgDomain,\n orgSecret,\n expiresAt: Date.now() + ORG_SIGNING_CONTEXT_TTL_MS,\n });\n return { orgDomain, orgSecret };\n}\n\nasync function mintFirstPartyMcpIdentityToken(\n trust: { orgId: string; appId: string; url: string } | null,\n): Promise<string | null> {\n if (!trust) return null;\n const [{ getRequestOrgId, getRequestUserEmail }, { signA2AToken }] =\n await Promise.all([\n import(\"../server/request-context.js\"),\n import(\"../a2a/client.js\"),\n ]);\n const userEmail = getRequestUserEmail();\n const requestOrgId = getRequestOrgId();\n if (requestOrgId && requestOrgId !== trust.orgId) {\n return null;\n }\n const orgId = requestOrgId ?? trust.orgId;\n if (!orgId) return null;\n if (!(await isFirstPartyTrustCached({ ...trust, orgId }))) return null;\n\n const { orgDomain, orgSecret } = await resolveOrgSigningContext(orgId);\n const subject =\n userEmail && requestOrgId\n ? userEmail\n : (await import(\"../mcp/connect-store.js\")).serviceIdentityEmail(\n \"mcp-client\",\n orgId,\n );\n\n return signA2AToken(subject, orgDomain, orgSecret, {\n expiresIn: \"5m\",\n audience: firstPartyMcpAudienceForUrl(trust.url),\n preferGlobalSecret: !orgSecret,\n extraClaims: {\n jti: randomJti(),\n scope: \"mcp-connect\",\n org_id: orgId,\n agent_native_first_party_mcp: true,\n },\n });\n}\n\nfunction firstPartyMcpAudienceForUrl(rawUrl: string): string | undefined {\n try {\n const url = new URL(rawUrl);\n const pathname = url.pathname.replace(/\\/+$/, \"\");\n if (pathname.endsWith(\"/_agent-native/mcp\")) {\n url.pathname = `${pathname.slice(0, -\"/_agent-native/mcp\".length)}/mcp`;\n } else {\n url.pathname = pathname.endsWith(\"/mcp\") ? pathname : `${pathname}/mcp`;\n }\n url.search = \"\";\n url.hash = \"\";\n return url.toString().replace(/\\/+$/, \"\");\n } catch {\n return undefined;\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 { MCP_APP_EXTENSION_ID, MCP_APP_MIME_TYPE } from \"../action.js\";\nimport type { McpConfig, McpServerConfig } from \"./config.js\";\nimport { formatMcpConnectError } from \"./errors.js\";\nimport {\n isFirstPartyRemoteEndpointTrusted,\n parseMergedKey,\n} from \"./remote-store.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 a.firstParty === b.firstParty &&\n a.firstPartyAppId === b.firstPartyAppId &&\n a.firstPartyOrgId === b.firstPartyOrgId\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\nconst DEFAULT_MCP_CONNECT_TIMEOUT_MS = 5_000;\n\nfunction mcpConnectTimeoutMs(): number {\n const raw =\n typeof process !== \"undefined\"\n ? process.env.AGENT_NATIVE_MCP_CLIENT_CONNECT_TIMEOUT_MS ||\n process.env.MCP_CLIENT_CONNECT_TIMEOUT_MS\n : undefined;\n const parsed = raw ? Number(raw) : NaN;\n if (Number.isFinite(parsed) && parsed >= 0) return parsed;\n return DEFAULT_MCP_CONNECT_TIMEOUT_MS;\n}\n\nasync function withConnectTimeout<T>(\n work: Promise<T>,\n label: string,\n timeoutMs: number,\n): Promise<T> {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) return work;\n let timer: ReturnType<typeof setTimeout> | undefined;\n const timeout = new Promise<never>((_resolve, reject) => {\n timer = setTimeout(() => {\n reject(new Error(`${label} timed out after ${timeoutMs}ms`));\n }, timeoutMs);\n });\n try {\n return await Promise.race([work, timeout]);\n } finally {\n if (timer) clearTimeout(timer);\n }\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 = await import(\"@modelcontextprotocol/client/stdio\");\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 = await import(\"@modelcontextprotocol/client\");\n let StdioClientTransport: any = null;\n if (needStdio && isNode()) {\n try {\n const stdioMod = await import(\"@modelcontextprotocol/client/stdio\");\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: clientMod.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 const staticHeaders = { ...(cfg.headers ?? {}) };\n const transportOptions: Record<string, unknown> = { requestInit };\n if (this.shouldInjectFirstPartyIdentity(entry)) {\n const baselineHeaders = { ...staticHeaders };\n removeAuthorizationHeaders(baselineHeaders);\n if (Object.keys(baselineHeaders).length > 0) {\n requestInit.headers = baselineHeaders;\n }\n if (typeof fetch === \"function\") {\n const nativeFetch = fetch.bind(globalThis);\n transportOptions.fetch = async (input: unknown, init?: unknown) =>\n nativeFetch(\n input as Parameters<typeof fetch>[0],\n await buildFirstPartyRequestInit(\n staticHeaders,\n init,\n this.firstPartyTrust(entry),\n ),\n );\n }\n } else if (Object.keys(staticHeaders).length > 0) {\n requestInit.headers = staticHeaders;\n }\n transport = new sdk.StreamableHTTPClientTransport(\n new URL(cfg.url),\n transportOptions,\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 versionNegotiation: { mode: \"auto\" },\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/client) 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 const timeoutMs = mcpConnectTimeoutMs();\n await withConnectTimeout(\n Promise.resolve(client.connect(transport)),\n `MCP server ${entry.id} connect`,\n timeoutMs,\n );\n const listed = await withConnectTimeout(\n Promise.resolve(client.listTools()),\n `MCP server ${entry.id} tools/list`,\n timeoutMs,\n );\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 const entry = this.servers.get(id);\n if (entry?.error) reconnected.push(id);\n else 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 private shouldInjectFirstPartyIdentity(entry: ServerEntry): boolean {\n return this.firstPartyTrust(entry) !== null;\n }\n\n private firstPartyTrust(\n entry: ServerEntry,\n ): { orgId: string; appId: string; url: string } | null {\n if (entry.config.type !== \"http\" || entry.config.firstParty !== true) {\n return null;\n }\n const parsed = parseMergedKey(entry.id);\n if (parsed?.scope !== \"org\") return null;\n return {\n orgId: entry.config.firstPartyOrgId ?? parsed.owner,\n appId: entry.config.firstPartyAppId ?? parsed.name,\n url: entry.config.url,\n };\n }\n}\n\nfunction removeAuthorizationHeaders(headers: Record<string, string>): void {\n for (const key of Object.keys(headers)) {\n if (key.toLowerCase() === \"authorization\") delete headers[key];\n }\n}\n\nfunction headersToRecord(value: unknown): Record<string, string> {\n if (!value) return {};\n if (typeof Headers !== \"undefined\" && value instanceof Headers) {\n return Object.fromEntries(value.entries());\n }\n if (Array.isArray(value)) {\n return Object.fromEntries(\n value\n .filter((entry) => Array.isArray(entry) && entry.length >= 2)\n .map(([key, headerValue]) => [String(key), String(headerValue)]),\n );\n }\n if (typeof value === \"object\") {\n return Object.fromEntries(\n Object.entries(value as Record<string, unknown>).map(\n ([key, headerValue]) => [key, String(headerValue)],\n ),\n );\n }\n return {};\n}\n\nasync function buildFirstPartyRequestInit(\n staticHeaders: Record<string, string>,\n rawInit: unknown,\n trust: { orgId: string; appId: string; url: string } | null,\n): Promise<RequestInit> {\n const init =\n rawInit && typeof rawInit === \"object\" ? (rawInit as RequestInit) : {};\n const headers = {\n ...headersToRecord(staticHeaders),\n ...headersToRecord(init.headers),\n };\n removeAuthorizationHeaders(headers);\n const token = await mintFirstPartyMcpIdentityToken(trust).catch(() => null);\n if (token) headers.Authorization = `Bearer ${token}`;\n headers[\"x-agent-native-mcp-inline-apps\"] = \"1\";\n return { ...init, headers };\n}\n\nfunction randomJti(): string {\n return (\n globalThis.crypto?.randomUUID?.() ??\n `${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`\n );\n}\n\nconst FIRST_PARTY_TRUST_TTL_MS = 60_000;\nconst FIRST_PARTY_TRUST_FAILURE_TTL_MS = 10_000;\nconst ORG_SIGNING_CONTEXT_TTL_MS = 60_000;\n\nconst firstPartyTrustCache = new Map<\n string,\n { ok: boolean; expiresAt: number }\n>();\nconst orgSigningContextCache = new Map<\n string,\n { orgDomain?: string; orgSecret?: string; expiresAt: number }\n>();\n\nasync function isFirstPartyTrustCached(trust: {\n orgId: string;\n appId: string;\n url: string;\n}): Promise<boolean> {\n const key = `${trust.orgId}\\n${trust.appId}\\n${trust.url}`;\n const cached = firstPartyTrustCache.get(key);\n if (cached && cached.expiresAt > Date.now()) return cached.ok;\n const result = await isFirstPartyRemoteEndpointTrusted(\n trust.orgId,\n trust.appId,\n trust.url,\n );\n const ok = result.ok === true;\n firstPartyTrustCache.set(key, {\n ok,\n expiresAt:\n Date.now() +\n (ok ? FIRST_PARTY_TRUST_TTL_MS : FIRST_PARTY_TRUST_FAILURE_TTL_MS),\n });\n return ok;\n}\n\nasync function resolveOrgSigningContext(orgId: string): Promise<{\n orgDomain?: string;\n orgSecret?: string;\n}> {\n const cached = orgSigningContextCache.get(orgId);\n if (cached && cached.expiresAt > Date.now()) {\n return { orgDomain: cached.orgDomain, orgSecret: cached.orgSecret };\n }\n let orgDomain: string | undefined;\n let orgSecret: string | undefined;\n try {\n const { getOrgDomain, getOrgA2ASecret } = await import(\"../org/context.js\");\n orgDomain = (await getOrgDomain(orgId)) ?? undefined;\n orgSecret = (await getOrgA2ASecret(orgId)) ?? undefined;\n } catch {\n // Global A2A_SECRET remains the hosted/common path.\n }\n orgSigningContextCache.set(orgId, {\n orgDomain,\n orgSecret,\n expiresAt: Date.now() + ORG_SIGNING_CONTEXT_TTL_MS,\n });\n return { orgDomain, orgSecret };\n}\n\nasync function mintFirstPartyMcpIdentityToken(\n trust: { orgId: string; appId: string; url: string } | null,\n): Promise<string | null> {\n if (!trust) return null;\n const [{ getRequestOrgId, getRequestUserEmail }, { signA2AToken }] =\n await Promise.all([\n import(\"../server/request-context.js\"),\n import(\"../a2a/client.js\"),\n ]);\n const userEmail = getRequestUserEmail();\n const requestOrgId = getRequestOrgId();\n if (requestOrgId && requestOrgId !== trust.orgId) {\n return null;\n }\n const orgId = requestOrgId ?? trust.orgId;\n if (!orgId) return null;\n if (!(await isFirstPartyTrustCached({ ...trust, orgId }))) return null;\n\n const { orgDomain, orgSecret } = await resolveOrgSigningContext(orgId);\n const subject =\n userEmail && requestOrgId\n ? userEmail\n : (await import(\"../mcp/connect-store.js\")).serviceIdentityEmail(\n \"mcp-client\",\n orgId,\n );\n\n return signA2AToken(subject, orgDomain, orgSecret, {\n expiresIn: \"5m\",\n audience: firstPartyMcpAudienceForUrl(trust.url),\n preferGlobalSecret: !orgSecret,\n extraClaims: {\n jti: randomJti(),\n scope: \"mcp-connect\",\n org_id: orgId,\n agent_native_first_party_mcp: true,\n },\n });\n}\n\nfunction firstPartyMcpAudienceForUrl(rawUrl: string): string | undefined {\n try {\n const url = new URL(rawUrl);\n const pathname = url.pathname.replace(/\\/+$/, \"\");\n if (pathname.endsWith(\"/_agent-native/mcp\")) {\n url.pathname = `${pathname.slice(0, -\"/_agent-native/mcp\".length)}/mcp`;\n } else {\n url.pathname = pathname.endsWith(\"/mcp\") ? pathname : `${pathname}/mcp`;\n }\n url.search = \"\";\n url.hash = \"\";\n return url.toString().replace(/\\/+$/, \"\");\n } catch {\n return undefined;\n }\n}\n"]}
|
|
@@ -6,26 +6,20 @@
|
|
|
6
6
|
* protocol details; this module owns the framework-specific encrypted storage
|
|
7
7
|
* and refresh boundary.
|
|
8
8
|
*/
|
|
9
|
-
import { type OAuthClientProvider } from "@modelcontextprotocol/
|
|
10
|
-
|
|
11
|
-
export interface McpOAuthDiscoveryState {
|
|
12
|
-
authorizationServerUrl: string;
|
|
13
|
-
authorizationServerMetadata?: AuthorizationServerMetadata;
|
|
14
|
-
resourceMetadata?: OAuthProtectedResourceMetadata;
|
|
15
|
-
resourceMetadataUrl?: string;
|
|
16
|
-
}
|
|
9
|
+
import { type AuthorizationServerMetadata, type OAuthClientInformationContext, type OAuthClientMetadata, type OAuthClientProvider, type OAuthDiscoveryState, OAuthProtectedResourceMetadata, type StoredOAuthClientInformation, type StoredOAuthTokens, OAuthTokens } from "@modelcontextprotocol/client";
|
|
10
|
+
export type McpOAuthDiscoveryState = OAuthDiscoveryState;
|
|
17
11
|
export interface McpOAuthCredentialBundle {
|
|
18
12
|
serverUrl: string;
|
|
19
|
-
clientInformation:
|
|
13
|
+
clientInformation: StoredOAuthClientInformation;
|
|
20
14
|
discoveryState?: McpOAuthDiscoveryState;
|
|
21
|
-
tokens:
|
|
15
|
+
tokens: StoredOAuthTokens;
|
|
22
16
|
tokenExpiresAt?: number;
|
|
23
17
|
}
|
|
24
18
|
export interface McpOAuthStartResult {
|
|
25
19
|
authorizationUrl: URL;
|
|
26
20
|
codeVerifier: string;
|
|
27
21
|
state: string;
|
|
28
|
-
clientInformation:
|
|
22
|
+
clientInformation: StoredOAuthClientInformation;
|
|
29
23
|
discoveryState?: McpOAuthDiscoveryState;
|
|
30
24
|
}
|
|
31
25
|
export interface McpOAuthCallbackResult {
|
|
@@ -35,7 +29,7 @@ export interface McpOAuthProviderOptions {
|
|
|
35
29
|
serverUrl: string;
|
|
36
30
|
redirectUrl: string;
|
|
37
31
|
state: string;
|
|
38
|
-
clientInformation?:
|
|
32
|
+
clientInformation?: StoredOAuthClientInformation;
|
|
39
33
|
codeVerifier?: string;
|
|
40
34
|
discoveryState?: McpOAuthDiscoveryState;
|
|
41
35
|
}
|
|
@@ -57,10 +51,10 @@ export declare class McpOAuthClientProvider implements OAuthClientProvider {
|
|
|
57
51
|
get redirectUrl(): string;
|
|
58
52
|
get clientMetadata(): OAuthClientMetadata;
|
|
59
53
|
state(): string;
|
|
60
|
-
clientInformation():
|
|
61
|
-
saveClientInformation(info:
|
|
62
|
-
tokens():
|
|
63
|
-
saveTokens(tokens:
|
|
54
|
+
clientInformation(context?: OAuthClientInformationContext): StoredOAuthClientInformation | undefined;
|
|
55
|
+
saveClientInformation(info: StoredOAuthClientInformation, context?: OAuthClientInformationContext): void;
|
|
56
|
+
tokens(context?: OAuthClientInformationContext): StoredOAuthTokens | undefined;
|
|
57
|
+
saveTokens(tokens: StoredOAuthTokens, context?: OAuthClientInformationContext): void;
|
|
64
58
|
redirectToAuthorization(authorizationUrl: URL): void;
|
|
65
59
|
saveCodeVerifier(codeVerifier: string): void;
|
|
66
60
|
codeVerifier(): string;
|
|
@@ -74,14 +68,16 @@ export declare class McpOAuthClientProvider implements OAuthClientProvider {
|
|
|
74
68
|
get authorizationRedirect(): URL | undefined;
|
|
75
69
|
get savedCodeVerifierValue(): string | undefined;
|
|
76
70
|
get savedTokensValue(): OAuthTokens | undefined;
|
|
77
|
-
get savedClientInformation():
|
|
71
|
+
get savedClientInformation(): StoredOAuthClientInformation | undefined;
|
|
78
72
|
}
|
|
79
73
|
export declare function startMcpOAuthAuthorization(options: McpOAuthProviderOptions & {
|
|
80
74
|
scope?: string;
|
|
81
75
|
}): Promise<McpOAuthStartResult>;
|
|
82
76
|
export declare function finishMcpOAuthAuthorization(options: McpOAuthProviderOptions & {
|
|
83
77
|
authorizationCode: string;
|
|
78
|
+
iss?: string;
|
|
84
79
|
}): Promise<McpOAuthCallbackResult>;
|
|
80
|
+
export declare function validateMcpOAuthCallbackIssuer(discoveryState: McpOAuthDiscoveryState | undefined, iss: string | undefined): void;
|
|
85
81
|
export declare function tokenExpiresAt(tokens: OAuthTokens): number | undefined;
|
|
86
82
|
export declare function saveMcpOAuthCredentials(options: {
|
|
87
83
|
key: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-client.d.ts","sourceRoot":"","sources":["../../src/mcp-client/oauth-client.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,
|
|
1
|
+
{"version":3,"file":"oauth-client.d.ts","sourceRoot":"","sources":["../../src/mcp-client/oauth-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* protocol details; this module owns the framework-specific encrypted storage
|
|
7
7
|
* and refresh boundary.
|
|
8
8
|
*/
|
|
9
|
-
import { auth, refreshAuthorization, } from "@modelcontextprotocol/
|
|
9
|
+
import { auth, refreshAuthorization, validateAuthorizationResponseIssuer, } from "@modelcontextprotocol/client";
|
|
10
10
|
import { deleteOAuthTokens, getOAuthTokens, saveOAuthTokens, } from "../oauth-tokens/store.js";
|
|
11
11
|
import { validateRemoteUrl } from "./remote-url.js";
|
|
12
12
|
const TOKEN_EXPIRY_SKEW_MS = 60_000;
|
|
@@ -88,6 +88,31 @@ function validateDiscoveryUrls(state) {
|
|
|
88
88
|
function credentialOwner(options) {
|
|
89
89
|
return `${options.scope}:${options.scopeId}`;
|
|
90
90
|
}
|
|
91
|
+
function issuerForDiscovery(discovery) {
|
|
92
|
+
const issuer = discovery?.authorizationServerMetadata?.issuer;
|
|
93
|
+
return typeof issuer === "string" && issuer ? issuer : undefined;
|
|
94
|
+
}
|
|
95
|
+
function withIssuer(value, context) {
|
|
96
|
+
if (value.issuer && context?.issuer && value.issuer !== context.issuer) {
|
|
97
|
+
throw new Error("MCP OAuth credential issuer does not match discovery");
|
|
98
|
+
}
|
|
99
|
+
const issuer = context?.issuer ?? value.issuer;
|
|
100
|
+
return issuer ? { ...value, issuer } : value;
|
|
101
|
+
}
|
|
102
|
+
function isBoundToIssuer(value, context) {
|
|
103
|
+
return !context?.issuer || value?.issuer === context.issuer;
|
|
104
|
+
}
|
|
105
|
+
function applicationTypeForRedirect(redirectUrl) {
|
|
106
|
+
const url = new URL(redirectUrl);
|
|
107
|
+
if (url.protocol !== "https:" ||
|
|
108
|
+
url.hostname === "localhost" ||
|
|
109
|
+
url.hostname === "127.0.0.1" ||
|
|
110
|
+
url.hostname === "::1" ||
|
|
111
|
+
url.hostname === "[::1]") {
|
|
112
|
+
return "native";
|
|
113
|
+
}
|
|
114
|
+
return "web";
|
|
115
|
+
}
|
|
91
116
|
/**
|
|
92
117
|
* A small adapter around the MCP SDK's OAuth provider interface. The route
|
|
93
118
|
* stores the adapter's state in an encrypted, short-lived browser cookie; the
|
|
@@ -108,11 +133,22 @@ export class McpOAuthClientProvider {
|
|
|
108
133
|
this.clientInfo = options.clientInformation;
|
|
109
134
|
this.savedCodeVerifier = options.codeVerifier;
|
|
110
135
|
this.savedDiscovery = options.discoveryState;
|
|
136
|
+
const recordedIssuer = issuerForDiscovery(this.savedDiscovery);
|
|
137
|
+
if (this.clientInfo &&
|
|
138
|
+
!this.clientInfo.issuer &&
|
|
139
|
+
recordedIssuer &&
|
|
140
|
+
this.savedCodeVerifier) {
|
|
141
|
+
// A callback flow persists registration, discovery, PKCE, and state in
|
|
142
|
+
// one encrypted cookie. Binding that pre-v2 in-flight registration to
|
|
143
|
+
// its recorded issuer is safe; durable credentials are never inferred.
|
|
144
|
+
this.clientInfo = { ...this.clientInfo, issuer: recordedIssuer };
|
|
145
|
+
}
|
|
111
146
|
this.metadata = {
|
|
112
147
|
redirect_uris: [options.redirectUrl],
|
|
113
148
|
token_endpoint_auth_method: "none",
|
|
114
|
-
grant_types: ["authorization_code"],
|
|
149
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
115
150
|
response_types: ["code"],
|
|
151
|
+
application_type: applicationTypeForRedirect(options.redirectUrl),
|
|
116
152
|
client_name: "Agent Native MCP connector",
|
|
117
153
|
};
|
|
118
154
|
}
|
|
@@ -125,17 +161,21 @@ export class McpOAuthClientProvider {
|
|
|
125
161
|
state() {
|
|
126
162
|
return this.stateValue;
|
|
127
163
|
}
|
|
128
|
-
clientInformation() {
|
|
129
|
-
return this.clientInfo
|
|
164
|
+
clientInformation(context) {
|
|
165
|
+
return isBoundToIssuer(this.clientInfo, context)
|
|
166
|
+
? this.clientInfo
|
|
167
|
+
: undefined;
|
|
130
168
|
}
|
|
131
|
-
saveClientInformation(info) {
|
|
132
|
-
this.clientInfo = info;
|
|
169
|
+
saveClientInformation(info, context) {
|
|
170
|
+
this.clientInfo = withIssuer(info, context);
|
|
133
171
|
}
|
|
134
|
-
tokens() {
|
|
135
|
-
return this.savedTokens
|
|
172
|
+
tokens(context) {
|
|
173
|
+
return isBoundToIssuer(this.savedTokens, context)
|
|
174
|
+
? this.savedTokens
|
|
175
|
+
: undefined;
|
|
136
176
|
}
|
|
137
|
-
saveTokens(tokens) {
|
|
138
|
-
this.savedTokens = tokens;
|
|
177
|
+
saveTokens(tokens, context) {
|
|
178
|
+
this.savedTokens = withIssuer(tokens, context);
|
|
139
179
|
}
|
|
140
180
|
redirectToAuthorization(authorizationUrl) {
|
|
141
181
|
this.authorizationUrl = checkedRemoteUrl(authorizationUrl, "authorization redirect");
|
|
@@ -198,6 +238,7 @@ export async function finishMcpOAuthAuthorization(options) {
|
|
|
198
238
|
const result = await auth(provider, {
|
|
199
239
|
serverUrl: options.serverUrl,
|
|
200
240
|
authorizationCode: options.authorizationCode,
|
|
241
|
+
iss: options.iss,
|
|
201
242
|
fetchFn: guardedOAuthFetch(),
|
|
202
243
|
});
|
|
203
244
|
if (result !== "AUTHORIZED" || !provider.savedTokensValue) {
|
|
@@ -214,6 +255,14 @@ export async function finishMcpOAuthAuthorization(options) {
|
|
|
214
255
|
},
|
|
215
256
|
};
|
|
216
257
|
}
|
|
258
|
+
export function validateMcpOAuthCallbackIssuer(discoveryState, iss) {
|
|
259
|
+
validateAuthorizationResponseIssuer({
|
|
260
|
+
iss,
|
|
261
|
+
expectedIssuer: issuerForDiscovery(discoveryState),
|
|
262
|
+
issParameterSupported: discoveryState?.authorizationServerMetadata
|
|
263
|
+
?.authorization_response_iss_parameter_supported === true,
|
|
264
|
+
});
|
|
265
|
+
}
|
|
217
266
|
export function tokenExpiresAt(tokens) {
|
|
218
267
|
const expiresIn = Number(tokens.expires_in);
|
|
219
268
|
if (!Number.isFinite(expiresIn) || expiresIn <= 0)
|
|
@@ -265,16 +314,24 @@ export async function getMcpOAuthAccessToken(options) {
|
|
|
265
314
|
if (!credentials || credentials.serverUrl !== options.serverUrl)
|
|
266
315
|
return null;
|
|
267
316
|
const accessToken = credentials.tokens.access_token;
|
|
317
|
+
const now = Date.now();
|
|
268
318
|
if (typeof credentials.tokenExpiresAt !== "number" ||
|
|
269
|
-
credentials.tokenExpiresAt -
|
|
319
|
+
credentials.tokenExpiresAt - now > TOKEN_EXPIRY_SKEW_MS) {
|
|
270
320
|
return accessToken;
|
|
271
321
|
}
|
|
322
|
+
const tokenIsExpired = credentials.tokenExpiresAt <= now;
|
|
272
323
|
const refreshToken = credentials.tokens.refresh_token;
|
|
273
324
|
const discovery = credentials.discoveryState;
|
|
274
325
|
if (!refreshToken || !discovery?.authorizationServerUrl) {
|
|
275
|
-
return accessToken;
|
|
326
|
+
return tokenIsExpired ? null : accessToken;
|
|
276
327
|
}
|
|
277
328
|
try {
|
|
329
|
+
const expectedIssuer = issuerForDiscovery(discovery);
|
|
330
|
+
if (!expectedIssuer ||
|
|
331
|
+
credentials.clientInformation.issuer !== expectedIssuer ||
|
|
332
|
+
credentials.tokens.issuer !== expectedIssuer) {
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
278
335
|
const resource = discovery.resourceMetadata?.resource
|
|
279
336
|
? checkedRemoteUrl(discovery.resourceMetadata.resource, "resource")
|
|
280
337
|
: undefined;
|
|
@@ -289,6 +346,7 @@ export async function getMcpOAuthAccessToken(options) {
|
|
|
289
346
|
const nextTokens = {
|
|
290
347
|
...credentials.tokens,
|
|
291
348
|
...refreshed,
|
|
349
|
+
issuer: expectedIssuer,
|
|
292
350
|
...(refreshed.refresh_token
|
|
293
351
|
? { refresh_token: refreshed.refresh_token }
|
|
294
352
|
: credentials.tokens.refresh_token
|
|
@@ -307,10 +365,10 @@ export async function getMcpOAuthAccessToken(options) {
|
|
|
307
365
|
return nextTokens.access_token;
|
|
308
366
|
}
|
|
309
367
|
catch {
|
|
310
|
-
//
|
|
311
|
-
//
|
|
312
|
-
//
|
|
313
|
-
return accessToken;
|
|
368
|
+
// A still-valid token can survive a transient refresh failure. Once it has
|
|
369
|
+
// expired, omit it so callers surface reauthorization instead of retrying
|
|
370
|
+
// a credential that can never authenticate.
|
|
371
|
+
return tokenIsExpired ? null : accessToken;
|
|
314
372
|
}
|
|
315
373
|
}
|
|
316
374
|
//# sourceMappingURL=oauth-client.js.map
|