@gajae-code/coding-agent 0.10.2 → 0.11.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 (465) hide show
  1. package/CHANGELOG.md +50 -2
  2. package/dist/types/append-only-mode.d.ts +1 -1
  3. package/dist/types/cli/args.d.ts +4 -5
  4. package/dist/types/cli/daemon-cli.d.ts +12 -1
  5. package/dist/types/cli/notify-cli.d.ts +21 -1
  6. package/dist/types/cli.d.ts +3 -0
  7. package/dist/types/commands/daemon.d.ts +39 -0
  8. package/dist/types/commands/launch.d.ts +3 -0
  9. package/dist/types/commands/notify.d.ts +28 -1
  10. package/dist/types/commands/sdk.d.ts +33 -0
  11. package/dist/types/config/atomic-yaml-patch.d.ts +85 -0
  12. package/dist/types/config/model-profile-activation.d.ts +35 -15
  13. package/dist/types/config/model-profiles.d.ts +11 -5
  14. package/dist/types/config/model-registry.d.ts +3 -3
  15. package/dist/types/config/model-resolver.d.ts +39 -6
  16. package/dist/types/config/model-selector-value.d.ts +17 -0
  17. package/dist/types/config/models-config-schema.d.ts +10 -6
  18. package/dist/types/config/settings-schema.d.ts +133 -6
  19. package/dist/types/config/settings.d.ts +63 -35
  20. package/dist/types/coordinator-mcp/model-preset.d.ts +7 -6
  21. package/dist/types/coordinator-mcp/server.d.ts +6 -49
  22. package/dist/types/daemon/builtin.d.ts +6 -5
  23. package/dist/types/daemon/control-types.d.ts +1 -1
  24. package/dist/types/discovery/mcp-json.d.ts +12 -1
  25. package/dist/types/extensibility/custom-tools/types.d.ts +1 -1
  26. package/dist/types/extensibility/extensions/compact-handler.d.ts +4 -2
  27. package/dist/types/extensibility/extensions/get-commands-handler.d.ts +2 -2
  28. package/dist/types/extensibility/extensions/loader.d.ts +10 -1
  29. package/dist/types/extensibility/extensions/runner.d.ts +3 -3
  30. package/dist/types/extensibility/extensions/types.d.ts +141 -16
  31. package/dist/types/extensibility/hooks/types.d.ts +1 -1
  32. package/dist/types/gjc-runtime/launch-tmux.d.ts +3 -2
  33. package/dist/types/gjc-runtime/psmux-detect.d.ts +3 -0
  34. package/dist/types/gjc-runtime/session-state-sidecar.d.ts +3 -0
  35. package/dist/types/gjc-runtime/team-runtime.d.ts +3 -4
  36. package/dist/types/gjc-runtime/tmux-owner-isolation-cli.d.ts +13 -0
  37. package/dist/types/gjc-runtime/tmux-sessions.d.ts +4 -1
  38. package/dist/types/gjc-runtime/windows-powershell-command.d.ts +9 -0
  39. package/dist/types/harness-control-plane/operate.d.ts +5 -5
  40. package/dist/types/harness-control-plane/owner.d.ts +18 -4
  41. package/dist/types/harness-control-plane/receipts.d.ts +0 -1
  42. package/dist/types/harness-control-plane/sdk-transport.d.ts +43 -0
  43. package/dist/types/harness-control-plane/session-transport.d.ts +48 -0
  44. package/dist/types/harness-control-plane/types.d.ts +3 -4
  45. package/dist/types/lsp/index.d.ts +1 -1
  46. package/dist/types/main.d.ts +32 -38
  47. package/dist/types/modes/acp/acp-agent.d.ts +224 -53
  48. package/dist/types/modes/acp/acp-client-bridge.d.ts +1 -0
  49. package/dist/types/modes/acp/acp-mode.d.ts +6 -15
  50. package/dist/types/modes/acp/permission-mode.d.ts +4 -0
  51. package/dist/types/modes/acp/startup-options.d.ts +6 -0
  52. package/dist/types/modes/components/agent-dashboard.d.ts +3 -0
  53. package/dist/types/modes/components/model-selector.d.ts +1 -0
  54. package/dist/types/modes/components/notifications-settings-editor.d.ts +135 -0
  55. package/dist/types/modes/components/settings-selector.d.ts +6 -4
  56. package/dist/types/modes/components/welcome.d.ts +1 -1
  57. package/dist/types/modes/controllers/selector-controller.d.ts +35 -1
  58. package/dist/types/modes/index.d.ts +0 -4
  59. package/dist/types/modes/interactive-mode.d.ts +3 -0
  60. package/dist/types/modes/runtime-init.d.ts +2 -2
  61. package/dist/types/modes/shared/agent-wire/approval-gate.d.ts +6 -9
  62. package/dist/types/modes/shared/agent-wire/deep-interview-gate.d.ts +4 -6
  63. package/dist/types/modes/shared/agent-wire/event-contract.d.ts +6 -6
  64. package/dist/types/modes/shared/agent-wire/event-envelope.d.ts +4 -9
  65. package/dist/types/modes/shared/agent-wire/event-observation.d.ts +1 -1
  66. package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +169 -30
  67. package/dist/types/modes/shared/agent-wire/workflow-gate-schema.d.ts +7 -7
  68. package/dist/types/modes/shared/agent-wire/workflow-gate-types.d.ts +105 -0
  69. package/dist/types/modes/types.d.ts +5 -0
  70. package/dist/types/runtime-mcp/client.d.ts +2 -0
  71. package/dist/types/runtime-mcp/config.d.ts +5 -1
  72. package/dist/types/runtime-mcp/manager.d.ts +8 -1
  73. package/dist/types/runtime-mcp/types.d.ts +4 -0
  74. package/dist/types/sdk/acp/adapter.d.ts +67 -0
  75. package/dist/types/sdk/acp/index.d.ts +2 -0
  76. package/dist/types/sdk/broker/broker.d.ts +53 -0
  77. package/dist/types/sdk/broker/discovery.d.ts +30 -0
  78. package/dist/types/sdk/broker/ensure.d.ts +33 -0
  79. package/dist/types/sdk/broker/identity.d.ts +3 -0
  80. package/dist/types/sdk/broker/index.d.ts +8 -0
  81. package/dist/types/sdk/broker/lifecycle-ledger.d.ts +95 -0
  82. package/dist/types/sdk/broker/lifecycle.d.ts +85 -0
  83. package/dist/types/sdk/broker/process-incarnation.d.ts +14 -0
  84. package/dist/types/sdk/broker/runtime.d.ts +33 -0
  85. package/dist/types/sdk/broker/session-index.d.ts +57 -0
  86. package/dist/types/sdk/broker/state-version.d.ts +8 -0
  87. package/dist/types/sdk/broker/transport.d.ts +9 -0
  88. package/dist/types/sdk/bus/chat-command-policy.d.ts +49 -0
  89. package/dist/types/sdk/bus/chat-daemon-cli.d.ts +21 -0
  90. package/dist/types/sdk/bus/chat-daemon-control.d.ts +111 -0
  91. package/dist/types/sdk/bus/chat-daemon-runtime.d.ts +77 -0
  92. package/dist/types/sdk/bus/chat-effect-journal.d.ts +84 -0
  93. package/dist/types/{notifications → sdk/bus}/config-commands.d.ts +7 -2
  94. package/dist/types/sdk/bus/config.d.ts +274 -0
  95. package/dist/types/sdk/bus/conversation-store.d.ts +72 -0
  96. package/dist/types/sdk/bus/discord-conversation.d.ts +58 -0
  97. package/dist/types/sdk/bus/discord-daemon.d.ts +45 -0
  98. package/dist/types/sdk/bus/discord-live-provider.d.ts +70 -0
  99. package/dist/types/sdk/bus/discord-provider.d.ts +85 -0
  100. package/dist/types/{notifications → sdk/bus}/html-format.d.ts +2 -2
  101. package/dist/types/{notifications → sdk/bus}/index.d.ts +113 -13
  102. package/dist/types/{notifications → sdk/bus}/lifecycle-control-runtime.d.ts +4 -2
  103. package/dist/types/{notifications → sdk/bus}/lifecycle-orchestrator.d.ts +18 -21
  104. package/dist/types/{notifications → sdk/bus}/managed-daemon.d.ts +1 -1
  105. package/dist/types/sdk/bus/native-runtime-compatibility.d.ts +13 -0
  106. package/dist/types/sdk/bus/notification-orchestration.d.ts +170 -0
  107. package/dist/types/{notifications → sdk/bus}/notification-service.d.ts +7 -1
  108. package/dist/types/sdk/bus/session-control.d.ts +83 -0
  109. package/dist/types/sdk/bus/slack-conversation.d.ts +56 -0
  110. package/dist/types/sdk/bus/slack-daemon.d.ts +60 -0
  111. package/dist/types/sdk/bus/slack-live-provider.d.ts +59 -0
  112. package/dist/types/sdk/bus/slack-provider.d.ts +55 -0
  113. package/dist/types/{notifications → sdk/bus}/telegram-cli.d.ts +4 -4
  114. package/dist/types/{notifications → sdk/bus}/telegram-daemon-cli.d.ts +14 -5
  115. package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +12 -0
  116. package/dist/types/{notifications → sdk/bus}/telegram-daemon-control.d.ts +2 -2
  117. package/dist/types/{notifications → sdk/bus}/telegram-daemon.d.ts +55 -17
  118. package/dist/types/{notifications → sdk/bus}/telegram-reference.d.ts +2 -2
  119. package/dist/types/sdk/bus/telegram-setup.d.ts +128 -0
  120. package/dist/types/{notifications → sdk/bus}/topic-registry.d.ts +11 -0
  121. package/dist/types/sdk/cli/index.d.ts +1 -0
  122. package/dist/types/sdk/cli/session-cli.d.ts +19 -0
  123. package/dist/types/sdk/client/client.d.ts +1 -0
  124. package/dist/types/sdk/client/discovery.d.ts +27 -0
  125. package/dist/types/sdk/client/index.d.ts +2 -0
  126. package/dist/types/sdk/host/control/dispatch.d.ts +34 -0
  127. package/dist/types/sdk/host/control/index.d.ts +2 -0
  128. package/dist/types/sdk/host/control/operations.d.ts +65 -0
  129. package/dist/types/sdk/host/events.d.ts +35 -0
  130. package/dist/types/sdk/host/host.d.ts +35 -0
  131. package/dist/types/sdk/host/index.d.ts +4 -0
  132. package/dist/types/sdk/host/query/cursor.d.ts +62 -0
  133. package/dist/types/sdk/host/query/handlers.d.ts +70 -0
  134. package/dist/types/sdk/host/query/index.d.ts +3 -0
  135. package/dist/types/sdk/host/query/revision-store.d.ts +60 -0
  136. package/dist/types/sdk/host/reverse-leases.d.ts +45 -0
  137. package/dist/types/sdk/host/types.d.ts +32 -0
  138. package/dist/types/sdk/index.d.ts +6 -0
  139. package/dist/types/sdk/lifecycle-session.d.ts +14 -0
  140. package/dist/types/sdk/mcp/index.d.ts +1 -0
  141. package/dist/types/sdk/mcp/server.d.ts +37 -0
  142. package/dist/types/sdk/models.d.ts +44 -0
  143. package/dist/types/sdk/protocol/adapter-validation.d.ts +14 -0
  144. package/dist/types/sdk/protocol/operation-registry.d.ts +24 -0
  145. package/dist/types/{sdk.d.ts → sdk/session.d.ts} +44 -38
  146. package/dist/types/sdk/startup-capability.d.ts +50 -0
  147. package/dist/types/session/agent-session.d.ts +114 -21
  148. package/dist/types/session/default-model-selection.d.ts +25 -0
  149. package/dist/types/session/fallback-chain-controller.d.ts +52 -0
  150. package/dist/types/session/session-manager.d.ts +58 -1
  151. package/dist/types/setup/credential-auto-import.d.ts +36 -6
  152. package/dist/types/tools/ask-answer-registry.d.ts +1 -1
  153. package/dist/types/tools/browser/benchmark/detector-report.d.ts +63 -0
  154. package/dist/types/tools/browser/benchmark/run-suite.d.ts +18 -0
  155. package/dist/types/tools/browser/launch.d.ts +22 -0
  156. package/dist/types/tools/browser/profile-discovery.d.ts +31 -0
  157. package/dist/types/tools/browser/profile-posture.d.ts +37 -0
  158. package/dist/types/tools/browser/profile-reuse.d.ts +39 -0
  159. package/dist/types/tools/browser/profile-warmup.d.ts +39 -0
  160. package/dist/types/tools/browser/registry.d.ts +19 -0
  161. package/dist/types/tools/browser/tab-protocol.d.ts +4 -0
  162. package/dist/types/tools/index.d.ts +8 -8
  163. package/package.json +34 -13
  164. package/scripts/build-sdk-package-smoke.ts +94 -0
  165. package/scripts/capture-notifications-settings-showcase.ts +435 -0
  166. package/scripts/compile-args.ts +4 -2
  167. package/scripts/g005-daemon-smoke.ts +4 -5
  168. package/scripts/g011-daemon-path-smoke.ts +5 -5
  169. package/scripts/generate-sdk-adapter-parity-manifest.ts +163 -0
  170. package/scripts/generate-sdk-operation-inventory.ts +867 -0
  171. package/scripts/generate-telegram-baseline-manifest.ts +128 -0
  172. package/scripts/manifest-schema.ts +124 -0
  173. package/scripts/run-test-manifest.ts +153 -0
  174. package/scripts/run-threat-model-check.ts +157 -0
  175. package/scripts/verify-gjc-sdk-canonicalization.ts +3467 -0
  176. package/scripts/verify-gjc-sdk-rename.ts +90 -0
  177. package/src/append-only-mode.ts +1 -1
  178. package/src/cli/args.ts +43 -12
  179. package/src/cli/auth-gateway-cli.ts +2 -2
  180. package/src/cli/config-cli.ts +2 -1
  181. package/src/cli/daemon-cli.ts +63 -14
  182. package/src/cli/list-models.ts +1 -1
  183. package/src/cli/notify-cli.ts +288 -286
  184. package/src/cli.ts +21 -2
  185. package/src/commands/daemon.ts +50 -6
  186. package/src/commands/harness.ts +93 -36
  187. package/src/commands/launch.ts +5 -2
  188. package/src/commands/mcp-serve.ts +19 -12
  189. package/src/commands/notify.ts +36 -3
  190. package/src/commands/sdk.ts +426 -0
  191. package/src/commit/agentic/agent.ts +1 -0
  192. package/src/config/atomic-yaml-patch.ts +423 -0
  193. package/src/config/model-profile-activation.ts +240 -89
  194. package/src/config/model-profiles.ts +18 -15
  195. package/src/config/model-registry.ts +51 -26
  196. package/src/config/model-resolver.ts +138 -51
  197. package/src/config/model-selector-value.ts +50 -0
  198. package/src/config/models-config-schema.ts +14 -21
  199. package/src/config/settings-schema.ts +128 -10
  200. package/src/config/settings.ts +1120 -158
  201. package/src/coordinator-mcp/model-preset.ts +74 -20
  202. package/src/coordinator-mcp/server.ts +1597 -3052
  203. package/src/daemon/builtin.ts +8 -5
  204. package/src/daemon/control-types.ts +1 -1
  205. package/src/defaults/gjc/skills/team/SKILL.md +4 -4
  206. package/src/discovery/mcp-json.ts +327 -20
  207. package/src/extensibility/custom-tools/types.ts +1 -1
  208. package/src/extensibility/extensions/compact-handler.ts +3 -3
  209. package/src/extensibility/extensions/get-commands-handler.ts +2 -2
  210. package/src/extensibility/extensions/loader.ts +69 -5
  211. package/src/extensibility/extensions/runner.ts +112 -4
  212. package/src/extensibility/extensions/types.ts +176 -17
  213. package/src/extensibility/hooks/types.ts +1 -1
  214. package/src/gjc-runtime/launch-tmux.ts +170 -86
  215. package/src/gjc-runtime/psmux-detect.ts +82 -4
  216. package/src/gjc-runtime/session-state-sidecar.ts +41 -31
  217. package/src/gjc-runtime/team-runtime.ts +54 -35
  218. package/src/gjc-runtime/tmux-owner-isolation-cli.ts +53 -17
  219. package/src/gjc-runtime/tmux-owner-isolation.ts +1 -1
  220. package/src/gjc-runtime/tmux-sessions.ts +19 -13
  221. package/src/gjc-runtime/ultragoal-guard.ts +53 -6
  222. package/src/gjc-runtime/ultragoal-runtime.ts +155 -3
  223. package/src/gjc-runtime/windows-powershell-command.ts +58 -0
  224. package/src/harness-control-plane/operate.ts +9 -9
  225. package/src/harness-control-plane/owner.ts +283 -39
  226. package/src/harness-control-plane/receipts.ts +0 -1
  227. package/src/harness-control-plane/sdk-transport.ts +395 -0
  228. package/src/harness-control-plane/session-transport.ts +94 -0
  229. package/src/harness-control-plane/types.ts +1 -1
  230. package/src/internal-urls/docs-index.generated.ts +34 -35
  231. package/src/lsp/client.ts +42 -6
  232. package/src/lsp/index.ts +2 -2
  233. package/src/main.ts +299 -204
  234. package/src/modes/DESIGN.md +258 -0
  235. package/src/modes/acp/acp-agent.ts +1228 -2612
  236. package/src/modes/acp/acp-client-bridge.ts +2 -20
  237. package/src/modes/acp/acp-event-mapper.ts +18 -2
  238. package/src/modes/acp/acp-mode.ts +8 -36
  239. package/src/modes/acp/permission-mode.ts +25 -0
  240. package/src/modes/acp/startup-options.ts +6 -0
  241. package/src/modes/components/agent-dashboard.ts +37 -17
  242. package/src/modes/components/model-selector.ts +93 -35
  243. package/src/modes/components/notifications-settings-editor.ts +1379 -0
  244. package/src/modes/components/settings-selector.ts +60 -11
  245. package/src/modes/components/welcome.ts +4 -4
  246. package/src/modes/controllers/command-controller.ts +1 -2
  247. package/src/modes/controllers/event-controller.ts +11 -16
  248. package/src/modes/controllers/extension-ui-controller.ts +348 -4
  249. package/src/modes/controllers/selector-controller.ts +674 -36
  250. package/src/modes/index.ts +0 -22
  251. package/src/modes/interactive-mode.ts +59 -20
  252. package/src/modes/runtime-init.ts +298 -6
  253. package/src/modes/shared/agent-wire/approval-gate.ts +9 -11
  254. package/src/modes/shared/agent-wire/deep-interview-gate.ts +10 -11
  255. package/src/modes/shared/agent-wire/event-contract.ts +7 -8
  256. package/src/modes/shared/agent-wire/event-envelope.ts +9 -17
  257. package/src/modes/shared/agent-wire/event-observation.ts +16 -7
  258. package/src/modes/shared/agent-wire/workflow-gate-broker.ts +1254 -87
  259. package/src/modes/shared/agent-wire/workflow-gate-schema.ts +15 -15
  260. package/src/modes/shared/agent-wire/workflow-gate-types.ts +113 -0
  261. package/src/modes/types.ts +5 -0
  262. package/src/runtime-mcp/client.ts +94 -19
  263. package/src/runtime-mcp/config.ts +27 -15
  264. package/src/runtime-mcp/manager.ts +343 -105
  265. package/src/runtime-mcp/oauth-flow.ts +42 -12
  266. package/src/runtime-mcp/transports/http.ts +49 -19
  267. package/src/runtime-mcp/transports/stdio.ts +47 -28
  268. package/src/runtime-mcp/types.ts +10 -0
  269. package/src/sdk/acp/adapter.ts +418 -0
  270. package/src/sdk/acp/index.ts +2 -0
  271. package/src/sdk/broker/broker.ts +642 -0
  272. package/src/sdk/broker/discovery.ts +94 -0
  273. package/src/sdk/broker/ensure.ts +249 -0
  274. package/src/sdk/broker/identity.ts +42 -0
  275. package/src/sdk/broker/index.ts +8 -0
  276. package/src/sdk/broker/internal-source-marker-2178.txt +1 -0
  277. package/src/sdk/broker/internal-source.bunfig.toml +1 -0
  278. package/src/sdk/broker/lifecycle-ledger.ts +286 -0
  279. package/src/sdk/broker/lifecycle.ts +2157 -0
  280. package/src/sdk/broker/process-incarnation.ts +159 -0
  281. package/src/sdk/broker/runtime.ts +164 -0
  282. package/src/sdk/broker/session-index.ts +318 -0
  283. package/src/sdk/broker/state-version.ts +23 -0
  284. package/src/sdk/broker/transport.ts +125 -0
  285. package/src/sdk/bus/chat-command-policy.ts +107 -0
  286. package/src/sdk/bus/chat-daemon-cli.ts +214 -0
  287. package/src/sdk/bus/chat-daemon-control.ts +713 -0
  288. package/src/sdk/bus/chat-daemon-runtime.ts +526 -0
  289. package/src/sdk/bus/chat-effect-journal.ts +353 -0
  290. package/src/{notifications → sdk/bus}/config-commands.ts +39 -10
  291. package/src/sdk/bus/config.ts +433 -0
  292. package/src/sdk/bus/conversation-store.ts +391 -0
  293. package/src/sdk/bus/discord-conversation.ts +85 -0
  294. package/src/sdk/bus/discord-daemon.ts +2275 -0
  295. package/src/sdk/bus/discord-live-provider.ts +521 -0
  296. package/src/sdk/bus/discord-provider.ts +56 -0
  297. package/src/{notifications → sdk/bus}/html-format.ts +2 -2
  298. package/src/sdk/bus/index.ts +3943 -0
  299. package/src/{notifications → sdk/bus}/lifecycle-commands.ts +2 -0
  300. package/src/{notifications → sdk/bus}/lifecycle-control-runtime.ts +225 -196
  301. package/src/{notifications → sdk/bus}/lifecycle-orchestrator.ts +161 -74
  302. package/src/{notifications → sdk/bus}/managed-daemon.ts +2 -2
  303. package/src/sdk/bus/native-runtime-compatibility.ts +42 -0
  304. package/src/sdk/bus/natives-augment.d.ts +38 -0
  305. package/src/sdk/bus/notification-orchestration.ts +535 -0
  306. package/src/{notifications → sdk/bus}/notification-service.ts +106 -12
  307. package/src/sdk/bus/session-control.ts +333 -0
  308. package/src/sdk/bus/slack-conversation.ts +74 -0
  309. package/src/sdk/bus/slack-daemon.ts +2144 -0
  310. package/src/sdk/bus/slack-live-provider.ts +380 -0
  311. package/src/sdk/bus/slack-provider.ts +76 -0
  312. package/src/{notifications → sdk/bus}/telegram-cli.ts +8 -8
  313. package/src/sdk/bus/telegram-daemon-cli.ts +330 -0
  314. package/src/sdk/bus/telegram-daemon-contract.ts +14 -0
  315. package/src/{notifications → sdk/bus}/telegram-daemon-control.ts +4 -4
  316. package/src/{notifications → sdk/bus}/telegram-daemon.ts +502 -54
  317. package/src/{notifications → sdk/bus}/telegram-reference.ts +2 -2
  318. package/src/sdk/bus/telegram-setup.ts +663 -0
  319. package/src/{notifications → sdk/bus}/topic-registry.ts +32 -0
  320. package/src/sdk/cli/index.ts +1 -0
  321. package/src/sdk/cli/session-cli.ts +275 -0
  322. package/src/sdk/client/client.ts +1 -0
  323. package/src/sdk/client/discovery.ts +108 -0
  324. package/src/sdk/client/index.ts +2 -0
  325. package/src/sdk/host/control/dispatch.ts +367 -0
  326. package/src/sdk/host/control/index.ts +10 -0
  327. package/src/sdk/host/control/operations.ts +63 -0
  328. package/src/sdk/host/events.ts +91 -0
  329. package/src/sdk/host/host.ts +296 -0
  330. package/src/sdk/host/index.ts +4 -0
  331. package/src/sdk/host/query/cursor.ts +189 -0
  332. package/src/sdk/host/query/handlers.ts +533 -0
  333. package/src/sdk/host/query/index.ts +3 -0
  334. package/src/sdk/host/query/revision-store.ts +1126 -0
  335. package/src/sdk/host/reverse-leases.ts +325 -0
  336. package/src/sdk/host/types.ts +29 -0
  337. package/src/sdk/index.ts +13 -0
  338. package/src/sdk/lifecycle-session.ts +39 -0
  339. package/src/sdk/mcp/index.ts +1 -0
  340. package/src/sdk/mcp/server.ts +332 -0
  341. package/src/sdk/models.ts +168 -0
  342. package/src/sdk/protocol/adapter-validation.ts +48 -0
  343. package/src/sdk/protocol/operation-inventory.generated.json +5654 -0
  344. package/src/sdk/protocol/operation-registry.ts +312 -0
  345. package/src/{sdk.ts → sdk/session.ts} +339 -212
  346. package/src/sdk/startup-capability.ts +189 -0
  347. package/src/session/agent-session.ts +2453 -894
  348. package/src/session/default-model-selection.ts +93 -0
  349. package/src/session/fallback-chain-controller.ts +136 -0
  350. package/src/session/session-manager.ts +438 -11
  351. package/src/session/session-storage.ts +8 -1
  352. package/src/setup/credential-auto-import.ts +290 -35
  353. package/src/setup/hermes/templates/operator-instructions.v1.md +3 -5
  354. package/src/slash-commands/builtin-registry.ts +2 -1
  355. package/src/task/executor.ts +62 -13
  356. package/src/tools/ask-answer-registry.ts +1 -1
  357. package/src/tools/ask.ts +13 -8
  358. package/src/tools/browser/STEALTH-THIRD-PARTY-NOTICES.md +26 -0
  359. package/src/tools/browser/benchmark/detector-report.ts +157 -0
  360. package/src/tools/browser/benchmark/run-suite.ts +39 -0
  361. package/src/tools/browser/launch.ts +124 -19
  362. package/src/tools/browser/profile-discovery.ts +63 -0
  363. package/src/tools/browser/profile-posture.ts +59 -0
  364. package/src/tools/browser/profile-reuse.ts +102 -0
  365. package/src/tools/browser/profile-warmup.ts +109 -0
  366. package/src/tools/browser/registry.ts +87 -11
  367. package/src/tools/browser/tab-protocol.ts +1 -0
  368. package/src/tools/browser/tab-supervisor.ts +1 -0
  369. package/src/tools/browser/tab-worker.ts +1 -1
  370. package/src/tools/browser.ts +6 -0
  371. package/src/tools/index.ts +8 -8
  372. package/src/tools/puppeteer/14_stealth_permissions.txt +57 -0
  373. package/src/tools/puppeteer/15_stealth_webrtc.txt +60 -0
  374. package/src/tools/telegram-send.ts +2 -2
  375. package/vendor/insane-search/MANIFEST.json +2 -1
  376. package/vendor/insane-search/engine/bias_check.py +4 -1
  377. package/vendor/insane-search/engine/phase0.py +26 -1
  378. package/dist/types/harness-control-plane/rpc-adapter.d.ts +0 -69
  379. package/dist/types/modes/bridge/auth.d.ts +0 -12
  380. package/dist/types/modes/bridge/bridge-client-bridge.d.ts +0 -9
  381. package/dist/types/modes/bridge/bridge-mode.d.ts +0 -47
  382. package/dist/types/modes/bridge/bridge-ui-context.d.ts +0 -88
  383. package/dist/types/modes/bridge/event-stream.d.ts +0 -8
  384. package/dist/types/modes/rpc/host-tools.d.ts +0 -1
  385. package/dist/types/modes/rpc/host-uris.d.ts +0 -1
  386. package/dist/types/modes/rpc/rpc-client.d.ts +0 -299
  387. package/dist/types/modes/rpc/rpc-mode.d.ts +0 -86
  388. package/dist/types/modes/rpc/rpc-socket-security.d.ts +0 -10
  389. package/dist/types/modes/rpc/rpc-types.d.ts +0 -810
  390. package/dist/types/modes/shared/agent-wire/command-contract.d.ts +0 -18
  391. package/dist/types/modes/shared/agent-wire/command-dispatch.d.ts +0 -37
  392. package/dist/types/modes/shared/agent-wire/command-validation.d.ts +0 -2
  393. package/dist/types/modes/shared/agent-wire/handshake.d.ts +0 -56
  394. package/dist/types/modes/shared/agent-wire/host-tool-bridge.d.ts +0 -16
  395. package/dist/types/modes/shared/agent-wire/host-uri-bridge.d.ts +0 -17
  396. package/dist/types/modes/shared/agent-wire/protocol.d.ts +0 -25
  397. package/dist/types/modes/shared/agent-wire/responses.d.ts +0 -4
  398. package/dist/types/modes/shared/agent-wire/scopes.d.ts +0 -18
  399. package/dist/types/modes/shared/agent-wire/session-registry.d.ts +0 -25
  400. package/dist/types/modes/shared/agent-wire/ui-request-broker.d.ts +0 -42
  401. package/dist/types/modes/shared/agent-wire/ui-result.d.ts +0 -27
  402. package/dist/types/modes/shared/agent-wire/unattended-action-policy.d.ts +0 -29
  403. package/dist/types/modes/shared/agent-wire/unattended-audit.d.ts +0 -68
  404. package/dist/types/modes/shared/agent-wire/unattended-run-controller.d.ts +0 -166
  405. package/dist/types/modes/shared/agent-wire/unattended-session.d.ts +0 -127
  406. package/dist/types/notifications/config.d.ts +0 -132
  407. package/src/harness-control-plane/rpc-adapter.ts +0 -290
  408. package/src/modes/bridge/auth.ts +0 -41
  409. package/src/modes/bridge/bridge-client-bridge.ts +0 -47
  410. package/src/modes/bridge/bridge-mode.ts +0 -675
  411. package/src/modes/bridge/bridge-ui-context.ts +0 -200
  412. package/src/modes/bridge/event-stream.ts +0 -70
  413. package/src/modes/rpc/host-tools.ts +0 -1
  414. package/src/modes/rpc/host-uris.ts +0 -1
  415. package/src/modes/rpc/rpc-client.ts +0 -1166
  416. package/src/modes/rpc/rpc-mode.ts +0 -1029
  417. package/src/modes/rpc/rpc-socket-security.ts +0 -115
  418. package/src/modes/rpc/rpc-types.ts +0 -637
  419. package/src/modes/shared/agent-wire/command-contract.ts +0 -18
  420. package/src/modes/shared/agent-wire/command-dispatch.ts +0 -498
  421. package/src/modes/shared/agent-wire/command-validation.ts +0 -181
  422. package/src/modes/shared/agent-wire/handshake.ts +0 -157
  423. package/src/modes/shared/agent-wire/host-tool-bridge.ts +0 -197
  424. package/src/modes/shared/agent-wire/host-uri-bridge.ts +0 -236
  425. package/src/modes/shared/agent-wire/protocol.ts +0 -46
  426. package/src/modes/shared/agent-wire/responses.ts +0 -17
  427. package/src/modes/shared/agent-wire/scopes.ts +0 -94
  428. package/src/modes/shared/agent-wire/session-registry.ts +0 -109
  429. package/src/modes/shared/agent-wire/ui-request-broker.ts +0 -150
  430. package/src/modes/shared/agent-wire/ui-result.ts +0 -48
  431. package/src/modes/shared/agent-wire/unattended-action-policy.ts +0 -365
  432. package/src/modes/shared/agent-wire/unattended-audit.ts +0 -176
  433. package/src/modes/shared/agent-wire/unattended-run-controller.ts +0 -426
  434. package/src/modes/shared/agent-wire/unattended-session.ts +0 -528
  435. package/src/notifications/config.ts +0 -219
  436. package/src/notifications/index.ts +0 -1835
  437. package/src/notifications/telegram-daemon-cli.ts +0 -243
  438. package/src/tools/puppeteer/09_stealth_locale.txt +0 -46
  439. /package/dist/types/{notifications → sdk/bus}/attachment-registry.d.ts +0 -0
  440. /package/dist/types/{notifications → sdk/bus}/chat-adapters.d.ts +0 -0
  441. /package/dist/types/{notifications → sdk/bus}/daemon-paths.d.ts +0 -0
  442. /package/dist/types/{notifications → sdk/bus}/engine.d.ts +0 -0
  443. /package/dist/types/{notifications → sdk/bus}/helpers.d.ts +0 -0
  444. /package/dist/types/{notifications → sdk/bus}/lifecycle-commands.d.ts +0 -0
  445. /package/dist/types/{notifications → sdk/bus}/operator-runtime.d.ts +0 -0
  446. /package/dist/types/{notifications → sdk/bus}/rate-limit-pool.d.ts +0 -0
  447. /package/dist/types/{notifications → sdk/bus}/recent-activity.d.ts +0 -0
  448. /package/dist/types/{notifications → sdk/bus}/reply-sent-store.d.ts +0 -0
  449. /package/dist/types/{notifications → sdk/bus}/rich-draft.d.ts +0 -0
  450. /package/dist/types/{notifications → sdk/bus}/rich-render.d.ts +0 -0
  451. /package/dist/types/{notifications → sdk/bus}/threaded-inbound.d.ts +0 -0
  452. /package/dist/types/{notifications → sdk/bus}/threaded-render.d.ts +0 -0
  453. /package/src/{notifications → sdk/bus}/attachment-registry.ts +0 -0
  454. /package/src/{notifications → sdk/bus}/chat-adapters.ts +0 -0
  455. /package/src/{notifications → sdk/bus}/daemon-paths.ts +0 -0
  456. /package/src/{notifications → sdk/bus}/engine.ts +0 -0
  457. /package/src/{notifications → sdk/bus}/helpers.ts +0 -0
  458. /package/src/{notifications → sdk/bus}/operator-runtime.ts +0 -0
  459. /package/src/{notifications → sdk/bus}/rate-limit-pool.ts +0 -0
  460. /package/src/{notifications → sdk/bus}/recent-activity.ts +0 -0
  461. /package/src/{notifications → sdk/bus}/reply-sent-store.ts +0 -0
  462. /package/src/{notifications → sdk/bus}/rich-draft.ts +0 -0
  463. /package/src/{notifications → sdk/bus}/rich-render.ts +0 -0
  464. /package/src/{notifications → sdk/bus}/threaded-inbound.ts +0 -0
  465. /package/src/{notifications → sdk/bus}/threaded-render.ts +0 -0
