@agent-native/core 0.128.4 → 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 +84 -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/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/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/security/SKILL.md +13 -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/chat/README.md +0 -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/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/collab/struct-routes.d.ts +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/file-upload/actions/upload-image.d.ts +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/observability/routes.d.ts +3 -3
- package/dist/progress/routes.d.ts +1 -1
- package/dist/provider-api/actions/custom-provider-registration.d.ts +14 -14
- package/dist/provider-api/actions/provider-api.d.ts +8 -8
- 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/realtime-token.d.ts +1 -1
- package/dist/server/transcribe-voice.d.ts +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/chat/README.md +0 -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/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/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/chat/README.md +0 -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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-server.d.ts","sourceRoot":"","sources":["../../src/mcp/build-server.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"build-server.d.ts","sourceRoot":"","sources":["../../src/mcp/build-server.ts"],"names":[],"mappings":"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"}
|
package/dist/mcp/build-server.js
CHANGED
|
@@ -24,10 +24,65 @@ import { buildDeepLink, toAbsoluteOpenUrl, toDesktopOpenUrl, toVsCodeOpenUrl, }
|
|
|
24
24
|
import { getRequestContext, getRequestOrgId, getRequestUserEmail, runWithRequestContext, } from "../server/request-context.js";
|
|
25
25
|
import { isAgentNativeOpenDeepLink, withCollapsedAgentSidebarParam, } from "../shared/agent-sidebar-url.js";
|
|
26
26
|
import { MCP_APP_CHAT_BRIDGE_QUERY_PARAM } from "../shared/embed-auth.js";
|
|
27
|
+
import { consumeMcpApprovalGrant, createMcpApprovalGrant, } from "./approval-store.js";
|
|
27
28
|
import { getBuiltinCrossAppTools } from "./builtin-tools.js";
|
|
28
29
|
import { MCP_CONNECT_OAUTH_CLIENT_ID, MCP_CONNECT_SCOPE, } from "./connect-store.js";
|
|
29
30
|
import { MCP_APP_REQUEST_ORIGIN_CSP_SOURCE } from "./embed-app.js";
|
|
30
31
|
import { hasMcpOAuthScope, verifyMcpOAuthAccessToken, } from "./oauth-token.js";
|
|
32
|
+
const MCP_ACTION_APPROVAL_TTL_SECONDS = 10 * 60;
|
|
33
|
+
const MCP_ACTION_APPROVAL_INPUT_KEY = "actionApproval";
|
|
34
|
+
function canonicalJson(value) {
|
|
35
|
+
if (value === null ||
|
|
36
|
+
typeof value === "boolean" ||
|
|
37
|
+
typeof value === "string") {
|
|
38
|
+
return JSON.stringify(value);
|
|
39
|
+
}
|
|
40
|
+
if (typeof value === "number") {
|
|
41
|
+
if (!Number.isFinite(value)) {
|
|
42
|
+
throw new TypeError("MCP action arguments must contain finite numbers");
|
|
43
|
+
}
|
|
44
|
+
return JSON.stringify(value);
|
|
45
|
+
}
|
|
46
|
+
if (Array.isArray(value)) {
|
|
47
|
+
return `[${value.map((item) => canonicalJson(item)).join(",")}]`;
|
|
48
|
+
}
|
|
49
|
+
if (value && typeof value === "object") {
|
|
50
|
+
const record = value;
|
|
51
|
+
return `{${Object.keys(record)
|
|
52
|
+
.sort()
|
|
53
|
+
.map((key) => `${JSON.stringify(key)}:${canonicalJson(record[key])}`)
|
|
54
|
+
.join(",")}}`;
|
|
55
|
+
}
|
|
56
|
+
throw new TypeError("MCP action arguments must be JSON values");
|
|
57
|
+
}
|
|
58
|
+
async function sha256Base64Url(value) {
|
|
59
|
+
const digest = await globalThis.crypto.subtle.digest("SHA-256", new TextEncoder().encode(value));
|
|
60
|
+
const bytes = new Uint8Array(digest);
|
|
61
|
+
let binary = "";
|
|
62
|
+
for (const byte of bytes)
|
|
63
|
+
binary += String.fromCharCode(byte);
|
|
64
|
+
return btoa(binary)
|
|
65
|
+
.replace(/\+/g, "-")
|
|
66
|
+
.replace(/\//g, "_")
|
|
67
|
+
.replace(/=+$/, "");
|
|
68
|
+
}
|
|
69
|
+
function mcpApprovalPrincipal(identity, orgId, requestMeta) {
|
|
70
|
+
return canonicalJson({
|
|
71
|
+
caller: "mcp",
|
|
72
|
+
userEmail: identity?.userEmail?.trim().toLowerCase() ?? "",
|
|
73
|
+
orgId: orgId ?? identity?.orgId ?? "",
|
|
74
|
+
orgDomain: identity?.orgDomain?.trim().toLowerCase() ?? "",
|
|
75
|
+
oauthClientId: identity?.oauthClientId ?? "",
|
|
76
|
+
firstPartyMcp: identity?.firstPartyMcp === true,
|
|
77
|
+
origin: requestMeta?.origin ?? "",
|
|
78
|
+
});
|
|
79
|
+
}
|
|
80
|
+
function actionApprovalError(message) {
|
|
81
|
+
return {
|
|
82
|
+
content: [{ type: "text", text: message }],
|
|
83
|
+
isError: true,
|
|
84
|
+
};
|
|
85
|
+
}
|
|
31
86
|
const ASK_AGENT_DEFAULT_INLINE_WAIT_MS = 20_000;
|
|
32
87
|
const ASK_AGENT_MAX_INLINE_WAIT_MS = 25_000;
|
|
33
88
|
function boundedAskAgentWaitMs(raw) {
|
|
@@ -639,6 +694,9 @@ function mcpServerInfo(config, requestMeta) {
|
|
|
639
694
|
...(icons?.length ? { icons } : {}),
|
|
640
695
|
};
|
|
641
696
|
}
|
|
697
|
+
function compareMcpCatalogValues(a, b) {
|
|
698
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
699
|
+
}
|
|
642
700
|
function safeUiSegment(value, fallback) {
|
|
643
701
|
const normalized = (value || fallback)
|
|
644
702
|
.trim()
|
|
@@ -1016,8 +1074,7 @@ function conciseToolResultText(name, result, options) {
|
|
|
1016
1074
|
* origin so deep links still become absolute URLs.
|
|
1017
1075
|
*/
|
|
1018
1076
|
export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
1019
|
-
const { Server } = await import("@modelcontextprotocol/
|
|
1020
|
-
const { ListToolsRequestSchema, CallToolRequestSchema, ListResourcesRequestSchema, ReadResourceRequestSchema, ListResourceTemplatesRequestSchema, } = await import("@modelcontextprotocol/sdk/types.js");
|
|
1077
|
+
const { ResourceNotFoundError, Server, acceptedContent, createRequestStateCodec, inputRequired, } = await import("@modelcontextprotocol/server");
|
|
1021
1078
|
// Resolve the effective caller identity. JWT / header-derived identity
|
|
1022
1079
|
// (passed by `mountMCP` via `verifyAuth`) wins. When the caller passed no
|
|
1023
1080
|
// identity — the stdio **standalone** path — fall back to the
|
|
@@ -1101,6 +1158,37 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1101
1158
|
if (fullCatalogRequested) {
|
|
1102
1159
|
warnFullCatalogServed(Object.keys(advertisedActions).length);
|
|
1103
1160
|
}
|
|
1161
|
+
// Resolve orgId once per request (DB lookup) so approval state and every
|
|
1162
|
+
// downstream action see the same authenticated principal.
|
|
1163
|
+
const orgIdPromise = resolveMcpIdentityOrgId(effectiveIdentity);
|
|
1164
|
+
const hasApprovalActions = Object.values(actions).some((entry) => entry.needsApproval !== undefined);
|
|
1165
|
+
const approvalOrgId = hasApprovalActions ? await orgIdPromise : undefined;
|
|
1166
|
+
const approvalPrincipal = hasApprovalActions
|
|
1167
|
+
? mcpApprovalPrincipal(effectiveIdentity, approvalOrgId, requestMeta)
|
|
1168
|
+
: undefined;
|
|
1169
|
+
const approvalCallerKey = approvalPrincipal
|
|
1170
|
+
? await sha256Base64Url(approvalPrincipal)
|
|
1171
|
+
: undefined;
|
|
1172
|
+
let approvalCodec;
|
|
1173
|
+
let approvalConfigurationError = false;
|
|
1174
|
+
if (hasApprovalActions && approvalPrincipal) {
|
|
1175
|
+
try {
|
|
1176
|
+
const { getAuthSecret } = await import("../server/better-auth-instance.js");
|
|
1177
|
+
approvalCodec = createRequestStateCodec({
|
|
1178
|
+
key: getAuthSecret(),
|
|
1179
|
+
ttlSeconds: MCP_ACTION_APPROVAL_TTL_SECONDS,
|
|
1180
|
+
bind: (ctx) => `${ctx.mcpReq.method}\0${approvalPrincipal}`,
|
|
1181
|
+
});
|
|
1182
|
+
}
|
|
1183
|
+
catch {
|
|
1184
|
+
// Production secret resolution deliberately throws when neither the
|
|
1185
|
+
// explicit Better Auth secret nor the workspace-derived A2A secret is
|
|
1186
|
+
// stable. Keep the MCP server available for reads, but refuse every
|
|
1187
|
+
// approval-gated action rather than minting replayable/ephemeral hosted
|
|
1188
|
+
// authorization state.
|
|
1189
|
+
approvalConfigurationError = true;
|
|
1190
|
+
}
|
|
1191
|
+
}
|
|
1104
1192
|
const supportsMcpApps = compactMcpAppCatalog ||
|
|
1105
1193
|
Object.values(advertisedActions).some((entry) => Boolean(entry.mcpApp?.resource));
|
|
1106
1194
|
const server = new Server(mcpServerInfo(config, requestMeta), {
|
|
@@ -1117,13 +1205,27 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1117
1205
|
}
|
|
1118
1206
|
: {}),
|
|
1119
1207
|
},
|
|
1208
|
+
// Every catalog and resource is identity-scoped and can change at runtime
|
|
1209
|
+
// through app configuration/HMR. Explicitly mark modern cacheable results
|
|
1210
|
+
// private and immediately stale; the 2026 codec adds the required
|
|
1211
|
+
// ttlMs/cacheScope fields while 2025 responses remain byte-compatible.
|
|
1212
|
+
cacheHints: {
|
|
1213
|
+
"server/discover": { ttlMs: 0, cacheScope: "private" },
|
|
1214
|
+
"tools/list": { ttlMs: 0, cacheScope: "private" },
|
|
1215
|
+
"resources/list": { ttlMs: 0, cacheScope: "private" },
|
|
1216
|
+
"resources/templates/list": { ttlMs: 0, cacheScope: "private" },
|
|
1217
|
+
"resources/read": { ttlMs: 0, cacheScope: "private" },
|
|
1218
|
+
},
|
|
1219
|
+
...(approvalCodec
|
|
1220
|
+
? {
|
|
1221
|
+
inputRequired: {
|
|
1222
|
+
maxRounds: 2,
|
|
1223
|
+
roundTimeoutMs: 10 * 60_000,
|
|
1224
|
+
},
|
|
1225
|
+
requestState: { verify: approvalCodec.verify },
|
|
1226
|
+
}
|
|
1227
|
+
: {}),
|
|
1120
1228
|
});
|
|
1121
|
-
// Resolve orgId once per request (DB lookup) so subsequent wraps are
|
|
1122
|
-
// synchronous. The caller identity may be undefined for true dev-open —
|
|
1123
|
-
// in that case we run with no userEmail/orgId, which makes downstream
|
|
1124
|
-
// tools that require per-user scope return empty results rather than
|
|
1125
|
-
// cross-tenant data (the safe default).
|
|
1126
|
-
const orgIdPromise = resolveMcpIdentityOrgId(effectiveIdentity);
|
|
1127
1229
|
/**
|
|
1128
1230
|
* Wrap a callback in
|
|
1129
1231
|
* `runWithRequestContext({ userEmail, orgId, requestOrigin }, fn)`.
|
|
@@ -1143,12 +1245,100 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1143
1245
|
...(requestMeta?.origin ? { requestOrigin: requestMeta.origin } : {}),
|
|
1144
1246
|
}, fn);
|
|
1145
1247
|
}
|
|
1248
|
+
async function requireMcpActionApproval(entry, name, args, ctx) {
|
|
1249
|
+
const verifiedState = ctx.mcpReq.requestState() ?? undefined;
|
|
1250
|
+
const argumentsHash = await sha256Base64Url(canonicalJson(args));
|
|
1251
|
+
if (verifiedState !== undefined) {
|
|
1252
|
+
if (verifiedState.version !== 1 ||
|
|
1253
|
+
typeof verifiedState.nonce !== "string" ||
|
|
1254
|
+
verifiedState.actionName !== name ||
|
|
1255
|
+
verifiedState.argumentsHash !== argumentsHash ||
|
|
1256
|
+
!Number.isFinite(verifiedState.expiresAt) ||
|
|
1257
|
+
verifiedState.expiresAt < Date.now() ||
|
|
1258
|
+
!approvalCallerKey) {
|
|
1259
|
+
return actionApprovalError(`Approval for ${name} is invalid or does not match this exact call.`);
|
|
1260
|
+
}
|
|
1261
|
+
const consumed = await consumeMcpApprovalGrant({
|
|
1262
|
+
nonce: verifiedState.nonce,
|
|
1263
|
+
callerKey: approvalCallerKey,
|
|
1264
|
+
actionName: name,
|
|
1265
|
+
argumentsHash,
|
|
1266
|
+
expiresAt: verifiedState.expiresAt,
|
|
1267
|
+
});
|
|
1268
|
+
if (!consumed) {
|
|
1269
|
+
return actionApprovalError(`Approval for ${name} is invalid, expired, or already used.`);
|
|
1270
|
+
}
|
|
1271
|
+
const approval = acceptedContent(ctx.mcpReq.inputResponses, MCP_ACTION_APPROVAL_INPUT_KEY);
|
|
1272
|
+
if (approval?.decision !== "approve") {
|
|
1273
|
+
return actionApprovalError(`${name} was not approved.`);
|
|
1274
|
+
}
|
|
1275
|
+
return undefined;
|
|
1276
|
+
}
|
|
1277
|
+
if (entry.needsApproval === undefined)
|
|
1278
|
+
return undefined;
|
|
1279
|
+
let mustApprove = false;
|
|
1280
|
+
try {
|
|
1281
|
+
mustApprove =
|
|
1282
|
+
typeof entry.needsApproval === "function"
|
|
1283
|
+
? Boolean(await entry.needsApproval(args, {
|
|
1284
|
+
userEmail: getRequestUserEmail(),
|
|
1285
|
+
orgId: getRequestOrgId() ?? null,
|
|
1286
|
+
caller: "mcp",
|
|
1287
|
+
actionName: name,
|
|
1288
|
+
}))
|
|
1289
|
+
: entry.needsApproval === true;
|
|
1290
|
+
}
|
|
1291
|
+
catch {
|
|
1292
|
+
mustApprove = true;
|
|
1293
|
+
}
|
|
1294
|
+
if (!mustApprove)
|
|
1295
|
+
return undefined;
|
|
1296
|
+
if (approvalConfigurationError || !approvalCodec || !approvalCallerKey) {
|
|
1297
|
+
return actionApprovalError(`${name} requires approval, but secure MCP approval is not configured on this server.`);
|
|
1298
|
+
}
|
|
1299
|
+
const now = Date.now();
|
|
1300
|
+
const approvalState = {
|
|
1301
|
+
version: 1,
|
|
1302
|
+
nonce: globalThis.crypto.randomUUID(),
|
|
1303
|
+
actionName: name,
|
|
1304
|
+
argumentsHash,
|
|
1305
|
+
expiresAt: now + MCP_ACTION_APPROVAL_TTL_SECONDS * 1000,
|
|
1306
|
+
};
|
|
1307
|
+
await createMcpApprovalGrant({
|
|
1308
|
+
...approvalState,
|
|
1309
|
+
callerKey: approvalCallerKey,
|
|
1310
|
+
});
|
|
1311
|
+
const requestState = await approvalCodec.mint(approvalState, ctx);
|
|
1312
|
+
return inputRequired({
|
|
1313
|
+
inputRequests: {
|
|
1314
|
+
[MCP_ACTION_APPROVAL_INPUT_KEY]: inputRequired.elicit({
|
|
1315
|
+
message: `Action "${name}" requires your approval before it can run. ` +
|
|
1316
|
+
"Review the exact tool arguments in your MCP client, then explicitly choose Approve or Deny.",
|
|
1317
|
+
requestedSchema: {
|
|
1318
|
+
type: "object",
|
|
1319
|
+
properties: {
|
|
1320
|
+
decision: {
|
|
1321
|
+
type: "string",
|
|
1322
|
+
title: `Run ${name}?`,
|
|
1323
|
+
description: "Approve runs this exact call once. Deny leaves it unexecuted.",
|
|
1324
|
+
enum: ["approve", "deny"],
|
|
1325
|
+
},
|
|
1326
|
+
},
|
|
1327
|
+
required: ["decision"],
|
|
1328
|
+
},
|
|
1329
|
+
}),
|
|
1330
|
+
},
|
|
1331
|
+
requestState,
|
|
1332
|
+
});
|
|
1333
|
+
}
|
|
1146
1334
|
// tools/list — return all actions + ask-agent meta-tool. Wrapped in the
|
|
1147
1335
|
// request context so per-user MCP visibility (mcp-client/visibility.ts)
|
|
1148
1336
|
// applies to the listing too.
|
|
1149
|
-
server.setRequestHandler(
|
|
1337
|
+
server.setRequestHandler("tools/list", async () => {
|
|
1150
1338
|
return withCallerContext(async () => {
|
|
1151
|
-
const tools = await Promise.all(Object.entries(advertisedActions)
|
|
1339
|
+
const tools = await Promise.all(Object.entries(advertisedActions)
|
|
1340
|
+
.sort(([a], [b]) => compareMcpCatalogValues(a, b))
|
|
1341
|
+
.map(async ([name, entry]) => {
|
|
1152
1342
|
const hasLink = typeof entry.link === "function";
|
|
1153
1343
|
const mcpAppResource = await resolveMcpAppResourceSafely(config, name, entry, requestMeta);
|
|
1154
1344
|
const rawToolMeta = entry.tool._meta &&
|
|
@@ -1159,8 +1349,8 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1159
1349
|
const toolMeta = {
|
|
1160
1350
|
...rawToolMeta,
|
|
1161
1351
|
// Advertisement path: only tag the tool with its inline-embed
|
|
1162
|
-
// descriptor when the kill switch is on, so disabled embeds
|
|
1163
|
-
// prompt a host to render/read the `ui://` resource.
|
|
1352
|
+
// descriptor when the kill switch is on, so disabled embeds
|
|
1353
|
+
// never prompt a host to render/read the `ui://` resource.
|
|
1164
1354
|
...(mcpAppResource && requestMeta?.inlineMcpApps
|
|
1165
1355
|
? {
|
|
1166
1356
|
...openAiToolDescriptorMeta(mcpAppResource),
|
|
@@ -1173,7 +1363,8 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1173
1363
|
const baseDescription = entry.tool.description ?? name;
|
|
1174
1364
|
const annotations = {
|
|
1175
1365
|
readOnlyHint: entry.readOnly === true,
|
|
1176
|
-
destructiveHint: entry.publicAgent?.isConsequential === true
|
|
1366
|
+
destructiveHint: entry.publicAgent?.isConsequential === true ||
|
|
1367
|
+
entry.needsApproval !== undefined,
|
|
1177
1368
|
openWorldHint: false,
|
|
1178
1369
|
};
|
|
1179
1370
|
if (hasLink)
|
|
@@ -1227,13 +1418,14 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1227
1418
|
},
|
|
1228
1419
|
});
|
|
1229
1420
|
}
|
|
1421
|
+
tools.sort((a, b) => compareMcpCatalogValues(a.name, b.name));
|
|
1230
1422
|
return { tools };
|
|
1231
1423
|
});
|
|
1232
1424
|
});
|
|
1233
1425
|
// tools/call — dispatch to action registry or ask-agent. Wrapped in the
|
|
1234
1426
|
// request context so the action's `run(args)` and `askAgent()` execute
|
|
1235
1427
|
// with the verified caller's identity, not the platform default.
|
|
1236
|
-
server.setRequestHandler(
|
|
1428
|
+
server.setRequestHandler("tools/call", async (request, ctx) => {
|
|
1237
1429
|
return withCallerContext(async () => {
|
|
1238
1430
|
const { name, arguments: args } = request.params;
|
|
1239
1431
|
if (name === "ask-agent" && config.askAgent) {
|
|
@@ -1309,6 +1501,9 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1309
1501
|
};
|
|
1310
1502
|
}
|
|
1311
1503
|
try {
|
|
1504
|
+
const approvalResult = await requireMcpActionApproval(entry, name, args ?? {}, ctx);
|
|
1505
|
+
if (approvalResult !== undefined)
|
|
1506
|
+
return approvalResult;
|
|
1312
1507
|
// We're inside `withCallerContext`, so the request-context getters
|
|
1313
1508
|
// resolve the verified MCP caller's identity (do NOT inject a dev
|
|
1314
1509
|
// fallback). Tag the call as an external-agent MCP dispatch.
|
|
@@ -1404,11 +1599,13 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1404
1599
|
});
|
|
1405
1600
|
});
|
|
1406
1601
|
if (supportsMcpApps) {
|
|
1407
|
-
server.setRequestHandler(
|
|
1602
|
+
server.setRequestHandler("resources/list", async () => {
|
|
1408
1603
|
return withCallerContext(async () => {
|
|
1409
1604
|
const mcpAppResources = await getMcpAppResources(config, advertisedActions, requestMeta);
|
|
1410
1605
|
return {
|
|
1411
|
-
resources: mcpAppResources
|
|
1606
|
+
resources: mcpAppResources
|
|
1607
|
+
.sort((a, b) => compareMcpCatalogValues(a.uri, b.uri))
|
|
1608
|
+
.map((resource) => ({
|
|
1412
1609
|
uri: resource.uri,
|
|
1413
1610
|
name: resource.name,
|
|
1414
1611
|
...(resource.title ? { title: resource.title } : {}),
|
|
@@ -1421,11 +1618,13 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1421
1618
|
};
|
|
1422
1619
|
});
|
|
1423
1620
|
});
|
|
1424
|
-
server.setRequestHandler(
|
|
1621
|
+
server.setRequestHandler("resources/templates/list", async () => {
|
|
1425
1622
|
return withCallerContext(async () => {
|
|
1426
1623
|
const mcpAppResources = await getMcpAppResources(config, advertisedActions, requestMeta);
|
|
1427
1624
|
return {
|
|
1428
|
-
resourceTemplates: mcpAppResources
|
|
1625
|
+
resourceTemplates: mcpAppResources
|
|
1626
|
+
.sort((a, b) => compareMcpCatalogValues(a.uri, b.uri))
|
|
1627
|
+
.map((resource) => ({
|
|
1429
1628
|
uriTemplate: resource.uri,
|
|
1430
1629
|
name: resource.name,
|
|
1431
1630
|
...(resource.title ? { title: resource.title } : {}),
|
|
@@ -1438,7 +1637,7 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1438
1637
|
};
|
|
1439
1638
|
});
|
|
1440
1639
|
});
|
|
1441
|
-
server.setRequestHandler(
|
|
1640
|
+
server.setRequestHandler("resources/read", async (request) => {
|
|
1442
1641
|
return withCallerContext(async () => {
|
|
1443
1642
|
const uri = request.params?.uri;
|
|
1444
1643
|
let found = null;
|
|
@@ -1457,7 +1656,7 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1457
1656
|
// aborting and reporting the resource as missing.
|
|
1458
1657
|
}
|
|
1459
1658
|
if (!found) {
|
|
1460
|
-
throw new
|
|
1659
|
+
throw new ResourceNotFoundError(String(uri ?? ""), `MCP App resource not found: ${uri}`);
|
|
1461
1660
|
}
|
|
1462
1661
|
return {
|
|
1463
1662
|
contents: [
|
|
@@ -1465,9 +1664,7 @@ export async function createMCPServerForRequest(config, identity, requestMeta) {
|
|
|
1465
1664
|
uri,
|
|
1466
1665
|
mimeType: found.resource.mimeType,
|
|
1467
1666
|
text: renderMcpAppHtml(found.resource, found.actionName, config, requestMeta),
|
|
1468
|
-
...(found.resource._meta
|
|
1469
|
-
? { _meta: found.resource._meta }
|
|
1470
|
-
: {}),
|
|
1667
|
+
...(found.resource._meta ? { _meta: found.resource._meta } : {}),
|
|
1471
1668
|
},
|
|
1472
1669
|
],
|
|
1473
1670
|
};
|