@qduc/term2 0.24.0 → 0.25.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 (309) hide show
  1. package/dist/agent.d.ts +3 -0
  2. package/dist/agent.d.ts.map +1 -1
  3. package/dist/agent.js +2 -1
  4. package/dist/agent.js.map +1 -1
  5. package/dist/app.d.ts +10 -0
  6. package/dist/app.d.ts.map +1 -1
  7. package/dist/app.js +33 -6
  8. package/dist/app.js.map +1 -1
  9. package/dist/cli.js +43 -1
  10. package/dist/cli.js.map +1 -1
  11. package/dist/commands/mcp-login-command.d.ts +24 -0
  12. package/dist/commands/mcp-login-command.d.ts.map +1 -0
  13. package/dist/commands/mcp-login-command.js +65 -0
  14. package/dist/commands/mcp-login-command.js.map +1 -0
  15. package/dist/commands/mcp-status-command.d.ts +19 -0
  16. package/dist/commands/mcp-status-command.d.ts.map +1 -0
  17. package/dist/commands/mcp-status-command.js +19 -0
  18. package/dist/commands/mcp-status-command.js.map +1 -0
  19. package/dist/components/input/ApplicationInputSurface.d.ts +4 -0
  20. package/dist/components/input/ApplicationInputSurface.d.ts.map +1 -1
  21. package/dist/components/input/ApplicationInputSurface.js +2 -0
  22. package/dist/components/input/ApplicationInputSurface.js.map +1 -1
  23. package/dist/components/input/McpMenuSession.d.ts +9 -0
  24. package/dist/components/input/McpMenuSession.d.ts.map +1 -0
  25. package/dist/components/input/McpMenuSession.js +370 -0
  26. package/dist/components/input/McpMenuSession.js.map +1 -0
  27. package/dist/components/input/ProviderMenuSession.d.ts.map +1 -1
  28. package/dist/components/input/ProviderMenuSession.js +0 -4
  29. package/dist/components/input/ProviderMenuSession.js.map +1 -1
  30. package/dist/components/input/SubagentPoolMenuSession.d.ts.map +1 -1
  31. package/dist/components/input/SubagentPoolMenuSession.js +0 -9
  32. package/dist/components/input/SubagentPoolMenuSession.js.map +1 -1
  33. package/dist/components/input/mcp-intent-host.d.ts +10 -0
  34. package/dist/components/input/mcp-intent-host.d.ts.map +1 -0
  35. package/dist/components/input/mcp-intent-host.js +31 -0
  36. package/dist/components/input/mcp-intent-host.js.map +1 -0
  37. package/dist/components/input/menu-bindings.d.ts +69 -0
  38. package/dist/components/input/menu-bindings.d.ts.map +1 -0
  39. package/dist/components/input/menu-bindings.js +110 -0
  40. package/dist/components/input/menu-bindings.js.map +1 -0
  41. package/dist/components/input/menu-controller.d.ts.map +1 -1
  42. package/dist/components/input/menu-controller.js +8 -5
  43. package/dist/components/input/menu-controller.js.map +1 -1
  44. package/dist/components/input/menu-registry.d.ts.map +1 -1
  45. package/dist/components/input/menu-registry.js +2 -0
  46. package/dist/components/input/menu-registry.js.map +1 -1
  47. package/dist/components/input/menu-types.d.ts +22 -7
  48. package/dist/components/input/menu-types.d.ts.map +1 -1
  49. package/dist/components/layout/BackgroundTasksPanel.d.ts +6 -0
  50. package/dist/components/layout/BackgroundTasksPanel.d.ts.map +1 -1
  51. package/dist/components/layout/BackgroundTasksPanel.js +58 -64
  52. package/dist/components/layout/BackgroundTasksPanel.js.map +1 -1
  53. package/dist/components/layout/BottomArea.d.ts +6 -1
  54. package/dist/components/layout/BottomArea.d.ts.map +1 -1
  55. package/dist/components/layout/BottomArea.js +9 -6
  56. package/dist/components/layout/BottomArea.js.map +1 -1
  57. package/dist/components/layout/StatusBar.d.ts.map +1 -1
  58. package/dist/components/layout/StatusBar.js +27 -18
  59. package/dist/components/layout/StatusBar.js.map +1 -1
  60. package/dist/components/menu/McpSelectionMenu.d.ts +15 -0
  61. package/dist/components/menu/McpSelectionMenu.d.ts.map +1 -0
  62. package/dist/components/menu/McpSelectionMenu.js +19 -0
  63. package/dist/components/menu/McpSelectionMenu.js.map +1 -0
  64. package/dist/components/menu/ModelSelectionMenu.d.ts.map +1 -1
  65. package/dist/components/menu/ModelSelectionMenu.js +16 -26
  66. package/dist/components/menu/ModelSelectionMenu.js.map +1 -1
  67. package/dist/components/menu/ProviderSelectionMenu.d.ts.map +1 -1
  68. package/dist/components/menu/ProviderSelectionMenu.js +8 -15
  69. package/dist/components/menu/ProviderSelectionMenu.js.map +1 -1
  70. package/dist/components/menu/SlashCommandMenu.d.ts.map +1 -1
  71. package/dist/components/menu/SlashCommandMenu.js +2 -5
  72. package/dist/components/menu/SlashCommandMenu.js.map +1 -1
  73. package/dist/components/menu/SubagentPoolSelectionMenu.d.ts.map +1 -1
  74. package/dist/components/menu/SubagentPoolSelectionMenu.js +6 -11
  75. package/dist/components/menu/SubagentPoolSelectionMenu.js.map +1 -1
  76. package/dist/components/message/command-message-helpers.d.ts +2 -2
  77. package/dist/components/message/command-message-helpers.d.ts.map +1 -1
  78. package/dist/components/prompt/ApprovalPrompt.d.ts.map +1 -1
  79. package/dist/components/prompt/ApprovalPrompt.js +3 -0
  80. package/dist/components/prompt/ApprovalPrompt.js.map +1 -1
  81. package/dist/contracts/conversation.d.ts +2 -0
  82. package/dist/contracts/conversation.d.ts.map +1 -1
  83. package/dist/contracts/conversation.js.map +1 -1
  84. package/dist/gateway/settings-rpc.d.ts +1 -0
  85. package/dist/gateway/settings-rpc.d.ts.map +1 -1
  86. package/dist/gateway/settings-rpc.js +1 -0
  87. package/dist/gateway/settings-rpc.js.map +1 -1
  88. package/dist/hooks/conversation-ui-reducer.d.ts +1 -1
  89. package/dist/hooks/conversation-ui-reducer.d.ts.map +1 -1
  90. package/dist/hooks/settings-completion-config.d.ts.map +1 -1
  91. package/dist/hooks/settings-completion-config.js +2 -1
  92. package/dist/hooks/settings-completion-config.js.map +1 -1
  93. package/dist/hooks/use-app-commands.d.ts +9 -1
  94. package/dist/hooks/use-app-commands.d.ts.map +1 -1
  95. package/dist/hooks/use-app-commands.js +14 -1
  96. package/dist/hooks/use-app-commands.js.map +1 -1
  97. package/dist/hooks/use-conversation.d.ts +1 -1
  98. package/dist/hooks/use-mcp-notices.d.ts +10 -0
  99. package/dist/hooks/use-mcp-notices.d.ts.map +1 -0
  100. package/dist/hooks/use-mcp-notices.js +47 -0
  101. package/dist/hooks/use-mcp-notices.js.map +1 -0
  102. package/dist/hooks/use-provider-selection.d.ts +1 -7
  103. package/dist/hooks/use-provider-selection.d.ts.map +1 -1
  104. package/dist/hooks/use-provider-selection.js +34 -87
  105. package/dist/hooks/use-provider-selection.js.map +1 -1
  106. package/dist/hooks/use-settings-value-completion.d.ts +3 -2
  107. package/dist/hooks/use-settings-value-completion.d.ts.map +1 -1
  108. package/dist/hooks/use-settings-value-completion.js +21 -3
  109. package/dist/hooks/use-settings-value-completion.js.map +1 -1
  110. package/dist/hooks/use-shell-mode.d.ts +1 -0
  111. package/dist/hooks/use-shell-mode.d.ts.map +1 -1
  112. package/dist/hooks/use-shell-mode.js +1 -0
  113. package/dist/hooks/use-shell-mode.js.map +1 -1
  114. package/dist/hooks/use-subagent-pool-selection.d.ts +2 -10
  115. package/dist/hooks/use-subagent-pool-selection.d.ts.map +1 -1
  116. package/dist/hooks/use-subagent-pool-selection.js +5 -62
  117. package/dist/hooks/use-subagent-pool-selection.js.map +1 -1
  118. package/dist/lib/agent-client.d.ts +1 -0
  119. package/dist/lib/agent-client.d.ts.map +1 -1
  120. package/dist/lib/agent-client.js +2 -0
  121. package/dist/lib/agent-client.js.map +1 -1
  122. package/dist/lib/agent-configuration.d.ts +4 -0
  123. package/dist/lib/agent-configuration.d.ts.map +1 -1
  124. package/dist/lib/agent-configuration.js +8 -0
  125. package/dist/lib/agent-configuration.js.map +1 -1
  126. package/dist/lib/agent-factory.d.ts +2 -0
  127. package/dist/lib/agent-factory.d.ts.map +1 -1
  128. package/dist/lib/agent-factory.js +1 -0
  129. package/dist/lib/agent-factory.js.map +1 -1
  130. package/dist/lib/oauth-loopback.d.ts +79 -0
  131. package/dist/lib/oauth-loopback.d.ts.map +1 -0
  132. package/dist/lib/oauth-loopback.js +221 -0
  133. package/dist/lib/oauth-loopback.js.map +1 -0
  134. package/dist/non-interactive.d.ts +2 -0
  135. package/dist/non-interactive.d.ts.map +1 -1
  136. package/dist/non-interactive.js +19 -0
  137. package/dist/non-interactive.js.map +1 -1
  138. package/dist/providers/codex.provider.d.ts.map +1 -1
  139. package/dist/providers/codex.provider.js +4 -3
  140. package/dist/providers/codex.provider.js.map +1 -1
  141. package/dist/providers/index.d.ts +1 -1
  142. package/dist/providers/index.d.ts.map +1 -1
  143. package/dist/providers/index.js +1 -1
  144. package/dist/providers/index.js.map +1 -1
  145. package/dist/providers/oauth-pkce.d.ts +5 -1
  146. package/dist/providers/oauth-pkce.d.ts.map +1 -1
  147. package/dist/providers/oauth-pkce.js +28 -208
  148. package/dist/providers/oauth-pkce.js.map +1 -1
  149. package/dist/providers/openai-responses-model.d.ts.map +1 -1
  150. package/dist/providers/openai-responses-model.js +5 -1
  151. package/dist/providers/openai-responses-model.js.map +1 -1
  152. package/dist/providers/openrouter-decisions.d.ts +15 -0
  153. package/dist/providers/openrouter-decisions.d.ts.map +1 -0
  154. package/dist/providers/openrouter-decisions.js +25 -0
  155. package/dist/providers/openrouter-decisions.js.map +1 -0
  156. package/dist/providers/provider-service.d.ts +3 -1
  157. package/dist/providers/provider-service.d.ts.map +1 -1
  158. package/dist/providers/provider-service.js +4 -1
  159. package/dist/providers/provider-service.js.map +1 -1
  160. package/dist/providers/registry.d.ts +0 -6
  161. package/dist/providers/registry.d.ts.map +1 -1
  162. package/dist/providers/registry.js +0 -25
  163. package/dist/providers/registry.js.map +1 -1
  164. package/dist/services/approval/decision-shadow.d.ts +15 -0
  165. package/dist/services/approval/decision-shadow.d.ts.map +1 -0
  166. package/dist/services/approval/decision-shadow.js +77 -0
  167. package/dist/services/approval/decision-shadow.js.map +1 -0
  168. package/dist/services/approval/non-interactive-approval-policy.d.ts +5 -0
  169. package/dist/services/approval/non-interactive-approval-policy.d.ts.map +1 -1
  170. package/dist/services/approval/non-interactive-approval-policy.js +14 -0
  171. package/dist/services/approval/non-interactive-approval-policy.js.map +1 -1
  172. package/dist/services/approval/shell-auto-approval-evaluator.d.ts +5 -1
  173. package/dist/services/approval/shell-auto-approval-evaluator.d.ts.map +1 -1
  174. package/dist/services/approval/shell-auto-approval-evaluator.js +80 -4
  175. package/dist/services/approval/shell-auto-approval-evaluator.js.map +1 -1
  176. package/dist/services/conversation/conversation-orchestrator.d.ts.map +1 -1
  177. package/dist/services/conversation/conversation-orchestrator.js +16 -2
  178. package/dist/services/conversation/conversation-orchestrator.js.map +1 -1
  179. package/dist/services/conversation/conversation-orchestrator.types.d.ts +1 -1
  180. package/dist/services/conversation/conversation-orchestrator.types.d.ts.map +1 -1
  181. package/dist/services/conversation/session-browser.d.ts +4 -2
  182. package/dist/services/conversation/session-browser.d.ts.map +1 -1
  183. package/dist/services/conversation/session-browser.js +17 -6
  184. package/dist/services/conversation/session-browser.js.map +1 -1
  185. package/dist/services/conversation/session-index/session-index-database.d.ts.map +1 -1
  186. package/dist/services/conversation/session-index/session-index-database.js +24 -6
  187. package/dist/services/conversation/session-index/session-index-database.js.map +1 -1
  188. package/dist/services/mcp/mcp-config-controller.d.ts +32 -0
  189. package/dist/services/mcp/mcp-config-controller.d.ts.map +1 -0
  190. package/dist/services/mcp/mcp-config-controller.js +89 -0
  191. package/dist/services/mcp/mcp-config-controller.js.map +1 -0
  192. package/dist/services/mcp/mcp-config.d.ts +61 -0
  193. package/dist/services/mcp/mcp-config.d.ts.map +1 -0
  194. package/dist/services/mcp/mcp-config.js +232 -0
  195. package/dist/services/mcp/mcp-config.js.map +1 -0
  196. package/dist/services/mcp/mcp-connection-manager.d.ts +126 -0
  197. package/dist/services/mcp/mcp-connection-manager.d.ts.map +1 -0
  198. package/dist/services/mcp/mcp-connection-manager.js +488 -0
  199. package/dist/services/mcp/mcp-connection-manager.js.map +1 -0
  200. package/dist/services/mcp/mcp-oauth-login.d.ts +79 -0
  201. package/dist/services/mcp/mcp-oauth-login.d.ts.map +1 -0
  202. package/dist/services/mcp/mcp-oauth-login.js +126 -0
  203. package/dist/services/mcp/mcp-oauth-login.js.map +1 -0
  204. package/dist/services/mcp/mcp-oauth-provider.d.ts +77 -0
  205. package/dist/services/mcp/mcp-oauth-provider.d.ts.map +1 -0
  206. package/dist/services/mcp/mcp-oauth-provider.js +121 -0
  207. package/dist/services/mcp/mcp-oauth-provider.js.map +1 -0
  208. package/dist/services/mcp/mcp-oauth-store.d.ts +106 -0
  209. package/dist/services/mcp/mcp-oauth-store.d.ts.map +1 -0
  210. package/dist/services/mcp/mcp-oauth-store.js +278 -0
  211. package/dist/services/mcp/mcp-oauth-store.js.map +1 -0
  212. package/dist/services/mcp/mcp-status.d.ts +41 -0
  213. package/dist/services/mcp/mcp-status.d.ts.map +1 -0
  214. package/dist/services/mcp/mcp-status.js +69 -0
  215. package/dist/services/mcp/mcp-status.js.map +1 -0
  216. package/dist/services/mcp/mcp-stdio-launcher.d.ts +26 -0
  217. package/dist/services/mcp/mcp-stdio-launcher.d.ts.map +1 -0
  218. package/dist/services/mcp/mcp-stdio-launcher.js +8 -0
  219. package/dist/services/mcp/mcp-stdio-launcher.js.map +1 -0
  220. package/dist/services/mcp/mcp-tool-source.d.ts +77 -0
  221. package/dist/services/mcp/mcp-tool-source.d.ts.map +1 -0
  222. package/dist/services/mcp/mcp-tool-source.js +10 -0
  223. package/dist/services/mcp/mcp-tool-source.js.map +1 -0
  224. package/dist/services/mcp/test-fixtures/fake-authorization-server.d.ts +25 -0
  225. package/dist/services/mcp/test-fixtures/fake-authorization-server.d.ts.map +1 -0
  226. package/dist/services/mcp/test-fixtures/fake-authorization-server.js +147 -0
  227. package/dist/services/mcp/test-fixtures/fake-authorization-server.js.map +1 -0
  228. package/dist/services/mcp/test-fixtures/protected-mcp-server.d.ts +29 -0
  229. package/dist/services/mcp/test-fixtures/protected-mcp-server.d.ts.map +1 -0
  230. package/dist/services/mcp/test-fixtures/protected-mcp-server.js +87 -0
  231. package/dist/services/mcp/test-fixtures/protected-mcp-server.js.map +1 -0
  232. package/dist/services/mcp/turn-stable-mcp-tool-source.d.ts +19 -0
  233. package/dist/services/mcp/turn-stable-mcp-tool-source.d.ts.map +1 -0
  234. package/dist/services/mcp/turn-stable-mcp-tool-source.js +37 -0
  235. package/dist/services/mcp/turn-stable-mcp-tool-source.js.map +1 -0
  236. package/dist/services/models/decision-model-listing.d.ts +26 -0
  237. package/dist/services/models/decision-model-listing.d.ts.map +1 -0
  238. package/dist/services/models/decision-model-listing.js +61 -0
  239. package/dist/services/models/decision-model-listing.js.map +1 -0
  240. package/dist/services/models/model-catalog-session.d.ts +6 -1
  241. package/dist/services/models/model-catalog-session.d.ts.map +1 -1
  242. package/dist/services/models/model-catalog-session.js +9 -8
  243. package/dist/services/models/model-catalog-session.js.map +1 -1
  244. package/dist/services/profiles/registry.d.ts +1 -1
  245. package/dist/services/profiles/registry.d.ts.map +1 -1
  246. package/dist/services/profiles/registry.js +2 -1
  247. package/dist/services/profiles/registry.js.map +1 -1
  248. package/dist/services/providers/provider-management-session.d.ts +0 -1
  249. package/dist/services/providers/provider-management-session.d.ts.map +1 -1
  250. package/dist/services/providers/provider-management-session.js +0 -3
  251. package/dist/services/providers/provider-management-session.js.map +1 -1
  252. package/dist/services/settings/settings-merger.d.ts.map +1 -1
  253. package/dist/services/settings/settings-merger.js +0 -2
  254. package/dist/services/settings/settings-merger.js.map +1 -1
  255. package/dist/services/settings/settings-schema.d.ts +8 -3
  256. package/dist/services/settings/settings-schema.d.ts.map +1 -1
  257. package/dist/services/settings/settings-schema.js +16 -8
  258. package/dist/services/settings/settings-schema.js.map +1 -1
  259. package/dist/services/settings/settings-sources.d.ts +2 -0
  260. package/dist/services/settings/settings-sources.d.ts.map +1 -1
  261. package/dist/services/settings/settings-sources.js +2 -0
  262. package/dist/services/settings/settings-sources.js.map +1 -1
  263. package/dist/services/settings/settings-ui-metadata.d.ts.map +1 -1
  264. package/dist/services/settings/settings-ui-metadata.js +0 -1
  265. package/dist/services/settings/settings-ui-metadata.js.map +1 -1
  266. package/dist/services/settings/test-helpers/settings-consumer-inventory.d.ts +2 -2
  267. package/dist/services/settings/test-helpers/settings-consumer-inventory.d.ts.map +1 -1
  268. package/dist/services/settings/test-helpers/settings-consumer-inventory.js +2 -1
  269. package/dist/services/settings/test-helpers/settings-consumer-inventory.js.map +1 -1
  270. package/dist/services/shell/shell-interaction-session.d.ts +2 -0
  271. package/dist/services/shell/shell-interaction-session.d.ts.map +1 -1
  272. package/dist/services/shell/shell-interaction-session.js +11 -2
  273. package/dist/services/shell/shell-interaction-session.js.map +1 -1
  274. package/dist/services/subagents/mentor-runner.d.ts.map +1 -1
  275. package/dist/services/subagents/mentor-runner.js +6 -8
  276. package/dist/services/subagents/mentor-runner.js.map +1 -1
  277. package/dist/services/subagents/subagent-notification-store.js.map +1 -1
  278. package/dist/tools/memory/memory-tools.d.ts.map +1 -1
  279. package/dist/tools/memory/memory-tools.js +3 -1
  280. package/dist/tools/memory/memory-tools.js.map +1 -1
  281. package/dist/tools/session-browser/session-browser-tools.d.ts +1 -1
  282. package/dist/tools/session-browser/session-browser-tools.d.ts.map +1 -1
  283. package/dist/tools/session-browser/session-browser-tools.js +4 -3
  284. package/dist/tools/session-browser/session-browser-tools.js.map +1 -1
  285. package/dist/tools/system/run-code/mcp-script-surface.d.ts +28 -0
  286. package/dist/tools/system/run-code/mcp-script-surface.d.ts.map +1 -0
  287. package/dist/tools/system/run-code/mcp-script-surface.js +165 -0
  288. package/dist/tools/system/run-code/mcp-script-surface.js.map +1 -0
  289. package/dist/tools/system/run-code/run-code-runtime.d.ts.map +1 -1
  290. package/dist/tools/system/run-code/run-code-runtime.js +13 -1
  291. package/dist/tools/system/run-code/run-code-runtime.js.map +1 -1
  292. package/dist/tools/system/run-code/run-code.d.ts +3 -0
  293. package/dist/tools/system/run-code/run-code.d.ts.map +1 -1
  294. package/dist/tools/system/run-code/run-code.js +32 -4
  295. package/dist/tools/system/run-code/run-code.js.map +1 -1
  296. package/dist/utils/ai/provider-credentials.d.ts +8 -0
  297. package/dist/utils/ai/provider-credentials.d.ts.map +1 -1
  298. package/dist/utils/ai/provider-credentials.js +18 -0
  299. package/dist/utils/ai/provider-credentials.js.map +1 -1
  300. package/dist/utils/conversation/conversation-event-handler.js.map +1 -1
  301. package/dist/utils/conversation/conversation-utils.d.ts +1 -5
  302. package/dist/utils/conversation/conversation-utils.d.ts.map +1 -1
  303. package/dist/utils/conversation/conversation-utils.js +4 -1
  304. package/dist/utils/conversation/conversation-utils.js.map +1 -1
  305. package/dist/utils/value-suggestions.d.ts +14 -0
  306. package/dist/utils/value-suggestions.d.ts.map +1 -1
  307. package/dist/utils/value-suggestions.js +31 -0
  308. package/dist/utils/value-suggestions.js.map +1 -1
  309. package/package.json +3 -1