@@ -9,7 +9,7 @@ import * as url from "node:url";
9
9
  import type { TSchema } from "@gajae-code/ai";
10
10
  import { logger } from "@gajae-code/utils";
11
11
  import type { SourceMeta } from "../capability/types";
12
- import { resolveConfigValue } from "../config/resolve-config-value";
12
+ import * as configValue from "../config/resolve-config-value";
13
13
  import type { CustomTool } from "../extensibility/custom-tools/types";
14
14
  import type { AuthStorage } from "../session/auth-storage";
15
15
  import {
@@ -43,7 +43,7 @@ import type {
43
43
  MCPServerConnection,
44
44
  MCPToolDefinition,
45
45
  } from "./types";
46
- import { MCPNotificationMethods } from "./types";
46
+ import { MCPExpectedFailure, MCPNotificationMethods } from "./types";
47
47
 
48
48
  type ToolLoadResult = {
49
49
  connection: MCPServerConnection;
@@ -56,6 +56,16 @@ type TrackedPromise<T> = {
56
56
  value?: T;
57
57
  reason?: unknown;
58
58
  };
59
+ type ConnectionTask = {
60
+ name: string;
61
+ config: MCPServerConfig;
62
+ tracked: TrackedPromise<ToolLoadResult>;
63
+ connectionPromise: Promise<MCPServerConnection>;
64
+ toolsPromise: Promise<ToolLoadResult>;
65
+ connectionAbort: AbortController;
66
+ connectionEpoch: number;
67
+ disconnectEpoch: number;
68
+ };
59
69
 
60
70
  const STARTUP_TIMEOUT_MS = 250;
61
71
  const STARTUP_TIMEOUT_GRACE_MS = 500;
@@ -86,6 +96,24 @@ function trackPromise<T>(promise: Promise<T>): TrackedPromise<T> {
86
96
  );
87
97
  return tracked;
88
98
  }
99
+ const EXPECTED_CONFIG_RESOLUTION_CODES = new Set([
100
+ "EACCES",
101
+ "EISDIR",
102
+ "ELOOP",
103
+ "ENAMETOOLONG",
104
+ "ENOENT",
105
+ "ENOTDIR",
106
+ "EPERM",
107
+ "ESTALE",
108
+ ]);
109
+
110
+ function isExpectedConfigResolutionFailure(error: unknown): boolean {
111
+ if (error instanceof DOMException && error.name === "AbortError") return true;
112
+ if (!(error instanceof Error)) return false;
113
+ if (error.name === "AbortError") return true;
114
+ const code = "code" in error && typeof error.code === "string" ? error.code : undefined;
115
+ return code !== undefined && EXPECTED_CONFIG_RESOLUTION_CODES.has(code);
116
+ }
89
117
 
90
118
  function delay(ms: number, signal?: AbortSignal): Promise<void> {
91
119
  if (!signal) return Bun.sleep(ms);
@@ -151,6 +179,13 @@ export interface MCPDiscoverOptions {
151
179
  autoloadOnly?: boolean;
152
180
  /** Called when starting to connect to servers */
153
181
  onConnecting?: (serverNames: string[]) => void;
182
+ /** Load only this explicit MCP config file. */
183
+ configPath?: string;
184
+ }
185
+
186
+ export interface MCPManagerOptions {
187
+ /** Restrict this instance to tools from an explicit MCP config. */
188
+ toolsOnly?: boolean;
154
189
  }
155
190
 
156
191
  /**
@@ -198,6 +233,15 @@ export class MCPManager {
198
233
  #serverConfigs = new Map<string, MCPServerConfig>();
199
234
  /** Monotonic epoch incremented on disconnectAll to invalidate stale reconnections. */
200
235
  #epoch = 0;
236
+ readonly #toolsOnly: boolean;
237
+ #toolsOnlyConfigLoaded = false;
238
+
239
+ #serverError(message: string): string {
240
+ return this.#toolsOnly ? "MCP server unavailable" : message;
241
+ }
242
+ #assertRawMCPAccessAllowed(): void {
243
+ if (this.#toolsOnly) throw new Error("Tools-only MCP manager does not allow raw MCP access");
244
+ }
201
245
 
202
246
  #isCurrentConnection(
203
247
  name: string,
@@ -217,12 +261,20 @@ export class MCPManager {
217
261
  constructor(
218
262
  private cwd: string,
219
263
  private toolCache: MCPToolCache | null = null,
220
- ) {}
264
+ options: MCPManagerOptions = {},
265
+ ) {
266
+ this.#toolsOnly = options.toolsOnly === true;
267
+ }
268
+
269
+ isToolsOnly(): boolean {
270
+ return this.#toolsOnly;
271
+ }
221
272
 
222
273
  /**
223
274
  * Set a callback to receive all server notifications.
224
275
  */
225
276
  setOnNotification(handler: (serverName: string, method: string, params: unknown) => void): void {
277
+ if (this.#toolsOnly) return;
226
278
  this.#onNotification = handler;
227
279
  }
228
280
 
@@ -230,6 +282,7 @@ export class MCPManager {
230
282
  * Set a callback to fire when any server's tools change.
231
283
  */
232
284
  setOnToolsChanged(handler: (tools: CustomTool<TSchema, MCPToolDetails>[]) => void): void {
285
+ if (this.#toolsOnly) return;
233
286
  this.#onToolsChanged = handler;
234
287
  }
235
288
 
@@ -237,6 +290,7 @@ export class MCPManager {
237
290
  * Set a callback to fire when any server's resources change.
238
291
  */
239
292
  setOnResourcesChanged(handler: (serverName: string, uri: string) => void): void {
293
+ if (this.#toolsOnly) return;
240
294
  this.#onResourcesChanged = handler;
241
295
  }
242
296
 
@@ -244,6 +298,7 @@ export class MCPManager {
244
298
  * Set a callback to fire when any server's prompts change.
245
299
  */
246
300
  setOnPromptsChanged(handler: (serverName: string) => void): void {
301
+ if (this.#toolsOnly) return;
247
302
  this.#onPromptsChanged = handler;
248
303
  // Fire immediately for servers that already have prompts loaded
249
304
  for (const [name, connection] of this.#connections) {
@@ -281,6 +336,7 @@ export class MCPManager {
281
336
  }
282
337
 
283
338
  setNotificationsEnabled(enabled: boolean): void {
339
+ if (this.#toolsOnly) return;
284
340
  const wasEnabled = this.#notificationsEnabled;
285
341
  this.#notificationsEnabled = enabled;
286
342
  if (enabled === wasEnabled) return;
@@ -323,13 +379,27 @@ export class MCPManager {
323
379
  * Returns tools and any connection errors.
324
380
  */
325
381
  async discoverAndConnect(options?: MCPDiscoverOptions): Promise<MCPLoadResult> {
326
- const { configs, exaApiKeys, sources } = await loadAllMCPConfigs(this.cwd, {
382
+ const hasConfigPath = options?.configPath !== undefined;
383
+ if (this.#toolsOnly !== hasConfigPath) {
384
+ throw new Error(
385
+ this.#toolsOnly
386
+ ? "Tools-only MCP manager requires an explicit config path"
387
+ : "Explicit MCP config requires a tools-only MCP manager",
388
+ );
389
+ }
390
+ if (this.#toolsOnly && this.#toolsOnlyConfigLoaded) {
391
+ throw new Error("Tools-only MCP manager already loaded an explicit config");
392
+ }
393
+ if (this.#toolsOnly) this.#toolsOnlyConfigLoaded = true;
394
+ const { configs, exaApiKeys, sources, configurationWarning } = await loadAllMCPConfigs(this.cwd, {
327
395
  enableProjectConfig: options?.enableProjectConfig,
328
396
  filterExa: options?.filterExa,
329
397
  filterBrowser: options?.filterBrowser,
330
398
  autoloadOnly: options?.autoloadOnly,
399
+ configPath: options?.configPath,
331
400
  });
332
- const result = await this.connectServers(configs, sources, options?.onConnecting);
401
+ const result = await this.#connectServers(configs, sources, options?.onConnecting);
402
+ if (configurationWarning) result.errors.set("$config", "MCP configuration unavailable");
333
403
  result.exaApiKeys = exaApiKeys;
334
404
  return result;
335
405
  }
@@ -343,16 +413,15 @@ export class MCPManager {
343
413
  sources: Record<string, SourceMeta>,
344
414
  onConnecting?: (serverNames: string[]) => void,
345
415
  ): Promise<MCPLoadResult> {
346
- type ConnectionTask = {
347
- name: string;
348
- config: MCPServerConfig;
349
- tracked: TrackedPromise<ToolLoadResult>;
350
- toolsPromise: Promise<ToolLoadResult>;
351
- connectionAbort: AbortController;
352
- connectionEpoch: number;
353
- disconnectEpoch: number;
354
- };
416
+ this.#assertRawMCPAccessAllowed();
417
+ return this.#connectServers(configs, sources, onConnecting);
418
+ }
355
419
 
420
+ async #connectServers(
421
+ configs: Record<string, MCPServerConfig>,
422
+ sources: Record<string, SourceMeta>,
423
+ onConnecting?: (serverNames: string[]) => void,
424
+ ): Promise<MCPLoadResult> {
356
425
  const errors = new Map<string, string>();
357
426
  const connectedServers = new Set<string>();
358
427
  const allTools: CustomTool<TSchema, MCPToolDetails>[] = [];
@@ -372,9 +441,14 @@ export class MCPManager {
372
441
  }
373
442
  }
374
443
 
375
- // Skip if already connected
444
+ // Skip if already connected.
376
445
  if (this.#connections.has(name)) {
377
446
  connectedServers.add(name);
447
+ allTools.push(
448
+ ...this.#tools.filter(
449
+ tool => (tool instanceof MCPTool || tool instanceof DeferredMCPTool) && tool.mcpServerName === name,
450
+ ),
451
+ );
378
452
  continue;
379
453
  }
380
454
 
@@ -389,7 +463,7 @@ export class MCPManager {
389
463
  // Validate config
390
464
  const validationErrors = validateServerConfig(name, config);
391
465
  if (validationErrors.length > 0) {
392
- errors.set(name, validationErrors.join("; "));
466
+ errors.set(name, this.#serverError(validationErrors.join("; ")));
393
467
  reportedErrors.add(name);
394
468
  continue;
395
469
  }
@@ -406,10 +480,13 @@ export class MCPManager {
406
480
  const connectionPromise = (async () => {
407
481
  const resolvedConfig = await this.#resolveAuthConfig(config);
408
482
  return connectToServer(name, resolvedConfig, {
483
+ advertiseRoots: !this.#toolsOnly,
409
484
  signal: connectionAbort.signal,
410
- onNotification: (method, params) => {
411
- this.#handleServerNotification(name, method, params);
412
- },
485
+ onNotification: this.#toolsOnly
486
+ ? undefined
487
+ : (method, params) => {
488
+ this.#handleServerNotification(name, method, params);
489
+ },
413
490
  onRequest: (method, params) => {
414
491
  return this.#handleServerRequest(method, params);
415
492
  },
@@ -426,7 +503,8 @@ export class MCPManager {
426
503
  const stillCurrent =
427
504
  this.#epoch === connectionEpoch &&
428
505
  (this.#disconnectEpochs.get(name) ?? 0) === disconnectEpoch &&
429
- this.#serverConfigs.get(name) === config;
506
+ this.#serverConfigs.get(name) === config &&
507
+ !connectionAbort.signal.aborted;
430
508
  if (stillPending) {
431
509
  this.#pendingConnections.delete(name);
432
510
  this.#pendingConnectionControllers.delete(name);
@@ -450,12 +528,14 @@ export class MCPManager {
450
528
  };
451
529
  }
452
530
 
453
- // Re-establish connection if the transport closes (server restart,
454
- // network interruption).
455
- connection.transport.onClose = () => {
456
- logger.debug("MCP transport lost, triggering reconnect", { path: `mcp:${name}` });
457
- void this.reconnectServer(name);
458
- };
531
+ if (!this.#toolsOnly) {
532
+ // Re-establish connection if the transport closes (server restart,
533
+ // network interruption).
534
+ connection.transport.onClose = () => {
535
+ logger.debug("MCP transport lost, triggering reconnect", { path: `mcp:${name}` });
536
+ void this.reconnectServer(name);
537
+ };
538
+ }
459
539
 
460
540
  return connection;
461
541
  },
@@ -476,10 +556,13 @@ export class MCPManager {
476
556
  } catch (error) {
477
557
  connection.transport.onClose = undefined;
478
558
  if (this.#connections.get(name) === connection) this.#connections.delete(name);
479
- void connection.transport.close().catch(() => {});
559
+ await connection.transport.close().catch(() => {});
480
560
  throw error;
481
561
  }
482
- if (!this.#isCurrentConnection(name, config, connectionEpoch, disconnectEpoch, connection)) {
562
+ if (
563
+ connectionAbort.signal.aborted ||
564
+ !this.#isCurrentConnection(name, config, connectionEpoch, disconnectEpoch, connection)
565
+ ) {
483
566
  connection.transport.onClose = undefined;
484
567
  await connection.transport.close().catch(() => {});
485
568
  throw new Error(`Server "${name}" was disconnected during tool loading`);
@@ -493,6 +576,7 @@ export class MCPManager {
493
576
  name,
494
577
  config,
495
578
  tracked,
579
+ connectionPromise,
496
580
  toolsPromise,
497
581
  connectionAbort,
498
582
  connectionEpoch,
@@ -501,20 +585,25 @@ export class MCPManager {
501
585
 
502
586
  void toolsPromise
503
587
  .then(async ({ connection, serverTools }) => {
588
+ if (connectionAbort.signal.aborted) return;
504
589
  if (this.#pendingToolLoads.get(name) !== toolsPromise) return;
505
- if (!this.#isCurrentConnection(name, config, connectionEpoch, disconnectEpoch, connection)) return;
590
+ if (
591
+ connectionAbort.signal.aborted ||
592
+ !this.#isCurrentConnection(name, config, connectionEpoch, disconnectEpoch, connection)
593
+ )
594
+ return;
506
595
  this.#pendingToolLoads.delete(name);
507
- const reconnect = () => this.reconnectServer(name);
596
+ const reconnect = this.#toolsOnly ? undefined : () => this.reconnectServer(name);
508
597
  const customTools = MCPTool.fromTools(connection, serverTools, reconnect);
509
598
  this.#replaceServerTools(name, customTools);
510
- this.#onToolsChanged?.(this.#tools);
511
- void this.toolCache?.set(name, config, serverTools);
512
- await this.#loadServerResourcesAndPrompts(name, connection);
599
+ if (!this.#toolsOnly) this.#onToolsChanged?.(this.#tools);
600
+ if (!this.#toolsOnly) void this.toolCache?.set(name, config, serverTools);
601
+ if (!this.#toolsOnly) await this.#loadServerResourcesAndPrompts(name, connection);
513
602
  })
514
603
  .catch(error => {
515
604
  if (this.#pendingToolLoads.get(name) !== toolsPromise) return;
516
605
  this.#pendingToolLoads.delete(name);
517
- if (!allowBackgroundLogging || reportedErrors.has(name)) return;
606
+ if (!allowBackgroundLogging || reportedErrors.has(name) || this.#toolsOnly) return;
518
607
  const message = error instanceof Error ? error.message : String(error);
519
608
  logger.error("MCP tool load failed", { path: `mcp:${name}`, error: message });
520
609
  });
@@ -522,21 +611,47 @@ export class MCPManager {
522
611
 
523
612
  // Notify about servers we're connecting to
524
613
  if (connectionTasks.length > 0 && onConnecting) {
525
- onConnecting(connectionTasks.map(task => task.name));
614
+ try {
615
+ onConnecting(connectionTasks.map(task => task.name));
616
+ } catch (error) {
617
+ await this.#cleanupConnectionTasks(connectionTasks);
618
+ throw error;
619
+ }
526
620
  }
527
621
 
528
622
  if (connectionTasks.length > 0) {
529
623
  const startupTimeoutMs = resolveStartupTimeoutMs(connectionTasks.map(task => task.config));
530
- await Promise.race([
531
- Promise.allSettled(connectionTasks.map(task => task.tracked.promise)),
532
- delay(startupTimeoutMs),
624
+ const firstUnexpectedFailure = Promise.withResolvers<{ reason: unknown }>();
625
+ if (this.#toolsOnly) {
626
+ for (const task of connectionTasks) {
627
+ void task.toolsPromise.catch(reason => {
628
+ if (!(reason instanceof MCPExpectedFailure)) firstUnexpectedFailure.resolve({ reason });
629
+ });
630
+ }
631
+ }
632
+ const startupOutcome = await Promise.race([
633
+ Promise.allSettled(connectionTasks.map(task => task.tracked.promise)).then(() => undefined),
634
+ delay(startupTimeoutMs).then(() => undefined),
635
+ firstUnexpectedFailure.promise,
533
636
  ]);
637
+ const unexpectedTask = connectionTasks.find(
638
+ task =>
639
+ task.tracked.status === "rejected" &&
640
+ this.#toolsOnly &&
641
+ !(task.tracked.reason instanceof MCPExpectedFailure),
642
+ );
643
+ const unexpectedFailure =
644
+ startupOutcome ?? (unexpectedTask ? { reason: unexpectedTask.tracked.reason } : undefined);
645
+ if (unexpectedFailure) {
646
+ await this.#cleanupConnectionTasks(connectionTasks);
647
+ throw unexpectedFailure.reason;
648
+ }
534
649
 
535
650
  const cachedTools = new Map<string, MCPToolDefinition[]>();
536
651
  const pendingTasks = connectionTasks.filter(task => task.tracked.status === "pending");
537
652
 
538
653
  if (pendingTasks.length > 0) {
539
- if (this.toolCache) {
654
+ if (this.toolCache && !this.#toolsOnly) {
540
655
  await Promise.all(
541
656
  pendingTasks.map(async task => {
542
657
  const cached = await this.toolCache?.get(task.name, task.config);
@@ -551,17 +666,18 @@ export class MCPManager {
551
666
  if (pendingWithoutCache.length > 0) {
552
667
  for (const task of pendingWithoutCache) {
553
668
  const message = `MCP server connection timed out during startup: ${task.name}`;
554
- errors.set(task.name, message);
669
+ errors.set(task.name, this.#serverError(message));
555
670
  reportedErrors.add(task.name);
556
671
  task.connectionAbort.abort(new Error(message));
557
672
  if (this.#pendingConnections.has(task.name)) this.#pendingConnections.delete(task.name);
558
673
  if (this.#pendingToolLoads.get(task.name) === task.toolsPromise)
559
674
  this.#pendingToolLoads.delete(task.name);
560
675
  this.#pendingConnectionControllers.delete(task.name);
676
+ void this.#disconnectServer(task.name).catch(() => {});
561
677
  }
562
- // Do not await these promises here: a misbehaving stdio/MCP transport can ignore
563
- // AbortSignal and keep startup blocked indefinitely. The background toolsPromise
564
- // handler will clean up if it eventually settles.
678
+ // Abort and disconnect in the background: a misbehaving stdio/MCP transport can
679
+ // ignore AbortSignal and keep startup blocked indefinitely, but it must not remain
680
+ // registered if it eventually connects.
565
681
  }
566
682
  }
567
683
 
@@ -579,13 +695,21 @@ export class MCPManager {
579
695
  continue;
580
696
  }
581
697
  connectedServers.add(name);
582
- const reconnect = () => this.reconnectServer(name);
583
- allTools.push(...MCPTool.fromTools(connection, serverTools, reconnect));
698
+ const reconnect = this.#toolsOnly ? undefined : () => this.reconnectServer(name);
699
+ try {
700
+ allTools.push(...MCPTool.fromTools(connection, serverTools, reconnect));
701
+ } catch (error) {
702
+ await this.#cleanupConnectionTasks(connectionTasks);
703
+ throw error;
704
+ }
584
705
  } else if (task.tracked.status === "rejected") {
585
- const message =
586
- task.tracked.reason instanceof Error ? task.tracked.reason.message : String(task.tracked.reason);
587
- errors.set(name, message);
706
+ const reason = task.tracked.reason;
707
+ const message = reason instanceof Error ? reason.message : String(reason);
708
+ errors.set(name, this.#serverError(message));
588
709
  reportedErrors.add(name);
710
+ if (this.#toolsOnly && reason instanceof MCPExpectedFailure) {
711
+ await this.#disconnectServer(name);
712
+ }
589
713
  if ((this.#disconnectEpochs.get(name) ?? 0) !== task.disconnectEpoch) {
590
714
  shouldPublishToolSnapshot = false;
591
715
  }
@@ -593,10 +717,21 @@ export class MCPManager {
593
717
  const cached = cachedTools.get(name);
594
718
  if (cached) {
595
719
  const source = this.#sources.get(name);
596
- const reconnect = () => this.reconnectServer(name);
597
- allTools.push(
598
- ...DeferredMCPTool.fromTools(name, cached, () => this.waitForConnection(name), source, reconnect),
599
- );
720
+ const reconnect = this.#toolsOnly ? undefined : () => this.reconnectServer(name);
721
+ try {
722
+ allTools.push(
723
+ ...DeferredMCPTool.fromTools(
724
+ name,
725
+ cached,
726
+ () => this.#waitForConnection(name),
727
+ source,
728
+ reconnect,
729
+ ),
730
+ );
731
+ } catch (error) {
732
+ await this.#cleanupConnectionTasks(connectionTasks);
733
+ throw error;
734
+ }
600
735
  }
601
736
  }
602
737
  }
@@ -605,13 +740,17 @@ export class MCPManager {
605
740
  // Stable sort by name so the order is independent of connection completion.
606
741
  // See `sortMCPToolsByName` for the cache-stability rationale.
607
742
  sortMCPToolsByName(allTools);
743
+ if (this.#toolsOnly && new Set(allTools.map(tool => tool.name)).size !== allTools.length) {
744
+ await this.#cleanupConnectionTasks(connectionTasks);
745
+ throw new Error("MCP tool catalog contains duplicate tool names");
746
+ }
608
747
 
609
748
  // Update cached tools
610
749
  if (shouldPublishToolSnapshot) this.#tools = allTools;
611
750
  allowBackgroundLogging = true;
612
751
 
613
752
  return {
614
- tools: allTools,
753
+ tools: [...allTools],
615
754
  errors,
616
755
  connectedServers: Array.from(connectedServers),
617
756
  exaApiKeys: [], // Will be populated by discoverAndConnect
@@ -619,7 +758,9 @@ export class MCPManager {
619
758
  }
620
759
 
621
760
  #replaceServerTools(name: string, tools: CustomTool<TSchema, MCPToolDetails>[]): void {
622
- this.#tools = this.#tools.filter(t => !t.name.startsWith(`mcp__${name}_`));
761
+ this.#tools = this.#tools.filter(
762
+ tool => !((tool instanceof MCPTool || tool instanceof DeferredMCPTool) && tool.mcpServerName === name),
763
+ );
623
764
  this.#tools.push(...tools);
624
765
  // Stable sort by name so reconnect order does not perturb the array.
625
766
  // See `sortMCPToolsByName` for the cache-stability rationale.
@@ -671,6 +812,9 @@ export class MCPManager {
671
812
 
672
813
  /** Handle server-to-client JSON-RPC requests (e.g. ping, roots/list). */
673
814
  async #handleServerRequest(method: string, _params: unknown): Promise<unknown> {
815
+ if (this.#toolsOnly && method !== "ping") {
816
+ throw Object.assign(new Error(`Unsupported server request: ${method}`), { code: -32601 });
817
+ }
674
818
  switch (method) {
675
819
  case "ping":
676
820
  return {};
@@ -696,13 +840,14 @@ export class MCPManager {
696
840
  * Get all loaded tools.
697
841
  */
698
842
  getTools(): CustomTool<TSchema, MCPToolDetails>[] {
699
- return this.#tools;
843
+ return [...this.#tools];
700
844
  }
701
845
 
702
846
  /**
703
847
  * Get a specific connection.
704
848
  */
705
849
  getConnection(name: string): MCPServerConnection | undefined {
850
+ this.#assertRawMCPAccessAllowed();
706
851
  return this.#connections.get(name);
707
852
  }
708
853
 
@@ -731,6 +876,11 @@ export class MCPManager {
731
876
  * Wait for a connection to complete (or fail).
732
877
  */
733
878
  async waitForConnection(name: string): Promise<MCPServerConnection> {
879
+ this.#assertRawMCPAccessAllowed();
880
+ return this.#waitForConnection(name);
881
+ }
882
+
883
+ async #waitForConnection(name: string): Promise<MCPServerConnection> {
734
884
  const connection = this.#connections.get(name);
735
885
  if (connection) return connection;
736
886
  const pending = this.#pendingConnections.get(name);
@@ -748,6 +898,7 @@ export class MCPManager {
748
898
  * Resolve auth and shell-command substitutions in config before connecting.
749
899
  */
750
900
  async prepareConfig(config: MCPServerConfig): Promise<MCPServerConfig> {
901
+ this.#assertRawMCPAccessAllowed();
751
902
  return this.#resolveAuthConfig(config);
752
903
  }
753
904
 
@@ -771,6 +922,11 @@ export class MCPManager {
771
922
  * Disconnect from a specific server.
772
923
  */
773
924
  async disconnectServer(name: string): Promise<void> {
925
+ this.#assertRawMCPAccessAllowed();
926
+ await this.#disconnectServer(name);
927
+ }
928
+
929
+ async #disconnectServer(name: string): Promise<void> {
774
930
  const nextEpoch = (this.#disconnectEpochs.get(name) ?? 0) + 1;
775
931
  this.#disconnectEpochs.set(name, nextEpoch);
776
932
  this.#pendingConnectionControllers.get(name)?.abort(new Error(`MCP server disconnected: ${name}`));
@@ -791,20 +947,66 @@ export class MCPManager {
791
947
  }
792
948
  this.#subscribedResources.delete(name);
793
949
 
950
+ let closeError: unknown;
794
951
  if (connection) {
795
952
  // Detach onClose to prevent spurious reconnect from close()
796
953
  connection.transport.onClose = undefined;
797
- await disconnectServer(connection);
798
- this.#connections.delete(name);
954
+ try {
955
+ await disconnectServer(connection);
956
+ } catch (error) {
957
+ closeError = error;
958
+ }
959
+ if (this.#connections.get(name) === connection) this.#connections.delete(name);
799
960
  }
800
961
 
801
962
  // Remove tools from this server and notify consumers
802
- const hadTools = this.#tools.some(t => t.name.startsWith(`mcp__${name}_`));
803
- this.#tools = this.#tools.filter(t => !t.name.startsWith(`mcp__${name}_`));
963
+ const hadTools = this.#tools.some(
964
+ tool => (tool instanceof MCPTool || tool instanceof DeferredMCPTool) && tool.mcpServerName === name,
965
+ );
966
+ this.#tools = this.#tools.filter(
967
+ tool => !((tool instanceof MCPTool || tool instanceof DeferredMCPTool) && tool.mcpServerName === name),
968
+ );
804
969
  if (hadTools) this.#onToolsChanged?.(this.#tools);
805
970
 
806
971
  // Notify prompt consumers so stale commands are cleared
807
972
  if (connection?.prompts?.length) this.#onPromptsChanged?.(name);
973
+ if (closeError) throw closeError;
974
+ }
975
+
976
+ #abortConnectionTask(task: ConnectionTask): void {
977
+ task.connectionAbort.abort(new Error(`MCP server startup aborted: ${task.name}`));
978
+ if (this.#pendingConnectionControllers.get(task.name) === task.connectionAbort) {
979
+ this.#pendingConnectionControllers.delete(task.name);
980
+ }
981
+ if (this.#pendingConnections.get(task.name) === task.connectionPromise) {
982
+ this.#pendingConnections.delete(task.name);
983
+ }
984
+ if (this.#pendingToolLoads.get(task.name) === task.toolsPromise) {
985
+ this.#pendingToolLoads.delete(task.name);
986
+ }
987
+ if ((this.#disconnectEpochs.get(task.name) ?? 0) === task.disconnectEpoch) {
988
+ this.#disconnectEpochs.set(task.name, task.disconnectEpoch + 1);
989
+ }
990
+ }
991
+
992
+ async #terminateConnectionTask(task: ConnectionTask): Promise<void> {
993
+ const connection = await task.connectionPromise.catch(() => undefined);
994
+ if (!connection || this.#connections.get(task.name) !== connection) return;
995
+
996
+ connection.transport.onClose = undefined;
997
+ try {
998
+ await disconnectServer(connection);
999
+ } catch {
1000
+ // Preserve the primary startup failure over best-effort transport cleanup failures.
1001
+ } finally {
1002
+ if (this.#connections.get(task.name) === connection) this.#connections.delete(task.name);
1003
+ }
1004
+ }
1005
+
1006
+ async #cleanupConnectionTasks(tasks: ConnectionTask[]): Promise<void> {
1007
+ for (const task of tasks) this.#abortConnectionTask(task);
1008
+ await Promise.allSettled(tasks.map(task => this.#terminateConnectionTask(task)));
1009
+ await Promise.allSettled(tasks.map(task => this.#disconnectServer(task.name)));
808
1010
  }
809
1011
 
810
1012
  /**
@@ -848,6 +1050,7 @@ export class MCPManager {
848
1050
  * Returns the new connection, or null if reconnection failed.
849
1051
  */
850
1052
  async reconnectServer(name: string): Promise<MCPServerConnection | null> {
1053
+ if (this.#toolsOnly) return null;
851
1054
  const pending = this.#pendingReconnections.get(name);
852
1055
  if (pending) return pending;
853
1056
 
@@ -1025,6 +1228,7 @@ export class MCPManager {
1025
1228
  * Shared between initial connection and reconnection.
1026
1229
  */
1027
1230
  async #loadServerResourcesAndPrompts(name: string, connection: MCPServerConnection): Promise<void> {
1231
+ if (this.#toolsOnly) return;
1028
1232
  if (serverSupportsResources(connection.capabilities)) {
1029
1233
  try {
1030
1234
  const [resources] = await Promise.all([listResources(connection), listResourceTemplates(connection)]);
@@ -1053,6 +1257,7 @@ export class MCPManager {
1053
1257
  * Refresh tools from a specific server.
1054
1258
  */
1055
1259
  async refreshServerTools(name: string): Promise<void> {
1260
+ if (this.#toolsOnly) return;
1056
1261
  const connection = this.#connections.get(name);
1057
1262
  if (!connection) return;
1058
1263
  const globalEpoch = this.#epoch;
@@ -1077,6 +1282,7 @@ export class MCPManager {
1077
1282
  * Refresh tools from all servers.
1078
1283
  */
1079
1284
  async refreshAllTools(): Promise<void> {
1285
+ if (this.#toolsOnly) return;
1080
1286
  const promises = Array.from(this.#connections.keys()).map(name => this.refreshServerTools(name));
1081
1287
  await Promise.allSettled(promises);
1082
1288
  }
@@ -1085,6 +1291,7 @@ export class MCPManager {
1085
1291
  * Refresh resources from a specific server.
1086
1292
  */
1087
1293
  async refreshServerResources(name: string): Promise<void> {
1294
+ if (this.#toolsOnly) return;
1088
1295
  const connection = this.#connections.get(name);
1089
1296
  if (!connection || !serverSupportsResources(connection.capabilities)) return;
1090
1297
 
@@ -1154,6 +1361,7 @@ export class MCPManager {
1154
1361
  * Refresh prompts from a specific server.
1155
1362
  */
1156
1363
  async refreshServerPrompts(name: string): Promise<void> {
1364
+ if (this.#toolsOnly) return;
1157
1365
  const connection = this.#connections.get(name);
1158
1366
  if (!connection || !serverSupportsPrompts(connection.capabilities)) return;
1159
1367
 
@@ -1167,6 +1375,7 @@ export class MCPManager {
1167
1375
  * Get resources and templates for a specific server.
1168
1376
  */
1169
1377
  getServerResources(name: string): { resources: MCPResource[]; templates: MCPResourceTemplate[] } | undefined {
1378
+ if (this.#toolsOnly) return undefined;
1170
1379
  const connection = this.#connections.get(name);
1171
1380
  if (!connection) return undefined;
1172
1381
  return {
@@ -1183,6 +1392,7 @@ export class MCPManager {
1183
1392
  uri: string,
1184
1393
  options?: MCPRequestOptions,
1185
1394
  ): Promise<MCPResourceReadResult | undefined> {
1395
+ if (this.#toolsOnly) return undefined;
1186
1396
  const connection = this.#connections.get(name);
1187
1397
  if (!connection) return undefined;
1188
1398
  return readResource(connection, uri, options);
@@ -1192,6 +1402,7 @@ export class MCPManager {
1192
1402
  * Get prompts for a specific server.
1193
1403
  */
1194
1404
  getServerPrompts(name: string): MCPPrompt[] | undefined {
1405
+ if (this.#toolsOnly) return undefined;
1195
1406
  const connection = this.#connections.get(name);
1196
1407
  if (!connection) return undefined;
1197
1408
  return connection.prompts ?? [];
@@ -1206,6 +1417,7 @@ export class MCPManager {
1206
1417
  args?: Record<string, string>,
1207
1418
  options?: MCPRequestOptions,
1208
1419
  ): Promise<MCPGetPromptResult | undefined> {
1420
+ if (this.#toolsOnly) return undefined;
1209
1421
  const connection = this.#connections.get(name);
1210
1422
  if (!connection) return undefined;
1211
1423
  return getPrompt(connection, promptName, args, options);
@@ -1215,6 +1427,7 @@ export class MCPManager {
1215
1427
  * Get all server instructions (for system prompt injection).
1216
1428
  */
1217
1429
  getServerInstructions(): Map<string, string> {
1430
+ if (this.#toolsOnly) return new Map();
1218
1431
  const instructions = new Map<string, string>();
1219
1432
  for (const [name, connection] of this.#connections) {
1220
1433
  if (connection.instructions) {
@@ -1243,61 +1456,85 @@ export class MCPManager {
1243
1456
  const auth = config.auth;
1244
1457
  if (auth?.type === "oauth" && auth.credentialId && this.#authStorage) {
1245
1458
  const credentialId = auth.credentialId;
1246
- try {
1247
- let credential = this.#authStorage.get(credentialId);
1248
- if (credential?.type === "oauth") {
1249
- // Proactive refresh: 5-minute buffer before expiry
1250
- // Force refresh: on 401/403 auth errors (revoked tokens, clock skew, missing expires)
1251
- const REFRESH_BUFFER_MS = 5 * 60_000;
1252
- const shouldRefresh =
1253
- forceRefresh || (credential.expires && Date.now() >= credential.expires - REFRESH_BUFFER_MS);
1254
- if (shouldRefresh && credential.refresh && auth.tokenUrl) {
1255
- try {
1256
- const refreshed = await refreshMCPOAuthToken(
1257
- auth.tokenUrl,
1258
- credential.refresh,
1259
- auth.clientId,
1260
- auth.clientSecret,
1261
- );
1262
- const refreshedCredential = { type: "oauth" as const, ...refreshed };
1263
- await this.#authStorage.set(credentialId, refreshedCredential);
1264
- credential = refreshedCredential;
1265
- } catch (refreshError) {
1266
- logger.warn("MCP OAuth refresh failed, using existing token", {
1267
- credentialId,
1268
- error: refreshError,
1269
- });
1459
+ let credential = this.#authStorage.get(credentialId);
1460
+ if (credential?.type === "oauth") {
1461
+ // Proactive refresh: 5-minute buffer before expiry
1462
+ // Force refresh: on 401/403 auth errors (revoked tokens, clock skew, missing expires)
1463
+ const REFRESH_BUFFER_MS = 5 * 60_000;
1464
+ const shouldRefresh =
1465
+ forceRefresh || (credential.expires && Date.now() >= credential.expires - REFRESH_BUFFER_MS);
1466
+ let refreshedCredential:
1467
+ | {
1468
+ type: "oauth";
1469
+ access: string;
1470
+ refresh: string;
1471
+ expires: number;
1472
+ }
1473
+ | undefined;
1474
+ if (shouldRefresh && credential.refresh && auth.tokenUrl) {
1475
+ try {
1476
+ const refreshed = await refreshMCPOAuthToken(
1477
+ auth.tokenUrl,
1478
+ credential.refresh,
1479
+ auth.clientId,
1480
+ auth.clientSecret,
1481
+ );
1482
+ refreshedCredential = { type: "oauth", ...refreshed };
1483
+ } catch (error) {
1484
+ if (!(error instanceof MCPExpectedFailure)) throw error;
1485
+ if (this.#toolsOnly) {
1486
+ logger.debug("MCP OAuth refresh failed");
1487
+ } else {
1488
+ logger.warn("MCP OAuth refresh failed, using existing token");
1270
1489
  }
1271
1490
  }
1491
+ }
1492
+ if (refreshedCredential) {
1493
+ await this.#authStorage.set(credentialId, refreshedCredential);
1494
+ credential = refreshedCredential;
1495
+ }
1272
1496
 
1273
- if (resolved.type === "http" || resolved.type === "sse") {
1274
- resolved = {
1275
- ...resolved,
1276
- headers: {
1277
- ...resolved.headers,
1278
- Authorization: `Bearer ${credential.access}`,
1279
- },
1280
- };
1281
- } else {
1282
- resolved = {
1283
- ...resolved,
1284
- env: {
1285
- ...resolved.env,
1286
- OAUTH_ACCESS_TOKEN: credential.access,
1287
- },
1288
- };
1289
- }
1497
+ if (resolved.type === "http" || resolved.type === "sse") {
1498
+ resolved = {
1499
+ ...resolved,
1500
+ headers: {
1501
+ ...resolved.headers,
1502
+ Authorization: `Bearer ${credential.access}`,
1503
+ },
1504
+ };
1505
+ } else {
1506
+ resolved = {
1507
+ ...resolved,
1508
+ env: {
1509
+ ...resolved.env,
1510
+ OAUTH_ACCESS_TOKEN: credential.access,
1511
+ },
1512
+ };
1290
1513
  }
1291
- } catch (error) {
1292
- logger.warn("Failed to resolve OAuth credential", { credentialId, error });
1293
1514
  }
1294
1515
  }
1516
+ if (this.#toolsOnly && resolved.type === "stdio") {
1517
+ resolved = { ...resolved, noInheritEnv: true };
1518
+ }
1519
+
1520
+ const resolveValue = async (value: string): Promise<string | undefined> => {
1521
+ try {
1522
+ const resolvedValue = await configValue.resolveConfigValue(value);
1523
+ if (this.#toolsOnly && !resolvedValue) throw new MCPExpectedFailure();
1524
+ return resolvedValue;
1525
+ } catch (error) {
1526
+ if (this.#toolsOnly && isExpectedConfigResolutionFailure(error)) {
1527
+ throw new MCPExpectedFailure(error);
1528
+ }
1529
+ throw error;
1530
+ }
1531
+ };
1295
1532
 
1296
1533
  if (resolved.type !== "http" && resolved.type !== "sse") {
1297
1534
  if (resolved.env) {
1298
1535
  const nextEnv: Record<string, string> = {};
1299
1536
  for (const [key, value] of Object.entries(resolved.env)) {
1300
- const resolvedValue = await resolveConfigValue(value);
1537
+ const resolvedValue = await resolveValue(value);
1301
1538
  if (resolvedValue) nextEnv[key] = resolvedValue;
1302
1539
  }
1303
1540
  resolved = { ...resolved, env: nextEnv };
@@ -1306,7 +1543,7 @@ export class MCPManager {
1306
1543
  if (resolved.headers) {
1307
1544
  const nextHeaders: Record<string, string> = {};
1308
1545
  for (const [key, value] of Object.entries(resolved.headers)) {
1309
- const resolvedValue = await resolveConfigValue(value);
1546
+ const resolvedValue = await resolveValue(value);
1310
1547
  if (resolvedValue) nextHeaders[key] = resolvedValue;
1311
1548
  }
1312
1549
  resolved = { ...resolved, headers: nextHeaders };
@@ -1328,7 +1565,8 @@ export async function createMCPManager(
1328
1565
  manager: MCPManager;
1329
1566
  result: MCPLoadResult;
1330
1567
  }> {
1331
- const manager = new MCPManager(cwd);
1568
+ const manager =
1569
+ options?.configPath !== undefined ? new MCPManager(cwd, null, { toolsOnly: true }) : new MCPManager(cwd);
1332
1570
  const result = await manager.discoverAndConnect(options);
1333
1571
  return { manager, result };
1334
1572
  }