@akon-labs/nexus-cli 0.1.8 → 0.1.10

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 (320) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/LICENSE +1 -0
  3. package/README.md +3 -2
  4. package/dist/app-bridge.bundle.js +67 -0
  5. package/dist/cli.js +19934 -1869
  6. package/dist/core/agent-session.d.ts.map +1 -1
  7. package/dist/core/agent-session.js +1 -1
  8. package/dist/core/agent-session.js.map +1 -1
  9. package/dist/core/auto-model.d.ts +1 -1
  10. package/dist/core/auto-model.d.ts.map +1 -1
  11. package/dist/core/auto-model.js +1 -1
  12. package/dist/core/auto-model.js.map +1 -1
  13. package/dist/core/model-resolver.d.ts +2 -2
  14. package/dist/core/model-resolver.d.ts.map +1 -1
  15. package/dist/core/model-resolver.js +3 -3
  16. package/dist/core/model-resolver.js.map +1 -1
  17. package/dist/core/package-manager.d.ts +15 -0
  18. package/dist/core/package-manager.d.ts.map +1 -1
  19. package/dist/core/package-manager.js +50 -0
  20. package/dist/core/package-manager.js.map +1 -1
  21. package/dist/core/sdk.d.ts.map +1 -1
  22. package/dist/core/sdk.js +1 -1
  23. package/dist/core/sdk.js.map +1 -1
  24. package/dist/core/slash-commands.d.ts.map +1 -1
  25. package/dist/core/slash-commands.js +3 -3
  26. package/dist/core/slash-commands.js.map +1 -1
  27. package/dist/core/system-prompt.d.ts.map +1 -1
  28. package/dist/core/system-prompt.js +1 -1
  29. package/dist/core/system-prompt.js.map +1 -1
  30. package/dist/core/tools/index.d.ts +1 -1
  31. package/dist/core/tools/index.d.ts.map +1 -1
  32. package/dist/core/tools/index.js +5 -5
  33. package/dist/core/tools/index.js.map +1 -1
  34. package/dist/core/tools/websearch.d.ts.map +1 -1
  35. package/dist/core/tools/websearch.js +3 -3
  36. package/dist/core/tools/websearch.js.map +1 -1
  37. package/dist/extensions/gitnexus/gateway.d.ts +6 -6
  38. package/dist/extensions/gitnexus/gateway.d.ts.map +1 -1
  39. package/dist/extensions/gitnexus/gateway.js +4 -4
  40. package/dist/extensions/gitnexus/gateway.js.map +1 -1
  41. package/dist/extensions/gitnexus/index.d.ts.map +1 -1
  42. package/dist/extensions/gitnexus/index.js +4 -2
  43. package/dist/extensions/gitnexus/index.js.map +1 -1
  44. package/dist/extensions/mcp/abort.d.ts +3 -0
  45. package/dist/extensions/mcp/abort.d.ts.map +1 -0
  46. package/dist/extensions/mcp/abort.js +41 -0
  47. package/dist/extensions/mcp/abort.js.map +1 -0
  48. package/dist/extensions/mcp/agent-dir.d.ts +6 -0
  49. package/dist/extensions/mcp/agent-dir.d.ts.map +1 -0
  50. package/dist/extensions/mcp/agent-dir.js +18 -0
  51. package/dist/extensions/mcp/agent-dir.js.map +1 -0
  52. package/dist/extensions/mcp/agent-plugin-loader.d.ts +9 -0
  53. package/dist/extensions/mcp/agent-plugin-loader.d.ts.map +1 -0
  54. package/dist/extensions/mcp/agent-plugin-loader.js +384 -0
  55. package/dist/extensions/mcp/agent-plugin-loader.js.map +1 -0
  56. package/dist/extensions/mcp/app-bridge.bundle.js +67 -0
  57. package/dist/extensions/mcp/commands.d.ts +27 -0
  58. package/dist/extensions/mcp/commands.d.ts.map +1 -0
  59. package/dist/extensions/mcp/commands.js +629 -0
  60. package/dist/extensions/mcp/commands.js.map +1 -0
  61. package/dist/extensions/mcp/config.d.ts +121 -38
  62. package/dist/extensions/mcp/config.d.ts.map +1 -1
  63. package/dist/extensions/mcp/config.js +1030 -70
  64. package/dist/extensions/mcp/config.js.map +1 -1
  65. package/dist/extensions/mcp/consent-manager.d.ts +14 -0
  66. package/dist/extensions/mcp/consent-manager.d.ts.map +1 -0
  67. package/dist/extensions/mcp/consent-manager.js +60 -0
  68. package/dist/extensions/mcp/consent-manager.js.map +1 -0
  69. package/dist/extensions/mcp/direct-tools.d.ts +11 -0
  70. package/dist/extensions/mcp/direct-tools.d.ts.map +1 -0
  71. package/dist/extensions/mcp/direct-tools.js +562 -0
  72. package/dist/extensions/mcp/direct-tools.js.map +1 -0
  73. package/dist/extensions/mcp/elicitation-handler.d.ts +18 -0
  74. package/dist/extensions/mcp/elicitation-handler.d.ts.map +1 -0
  75. package/dist/extensions/mcp/elicitation-handler.js +320 -0
  76. package/dist/extensions/mcp/elicitation-handler.js.map +1 -0
  77. package/dist/extensions/mcp/error-signal.d.ts +16 -0
  78. package/dist/extensions/mcp/error-signal.d.ts.map +1 -0
  79. package/dist/extensions/mcp/error-signal.js +22 -0
  80. package/dist/extensions/mcp/error-signal.js.map +1 -0
  81. package/dist/extensions/mcp/errors.d.ts +104 -0
  82. package/dist/extensions/mcp/errors.d.ts.map +1 -0
  83. package/dist/extensions/mcp/errors.js +171 -0
  84. package/dist/extensions/mcp/errors.js.map +1 -0
  85. package/dist/extensions/mcp/glimpse-ui.d.ts +10 -0
  86. package/dist/extensions/mcp/glimpse-ui.d.ts.map +1 -0
  87. package/dist/extensions/mcp/glimpse-ui.js +67 -0
  88. package/dist/extensions/mcp/glimpse-ui.js.map +1 -0
  89. package/dist/extensions/mcp/host-html-template.d.ts +17 -0
  90. package/dist/extensions/mcp/host-html-template.d.ts.map +1 -0
  91. package/dist/extensions/mcp/host-html-template.js +442 -0
  92. package/dist/extensions/mcp/host-html-template.js.map +1 -0
  93. package/dist/extensions/mcp/index.d.ts +20 -15
  94. package/dist/extensions/mcp/index.d.ts.map +1 -1
  95. package/dist/extensions/mcp/index.js +1064 -82
  96. package/dist/extensions/mcp/index.js.map +1 -1
  97. package/dist/extensions/mcp/init.d.ts +28 -0
  98. package/dist/extensions/mcp/init.d.ts.map +1 -0
  99. package/dist/extensions/mcp/init.js +631 -0
  100. package/dist/extensions/mcp/init.js.map +1 -0
  101. package/dist/extensions/mcp/json-schema-validator.d.ts +3 -0
  102. package/dist/extensions/mcp/json-schema-validator.d.ts.map +1 -0
  103. package/dist/extensions/mcp/json-schema-validator.js +53 -0
  104. package/dist/extensions/mcp/json-schema-validator.js.map +1 -0
  105. package/dist/extensions/mcp/lifecycle.d.ts +56 -0
  106. package/dist/extensions/mcp/lifecycle.d.ts.map +1 -0
  107. package/dist/extensions/mcp/lifecycle.js +395 -0
  108. package/dist/extensions/mcp/lifecycle.js.map +1 -0
  109. package/dist/extensions/mcp/logger.d.ts +52 -0
  110. package/dist/extensions/mcp/logger.d.ts.map +1 -0
  111. package/dist/extensions/mcp/logger.js +134 -0
  112. package/dist/extensions/mcp/logger.js.map +1 -0
  113. package/dist/extensions/mcp/mcp-auth-flow.d.ts +117 -0
  114. package/dist/extensions/mcp/mcp-auth-flow.d.ts.map +1 -0
  115. package/dist/extensions/mcp/mcp-auth-flow.js +869 -0
  116. package/dist/extensions/mcp/mcp-auth-flow.js.map +1 -0
  117. package/dist/extensions/mcp/mcp-auth.d.ts +162 -0
  118. package/dist/extensions/mcp/mcp-auth.d.ts.map +1 -0
  119. package/dist/extensions/mcp/mcp-auth.js +897 -0
  120. package/dist/extensions/mcp/mcp-auth.js.map +1 -0
  121. package/dist/extensions/mcp/mcp-bearer-store.d.ts +25 -0
  122. package/dist/extensions/mcp/mcp-bearer-store.d.ts.map +1 -0
  123. package/dist/extensions/mcp/mcp-bearer-store.js +350 -0
  124. package/dist/extensions/mcp/mcp-bearer-store.js.map +1 -0
  125. package/dist/extensions/mcp/mcp-callback-server.d.ts +54 -0
  126. package/dist/extensions/mcp/mcp-callback-server.d.ts.map +1 -0
  127. package/dist/extensions/mcp/mcp-callback-server.js +454 -0
  128. package/dist/extensions/mcp/mcp-callback-server.js.map +1 -0
  129. package/dist/extensions/mcp/mcp-code.d.ts +48 -0
  130. package/dist/extensions/mcp/mcp-code.d.ts.map +1 -0
  131. package/dist/extensions/mcp/mcp-code.js +358 -0
  132. package/dist/extensions/mcp/mcp-code.js.map +1 -0
  133. package/dist/extensions/mcp/mcp-keyring-helper.cjs +89 -0
  134. package/dist/extensions/mcp/mcp-oauth-provider.d.ts +135 -0
  135. package/dist/extensions/mcp/mcp-oauth-provider.d.ts.map +1 -0
  136. package/dist/extensions/mcp/mcp-oauth-provider.js +491 -0
  137. package/dist/extensions/mcp/mcp-oauth-provider.js.map +1 -0
  138. package/dist/extensions/mcp/mcp-output-guard.d.ts +59 -0
  139. package/dist/extensions/mcp/mcp-output-guard.d.ts.map +1 -0
  140. package/dist/extensions/mcp/mcp-output-guard.js +343 -0
  141. package/dist/extensions/mcp/mcp-output-guard.js.map +1 -0
  142. package/dist/extensions/mcp/mcp-panel.d.ts +71 -0
  143. package/dist/extensions/mcp/mcp-panel.d.ts.map +1 -0
  144. package/dist/extensions/mcp/mcp-panel.js +973 -0
  145. package/dist/extensions/mcp/mcp-panel.js.map +1 -0
  146. package/dist/extensions/mcp/mcp-probe.d.ts +7 -0
  147. package/dist/extensions/mcp/mcp-probe.d.ts.map +1 -0
  148. package/dist/extensions/mcp/mcp-probe.js +155 -0
  149. package/dist/extensions/mcp/mcp-probe.js.map +1 -0
  150. package/dist/extensions/mcp/mcp-script-worker.mjs +130 -0
  151. package/dist/extensions/mcp/mcp-setup-panel.d.ts +85 -0
  152. package/dist/extensions/mcp/mcp-setup-panel.d.ts.map +1 -0
  153. package/dist/extensions/mcp/mcp-setup-panel.js +618 -0
  154. package/dist/extensions/mcp/mcp-setup-panel.js.map +1 -0
  155. package/dist/extensions/mcp/mcp-status.d.ts +12 -0
  156. package/dist/extensions/mcp/mcp-status.d.ts.map +1 -0
  157. package/dist/extensions/mcp/mcp-status.js +98 -0
  158. package/dist/extensions/mcp/mcp-status.js.map +1 -0
  159. package/dist/extensions/mcp/mcp-trace.d.ts +95 -0
  160. package/dist/extensions/mcp/mcp-trace.d.ts.map +1 -0
  161. package/dist/extensions/mcp/mcp-trace.js +252 -0
  162. package/dist/extensions/mcp/mcp-trace.js.map +1 -0
  163. package/dist/extensions/mcp/metadata-cache.d.ts +20 -0
  164. package/dist/extensions/mcp/metadata-cache.d.ts.map +1 -0
  165. package/dist/extensions/mcp/metadata-cache.js +318 -0
  166. package/dist/extensions/mcp/metadata-cache.js.map +1 -0
  167. package/dist/extensions/mcp/npx-resolver.d.ts +7 -0
  168. package/dist/extensions/mcp/npx-resolver.d.ts.map +1 -0
  169. package/dist/extensions/mcp/npx-resolver.js +505 -0
  170. package/dist/extensions/mcp/npx-resolver.js.map +1 -0
  171. package/dist/extensions/mcp/oauth.d.ts +21 -0
  172. package/dist/extensions/mcp/oauth.d.ts.map +1 -0
  173. package/dist/extensions/mcp/oauth.js +15 -0
  174. package/dist/extensions/mcp/oauth.js.map +1 -0
  175. package/dist/extensions/mcp/onboarding-state.d.ts +13 -0
  176. package/dist/extensions/mcp/onboarding-state.d.ts.map +1 -0
  177. package/dist/extensions/mcp/onboarding-state.js +65 -0
  178. package/dist/extensions/mcp/onboarding-state.js.map +1 -0
  179. package/dist/extensions/mcp/package-mcp-loader.d.ts +3 -0
  180. package/dist/extensions/mcp/package-mcp-loader.d.ts.map +1 -0
  181. package/dist/extensions/mcp/package-mcp-loader.js +170 -0
  182. package/dist/extensions/mcp/package-mcp-loader.js.map +1 -0
  183. package/dist/extensions/mcp/panel-keys.d.ts +21 -0
  184. package/dist/extensions/mcp/panel-keys.d.ts.map +1 -0
  185. package/dist/extensions/mcp/panel-keys.js +29 -0
  186. package/dist/extensions/mcp/panel-keys.js.map +1 -0
  187. package/dist/extensions/mcp/prompts.d.ts +63 -0
  188. package/dist/extensions/mcp/prompts.d.ts.map +1 -0
  189. package/dist/extensions/mcp/prompts.js +297 -0
  190. package/dist/extensions/mcp/prompts.js.map +1 -0
  191. package/dist/extensions/mcp/proxy-modes.d.ts +15 -0
  192. package/dist/extensions/mcp/proxy-modes.d.ts.map +1 -0
  193. package/dist/extensions/mcp/proxy-modes.js +1421 -0
  194. package/dist/extensions/mcp/proxy-modes.js.map +1 -0
  195. package/dist/extensions/mcp/request-headers-command.d.ts +11 -0
  196. package/dist/extensions/mcp/request-headers-command.d.ts.map +1 -0
  197. package/dist/extensions/mcp/request-headers-command.js +334 -0
  198. package/dist/extensions/mcp/request-headers-command.js.map +1 -0
  199. package/dist/extensions/mcp/resource-tools.d.ts +2 -0
  200. package/dist/extensions/mcp/resource-tools.d.ts.map +1 -0
  201. package/dist/extensions/mcp/resource-tools.js +15 -0
  202. package/dist/extensions/mcp/resource-tools.js.map +1 -0
  203. package/dist/extensions/mcp/runtime-owner.d.ts +14 -0
  204. package/dist/extensions/mcp/runtime-owner.d.ts.map +1 -0
  205. package/dist/extensions/mcp/runtime-owner.js +84 -0
  206. package/dist/extensions/mcp/runtime-owner.js.map +1 -0
  207. package/dist/extensions/mcp/sampling-handler.d.ts +18 -0
  208. package/dist/extensions/mcp/sampling-handler.d.ts.map +1 -0
  209. package/dist/extensions/mcp/sampling-handler.js +229 -0
  210. package/dist/extensions/mcp/sampling-handler.js.map +1 -0
  211. package/dist/extensions/mcp/search-ranking.d.ts +25 -0
  212. package/dist/extensions/mcp/search-ranking.d.ts.map +1 -0
  213. package/dist/extensions/mcp/search-ranking.js +234 -0
  214. package/dist/extensions/mcp/search-ranking.js.map +1 -0
  215. package/dist/extensions/mcp/server-manager.d.ts +116 -0
  216. package/dist/extensions/mcp/server-manager.d.ts.map +1 -0
  217. package/dist/extensions/mcp/server-manager.js +1052 -0
  218. package/dist/extensions/mcp/server-manager.js.map +1 -0
  219. package/dist/extensions/mcp/session-recovery.d.ts +27 -0
  220. package/dist/extensions/mcp/session-recovery.d.ts.map +1 -0
  221. package/dist/extensions/mcp/session-recovery.js +140 -0
  222. package/dist/extensions/mcp/session-recovery.js.map +1 -0
  223. package/dist/extensions/mcp/skills/mcp-scripting/SKILL.md +38 -0
  224. package/dist/extensions/mcp/state.d.ts +62 -0
  225. package/dist/extensions/mcp/state.d.ts.map +1 -0
  226. package/dist/extensions/mcp/state.js +2 -0
  227. package/dist/extensions/mcp/state.js.map +1 -0
  228. package/dist/extensions/mcp/tool-approval.d.ts +11 -0
  229. package/dist/extensions/mcp/tool-approval.d.ts.map +1 -0
  230. package/dist/extensions/mcp/tool-approval.js +156 -0
  231. package/dist/extensions/mcp/tool-approval.js.map +1 -0
  232. package/dist/extensions/mcp/tool-metadata.d.ts +11 -0
  233. package/dist/extensions/mcp/tool-metadata.d.ts.map +1 -0
  234. package/dist/extensions/mcp/tool-metadata.js +264 -0
  235. package/dist/extensions/mcp/tool-metadata.js.map +1 -0
  236. package/dist/extensions/mcp/tool-registrar.d.ts +21 -0
  237. package/dist/extensions/mcp/tool-registrar.d.ts.map +1 -0
  238. package/dist/extensions/mcp/tool-registrar.js +229 -0
  239. package/dist/extensions/mcp/tool-registrar.js.map +1 -0
  240. package/dist/extensions/mcp/tool-result-renderer.d.ts +83 -0
  241. package/dist/extensions/mcp/tool-result-renderer.d.ts.map +1 -0
  242. package/dist/extensions/mcp/tool-result-renderer.js +345 -0
  243. package/dist/extensions/mcp/tool-result-renderer.js.map +1 -0
  244. package/dist/extensions/mcp/ts-shape.d.ts +3 -0
  245. package/dist/extensions/mcp/ts-shape.d.ts.map +1 -0
  246. package/dist/extensions/mcp/ts-shape.js +160 -0
  247. package/dist/extensions/mcp/ts-shape.js.map +1 -0
  248. package/dist/extensions/mcp/types.d.ts +521 -0
  249. package/dist/extensions/mcp/types.d.ts.map +1 -0
  250. package/dist/extensions/mcp/types.js +294 -0
  251. package/dist/extensions/mcp/types.js.map +1 -0
  252. package/dist/extensions/mcp/ui-app-bridge-helpers.d.ts +7 -0
  253. package/dist/extensions/mcp/ui-app-bridge-helpers.d.ts.map +1 -0
  254. package/dist/extensions/mcp/ui-app-bridge-helpers.js +37 -0
  255. package/dist/extensions/mcp/ui-app-bridge-helpers.js.map +1 -0
  256. package/dist/extensions/mcp/ui-resource-handler.d.ts +18 -0
  257. package/dist/extensions/mcp/ui-resource-handler.d.ts.map +1 -0
  258. package/dist/extensions/mcp/ui-resource-handler.js +210 -0
  259. package/dist/extensions/mcp/ui-resource-handler.js.map +1 -0
  260. package/dist/extensions/mcp/ui-server.d.ts +52 -0
  261. package/dist/extensions/mcp/ui-server.d.ts.map +1 -0
  262. package/dist/extensions/mcp/ui-server.js +740 -0
  263. package/dist/extensions/mcp/ui-server.js.map +1 -0
  264. package/dist/extensions/mcp/ui-session.d.ts +40 -0
  265. package/dist/extensions/mcp/ui-session.d.ts.map +1 -0
  266. package/dist/extensions/mcp/ui-session.js +477 -0
  267. package/dist/extensions/mcp/ui-session.js.map +1 -0
  268. package/dist/extensions/mcp/ui-stream-types.d.ts +105 -0
  269. package/dist/extensions/mcp/ui-stream-types.d.ts.map +1 -0
  270. package/dist/extensions/mcp/ui-stream-types.js +61 -0
  271. package/dist/extensions/mcp/ui-stream-types.js.map +1 -0
  272. package/dist/extensions/mcp/ui-tool-visibility.d.ts +5 -0
  273. package/dist/extensions/mcp/ui-tool-visibility.d.ts.map +1 -0
  274. package/dist/extensions/mcp/ui-tool-visibility.js +27 -0
  275. package/dist/extensions/mcp/ui-tool-visibility.js.map +1 -0
  276. package/dist/extensions/mcp/unix-socket-transport.d.ts +15 -0
  277. package/dist/extensions/mcp/unix-socket-transport.d.ts.map +1 -0
  278. package/dist/extensions/mcp/unix-socket-transport.js +85 -0
  279. package/dist/extensions/mcp/unix-socket-transport.js.map +1 -0
  280. package/dist/extensions/mcp/utils.d.ts +32 -0
  281. package/dist/extensions/mcp/utils.d.ts.map +1 -0
  282. package/dist/extensions/mcp/utils.js +336 -0
  283. package/dist/extensions/mcp/utils.js.map +1 -0
  284. package/dist/extensions/subagent/index.d.ts +62 -3
  285. package/dist/extensions/subagent/index.d.ts.map +1 -1
  286. package/dist/extensions/subagent/index.js +193 -58
  287. package/dist/extensions/subagent/index.js.map +1 -1
  288. package/dist/extensions/web-access.d.ts.map +1 -1
  289. package/dist/extensions/web-access.js +1 -1
  290. package/dist/extensions/web-access.js.map +1 -1
  291. package/dist/index.d.ts +2 -0
  292. package/dist/index.d.ts.map +1 -1
  293. package/dist/index.js +20074 -2004
  294. package/dist/index.js.map +1 -1
  295. package/dist/mcp-keyring-helper.cjs +89 -0
  296. package/dist/mcp-script-worker.mjs +130 -0
  297. package/dist/modes/interactive/components/model-selector.d.ts.map +1 -1
  298. package/dist/modes/interactive/components/model-selector.js +1 -1
  299. package/dist/modes/interactive/components/model-selector.js.map +1 -1
  300. package/dist/modes/interactive/components/response-separator.d.ts +1 -1
  301. package/dist/modes/interactive/components/response-separator.d.ts.map +1 -1
  302. package/dist/modes/interactive/components/response-separator.js +1 -1
  303. package/dist/modes/interactive/components/response-separator.js.map +1 -1
  304. package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
  305. package/dist/modes/interactive/interactive-mode.js +7 -5
  306. package/dist/modes/interactive/interactive-mode.js.map +1 -1
  307. package/dist/rpc-entry.js +19934 -1869
  308. package/dist/skills/mcp-scripting/SKILL.md +38 -0
  309. package/dist/vendor/ai.js +282 -207
  310. package/docs/mcp.md +178 -0
  311. package/docs/pi-subagents.md +75 -0
  312. package/docs/quickstart.md +1 -1
  313. package/docs/usage.md +2 -1
  314. package/examples/extensions/pi-subagents-worker-policy.ts +86 -0
  315. package/npm-shrinkwrap.json +763 -6
  316. package/package.json +15 -4
  317. package/dist/extensions/mcp/client.d.ts +0 -86
  318. package/dist/extensions/mcp/client.d.ts.map +0 -1
  319. package/dist/extensions/mcp/client.js +0 -275
  320. package/dist/extensions/mcp/client.js.map +0 -1
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-auth-flow.js","sourceRoot":"","sources":["../../../src/extensions/mcp/mcp-auth-flow.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCP Auth Flow\n *\n * High-level OAuth flow management using the MCP SDK's built-in auth functions.\n */\n\nimport {\n\ttype AuthOptions,\n\textractWWWAuthenticateParams,\n\tLATEST_PROTOCOL_VERSION,\n\tauth as runSdkAuth,\n\tUnauthorizedError,\n} from \"@modelcontextprotocol/client\";\nimport open from \"open\";\nimport { VERSION } from \"../../config.ts\";\nimport { abortable, throwIfAborted } from \"./abort.ts\";\nimport {\n\ttype AuthStorageOptions,\n\tclearAllCredentials,\n\tclearClientInfo,\n\tclearCodeVerifier,\n\tclearOAuthState,\n\tclearTokens,\n\tgetAuthBaseDir,\n\tgetAuthForUrl,\n\tgetOAuthState,\n\thasStoredTokens,\n\tisTokenExpired,\n\tOAuthCredentialStoreError,\n\ttype StoredTokens,\n} from \"./mcp-auth.ts\";\nimport {\n\tcancelPendingCallback,\n\tensureCallbackServer,\n\treleaseCallbackServer,\n\tstopCallbackServer,\n\tstopCallbackServerIfIdle,\n\twaitForCallback,\n} from \"./mcp-callback-server.ts\";\nimport { type McpOAuthConfig, McpOAuthProvider } from \"./mcp-oauth-provider.ts\";\nimport { combineAbortSignals, isAbortError } from \"./runtime-owner.ts\";\nimport { isServerDisabled, type ServerEntry } from \"./types.ts\";\nimport { formatTerminalError, interpolateEnvRecord, interpolateEnvVars } from \"./utils.ts\";\n\n/** Auth status for a server */\nexport type AuthStatus = \"authenticated\" | \"expired\" | \"not_authenticated\";\n\nexport interface McpOAuthRuntime {\n\treadonly signal: AbortSignal;\n}\n\nexport interface AuthenticateOptions {\n\tonAuthorizationUrl?: (authorizationUrl: string) => void | Promise<void>;\n\tonAuthorizationInput?: (authorizationUrl: string, signal: AbortSignal) => Promise<string | undefined>;\n\tauthStorageOptions?: AuthStorageOptions;\n\tsignal?: AbortSignal;\n\truntime?: McpOAuthRuntime;\n\tskipIssuerMetadataValidation?: boolean;\n}\n\ntype AuthDiscovery = Pick<AuthOptions, \"resourceMetadataUrl\" | \"scope\" | \"skipIssuerMetadataValidation\">;\n\nfunction applyOAuthConfig(discovery: AuthDiscovery, config: McpOAuthConfig): AuthDiscovery {\n\treturn {\n\t\t...discovery,\n\t\t...(config.scope !== undefined ? { scope: config.scope } : {}),\n\t\t...(config.skipIssuerMetadataValidation === true ? { skipIssuerMetadataValidation: true } : {}),\n\t};\n}\n\ntype PendingAuth = {\n\tserverName: string;\n\tauthProvider: McpOAuthProvider;\n\tserverUrl: string;\n\tauthorizationUrl: string;\n\tdiscovery: AuthDiscovery;\n\tauthStorageOptions: AuthStorageOptions;\n};\n\ntype RuntimeState = {\n\tcontroller: AbortController;\n\tgeneration: number;\n\tpendingAuths: Map<string, PendingAuth>;\n\tpendingAuthStates: Map<string, string>;\n\tpendingAuthCleanupTimers: Map<string, ReturnType<typeof setTimeout>>;\n\tpendingAuthentications: Map<string, Promise<AuthStatus>>;\n};\n\nconst runtimeStates = new WeakMap<McpOAuthRuntime, RuntimeState>();\nconst activeRuntimes = new Set<McpOAuthRuntime>();\n\nexport function createOAuthRuntime(signal?: AbortSignal): McpOAuthRuntime {\n\tconst controller = new AbortController();\n\tconst runtime = { signal: combineAbortSignals(signal, controller.signal)! } satisfies McpOAuthRuntime;\n\truntimeStates.set(runtime, {\n\t\tcontroller,\n\t\tgeneration: 0,\n\t\tpendingAuths: new Map(),\n\t\tpendingAuthStates: new Map(),\n\t\tpendingAuthCleanupTimers: new Map(),\n\t\tpendingAuthentications: new Map(),\n\t});\n\tactiveRuntimes.add(runtime);\n\treturn runtime;\n}\n\nlet legacyRuntime = createOAuthRuntime();\nactiveRuntimes.delete(legacyRuntime);\n\nfunction getRuntime(options?: AuthenticateOptions): McpOAuthRuntime {\n\tif (options?.runtime) {\n\t\toptions.runtime.signal.throwIfAborted();\n\t\tactiveRuntimes.add(options.runtime);\n\t\treturn options.runtime;\n\t}\n\tif (legacyRuntime.signal.aborted) legacyRuntime = createOAuthRuntime();\n\tactiveRuntimes.add(legacyRuntime);\n\treturn legacyRuntime;\n}\n\nfunction getRuntimeState(runtime: McpOAuthRuntime): RuntimeState {\n\tconst state = runtimeStates.get(runtime);\n\tif (!state) throw new Error(\"Unknown OAuth runtime\");\n\treturn state;\n}\n\nfunction getPendingAuthKey(serverName: string, options: AuthStorageOptions): string {\n\treturn `${serverName}|${getAuthBaseDir(options)}`;\n}\n\nexport function hasPendingAuth(serverName: string, options?: AuthStorageOptions, runtime?: McpOAuthRuntime): boolean {\n\tconst state = getRuntimeState(runtime ?? legacyRuntime);\n\tif (options) {\n\t\treturn state.pendingAuths.has(getPendingAuthKey(serverName, options));\n\t}\n\treturn Array.from(state.pendingAuths.values()).some((pendingAuth) => pendingAuth.serverName === serverName);\n}\n\n/** Timeout for manual auth completion (5 minutes) */\nconst MANUAL_AUTH_TIMEOUT_MS = 5 * 60 * 1000;\n\n/**\n * Generate a cryptographically secure random state parameter.\n */\nfunction generateState(): string {\n\treturn Array.from(crypto.getRandomValues(new Uint8Array(32)))\n\t\t.map((b) => b.toString(16).padStart(2, \"0\"))\n\t\t.join(\"\");\n}\n\n/**\n * Extract OAuth configuration from a ServerEntry.\n */\nexport function extractOAuthConfig(definition: ServerEntry): McpOAuthConfig {\n\tif (definition.oauth === false) {\n\t\treturn {};\n\t}\n\n\tconst config: McpOAuthConfig = {};\n\tif (definition.oauth?.grantType !== undefined) config.grantType = definition.oauth.grantType;\n\tif (definition.oauth?.clientId !== undefined) {\n\t\tif (typeof definition.oauth.clientId !== \"string\") throw new Error(\"OAuth clientId must be a string\");\n\t\tconfig.clientId = interpolateEnvVars(definition.oauth.clientId);\n\t}\n\tif (definition.oauth?.clientSecret !== undefined) {\n\t\tif (typeof definition.oauth.clientSecret !== \"string\") throw new Error(\"OAuth clientSecret must be a string\");\n\t\t// Preserve command expressions for the provider; interpolation remains eager for ordinary values.\n\t\tconfig.clientSecret = definition.oauth.clientSecret.startsWith(\"!\")\n\t\t\t? definition.oauth.clientSecret\n\t\t\t: interpolateEnvVars(definition.oauth.clientSecret);\n\t}\n\tif (definition.oauth?.scope !== undefined) {\n\t\tif (typeof definition.oauth.scope !== \"string\") throw new Error(\"OAuth scope must be a string\");\n\t\tconfig.scope = interpolateEnvVars(definition.oauth.scope);\n\t}\n\tif (definition.oauth?.authorizationParams !== undefined) {\n\t\tconst params = definition.oauth.authorizationParams;\n\t\tif (!params || typeof params !== \"object\" || Array.isArray(params)) {\n\t\t\tthrow new Error(\"OAuth authorizationParams must be an object\");\n\t\t}\n\t\tconfig.authorizationParams = {};\n\t\tfor (const [key, value] of Object.entries(params)) {\n\t\t\tif (!key) throw new Error(\"OAuth authorizationParams keys must not be empty\");\n\t\t\tif (typeof value !== \"string\") throw new Error(`OAuth authorizationParams.${key} must be a string`);\n\t\t\tconfig.authorizationParams[key] = interpolateEnvVars(value);\n\t\t}\n\t}\n\tif (definition.oauth?.redirectUri !== undefined) {\n\t\tif (typeof definition.oauth.redirectUri !== \"string\") {\n\t\t\tthrow new Error(\"OAuth redirectUri must be a string\");\n\t\t}\n\t\tconst redirectUri = interpolateEnvVars(definition.oauth.redirectUri).trim();\n\t\tif (!redirectUri) {\n\t\t\tthrow new Error(\"OAuth redirectUri must not be empty\");\n\t\t}\n\t\tconfig.redirectUri = redirectUri;\n\t}\n\tif (definition.oauth?.clientName !== undefined) {\n\t\tif (typeof definition.oauth.clientName !== \"string\") {\n\t\t\tthrow new Error(\"OAuth clientName must be a string\");\n\t\t}\n\t\tconst clientName = interpolateEnvVars(definition.oauth.clientName).trim();\n\t\tif (!clientName) {\n\t\t\tthrow new Error(\"OAuth clientName must not be empty\");\n\t\t}\n\t\tconfig.clientName = clientName;\n\t}\n\tif (definition.oauth?.clientUri !== undefined) {\n\t\tif (typeof definition.oauth.clientUri !== \"string\") {\n\t\t\tthrow new Error(\"OAuth clientUri must be a string\");\n\t\t}\n\t\tconst clientUri = interpolateEnvVars(definition.oauth.clientUri).trim();\n\t\tif (!clientUri) {\n\t\t\tthrow new Error(\"OAuth clientUri must not be empty\");\n\t\t}\n\t\tconfig.clientUri = clientUri;\n\t}\n\tif (definition.oauth?.logoUri !== undefined) {\n\t\tif (typeof definition.oauth.logoUri !== \"string\") {\n\t\t\tthrow new Error(\"OAuth logoUri must be a string\");\n\t\t}\n\t\tconst logoUri = interpolateEnvVars(definition.oauth.logoUri).trim();\n\t\tif (!logoUri) {\n\t\t\tthrow new Error(\"OAuth logoUri must not be empty\");\n\t\t}\n\t\t// Consent screens fetch this server-side, so a local path silently renders\n\t\t// nothing. Fail here instead, where the message can say why.\n\t\tlet parsed: URL;\n\t\ttry {\n\t\t\tparsed = new URL(logoUri);\n\t\t} catch {\n\t\t\tthrow new Error(\"OAuth logoUri must be an absolute http(s) URL\");\n\t\t}\n\t\tif (parsed.protocol !== \"https:\" && parsed.protocol !== \"http:\") {\n\t\t\tthrow new Error(\"OAuth logoUri must be an absolute http(s) URL\");\n\t\t}\n\t\tconfig.logoUri = logoUri;\n\t}\n\tif (definition.oauth?.skipIssuerMetadataValidation !== undefined) {\n\t\tif (typeof definition.oauth.skipIssuerMetadataValidation !== \"boolean\") {\n\t\t\tthrow new Error(\"OAuth skipIssuerMetadataValidation must be a boolean\");\n\t\t}\n\t\tconfig.skipIssuerMetadataValidation = definition.oauth.skipIssuerMetadataValidation;\n\t}\n\treturn config;\n}\n\nasync function probeAuthDiscovery(\n\tserverUrl: string,\n\tdefinition?: ServerEntry,\n\tsignal?: AbortSignal,\n): Promise<AuthDiscovery> {\n\t// Discovery must not execute config commands or send their source text.\n\tconst discoveryHeaders = definition?.headers\n\t\t? Object.fromEntries(\n\t\t\t\tObject.entries(definition.headers).filter(([, value]) => !value.startsWith(\"!\") || value.startsWith(\"!!\")),\n\t\t\t)\n\t\t: undefined;\n\tconst headers = new Headers(interpolateEnvRecord(discoveryHeaders));\n\theaders.set(\"content-type\", \"application/json\");\n\n\tconst controller = new AbortController();\n\tconst discoverySignal = combineAbortSignals(signal, controller.signal);\n\tconst timer = setTimeout(() => controller.abort(), 5000);\n\n\ttry {\n\t\theaders.set(\"accept\", \"application/json, text/event-stream\");\n\n\t\tconst response = await fetch(new URL(serverUrl), {\n\t\t\tmethod: \"POST\",\n\t\t\theaders,\n\t\t\tbody: JSON.stringify({\n\t\t\t\tjsonrpc: \"2.0\",\n\t\t\t\tid: 0,\n\t\t\t\tmethod: \"initialize\",\n\t\t\t\tparams: {\n\t\t\t\t\tprotocolVersion: LATEST_PROTOCOL_VERSION,\n\t\t\t\t\tcapabilities: {},\n\t\t\t\t\tclientInfo: { name: \"nexus-cli\", version: VERSION },\n\t\t\t\t},\n\t\t\t}),\n\t\t\t...(discoverySignal ? { signal: discoverySignal } : {}),\n\t\t});\n\t\tconst { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n\t\tawait response.body?.cancel().catch(() => {});\n\t\treturn { ...(resourceMetadataUrl ? { resourceMetadataUrl } : {}), ...(scope ? { scope } : {}) };\n\t} catch (_error) {\n\t\tif (signal?.aborted) throwIfAborted(signal);\n\t\treturn {};\n\t} finally {\n\t\tclearTimeout(timer);\n\t}\n}\n\nfunction parseOAuthRedirectUri(redirectUri: string): { port: number; callbackHost: string; callbackPath: string } {\n\tlet url: URL;\n\ttry {\n\t\turl = new URL(redirectUri);\n\t} catch (error) {\n\t\tthrow new Error(`Invalid OAuth redirectUri: ${redirectUri}`, { cause: error });\n\t}\n\n\tconst hostname = url.hostname.toLowerCase();\n\tconst isLocalhost =\n\t\thostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\" || hostname === \"::1\";\n\tif (url.protocol !== \"http:\" || !isLocalhost) {\n\t\tthrow new Error(\"OAuth redirectUri must be an http:// localhost or loopback URI\");\n\t}\n\n\tif (url.username || url.password) {\n\t\tthrow new Error(\"OAuth redirectUri must not include username or password\");\n\t}\n\n\tif (url.hash) {\n\t\tthrow new Error(\"OAuth redirectUri must not include a fragment\");\n\t}\n\n\tif (!url.port) {\n\t\tthrow new Error(\"OAuth redirectUri must include an explicit numeric port\");\n\t}\n\n\tconst port = Number.parseInt(url.port, 10);\n\tif (!Number.isInteger(port) || port <= 0 || port > 65535) {\n\t\tthrow new Error(\"OAuth redirectUri must include an explicit numeric port\");\n\t}\n\n\tconst callbackHost = hostname === \"[::1]\" ? \"::1\" : hostname;\n\treturn { port, callbackHost, callbackPath: url.pathname };\n}\n\n/**\n * Start OAuth authentication flow for a server.\n * Returns the authorization URL when browser authorization is required.\n */\nexport async function startAuth(\n\tserverName: string,\n\tserverUrl: string,\n\tdefinition?: ServerEntry,\n\toptions: AuthenticateOptions = {},\n): Promise<{ authorizationUrl: string }> {\n\tif (isServerDisabled(definition)) throw new Error(`MCP server \"${serverName}\" is disabled`);\n\tconst runtime = getRuntime(options);\n\tconst runtimeState = getRuntimeState(runtime);\n\tconst config = definition ? extractOAuthConfig(definition) : {};\n\tconst authStorageOptions = options.authStorageOptions ?? {};\n\tconst signal = combineAbortSignals(runtime.signal, options.signal);\n\tconst generation = runtimeState.generation;\n\tthrowIfAborted(signal);\n\n\tif (config.grantType === \"client_credentials\") {\n\t\tconst storedAuth = await getAuthForUrl(serverName, serverUrl, authStorageOptions);\n\t\tif (storedAuth?.clientInfo && !storedAuth.tokens && !config.clientId) {\n\t\t\tclearClientInfo(serverName, authStorageOptions);\n\t\t\tclearCodeVerifier(serverName, authStorageOptions);\n\t\t\tawait clearOAuthState(serverName, authStorageOptions);\n\t\t}\n\n\t\tconst authProvider = new McpOAuthProvider(\n\t\t\tserverName,\n\t\t\tserverUrl,\n\t\t\tconfig,\n\t\t\t{\n\t\t\t\tonRedirect: async () => {\n\t\t\t\t\tthrow new Error(\"Browser redirect is not used for client_credentials flow\");\n\t\t\t\t},\n\t\t\t},\n\t\t\tauthStorageOptions,\n\t\t\truntime.signal,\n\t\t);\n\t\ttry {\n\t\t\tconst discovery = applyOAuthConfig(await probeAuthDiscovery(serverUrl, definition, signal), config);\n\t\t\tthrowIfAborted(signal);\n\t\t\tconst result = await abortable(runSdkAuth(authProvider, { serverUrl, ...discovery }), signal);\n\t\t\tthrowIfAborted(signal);\n\t\t\tif (result !== \"AUTHORIZED\") {\n\t\t\t\tthrow new UnauthorizedError(\"Failed to authorize\");\n\t\t\t}\n\t\t\treturn { authorizationUrl: \"\" };\n\t\t} finally {\n\t\t\tauthProvider.deactivate();\n\t\t}\n\t}\n\n\tconst existingPendingAuth = runtimeState.pendingAuths.get(getPendingAuthKey(serverName, authStorageOptions));\n\tif (existingPendingAuth?.serverUrl === serverUrl) {\n\t\treturn { authorizationUrl: existingPendingAuth.authorizationUrl };\n\t}\n\n\tconst redirectCallback = config.redirectUri !== undefined ? parseOAuthRedirectUri(config.redirectUri) : undefined;\n\tconst oauthState = generateState();\n\n\ttry {\n\t\tawait ensureCallbackServer({\n\t\t\tstrictPort: Boolean(config.clientId) || config.redirectUri !== undefined,\n\t\t\toauthState,\n\t\t\treserveState: true,\n\t\t\t...(redirectCallback\n\t\t\t\t? {\n\t\t\t\t\t\tport: redirectCallback.port,\n\t\t\t\t\t\tcallbackHost: redirectCallback.callbackHost,\n\t\t\t\t\t\tcallbackPath: redirectCallback.callbackPath,\n\t\t\t\t\t}\n\t\t\t\t: {}),\n\t\t});\n\t\tthrowIfAborted(signal);\n\t} catch (error) {\n\t\treleaseCallbackServer(oauthState);\n\t\ttry {\n\t\t\tawait cleanupAndReleaseCallbackServerIfIdle(() => clearOAuthState(serverName, authStorageOptions));\n\t\t} catch (cleanupError) {\n\t\t\tthrow new AggregateError([error, cleanupError], \"OAuth startup cleanup failed\");\n\t\t}\n\t\tthrow error;\n\t}\n\n\tlet capturedUrl: URL | undefined;\n\tconst authProvider = new McpOAuthProvider(\n\t\tserverName,\n\t\tserverUrl,\n\t\tconfig,\n\t\t{\n\t\t\tonRedirect: async (url) => {\n\t\t\t\tcapturedUrl = url;\n\t\t\t},\n\t\t},\n\t\tauthStorageOptions,\n\t\truntime.signal,\n\t\toauthState,\n\t);\n\n\ttry {\n\t\tconst storedAuth = await getAuthForUrl(serverName, serverUrl, authStorageOptions);\n\t\tif (storedAuth?.clientInfo && !config.clientId) {\n\t\t\tif (!storedAuth.tokens) {\n\t\t\t\tclearClientInfo(serverName, authStorageOptions);\n\t\t\t\tclearCodeVerifier(serverName, authStorageOptions);\n\t\t\t\tawait clearOAuthState(serverName, authStorageOptions);\n\t\t\t} else {\n\t\t\t\tconst redirectUris = storedAuth.clientInfo.redirectUris;\n\t\t\t\tif (!Array.isArray(redirectUris) || !redirectUris.includes(authProvider.redirectUrl ?? \"\")) {\n\t\t\t\t\tclearClientInfo(serverName, authStorageOptions);\n\t\t\t\t\tclearTokens(serverName, authStorageOptions);\n\t\t\t\t\tclearCodeVerifier(serverName, authStorageOptions);\n\t\t\t\t\tawait clearOAuthState(serverName, authStorageOptions);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tthrowIfAborted(signal);\n\n\t\tconst discovery = applyOAuthConfig(await probeAuthDiscovery(serverUrl, definition, signal), config);\n\t\tthrowIfAborted(signal);\n\t\tconst result = await abortable(runSdkAuth(authProvider, { serverUrl, ...discovery }), signal);\n\t\tthrowIfAborted(signal);\n\t\tif (result === \"AUTHORIZED\") {\n\t\t\tauthProvider.deactivate();\n\t\t\treleaseCallbackServer(oauthState);\n\t\t\tawait clearOAuthState(serverName, authStorageOptions);\n\t\t\tawait stopCallbackServerIfIdle();\n\t\t\treturn { authorizationUrl: \"\" };\n\t\t}\n\t\tif (!capturedUrl) {\n\t\t\tthrow new UnauthorizedError(\"OAuth authorization URL was not provided\");\n\t\t}\n\t\tawait setPendingAuth(\n\t\t\truntime,\n\t\t\tserverName,\n\t\t\t{\n\t\t\t\tserverName,\n\t\t\t\tauthProvider,\n\t\t\t\tserverUrl,\n\t\t\t\tauthorizationUrl: capturedUrl.toString(),\n\t\t\t\tdiscovery,\n\t\t\t\tauthStorageOptions,\n\t\t\t},\n\t\t\toauthState,\n\t\t\tsignal,\n\t\t\tgeneration,\n\t\t);\n\t\treturn { authorizationUrl: capturedUrl.toString() };\n\t} catch (error) {\n\t\tauthProvider.deactivate();\n\t\ttry {\n\t\t\tawait clearPendingAuthAndReleaseIfIdle(runtime, serverName, oauthState, authStorageOptions);\n\t\t} catch (cleanupError) {\n\t\t\tthrow new AggregateError([error, cleanupError], \"OAuth startup cleanup failed\");\n\t\t}\n\t\tthrow error;\n\t}\n}\n\nasync function setPendingAuth(\n\truntime: McpOAuthRuntime,\n\tserverName: string,\n\tpendingAuth: PendingAuth,\n\toauthState: string,\n\tsignal?: AbortSignal,\n\tgeneration = getRuntimeState(runtime).generation,\n): Promise<void> {\n\tconst state = getRuntimeState(runtime);\n\tconst key = getPendingAuthKey(serverName, pendingAuth.authStorageOptions);\n\tawait clearPendingAuth(runtime, serverName, undefined, pendingAuth.authStorageOptions);\n\tthrowIfAborted(signal);\n\tif (generation !== state.generation) throw new Error(\"OAuth runtime stopped\");\n\tstate.pendingAuths.set(key, pendingAuth);\n\tstate.pendingAuthStates.set(key, oauthState);\n\tconst cleanupTimer = setTimeout(() => {\n\t\tvoid clearPendingAuthAndReleaseIfIdle(runtime, serverName, oauthState, pendingAuth.authStorageOptions).catch(\n\t\t\t(error) => {\n\t\t\t\tconsole.error(`MCP Auth: Timed-out flow cleanup failed: ${formatTerminalError(error)}`);\n\t\t\t},\n\t\t);\n\t}, MANUAL_AUTH_TIMEOUT_MS);\n\tcleanupTimer.unref?.();\n\tstate.pendingAuthCleanupTimers.set(key, cleanupTimer);\n}\n\nasync function clearPendingAuth(\n\truntime: McpOAuthRuntime,\n\tserverName: string,\n\toauthState?: string,\n\tfallbackStorageOptions: AuthStorageOptions = {},\n): Promise<void> {\n\tconst state = getRuntimeState(runtime);\n\tconst key = getPendingAuthKey(serverName, fallbackStorageOptions);\n\tconst pendingAuth = state.pendingAuths.get(key);\n\tconst authStorageOptions = pendingAuth?.authStorageOptions ?? fallbackStorageOptions;\n\tconst pendingState = state.pendingAuthStates.get(key);\n\tif (oauthState && pendingState && pendingState !== oauthState) return;\n\n\tconst timer = state.pendingAuthCleanupTimers.get(key);\n\tif (timer) {\n\t\tclearTimeout(timer);\n\t\tstate.pendingAuthCleanupTimers.delete(key);\n\t}\n\n\tpendingAuth?.authProvider.deactivate();\n\tstate.pendingAuths.delete(key);\n\tstate.pendingAuthStates.delete(key);\n\tconst stateToRelease = pendingState ?? oauthState;\n\tif (stateToRelease) {\n\t\tcancelPendingCallback(stateToRelease);\n\t\tconst storedState = await getOAuthState(serverName, authStorageOptions);\n\t\tif (storedState === stateToRelease) {\n\t\t\tawait clearOAuthState(serverName, authStorageOptions);\n\t\t}\n\t}\n}\n\nasync function clearPendingAuthAndReleaseIfIdle(\n\truntime: McpOAuthRuntime,\n\tserverName: string,\n\toauthState: string | undefined,\n\tfallbackStorageOptions: AuthStorageOptions = {},\n): Promise<void> {\n\tawait cleanupAndReleaseCallbackServerIfIdle(() =>\n\t\tclearPendingAuth(runtime, serverName, oauthState, fallbackStorageOptions),\n\t);\n}\n\nasync function cleanupAndReleaseCallbackServerIfIdle(cleanup: () => void | Promise<void>): Promise<void> {\n\tlet cleanupFailure: { error: unknown } | undefined;\n\ttry {\n\t\tawait cleanup();\n\t} catch (error) {\n\t\tcleanupFailure = { error };\n\t}\n\n\ttry {\n\t\tawait stopCallbackServerIfIdle();\n\t} catch (releaseError) {\n\t\tif (cleanupFailure) {\n\t\t\tthrow new AggregateError([cleanupFailure.error, releaseError], \"OAuth callback cleanup failed\");\n\t\t}\n\t\tthrow releaseError;\n\t}\n\n\tif (cleanupFailure) throw cleanupFailure.error;\n}\n\nfunction getSearchParamsFromInput(input: string): URLSearchParams | undefined {\n\ttry {\n\t\tconst url = new URL(input);\n\t\tconst params = new URLSearchParams(url.search);\n\t\tif (url.hash) {\n\t\t\tconst hash = url.hash.startsWith(\"#\") ? url.hash.slice(1) : url.hash;\n\t\t\tconst hashParams = new URLSearchParams(hash);\n\t\t\tfor (const [key, value] of hashParams) {\n\t\t\t\tif (!params.has(key)) params.set(key, value);\n\t\t\t}\n\t\t}\n\t\treturn params;\n\t} catch {\n\t\tconst query = input.includes(\"?\") ? input.slice(input.indexOf(\"?\") + 1) : input;\n\t\tconst params = new URLSearchParams(query.startsWith(\"#\") ? query.slice(1) : query);\n\t\treturn params.has(\"code\") || params.has(\"state\") || params.has(\"error\") ? params : undefined;\n\t}\n}\n\n/** Authorization code plus the optional RFC 9207 `iss` callback parameter. */\nexport interface AuthorizationCodeInput {\n\tcode: string;\n\tiss?: string;\n}\n\n/**\n * Extract an OAuth authorization code (and the RFC 9207 `iss` parameter, when\n * present) from either a raw code, a query string, or the full localhost\n * redirect URL copied from the browser address bar.\n */\nexport function parseAuthorizationRedirectInput(input: string, expectedState?: string): AuthorizationCodeInput {\n\tconst trimmed = input.trim();\n\tif (!trimmed) {\n\t\tthrow new Error(\"Authorization code or redirect URL is required\");\n\t}\n\n\tconst params = getSearchParamsFromInput(trimmed);\n\tif (params) {\n\t\tconst error = params.get(\"error\");\n\t\tif (error) {\n\t\t\tconst description = params.get(\"error_description\");\n\t\t\tthrow new Error(description ? `${error}: ${description}` : error);\n\t\t}\n\n\t\tconst state = params.get(\"state\");\n\t\tif (expectedState && !state) {\n\t\t\tthrow new Error(\"OAuth state missing from redirect URL\");\n\t\t}\n\t\tif (expectedState && state !== expectedState) {\n\t\t\tthrow new Error(\"OAuth state mismatch - potential CSRF attack\");\n\t\t}\n\n\t\tconst code = params.get(\"code\");\n\t\tif (code) {\n\t\t\tconst iss = params.get(\"iss\");\n\t\t\treturn { code, ...(iss !== null ? { iss } : {}) };\n\t\t}\n\t}\n\n\tif (/^[A-Za-z0-9._~+/=-]+$/.test(trimmed)) {\n\t\treturn { code: trimmed };\n\t}\n\n\tthrow new Error(\"Could not find an OAuth authorization code in the provided input\");\n}\n\n/**\n * Extract an OAuth authorization code from either a raw code, a query string,\n * or the full localhost redirect URL copied from the browser address bar.\n */\nexport function parseAuthorizationCodeInput(input: string, expectedState?: string): string {\n\treturn parseAuthorizationRedirectInput(input, expectedState).code;\n}\n\ntype AuthorizationResponse = {\n\tinput: AuthorizationCodeInput;\n\tsource: \"callback\" | \"manual\";\n};\n\n/**\n * Wait for either the localhost callback or a manually pasted redirect URL.\n * The manual input prompt is dismissed as soon as either path finishes.\n */\nexport async function waitForAuthorizationResponse(\n\tcallbackPromise: Promise<AuthorizationCodeInput>,\n\tauthorizationUrl: string,\n\texpectedState: string,\n\tonAuthorizationInput?: AuthenticateOptions[\"onAuthorizationInput\"],\n\tsignal?: AbortSignal,\n): Promise<AuthorizationResponse> {\n\tif (!onAuthorizationInput) {\n\t\treturn {\n\t\t\tinput: await abortable(callbackPromise, signal),\n\t\t\tsource: \"callback\",\n\t\t};\n\t}\n\n\tconst inputController = new AbortController();\n\ttry {\n\t\tconst response = await abortable(\n\t\t\tPromise.race([\n\t\t\t\tcallbackPromise.then((input) => ({ input, source: \"callback\" as const })),\n\t\t\t\tonAuthorizationInput(authorizationUrl, inputController.signal).then((input) => ({\n\t\t\t\t\tinput,\n\t\t\t\t\tsource: \"manual\" as const,\n\t\t\t\t})),\n\t\t\t]),\n\t\t\tsignal,\n\t\t);\n\n\t\tif (response.source === \"callback\") return response;\n\t\tif (!response.input?.trim()) throw new Error(\"OAuth authentication cancelled\");\n\t\tif (!getSearchParamsFromInput(response.input.trim())) {\n\t\t\tthrow new Error(\"Paste the full OAuth callback URL, including its code and state parameters\");\n\t\t}\n\t\treturn {\n\t\t\tinput: parseAuthorizationRedirectInput(response.input, expectedState),\n\t\t\tsource: \"manual\",\n\t\t};\n\t} finally {\n\t\tinputController.abort();\n\t}\n}\n\n/**\n * Complete OAuth authentication from manual user input.\n */\nexport async function completeAuthFromInput(\n\tserverName: string,\n\tinput: string,\n\toptions: AuthenticateOptions = {},\n): Promise<AuthStatus> {\n\tconst runtime = getRuntime(options);\n\tconst runtimeState = getRuntimeState(runtime);\n\tconst fallbackAuthStorageOptions = options.authStorageOptions ?? {};\n\tconst signal = combineAbortSignals(runtime.signal, options.signal);\n\tthrowIfAborted(signal);\n\tconst key = getPendingAuthKey(serverName, fallbackAuthStorageOptions);\n\tconst oauthState = runtimeState.pendingAuthStates.get(key);\n\tthrowIfAborted(signal);\n\tconst parsed = parseAuthorizationRedirectInput(input, oauthState);\n\treturn completeAuth(serverName, parsed, options);\n}\n\n/**\n * Complete OAuth authentication with the authorization code.\n */\nexport async function completeAuth(\n\tserverName: string,\n\tauthorizationCode: string | AuthorizationCodeInput,\n\toptions: AuthenticateOptions = {},\n): Promise<AuthStatus> {\n\tconst runtime = getRuntime(options);\n\tconst runtimeState = getRuntimeState(runtime);\n\tconst { code, iss } =\n\t\ttypeof authorizationCode === \"string\" ? { code: authorizationCode, iss: undefined } : authorizationCode;\n\tconst fallbackAuthStorageOptions = options.authStorageOptions ?? {};\n\tconst signal = combineAbortSignals(runtime.signal, options.signal);\n\tthrowIfAborted(signal);\n\tconst key = getPendingAuthKey(serverName, fallbackAuthStorageOptions);\n\tconst pendingAuth = runtimeState.pendingAuths.get(key);\n\tconst authStorageOptions = pendingAuth?.authStorageOptions ?? fallbackAuthStorageOptions;\n\tif (!pendingAuth) {\n\t\tthrow new Error(`No pending OAuth flow for server: ${serverName}`);\n\t}\n\n\tconst oauthState = runtimeState.pendingAuthStates.get(key);\n\tthrowIfAborted(signal);\n\n\tlet keepPendingForRetry = false;\n\ttry {\n\t\tconst discoveryState = await pendingAuth.authProvider.discoveryState();\n\t\tconst metadata = discoveryState?.authorizationServerMetadata;\n\t\tconst expectedIssuer = metadata?.issuer ?? discoveryState?.authorizationServerUrl;\n\t\tconst requiresIssuer =\n\t\t\t(metadata as { authorization_response_iss_parameter_supported?: unknown } | undefined)\n\t\t\t\t?.authorization_response_iss_parameter_supported === true;\n\t\tif (expectedIssuer !== undefined && iss === undefined && requiresIssuer) {\n\t\t\tkeepPendingForRetry = true;\n\t\t\tthrow new Error(\n\t\t\t\t`The authorization server for ${serverName} requires the RFC 9207 \"iss\" parameter. ` +\n\t\t\t\t\t\"Paste the full redirect URL from the browser address bar (not just the authorization code).\",\n\t\t\t);\n\t\t}\n\t\tif (expectedIssuer !== undefined && iss !== undefined && iss !== expectedIssuer) {\n\t\t\tthrow new Error(\n\t\t\t\t`The OAuth authorization response issuer does not match the discovered issuer for ${serverName}.`,\n\t\t\t);\n\t\t}\n\n\t\tconst result = await abortable(\n\t\t\trunSdkAuth(pendingAuth.authProvider, {\n\t\t\t\tserverUrl: pendingAuth.serverUrl,\n\t\t\t\tauthorizationCode: code,\n\t\t\t\t...(iss !== undefined ? { iss } : {}),\n\t\t\t\t...pendingAuth.discovery,\n\t\t\t}),\n\t\t\tsignal,\n\t\t);\n\t\tthrowIfAborted(signal);\n\t\tif (result !== \"AUTHORIZED\") {\n\t\t\tthrow new UnauthorizedError(\"Failed to authorize\");\n\t\t}\n\t} catch (error) {\n\t\tif (!keepPendingForRetry) {\n\t\t\ttry {\n\t\t\t\tawait clearPendingAuthAndReleaseIfIdle(runtime, serverName, oauthState, authStorageOptions);\n\t\t\t} catch (cleanupError) {\n\t\t\t\tthrow new AggregateError([error, cleanupError], \"OAuth completion cleanup failed\");\n\t\t\t}\n\t\t}\n\t\tthrow error;\n\t}\n\n\tawait clearPendingAuthAndReleaseIfIdle(runtime, serverName, oauthState, authStorageOptions);\n\treturn \"authenticated\";\n}\n\n/**\n * Perform the complete OAuth authentication flow for a server.\n *\n * @param serverName - The name of the MCP server\n * @param serverUrl - The URL of the MCP server\n * @param definition - The server definition (optional)\n * @returns The final auth status\n */\nexport async function authenticate(\n\tserverName: string,\n\tserverUrl: string,\n\tdefinition?: ServerEntry,\n\toptions: AuthenticateOptions = {},\n): Promise<AuthStatus> {\n\tif (isServerDisabled(definition)) throw new Error(`MCP server \"${serverName}\" is disabled`);\n\tconst runtime = getRuntime(options);\n\tconst runtimeState = getRuntimeState(runtime);\n\tconst authStorageOptions = options.authStorageOptions ?? {};\n\tconst signal = combineAbortSignals(runtime.signal, options.signal);\n\tthrowIfAborted(signal);\n\tconst authKey = `${serverName}|${serverUrl}|${getAuthBaseDir(authStorageOptions)}`;\n\tconst inFlight = runtimeState.pendingAuthentications.get(authKey);\n\tif (inFlight) {\n\t\treturn inFlight;\n\t}\n\n\tconst operation = (async (): Promise<AuthStatus> => {\n\t\tconst { authorizationUrl } = await startAuth(serverName, serverUrl, definition, {\n\t\t\t...options,\n\t\t\t...(signal ? { signal } : {}),\n\t\t\truntime,\n\t\t});\n\n\t\tif (!authorizationUrl) {\n\t\t\treturn \"authenticated\";\n\t\t}\n\n\t\tlet oauthState: string | undefined;\n\t\ttry {\n\t\t\t// Get the state that was already generated and stored in startAuth().\n\t\t\t// Keep this lookup and its abort check inside the cleanup boundary because\n\t\t\t// startAuth has already reserved callback state at this point.\n\t\t\toauthState = runtimeState.pendingAuthStates.get(getPendingAuthKey(serverName, authStorageOptions));\n\t\t\tthrowIfAborted(signal);\n\t\t\tif (!oauthState) {\n\t\t\t\tthrow new Error(\"OAuth state not found - this should not happen\");\n\t\t\t}\n\n\t\t\t// Register the callback BEFORE opening the browser.\n\t\t\tconst callbackPromise = waitForCallback(oauthState);\n\t\t\tvoid callbackPromise.catch(() => {});\n\n\t\t\t// Open browser. Always surface the URL first so remote/headless users can copy it\n\t\t\t// even when the OS browser handoff is unavailable or invisible.\n\t\t\tif (options.onAuthorizationUrl) {\n\t\t\t\tawait abortable(Promise.resolve(options.onAuthorizationUrl(authorizationUrl)), signal);\n\t\t\t} else {\n\t\t\t\tconsole.log(`MCP Auth: Open this URL to authenticate ${serverName}:\\n${authorizationUrl}`);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait abortable(open(authorizationUrl), signal);\n\t\t\t} catch (error) {\n\t\t\t\tif (isAbortError(error, signal)) throw error;\n\t\t\t\tconsole.warn(`MCP Auth: Failed to open browser for ${serverName}; waiting for manual callback`, { error });\n\t\t\t}\n\n\t\t\tconst authorizationResponse = await waitForAuthorizationResponse(\n\t\t\t\tcallbackPromise,\n\t\t\t\tauthorizationUrl,\n\t\t\t\toauthState,\n\t\t\t\toptions.onAuthorizationInput,\n\t\t\t\tsignal,\n\t\t\t);\n\t\t\tif (authorizationResponse.source === \"manual\") {\n\t\t\t\tcancelPendingCallback(oauthState);\n\t\t\t}\n\n\t\t\t// The callback server accepted only the flow-local reserved state. Manual\n\t\t\t// input is checked against the same state before token exchange.\n\t\t\tthrowIfAborted(signal);\n\n\t\t\treturn await completeAuth(serverName, authorizationResponse.input, {\n\t\t\t\t...options,\n\t\t\t\t...(signal ? { signal } : {}),\n\t\t\t\truntime,\n\t\t\t});\n\t\t} catch (error) {\n\t\t\tif (oauthState) cancelPendingCallback(oauthState);\n\t\t\ttry {\n\t\t\t\tawait clearPendingAuthAndReleaseIfIdle(runtime, serverName, oauthState, authStorageOptions);\n\t\t\t} catch (cleanupError) {\n\t\t\t\tthrow new AggregateError([error, cleanupError], \"OAuth cancellation cleanup failed\");\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t})();\n\n\truntimeState.pendingAuthentications.set(authKey, operation);\n\n\ttry {\n\t\treturn await operation;\n\t} finally {\n\t\tif (runtimeState.pendingAuthentications.get(authKey) === operation) {\n\t\t\truntimeState.pendingAuthentications.delete(authKey);\n\t\t}\n\t}\n}\n\n/**\n * Get a valid access token for a server, refreshing if necessary.\n *\n * @param serverName - The name of the MCP server\n * @param serverUrl - The URL of the MCP server\n * @returns The valid tokens or null if not authenticated\n */\nexport async function getValidToken(\n\tserverName: string,\n\tserverUrl: string,\n\toptions: AuthenticateOptions = {},\n): Promise<StoredTokens | null> {\n\tconst runtime = getRuntime(options);\n\tconst authStorageOptions = options.authStorageOptions ?? {};\n\tconst signal = combineAbortSignals(runtime.signal, options.signal);\n\tthrowIfAborted(signal);\n\tconst entry = await getAuthForUrl(serverName, serverUrl, authStorageOptions);\n\tthrowIfAborted(signal);\n\tif (!entry?.tokens) {\n\t\treturn null;\n\t}\n\n\tconst expired = await isTokenExpired(serverName, authStorageOptions);\n\tif (expired === false) {\n\t\treturn entry.tokens;\n\t}\n\n\tif (expired === true && entry.tokens.refreshToken) {\n\t\tconsole.log(`MCP Auth: Token expired for ${serverName}, attempting refresh`);\n\n\t\ttry {\n\t\t\tconst authProvider = new McpOAuthProvider(\n\t\t\t\tserverName,\n\t\t\t\tserverUrl,\n\t\t\t\t{},\n\t\t\t\t{\n\t\t\t\t\tonRedirect: async () => {},\n\t\t\t\t},\n\t\t\t\tauthStorageOptions,\n\t\t\t\truntime.signal,\n\t\t\t);\n\n\t\t\ttry {\n\t\t\t\tconst clientInfo = await authProvider.clientInformation();\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\tif (!clientInfo) {\n\t\t\t\t\tconsole.log(`MCP Auth: No client info for refresh for ${serverName}`);\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\n\t\t\t\tconst discovery = await probeAuthDiscovery(serverUrl, undefined, signal);\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\tconst result = await abortable(\n\t\t\t\t\trunSdkAuth(authProvider, {\n\t\t\t\t\t\tserverUrl,\n\t\t\t\t\t\t...discovery,\n\t\t\t\t\t\t...(options.skipIssuerMetadataValidation === true ? { skipIssuerMetadataValidation: true } : {}),\n\t\t\t\t\t}),\n\t\t\t\t\tsignal,\n\t\t\t\t);\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\tif (result !== \"AUTHORIZED\") {\n\t\t\t\t\treturn null;\n\t\t\t\t}\n\t\t\t\tconst refreshed = await getAuthForUrl(serverName, serverUrl, authStorageOptions);\n\t\t\t\tthrowIfAborted(signal);\n\t\t\t\treturn refreshed?.tokens ?? null;\n\t\t\t} finally {\n\t\t\t\tauthProvider.deactivate();\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (isAbortError(error, signal) || error instanceof OAuthCredentialStoreError) throw error;\n\t\t\tconsole.error(`MCP Auth: Token refresh failed for ${serverName}`, { error });\n\t\t\treturn null;\n\t\t}\n\t}\n\n\t// No expiration info or no refresh token, assume valid\n\treturn entry.tokens;\n}\n\n/**\n * Check the authentication status for a server.\n *\n * @param serverName - The name of the MCP server\n * @returns The current auth status\n */\nexport async function getAuthStatus(serverName: string, options: AuthenticateOptions = {}): Promise<AuthStatus> {\n\tgetRuntime(options);\n\tconst authStorageOptions = options.authStorageOptions ?? {};\n\tconst hasTokens = await hasStoredTokens(serverName, authStorageOptions);\n\tif (!hasTokens) return \"not_authenticated\";\n\n\tconst expired = await isTokenExpired(serverName, authStorageOptions);\n\treturn expired ? \"expired\" : \"authenticated\";\n}\n\n/**\n * Remove all OAuth credentials for a server.\n *\n * @param serverName - The name of the MCP server\n */\nexport async function removeAuth(serverName: string, options: AuthenticateOptions = {}): Promise<void> {\n\tconst runtime = getRuntime(options);\n\tconst signal = combineAbortSignals(runtime.signal, options.signal);\n\tthrowIfAborted(signal);\n\tconst authStorageOptions = options.authStorageOptions ?? {};\n\tconst oauthState = await getOAuthState(serverName, authStorageOptions);\n\tthrowIfAborted(signal);\n\tif (oauthState) {\n\t\tcancelPendingCallback(oauthState);\n\t}\n\tawait clearPendingAuthAndReleaseIfIdle(runtime, serverName, oauthState, authStorageOptions);\n\tthrowIfAborted(signal);\n\tclearAllCredentials(serverName, authStorageOptions);\n\tawait clearOAuthState(serverName, authStorageOptions);\n\tthrowIfAborted(signal);\n\tconsole.log(`MCP Auth: Removed credentials for ${serverName}`);\n}\n\n/**\n * Check if OAuth is supported for a server configuration.\n * OAuth is supported for HTTP servers unless explicitly disabled.\n *\n * @param definition - The server definition\n * @returns True if OAuth is supported\n */\nexport function supportsOAuth(definition: ServerEntry): boolean {\n\t// OAuth requires a URL\n\tif (!definition.url) return false;\n\n\t// Explicitly disabled via auth: false or oauth: false\n\tif (definition.auth === false) return false;\n\tif (definition.oauth === false) return false;\n\tif (definition.auth === \"oauth\") return true;\n\n\t// Configured custom headers take precedence over implicit OAuth auto-detection.\n\tif (definition.headers && Object.keys(definition.headers).length > 0) return false;\n\n\t// OAuth is enabled when auth is not specified (auto-detect)\n\treturn definition.auth === undefined;\n}\n\n/**\n * Initialize the OAuth system on startup.\n * OAuth callback binding is lazy and starts from startAuth() only.\n */\nexport async function initializeOAuth(runtimeOrSignal?: McpOAuthRuntime | AbortSignal): Promise<McpOAuthRuntime> {\n\tif (runtimeOrSignal && \"signal\" in runtimeOrSignal) {\n\t\truntimeOrSignal.signal.throwIfAborted();\n\t\tactiveRuntimes.add(runtimeOrSignal);\n\t\treturn runtimeOrSignal;\n\t}\n\n\tawait shutdownOAuth(legacyRuntime);\n\tlegacyRuntime = createOAuthRuntime(runtimeOrSignal as AbortSignal | undefined);\n\treturn legacyRuntime;\n}\n\n/**\n * Shutdown one OAuth runtime. The callback server remains process-shared while\n * another runtime has pending/reserved callback state or is still active.\n */\nexport async function shutdownOAuth(runtime: McpOAuthRuntime = legacyRuntime): Promise<void> {\n\tconst state = getRuntimeState(runtime);\n\tif (state.controller.signal.aborted) return;\n\tstate.generation += 1;\n\tstate.controller.abort(new Error(\"OAuth runtime stopped\"));\n\tfor (const callbackState of Array.from(state.pendingAuthStates.values())) cancelPendingCallback(callbackState);\n\tfor (const pendingAuth of Array.from(state.pendingAuths.values())) {\n\t\tawait clearPendingAuth(runtime, pendingAuth.serverName, undefined, pendingAuth.authStorageOptions);\n\t}\n\tstate.pendingAuthentications.clear();\n\tactiveRuntimes.delete(runtime);\n\n\tif (activeRuntimes.size === 0) {\n\t\tawait stopCallbackServer();\n\t}\n}\n"]}
@@ -0,0 +1,162 @@
1
+ /**
2
+ * MCP Auth Storage Module
3
+ *
4
+ * Handles secure storage of OAuth credentials, tokens, client information,
5
+ * and legacy PKCE state for MCP servers.
6
+ *
7
+ * Persistent OAuth entries are stored in the operating system credential store.
8
+ * Legacy plaintext entries are imported from $MCP_OAUTH_DIR/sha256-<server-hash>/tokens.json
9
+ * when set, otherwise <Nexus agent dir>/mcp-oauth/sha256-<server-hash>/tokens.json,
10
+ * then the plaintext file is removed.
11
+ */
12
+ /** OAuth token storage format */
13
+ export interface StoredTokens {
14
+ accessToken: string;
15
+ refreshToken?: string;
16
+ expiresAt?: number;
17
+ scope?: string;
18
+ /** SEP-2352 authorization-server issuer binding */
19
+ issuer?: string;
20
+ }
21
+ /** OAuth client information from dynamic or static registration */
22
+ export interface StoredClientInfo {
23
+ clientId: string;
24
+ clientSecret?: string;
25
+ clientIdIssuedAt?: number;
26
+ clientSecretExpiresAt?: number;
27
+ redirectUris?: string[];
28
+ /** SEP-2352 authorization-server issuer binding */
29
+ issuer?: string;
30
+ /**
31
+ * True when this entry is a secretless SEP-2352 issuer stub persisted for a
32
+ * config-pre-registered client (written by the config-clientId path of
33
+ * saveClientInformation). Such a stub is only usable when paired with the
34
+ * config that supplies the client secret; it must never be served as
35
+ * standalone client information.
36
+ */
37
+ configPreRegistered?: boolean;
38
+ }
39
+ /** Complete auth entry for a server */
40
+ export interface AuthEntry {
41
+ tokens?: StoredTokens;
42
+ clientInfo?: StoredClientInfo;
43
+ codeVerifier?: string;
44
+ oauthState?: string;
45
+ serverUrl?: string;
46
+ }
47
+ export interface AuthStorageOptions {
48
+ /** Legacy plaintext import directory. Persistent secrets no longer use this as their store. */
49
+ baseDir?: string;
50
+ }
51
+ export declare class OAuthCredentialStoreError extends Error {
52
+ readonly code = "OAUTH_CREDENTIAL_STORE_UNAVAILABLE";
53
+ readonly operation: "read" | "write" | "remove";
54
+ constructor(message: string, operation: "read" | "write" | "remove", cause: unknown);
55
+ }
56
+ export type OAuthCredentialStatus = {
57
+ status: "present";
58
+ entry: AuthEntry;
59
+ } | {
60
+ status: "absent";
61
+ } | {
62
+ status: "unavailable";
63
+ message: string;
64
+ };
65
+ export declare function formatOAuthCredentialStoreUnavailable(error: OAuthCredentialStoreError): string;
66
+ interface KeyringEntry {
67
+ getPassword(): string | null;
68
+ setPassword(password: string): void;
69
+ deleteCredential(): boolean;
70
+ }
71
+ type KeyringEntryConstructor = new (service: string, account: string) => KeyringEntry;
72
+ type KeyringRequire = ((id: string) => unknown) & {
73
+ resolve(id: string): string;
74
+ };
75
+ export declare function resetTestAuthSecretStore(): void;
76
+ export declare function resetAuthEntryCache(): void;
77
+ export declare function getTestAuthSecretStoreReadCount(): number;
78
+ export declare function getTestAuthSecretStoreEntries(): [string, string][];
79
+ export declare function setTestAuthSecretStoreEntry(account: string, payload: string): void;
80
+ export declare function removeTestAuthSecretStoreEntry(account: string): void;
81
+ export declare function loadTestKeyringEntryClass(keyringRequire: KeyringRequire, platform: NodeJS.Platform, arch: NodeJS.Architecture): KeyringEntryConstructor;
82
+ export declare function getAuthStorageOptions(oauthDir: unknown, cwd?: string): AuthStorageOptions;
83
+ export declare function getAuthBaseDir(options?: AuthStorageOptions): string;
84
+ /**
85
+ * Get the legacy plaintext tokens file path for a server.
86
+ */
87
+ export declare function getAuthEntryFilePath(serverName: string, options?: AuthStorageOptions): string;
88
+ /**
89
+ * Get auth entry for a server.
90
+ */
91
+ export declare function getAuthEntry(serverName: string, options?: AuthStorageOptions): AuthEntry | undefined;
92
+ /**
93
+ * Get auth entry and validate it's for the correct URL.
94
+ * Returns undefined if URL has changed (credentials are invalid).
95
+ */
96
+ export declare function getAuthForUrl(serverName: string, serverUrl: string, options?: AuthStorageOptions): AuthEntry | undefined;
97
+ /**
98
+ * Inspect credentials for status-only UI paths without treating an unavailable
99
+ * secure store as missing credentials. Authentication operations continue to
100
+ * use getAuthForUrl() directly and therefore remain fail-closed.
101
+ */
102
+ export declare function inspectAuthForUrl(serverName: string, serverUrl: string, options?: AuthStorageOptions): OAuthCredentialStatus;
103
+ /**
104
+ * Save auth entry for a server.
105
+ */
106
+ export declare function saveAuthEntry(serverName: string, entry: AuthEntry, serverUrl?: string, options?: AuthStorageOptions): void;
107
+ export declare function removeAuthEntry(serverName: string, options?: AuthStorageOptions): void;
108
+ /**
109
+ * Forget a cached entry so the next ordinary read reloads secure storage.
110
+ */
111
+ export declare function invalidateAuthEntryCache(serverName: string): void;
112
+ /**
113
+ * Update tokens for a server.
114
+ */
115
+ export declare function updateTokens(serverName: string, tokens: StoredTokens, serverUrl?: string, options?: AuthStorageOptions): void;
116
+ /**
117
+ * Update client info for a server.
118
+ */
119
+ export declare function updateClientInfo(serverName: string, clientInfo: StoredClientInfo, serverUrl?: string, options?: AuthStorageOptions): void;
120
+ /**
121
+ * Update code verifier for a server.
122
+ */
123
+ export declare function updateCodeVerifier(serverName: string, codeVerifier: string, serverUrl?: string, options?: AuthStorageOptions): void;
124
+ /**
125
+ * Clear code verifier for a server.
126
+ */
127
+ export declare function clearCodeVerifier(serverName: string, options?: AuthStorageOptions): void;
128
+ /**
129
+ * Update OAuth state for a server.
130
+ */
131
+ export declare function updateOAuthState(serverName: string, state: string, serverUrl?: string, options?: AuthStorageOptions): void;
132
+ /**
133
+ * Get OAuth state for a server.
134
+ */
135
+ export declare function getOAuthState(serverName: string, options?: AuthStorageOptions): string | undefined;
136
+ /**
137
+ * Clear OAuth state for a server.
138
+ */
139
+ export declare function clearOAuthState(serverName: string, options?: AuthStorageOptions): void;
140
+ /**
141
+ * Check if stored tokens are expired.
142
+ * Returns null if no tokens exist, false if no expiry or not expired, true if expired.
143
+ */
144
+ export declare function isTokenExpired(serverName: string, options?: AuthStorageOptions): boolean | null;
145
+ /**
146
+ * Check if a server has stored tokens.
147
+ */
148
+ export declare function hasStoredTokens(serverName: string, options?: AuthStorageOptions): boolean;
149
+ /**
150
+ * Clear all credentials for a server.
151
+ */
152
+ export declare function clearAllCredentials(serverName: string, options?: AuthStorageOptions): void;
153
+ /**
154
+ * Clear only client info for a server.
155
+ */
156
+ export declare function clearClientInfo(serverName: string, options?: AuthStorageOptions): void;
157
+ /**
158
+ * Clear only tokens for a server.
159
+ */
160
+ export declare function clearTokens(serverName: string, options?: AuthStorageOptions): void;
161
+ export {};
162
+ //# sourceMappingURL=mcp-auth.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-auth.d.ts","sourceRoot":"","sources":["../../../src/extensions/mcp/mcp-auth.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * MCP Auth Storage Module\n *\n * Handles secure storage of OAuth credentials, tokens, client information,\n * and legacy PKCE state for MCP servers.\n *\n * Persistent OAuth entries are stored in the operating system credential store.\n * Legacy plaintext entries are imported from $MCP_OAUTH_DIR/sha256-<server-hash>/tokens.json\n * when set, otherwise <Nexus agent dir>/mcp-oauth/sha256-<server-hash>/tokens.json,\n * then the plaintext file is removed.\n */\n\nimport { spawnSync } from \"child_process\";\nimport { createHash } from \"crypto\";\nimport { existsSync, readFileSync, rmSync } from \"fs\";\nimport { createRequire } from \"module\";\nimport { dirname, join } from \"path\";\nimport { fileURLToPath } from \"url\";\nimport { getAgentPath } from \"./agent-dir.ts\";\nimport { resolveConfiguredOAuthDir } from \"./config.ts\";\n\nconst require = createRequire(import.meta.url);\nconst AUTH_SECRET_SERVICE = \"nexus-mcp.oauth\";\nconst TEST_AUTH_STORE_ENV = \"NEXUS_MCP_TEST_AUTH_STORE\";\n/**\n * Windows Credential Manager caps one value at CRED_MAX_CREDENTIAL_BLOB_SIZE\n * (2560 bytes) and stores it as UTF-16, so the real ceiling is\n * AUTH_SECRET_VALUE_LIMIT characters. Chunks must stay below that, and so must\n * the threshold that decides whether to chunk at all, or oversized records still\n * fail to persist on Windows.\n */\nconst AUTH_SECRET_CHUNK_SIZE = 1000;\n/** Largest single value the strictest supported credential store accepts. */\nconst AUTH_SECRET_VALUE_LIMIT = 1280;\nconst KEYRING_RECOVERY_DISABLED_ENV = \"NEXUS_MCP_DISABLE_KEYRING_RECOVERY\";\nconst KEYRING_RECOVERY_KEYCTL_ENV = \"NEXUS_MCP_KEYRING_RECOVERY_KEYCTL\";\nconst KEYRING_RECOVERY_NODE_ENV = \"NEXUS_MCP_KEYRING_RECOVERY_NODE\";\nconst KEYRING_RECOVERY_HELPER_ENV = \"NEXUS_MCP_KEYRING_RECOVERY_HELPER\";\nconst TEST_LINUX_KEYRING_RECOVERY_ENV = \"NEXUS_MCP_TEST_LINUX_KEYRING_RECOVERY\";\nconst AUTH_CACHE_DISABLED_ENV = \"NEXUS_MCP_DISABLE_AUTH_CACHE\";\nconst KEYRING_RECOVERY_TIMEOUT_MS = 10_000;\nconst AUTH_CHUNK_MANIFEST_KEY = \"__nexusMcpOAuthChunked\";\n\n/** OAuth token storage format */\nexport interface StoredTokens {\n\taccessToken: string;\n\trefreshToken?: string;\n\texpiresAt?: number; // Unix timestamp in seconds\n\tscope?: string;\n\t/** SEP-2352 authorization-server issuer binding */\n\tissuer?: string;\n}\n\n/** OAuth client information from dynamic or static registration */\nexport interface StoredClientInfo {\n\tclientId: string;\n\tclientSecret?: string;\n\tclientIdIssuedAt?: number;\n\tclientSecretExpiresAt?: number;\n\tredirectUris?: string[];\n\t/** SEP-2352 authorization-server issuer binding */\n\tissuer?: string;\n\t/**\n\t * True when this entry is a secretless SEP-2352 issuer stub persisted for a\n\t * config-pre-registered client (written by the config-clientId path of\n\t * saveClientInformation). Such a stub is only usable when paired with the\n\t * config that supplies the client secret; it must never be served as\n\t * standalone client information.\n\t */\n\tconfigPreRegistered?: boolean;\n}\n\n/** Complete auth entry for a server */\nexport interface AuthEntry {\n\ttokens?: StoredTokens;\n\tclientInfo?: StoredClientInfo;\n\tcodeVerifier?: string;\n\toauthState?: string;\n\tserverUrl?: string; // Track the URL these credentials are for\n}\n\nexport interface AuthStorageOptions {\n\t/** Legacy plaintext import directory. Persistent secrets no longer use this as their store. */\n\tbaseDir?: string;\n}\n\nexport class OAuthCredentialStoreError extends Error {\n\treadonly code = \"OAUTH_CREDENTIAL_STORE_UNAVAILABLE\";\n\treadonly operation: \"read\" | \"write\" | \"remove\";\n\n\tconstructor(message: string, operation: \"read\" | \"write\" | \"remove\", cause: unknown) {\n\t\tsuper(message, { cause });\n\t\tthis.name = \"OAuthCredentialStoreError\";\n\t\tthis.operation = operation;\n\t}\n}\n\nexport type OAuthCredentialStatus =\n\t| { status: \"present\"; entry: AuthEntry }\n\t| { status: \"absent\" }\n\t| { status: \"unavailable\"; message: string };\n\nfunction causeChainContains(error: unknown, pattern: RegExp): boolean {\n\tconst seen = new Set<unknown>();\n\tlet current = error;\n\twhile ((typeof current === \"object\" && current !== null) || typeof current === \"function\") {\n\t\tif (seen.has(current)) break;\n\t\tseen.add(current);\n\t\tconst candidate = current as { name?: unknown; message?: unknown; code?: unknown; cause?: unknown };\n\t\tif (\n\t\t\t[candidate.name, candidate.message, candidate.code].some(\n\t\t\t\t(value) => typeof value === \"string\" && pattern.test(value),\n\t\t\t)\n\t\t) {\n\t\t\treturn true;\n\t\t}\n\t\tcurrent = candidate.cause;\n\t}\n\treturn false;\n}\n\nexport function formatOAuthCredentialStoreUnavailable(error: OAuthCredentialStoreError): string {\n\tif (process.platform === \"linux\" && causeChainContains(error, /key\\s*(?:has been\\s*)?revoked|keyrevoked/i)) {\n\t\treturn \"OAuth credential store unavailable: the Linux session keyring may be revoked. Start Nexus from a fresh login/keyring session and retry.\";\n\t}\n\treturn \"OAuth credential store unavailable. Configure or unlock the OS credential store and retry.\";\n}\n\ninterface KeyringEntry {\n\tgetPassword(): string | null;\n\tsetPassword(password: string): void;\n\tdeleteCredential(): boolean;\n}\n\ntype KeyringEntryConstructor = new (service: string, account: string) => KeyringEntry;\ntype KeyringModule = { Entry: KeyringEntryConstructor };\ntype KeyringRequire = ((id: string) => unknown) & { resolve(id: string): string };\n\ninterface AuthSecretStore {\n\tread(account: string): string | undefined;\n\twrite(account: string, payload: string): void;\n\tremove(account: string): void;\n}\n\ninterface AuthEntryChunkManifest {\n\t[AUTH_CHUNK_MANIFEST_KEY]: 1;\n\tchunkCount: number;\n\tchunkDigest: string;\n}\n\nconst MAX_AUTH_SECRET_CHUNKS = 128;\n\nlet KeyringEntryClass: KeyringEntryConstructor | undefined;\nconst memoryAuthEntries = new Map<string, string>();\n\nlet testAuthSecretStoreReadCount = 0;\nconst authEntryCache = new Map<string, AuthEntry | undefined>();\n\nfunction getAuthEntryCacheKey(serverName: string, options?: AuthStorageOptions): string {\n\treturn `${serverName}\\0${getAuthBaseDir(options)}`;\n}\n\nfunction deleteAuthEntryCacheEntries(serverName: string): void {\n\tconst prefix = `${serverName}\\0`;\n\tfor (const key of authEntryCache.keys()) {\n\t\tif (key.startsWith(prefix)) authEntryCache.delete(key);\n\t}\n}\n\nfunction isAuthEntryCacheEnabled(): boolean {\n\treturn process.env[AUTH_CACHE_DISABLED_ENV] !== \"1\";\n}\n\nfunction cloneAuthEntry(entry: AuthEntry | undefined): AuthEntry | undefined {\n\treturn entry === undefined ? undefined : structuredClone(entry);\n}\n\nconst memoryAuthSecretStore: AuthSecretStore = {\n\tread(account) {\n\t\ttestAuthSecretStoreReadCount++;\n\t\treturn memoryAuthEntries.get(account);\n\t},\n\twrite(account, payload) {\n\t\tmemoryAuthEntries.set(account, payload);\n\t},\n\tremove(account) {\n\t\tmemoryAuthEntries.delete(account);\n\t},\n};\n\nconst keyringAuthSecretStore: AuthSecretStore = {\n\tread(account) {\n\t\treturn getKeyringEntry(account).getPassword() ?? undefined;\n\t},\n\twrite(account, payload) {\n\t\tgetKeyringEntry(account).setPassword(payload);\n\t},\n\tremove(account) {\n\t\tgetKeyringEntry(account).deleteCredential();\n\t},\n};\n\n/** Mimics the Windows Credential Manager per-value ceiling for tests. */\nconst sizeLimitedAuthSecretStore: AuthSecretStore = {\n\tread(account) {\n\t\ttestAuthSecretStoreReadCount++;\n\t\treturn memoryAuthEntries.get(account);\n\t},\n\twrite(account, payload) {\n\t\tif (payload.length > AUTH_SECRET_VALUE_LIMIT) {\n\t\t\tthrow new Error(\n\t\t\t\t`Value of 'password encoded as UTF-16' is longer than the platform limit of ${AUTH_SECRET_VALUE_LIMIT * 2} chars`,\n\t\t\t);\n\t\t}\n\t\tmemoryAuthEntries.set(account, payload);\n\t},\n\tremove(account) {\n\t\tmemoryAuthEntries.delete(account);\n\t},\n};\n\nconst unavailableAuthSecretStore: AuthSecretStore = {\n\tread() {\n\t\ttestAuthSecretStoreReadCount++;\n\t\tthrow new Error(\"simulated secure credential store unavailable\");\n\t},\n\twrite() {\n\t\tthrow new Error(\"simulated secure credential store unavailable\");\n\t},\n\tremove() {\n\t\tthrow new Error(\"simulated secure credential store unavailable\");\n\t},\n};\n\nfunction createKeyRevokedTestError(): Error {\n\treturn new Error(\"Couldn't access platform storage: KeyRevoked\", { cause: new Error(\"KeyRevoked\") });\n}\n\nconst keyRevokedAuthSecretStore: AuthSecretStore = {\n\tread() {\n\t\ttestAuthSecretStoreReadCount++;\n\t\tthrow createKeyRevokedTestError();\n\t},\n\twrite() {\n\t\tthrow createKeyRevokedTestError();\n\t},\n\tremove() {\n\t\tthrow createKeyRevokedTestError();\n\t},\n};\n\nexport function resetTestAuthSecretStore(): void {\n\tmemoryAuthEntries.clear();\n\tauthEntryCache.clear();\n\ttestAuthSecretStoreReadCount = 0;\n}\n\nexport function resetAuthEntryCache(): void {\n\tauthEntryCache.clear();\n}\n\nexport function getTestAuthSecretStoreReadCount(): number {\n\treturn testAuthSecretStoreReadCount;\n}\n\nexport function getTestAuthSecretStoreEntries(): [string, string][] {\n\treturn [...memoryAuthEntries.entries()];\n}\n\nexport function setTestAuthSecretStoreEntry(account: string, payload: string): void {\n\tmemoryAuthEntries.set(account, payload);\n}\n\nexport function removeTestAuthSecretStoreEntry(account: string): void {\n\tmemoryAuthEntries.delete(account);\n}\n\nfunction getAuthSecretStore(): AuthSecretStore {\n\tif (process.env[TEST_AUTH_STORE_ENV] === \"memory\") return memoryAuthSecretStore;\n\tif (process.env[TEST_AUTH_STORE_ENV] === \"sizelimited\") return sizeLimitedAuthSecretStore;\n\tif (process.env[TEST_AUTH_STORE_ENV] === \"unavailable\") return unavailableAuthSecretStore;\n\tif (process.env[TEST_AUTH_STORE_ENV] === \"keyrevoked\") return keyRevokedAuthSecretStore;\n\treturn keyringAuthSecretStore;\n}\n\nfunction getKeyringEntry(account: string): KeyringEntry {\n\ttry {\n\t\tKeyringEntryClass ??= loadKeyringEntryClass();\n\t\treturn new KeyringEntryClass(AUTH_SECRET_SERVICE, account);\n\t} catch (error) {\n\t\tthrow new Error(\n\t\t\t\"OAuth secure credential storage is unavailable. Configure the OS credential store and retry authentication.\",\n\t\t\t{ cause: error },\n\t\t);\n\t}\n}\n\nfunction loadKeyringEntryClass(\n\tkeyringRequire: KeyringRequire = require,\n\tplatform: NodeJS.Platform = process.platform,\n\tarch: NodeJS.Architecture = process.arch,\n): KeyringEntryConstructor {\n\ttry {\n\t\treturn (keyringRequire(\"@napi-rs/keyring\") as KeyringModule).Entry;\n\t} catch (loaderError) {\n\t\ttry {\n\t\t\treturn loadKeyringNativeBindingFallback(keyringRequire, platform, arch).Entry;\n\t\t} catch (fallbackError) {\n\t\t\tthrow new Error(\n\t\t\t\t`Failed to load @napi-rs/keyring; absolute-path native binding fallback also failed: ${formatErrorMessage(fallbackError)}`,\n\t\t\t\t{\n\t\t\t\t\tcause: loaderError,\n\t\t\t\t},\n\t\t\t);\n\t\t}\n\t}\n}\n\nfunction loadKeyringNativeBindingFallback(\n\tkeyringRequire: KeyringRequire,\n\tplatform: NodeJS.Platform,\n\tarch: NodeJS.Architecture,\n): KeyringModule {\n\tconst targets = getKeyringNativeBindingTargets(platform, arch);\n\tif (targets.length === 0) {\n\t\tthrow new Error(`Unsupported @napi-rs/keyring native binding target: ${platform}-${arch}`);\n\t}\n\n\tlet lastError: unknown;\n\tfor (const target of targets) {\n\t\ttry {\n\t\t\tconst packageJsonPath = keyringRequire.resolve(`${target.packageName}/package.json`);\n\t\t\treturn keyringRequire(join(dirname(packageJsonPath), target.bindingFile)) as KeyringModule;\n\t\t} catch (error) {\n\t\t\tlastError = error;\n\t\t}\n\t}\n\n\tthrow lastError instanceof Error ? lastError : new Error(String(lastError));\n}\n\nfunction getKeyringNativeBindingTargets(\n\tplatform: NodeJS.Platform,\n\tarch: NodeJS.Architecture,\n): { packageName: string; bindingFile: string }[] {\n\treturn getKeyringNativeBindingSuffixes(platform, arch).map((suffix) => ({\n\t\tpackageName: `@napi-rs/keyring-${suffix}`,\n\t\tbindingFile: `keyring.${suffix}.node`,\n\t}));\n}\n\nfunction getKeyringNativeBindingSuffixes(platform: NodeJS.Platform, arch: NodeJS.Architecture): string[] {\n\tif (platform === \"darwin\") {\n\t\tif (arch === \"arm64\") return [\"darwin-arm64\"];\n\t\tif (arch === \"x64\") return [\"darwin-x64\"];\n\t}\n\tif (platform === \"win32\") {\n\t\tif (arch === \"arm64\") return [\"win32-arm64-msvc\"];\n\t\tif (arch === \"x64\") return [\"win32-x64-msvc\"];\n\t\tif (arch === \"ia32\") return [\"win32-ia32-msvc\"];\n\t}\n\tif (platform === \"linux\") {\n\t\tif (arch === \"arm64\") return [\"linux-arm64-gnu\", \"linux-arm64-musl\"];\n\t\tif (arch === \"arm\") return [\"linux-arm-gnueabihf\"];\n\t\tif (arch === \"riscv64\") return [\"linux-riscv64-gnu\"];\n\t\tif (arch === \"x64\") return [\"linux-x64-gnu\", \"linux-x64-musl\"];\n\t}\n\tif (platform === \"freebsd\" && arch === \"x64\") return [\"freebsd-x64\"];\n\treturn [];\n}\n\nfunction formatErrorMessage(error: unknown): string {\n\treturn error instanceof Error ? error.message : String(error);\n}\n\ntype KeyringRecoveryOperation = \"read\" | \"write\" | \"remove\";\n\ntype KeyringRecoveryResponse = { ok: true; found?: boolean; value?: string } | { ok: false; error?: string };\n\nfunction isLinuxKeyringRecoveryEnabled(): boolean {\n\tif (process.env[KEYRING_RECOVERY_DISABLED_ENV] === \"1\") return false;\n\treturn process.platform === \"linux\" || process.env[TEST_LINUX_KEYRING_RECOVERY_ENV] === \"1\";\n}\n\nfunction shouldAttemptLinuxKeyringRecovery(error: unknown): boolean {\n\treturn isLinuxKeyringRecoveryEnabled() && causeChainContains(error, /key\\s*(?:has been\\s*)?revoked|keyrevoked/i);\n}\n\nfunction runLinuxKeyringRecoveryOperation(\n\toperation: KeyringRecoveryOperation,\n\taccount: string,\n\tpayload?: string,\n): KeyringRecoveryResponse {\n\tconst keyctl = process.env[KEYRING_RECOVERY_KEYCTL_ENV]?.trim() || \"keyctl\";\n\tconst node = process.env[KEYRING_RECOVERY_NODE_ENV]?.trim() || \"node\";\n\tconst helper =\n\t\tprocess.env[KEYRING_RECOVERY_HELPER_ENV]?.trim() ||\n\t\tfileURLToPath(new URL(\"./mcp-keyring-helper.cjs\", import.meta.url));\n\tconst request = JSON.stringify({ operation, service: AUTH_SECRET_SERVICE, account, payload });\n\tconst result = spawnSync(keyctl, [\"session\", \"-\", node, helper], {\n\t\tinput: `${request}\\n`,\n\t\tencoding: \"utf8\",\n\t\tmaxBuffer: 1024 * 1024,\n\t\ttimeout: KEYRING_RECOVERY_TIMEOUT_MS,\n\t\twindowsHide: true,\n\t});\n\n\tif (result.error) {\n\t\tthrow new Error(`Linux keyring recovery helper could not start: ${result.error.message}`, {\n\t\t\tcause: result.error,\n\t\t});\n\t}\n\tif (result.status !== 0) {\n\t\tthrow new Error(`Linux keyring recovery helper failed with exit code ${result.status ?? \"unknown\"}`);\n\t}\n\n\tlet response: unknown;\n\ttry {\n\t\tresponse = JSON.parse(result.stdout.trim()) as unknown;\n\t} catch (error) {\n\t\tthrow new Error(\"Linux keyring recovery helper returned invalid JSON\", { cause: error });\n\t}\n\tif (typeof response !== \"object\" || response === null || typeof (response as { ok?: unknown }).ok !== \"boolean\") {\n\t\tthrow new Error(\"Linux keyring recovery helper returned an invalid response\");\n\t}\n\tconst typedResponse = response as KeyringRecoveryResponse;\n\tif (typedResponse.ok === false) {\n\t\tthrow new Error(typedResponse.error || \"Linux keyring recovery helper failed\");\n\t}\n\tif (operation === \"read\" && typedResponse.found === true && typeof typedResponse.value !== \"string\") {\n\t\tthrow new Error(\"Linux keyring recovery helper returned an invalid read response\");\n\t}\n\treturn typedResponse;\n}\n\nconst linuxKeyringRecoveryAuthSecretStore: AuthSecretStore = {\n\tread(account) {\n\t\tconst response = runLinuxKeyringRecoveryOperation(\"read\", account);\n\t\treturn response.ok && response.found === true ? response.value : undefined;\n\t},\n\twrite(account, payload) {\n\t\trunLinuxKeyringRecoveryOperation(\"write\", account, payload);\n\t},\n\tremove(account) {\n\t\trunLinuxKeyringRecoveryOperation(\"remove\", account);\n\t},\n};\n\nexport function loadTestKeyringEntryClass(\n\tkeyringRequire: KeyringRequire,\n\tplatform: NodeJS.Platform,\n\tarch: NodeJS.Architecture,\n): KeyringEntryConstructor {\n\treturn loadKeyringEntryClass(keyringRequire, platform, arch);\n}\n\nexport function getAuthStorageOptions(oauthDir: unknown, cwd = process.cwd()): AuthStorageOptions {\n\tconst baseDir = resolveConfiguredOAuthDir(oauthDir, cwd);\n\treturn baseDir ? { baseDir } : {};\n}\n\nexport function getAuthBaseDir(options: AuthStorageOptions = {}): string {\n\tconst override = process.env.MCP_OAUTH_DIR?.trim();\n\tif (override) return override;\n\treturn options.baseDir ?? getAgentPath(\"mcp-oauth\");\n}\n\n/**\n * Get the legacy server-specific directory path.\n */\nfunction getServerDir(serverName: string, options?: AuthStorageOptions): string {\n\tif (typeof serverName !== \"string\") {\n\t\tthrow new Error(`Invalid MCP server name: ${JSON.stringify(serverName)}`);\n\t}\n\tconst storageKey = getAuthEntryAccount(serverName);\n\treturn join(getAuthBaseDir(options), storageKey);\n}\n\nfunction getAuthEntryAccount(serverName: string): string {\n\tif (typeof serverName !== \"string\") {\n\t\tthrow new Error(`Invalid MCP server name: ${JSON.stringify(serverName)}`);\n\t}\n\treturn `sha256-${createHash(\"sha256\").update(serverName, \"utf8\").digest(\"hex\")}`;\n}\n\n/**\n * Get the legacy plaintext tokens file path for a server.\n */\nexport function getAuthEntryFilePath(serverName: string, options?: AuthStorageOptions): string {\n\treturn join(getServerDir(serverName, options), \"tokens.json\");\n}\n\nfunction parseJsonPayload(serverName: string, payload: string, source: string): unknown {\n\ttry {\n\t\treturn JSON.parse(payload) as unknown;\n\t} catch (error) {\n\t\tthrow new Error(`Failed to parse OAuth credentials for ${serverName} from ${source}`, { cause: error });\n\t}\n}\n\nfunction parseAuthEntryPayload(serverName: string, payload: string, source: string): AuthEntry {\n\tconst parsed = parseJsonPayload(serverName, payload, source);\n\tconst entry = toAuthEntry(parsed);\n\tif (!entry) {\n\t\tthrow new Error(`Failed to parse OAuth credentials for ${serverName} from ${source}: invalid credential shape`);\n\t}\n\treturn entry;\n}\n\nfunction toAuthEntry(value: unknown): AuthEntry | undefined {\n\tconst entry = toRecord(value);\n\tif (!entry) return undefined;\n\n\tconst codeVerifier = optionalString(entry.codeVerifier);\n\tconst oauthState = optionalString(entry.oauthState);\n\tconst serverUrl = optionalString(entry.serverUrl);\n\tif (codeVerifier === null || oauthState === null || serverUrl === null) return undefined;\n\n\tconst tokens = entry.tokens === undefined ? undefined : toStoredTokens(entry.tokens);\n\tconst clientInfo = entry.clientInfo === undefined ? undefined : toStoredClientInfo(entry.clientInfo);\n\tif ((entry.tokens !== undefined && !tokens) || (entry.clientInfo !== undefined && !clientInfo)) return undefined;\n\n\tconst authEntry: AuthEntry = {};\n\tif (tokens) authEntry.tokens = tokens;\n\tif (clientInfo) authEntry.clientInfo = clientInfo;\n\tif (codeVerifier !== undefined) authEntry.codeVerifier = codeVerifier;\n\tif (oauthState !== undefined) authEntry.oauthState = oauthState;\n\tif (serverUrl !== undefined) authEntry.serverUrl = serverUrl;\n\treturn authEntry;\n}\n\nfunction toStoredTokens(value: unknown): StoredTokens | undefined {\n\tconst tokens = toRecord(value);\n\tif (!tokens || typeof tokens.accessToken !== \"string\") return undefined;\n\n\tconst refreshToken = optionalString(tokens.refreshToken);\n\tconst scope = optionalString(tokens.scope);\n\tconst issuer = optionalString(tokens.issuer);\n\tconst expiresAt = optionalNumber(tokens.expiresAt);\n\tif (refreshToken === null || scope === null || issuer === null || expiresAt === null) return undefined;\n\n\tconst storedTokens: StoredTokens = { accessToken: tokens.accessToken };\n\tif (refreshToken !== undefined) storedTokens.refreshToken = refreshToken;\n\tif (expiresAt !== undefined) storedTokens.expiresAt = expiresAt;\n\tif (scope !== undefined) storedTokens.scope = scope;\n\tif (issuer !== undefined) storedTokens.issuer = issuer;\n\treturn storedTokens;\n}\n\nfunction toStoredClientInfo(value: unknown): StoredClientInfo | undefined {\n\tconst clientInfo = toRecord(value);\n\tif (!clientInfo || typeof clientInfo.clientId !== \"string\") return undefined;\n\n\tconst clientSecret = optionalString(clientInfo.clientSecret);\n\tconst issuer = optionalString(clientInfo.issuer);\n\tconst clientIdIssuedAt = optionalNumber(clientInfo.clientIdIssuedAt);\n\tconst clientSecretExpiresAt = optionalNumber(clientInfo.clientSecretExpiresAt);\n\tconst configPreRegistered = optionalBoolean(clientInfo.configPreRegistered);\n\tif (\n\t\tclientSecret === null ||\n\t\tissuer === null ||\n\t\tclientIdIssuedAt === null ||\n\t\tclientSecretExpiresAt === null ||\n\t\tconfigPreRegistered === null\n\t)\n\t\treturn undefined;\n\n\tconst storedClient: StoredClientInfo = { clientId: clientInfo.clientId };\n\tconst redirectUris = stringArray(clientInfo.redirectUris);\n\tif (clientSecret !== undefined) storedClient.clientSecret = clientSecret;\n\tif (clientIdIssuedAt !== undefined) storedClient.clientIdIssuedAt = clientIdIssuedAt;\n\tif (clientSecretExpiresAt !== undefined) storedClient.clientSecretExpiresAt = clientSecretExpiresAt;\n\tif (redirectUris !== undefined) storedClient.redirectUris = redirectUris;\n\tif (issuer !== undefined) storedClient.issuer = issuer;\n\tif (configPreRegistered !== undefined) storedClient.configPreRegistered = configPreRegistered;\n\treturn storedClient;\n}\n\nfunction toRecord(value: unknown): Record<string, unknown> | undefined {\n\treturn typeof value === \"object\" && value !== null && !Array.isArray(value)\n\t\t? (value as Record<string, unknown>)\n\t\t: undefined;\n}\n\nfunction optionalString(value: unknown): string | null | undefined {\n\tif (value === undefined) return undefined;\n\treturn typeof value === \"string\" ? value : null;\n}\n\nfunction optionalNumber(value: unknown): number | null | undefined {\n\tif (value === undefined) return undefined;\n\treturn typeof value === \"number\" ? value : null;\n}\n\nfunction optionalBoolean(value: unknown): boolean | null | undefined {\n\tif (value === undefined) return undefined;\n\treturn typeof value === \"boolean\" ? value : null;\n}\n\nfunction stringArray(value: unknown): string[] | undefined {\n\treturn Array.isArray(value) && value.every((uri) => typeof uri === \"string\") ? value : undefined;\n}\n\nfunction isAuthEntryChunkManifest(value: unknown): value is AuthEntryChunkManifest {\n\tif (typeof value !== \"object\" || value === null) return false;\n\tconst manifest = value as Partial<AuthEntryChunkManifest>;\n\treturn (\n\t\tmanifest[AUTH_CHUNK_MANIFEST_KEY] === 1 &&\n\t\ttypeof manifest.chunkCount === \"number\" &&\n\t\tNumber.isInteger(manifest.chunkCount) &&\n\t\tmanifest.chunkCount > 0 &&\n\t\tmanifest.chunkCount <= MAX_AUTH_SECRET_CHUNKS &&\n\t\ttypeof manifest.chunkDigest === \"string\" &&\n\t\t/^[a-f0-9]{16}$/.test(manifest.chunkDigest)\n\t);\n}\n\nfunction getAuthEntryChunkAccount(account: string, manifest: AuthEntryChunkManifest, index: number): string {\n\treturn `${account}.chunk.${manifest.chunkDigest}.${index}`;\n}\n\nfunction getAuthEntryChunkAccounts(account: string, manifest: AuthEntryChunkManifest): string[] {\n\treturn Array.from({ length: manifest.chunkCount }, (_, index) => getAuthEntryChunkAccount(account, manifest, index));\n}\n\nfunction readChunkManifestFromPayload(\n\tserverName: string,\n\tpayload: string,\n\tsource: string,\n): AuthEntryChunkManifest | undefined {\n\tconst parsed = parseJsonPayload(serverName, payload, source);\n\tif (isAuthEntryChunkManifest(parsed)) return parsed;\n\tif (toRecord(parsed)?.[AUTH_CHUNK_MANIFEST_KEY] === 1) {\n\t\tthrow new OAuthCredentialStoreError(\n\t\t\t`Failed to read OAuth credentials for ${serverName} from the ${source}`,\n\t\t\t\"read\",\n\t\t\tnew Error(\"OAuth credential chunk manifest has invalid shape\"),\n\t\t);\n\t}\n\treturn undefined;\n}\n\nfunction readExistingChunkManifest(\n\tstore: AuthSecretStore,\n\tserverName: string,\n\taccount: string,\n): AuthEntryChunkManifest | undefined {\n\ttry {\n\t\tconst payload = store.read(account);\n\t\treturn payload === undefined\n\t\t\t? undefined\n\t\t\t: readChunkManifestFromPayload(serverName, payload, \"OS secure credential store\");\n\t} catch {\n\t\treturn undefined;\n\t}\n}\n\nfunction removeChunkPayloads(store: AuthSecretStore, account: string, manifest: AuthEntryChunkManifest): void {\n\tfor (const chunkAccount of getAuthEntryChunkAccounts(account, manifest)) {\n\t\tstore.remove(chunkAccount);\n\t}\n}\n\nfunction tryRemoveChunkPayloads(\n\tstore: AuthSecretStore,\n\taccount: string,\n\tmanifest: AuthEntryChunkManifest | undefined,\n): void {\n\tif (!manifest) return;\n\ttry {\n\t\tremoveChunkPayloads(store, account, manifest);\n\t} catch {\n\t\t// Stale chunk cleanup must not hide a successful credential write.\n\t}\n}\n\nfunction createChunkManifest(payload: string): AuthEntryChunkManifest {\n\treturn {\n\t\t[AUTH_CHUNK_MANIFEST_KEY]: 1,\n\t\tchunkCount: Math.ceil(payload.length / AUTH_SECRET_CHUNK_SIZE),\n\t\tchunkDigest: createHash(\"sha256\").update(payload, \"utf8\").digest(\"hex\").slice(0, 16),\n\t};\n}\n\nfunction readChunkedAuthEntry(\n\tstore: AuthSecretStore,\n\tserverName: string,\n\taccount: string,\n\tmanifest: AuthEntryChunkManifest,\n): AuthEntry {\n\tconst chunks = getAuthEntryChunkAccounts(account, manifest).map((chunkAccount) => {\n\t\ttry {\n\t\t\tconst chunk = store.read(chunkAccount);\n\t\t\tif (chunk === undefined) {\n\t\t\t\tthrow new Error(`Missing OAuth credential chunk ${chunkAccount} for ${serverName}`);\n\t\t\t}\n\t\t\treturn chunk;\n\t\t} catch (error) {\n\t\t\tthrow new OAuthCredentialStoreError(\n\t\t\t\t`Failed to read OAuth credentials for ${serverName} from the OS secure credential store`,\n\t\t\t\t\"read\",\n\t\t\t\terror,\n\t\t\t);\n\t\t}\n\t});\n\tconst payload = chunks.join(\"\");\n\tconst digest = createHash(\"sha256\").update(payload, \"utf8\").digest(\"hex\").slice(0, 16);\n\tif (digest !== manifest.chunkDigest) {\n\t\tthrow new OAuthCredentialStoreError(\n\t\t\t`Failed to read OAuth credentials for ${serverName} from the OS secure credential store`,\n\t\t\t\"read\",\n\t\t\tnew Error(\"OAuth credential chunk digest mismatch\"),\n\t\t);\n\t}\n\treturn parseAuthEntryPayload(serverName, payload, \"OS secure credential store chunks\");\n}\n\nfunction readLegacyAuthEntry(serverName: string, options?: AuthStorageOptions): AuthEntry | undefined {\n\tconst filePath = getAuthEntryFilePath(serverName, options);\n\tif (!existsSync(filePath)) return undefined;\n\tconst data = readFileSync(filePath, \"utf-8\");\n\treturn parseAuthEntryPayload(serverName, data, filePath);\n}\n\nfunction removeLegacyAuthEntry(serverName: string, options?: AuthStorageOptions): void {\n\tconst filePath = getAuthEntryFilePath(serverName, options);\n\tif (!existsSync(filePath)) return;\n\ttry {\n\t\trmSync(filePath, { force: true });\n\t} catch (error) {\n\t\tthrow new Error(`Failed to remove legacy plaintext OAuth credentials for ${serverName} at ${filePath}`, {\n\t\t\tcause: error,\n\t\t});\n\t}\n\n\tconst dir = getServerDir(serverName, options);\n\ttry {\n\t\trmSync(dir, { recursive: true });\n\t} catch {\n\t\t// Directory may contain future non-secret metadata; the plaintext file was already removed.\n\t}\n}\n\nfunction writeSecureAuthEntryToStore(\n\tstore: AuthSecretStore,\n\tserverName: string,\n\tentry: AuthEntry,\n\toptions?: AuthStorageOptions,\n): void {\n\tconst account = getAuthEntryAccount(serverName);\n\tconst payload = JSON.stringify(entry);\n\tconst previousManifest = readExistingChunkManifest(store, serverName, account);\n\tconst manifest = payload.length > AUTH_SECRET_CHUNK_SIZE ? createChunkManifest(payload) : undefined;\n\n\ttry {\n\t\tif (manifest) {\n\t\t\tfor (let index = 0; index < manifest.chunkCount; index++) {\n\t\t\t\tconst chunk = payload.slice(index * AUTH_SECRET_CHUNK_SIZE, (index + 1) * AUTH_SECRET_CHUNK_SIZE);\n\t\t\t\tstore.write(getAuthEntryChunkAccount(account, manifest, index), chunk);\n\t\t\t}\n\t\t\tstore.write(account, JSON.stringify(manifest));\n\t\t} else {\n\t\t\t// Compact: multiline secrets corrupt gnome-keyring plaintext (GKeyFile) collections.\n\t\t\tstore.write(account, payload);\n\t\t}\n\t\tif (previousManifest?.chunkDigest !== manifest?.chunkDigest) {\n\t\t\ttryRemoveChunkPayloads(store, account, previousManifest);\n\t\t}\n\t} catch (error) {\n\t\ttryRemoveChunkPayloads(store, account, manifest);\n\t\tthrow new OAuthCredentialStoreError(\n\t\t\t`Failed to write OAuth credentials for ${serverName} to the OS secure credential store`,\n\t\t\t\"write\",\n\t\t\terror,\n\t\t);\n\t}\n\n\tpublishAuthEntryToCache(serverName, payload, options);\n}\n\nfunction publishAuthEntryToCache(serverName: string, payload: string, options?: AuthStorageOptions): void {\n\tif (!isAuthEntryCacheEnabled()) return;\n\tdeleteAuthEntryCacheEntries(serverName);\n\t// Cache the same normalized shape a fresh persistent-store read returns.\n\tconst normalized = toAuthEntry(JSON.parse(payload) as unknown);\n\tif (!normalized) {\n\t\treturn;\n\t}\n\tauthEntryCache.set(getAuthEntryCacheKey(serverName, options), cloneAuthEntry(normalized));\n}\n\nfunction writeSecureAuthEntry(serverName: string, entry: AuthEntry, options?: AuthStorageOptions): void {\n\ttry {\n\t\twriteSecureAuthEntryToStore(getAuthSecretStore(), serverName, entry, options);\n\t} catch (error) {\n\t\tif (!shouldAttemptLinuxKeyringRecovery(error)) throw error;\n\t\twriteSecureAuthEntryToStore(linuxKeyringRecoveryAuthSecretStore, serverName, entry, options);\n\t}\n}\n\n/**\n * Read the auth entry for a server from the OS secure store, importing and\n * deleting a legacy plaintext entry when present.\n */\nfunction readAuthEntryFromStore(\n\tstore: AuthSecretStore,\n\tserverName: string,\n\toptions?: AuthStorageOptions,\n\tbehavior: { migrateLegacy?: boolean } = {},\n): AuthEntry | undefined {\n\tconst account = getAuthEntryAccount(serverName);\n\tlet payload: string | undefined;\n\ttry {\n\t\tpayload = store.read(account);\n\t} catch (error) {\n\t\tthrow new OAuthCredentialStoreError(\n\t\t\t`Failed to read OAuth credentials for ${serverName} from the OS secure credential store`,\n\t\t\t\"read\",\n\t\t\terror,\n\t\t);\n\t}\n\n\tif (payload !== undefined) {\n\t\tconst manifest = readChunkManifestFromPayload(serverName, payload, \"OS secure credential store\");\n\t\tconst entry = manifest\n\t\t\t? readChunkedAuthEntry(store, serverName, account, manifest)\n\t\t\t: parseAuthEntryPayload(serverName, payload, \"OS secure credential store\");\n\t\tremoveLegacyAuthEntry(serverName, options);\n\t\treturn entry;\n\t}\n\n\tconst legacyEntry = readLegacyAuthEntry(serverName, options);\n\tif (!legacyEntry) return undefined;\n\tif (behavior.migrateLegacy === false) return legacyEntry;\n\twriteSecureAuthEntryToStore(store, serverName, legacyEntry, options);\n\tremoveLegacyAuthEntry(serverName, options);\n\treturn legacyEntry;\n}\n\nfunction readAuthEntry(\n\tserverName: string,\n\toptions?: AuthStorageOptions,\n\tbehavior: { migrateLegacy?: boolean } = {},\n): AuthEntry | undefined {\n\t// Status-only reads deliberately bypass the cache because they do not\n\t// migrate legacy entries.\n\tconst cacheable = behavior.migrateLegacy !== false && isAuthEntryCacheEnabled();\n\tconst cacheKey = getAuthEntryCacheKey(serverName, options);\n\tif (cacheable && authEntryCache.has(cacheKey)) {\n\t\treturn cloneAuthEntry(authEntryCache.get(cacheKey));\n\t}\n\n\tlet entry: AuthEntry | undefined;\n\ttry {\n\t\tentry = readAuthEntryFromStore(getAuthSecretStore(), serverName, options, behavior);\n\t} catch (error) {\n\t\tif (!shouldAttemptLinuxKeyringRecovery(error)) throw error;\n\t\tentry = readAuthEntryFromStore(linuxKeyringRecoveryAuthSecretStore, serverName, options, behavior);\n\t}\n\n\tif (cacheable) authEntryCache.set(cacheKey, cloneAuthEntry(entry));\n\treturn entry;\n}\n\n/**\n * Get auth entry for a server.\n */\nexport function getAuthEntry(serverName: string, options?: AuthStorageOptions): AuthEntry | undefined {\n\treturn readAuthEntry(serverName, options);\n}\n\n/**\n * Get auth entry and validate it's for the correct URL.\n * Returns undefined if URL has changed (credentials are invalid).\n */\nexport function getAuthForUrl(\n\tserverName: string,\n\tserverUrl: string,\n\toptions?: AuthStorageOptions,\n): AuthEntry | undefined {\n\tconst entry = getAuthEntry(serverName, options);\n\tif (!entry) return undefined;\n\n\t// If no serverUrl is stored, this is from an old version - consider it invalid\n\tif (!entry.serverUrl) return undefined;\n\n\t// If URL has changed, credentials are invalid\n\tif (entry.serverUrl !== serverUrl) return undefined;\n\n\treturn entry;\n}\n\n/**\n * Inspect credentials for status-only UI paths without treating an unavailable\n * secure store as missing credentials. Authentication operations continue to\n * use getAuthForUrl() directly and therefore remain fail-closed.\n */\nexport function inspectAuthForUrl(\n\tserverName: string,\n\tserverUrl: string,\n\toptions?: AuthStorageOptions,\n): OAuthCredentialStatus {\n\ttry {\n\t\tconst entry = readAuthEntry(serverName, options, { migrateLegacy: false });\n\t\tif (!entry?.serverUrl || entry.serverUrl !== serverUrl) return { status: \"absent\" };\n\t\treturn { status: \"present\", entry };\n\t} catch (error) {\n\t\tif (!(error instanceof OAuthCredentialStoreError)) throw error;\n\t\treturn { status: \"unavailable\", message: formatOAuthCredentialStoreUnavailable(error) };\n\t}\n}\n\n/**\n * Save auth entry for a server.\n */\nexport function saveAuthEntry(\n\tserverName: string,\n\tentry: AuthEntry,\n\tserverUrl?: string,\n\toptions?: AuthStorageOptions,\n): void {\n\t// Always update serverUrl if provided\n\tif (serverUrl) {\n\t\tentry.serverUrl = serverUrl;\n\t}\n\twriteSecureAuthEntry(serverName, entry, options);\n\tremoveLegacyAuthEntry(serverName, options);\n}\n\n/**\n * Remove auth entry for a server.\n */\nfunction removeAuthEntryFromStore(store: AuthSecretStore, serverName: string): void {\n\tconst account = getAuthEntryAccount(serverName);\n\ttry {\n\t\tconst payload = store.read(account);\n\t\tconst manifest =\n\t\t\tpayload === undefined\n\t\t\t\t? undefined\n\t\t\t\t: readChunkManifestFromPayload(serverName, payload, \"OS secure credential store\");\n\t\tif (manifest) removeChunkPayloads(store, account, manifest);\n\t\tstore.remove(account);\n\t} catch (error) {\n\t\tthrow new OAuthCredentialStoreError(\n\t\t\t`Failed to remove OAuth credentials for ${serverName} from the OS secure credential store`,\n\t\t\t\"remove\",\n\t\t\terror,\n\t\t);\n\t}\n}\n\nexport function removeAuthEntry(serverName: string, options?: AuthStorageOptions): void {\n\ttry {\n\t\tremoveAuthEntryFromStore(getAuthSecretStore(), serverName);\n\t} catch (error) {\n\t\tif (!shouldAttemptLinuxKeyringRecovery(error)) throw error;\n\t\tremoveAuthEntryFromStore(linuxKeyringRecoveryAuthSecretStore, serverName);\n\t}\n\tdeleteAuthEntryCacheEntries(serverName);\n\tremoveLegacyAuthEntry(serverName, options);\n}\n\n/**\n * Forget a cached entry so the next ordinary read reloads secure storage.\n */\nexport function invalidateAuthEntryCache(serverName: string): void {\n\tdeleteAuthEntryCacheEntries(serverName);\n}\n\n/**\n * Update tokens for a server.\n */\nexport function updateTokens(\n\tserverName: string,\n\ttokens: StoredTokens,\n\tserverUrl?: string,\n\toptions?: AuthStorageOptions,\n): void {\n\tconst entry = getAuthEntry(serverName, options) ?? {};\n\tif (serverUrl && entry.serverUrl !== serverUrl) {\n\t\tdelete entry.clientInfo;\n\t\tdelete entry.codeVerifier;\n\t\tdelete entry.oauthState;\n\t}\n\tentry.tokens = tokens;\n\tsaveAuthEntry(serverName, entry, serverUrl, options);\n}\n\n/**\n * Update client info for a server.\n */\nexport function updateClientInfo(\n\tserverName: string,\n\tclientInfo: StoredClientInfo,\n\tserverUrl?: string,\n\toptions?: AuthStorageOptions,\n): void {\n\tconst entry = getAuthEntry(serverName, options) ?? {};\n\tif (serverUrl && entry.serverUrl !== serverUrl) {\n\t\tdelete entry.tokens;\n\t\tdelete entry.codeVerifier;\n\t\tdelete entry.oauthState;\n\t}\n\tentry.clientInfo = clientInfo;\n\tsaveAuthEntry(serverName, entry, serverUrl, options);\n}\n\n/**\n * Update code verifier for a server.\n */\nexport function updateCodeVerifier(\n\tserverName: string,\n\tcodeVerifier: string,\n\tserverUrl?: string,\n\toptions?: AuthStorageOptions,\n): void {\n\tconst entry = getAuthEntry(serverName, options) ?? {};\n\tif (serverUrl && entry.serverUrl !== serverUrl) {\n\t\tdelete entry.tokens;\n\t\tdelete entry.clientInfo;\n\t\tdelete entry.oauthState;\n\t}\n\tentry.codeVerifier = codeVerifier;\n\tsaveAuthEntry(serverName, entry, serverUrl, options);\n}\n\n/**\n * Clear code verifier for a server.\n */\nexport function clearCodeVerifier(serverName: string, options?: AuthStorageOptions): void {\n\tconst entry = getAuthEntry(serverName, options);\n\tif (entry) {\n\t\tdelete entry.codeVerifier;\n\t\tsaveAuthEntry(serverName, entry, undefined, options);\n\t}\n}\n\n/**\n * Update OAuth state for a server.\n */\nexport function updateOAuthState(\n\tserverName: string,\n\tstate: string,\n\tserverUrl?: string,\n\toptions?: AuthStorageOptions,\n): void {\n\tconst entry = getAuthEntry(serverName, options) ?? {};\n\tif (serverUrl && entry.serverUrl !== serverUrl) {\n\t\tdelete entry.tokens;\n\t\tdelete entry.clientInfo;\n\t\tdelete entry.codeVerifier;\n\t}\n\tentry.oauthState = state;\n\tsaveAuthEntry(serverName, entry, serverUrl, options);\n}\n\n/**\n * Get OAuth state for a server.\n */\nexport function getOAuthState(serverName: string, options?: AuthStorageOptions): string | undefined {\n\tconst entry = getAuthEntry(serverName, options);\n\treturn entry?.oauthState;\n}\n\n/**\n * Clear OAuth state for a server.\n */\nexport function clearOAuthState(serverName: string, options?: AuthStorageOptions): void {\n\tconst entry = getAuthEntry(serverName, options);\n\tif (entry) {\n\t\tdelete entry.oauthState;\n\t\tsaveAuthEntry(serverName, entry, undefined, options);\n\t}\n}\n\n/**\n * Check if stored tokens are expired.\n * Returns null if no tokens exist, false if no expiry or not expired, true if expired.\n */\nexport function isTokenExpired(serverName: string, options?: AuthStorageOptions): boolean | null {\n\tconst entry = getAuthEntry(serverName, options);\n\tif (!entry?.tokens) return null;\n\tif (entry.tokens.expiresAt === undefined) return false;\n\treturn entry.tokens.expiresAt < Date.now() / 1000;\n}\n\n/**\n * Check if a server has stored tokens.\n */\nexport function hasStoredTokens(serverName: string, options?: AuthStorageOptions): boolean {\n\tconst entry = getAuthEntry(serverName, options);\n\treturn !!entry?.tokens;\n}\n\n/**\n * Clear all credentials for a server.\n */\nexport function clearAllCredentials(serverName: string, options?: AuthStorageOptions): void {\n\tremoveAuthEntry(serverName, options);\n}\n\n/**\n * Clear only client info for a server.\n */\nexport function clearClientInfo(serverName: string, options?: AuthStorageOptions): void {\n\tconst entry = getAuthEntry(serverName, options);\n\tif (entry) {\n\t\tdelete entry.clientInfo;\n\t\tsaveAuthEntry(serverName, entry, undefined, options);\n\t}\n}\n\n/**\n * Clear only tokens for a server.\n */\nexport function clearTokens(serverName: string, options?: AuthStorageOptions): void {\n\tconst entry = getAuthEntry(serverName, options);\n\tif (entry) {\n\t\tdelete entry.tokens;\n\t\tsaveAuthEntry(serverName, entry, undefined, options);\n\t}\n}\n"]}