@@ -0,0 +1,488 @@
1
+ /**
2
+ * The MCP connection layer: owns one connection per configured server and
3
+ * exposes them through {@linkcode McpToolSource} (the fixed contract with the
4
+ * `run_code` script surface).
5
+ *
6
+ * Lifecycle: `start()` connects every server concurrently in the background
7
+ * (connecting → ready/failed); `snapshot()` keeps a stable array identity until
8
+ * something actually changes; `notifications/tools/list_changed` triggers a
9
+ * refetch; `close()` shuts everything down. There is no automatic reconnect in
10
+ * this slice — a failed server stays failed until the next `start()`.
11
+ */
12
+ import { Client, SdkError, SdkErrorCode, SdkHttpError, SseError, SSEClientTransport, StreamableHTTPClientTransport, UnauthorizedError, } from '@modelcontextprotocol/client';
13
+ import { StdioClientTransport } from '@modelcontextprotocol/client/stdio';
14
+ import { McpCallError } from './mcp-tool-source.js';
15
+ export { McpCallError };
16
+ import { realpathOrSelf } from './mcp-config.js';
17
+ import { unsandboxedStdioLauncher } from './mcp-stdio-launcher.js';
18
+ import { createRefreshOnlyProvider, McpInteractiveLoginRequiredError, mcpNeedsAuthMessage } from './mcp-oauth-login.js';
19
+ const DEFAULT_CALL_TIMEOUT_MS = 120_000;
20
+ const STDERR_TAIL_CHARS = 2000;
21
+ const CONNECT_TIMEOUT_MS = 15_000;
22
+ const LIST_TIMEOUT_MS = 15_000;
23
+ /** Upper bound on waiting for a client/transport close during `close()`. */
24
+ const CLOSE_TIMEOUT_MS = 5_000;
25
+ /** The exact nested line a user must add to start a project stdio server. */
26
+ const projectOptInError = (name, workspaceRoot, userConfigPath) => `not started — a project stdio server must be enabled for this workspace by adding \`"projectServers": { "${workspaceRoot ?? '<workspace root>'}": { "${name}": { "enabled": true } } }\` to ${userConfigPath ?? 'the user mcp.json'}`;
27
+ /**
28
+ * Plan decision D2 (2026-09-18): a project `.mcp.json` may name any URL, so an
29
+ * OAuth login it provokes would send the user to an issuer the repository chose.
30
+ * Project HTTP servers therefore need the same workspace-scoped opt-in as
31
+ * project stdio servers before any credential flow may begin.
32
+ */
33
+ const projectOAuthOptInError = (name, workspaceRoot, userConfigPath) => `requires an OAuth login, which a project config may not start on its own: enable it for this workspace by adding \`"projectServers": { "${workspaceRoot ?? '<workspace root>'}": { "${name}": { "enabled": true } } }\` to ${userConfigPath ?? 'the user mcp.json'}, then run /mcp-login ${name}`;
34
+ export class McpConnectionManager {
35
+ connections = new Map();
36
+ listeners = new Set();
37
+ stdioLauncher;
38
+ userConfigPath;
39
+ workspaceRoot;
40
+ onNotice;
41
+ oauthStore;
42
+ interactive;
43
+ noticedFailures = new Set();
44
+ snapshotCache = [];
45
+ started = false;
46
+ closed = false;
47
+ settlePromise = Promise.resolve();
48
+ constructor(options) {
49
+ this.stdioLauncher = options.stdioLauncher ?? unsandboxedStdioLauncher;
50
+ this.userConfigPath = options.userConfigPath;
51
+ this.workspaceRoot = options.workspaceRoot;
52
+ this.onNotice = options.onNotice;
53
+ this.oauthStore = options.oauthStore;
54
+ this.interactive = options.interactive ?? true;
55
+ for (const config of options.servers) {
56
+ if (this.connections.has(config.name)) {
57
+ this.connections.set(config.name, {
58
+ config,
59
+ state: 'failed',
60
+ tools: [],
61
+ error: `duplicate server name "${config.name}" in resolved config`,
62
+ });
63
+ continue;
64
+ }
65
+ this.connections.set(config.name, { config, state: 'connecting', tools: [] });
66
+ }
67
+ this.rebuildSnapshot();
68
+ }
69
+ /** Begins connecting every server concurrently. Resolved configs never throw. */
70
+ start() {
71
+ if (this.started)
72
+ return;
73
+ this.started = true;
74
+ const settling = Array.from(this.connections.values(), (connection) => this.connectOne(connection));
75
+ this.settlePromise = Promise.all(settling).then(() => undefined);
76
+ }
77
+ /** Resolves once every connection started by `start()` left `connecting`. */
78
+ whenSettled() {
79
+ return this.settlePromise;
80
+ }
81
+ snapshot() {
82
+ return this.snapshotCache;
83
+ }
84
+ onCatalogChanged(listener) {
85
+ this.listeners.add(listener);
86
+ return () => this.listeners.delete(listener);
87
+ }
88
+ async callTool(server, tool, args, options) {
89
+ const connection = this.connections.get(server);
90
+ if (!connection)
91
+ throw new McpCallError('unknown_server', `no MCP server named "${server}"`);
92
+ if (connection.state !== 'ready' || !connection.client) {
93
+ throw new McpCallError('server_unavailable', `server "${server}" is ${connection.state}${connection.error ? ` (${connection.error})` : ''}`);
94
+ }
95
+ if (!connection.tools.some((t) => t.name === tool)) {
96
+ throw new McpCallError('unknown_tool', `server "${server}" does not list a tool named "${tool}"`);
97
+ }
98
+ if (options.signal.aborted)
99
+ throw new McpCallError('aborted', 'call aborted before it was sent');
100
+ try {
101
+ const result = await connection.client.callTool({ name: tool, arguments: args }, { signal: options.signal, timeout: options.timeoutMs ?? DEFAULT_CALL_TIMEOUT_MS });
102
+ return {
103
+ content: result.content ?? [],
104
+ ...(result.structuredContent !== undefined ? { structuredContent: result.structuredContent } : {}),
105
+ isError: result.isError === true,
106
+ };
107
+ }
108
+ catch (error) {
109
+ throw this.mapCallError(server, tool, options.signal, error);
110
+ }
111
+ }
112
+ async close() {
113
+ this.closed = true;
114
+ await Promise.all(Array.from(this.connections.values(), async (connection) => {
115
+ connection.closing = true;
116
+ // The grace timer is cleared (and unref'd) as soon as teardown wins,
117
+ // so a finished close() never keeps the event loop alive.
118
+ let grace;
119
+ try {
120
+ await Promise.race([
121
+ this.teardown(connection),
122
+ new Promise((resolve) => {
123
+ grace = setTimeout(resolve, CLOSE_TIMEOUT_MS);
124
+ grace.unref?.();
125
+ }),
126
+ ]);
127
+ }
128
+ finally {
129
+ if (grace !== undefined)
130
+ clearTimeout(grace);
131
+ }
132
+ }));
133
+ }
134
+ /** Reconciles edited config while preserving this stable tool-source object. */
135
+ async replaceServers(configs) {
136
+ if (this.closed)
137
+ return;
138
+ const nextByName = new Map(configs.map((config) => [config.name, config]));
139
+ const connect = [];
140
+ for (const [name, connection] of this.connections) {
141
+ const next = nextByName.get(name);
142
+ if (next && JSON.stringify(next) === JSON.stringify(connection.config)) {
143
+ nextByName.delete(name);
144
+ continue;
145
+ }
146
+ connection.closing = true;
147
+ await this.teardown(connection);
148
+ this.connections.delete(name);
149
+ this.noticedFailures.delete(name);
150
+ }
151
+ for (const config of configs) {
152
+ if (!nextByName.has(config.name))
153
+ continue;
154
+ const connection = { config, state: 'connecting', tools: [] };
155
+ this.connections.set(config.name, connection);
156
+ connect.push(connection);
157
+ }
158
+ this.rebuildSnapshot();
159
+ const settling = connect.map((connection) => this.connectOne(connection));
160
+ this.settlePromise = Promise.all(settling).then(() => undefined);
161
+ await this.settlePromise;
162
+ }
163
+ /**
164
+ * Closes and clears this connection's client and transport, waiting for the
165
+ * closes to finish (bounded by the caller). Clearing first means a close()
166
+ * racing an in-flight connect can never double-close or re-await a torn-down
167
+ * client, and connectOne's post-await checks see the cleared state.
168
+ */
169
+ async teardown(connection) {
170
+ const { client, transport } = connection;
171
+ connection.client = undefined;
172
+ connection.transport = undefined;
173
+ await Promise.all([client?.close().catch(() => { }), transport?.close().catch(() => { })]);
174
+ }
175
+ /** True once close() ran or this connection is being torn down. */
176
+ isAbandoned(connection) {
177
+ return this.closed || connection.closing === true;
178
+ }
179
+ mapCallError(server, tool, signal, error) {
180
+ if (signal.aborted || (error instanceof Error && error.name === 'AbortError')) {
181
+ return new McpCallError('aborted', `call to ${server}.${tool} was aborted`);
182
+ }
183
+ if (error instanceof SdkError && error.code === SdkErrorCode.RequestTimeout) {
184
+ return new McpCallError('timeout', `call to ${server}.${tool} exceeded its timeout`);
185
+ }
186
+ // A crash or teardown mid-call kills the transport and (soon after) moves
187
+ // the connection out of `ready`; either signal means the server, not the
188
+ // protocol, is gone.
189
+ const connection = this.connections.get(server);
190
+ const connectionLost = connection !== undefined && connection.state !== 'ready' && !this.isAbandoned(connection);
191
+ const transportClosed = error instanceof SdkError &&
192
+ (error.code === SdkErrorCode.ConnectionClosed || error.code === SdkErrorCode.NotConnected);
193
+ if (connectionLost || transportClosed) {
194
+ return new McpCallError('server_unavailable', `server "${server}" is unavailable: ${error instanceof Error ? error.message : String(error)}`);
195
+ }
196
+ const message = error instanceof Error ? error.message : String(error);
197
+ return new McpCallError('protocol', `call to ${server}.${tool} failed: ${message}`);
198
+ }
199
+ async connectOne(connection) {
200
+ const { config } = connection;
201
+ if (this.isAbandoned(connection))
202
+ return;
203
+ try {
204
+ if (config.error !== undefined) {
205
+ this.markFailed(connection, config.error);
206
+ return;
207
+ }
208
+ if (config.transport === 'stdio' && config.provenance === 'project' && config.projectEnabledOverride !== true) {
209
+ this.markFailed(connection, projectOptInError(config.name, realpathOrSelf(this.workspaceRoot ?? ''), this.userConfigPath));
210
+ return;
211
+ }
212
+ if (config.transport === 'stdio') {
213
+ await this.connectStdio(connection);
214
+ }
215
+ else {
216
+ await this.connectHttp(connection);
217
+ }
218
+ // Re-check after every await: close() may have fired while we were
219
+ // launching or connecting. Anything just created is torn down, and the
220
+ // connection never becomes `ready` or notifies after close.
221
+ if (this.isAbandoned(connection)) {
222
+ await this.teardown(connection);
223
+ return;
224
+ }
225
+ await this.refreshTools(connection, { cache: 'use' });
226
+ if (this.isAbandoned(connection)) {
227
+ await this.teardown(connection);
228
+ return;
229
+ }
230
+ connection.state = 'ready';
231
+ this.rebuildSnapshot();
232
+ }
233
+ catch (error) {
234
+ // A failure after spawn/connect must not leak the process or transport.
235
+ await this.teardown(connection);
236
+ // The failure may itself be caused by close() aborting the connect;
237
+ // never record a failure or notify after close.
238
+ if (this.isAbandoned(connection))
239
+ return;
240
+ if (this.isAuthRequired(error)) {
241
+ this.markAuthRequired(connection);
242
+ return;
243
+ }
244
+ const detail = error instanceof Error ? error.message : String(error);
245
+ const tail = connection.stderrTail ? ` stderr: ${connection.stderrTail}` : '';
246
+ this.markFailed(connection, `${detail}${tail}`);
247
+ }
248
+ }
249
+ /**
250
+ * All three shapes mean the same thing: the server wants a credential this
251
+ * session does not have.
252
+ *
253
+ * The `SdkHttpError` case is not redundant — the transport only raises
254
+ * `UnauthorizedError` when an auth provider is attached, and one is attached
255
+ * only once a credential is stored. A server nobody has logged in to yet
256
+ * therefore reports its 401 as a plain HTTP error, which is precisely the
257
+ * case that must reach `needs-auth`.
258
+ */
259
+ isAuthRequired(error) {
260
+ if (error instanceof UnauthorizedError || error instanceof McpInteractiveLoginRequiredError)
261
+ return true;
262
+ if (error instanceof SdkHttpError && error.status === 401)
263
+ return true;
264
+ // The legacy SSE transport reports the same 401 as an `SseError` carrying
265
+ // the status in `code`, because the refused response arrives on the event
266
+ // stream rather than from a JSON-RPC POST. Observed against real servers
267
+ // (Asana, Atlassian), which without this land in `failed` with an opaque
268
+ // "SSE error: Non-200 status code (401)" instead of an actionable login.
269
+ return error instanceof SseError && error.code === 401;
270
+ }
271
+ /**
272
+ * Routes a server that asked for a login to the right resting state: an
273
+ * actionable `needs-auth` interactively, a `failed` that says why when no one
274
+ * can complete a browser flow (non-interactive) or when a project config is
275
+ * not allowed to start one (D2).
276
+ */
277
+ markAuthRequired(connection) {
278
+ const { config } = connection;
279
+ if (!this.oauthEligible(config)) {
280
+ this.markFailed(connection, projectOAuthOptInError(config.name, realpathOrSelf(this.workspaceRoot ?? ''), this.userConfigPath));
281
+ return;
282
+ }
283
+ if (!this.interactive) {
284
+ this.markFailed(connection, `requires an OAuth login, which cannot be completed in a non-interactive run: authenticate once with \`/mcp-login ${config.name}\` in an interactive session and the stored token will refresh here`);
285
+ return;
286
+ }
287
+ if (this.isAbandoned(connection))
288
+ return;
289
+ connection.state = 'needs-auth';
290
+ connection.error = mcpNeedsAuthMessage(config.name);
291
+ connection.tools = [];
292
+ if (!this.noticedFailures.has(config.name)) {
293
+ this.noticedFailures.add(config.name);
294
+ this.onNotice?.(`MCP server "${config.name}": ${mcpNeedsAuthMessage(config.name)}`);
295
+ }
296
+ this.rebuildSnapshot();
297
+ }
298
+ async connectStdio(connection) {
299
+ const { config } = connection;
300
+ const spawned = await this.stdioLauncher({
301
+ name: config.name,
302
+ command: config.command ?? '',
303
+ args: config.args ?? [],
304
+ env: config.env ?? {},
305
+ ...(config.cwd !== undefined ? { cwd: config.cwd } : {}),
306
+ });
307
+ // The launcher may have resolved after close() started: never spawn then.
308
+ if (this.isAbandoned(connection))
309
+ return;
310
+ const transport = new StdioClientTransport({
311
+ command: spawned.command,
312
+ args: [...spawned.args],
313
+ env: { ...spawned.env },
314
+ ...(spawned.cwd !== undefined ? { cwd: spawned.cwd } : {}),
315
+ stderr: 'pipe',
316
+ });
317
+ // Registered on the connection before connecting, so a close() that
318
+ // fires mid-handshake can always reach the transport and kill the child.
319
+ connection.transport = transport;
320
+ this.watchStdio(connection, transport);
321
+ await this.connectClient(connection, transport);
322
+ }
323
+ async connectHttp(connection) {
324
+ const { config } = connection;
325
+ if (config.url === undefined)
326
+ throw new Error('http/sse server has no url');
327
+ const headers = config.headers ?? {};
328
+ const url = new URL(config.url);
329
+ // An auth provider is attached only when a credential is already stored, so
330
+ // startup never runs discovery or dynamic client registration against a URL
331
+ // nobody has logged in to yet. Present tokens refresh silently; an absent
332
+ // one falls through to the 401 that `connectOne` maps to `needs-auth`.
333
+ const authProvider = this.refreshOnlyAuthProvider(config);
334
+ const options = { requestInit: { headers }, ...(authProvider ? { authProvider } : {}) };
335
+ const transport = config.transport === 'sse'
336
+ ? new SSEClientTransport(url, options)
337
+ : new StreamableHTTPClientTransport(url, options);
338
+ // Stored like stdio so teardown is uniform across transports.
339
+ connection.transport = transport;
340
+ // Known gap: HTTP/SSE transports do not observe a dropped remote session
341
+ // (no onclose signal we can rely on here), so such a server stays `ready`
342
+ // until a call fails. Not handled in this slice.
343
+ await this.connectClient(connection, transport);
344
+ }
345
+ /**
346
+ * A provider that refreshes a stored credential but never starts a login, or
347
+ * `undefined` when there is nothing stored to refresh.
348
+ *
349
+ * D2: a project server that has not been opted in gets no provider at all, so
350
+ * a repository cannot cause even a discovery request to an issuer it chose.
351
+ */
352
+ refreshOnlyAuthProvider(config) {
353
+ if (!this.oauthStore || config.url === undefined)
354
+ return undefined;
355
+ if (!this.oauthEligible(config))
356
+ return undefined;
357
+ if (this.oauthStore.getTokens(config.url) === undefined)
358
+ return undefined;
359
+ return createRefreshOnlyProvider({
360
+ serverName: config.name,
361
+ serverUrl: config.url,
362
+ store: this.oauthStore,
363
+ ...(config.clientMetadataUrl !== undefined ? { clientMetadataUrl: config.clientMetadataUrl } : {}),
364
+ ...(config.clientId !== undefined ? { clientId: config.clientId } : {}),
365
+ });
366
+ }
367
+ /** Whether this server's config is allowed to hold or obtain OAuth credentials (D2). */
368
+ oauthEligible(config) {
369
+ return config.provenance === 'user' || config.projectEnabledOverride === true;
370
+ }
371
+ /** The login details for a server, or undefined when it may not use OAuth. */
372
+ oauthTarget(name) {
373
+ const connection = this.connections.get(name);
374
+ const config = connection?.config;
375
+ if (!config || config.url === undefined || !this.oauthEligible(config))
376
+ return undefined;
377
+ return {
378
+ serverName: config.name,
379
+ serverUrl: config.url,
380
+ ...(config.clientMetadataUrl !== undefined ? { clientMetadataUrl: config.clientMetadataUrl } : {}),
381
+ ...(config.clientId !== undefined ? { clientId: config.clientId } : {}),
382
+ ...(config.redirectPorts !== undefined ? { redirectPorts: config.redirectPorts } : {}),
383
+ };
384
+ }
385
+ /**
386
+ * Re-runs one server's connection, used after `/mcp-login` stores a token.
387
+ *
388
+ * Clears the previous failure first so a re-entered failure is noticed (and
389
+ * announced) again rather than being swallowed as a duplicate.
390
+ */
391
+ async reconnect(name) {
392
+ const connection = this.connections.get(name);
393
+ if (!connection || this.isAbandoned(connection))
394
+ return;
395
+ await this.teardown(connection);
396
+ if (this.isAbandoned(connection))
397
+ return;
398
+ this.noticedFailures.delete(name);
399
+ connection.state = 'connecting';
400
+ delete connection.error;
401
+ connection.tools = [];
402
+ delete connection.stderrTail;
403
+ this.rebuildSnapshot();
404
+ await this.connectOne(connection);
405
+ }
406
+ async connectClient(connection, transport) {
407
+ const client = new Client({ name: 'term2', version: '0.0.0' });
408
+ client.setNotificationHandler('notifications/tools/list_changed', () => {
409
+ void this.handleListChanged(connection);
410
+ });
411
+ connection.client = client;
412
+ await client.connect(transport, { timeout: CONNECT_TIMEOUT_MS });
413
+ }
414
+ watchStdio(connection, transport) {
415
+ let tail = '';
416
+ transport.onclose = () => {
417
+ if (connection.closing || this.closed)
418
+ return;
419
+ // A stdio process exiting is terminal for that connection.
420
+ this.markFailed(connection, `stdio server process exited${connection.stderrTail ? `. stderr tail: ${connection.stderrTail}` : ''}`);
421
+ };
422
+ transport.stderr?.on('data', (chunk) => {
423
+ tail = (tail + chunk.toString('utf8')).slice(-STDERR_TAIL_CHARS);
424
+ connection.stderrTail = tail;
425
+ });
426
+ }
427
+ async handleListChanged(connection) {
428
+ if (connection.state !== 'ready' || this.isAbandoned(connection))
429
+ return;
430
+ try {
431
+ await this.refreshTools(connection, { cache: 'refresh' });
432
+ if (this.isAbandoned(connection))
433
+ return;
434
+ this.rebuildSnapshot();
435
+ }
436
+ catch (error) {
437
+ // close() aborts the in-flight list; that rejection is not a failure.
438
+ if (this.isAbandoned(connection))
439
+ return;
440
+ const detail = error instanceof Error ? error.message : String(error);
441
+ this.markFailed(connection, `tools/list after list_changed failed: ${detail}`);
442
+ }
443
+ }
444
+ async refreshTools(connection, options) {
445
+ const client = connection.client;
446
+ if (!client)
447
+ throw new Error('no client');
448
+ // No cursor: the client walks every page and returns the merged catalog.
449
+ const result = await client.listTools(undefined, { ...options, timeout: LIST_TIMEOUT_MS });
450
+ connection.tools = result.tools.map((tool) => ({
451
+ name: tool.name,
452
+ ...(tool.title !== undefined ? { title: tool.title } : {}),
453
+ ...(tool.description !== undefined ? { description: tool.description } : {}),
454
+ inputSchema: (tool.inputSchema ?? {}),
455
+ ...(tool.outputSchema !== undefined ? { outputSchema: tool.outputSchema } : {}),
456
+ ...(tool.annotations !== undefined ? { annotations: tool.annotations } : {}),
457
+ }));
458
+ }
459
+ markFailed(connection, error) {
460
+ // A closed manager never changes state or notifies listeners.
461
+ if (this.isAbandoned(connection))
462
+ return;
463
+ connection.state = 'failed';
464
+ connection.error = error;
465
+ connection.tools = [];
466
+ if (!this.noticedFailures.has(connection.config.name)) {
467
+ this.noticedFailures.add(connection.config.name);
468
+ this.onNotice?.(`MCP server "${connection.config.name}" failed: ${error}`);
469
+ }
470
+ this.rebuildSnapshot();
471
+ }
472
+ rebuildSnapshot() {
473
+ const next = Array.from(this.connections.values(), (connection) => ({
474
+ name: connection.config.name,
475
+ provenance: connection.config.provenance,
476
+ transport: connection.config.transport,
477
+ state: connection.state,
478
+ ...(connection.error !== undefined ? { error: connection.error } : {}),
479
+ tools: connection.tools,
480
+ }));
481
+ if (JSON.stringify(next) === JSON.stringify(this.snapshotCache))
482
+ return;
483
+ this.snapshotCache = next;
484
+ for (const listener of this.listeners)
485
+ listener();
486
+ }
487
+ }
488
+ //# sourceMappingURL=mcp-connection-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-connection-manager.js","sourceRoot":"","sources":["../../../source/services/mcp/mcp-connection-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,79 @@
1
+ /**
2
+ * The interactive half of MCP OAuth: bind a loopback redirect, drive the SDK's
3
+ * `auth()` through both legs, and persist the result via {@linkcode McpOAuthProvider}.
4
+ *
5
+ * This module owns the *mechanics* of a login, never the *policy* of when one
6
+ * may start. Plan decision D1 (2026-09-18) puts the trigger behind an explicit
7
+ * `/mcp-login <server>`: nothing here runs on its own, so a server returning 401
8
+ * mid-session can never pop a browser window. The connection manager only ever
9
+ * refreshes silently (see {@linkcode McpInteractiveLoginRequiredError}).
10
+ *
11
+ * Redirect ports follow D3: an ephemeral port first (RFC 8252), falling back to
12
+ * the server's configured `redirectPorts` for authorization servers that match
13
+ * the redirect against a registered allow-list.
14
+ */
15
+ import { auth as sdkAuth } from '@modelcontextprotocol/client';
16
+ import { McpOAuthProvider } from './mcp-oauth-provider.js';
17
+ import { McpOAuthStore } from './mcp-oauth-store.js';
18
+ /**
19
+ * Thrown by a refresh-only provider when the SDK concludes the user must visit
20
+ * an authorization server. The connection manager turns this into the
21
+ * `needs-auth` state rather than a browser window.
22
+ */
23
+ export declare class McpInteractiveLoginRequiredError extends Error {
24
+ readonly serverName: string;
25
+ constructor(serverName: string);
26
+ }
27
+ /** The exact text a user acts on when a server is waiting for a login. */
28
+ export declare const mcpNeedsAuthMessage: (serverName: string) => string;
29
+ export interface McpOAuthLoginOptions {
30
+ /** Config key of the server, used only in user-facing text. */
31
+ serverName: string;
32
+ /** The MCP server URL; the credential storage key. */
33
+ serverUrl: string;
34
+ store: McpOAuthStore;
35
+ /** CIMD document URL, when the server config names one. Skips DCR. */
36
+ clientMetadataUrl?: string;
37
+ /** Pre-registered client id, for servers offering neither DCR nor CIMD. */
38
+ clientId?: string;
39
+ /**
40
+ * Registered redirect ports to fall back to when the ephemeral port is not
41
+ * acceptable to the authorization server (D3). Tried in order after port 0.
42
+ */
43
+ redirectPorts?: readonly number[];
44
+ signal?: AbortSignal;
45
+ /** Receives the authorization URL so the caller can show it (headless hosts). */
46
+ onAuthorizationUrl?: (url: string) => void;
47
+ /** Injectable for tests; defaults to really launching a browser. */
48
+ openBrowser?: (url: string) => void;
49
+ /** Injectable for tests; defaults to the SDK's `auth()`. */
50
+ auth?: typeof sdkAuth;
51
+ }
52
+ export interface McpOAuthLoginResult {
53
+ /** True when a browser round trip happened; false when a refresh sufficed. */
54
+ readonly interactive: boolean;
55
+ /** The issuer the credential was filed under, when the SDK reported one. */
56
+ readonly issuer?: string;
57
+ }
58
+ /**
59
+ * Runs a full OAuth login for one MCP server and stores the tokens.
60
+ *
61
+ * Resolves without opening a browser when the stored refresh token still works,
62
+ * so re-running `/mcp-login` on a healthy server is cheap and safe.
63
+ */
64
+ export declare function runMcpOAuthLogin(options: McpOAuthLoginOptions): Promise<McpOAuthLoginResult>;
65
+ /**
66
+ * A provider that persists and refreshes but refuses to send the user anywhere.
67
+ *
68
+ * Handed to HTTP transports so an expired access token is renewed silently
69
+ * mid-session, while a genuinely unauthenticated server surfaces as `needs-auth`
70
+ * instead of hijacking the terminal with a browser launch.
71
+ */
72
+ export declare function createRefreshOnlyProvider(options: {
73
+ serverName: string;
74
+ serverUrl: string;
75
+ store: McpOAuthStore;
76
+ clientMetadataUrl?: string;
77
+ clientId?: string;
78
+ }): McpOAuthProvider;
79
+ //# sourceMappingURL=mcp-oauth-login.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-oauth-login.d.ts","sourceRoot":"","sources":["../../../source/services/mcp/mcp-oauth-login.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AACH,OAAO,EAAE,IAAI,IAAI,OAAO,EAAmB,MAAM,8BAA8B,CAAC;AAQhF,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAIrD;;;;GAIG;AACH,qBAAa,gCAAiC,SAAQ,KAAK;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM;IAAvC,YAAqB,UAAU,EAAE,MAAM,EAGtC;CACF;AAED,0EAA0E;AAC1E,eAAO,MAAM,mBAAmB,eAAgB,MAAM,KAAG,MAAwD,CAAC;AAElH,MAAM,WAAW,oBAAoB;IACnC,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,2EAA2E;IAC3E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,oEAAoE;IACpE,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,4DAA4D;IAC5D,IAAI,CAAC,EAAE,OAAO,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,mBAAmB;IAClC,8EAA8E;IAC9E,QAAQ,CAAC,WAAW,EAAE,OAAO,CAAC;IAC9B,4EAA4E;IAC5E,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CA+DlG;AAOD;;;;;;GAMG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,aAAa,CAAC;IACrB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,gBAAgB,CAanB"}