@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.
Files changed (599) hide show
  1. package/CHANGELOG.md +184 -2
  2. package/README.md +2 -0
  3. package/bin/gajaessi.js +4 -0
  4. package/dist/types/async/job-manager.d.ts +55 -2
  5. package/dist/types/async/support.d.ts +14 -0
  6. package/dist/types/capability/mcp.d.ts +6 -0
  7. package/dist/types/capability/types.d.ts +6 -0
  8. package/dist/types/cli/accounts-cli.d.ts +19 -0
  9. package/dist/types/cli/args.d.ts +3 -0
  10. package/dist/types/cli/config-cli.d.ts +6 -0
  11. package/dist/types/cli/crash-cli.d.ts +10 -0
  12. package/dist/types/cli/customize-doctor.d.ts +145 -0
  13. package/dist/types/cli/daemon-cli.d.ts +3 -1
  14. package/dist/types/cli/mcp-cli.d.ts +11 -0
  15. package/dist/types/cli/notify-cli.d.ts +1 -1
  16. package/dist/types/cli/root-flags.d.ts +12 -0
  17. package/dist/types/cli/setup-cli.d.ts +3 -1
  18. package/dist/types/cli/skills-cli.d.ts +2 -1
  19. package/dist/types/cli/update-cli.d.ts +19 -1
  20. package/dist/types/cli.d.ts +6 -0
  21. package/dist/types/commands/accounts.d.ts +40 -0
  22. package/dist/types/commands/crash.d.ts +24 -0
  23. package/dist/types/commands/customize.d.ts +22 -0
  24. package/dist/types/commands/daemon.d.ts +1 -1
  25. package/dist/types/commands/launch.d.ts +6 -0
  26. package/dist/types/commands/setup.d.ts +6 -0
  27. package/dist/types/commands/skills.d.ts +6 -1
  28. package/dist/types/commands/update.d.ts +7 -0
  29. package/dist/types/config/atomic-yaml-patch-worker.d.ts +25 -0
  30. package/dist/types/config/atomic-yaml-patch.d.ts +62 -2
  31. package/dist/types/config/config-schema-version.d.ts +10 -0
  32. package/dist/types/config/file-lock.d.ts +18 -0
  33. package/dist/types/config/model-profile-activation.d.ts +3 -1
  34. package/dist/types/config/model-registry.d.ts +9 -1
  35. package/dist/types/config/models-config-schema.d.ts +2 -0
  36. package/dist/types/config/settings-schema.d.ts +70 -6
  37. package/dist/types/config/settings.d.ts +63 -0
  38. package/dist/types/config/skill-settings-defaults.d.ts +26 -0
  39. package/dist/types/config/task-delegation.d.ts +39 -0
  40. package/dist/types/config/update-channel.d.ts +10 -0
  41. package/dist/types/coordinator-mcp/server.d.ts +5 -1
  42. package/dist/types/crash/index-store.d.ts +87 -0
  43. package/dist/types/crash/nudge.d.ts +50 -0
  44. package/dist/types/crash/record-loader.d.ts +17 -0
  45. package/dist/types/crash/report.d.ts +134 -0
  46. package/dist/types/crash/sanitize.d.ts +25 -0
  47. package/dist/types/cursor.d.ts +13 -2
  48. package/dist/types/customization/import.d.ts +37 -0
  49. package/dist/types/customization/index.d.ts +4 -0
  50. package/dist/types/customization/inventory.d.ts +25 -0
  51. package/dist/types/customization/mutations.d.ts +32 -0
  52. package/dist/types/customization/types.d.ts +115 -0
  53. package/dist/types/daemon/control-types.d.ts +8 -1
  54. package/dist/types/daemon/operator-contract.d.ts +4 -4
  55. package/dist/types/discovery/claude.d.ts +39 -1
  56. package/dist/types/discovery/codex.d.ts +39 -1
  57. package/dist/types/discovery/index.d.ts +2 -0
  58. package/dist/types/discovery/mcp-compat.d.ts +30 -0
  59. package/dist/types/edit/renderer.d.ts +23 -0
  60. package/dist/types/extensibility/extensions/runner.d.ts +3 -0
  61. package/dist/types/extensibility/extensions/types.d.ts +21 -4
  62. package/dist/types/extensibility/gjc-plugins/observability.d.ts +6 -1
  63. package/dist/types/extensibility/gjc-plugins/registry.d.ts +8 -1
  64. package/dist/types/extensibility/hooks/loader.d.ts +19 -5
  65. package/dist/types/extensibility/runtime-skill-discovery.d.ts +22 -1
  66. package/dist/types/extensibility/skill-management.d.ts +107 -0
  67. package/dist/types/gjc-runtime/deep-interview-runtime.d.ts +3 -1
  68. package/dist/types/gjc-runtime/launch-worktree.d.ts +8 -0
  69. package/dist/types/gjc-runtime/linux-proc.d.ts +3 -0
  70. package/dist/types/gjc-runtime/ralplan-runtime.d.ts +10 -6
  71. package/dist/types/gjc-runtime/session-state-lock.d.ts +104 -0
  72. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +120 -2
  73. package/dist/types/gjc-runtime/state-writer.d.ts +10 -1
  74. package/dist/types/gjc-runtime/ultragoal-guard.d.ts +4 -2
  75. package/dist/types/gjc-runtime/ultragoal-runtime.d.ts +8 -6
  76. package/dist/types/gjc-runtime/workflow-settings.d.ts +109 -0
  77. package/dist/types/hooks/events.d.ts +60 -0
  78. package/dist/types/hooks/normalize.d.ts +83 -0
  79. package/dist/types/hooks/skill-state.d.ts +9 -2
  80. package/dist/types/main.d.ts +1 -1
  81. package/dist/types/modes/acp/abort-scope.d.ts +13 -0
  82. package/dist/types/modes/acp/acp-agent.d.ts +7 -4
  83. package/dist/types/modes/components/customization/customization-dashboard.d.ts +44 -0
  84. package/dist/types/modes/components/customization/import-wizard.d.ts +21 -0
  85. package/dist/types/modes/components/customization/index.d.ts +1 -0
  86. package/dist/types/modes/components/gajae-pet-widget.d.ts +8 -30
  87. package/dist/types/modes/components/irc-sidebar.d.ts +1 -0
  88. package/dist/types/modes/components/iterm-pet-transport.d.ts +122 -0
  89. package/dist/types/modes/components/oauth-selector.d.ts +10 -4
  90. package/dist/types/modes/components/pet-capability.d.ts +11 -25
  91. package/dist/types/modes/components/status-line/gh.d.ts +6 -2
  92. package/dist/types/modes/controllers/extension-ui-controller.d.ts +1 -1
  93. package/dist/types/modes/controllers/selector-controller.d.ts +7 -8
  94. package/dist/types/modes/controllers/stt-controller.d.ts +1 -1
  95. package/dist/types/modes/interactive-mode.d.ts +1 -0
  96. package/dist/types/modes/types.d.ts +1 -0
  97. package/dist/types/modes/utils/injected-user-submission.d.ts +10 -0
  98. package/dist/types/runtime-mcp/config.d.ts +9 -0
  99. package/dist/types/runtime-mcp/manager.d.ts +26 -1
  100. package/dist/types/runtime-mcp/oauth-discovery.d.ts +4 -0
  101. package/dist/types/runtime-mcp/oauth-flow.d.ts +24 -1
  102. package/dist/types/runtime-mcp/pool-key.d.ts +2 -0
  103. package/dist/types/runtime-mcp/protocol.d.ts +278 -0
  104. package/dist/types/runtime-mcp/scope-config.d.ts +29 -0
  105. package/dist/types/runtime-mcp/tool-bridge.d.ts +15 -13
  106. package/dist/types/runtime-mcp/transports/http.d.ts +9 -0
  107. package/dist/types/runtime-mcp/types.d.ts +102 -10
  108. package/dist/types/sdk/acp/adapter.d.ts +26 -5
  109. package/dist/types/sdk/broker/broker.d.ts +3 -55
  110. package/dist/types/sdk/broker/lifecycle.d.ts +18 -12
  111. package/dist/types/sdk/broker/session-index.d.ts +14 -5
  112. package/dist/types/sdk/broker/startup-failure.d.ts +16 -1
  113. package/dist/types/sdk/bus/chat-daemon-control.d.ts +51 -1
  114. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +4 -41
  115. package/dist/types/sdk/bus/config.d.ts +11 -0
  116. package/dist/types/sdk/bus/conversation-store.d.ts +0 -1
  117. package/dist/types/sdk/bus/daemon-paths.d.ts +6 -0
  118. package/dist/types/sdk/bus/discord-conversation.d.ts +2 -0
  119. package/dist/types/sdk/bus/discord-daemon.d.ts +17 -12
  120. package/dist/types/sdk/bus/existing-thread-readiness.d.ts +4 -34
  121. package/dist/types/sdk/bus/inbound-reaction-ordering.d.ts +61 -0
  122. package/dist/types/sdk/bus/index.d.ts +85 -99
  123. package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +29 -7
  124. package/dist/types/sdk/bus/managed-daemon.d.ts +2 -32
  125. package/dist/types/sdk/bus/notification-service.d.ts +52 -0
  126. package/dist/types/sdk/bus/operator-runtime.d.ts +1 -1
  127. package/dist/types/sdk/bus/prompt-reconciliation.d.ts +16 -5
  128. package/dist/types/sdk/bus/reconciliation-store.d.ts +113 -5
  129. package/dist/types/sdk/bus/session-control.d.ts +25 -1
  130. package/dist/types/sdk/bus/slack-conversation.d.ts +4 -0
  131. package/dist/types/sdk/bus/slack-daemon.d.ts +9 -17
  132. package/dist/types/sdk/bus/slack-live-provider.d.ts +3 -1
  133. package/dist/types/sdk/bus/slack-provider.d.ts +4 -0
  134. package/dist/types/sdk/bus/slack-thread-binding.d.ts +6 -40
  135. package/dist/types/sdk/bus/telegram-adoption-intent.d.ts +30 -104
  136. package/dist/types/sdk/bus/telegram-daemon-cli.d.ts +10 -0
  137. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +262 -19
  138. package/dist/types/sdk/bus/telegram-daemon-orphan-reap.d.ts +125 -0
  139. package/dist/types/sdk/bus/telegram-daemon-owner-registry.d.ts +22 -0
  140. package/dist/types/sdk/bus/telegram-daemon.d.ts +119 -310
  141. package/dist/types/sdk/bus/telegram-reference.d.ts +1 -47
  142. package/dist/types/sdk/bus/threaded-render.d.ts +1 -0
  143. package/dist/types/sdk/bus/topic-registry.d.ts +33 -17
  144. package/dist/types/sdk/cli/rows.d.ts +2 -11
  145. package/dist/types/sdk/cli/session-cli.d.ts +15 -25
  146. package/dist/types/sdk/client/client.d.ts +97 -1
  147. package/dist/types/sdk/host/control/dispatch.d.ts +0 -7
  148. package/dist/types/sdk/host/control/index.d.ts +1 -1
  149. package/dist/types/sdk/host/control/operations.d.ts +18 -5
  150. package/dist/types/sdk/host/control/runtime-gate.d.ts +19 -0
  151. package/dist/types/sdk/host/host.d.ts +15 -1
  152. package/dist/types/sdk/host/query/handlers.d.ts +5 -0
  153. package/dist/types/sdk/host/reverse-leases.d.ts +1 -1
  154. package/dist/types/sdk/host/session-runtime.d.ts +127 -7
  155. package/dist/types/sdk/host/types.d.ts +1 -1
  156. package/dist/types/sdk/host/websocket-transport.d.ts +1 -1
  157. package/dist/types/sdk/index.d.ts +2 -1
  158. package/dist/types/sdk/lifecycle/broker-client.d.ts +8 -0
  159. package/dist/types/sdk/lifecycle/client.d.ts +59 -0
  160. package/dist/types/sdk/lifecycle/index.d.ts +3 -0
  161. package/dist/types/sdk/lifecycle/service.d.ts +232 -0
  162. package/dist/types/sdk/mcp/server.d.ts +9 -6
  163. package/dist/types/sdk/prompt-deadline-lease.d.ts +43 -0
  164. package/dist/types/sdk/prompt-deadline-manager.d.ts +28 -0
  165. package/dist/types/sdk/prompt-status.d.ts +10 -3
  166. package/dist/types/sdk/protocol/operation-registry.d.ts +5 -0
  167. package/dist/types/sdk/receipt-state.d.ts +17 -0
  168. package/dist/types/sdk/reconciliation-extensions.d.ts +2 -0
  169. package/dist/types/sdk/router/index.d.ts +1 -0
  170. package/dist/types/sdk/router/session-router.d.ts +152 -0
  171. package/dist/types/sdk/session-list.d.ts +22 -0
  172. package/dist/types/sdk/session-reconnect.d.ts +43 -1
  173. package/dist/types/sdk/session.d.ts +34 -1
  174. package/dist/types/sdk/transport/serve-cli.d.ts +1 -4
  175. package/dist/types/session/account-inventory.d.ts +86 -0
  176. package/dist/types/session/agent-session.d.ts +145 -6
  177. package/dist/types/session/agent-storage.d.ts +10 -0
  178. package/dist/types/session/coordinator-tool-label.d.ts +28 -0
  179. package/dist/types/session/internal/managed-session-storage.d.ts +23 -4
  180. package/dist/types/session/messages.d.ts +1 -1
  181. package/dist/types/session/secure-token-file.d.ts +3 -0
  182. package/dist/types/session/session-manager.d.ts +40 -1
  183. package/dist/types/session/startup-auth-config.d.ts +44 -0
  184. package/dist/types/session/terminal-abort.d.ts +378 -0
  185. package/dist/types/session/yield-queue.d.ts +7 -0
  186. package/dist/types/session-import/claude.d.ts +26 -0
  187. package/dist/types/session-import/codex.d.ts +88 -0
  188. package/dist/types/session-import/command.d.ts +35 -0
  189. package/dist/types/session-import/detect.d.ts +22 -0
  190. package/dist/types/session-import/index.d.ts +7 -0
  191. package/dist/types/session-import/provider-codex.d.ts +22 -0
  192. package/dist/types/session-import/provider-service.d.ts +38 -0
  193. package/dist/types/session-import/redact.d.ts +23 -0
  194. package/dist/types/session-import/service.d.ts +47 -0
  195. package/dist/types/session-import/types.d.ts +120 -0
  196. package/dist/types/setup/paseo/check.d.ts +16 -0
  197. package/dist/types/setup/paseo/install-saga.d.ts +115 -0
  198. package/dist/types/setup/paseo/json-publisher.d.ts +76 -0
  199. package/dist/types/setup/paseo/orchestration-preferences.d.ts +24 -0
  200. package/dist/types/setup/paseo/paseo-ownership.d.ts +87 -0
  201. package/dist/types/setup/paseo/paseo-setup.d.ts +29 -0
  202. package/dist/types/setup/paseo/provider-config.d.ts +35 -0
  203. package/dist/types/setup/paseo/remove.d.ts +14 -0
  204. package/dist/types/setup/paseo/result-types.d.ts +59 -0
  205. package/dist/types/setup/paseo/setup-deps.d.ts +73 -0
  206. package/dist/types/setup/paseo/skills-bridge.d.ts +44 -0
  207. package/dist/types/skill-state/active-state.d.ts +5 -1
  208. package/dist/types/slash-commands/acp-builtins.d.ts +5 -1
  209. package/dist/types/slash-commands/builtin-registry.d.ts +2 -0
  210. package/dist/types/slash-commands/helpers/credential-switch.d.ts +12 -0
  211. package/dist/types/slash-commands/helpers/usage-report.d.ts +5 -6
  212. package/dist/types/slash-commands/types.d.ts +7 -1
  213. package/dist/types/task/executor.d.ts +10 -0
  214. package/dist/types/task/index.d.ts +3 -1
  215. package/dist/types/tools/ask-answer-registry.d.ts +6 -3
  216. package/dist/types/tools/bash-sleep-advisory.d.ts +14 -0
  217. package/dist/types/tools/bash.d.ts +2 -6
  218. package/dist/types/tools/browser/attach.d.ts +11 -0
  219. package/dist/types/tools/browser/launch.d.ts +20 -0
  220. package/dist/types/tools/browser/profile-discovery.d.ts +6 -0
  221. package/dist/types/tools/browser/render.d.ts +1 -0
  222. package/dist/types/tools/browser.d.ts +3 -1
  223. package/dist/types/tools/image-gen.d.ts +9 -2
  224. package/dist/types/tools/index.d.ts +8 -0
  225. package/dist/types/tools/monitor.d.ts +1 -1
  226. package/dist/types/tools/skill-discovery.d.ts +8 -1
  227. package/dist/types/tools/subagent.d.ts +2 -0
  228. package/dist/types/tools/ultragoal-ask-guard.d.ts +2 -2
  229. package/dist/types/utils/herdr-pane.d.ts +76 -0
  230. package/package.json +19 -9
  231. package/scripts/build-binary.ts +2 -1
  232. package/scripts/build-sdk-package-smoke.ts +2 -13
  233. package/scripts/capture-sticky-viewport-showcase.ts +0 -1
  234. package/scripts/compile-args.ts +2 -0
  235. package/scripts/generate-sdk-adapter-parity-manifest.ts +31 -16
  236. package/scripts/generate-sdk-operation-inventory.ts +28 -0
  237. package/scripts/generate-telegram-baseline-manifest.ts +1 -0
  238. package/scripts/generate-tool-catalog.ts +6 -4
  239. package/scripts/verify-gjc-sdk-canonicalization.ts +5 -39
  240. package/src/async/job-manager.ts +352 -17
  241. package/src/async/support.ts +25 -0
  242. package/src/autoresearch/dashboard.ts +28 -13
  243. package/src/capability/index.ts +3 -1
  244. package/src/capability/mcp.ts +6 -0
  245. package/src/capability/types.ts +6 -0
  246. package/src/cli/accounts-cli.ts +395 -0
  247. package/src/cli/args.ts +23 -0
  248. package/src/cli/auth-broker-cli.ts +136 -66
  249. package/src/cli/auth-gateway-cli.ts +94 -70
  250. package/src/cli/config-cli.ts +27 -2
  251. package/src/cli/crash-cli.ts +78 -0
  252. package/src/cli/customize-doctor.ts +1605 -0
  253. package/src/cli/daemon-cli.ts +12 -3
  254. package/src/cli/fast-help.ts +1 -0
  255. package/src/cli/mcp-cli.ts +128 -60
  256. package/src/cli/notify-cli.ts +8 -14
  257. package/src/cli/root-flags.ts +8 -0
  258. package/src/cli/setup-cli.ts +145 -0
  259. package/src/cli/skills-cli.ts +38 -2
  260. package/src/cli/update-cli.ts +167 -12
  261. package/src/cli.ts +4 -0
  262. package/src/commands/accounts.ts +71 -0
  263. package/src/commands/crash.ts +35 -0
  264. package/src/commands/customize.ts +84 -0
  265. package/src/commands/daemon.ts +2 -2
  266. package/src/commands/deep-interview.ts +2 -0
  267. package/src/commands/launch.ts +1 -0
  268. package/src/commands/mcp.ts +12 -7
  269. package/src/commands/ralplan.ts +2 -0
  270. package/src/commands/sdk.ts +65 -32
  271. package/src/commands/setup.ts +5 -0
  272. package/src/commands/skills.ts +14 -4
  273. package/src/commands/ultragoal.ts +10 -1
  274. package/src/commands/update.ts +26 -15
  275. package/src/config/atomic-yaml-patch-worker.ts +57 -0
  276. package/src/config/atomic-yaml-patch.ts +769 -29
  277. package/src/config/config-schema-version.ts +10 -0
  278. package/src/config/file-lock.ts +70 -1
  279. package/src/config/mcp-schema.json +52 -14
  280. package/src/config/model-profile-activation.ts +20 -1
  281. package/src/config/model-profiles.ts +29 -19
  282. package/src/config/model-registry.ts +132 -21
  283. package/src/config/models-config-schema.ts +1 -1
  284. package/src/config/settings-schema.ts +76 -6
  285. package/src/config/settings.ts +4038 -199
  286. package/src/config/skill-settings-defaults.ts +41 -3
  287. package/src/config/task-delegation.ts +87 -0
  288. package/src/config/update-channel.ts +23 -0
  289. package/src/coordinator-mcp/server.ts +377 -308
  290. package/src/crash/index-store.ts +723 -0
  291. package/src/crash/nudge.ts +89 -0
  292. package/src/crash/record-loader.ts +149 -0
  293. package/src/crash/report.ts +551 -0
  294. package/src/crash/sanitize.ts +129 -0
  295. package/src/cursor.ts +36 -10
  296. package/src/customization/import.ts +946 -0
  297. package/src/customization/index.ts +4 -0
  298. package/src/customization/inventory.ts +335 -0
  299. package/src/customization/mutations.ts +141 -0
  300. package/src/customization/types.ts +223 -0
  301. package/src/daemon/control-types.ts +8 -1
  302. package/src/daemon/operator-contract.ts +6 -6
  303. package/src/defaults/gjc/skills/deep-interview/SKILL.md +11 -22
  304. package/src/defaults/gjc/skills/ralplan/SKILL.md +36 -23
  305. package/src/defaults/gjc/skills/ultragoal/SKILL.md +16 -0
  306. package/src/discovery/claude-hooks.ts +38 -0
  307. package/src/discovery/claude.ts +142 -209
  308. package/src/discovery/codex-hooks.ts +38 -0
  309. package/src/discovery/codex.ts +132 -198
  310. package/src/discovery/helpers.ts +8 -1
  311. package/src/discovery/index.ts +2 -0
  312. package/src/discovery/mcp-compat.ts +234 -0
  313. package/src/discovery/mcp-json.ts +6 -0
  314. package/src/edit/renderer.ts +40 -0
  315. package/src/edit/streaming.ts +4 -2
  316. package/src/exec/bash-executor.ts +24 -20
  317. package/src/export/html/index.ts +51 -2
  318. package/src/extensibility/extensions/loader.ts +9 -1
  319. package/src/extensibility/extensions/runner.ts +17 -4
  320. package/src/extensibility/extensions/types.ts +31 -6
  321. package/src/extensibility/gjc-plugins/constrained-hooks.ts +33 -0
  322. package/src/extensibility/gjc-plugins/installer.ts +9 -5
  323. package/src/extensibility/gjc-plugins/observability.ts +8 -2
  324. package/src/extensibility/gjc-plugins/registry.ts +13 -2
  325. package/src/extensibility/gjc-plugins/runtime-adapters.ts +3 -1
  326. package/src/extensibility/gjc-plugins/schema.ts +222 -39
  327. package/src/extensibility/hooks/loader.ts +154 -10
  328. package/src/extensibility/runtime-skill-discovery.ts +257 -60
  329. package/src/extensibility/skill-management.ts +368 -0
  330. package/src/extensibility/skills.ts +52 -16
  331. package/src/gjc-runtime/deep-interview-runtime.ts +45 -61
  332. package/src/gjc-runtime/launch-worktree.ts +56 -2
  333. package/src/gjc-runtime/linux-proc.ts +7 -1
  334. package/src/gjc-runtime/ralplan-runtime.ts +100 -164
  335. package/src/gjc-runtime/session-state-lock.ts +992 -0
  336. package/src/gjc-runtime/session-state-sidecar.ts +644 -142
  337. package/src/gjc-runtime/state-writer.ts +39 -14
  338. package/src/gjc-runtime/tmux-owner-isolation.ts +5 -4
  339. package/src/gjc-runtime/ultragoal-guard.ts +11 -4
  340. package/src/gjc-runtime/ultragoal-runtime.ts +44 -41
  341. package/src/gjc-runtime/workflow-settings.ts +596 -0
  342. package/src/goals/tools/goal-tool.ts +6 -1
  343. package/src/hooks/events.ts +291 -0
  344. package/src/hooks/native-skill-hook.ts +4 -0
  345. package/src/hooks/normalize.ts +369 -0
  346. package/src/hooks/skill-state.ts +165 -46
  347. package/src/internal-urls/docs-index.generated.ts +40 -32
  348. package/src/main.ts +32 -5
  349. package/src/migrate/mcp-mapper.ts +25 -2
  350. package/src/modes/acp/abort-scope.ts +29 -0
  351. package/src/modes/acp/acp-agent.ts +423 -98
  352. package/src/modes/components/assistant-message.ts +6 -1
  353. package/src/modes/components/customization/customization-dashboard.ts +443 -0
  354. package/src/modes/components/customization/import-wizard.ts +372 -0
  355. package/src/modes/components/customization/index.ts +1 -0
  356. package/src/modes/components/gajae-pet-widget.ts +539 -213
  357. package/src/modes/components/irc-sidebar.ts +11 -0
  358. package/src/modes/components/iterm-pet-transport.ts +585 -0
  359. package/src/modes/components/oauth-selector.ts +277 -86
  360. package/src/modes/components/pet-capability.ts +39 -40
  361. package/src/modes/components/settings-selector.ts +9 -0
  362. package/src/modes/components/status-line/gh.ts +45 -1
  363. package/src/modes/components/status-line/segments.ts +16 -1
  364. package/src/modes/components/tool-status-header.ts +13 -3
  365. package/src/modes/controllers/command-controller.ts +20 -8
  366. package/src/modes/controllers/extension-ui-controller.ts +56 -257
  367. package/src/modes/controllers/input-controller.ts +10 -0
  368. package/src/modes/controllers/runtime-mcp-command-controller.ts +16 -3
  369. package/src/modes/controllers/selector-controller.ts +177 -72
  370. package/src/modes/controllers/stt-controller.ts +3 -3
  371. package/src/modes/interactive-mode.ts +88 -16
  372. package/src/modes/print-mode.ts +35 -6
  373. package/src/modes/runtime-init.ts +21 -68
  374. package/src/modes/types.ts +1 -0
  375. package/src/modes/utils/injected-user-submission.ts +25 -0
  376. package/src/modes/utils/terminal-bell.ts +15 -1
  377. package/src/prompts/agent-fragments/ralplan-persistence.md +1 -1
  378. package/src/prompts/agent-fragments/restricted-bash.md +1 -1
  379. package/src/prompts/agents/critic.md +1 -1
  380. package/src/prompts/system/rlm-research.md +1 -1
  381. package/src/prompts/system/system-prompt.md +0 -2
  382. package/src/prompts/tools/bash.md +7 -1
  383. package/src/prompts/tools/browser.md +1 -1
  384. package/src/prompts/tools/cron.md +6 -6
  385. package/src/prompts/tools/read.md +0 -2
  386. package/src/prompts/tools/skill-discovery.md +4 -2
  387. package/src/runtime-mcp/client.ts +427 -23
  388. package/src/runtime-mcp/config.ts +37 -5
  389. package/src/runtime-mcp/manager-pool.test.ts +56 -0
  390. package/src/runtime-mcp/manager.ts +52 -2
  391. package/src/runtime-mcp/oauth-discovery.ts +13 -0
  392. package/src/runtime-mcp/oauth-flow.ts +46 -1
  393. package/src/runtime-mcp/pool-key.ts +5 -1
  394. package/src/runtime-mcp/pool.test.ts +9 -0
  395. package/src/runtime-mcp/protocol.test.ts +353 -0
  396. package/src/runtime-mcp/protocol.ts +624 -0
  397. package/src/runtime-mcp/scope-config.ts +78 -0
  398. package/src/runtime-mcp/tool-bridge.ts +44 -10
  399. package/src/runtime-mcp/transports/http.ts +84 -13
  400. package/src/runtime-mcp/types.ts +123 -12
  401. package/src/sdk/acp/adapter.ts +328 -97
  402. package/src/sdk/broker/broker.ts +160 -741
  403. package/src/sdk/broker/ensure.ts +9 -1
  404. package/src/sdk/broker/lifecycle.ts +510 -116
  405. package/src/sdk/broker/operation-receipt-ledger.ts +11 -2
  406. package/src/sdk/broker/process-incarnation.ts +19 -0
  407. package/src/sdk/broker/session-index.ts +516 -117
  408. package/src/sdk/broker/startup-failure.ts +28 -5
  409. package/src/sdk/broker/transport.ts +1 -13
  410. package/src/sdk/bus/chat-daemon-cli.ts +4 -2
  411. package/src/sdk/bus/chat-daemon-control.ts +67 -6
  412. package/src/sdk/bus/chat-daemon-runtime.ts +183 -859
  413. package/src/sdk/bus/config.ts +13 -0
  414. package/src/sdk/bus/conversation-store.ts +59 -171
  415. package/src/sdk/bus/daemon-paths.ts +20 -0
  416. package/src/sdk/bus/discord-conversation.ts +2 -0
  417. package/src/sdk/bus/discord-daemon.ts +524 -126
  418. package/src/sdk/bus/discord-live-provider.ts +206 -79
  419. package/src/sdk/bus/existing-thread-readiness.ts +4 -97
  420. package/src/sdk/bus/inbound-reaction-ordering.ts +122 -0
  421. package/src/sdk/bus/index.ts +2480 -456
  422. package/src/sdk/bus/kind-aware-reconciliation.ts +204 -34
  423. package/src/sdk/bus/lifecycle-commands.ts +2 -2
  424. package/src/sdk/bus/managed-daemon.ts +2 -145
  425. package/src/sdk/bus/notification-service.ts +196 -0
  426. package/src/sdk/bus/operator-runtime.ts +1 -1
  427. package/src/sdk/bus/prompt-reconciliation.ts +24 -15
  428. package/src/sdk/bus/reconciliation-store.ts +553 -24
  429. package/src/sdk/bus/session-control.ts +49 -3
  430. package/src/sdk/bus/slack-conversation.ts +4 -0
  431. package/src/sdk/bus/slack-daemon.ts +733 -134
  432. package/src/sdk/bus/slack-live-provider.ts +65 -15
  433. package/src/sdk/bus/slack-provider.ts +4 -0
  434. package/src/sdk/bus/slack-thread-binding.ts +9 -104
  435. package/src/sdk/bus/telegram-adoption-intent.ts +299 -209
  436. package/src/sdk/bus/telegram-daemon-cli.ts +194 -7
  437. package/src/sdk/bus/telegram-daemon-contract.ts +265 -19
  438. package/src/sdk/bus/telegram-daemon-control.ts +3 -13
  439. package/src/sdk/bus/telegram-daemon-orphan-reap.ts +498 -0
  440. package/src/sdk/bus/telegram-daemon-owner-registry.ts +176 -0
  441. package/src/sdk/bus/telegram-daemon.ts +2552 -2280
  442. package/src/sdk/bus/telegram-reference.ts +1 -226
  443. package/src/sdk/bus/telegram-setup.ts +2 -2
  444. package/src/sdk/bus/threaded-render.ts +1 -0
  445. package/src/sdk/bus/topic-registry.ts +279 -146
  446. package/src/sdk/cli/rows.ts +2 -35
  447. package/src/sdk/cli/session-cli.ts +776 -700
  448. package/src/sdk/client/client.ts +892 -1
  449. package/src/sdk/host/control/dispatch.ts +93 -58
  450. package/src/sdk/host/control/index.ts +1 -1
  451. package/src/sdk/host/control/operations.ts +18 -10
  452. package/src/sdk/host/control/runtime-gate.ts +40 -0
  453. package/src/sdk/host/host.ts +63 -12
  454. package/src/sdk/host/query/handlers.ts +66 -7
  455. package/src/sdk/host/reverse-leases.ts +2 -2
  456. package/src/sdk/host/sdk-surface-parity.test.ts +1 -1
  457. package/src/sdk/host/session-runtime.test.ts +2787 -34
  458. package/src/sdk/host/session-runtime.ts +1489 -101
  459. package/src/sdk/host/surface-policy.ts +12 -8
  460. package/src/sdk/host/types.ts +1 -1
  461. package/src/sdk/host/websocket-transport.lifecycle.test.ts +31 -59
  462. package/src/sdk/host/websocket-transport.ts +85 -50
  463. package/src/sdk/index.ts +2 -1
  464. package/src/sdk/lifecycle/broker-client.ts +53 -0
  465. package/src/sdk/lifecycle/client.ts +234 -0
  466. package/src/sdk/lifecycle/index.ts +3 -0
  467. package/src/sdk/{bus/recent-activity.ts → lifecycle/recent-sessions.ts} +5 -2
  468. package/src/sdk/lifecycle/service.ts +720 -0
  469. package/src/sdk/mcp/server.ts +226 -188
  470. package/src/sdk/prompt-deadline-lease.ts +55 -0
  471. package/src/sdk/prompt-deadline-manager.ts +148 -0
  472. package/src/sdk/prompt-status.ts +11 -3
  473. package/src/sdk/protocol/operation-inventory.generated.json +272 -129
  474. package/src/sdk/protocol/operation-registry.ts +71 -8
  475. package/src/sdk/receipt-state.ts +43 -0
  476. package/src/sdk/reconciliation-extensions.ts +14 -0
  477. package/src/sdk/router/index.ts +1 -0
  478. package/src/sdk/router/session-router.ts +1658 -0
  479. package/src/sdk/session-list.ts +93 -0
  480. package/src/sdk/session-reconnect.ts +45 -1
  481. package/src/sdk/session.ts +716 -120
  482. package/src/sdk/transport/serve-cli.ts +18 -34
  483. package/src/session/account-inventory.ts +603 -0
  484. package/src/session/agent-session.ts +2857 -582
  485. package/src/session/agent-storage.ts +35 -0
  486. package/src/session/blob-store.ts +32 -1
  487. package/src/session/coordinator-tool-label.ts +40 -0
  488. package/src/session/internal/managed-session-scope.ts +4 -0
  489. package/src/session/internal/managed-session-storage.ts +173 -12
  490. package/src/session/messages.ts +1 -1
  491. package/src/session/secure-token-file.ts +80 -0
  492. package/src/session/session-manager.ts +730 -58
  493. package/src/session/session-storage.ts +25 -16
  494. package/src/session/startup-auth-config.ts +297 -0
  495. package/src/session/terminal-abort.ts +1253 -0
  496. package/src/session/yield-queue.ts +57 -15
  497. package/src/session-import/claude.ts +334 -0
  498. package/src/session-import/codex.ts +1033 -0
  499. package/src/session-import/command.ts +77 -0
  500. package/src/session-import/detect.ts +133 -0
  501. package/src/session-import/index.ts +7 -0
  502. package/src/session-import/provider-codex.ts +327 -0
  503. package/src/session-import/provider-service.ts +457 -0
  504. package/src/session-import/redact.ts +128 -0
  505. package/src/session-import/service.ts +1264 -0
  506. package/src/session-import/types.ts +148 -0
  507. package/src/setup/paseo/check.ts +213 -0
  508. package/src/setup/paseo/install-saga.ts +293 -0
  509. package/src/setup/paseo/json-publisher.ts +263 -0
  510. package/src/setup/paseo/orchestration-preferences.ts +86 -0
  511. package/src/setup/paseo/paseo-ownership.ts +224 -0
  512. package/src/setup/paseo/paseo-setup.ts +253 -0
  513. package/src/setup/paseo/provider-config.ts +139 -0
  514. package/src/setup/paseo/remove.ts +183 -0
  515. package/src/setup/paseo/result-types.ts +79 -0
  516. package/src/setup/paseo/setup-deps.ts +175 -0
  517. package/src/setup/paseo/skills-bridge.ts +260 -0
  518. package/src/skill-state/active-state.ts +21 -11
  519. package/src/slash-commands/acp-builtins.ts +9 -1
  520. package/src/slash-commands/builtin-registry.ts +98 -16
  521. package/src/slash-commands/helpers/credential-switch.ts +143 -0
  522. package/src/slash-commands/helpers/mcp.ts +9 -3
  523. package/src/slash-commands/helpers/usage-report.ts +61 -56
  524. package/src/slash-commands/types.ts +7 -2
  525. package/src/task/executor.ts +30 -11
  526. package/src/task/index.ts +66 -7
  527. package/src/task/render.ts +23 -9
  528. package/src/tools/ask-answer-registry.ts +23 -7
  529. package/src/tools/ask.ts +8 -4
  530. package/src/tools/bash-sleep-advisory.ts +115 -0
  531. package/src/tools/bash.ts +98 -18
  532. package/src/tools/browser/attach.ts +71 -3
  533. package/src/tools/browser/launch.ts +86 -13
  534. package/src/tools/browser/profile-discovery.ts +57 -7
  535. package/src/tools/browser/render.ts +8 -1
  536. package/src/tools/browser.ts +130 -21
  537. package/src/tools/computer.enforcement.test.ts +1 -1
  538. package/src/tools/computer.ts +3 -2
  539. package/src/tools/cron.ts +12 -1
  540. package/src/tools/image-gen.ts +27 -16
  541. package/src/tools/index.ts +8 -0
  542. package/src/tools/job.ts +33 -6
  543. package/src/tools/monitor.ts +41 -2
  544. package/src/tools/skill-discovery.ts +21 -29
  545. package/src/tools/subagent.ts +142 -24
  546. package/src/tools/tool-catalog.generated.ts +6 -6
  547. package/src/tools/ultragoal-ask-guard.ts +10 -3
  548. package/src/utils/herdr-pane.ts +345 -0
  549. package/src/utils/title-generator.ts +2 -0
  550. package/src/web/scrapers/index.ts +6 -4
  551. package/dist/types/cli/malloc-env-guard.test.d.ts +0 -1
  552. package/dist/types/defaults/gjc-defaults.test.d.ts +0 -1
  553. package/dist/types/memory-backend/lazy-loading.test.d.ts +0 -1
  554. package/dist/types/runtime/boot-ordering.test.d.ts +0 -1
  555. package/dist/types/runtime/lazy-service.test.d.ts +0 -1
  556. package/dist/types/runtime/network-prewarm-service.test.d.ts +0 -1
  557. package/dist/types/runtime/workspace-tree-service.test.d.ts +0 -1
  558. package/dist/types/runtime-mcp/config.test.d.ts +0 -1
  559. package/dist/types/runtime-mcp/http.test.d.ts +0 -1
  560. package/dist/types/runtime-mcp/manager-pool.test.d.ts +0 -1
  561. package/dist/types/runtime-mcp/pool-key.test.d.ts +0 -1
  562. package/dist/types/runtime-mcp/pool.test.d.ts +0 -1
  563. package/dist/types/sdk/bus/lifecycle-control-runtime.d.ts +0 -117
  564. package/dist/types/sdk/bus/lifecycle-orchestrator.d.ts +0 -141
  565. package/dist/types/sdk/bus/telegram-cli.d.ts +0 -31
  566. package/dist/types/sdk/elevation/allowlist.d.ts +0 -20
  567. package/dist/types/sdk/elevation/audit.d.ts +0 -93
  568. package/dist/types/sdk/elevation/capability.d.ts +0 -3
  569. package/dist/types/sdk/elevation/digest.d.ts +0 -72
  570. package/dist/types/sdk/elevation/dispatch-receipt.d.ts +0 -85
  571. package/dist/types/sdk/elevation/grant-ledger.d.ts +0 -163
  572. package/dist/types/sdk/elevation/owner.d.ts +0 -48
  573. package/dist/types/sdk/host/import-graph.test.d.ts +0 -1
  574. package/dist/types/sdk/host/sdk-surface-parity.test.d.ts +0 -1
  575. package/dist/types/sdk/host/session-runtime.test.d.ts +0 -1
  576. package/dist/types/sdk/host/websocket-transport.lifecycle.test.d.ts +0 -1
  577. package/dist/types/session/auth-broker-config.d.ts +0 -13
  578. package/dist/types/session/heap-eviction-artifacts.test.d.ts +0 -1
  579. package/dist/types/skills/skills.test.d.ts +0 -1
  580. package/dist/types/slash-commands/notify-command.test.d.ts +0 -1
  581. package/dist/types/task/token-log.test.d.ts +0 -1
  582. package/dist/types/tools/computer.enforcement.test.d.ts +0 -1
  583. package/dist/types/tools/descriptors.test.d.ts +0 -1
  584. package/scripts/g005-daemon-smoke.ts +0 -180
  585. package/scripts/g011-daemon-path-smoke.ts +0 -153
  586. package/src/sdk/bus/lifecycle-control-runtime.ts +0 -1733
  587. package/src/sdk/bus/lifecycle-orchestrator.ts +0 -489
  588. package/src/sdk/bus/telegram-cli.ts +0 -212
  589. package/src/sdk/elevation/allowlist.ts +0 -54
  590. package/src/sdk/elevation/audit.ts +0 -208
  591. package/src/sdk/elevation/capability.ts +0 -41
  592. package/src/sdk/elevation/digest.ts +0 -129
  593. package/src/sdk/elevation/dispatch-receipt.ts +0 -184
  594. package/src/sdk/elevation/grant-ledger.ts +0 -1142
  595. package/src/sdk/elevation/owner.ts +0 -109
  596. package/src/session/auth-broker-config.ts +0 -109
  597. /package/dist/types/{ai-core-import-gate.test.d.ts → discovery/claude-hooks.d.ts} +0 -0
  598. /package/dist/types/{cli/fixture-report.test.d.ts → discovery/codex-hooks.d.ts} +0 -0
  599. /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 initialization, tool listing, and tool calling.
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 { createHttpTransport } from "./transports/http";
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
- try {
258
- const initResult = await initializeConnection(transport, {
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
- // Check if server supports tools
322
- if (!connection.capabilities.tools) {
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 if available
659
+ // Return cached tools while fresh: server ttlMs hints bound freshness when present.
327
660
  if (connection.tools) {
328
- return connection.tools;
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
- await collectPaginated(connection, options, "tools/list", "tools", allTools, decodeToolsListResult);
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 = allTools;
702
+ connection.tools = validTools;
703
+ connection.toolsFreshUntil = freshUntil;
704
+ connection.toolsCacheScope = cacheScope;
336
705
 
337
- return allTools;
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
- return connection.transport.request<MCPToolCallResult>(
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
- if (!connection.capabilities.resources) {
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
- await collectPaginated(connection, options, "resources/list", "resources", allResources);
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
- if (!connection.capabilities.resources) {
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
- await collectPaginated(connection, options, "resources/templates/list", "resourceTemplates", allTemplates);
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 connection.transport.request<MCPResourceReadResult>(
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
- if (!connection.capabilities.prompts) {
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
- await collectPaginated(connection, options, "prompts/list", "prompts", allPrompts);
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 connection.transport.request<MCPGetPromptResult>(
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
- configurationWarning = (result.warnings?.length ?? 0) > 0;
134
+ warnings = result.warnings ?? [];
135
+ configurationWarning = warnings.length > 0;
123
136
  } else {
124
- // Load MCP servers via capability system
125
- const result = await loadCapability<MCPServer>(mcpCapability.id, { cwd });
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 = new Set(await readDisabledServers(getMCPConfigPath("user", cwd)));
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