@gajae-code/coding-agent 0.13.3 → 0.14.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/CHANGELOG.md +184 -2
- package/README.md +2 -0
- package/bin/gajaessi.js +4 -0
- package/dist/types/async/job-manager.d.ts +55 -2
- package/dist/types/async/support.d.ts +14 -0
- package/dist/types/capability/mcp.d.ts +6 -0
- package/dist/types/capability/types.d.ts +6 -0
- package/dist/types/cli/accounts-cli.d.ts +19 -0
- package/dist/types/cli/args.d.ts +3 -0
- package/dist/types/cli/config-cli.d.ts +6 -0
- package/dist/types/cli/crash-cli.d.ts +10 -0
- package/dist/types/cli/customize-doctor.d.ts +145 -0
- package/dist/types/cli/daemon-cli.d.ts +3 -1
- package/dist/types/cli/mcp-cli.d.ts +11 -0
- package/dist/types/cli/notify-cli.d.ts +1 -1
- package/dist/types/cli/root-flags.d.ts +12 -0
- package/dist/types/cli/setup-cli.d.ts +3 -1
- package/dist/types/cli/skills-cli.d.ts +2 -1
- package/dist/types/cli/update-cli.d.ts +19 -1
- package/dist/types/cli.d.ts +6 -0
- package/dist/types/commands/accounts.d.ts +40 -0
- package/dist/types/commands/crash.d.ts +24 -0
- package/dist/types/commands/customize.d.ts +22 -0
- package/dist/types/commands/daemon.d.ts +1 -1
- package/dist/types/commands/launch.d.ts +6 -0
- package/dist/types/commands/setup.d.ts +6 -0
- package/dist/types/commands/skills.d.ts +6 -1
- package/dist/types/commands/update.d.ts +7 -0
- package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
- package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
- package/dist/types/config/config-schema-version.d.ts +10 -0
- package/dist/types/config/file-lock.d.ts +18 -0
- package/dist/types/config/model-profile-activation.d.ts +3 -1
- package/dist/types/config/model-registry.d.ts +9 -1
- package/dist/types/config/models-config-schema.d.ts +2 -0
- package/dist/types/config/settings-schema.d.ts +70 -6
- package/dist/types/config/settings.d.ts +63 -0
- package/dist/types/config/skill-settings-defaults.d.ts +26 -0
- package/dist/types/config/task-delegation.d.ts +39 -0
- package/dist/types/config/update-channel.d.ts +10 -0
- package/dist/types/coordinator-mcp/server.d.ts +5 -1
- package/dist/types/crash/index-store.d.ts +87 -0
- package/dist/types/crash/nudge.d.ts +50 -0
- package/dist/types/crash/record-loader.d.ts +17 -0
- package/dist/types/crash/report.d.ts +134 -0
- package/dist/types/crash/sanitize.d.ts +25 -0
- package/dist/types/cursor.d.ts +13 -2
- package/dist/types/customization/import.d.ts +37 -0
- package/dist/types/customization/index.d.ts +4 -0
- package/dist/types/customization/inventory.d.ts +25 -0
- package/dist/types/customization/mutations.d.ts +32 -0
- package/dist/types/customization/types.d.ts +115 -0
- package/dist/types/daemon/control-types.d.ts +8 -1
- package/dist/types/daemon/operator-contract.d.ts +4 -4
- package/dist/types/discovery/claude.d.ts +39 -1
- package/dist/types/discovery/codex.d.ts +39 -1
- package/dist/types/discovery/index.d.ts +2 -0
- package/dist/types/discovery/mcp-compat.d.ts +30 -0
- package/dist/types/edit/renderer.d.ts +23 -0
- package/dist/types/extensibility/extensions/runner.d.ts +3 -0
- package/dist/types/extensibility/extensions/types.d.ts +21 -4
- package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
- package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
- package/dist/types/extensibility/hooks/loader.d.ts +19 -5
- package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
- package/dist/types/extensibility/skill-management.d.ts +107 -0
- package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
- package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
- package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
- package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
- package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
- package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
- package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
- package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
- package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
- package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
- package/dist/types/hooks/events.d.ts +60 -0
- package/dist/types/hooks/normalize.d.ts +83 -0
- package/dist/types/hooks/skill-state.d.ts +9 -2
- package/dist/types/main.d.ts +1 -1
- package/dist/types/modes/acp/abort-scope.d.ts +13 -0
- package/dist/types/modes/acp/acp-agent.d.ts +7 -4
- package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
- package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
- package/dist/types/modes/components/customization/index.d.ts +1 -0
- package/dist/types/modes/components/gajae-pet-widget.d.ts +8 -30
- package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
- package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
- package/dist/types/modes/components/oauth-selector.d.ts +10 -4
- package/dist/types/modes/components/pet-capability.d.ts +11 -25
- package/dist/types/modes/components/status-line/gh.d.ts +6 -2
- package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
- package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
- package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
- package/dist/types/modes/interactive-mode.d.ts +1 -0
- package/dist/types/modes/types.d.ts +1 -0
- package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
- package/dist/types/runtime-mcp/config.d.ts +9 -0
- package/dist/types/runtime-mcp/manager.d.ts +26 -1
- package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
- package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
- package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
- package/dist/types/runtime-mcp/protocol.d.ts +278 -0
- package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
- package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
- package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
- package/dist/types/runtime-mcp/types.d.ts +102 -10
- package/dist/types/sdk/acp/adapter.d.ts +26 -5
- package/dist/types/sdk/broker/broker.d.ts +3 -55
- package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
- package/dist/types/sdk/broker/session-index.d.ts +14 -5
- package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
- package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
- package/dist/types/sdk/bus/config.d.ts +11 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
- package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
- package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
- package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
- package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
- package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
- package/dist/types/sdk/bus/index.d.ts +85 -99
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
- package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
- package/dist/types/sdk/bus/notification-service.d.ts +52 -0
- package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
- package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
- package/dist/types/sdk/bus/session-control.d.ts +25 -1
- package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
- package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
- package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
- package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
- package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
- package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
- package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
- package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
- package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
- package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
- package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
- package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
- package/dist/types/sdk/cli/rows.d.ts +2 -11
- package/dist/types/sdk/cli/session-cli.d.ts +15 -25
- package/dist/types/sdk/client/client.d.ts +97 -1
- package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
- package/dist/types/sdk/host/control/index.d.ts +1 -1
- package/dist/types/sdk/host/control/operations.d.ts +18 -5
- package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
- package/dist/types/sdk/host/host.d.ts +15 -1
- package/dist/types/sdk/host/query/handlers.d.ts +5 -0
- package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
- package/dist/types/sdk/host/session-runtime.d.ts +127 -7
- package/dist/types/sdk/host/types.d.ts +1 -1
- package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
- package/dist/types/sdk/index.d.ts +2 -1
- package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
- package/dist/types/sdk/lifecycle/client.d.ts +59 -0
- package/dist/types/sdk/lifecycle/index.d.ts +3 -0
- package/dist/types/sdk/lifecycle/service.d.ts +232 -0
- package/dist/types/sdk/mcp/server.d.ts +9 -6
- package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
- package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
- package/dist/types/sdk/prompt-status.d.ts +10 -3
- package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
- package/dist/types/sdk/receipt-state.d.ts +17 -0
- package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
- package/dist/types/sdk/router/index.d.ts +1 -0
- package/dist/types/sdk/router/session-router.d.ts +152 -0
- package/dist/types/sdk/session-list.d.ts +22 -0
- package/dist/types/sdk/session-reconnect.d.ts +43 -1
- package/dist/types/sdk/session.d.ts +34 -1
- package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
- package/dist/types/session/account-inventory.d.ts +86 -0
- package/dist/types/session/agent-session.d.ts +145 -6
- package/dist/types/session/agent-storage.d.ts +10 -0
- package/dist/types/session/coordinator-tool-label.d.ts +28 -0
- package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
- package/dist/types/session/messages.d.ts +1 -1
- package/dist/types/session/secure-token-file.d.ts +3 -0
- package/dist/types/session/session-manager.d.ts +40 -1
- package/dist/types/session/startup-auth-config.d.ts +44 -0
- package/dist/types/session/terminal-abort.d.ts +378 -0
- package/dist/types/session/yield-queue.d.ts +7 -0
- package/dist/types/session-import/claude.d.ts +26 -0
- package/dist/types/session-import/codex.d.ts +88 -0
- package/dist/types/session-import/command.d.ts +35 -0
- package/dist/types/session-import/detect.d.ts +22 -0
- package/dist/types/session-import/index.d.ts +7 -0
- package/dist/types/session-import/provider-codex.d.ts +22 -0
- package/dist/types/session-import/provider-service.d.ts +38 -0
- package/dist/types/session-import/redact.d.ts +23 -0
- package/dist/types/session-import/service.d.ts +47 -0
- package/dist/types/session-import/types.d.ts +120 -0
- package/dist/types/setup/paseo/check.d.ts +16 -0
- package/dist/types/setup/paseo/install-saga.d.ts +115 -0
- package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
- package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
- package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
- package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
- package/dist/types/setup/paseo/provider-config.d.ts +35 -0
- package/dist/types/setup/paseo/remove.d.ts +14 -0
- package/dist/types/setup/paseo/result-types.d.ts +59 -0
- package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
- package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
- package/dist/types/skill-state/active-state.d.ts +5 -1
- package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
- package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
- package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
- package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
- package/dist/types/slash-commands/types.d.ts +7 -1
- package/dist/types/task/executor.d.ts +10 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/tools/ask-answer-registry.d.ts +6 -3
- package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
- package/dist/types/tools/bash.d.ts +2 -6
- package/dist/types/tools/browser/attach.d.ts +11 -0
- package/dist/types/tools/browser/launch.d.ts +20 -0
- package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
- package/dist/types/tools/browser/render.d.ts +1 -0
- package/dist/types/tools/browser.d.ts +3 -1
- package/dist/types/tools/image-gen.d.ts +9 -2
- package/dist/types/tools/index.d.ts +8 -0
- package/dist/types/tools/monitor.d.ts +1 -1
- package/dist/types/tools/skill-discovery.d.ts +8 -1
- package/dist/types/tools/subagent.d.ts +2 -0
- package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
- package/dist/types/utils/herdr-pane.d.ts +76 -0
- package/package.json +19 -9
- package/scripts/build-binary.ts +2 -1
- package/scripts/build-sdk-package-smoke.ts +2 -13
- package/scripts/capture-sticky-viewport-showcase.ts +0 -1
- package/scripts/compile-args.ts +2 -0
- package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
- package/scripts/generate-sdk-operation-inventory.ts +28 -0
- package/scripts/generate-telegram-baseline-manifest.ts +1 -0
- package/scripts/generate-tool-catalog.ts +6 -4
- package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
- package/src/async/job-manager.ts +352 -17
- package/src/async/support.ts +25 -0
- package/src/autoresearch/dashboard.ts +28 -13
- package/src/capability/index.ts +3 -1
- package/src/capability/mcp.ts +6 -0
- package/src/capability/types.ts +6 -0
- package/src/cli/accounts-cli.ts +395 -0
- package/src/cli/args.ts +23 -0
- package/src/cli/auth-broker-cli.ts +136 -66
- package/src/cli/auth-gateway-cli.ts +94 -70
- package/src/cli/config-cli.ts +27 -2
- package/src/cli/crash-cli.ts +78 -0
- package/src/cli/customize-doctor.ts +1605 -0
- package/src/cli/daemon-cli.ts +12 -3
- package/src/cli/fast-help.ts +1 -0
- package/src/cli/mcp-cli.ts +128 -60
- package/src/cli/notify-cli.ts +8 -14
- package/src/cli/root-flags.ts +8 -0
- package/src/cli/setup-cli.ts +145 -0
- package/src/cli/skills-cli.ts +38 -2
- package/src/cli/update-cli.ts +167 -12
- package/src/cli.ts +4 -0
- package/src/commands/accounts.ts +71 -0
- package/src/commands/crash.ts +35 -0
- package/src/commands/customize.ts +84 -0
- package/src/commands/daemon.ts +2 -2
- package/src/commands/deep-interview.ts +2 -0
- package/src/commands/launch.ts +1 -0
- package/src/commands/mcp.ts +12 -7
- package/src/commands/ralplan.ts +2 -0
- package/src/commands/sdk.ts +65 -32
- package/src/commands/setup.ts +5 -0
- package/src/commands/skills.ts +14 -4
- package/src/commands/ultragoal.ts +10 -1
- package/src/commands/update.ts +26 -15
- package/src/config/atomic-yaml-patch-worker.ts +57 -0
- package/src/config/atomic-yaml-patch.ts +769 -29
- package/src/config/config-schema-version.ts +10 -0
- package/src/config/file-lock.ts +70 -1
- package/src/config/mcp-schema.json +52 -14
- package/src/config/model-profile-activation.ts +20 -1
- package/src/config/model-profiles.ts +29 -19
- package/src/config/model-registry.ts +132 -21
- package/src/config/models-config-schema.ts +1 -1
- package/src/config/settings-schema.ts +76 -6
- package/src/config/settings.ts +4038 -199
- package/src/config/skill-settings-defaults.ts +41 -3
- package/src/config/task-delegation.ts +87 -0
- package/src/config/update-channel.ts +23 -0
- package/src/coordinator-mcp/server.ts +377 -308
- package/src/crash/index-store.ts +723 -0
- package/src/crash/nudge.ts +89 -0
- package/src/crash/record-loader.ts +149 -0
- package/src/crash/report.ts +551 -0
- package/src/crash/sanitize.ts +129 -0
- package/src/cursor.ts +36 -10
- package/src/customization/import.ts +946 -0
- package/src/customization/index.ts +4 -0
- package/src/customization/inventory.ts +335 -0
- package/src/customization/mutations.ts +141 -0
- package/src/customization/types.ts +223 -0
- package/src/daemon/control-types.ts +8 -1
- package/src/daemon/operator-contract.ts +6 -6
- package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
- package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
- package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
- package/src/discovery/claude-hooks.ts +38 -0
- package/src/discovery/claude.ts +142 -209
- package/src/discovery/codex-hooks.ts +38 -0
- package/src/discovery/codex.ts +132 -198
- package/src/discovery/helpers.ts +8 -1
- package/src/discovery/index.ts +2 -0
- package/src/discovery/mcp-compat.ts +234 -0
- package/src/discovery/mcp-json.ts +6 -0
- package/src/edit/renderer.ts +40 -0
- package/src/edit/streaming.ts +4 -2
- package/src/exec/bash-executor.ts +24 -20
- package/src/export/html/index.ts +51 -2
- package/src/extensibility/extensions/loader.ts +9 -1
- package/src/extensibility/extensions/runner.ts +17 -4
- package/src/extensibility/extensions/types.ts +31 -6
- package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
- package/src/extensibility/gjc-plugins/installer.ts +9 -5
- package/src/extensibility/gjc-plugins/observability.ts +8 -2
- package/src/extensibility/gjc-plugins/registry.ts +13 -2
- package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
- package/src/extensibility/gjc-plugins/schema.ts +222 -39
- package/src/extensibility/hooks/loader.ts +154 -10
- package/src/extensibility/runtime-skill-discovery.ts +257 -60
- package/src/extensibility/skill-management.ts +368 -0
- package/src/extensibility/skills.ts +52 -16
- package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
- package/src/gjc-runtime/launch-worktree.ts +56 -2
- package/src/gjc-runtime/linux-proc.ts +7 -1
- package/src/gjc-runtime/ralplan-runtime.ts +100 -164
- package/src/gjc-runtime/session-state-lock.ts +992 -0
- package/src/gjc-runtime/session-state-sidecar.ts +644 -142
- package/src/gjc-runtime/state-writer.ts +39 -14
- package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
- package/src/gjc-runtime/ultragoal-guard.ts +11 -4
- package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
- package/src/gjc-runtime/workflow-settings.ts +596 -0
- package/src/goals/tools/goal-tool.ts +6 -1
- package/src/hooks/events.ts +291 -0
- package/src/hooks/native-skill-hook.ts +4 -0
- package/src/hooks/normalize.ts +369 -0
- package/src/hooks/skill-state.ts +165 -46
- package/src/internal-urls/docs-index.generated.ts +40 -32
- package/src/main.ts +32 -5
- package/src/migrate/mcp-mapper.ts +25 -2
- package/src/modes/acp/abort-scope.ts +29 -0
- package/src/modes/acp/acp-agent.ts +423 -98
- package/src/modes/components/assistant-message.ts +6 -1
- package/src/modes/components/customization/customization-dashboard.ts +443 -0
- package/src/modes/components/customization/import-wizard.ts +372 -0
- package/src/modes/components/customization/index.ts +1 -0
- package/src/modes/components/gajae-pet-widget.ts +539 -213
- package/src/modes/components/irc-sidebar.ts +11 -0
- package/src/modes/components/iterm-pet-transport.ts +585 -0
- package/src/modes/components/oauth-selector.ts +277 -86
- package/src/modes/components/pet-capability.ts +39 -40
- package/src/modes/components/settings-selector.ts +9 -0
- package/src/modes/components/status-line/gh.ts +45 -1
- package/src/modes/components/status-line/segments.ts +16 -1
- package/src/modes/components/tool-status-header.ts +13 -3
- package/src/modes/controllers/command-controller.ts +20 -8
- package/src/modes/controllers/extension-ui-controller.ts +56 -257
- package/src/modes/controllers/input-controller.ts +10 -0
- package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
- package/src/modes/controllers/selector-controller.ts +177 -72
- package/src/modes/controllers/stt-controller.ts +3 -3
- package/src/modes/interactive-mode.ts +88 -16
- package/src/modes/print-mode.ts +35 -6
- package/src/modes/runtime-init.ts +21 -68
- package/src/modes/types.ts +1 -0
- package/src/modes/utils/injected-user-submission.ts +25 -0
- package/src/modes/utils/terminal-bell.ts +15 -1
- package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
- package/src/prompts/agent-fragments/restricted-bash.md +1 -1
- package/src/prompts/agents/critic.md +1 -1
- package/src/prompts/system/rlm-research.md +1 -1
- package/src/prompts/system/system-prompt.md +0 -2
- package/src/prompts/tools/bash.md +7 -1
- package/src/prompts/tools/browser.md +1 -1
- package/src/prompts/tools/cron.md +6 -6
- package/src/prompts/tools/read.md +0 -2
- package/src/prompts/tools/skill-discovery.md +4 -2
- package/src/runtime-mcp/client.ts +427 -23
- package/src/runtime-mcp/config.ts +37 -5
- package/src/runtime-mcp/manager-pool.test.ts +56 -0
- package/src/runtime-mcp/manager.ts +52 -2
- package/src/runtime-mcp/oauth-discovery.ts +13 -0
- package/src/runtime-mcp/oauth-flow.ts +46 -1
- package/src/runtime-mcp/pool-key.ts +5 -1
- package/src/runtime-mcp/pool.test.ts +9 -0
- package/src/runtime-mcp/protocol.test.ts +353 -0
- package/src/runtime-mcp/protocol.ts +624 -0
- package/src/runtime-mcp/scope-config.ts +78 -0
- package/src/runtime-mcp/tool-bridge.ts +44 -10
- package/src/runtime-mcp/transports/http.ts +84 -13
- package/src/runtime-mcp/types.ts +123 -12
- package/src/sdk/acp/adapter.ts +328 -97
- package/src/sdk/broker/broker.ts +160 -741
- package/src/sdk/broker/ensure.ts +9 -1
- package/src/sdk/broker/lifecycle.ts +510 -116
- package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
- package/src/sdk/broker/process-incarnation.ts +19 -0
- package/src/sdk/broker/session-index.ts +516 -117
- package/src/sdk/broker/startup-failure.ts +28 -5
- package/src/sdk/broker/transport.ts +1 -13
- package/src/sdk/bus/chat-daemon-cli.ts +4 -2
- package/src/sdk/bus/chat-daemon-control.ts +67 -6
- package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
- package/src/sdk/bus/config.ts +13 -0
- package/src/sdk/bus/conversation-store.ts +59 -171
- package/src/sdk/bus/daemon-paths.ts +20 -0
- package/src/sdk/bus/discord-conversation.ts +2 -0
- package/src/sdk/bus/discord-daemon.ts +524 -126
- package/src/sdk/bus/discord-live-provider.ts +206 -79
- package/src/sdk/bus/existing-thread-readiness.ts +4 -97
- package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
- package/src/sdk/bus/index.ts +2480 -456
- package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
- package/src/sdk/bus/lifecycle-commands.ts +2 -2
- package/src/sdk/bus/managed-daemon.ts +2 -145
- package/src/sdk/bus/notification-service.ts +196 -0
- package/src/sdk/bus/operator-runtime.ts +1 -1
- package/src/sdk/bus/prompt-reconciliation.ts +24 -15
- package/src/sdk/bus/reconciliation-store.ts +553 -24
- package/src/sdk/bus/session-control.ts +49 -3
- package/src/sdk/bus/slack-conversation.ts +4 -0
- package/src/sdk/bus/slack-daemon.ts +733 -134
- package/src/sdk/bus/slack-live-provider.ts +65 -15
- package/src/sdk/bus/slack-provider.ts +4 -0
- package/src/sdk/bus/slack-thread-binding.ts +9 -104
- package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
- package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
- package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
- package/src/sdk/bus/telegram-daemon-control.ts +3 -13
- package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
- package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
- package/src/sdk/bus/telegram-daemon.ts +2552 -2280
- package/src/sdk/bus/telegram-reference.ts +1 -226
- package/src/sdk/bus/telegram-setup.ts +2 -2
- package/src/sdk/bus/threaded-render.ts +1 -0
- package/src/sdk/bus/topic-registry.ts +279 -146
- package/src/sdk/cli/rows.ts +2 -35
- package/src/sdk/cli/session-cli.ts +776 -700
- package/src/sdk/client/client.ts +892 -1
- package/src/sdk/host/control/dispatch.ts +93 -58
- package/src/sdk/host/control/index.ts +1 -1
- package/src/sdk/host/control/operations.ts +18 -10
- package/src/sdk/host/control/runtime-gate.ts +40 -0
- package/src/sdk/host/host.ts +63 -12
- package/src/sdk/host/query/handlers.ts +66 -7
- package/src/sdk/host/reverse-leases.ts +2 -2
- package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
- package/src/sdk/host/session-runtime.test.ts +2787 -34
- package/src/sdk/host/session-runtime.ts +1489 -101
- package/src/sdk/host/surface-policy.ts +12 -8
- package/src/sdk/host/types.ts +1 -1
- package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
- package/src/sdk/host/websocket-transport.ts +85 -50
- package/src/sdk/index.ts +2 -1
- package/src/sdk/lifecycle/broker-client.ts +53 -0
- package/src/sdk/lifecycle/client.ts +234 -0
- package/src/sdk/lifecycle/index.ts +3 -0
- package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
- package/src/sdk/lifecycle/service.ts +720 -0
- package/src/sdk/mcp/server.ts +226 -188
- package/src/sdk/prompt-deadline-lease.ts +55 -0
- package/src/sdk/prompt-deadline-manager.ts +148 -0
- package/src/sdk/prompt-status.ts +11 -3
- package/src/sdk/protocol/operation-inventory.generated.json +272 -129
- package/src/sdk/protocol/operation-registry.ts +71 -8
- package/src/sdk/receipt-state.ts +43 -0
- package/src/sdk/reconciliation-extensions.ts +14 -0
- package/src/sdk/router/index.ts +1 -0
- package/src/sdk/router/session-router.ts +1658 -0
- package/src/sdk/session-list.ts +93 -0
- package/src/sdk/session-reconnect.ts +45 -1
- package/src/sdk/session.ts +716 -120
- package/src/sdk/transport/serve-cli.ts +18 -34
- package/src/session/account-inventory.ts +603 -0
- package/src/session/agent-session.ts +2857 -582
- package/src/session/agent-storage.ts +35 -0
- package/src/session/blob-store.ts +32 -1
- package/src/session/coordinator-tool-label.ts +40 -0
- package/src/session/internal/managed-session-scope.ts +4 -0
- package/src/session/internal/managed-session-storage.ts +173 -12
- package/src/session/messages.ts +1 -1
- package/src/session/secure-token-file.ts +80 -0
- package/src/session/session-manager.ts +730 -58
- package/src/session/session-storage.ts +25 -16
- package/src/session/startup-auth-config.ts +297 -0
- package/src/session/terminal-abort.ts +1253 -0
- package/src/session/yield-queue.ts +57 -15
- package/src/session-import/claude.ts +334 -0
- package/src/session-import/codex.ts +1033 -0
- package/src/session-import/command.ts +77 -0
- package/src/session-import/detect.ts +133 -0
- package/src/session-import/index.ts +7 -0
- package/src/session-import/provider-codex.ts +327 -0
- package/src/session-import/provider-service.ts +457 -0
- package/src/session-import/redact.ts +128 -0
- package/src/session-import/service.ts +1264 -0
- package/src/session-import/types.ts +148 -0
- package/src/setup/paseo/check.ts +213 -0
- package/src/setup/paseo/install-saga.ts +293 -0
- package/src/setup/paseo/json-publisher.ts +263 -0
- package/src/setup/paseo/orchestration-preferences.ts +86 -0
- package/src/setup/paseo/paseo-ownership.ts +224 -0
- package/src/setup/paseo/paseo-setup.ts +253 -0
- package/src/setup/paseo/provider-config.ts +139 -0
- package/src/setup/paseo/remove.ts +183 -0
- package/src/setup/paseo/result-types.ts +79 -0
- package/src/setup/paseo/setup-deps.ts +175 -0
- package/src/setup/paseo/skills-bridge.ts +260 -0
- package/src/skill-state/active-state.ts +21 -11
- package/src/slash-commands/acp-builtins.ts +9 -1
- package/src/slash-commands/builtin-registry.ts +98 -16
- package/src/slash-commands/helpers/credential-switch.ts +143 -0
- package/src/slash-commands/helpers/mcp.ts +9 -3
- package/src/slash-commands/helpers/usage-report.ts +61 -56
- package/src/slash-commands/types.ts +7 -2
- package/src/task/executor.ts +30 -11
- package/src/task/index.ts +66 -7
- package/src/task/render.ts +23 -9
- package/src/tools/ask-answer-registry.ts +23 -7
- package/src/tools/ask.ts +8 -4
- package/src/tools/bash-sleep-advisory.ts +115 -0
- package/src/tools/bash.ts +98 -18
- package/src/tools/browser/attach.ts +71 -3
- package/src/tools/browser/launch.ts +86 -13
- package/src/tools/browser/profile-discovery.ts +57 -7
- package/src/tools/browser/render.ts +8 -1
- package/src/tools/browser.ts +130 -21
- package/src/tools/computer.enforcement.test.ts +1 -1
- package/src/tools/computer.ts +3 -2
- package/src/tools/cron.ts +12 -1
- package/src/tools/image-gen.ts +27 -16
- package/src/tools/index.ts +8 -0
- package/src/tools/job.ts +33 -6
- package/src/tools/monitor.ts +41 -2
- package/src/tools/skill-discovery.ts +21 -29
- package/src/tools/subagent.ts +142 -24
- package/src/tools/tool-catalog.generated.ts +6 -6
- package/src/tools/ultragoal-ask-guard.ts +10 -3
- package/src/utils/herdr-pane.ts +345 -0
- package/src/utils/title-generator.ts +2 -0
- package/src/web/scrapers/index.ts +6 -4
- package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
- package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
- package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
- package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
- package/dist/types/runtime/lazy-service.test.d.ts +0 -1
- package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
- package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
- package/dist/types/runtime-mcp/config.test.d.ts +0 -1
- package/dist/types/runtime-mcp/http.test.d.ts +0 -1
- package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
- package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
- package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
- package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
- package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
- package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
- package/dist/types/sdk/elevation/audit.d.ts +0 -93
- package/dist/types/sdk/elevation/capability.d.ts +0 -3
- package/dist/types/sdk/elevation/digest.d.ts +0 -72
- package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
- package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
- package/dist/types/sdk/elevation/owner.d.ts +0 -48
- package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
- package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
- package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
- package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
- package/dist/types/session/auth-broker-config.d.ts +0 -13
- package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
- package/dist/types/skills/skills.test.d.ts +0 -1
- package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
- package/dist/types/task/token-log.test.d.ts +0 -1
- package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
- package/dist/types/tools/descriptors.test.d.ts +0 -1
- package/scripts/g005-daemon-smoke.ts +0 -180
- package/scripts/g011-daemon-path-smoke.ts +0 -153
- package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
- package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
- package/src/sdk/bus/telegram-cli.ts +0 -212
- package/src/sdk/elevation/allowlist.ts +0 -54
- package/src/sdk/elevation/audit.ts +0 -208
- package/src/sdk/elevation/capability.ts +0 -41
- package/src/sdk/elevation/digest.ts +0 -129
- package/src/sdk/elevation/dispatch-receipt.ts +0 -184
- package/src/sdk/elevation/grant-ledger.ts +0 -1142
- package/src/sdk/elevation/owner.ts +0 -109
- package/src/session/auth-broker-config.ts +0 -109
- /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
- /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
- /package/dist/types/sdk/{bus/recent-activity.d.ts → lifecycle/recent-sessions.d.ts} +0 -0
|
@@ -1,14 +1,33 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* MCP Client.
|
|
3
3
|
*
|
|
4
|
-
* Handles connection
|
|
4
|
+
* Handles connection negotiation (modern 2026-07-28 stateless vs legacy
|
|
5
|
+
* sessionful), tool listing, and tool calling. Era detection and the downgrade
|
|
6
|
+
* policy live in ./protocol.ts; legacy behavior is unchanged.
|
|
5
7
|
*/
|
|
6
8
|
import * as path from "node:path";
|
|
7
9
|
import * as url from "node:url";
|
|
8
10
|
import { getProjectDir, logger, withTimeout } from "@gajae-code/utils";
|
|
9
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
buildXMcpParamHeaders,
|
|
13
|
+
classifyMcpProbeFailure,
|
|
14
|
+
collectXMcpHeaderBindings,
|
|
15
|
+
extractMcpInputRequired,
|
|
16
|
+
isModernProtocolVersion,
|
|
17
|
+
JSONRPC_ERROR_METHOD_NOT_FOUND,
|
|
18
|
+
legacyEraObservation,
|
|
19
|
+
MCP_ERROR_UNSUPPORTED_PROTOCOL_VERSION,
|
|
20
|
+
MCP_PROTOCOL_VERSION_2026_07_28,
|
|
21
|
+
type MCPDowngradeReason,
|
|
22
|
+
type MCPModernClientContext,
|
|
23
|
+
modernEraObservation,
|
|
24
|
+
normalizeMcpCacheHints,
|
|
25
|
+
resolveMCPProtocolPreference,
|
|
26
|
+
} from "./protocol";
|
|
27
|
+
import { createHttpTransport, HttpTransport } from "./transports/http";
|
|
10
28
|
import { createStdioTransport } from "./transports/stdio";
|
|
11
29
|
import type {
|
|
30
|
+
MCPDiscoverResultLite,
|
|
12
31
|
MCPGetPromptParams,
|
|
13
32
|
MCPGetPromptResult,
|
|
14
33
|
MCPHttpServerConfig,
|
|
@@ -32,7 +51,7 @@ import type {
|
|
|
32
51
|
MCPToolsListResult,
|
|
33
52
|
MCPTransport,
|
|
34
53
|
} from "./types";
|
|
35
|
-
import { MCPExpectedFailure } from "./types";
|
|
54
|
+
import { MCPExpectedFailure, MCPHttpRequestError, MCPJsonRpcError } from "./types";
|
|
36
55
|
|
|
37
56
|
/** MCP protocol version we support */
|
|
38
57
|
const PROTOCOL_VERSION = "2025-03-26";
|
|
@@ -116,6 +135,7 @@ async function collectPaginated<T>(
|
|
|
116
135
|
itemKey: string,
|
|
117
136
|
items: T[],
|
|
118
137
|
decode?: (value: unknown) => unknown,
|
|
138
|
+
onPage?: (result: Record<string, unknown>) => void,
|
|
119
139
|
): Promise<void> {
|
|
120
140
|
const seenCursors = new Set<string>();
|
|
121
141
|
const failure = (detail: string) => new MCPExpectedFailure(new Error(`MCP ${method} pagination ${detail}`));
|
|
@@ -136,6 +156,7 @@ async function collectPaginated<T>(
|
|
|
136
156
|
if (itemCount > MAX_PAGINATION_ITEMS || (itemCount === MAX_PAGINATION_ITEMS && nextCursor))
|
|
137
157
|
throw failure("did not complete within the 10000-item budget");
|
|
138
158
|
items.push(...pageItems);
|
|
159
|
+
onPage?.(result as Record<string, unknown>);
|
|
139
160
|
if (!nextCursor) return;
|
|
140
161
|
if (page === MAX_PAGINATION_PAGES) throw failure("did not complete within the 100-page budget");
|
|
141
162
|
seenCursors.add(nextCursor);
|
|
@@ -224,6 +245,250 @@ async function initializeConnection(
|
|
|
224
245
|
return result;
|
|
225
246
|
}
|
|
226
247
|
|
|
248
|
+
/** Negotiation-local failure (distinguished from transport failures by type). */
|
|
249
|
+
class ModernNegotiationError extends Error {}
|
|
250
|
+
|
|
251
|
+
/** Build the per-request modern client context (2026-07-28). */
|
|
252
|
+
function buildModernClientContext(options?: { advertiseRoots?: boolean }): MCPModernClientContext {
|
|
253
|
+
const capabilities: Record<string, unknown> = {};
|
|
254
|
+
if (options?.advertiseRoots !== false) {
|
|
255
|
+
capabilities.roots = { listChanged: true };
|
|
256
|
+
// Form-mode elicitation is bridged to GJC's structured ask surface (MRTR).
|
|
257
|
+
capabilities.elicitation = { form: {} };
|
|
258
|
+
}
|
|
259
|
+
return {
|
|
260
|
+
protocolVersion: MCP_PROTOCOL_VERSION_2026_07_28,
|
|
261
|
+
clientInfo: CLIENT_INFO,
|
|
262
|
+
capabilities,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/** Decode a `server/discover` result, including `_meta` serverInfo and cache hints. */
|
|
267
|
+
function decodeDiscoverResult(value: unknown): MCPDiscoverResultLite {
|
|
268
|
+
if (
|
|
269
|
+
!isRecord(value) ||
|
|
270
|
+
!Array.isArray(value.supportedVersions) ||
|
|
271
|
+
!value.supportedVersions.every(entry => typeof entry === "string") ||
|
|
272
|
+
!isRecord(value.capabilities)
|
|
273
|
+
) {
|
|
274
|
+
throw new MCPExpectedFailure();
|
|
275
|
+
}
|
|
276
|
+
const meta = isRecord(value._meta) ? value._meta : undefined;
|
|
277
|
+
const serverInfoRaw = meta?.["io.modelcontextprotocol/serverInfo"];
|
|
278
|
+
const serverInfo =
|
|
279
|
+
isRecord(serverInfoRaw) && typeof serverInfoRaw.name === "string" && typeof serverInfoRaw.version === "string"
|
|
280
|
+
? { name: serverInfoRaw.name, version: serverInfoRaw.version }
|
|
281
|
+
: undefined;
|
|
282
|
+
const hints = normalizeMcpCacheHints(value);
|
|
283
|
+
return {
|
|
284
|
+
supportedVersions: value.supportedVersions as string[],
|
|
285
|
+
capabilities: value.capabilities as MCPServerCapabilities,
|
|
286
|
+
...(typeof value.instructions === "string" ? { instructions: value.instructions } : {}),
|
|
287
|
+
...(hints?.ttlMs !== undefined ? { ttlMs: hints.ttlMs } : {}),
|
|
288
|
+
...(hints?.cacheScope !== undefined ? { cacheScope: hints.cacheScope } : {}),
|
|
289
|
+
...(serverInfo ? { serverInfo } : {}),
|
|
290
|
+
};
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/** Unwrap the original transport failure preserved as MCPExpectedFailure.cause. */
|
|
294
|
+
function unwrapTransportFailure(error: unknown): unknown {
|
|
295
|
+
return error instanceof MCPExpectedFailure && error.cause !== undefined ? error.cause : error;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
type ModernNegotiation =
|
|
299
|
+
| { outcome: "modern"; discovery: MCPDiscoverResultLite | null; discoverState: "yes" | "no"; versionRetry: boolean }
|
|
300
|
+
| { outcome: "legacy-fallback"; reason: MCPDowngradeReason };
|
|
301
|
+
|
|
302
|
+
/**
|
|
303
|
+
* Negotiate the modern era with an HTTP server via the optional `server/discover`
|
|
304
|
+
* probe and the specification's era-detection rules. Auth, issuer/audience,
|
|
305
|
+
* redirect/SSRF/DNS, malformed-response, and other security or protocol-integrity
|
|
306
|
+
* failures NEVER authorize a downgrade; only a 400/404/405 without a recognized
|
|
307
|
+
* modern error body, or an explicit version advertisement containing only
|
|
308
|
+
* legacy-era versions, may fall back — and only under `auto`.
|
|
309
|
+
*/
|
|
310
|
+
async function negotiateModernEra(
|
|
311
|
+
transport: HttpTransport,
|
|
312
|
+
preference: "auto" | "2026-07-28",
|
|
313
|
+
signal: AbortSignal,
|
|
314
|
+
): Promise<ModernNegotiation> {
|
|
315
|
+
const strict = preference === MCP_PROTOCOL_VERSION_2026_07_28;
|
|
316
|
+
const failStrict = (detail: string): never => {
|
|
317
|
+
throw new ModernNegotiationError(`strict 2026-07-28: ${detail}`);
|
|
318
|
+
};
|
|
319
|
+
let versionRetry = false;
|
|
320
|
+
for (;;) {
|
|
321
|
+
let discovery: MCPDiscoverResultLite;
|
|
322
|
+
try {
|
|
323
|
+
discovery = decodeDiscoverResult(await transport.request<unknown>("server/discover", {}, { signal }));
|
|
324
|
+
} catch (error) {
|
|
325
|
+
const cause = unwrapTransportFailure(error);
|
|
326
|
+
if (cause instanceof MCPHttpRequestError) {
|
|
327
|
+
const classification = classifyMcpProbeFailure(cause.status, cause.body);
|
|
328
|
+
switch (classification.class) {
|
|
329
|
+
case "auth-failure":
|
|
330
|
+
case "other-failure":
|
|
331
|
+
// Auth/security/protocol-integrity failures are never era signals.
|
|
332
|
+
throw error;
|
|
333
|
+
case "legacy-signal":
|
|
334
|
+
if (strict) failStrict("server rejected the modern probe without a recognized modern error");
|
|
335
|
+
return { outcome: "legacy-fallback", reason: "legacy-server-signal" };
|
|
336
|
+
case "modern-error": {
|
|
337
|
+
if (classification.modernErrorCode === MCP_ERROR_UNSUPPORTED_PROTOCOL_VERSION) {
|
|
338
|
+
const supported = classification.supportedVersions ?? [];
|
|
339
|
+
if (supported.includes(MCP_PROTOCOL_VERSION_2026_07_28)) {
|
|
340
|
+
// Retry the probe once with the mutually supported version.
|
|
341
|
+
if (versionRetry) {
|
|
342
|
+
throw new MCPExpectedFailure(new Error("MCP version negotiation did not converge"));
|
|
343
|
+
}
|
|
344
|
+
versionRetry = true;
|
|
345
|
+
continue;
|
|
346
|
+
}
|
|
347
|
+
if (supported.length > 0 && supported.every(v => !isModernProtocolVersion(v))) {
|
|
348
|
+
if (strict) failStrict(`server advertises only legacy-era versions (${supported.join(", ")})`);
|
|
349
|
+
return { outcome: "legacy-fallback", reason: "server-advertised-legacy-only" };
|
|
350
|
+
}
|
|
351
|
+
throw new MCPExpectedFailure(
|
|
352
|
+
new Error(
|
|
353
|
+
`MCP server does not support protocol ${MCP_PROTOCOL_VERSION_2026_07_28} (supported: ${supported.join(", ") || "unknown"})`,
|
|
354
|
+
),
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
if (classification.modernErrorCode === JSONRPC_ERROR_METHOD_NOT_FOUND) {
|
|
358
|
+
// Modern server without the optional server/discover: proceed with
|
|
359
|
+
// direct v2 calls; capabilities are learned lazily.
|
|
360
|
+
return { outcome: "modern", discovery: null, discoverState: "no", versionRetry };
|
|
361
|
+
}
|
|
362
|
+
// HeaderMismatch / MissingRequiredClientCapability: a modern server
|
|
363
|
+
// rejecting our request context — a defect or policy failure, never
|
|
364
|
+
// a downgrade signal.
|
|
365
|
+
throw new MCPExpectedFailure(
|
|
366
|
+
new Error(
|
|
367
|
+
`MCP modern server rejected the request context (code ${classification.modernErrorCode})`,
|
|
368
|
+
),
|
|
369
|
+
);
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
if (cause instanceof MCPJsonRpcError && cause.code === JSONRPC_ERROR_METHOD_NOT_FOUND) {
|
|
374
|
+
// Ambiguous: legacy servers also answer -32601 to unknown methods. Strict
|
|
375
|
+
// mode may assume the modern era; auto treats it as a legacy signal.
|
|
376
|
+
if (strict) return { outcome: "modern", discovery: null, discoverState: "no", versionRetry };
|
|
377
|
+
return { outcome: "legacy-fallback", reason: "legacy-server-signal" };
|
|
378
|
+
}
|
|
379
|
+
// Network, timeout, abort, or malformed 2xx payloads: never downgrade.
|
|
380
|
+
throw error;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
if (discovery.supportedVersions.includes(MCP_PROTOCOL_VERSION_2026_07_28)) {
|
|
384
|
+
return { outcome: "modern", discovery, discoverState: "yes", versionRetry };
|
|
385
|
+
}
|
|
386
|
+
if (discovery.supportedVersions.some(isModernProtocolVersion)) {
|
|
387
|
+
throw new MCPExpectedFailure(
|
|
388
|
+
new Error(
|
|
389
|
+
`MCP server supports only newer modern protocol versions (${discovery.supportedVersions.join(", ")}); this client implements ${MCP_PROTOCOL_VERSION_2026_07_28}`,
|
|
390
|
+
),
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
if (discovery.supportedVersions.length > 0) {
|
|
394
|
+
if (strict)
|
|
395
|
+
failStrict(`server advertises only legacy-era versions (${discovery.supportedVersions.join(", ")})`);
|
|
396
|
+
return { outcome: "legacy-fallback", reason: "server-advertised-legacy-only" };
|
|
397
|
+
}
|
|
398
|
+
throw new MCPExpectedFailure(new Error("MCP server/discover returned no supported versions"));
|
|
399
|
+
}
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
/** Maximum MRTR retries per original request (repeated input_required rounds). */
|
|
403
|
+
const MAX_MRTR_RETRIES = 3;
|
|
404
|
+
|
|
405
|
+
/** True when the failure is a modern "method not found" (unknown/unsupported method). */
|
|
406
|
+
function isModernMethodNotFound(error: unknown): boolean {
|
|
407
|
+
const cause = unwrapTransportFailure(error);
|
|
408
|
+
if (cause instanceof MCPJsonRpcError && cause.code === JSONRPC_ERROR_METHOD_NOT_FOUND) return true;
|
|
409
|
+
if (cause instanceof MCPHttpRequestError && cause.status === 404) return true;
|
|
410
|
+
return false;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Issue a modern-era request, resolving `input_required` (MRTR) interim results.
|
|
415
|
+
* The original request is retried with `inputResponses` and a verbatim
|
|
416
|
+
* `requestState` echo under a fresh JSON-RPC id, at most MAX_MRTR_RETRIES times;
|
|
417
|
+
* the retry is fenced to the originating exchange by a stable correlation id.
|
|
418
|
+
*/
|
|
419
|
+
async function requestWithInputHandling<T>(
|
|
420
|
+
connection: MCPServerConnection,
|
|
421
|
+
method: string,
|
|
422
|
+
params: Record<string, unknown>,
|
|
423
|
+
options?: MCPRequestOptions,
|
|
424
|
+
): Promise<T> {
|
|
425
|
+
const stripResultType = (value: unknown): T => {
|
|
426
|
+
// A present resultType of "complete" is the modern default; drop the marker
|
|
427
|
+
// so legacy-shaped consumers see the legacy result shape.
|
|
428
|
+
if (isRecord(value) && typeof value.resultType === "string") {
|
|
429
|
+
const { resultType: _discarded, ...rest } = value;
|
|
430
|
+
return rest as T;
|
|
431
|
+
}
|
|
432
|
+
return value as T;
|
|
433
|
+
};
|
|
434
|
+
|
|
435
|
+
const initial = await connection.transport.request<unknown>(method, params, options);
|
|
436
|
+
if (connection.protocol.era !== "modern") return initial as T;
|
|
437
|
+
let inputRequired = extractMcpInputRequired(initial);
|
|
438
|
+
if (!inputRequired) return stripResultType(initial);
|
|
439
|
+
|
|
440
|
+
const handler = options?.inputHandler;
|
|
441
|
+
if (!handler) {
|
|
442
|
+
throw new MCPExpectedFailure(
|
|
443
|
+
new Error(
|
|
444
|
+
`MCP server "${connection.name}" requested additional input (input_required) for ${method}, but no interactive input handler is available`,
|
|
445
|
+
),
|
|
446
|
+
);
|
|
447
|
+
}
|
|
448
|
+
const correlationId = crypto.randomUUID();
|
|
449
|
+
|
|
450
|
+
for (let attempt = 0; attempt < MAX_MRTR_RETRIES; attempt++) {
|
|
451
|
+
const inputResponses: Record<string, unknown> = {};
|
|
452
|
+
for (const [key, request] of Object.entries(inputRequired.inputRequests)) {
|
|
453
|
+
if (options?.signal?.aborted) {
|
|
454
|
+
throw options.signal.reason instanceof Error ? options.signal.reason : new Error("Aborted");
|
|
455
|
+
}
|
|
456
|
+
if (request.method === "roots/list") {
|
|
457
|
+
// roots are answered from local state without user interaction.
|
|
458
|
+
inputResponses[key] = await defaultRequestHandler("roots/list", undefined);
|
|
459
|
+
continue;
|
|
460
|
+
}
|
|
461
|
+
const outcome = await handler(key, request, {
|
|
462
|
+
serverName: connection.name,
|
|
463
|
+
originMethod: method,
|
|
464
|
+
correlationId,
|
|
465
|
+
...(options?.signal ? { signal: options.signal } : {}),
|
|
466
|
+
});
|
|
467
|
+
if (outcome.kind === "failed") {
|
|
468
|
+
throw new MCPExpectedFailure(
|
|
469
|
+
new Error(
|
|
470
|
+
`MCP input request "${key}" for ${method} ${outcome.reason}${outcome.message ? `: ${outcome.message}` : ""}`,
|
|
471
|
+
),
|
|
472
|
+
);
|
|
473
|
+
}
|
|
474
|
+
inputResponses[key] = outcome.result;
|
|
475
|
+
}
|
|
476
|
+
// The retry is a NEW request (fresh JSON-RPC id assigned by the transport)
|
|
477
|
+
// carrying the original params plus the gathered input; inputResponses and
|
|
478
|
+
// requestState are fenced to this exchange and never reused elsewhere.
|
|
479
|
+
const retryParams: Record<string, unknown> = { ...params, inputResponses };
|
|
480
|
+
if (inputRequired.requestState !== undefined) {
|
|
481
|
+
retryParams.requestState = inputRequired.requestState;
|
|
482
|
+
}
|
|
483
|
+
const retryResult = await connection.transport.request<unknown>(method, retryParams, options);
|
|
484
|
+
inputRequired = extractMcpInputRequired(retryResult);
|
|
485
|
+
if (!inputRequired) return stripResultType(retryResult);
|
|
486
|
+
}
|
|
487
|
+
throw new MCPExpectedFailure(
|
|
488
|
+
new Error(`MCP server "${connection.name}" repeatedly requested additional input for ${method}`),
|
|
489
|
+
);
|
|
490
|
+
}
|
|
491
|
+
|
|
227
492
|
/**
|
|
228
493
|
* Connect to an MCP server.
|
|
229
494
|
* Has a 30 second timeout to prevent blocking startup.
|
|
@@ -244,6 +509,8 @@ export async function connectToServer(
|
|
|
244
509
|
const connectAbort = new AbortController();
|
|
245
510
|
const connectSignal = options?.signal ? AbortSignal.any([options.signal, connectAbort.signal]) : connectAbort.signal;
|
|
246
511
|
|
|
512
|
+
const preference = resolveMCPProtocolPreference(config.protocol);
|
|
513
|
+
|
|
247
514
|
const connect = async (): Promise<MCPServerConnection> => {
|
|
248
515
|
transport = await createTransport(config);
|
|
249
516
|
if (options?.onNotification) {
|
|
@@ -252,10 +519,15 @@ export async function connectToServer(
|
|
|
252
519
|
|
|
253
520
|
// Always install a handler for standard MCP server-to-client requests.
|
|
254
521
|
// Callers that do not advertise roots can reject roots/list via onRequest.
|
|
522
|
+
// (Modern-era transports never receive server-initiated requests; MRTR
|
|
523
|
+
// input requests arrive as input_required results instead.)
|
|
255
524
|
transport.onRequest = options?.onRequest ?? defaultRequestHandler;
|
|
256
525
|
|
|
257
|
-
|
|
258
|
-
|
|
526
|
+
const connectLegacy = async (
|
|
527
|
+
negotiationState: "legacy-fallback" | "legacy-forced",
|
|
528
|
+
reason: MCPDowngradeReason,
|
|
529
|
+
): Promise<MCPServerConnection> => {
|
|
530
|
+
const initResult = await initializeConnection(transport!, {
|
|
259
531
|
signal: connectSignal,
|
|
260
532
|
advertiseRoots: options?.advertiseRoots,
|
|
261
533
|
async onInitialized() {
|
|
@@ -266,14 +538,73 @@ export async function connectToServer(
|
|
|
266
538
|
}
|
|
267
539
|
},
|
|
268
540
|
});
|
|
269
|
-
|
|
270
541
|
return {
|
|
271
542
|
name,
|
|
272
543
|
config,
|
|
273
|
-
transport
|
|
544
|
+
transport: transport!,
|
|
274
545
|
serverInfo: initResult.serverInfo,
|
|
275
546
|
capabilities: initResult.capabilities,
|
|
276
547
|
instructions: initResult.instructions,
|
|
548
|
+
protocol: legacyEraObservation({
|
|
549
|
+
preference,
|
|
550
|
+
effectiveVersion: initResult.protocolVersion,
|
|
551
|
+
negotiation: negotiationState,
|
|
552
|
+
downgradeReason: reason,
|
|
553
|
+
serverInfo: initResult.serverInfo,
|
|
554
|
+
capabilities: {
|
|
555
|
+
tools: initResult.capabilities.tools !== undefined,
|
|
556
|
+
resources: initResult.capabilities.resources !== undefined,
|
|
557
|
+
prompts: initResult.capabilities.prompts !== undefined,
|
|
558
|
+
},
|
|
559
|
+
}),
|
|
560
|
+
};
|
|
561
|
+
};
|
|
562
|
+
|
|
563
|
+
try {
|
|
564
|
+
// stdio has no per-request HTTP era signals; it stays on the legacy handshake.
|
|
565
|
+
if ((config.type ?? "stdio") === "stdio") {
|
|
566
|
+
return await connectLegacy("legacy-forced", "stdio-transport");
|
|
567
|
+
}
|
|
568
|
+
if (preference === "legacy") {
|
|
569
|
+
return await connectLegacy("legacy-forced", "preference-legacy");
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
// auto / strict 2026-07-28: negotiate the modern era first.
|
|
573
|
+
if (!(transport instanceof HttpTransport)) {
|
|
574
|
+
throw new MCPExpectedFailure(new Error(`MCP server "${name}" did not produce an HTTP transport`));
|
|
575
|
+
}
|
|
576
|
+
transport.setProtocolMode("modern", buildModernClientContext(options));
|
|
577
|
+
const negotiation = await negotiateModernEra(transport, preference, connectSignal);
|
|
578
|
+
if (negotiation.outcome === "legacy-fallback") {
|
|
579
|
+
transport.setProtocolMode("legacy");
|
|
580
|
+
return await connectLegacy("legacy-fallback", negotiation.reason);
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
const discovery = negotiation.discovery;
|
|
584
|
+
const serverInfo = discovery?.serverInfo ?? { name, version: "unknown" };
|
|
585
|
+
const capabilities = discovery?.capabilities ?? {};
|
|
586
|
+
return {
|
|
587
|
+
name,
|
|
588
|
+
config,
|
|
589
|
+
transport,
|
|
590
|
+
serverInfo,
|
|
591
|
+
capabilities,
|
|
592
|
+
instructions: discovery?.instructions,
|
|
593
|
+
protocol: modernEraObservation({
|
|
594
|
+
preference,
|
|
595
|
+
effectiveVersion: MCP_PROTOCOL_VERSION_2026_07_28,
|
|
596
|
+
negotiation: negotiation.versionRetry ? "modern-version-retry" : "modern",
|
|
597
|
+
supportedVersions: discovery?.supportedVersions,
|
|
598
|
+
serverInfo: discovery?.serverInfo ?? null,
|
|
599
|
+
capabilities: discovery
|
|
600
|
+
? {
|
|
601
|
+
tools: discovery.capabilities.tools !== undefined,
|
|
602
|
+
resources: discovery.capabilities.resources !== undefined,
|
|
603
|
+
prompts: discovery.capabilities.prompts !== undefined,
|
|
604
|
+
}
|
|
605
|
+
: undefined,
|
|
606
|
+
discover: negotiation.discoverState,
|
|
607
|
+
}),
|
|
277
608
|
};
|
|
278
609
|
} catch (error) {
|
|
279
610
|
try {
|
|
@@ -318,23 +649,61 @@ export async function listTools(
|
|
|
318
649
|
connection: MCPServerConnection,
|
|
319
650
|
options?: { signal?: AbortSignal },
|
|
320
651
|
): Promise<MCPToolDefinition[]> {
|
|
321
|
-
|
|
322
|
-
|
|
652
|
+
const modern = connection.protocol.era === "modern";
|
|
653
|
+
// Legacy gating uses the negotiated capabilities; modern servers without
|
|
654
|
+
// server/discover learn capability lazily (method-not-found means no tools).
|
|
655
|
+
if (!modern && !connection.capabilities.tools) {
|
|
323
656
|
return [];
|
|
324
657
|
}
|
|
325
658
|
|
|
326
|
-
// Return cached tools
|
|
659
|
+
// Return cached tools while fresh: server ttlMs hints bound freshness when present.
|
|
327
660
|
if (connection.tools) {
|
|
328
|
-
|
|
661
|
+
if (connection.toolsFreshUntil !== undefined && Date.now() >= connection.toolsFreshUntil) {
|
|
662
|
+
connection.tools = undefined;
|
|
663
|
+
connection.toolsFreshUntil = undefined;
|
|
664
|
+
connection.toolsCacheScope = undefined;
|
|
665
|
+
} else {
|
|
666
|
+
return connection.tools;
|
|
667
|
+
}
|
|
329
668
|
}
|
|
330
669
|
|
|
670
|
+
let freshUntil: number | undefined;
|
|
671
|
+
let cacheScope: "public" | "private" | undefined;
|
|
331
672
|
const allTools: MCPToolDefinition[] = [];
|
|
332
|
-
|
|
673
|
+
try {
|
|
674
|
+
await collectPaginated(connection, options, "tools/list", "tools", allTools, decodeToolsListResult, page => {
|
|
675
|
+
const hints = normalizeMcpCacheHints(page);
|
|
676
|
+
if (hints?.ttlMs !== undefined) {
|
|
677
|
+
const deadline = Date.now() + hints.ttlMs;
|
|
678
|
+
freshUntil = freshUntil === undefined ? deadline : Math.min(freshUntil, deadline);
|
|
679
|
+
}
|
|
680
|
+
if (hints?.cacheScope !== undefined) cacheScope = hints.cacheScope;
|
|
681
|
+
});
|
|
682
|
+
} catch (error) {
|
|
683
|
+
if (modern && isModernMethodNotFound(error)) return [];
|
|
684
|
+
throw error;
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
// Modern era: HTTP clients MUST exclude tools with invalid x-mcp-header
|
|
688
|
+
// annotations rather than letting one malformed tool break the catalog.
|
|
689
|
+
const validTools = modern
|
|
690
|
+
? allTools.filter(tool => {
|
|
691
|
+
const { violations } = collectXMcpHeaderBindings(tool.inputSchema);
|
|
692
|
+
if (violations.length === 0) return true;
|
|
693
|
+
logger.warn("Excluding MCP tool with invalid x-mcp-header annotation", {
|
|
694
|
+
tool: tool.name,
|
|
695
|
+
reason: violations.join("; "),
|
|
696
|
+
});
|
|
697
|
+
return false;
|
|
698
|
+
})
|
|
699
|
+
: allTools;
|
|
333
700
|
|
|
334
701
|
// Cache tools
|
|
335
|
-
connection.tools =
|
|
702
|
+
connection.tools = validTools;
|
|
703
|
+
connection.toolsFreshUntil = freshUntil;
|
|
704
|
+
connection.toolsCacheScope = cacheScope;
|
|
336
705
|
|
|
337
|
-
return
|
|
706
|
+
return validTools;
|
|
338
707
|
}
|
|
339
708
|
|
|
340
709
|
/**
|
|
@@ -351,7 +720,22 @@ export async function callTool(
|
|
|
351
720
|
arguments: args,
|
|
352
721
|
};
|
|
353
722
|
|
|
354
|
-
|
|
723
|
+
// Modern era: mirror validated x-mcp-header bindings into Mcp-Param-* headers.
|
|
724
|
+
if (connection.protocol.era === "modern" && !options?.mcpParamHeaders) {
|
|
725
|
+
const tool = connection.tools?.find(candidate => candidate.name === toolName);
|
|
726
|
+
if (tool) {
|
|
727
|
+
const { bindings } = collectXMcpHeaderBindings(tool.inputSchema);
|
|
728
|
+
if (bindings.length > 0) {
|
|
729
|
+
const mcpParamHeaders = buildXMcpParamHeaders(bindings, args);
|
|
730
|
+
if (Object.keys(mcpParamHeaders).length > 0) {
|
|
731
|
+
options = { ...options, mcpParamHeaders };
|
|
732
|
+
}
|
|
733
|
+
}
|
|
734
|
+
}
|
|
735
|
+
}
|
|
736
|
+
|
|
737
|
+
return requestWithInputHandling<MCPToolCallResult>(
|
|
738
|
+
connection,
|
|
355
739
|
"tools/call",
|
|
356
740
|
params as unknown as Record<string, unknown>,
|
|
357
741
|
options,
|
|
@@ -379,7 +763,8 @@ export async function listResources(
|
|
|
379
763
|
connection: MCPServerConnection,
|
|
380
764
|
options?: { signal?: AbortSignal },
|
|
381
765
|
): Promise<MCPResource[]> {
|
|
382
|
-
|
|
766
|
+
const modern = connection.protocol.era === "modern";
|
|
767
|
+
if (!modern && !connection.capabilities.resources) {
|
|
383
768
|
return [];
|
|
384
769
|
}
|
|
385
770
|
|
|
@@ -388,7 +773,12 @@ export async function listResources(
|
|
|
388
773
|
}
|
|
389
774
|
|
|
390
775
|
const allResources: MCPResource[] = [];
|
|
391
|
-
|
|
776
|
+
try {
|
|
777
|
+
await collectPaginated(connection, options, "resources/list", "resources", allResources);
|
|
778
|
+
} catch (error) {
|
|
779
|
+
if (modern && isModernMethodNotFound(error)) return [];
|
|
780
|
+
throw error;
|
|
781
|
+
}
|
|
392
782
|
|
|
393
783
|
connection.resources = allResources;
|
|
394
784
|
return allResources;
|
|
@@ -401,7 +791,8 @@ export async function listResourceTemplates(
|
|
|
401
791
|
connection: MCPServerConnection,
|
|
402
792
|
options?: { signal?: AbortSignal },
|
|
403
793
|
): Promise<MCPResourceTemplate[]> {
|
|
404
|
-
|
|
794
|
+
const modern = connection.protocol.era === "modern";
|
|
795
|
+
if (!modern && !connection.capabilities.resources) {
|
|
405
796
|
return [];
|
|
406
797
|
}
|
|
407
798
|
|
|
@@ -410,7 +801,12 @@ export async function listResourceTemplates(
|
|
|
410
801
|
}
|
|
411
802
|
|
|
412
803
|
const allTemplates: MCPResourceTemplate[] = [];
|
|
413
|
-
|
|
804
|
+
try {
|
|
805
|
+
await collectPaginated(connection, options, "resources/templates/list", "resourceTemplates", allTemplates);
|
|
806
|
+
} catch (error) {
|
|
807
|
+
if (modern && isModernMethodNotFound(error)) return [];
|
|
808
|
+
throw error;
|
|
809
|
+
}
|
|
414
810
|
|
|
415
811
|
connection.resourceTemplates = allTemplates;
|
|
416
812
|
return allTemplates;
|
|
@@ -425,7 +821,8 @@ export async function readResource(
|
|
|
425
821
|
options?: MCPRequestOptions,
|
|
426
822
|
): Promise<MCPResourceReadResult> {
|
|
427
823
|
const params: MCPResourceReadParams = { uri };
|
|
428
|
-
return
|
|
824
|
+
return requestWithInputHandling<MCPResourceReadResult>(
|
|
825
|
+
connection,
|
|
429
826
|
"resources/read",
|
|
430
827
|
params as unknown as Record<string, unknown>,
|
|
431
828
|
options,
|
|
@@ -546,7 +943,8 @@ export async function listPrompts(
|
|
|
546
943
|
connection: MCPServerConnection,
|
|
547
944
|
options?: { signal?: AbortSignal },
|
|
548
945
|
): Promise<MCPPrompt[]> {
|
|
549
|
-
|
|
946
|
+
const modern = connection.protocol.era === "modern";
|
|
947
|
+
if (!modern && !connection.capabilities.prompts) {
|
|
550
948
|
return [];
|
|
551
949
|
}
|
|
552
950
|
|
|
@@ -555,7 +953,12 @@ export async function listPrompts(
|
|
|
555
953
|
}
|
|
556
954
|
|
|
557
955
|
const allPrompts: MCPPrompt[] = [];
|
|
558
|
-
|
|
956
|
+
try {
|
|
957
|
+
await collectPaginated(connection, options, "prompts/list", "prompts", allPrompts);
|
|
958
|
+
} catch (error) {
|
|
959
|
+
if (modern && isModernMethodNotFound(error)) return [];
|
|
960
|
+
throw error;
|
|
961
|
+
}
|
|
559
962
|
|
|
560
963
|
connection.prompts = allPrompts;
|
|
561
964
|
return allPrompts;
|
|
@@ -575,7 +978,8 @@ export async function getPrompt(
|
|
|
575
978
|
params.arguments = args;
|
|
576
979
|
}
|
|
577
980
|
|
|
578
|
-
return
|
|
981
|
+
return requestWithInputHandling<MCPGetPromptResult>(
|
|
982
|
+
connection,
|
|
579
983
|
"prompts/get",
|
|
580
984
|
params as unknown as Record<string, unknown>,
|
|
581
985
|
options,
|
|
@@ -12,6 +12,7 @@ import { loadCapability } from "../discovery";
|
|
|
12
12
|
import { loadMCPJsonFile } from "../discovery/mcp-json";
|
|
13
13
|
import { readDisabledServers } from "./config-writer";
|
|
14
14
|
import { canonicalizeMCPEndpoint } from "./pool-key";
|
|
15
|
+
import { isMCPProtocolPreference } from "./protocol";
|
|
15
16
|
import type { MCPServerConfig } from "./types";
|
|
16
17
|
|
|
17
18
|
/** Options for loading MCP configs */
|
|
@@ -24,6 +25,13 @@ export interface LoadMCPConfigsOptions {
|
|
|
24
25
|
filterBrowser?: boolean;
|
|
25
26
|
/** Only include startup-eligible servers; exact-config sessions always enforce autoload !== false. */
|
|
26
27
|
autoloadOnly?: boolean;
|
|
28
|
+
/**
|
|
29
|
+
* Restrict discovery to GJC's own native config (`.gjc/` project and
|
|
30
|
+
* `~/.gjc/agent/` user scopes). Conventional standalone sessions use this
|
|
31
|
+
* mode: Claude Code/Codex project/global MCP files are explicit import
|
|
32
|
+
* sources into `.gjc`, not implicit competing runtime authorities.
|
|
33
|
+
*/
|
|
34
|
+
nativeOnly?: boolean;
|
|
27
35
|
/** Load only this explicit MCP config file. */
|
|
28
36
|
configPath?: string;
|
|
29
37
|
}
|
|
@@ -38,6 +46,8 @@ export interface LoadMCPConfigsResult {
|
|
|
38
46
|
sources: Record<string, SourceMeta>;
|
|
39
47
|
/** Whether the explicit configuration was unavailable or contained invalid entries. */
|
|
40
48
|
configurationWarning: boolean;
|
|
49
|
+
/** Provider warnings surfaced during discovery (parse/skip diagnostics). */
|
|
50
|
+
warnings: string[];
|
|
41
51
|
}
|
|
42
52
|
|
|
43
53
|
/**
|
|
@@ -51,6 +61,7 @@ function convertToLegacyConfig(server: MCPServer): MCPServerConfig {
|
|
|
51
61
|
autoload: server.autoload,
|
|
52
62
|
timeout: server.timeout,
|
|
53
63
|
sharing: server.sharing,
|
|
64
|
+
protocol: server.protocol,
|
|
54
65
|
auth: server.auth,
|
|
55
66
|
oauth: server.oauth,
|
|
56
67
|
};
|
|
@@ -115,17 +126,35 @@ export async function loadAllMCPConfigs(cwd: string, options?: LoadMCPConfigsOpt
|
|
|
115
126
|
let servers: MCPServer[];
|
|
116
127
|
let disabledServers: Set<string>;
|
|
117
128
|
let configurationWarning = false;
|
|
129
|
+
let warnings: string[] = [];
|
|
118
130
|
if (exactConfig) {
|
|
119
131
|
const result = await loadMCPJsonFile(options.configPath!, "project", { quiet: true });
|
|
120
132
|
servers = result.items;
|
|
121
133
|
disabledServers = new Set(result.disabledServers);
|
|
122
|
-
|
|
134
|
+
warnings = result.warnings ?? [];
|
|
135
|
+
configurationWarning = warnings.length > 0;
|
|
123
136
|
} else {
|
|
124
|
-
// Load MCP servers via capability system
|
|
125
|
-
|
|
137
|
+
// Load MCP servers via capability system. Conventional standalone
|
|
138
|
+
// sessions restrict discovery to GJC's native `.gjc` scopes (nativeOnly),
|
|
139
|
+
// keeping Claude Code/Codex files as explicit import sources rather than
|
|
140
|
+
// implicit runtime authorities.
|
|
141
|
+
const result = await loadCapability<MCPServer>(mcpCapability.id, {
|
|
142
|
+
cwd,
|
|
143
|
+
providers: options?.nativeOnly === true ? ["native"] : undefined,
|
|
144
|
+
});
|
|
126
145
|
// Filter out project-level configs if disabled
|
|
127
146
|
servers = enableProjectConfig ? result.items : result.items.filter(server => server._source.level !== "project");
|
|
128
|
-
disabledServers
|
|
147
|
+
// The disabledServers denylist is honored from both native scopes so a
|
|
148
|
+
// name listed in either GJC config file stays out of runtime loading.
|
|
149
|
+
// Each scope is read independently: a malformed config file in one scope
|
|
150
|
+
// must not abort discovery of valid servers in the other scope (the
|
|
151
|
+
// capability loader itself is already per-file tolerant).
|
|
152
|
+
const [userDisabled, projectDisabled] = await Promise.all([
|
|
153
|
+
readDisabledServers(getMCPConfigPath("user", cwd)).catch(() => []),
|
|
154
|
+
readDisabledServers(getMCPConfigPath("project", cwd)).catch(() => []),
|
|
155
|
+
]);
|
|
156
|
+
disabledServers = new Set([...userDisabled, ...projectDisabled]);
|
|
157
|
+
warnings = result.warnings;
|
|
129
158
|
}
|
|
130
159
|
|
|
131
160
|
// Convert to legacy format and preserve source metadata
|
|
@@ -158,7 +187,7 @@ export async function loadAllMCPConfigs(cwd: string, options?: LoadMCPConfigsOpt
|
|
|
158
187
|
sources = browserResult.sources;
|
|
159
188
|
}
|
|
160
189
|
|
|
161
|
-
return { configs, exaApiKeys, sources, configurationWarning };
|
|
190
|
+
return { configs, exaApiKeys, sources, configurationWarning, warnings };
|
|
162
191
|
}
|
|
163
192
|
|
|
164
193
|
/** Pattern to match Exa MCP servers */
|
|
@@ -277,6 +306,9 @@ export function validateServerConfig(name: string, config: MCPServerConfig): str
|
|
|
277
306
|
if (config.sharing !== undefined && config.sharing !== "per-session" && config.sharing !== "shared") {
|
|
278
307
|
errors.push(`Server "${name}": sharing must be "per-session" or "shared"`);
|
|
279
308
|
}
|
|
309
|
+
if (config.protocol !== undefined && !isMCPProtocolPreference(config.protocol)) {
|
|
310
|
+
errors.push(`Server "${name}": protocol must be "auto", "2026-07-28", or "legacy"`);
|
|
311
|
+
}
|
|
280
312
|
const serverType = config.type ?? "stdio";
|
|
281
313
|
|
|
282
314
|
// Check for conflicting transport fields
|