@bastani/atomic 0.9.26-alpha.1 → 0.9.26-alpha.3

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 (140) hide show
  1. package/CHANGELOG.md +28 -0
  2. package/dist/builtin/intercom/broker/spawn.ts +2 -0
  3. package/dist/builtin/intercom/index.bundle.mjs +1 -0
  4. package/dist/builtin/intercom/package.json +1 -1
  5. package/dist/builtin/mcp/native-client-licenses/NOTICE +2 -0
  6. package/dist/builtin/mcp/package.json +1 -1
  7. package/dist/builtin/subagents/package.json +1 -1
  8. package/dist/builtin/web-access/package.json +1 -1
  9. package/dist/builtin/workflows/package.json +1 -1
  10. package/dist/cli/args.d.ts.map +1 -1
  11. package/dist/cli/args.js +4 -1
  12. package/dist/cli/args.js.map +1 -1
  13. package/dist/core/extensions/api-types.d.ts +2 -1
  14. package/dist/core/extensions/api-types.d.ts.map +1 -1
  15. package/dist/core/extensions/api-types.js.map +1 -1
  16. package/dist/core/extensions/index.d.ts +1 -1
  17. package/dist/core/extensions/index.d.ts.map +1 -1
  18. package/dist/core/extensions/index.js.map +1 -1
  19. package/dist/core/extensions/loader-api.d.ts.map +1 -1
  20. package/dist/core/extensions/loader-api.js +7 -0
  21. package/dist/core/extensions/loader-api.js.map +1 -1
  22. package/dist/core/extensions/provider-types.d.ts +2 -0
  23. package/dist/core/extensions/provider-types.d.ts.map +1 -1
  24. package/dist/core/extensions/provider-types.js.map +1 -1
  25. package/dist/core/keybindings.d.ts +5 -0
  26. package/dist/core/keybindings.d.ts.map +1 -1
  27. package/dist/core/keybindings.js +1 -0
  28. package/dist/core/keybindings.js.map +1 -1
  29. package/dist/core/model-runtime-streaming.d.ts +2 -1
  30. package/dist/core/model-runtime-streaming.d.ts.map +1 -1
  31. package/dist/core/model-runtime-streaming.js +4 -1
  32. package/dist/core/model-runtime-streaming.js.map +1 -1
  33. package/dist/core/model-runtime.d.ts +2 -0
  34. package/dist/core/model-runtime.d.ts.map +1 -1
  35. package/dist/core/model-runtime.js +69 -5
  36. package/dist/core/model-runtime.js.map +1 -1
  37. package/dist/core/oauth-provider-metadata.d.ts.map +1 -1
  38. package/dist/core/oauth-provider-metadata.js +4 -17
  39. package/dist/core/oauth-provider-metadata.js.map +1 -1
  40. package/dist/core/provider-alias.d.ts +8 -0
  41. package/dist/core/provider-alias.d.ts.map +1 -0
  42. package/dist/core/provider-alias.js +119 -0
  43. package/dist/core/provider-alias.js.map +1 -0
  44. package/dist/core/provider-composer-internal.d.ts +1 -0
  45. package/dist/core/provider-composer-internal.d.ts.map +1 -1
  46. package/dist/core/provider-composer-internal.js.map +1 -1
  47. package/dist/core/provider-composer.d.ts.map +1 -1
  48. package/dist/core/provider-composer.js +9 -0
  49. package/dist/core/provider-composer.js.map +1 -1
  50. package/dist/core/sdk.js +2 -1
  51. package/dist/core/sdk.js.map +1 -1
  52. package/dist/extensions/mcp/cli.d.ts.map +1 -1
  53. package/dist/extensions/mcp/cli.js +4 -1
  54. package/dist/extensions/mcp/cli.js.map +1 -1
  55. package/dist/extensions/mcp/client/oauth/callback.d.ts +4 -2
  56. package/dist/extensions/mcp/client/oauth/callback.d.ts.map +1 -1
  57. package/dist/extensions/mcp/client/oauth/callback.js +12 -7
  58. package/dist/extensions/mcp/client/oauth/callback.js.map +1 -1
  59. package/dist/extensions/mcp/client/oauth/flow.d.ts +7 -1
  60. package/dist/extensions/mcp/client/oauth/flow.d.ts.map +1 -1
  61. package/dist/extensions/mcp/client/oauth/flow.js +20 -21
  62. package/dist/extensions/mcp/client/oauth/flow.js.map +1 -1
  63. package/dist/extensions/mcp/client/oauth/index.d.ts +1 -1
  64. package/dist/extensions/mcp/client/oauth/index.d.ts.map +1 -1
  65. package/dist/extensions/mcp/client/oauth/index.js.map +1 -1
  66. package/dist/extensions/mcp/client/oauth/provider.d.ts +5 -2
  67. package/dist/extensions/mcp/client/oauth/provider.d.ts.map +1 -1
  68. package/dist/extensions/mcp/client/oauth/provider.js +2 -0
  69. package/dist/extensions/mcp/client/oauth/provider.js.map +1 -1
  70. package/dist/extensions/mcp/config.d.ts +16 -4
  71. package/dist/extensions/mcp/config.d.ts.map +1 -1
  72. package/dist/extensions/mcp/config.js +50 -11
  73. package/dist/extensions/mcp/config.js.map +1 -1
  74. package/dist/extensions/mcp/index.d.ts +4 -1
  75. package/dist/extensions/mcp/index.d.ts.map +1 -1
  76. package/dist/extensions/mcp/index.js +80 -46
  77. package/dist/extensions/mcp/index.js.map +1 -1
  78. package/dist/extensions/mcp/oauth.d.ts.map +1 -1
  79. package/dist/extensions/mcp/oauth.js +9 -5
  80. package/dist/extensions/mcp/oauth.js.map +1 -1
  81. package/dist/extensions/mcp/ui.d.ts.map +1 -1
  82. package/dist/extensions/mcp/ui.js +8 -4
  83. package/dist/extensions/mcp/ui.js.map +1 -1
  84. package/dist/index-extensions.d.ts +1 -1
  85. package/dist/index-extensions.d.ts.map +1 -1
  86. package/dist/index-extensions.js.map +1 -1
  87. package/dist/index.d.ts +1 -1
  88. package/dist/index.js.map +1 -1
  89. package/dist/modes/interactive/chat-input-actions.js.map +1 -1
  90. package/dist/modes/interactive/components/auth-url.d.ts +10 -0
  91. package/dist/modes/interactive/components/auth-url.d.ts.map +1 -0
  92. package/dist/modes/interactive/components/auth-url.js +37 -0
  93. package/dist/modes/interactive/components/auth-url.js.map +1 -0
  94. package/dist/modes/interactive/components/index.d.ts +0 -1
  95. package/dist/modes/interactive/components/index.d.ts.map +1 -1
  96. package/dist/modes/interactive/components/index.js +0 -1
  97. package/dist/modes/interactive/components/index.js.map +1 -1
  98. package/dist/modes/interactive/components/login-dialog.d.ts +1 -0
  99. package/dist/modes/interactive/components/login-dialog.d.ts.map +1 -1
  100. package/dist/modes/interactive/components/login-dialog.js +10 -5
  101. package/dist/modes/interactive/components/login-dialog.js.map +1 -1
  102. package/dist/modes/interactive/interactive-auth-login.js +0 -1
  103. package/dist/modes/interactive/interactive-auth-login.js.map +1 -1
  104. package/dist/modes/interactive/interactive-hotkeys-debug.js +1 -11
  105. package/dist/modes/interactive/interactive-hotkeys-debug.js.map +1 -1
  106. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  107. package/dist/modes/interactive/interactive-mode-deps.d.ts +1 -2
  108. package/dist/modes/interactive/interactive-mode-deps.d.ts.map +1 -1
  109. package/dist/modes/interactive/interactive-mode-deps.js +0 -1
  110. package/dist/modes/interactive/interactive-mode-deps.js.map +1 -1
  111. package/dist/modes/interactive/interactive-mode-surface.d.ts +0 -5
  112. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  113. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  114. package/dist/modes/interactive/interactive-model-routing.js +0 -2
  115. package/dist/modes/interactive/interactive-model-routing.js.map +1 -1
  116. package/dist/modes/interactive/interactive-tui.js.map +1 -1
  117. package/dist/modes/interactive-engine/engine-custom-ui.d.ts.map +1 -1
  118. package/dist/modes/interactive-engine/engine-custom-ui.js +38 -2
  119. package/dist/modes/interactive-engine/engine-custom-ui.js.map +1 -1
  120. package/dist/modes/interactive-engine/protocol.d.ts +10 -0
  121. package/dist/modes/interactive-engine/protocol.d.ts.map +1 -1
  122. package/dist/modes/interactive-engine/protocol.js +10 -0
  123. package/dist/modes/interactive-engine/protocol.js.map +1 -1
  124. package/dist/modes/interactive-engine/remote-component.d.ts +2 -1
  125. package/dist/modes/interactive-engine/remote-component.d.ts.map +1 -1
  126. package/dist/modes/interactive-engine/remote-component.js +23 -1
  127. package/dist/modes/interactive-engine/remote-component.js.map +1 -1
  128. package/docs/custom-provider/oauth.md +2 -0
  129. package/docs/custom-provider/registration.md +32 -0
  130. package/docs/custom-provider.md +1 -0
  131. package/docs/keybindings.md +3 -0
  132. package/docs/mcp-servers.md +13 -1
  133. package/docs/providers.md +2 -0
  134. package/examples/extensions/provider-accounts.ts +11 -0
  135. package/npm-shrinkwrap.json +55 -33
  136. package/package.json +4 -3
  137. package/dist/modes/interactive/components/daxnuts.d.ts +0 -23
  138. package/dist/modes/interactive/components/daxnuts.d.ts.map +0 -1
  139. package/dist/modes/interactive/components/daxnuts.js +0 -140
  140. package/dist/modes/interactive/components/daxnuts.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"callback.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/callback.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type Server, type ServerResponse } from \"node:http\";\n\nexport interface OAuthCallback {\n\tcode: string;\n\tstate: string;\n\tiss?: string;\n}\n\n/** Outcome shown on the browser page after the redirect. */\nexport type OAuthCallbackPage = { ok: true } | { ok: false; message: string; details?: string };\n\nexport interface OAuthCallbackServerOptions {\n\t/** Address to listen on. Default: `127.0.0.1`. */\n\thost?: string;\n\t/**\n\t * Host name in `redirectUrl`, for example `localhost` for a client registered with it while\n\t * listening on `127.0.0.1`. Default: `host`.\n\t */\n\tredirectHost?: string;\n\tport?: number;\n\tpath?: string;\n\ttimeoutMs?: number;\n\t/** Render the browser page as HTML. Default: a plain-text message. */\n\trenderPage?: (page: OAuthCallbackPage) => string;\n}\n\nfunction plainText(page: OAuthCallbackPage): string {\n\tif (page.ok) return \"Authorization complete. You may close this window.\";\n\treturn page.details ? `${page.message}\\n\\n${page.details}` : page.message;\n}\n\nexport class OAuthCallbackServer {\n\treadonly redirectUrl: string;\n\tprivate server: Server;\n\tprivate path: string;\n\tprivate timeoutMs: number;\n\tprivate renderPage: ((page: OAuthCallbackPage) => string) | undefined;\n\tprivate pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\tresolve: (callback: OAuthCallback) => void;\n\t\t\treject: (error: Error) => void;\n\t\t\ttimer: ReturnType<typeof setTimeout>;\n\t\t}\n\t>();\n\n\tprivate constructor(\n\t\tserver: Server,\n\t\tredirectUrl: string,\n\t\tpath: string,\n\t\ttimeoutMs: number,\n\t\trenderPage: ((page: OAuthCallbackPage) => string) | undefined,\n\t) {\n\t\tthis.server = server;\n\t\tthis.redirectUrl = redirectUrl;\n\t\tthis.path = path;\n\t\tthis.timeoutMs = timeoutMs;\n\t\tthis.renderPage = renderPage;\n\t}\n\n\tstatic async listen(options: OAuthCallbackServerOptions = {}): Promise<OAuthCallbackServer> {\n\t\tconst host = options.host ?? \"127.0.0.1\";\n\t\tconst redirectHost = options.redirectHost ?? host;\n\t\tconst path = options.path ?? \"/callback\";\n\t\tlet instance: OAuthCallbackServer | undefined;\n\t\tconst server = createServer((request, response) => instance?.handle(request.url ?? \"/\", response));\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tserver.once(\"error\", reject);\n\t\t\tserver.listen(options.port ?? 0, host, () => {\n\t\t\t\tserver.off(\"error\", reject);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t\tconst address = server.address();\n\t\tif (!address || typeof address === \"string\") throw new Error(\"OAuth callback server did not bind to TCP\");\n\t\tinstance = new OAuthCallbackServer(\n\t\t\tserver,\n\t\t\t`http://${redirectHost.includes(\":\") ? `[${redirectHost}]` : redirectHost}:${address.port}${path}`,\n\t\t\tpath,\n\t\t\toptions.timeoutMs ?? 5 * 60_000,\n\t\t\toptions.renderPage,\n\t\t);\n\t\treturn instance;\n\t}\n\n\twaitForCallback(state: string): Promise<OAuthCallback> {\n\t\tif (this.pending.has(state)) throw new Error(\"OAuth state is already pending\");\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.pending.delete(state);\n\t\t\t\treject(new Error(\"OAuth callback timed out\"));\n\t\t\t}, this.timeoutMs);\n\t\t\tthis.pending.set(state, { resolve, reject, timer });\n\t\t});\n\t}\n\n\tasync close(): Promise<void> {\n\t\tfor (const pending of this.pending.values()) {\n\t\t\tclearTimeout(pending.timer);\n\t\t\tpending.reject(new Error(\"OAuth callback server closed\"));\n\t\t}\n\t\tthis.pending.clear();\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tthis.server.close((error) => (error ? reject(error) : resolve()));\n\t\t});\n\t}\n\n\tprivate reply(response: ServerResponse, status: number, page: OAuthCallbackPage): void {\n\t\tif (this.renderPage) {\n\t\t\tresponse.writeHead(status, { \"content-type\": \"text/html; charset=utf-8\", \"cache-control\": \"no-store\" });\n\t\t\tresponse.end(this.renderPage(page));\n\t\t} else {\n\t\t\tresponse.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" }).end(plainText(page));\n\t\t}\n\t}\n\n\tprivate handle(rawUrl: string, response: ServerResponse): void {\n\t\tconst url = new URL(rawUrl, this.redirectUrl);\n\t\tif (url.pathname !== this.path) {\n\t\t\tthis.reply(response, 404, { ok: false, message: \"Not found\" });\n\t\t\treturn;\n\t\t}\n\t\tconst state = url.searchParams.get(\"state\");\n\t\tconst pending = state ? this.pending.get(state) : undefined;\n\t\tif (!state || !pending) {\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Invalid or expired OAuth state\" });\n\t\t\treturn;\n\t\t}\n\t\tclearTimeout(pending.timer);\n\t\tthis.pending.delete(state);\n\t\tconst error = url.searchParams.get(\"error\");\n\t\tif (error) {\n\t\t\tconst description = url.searchParams.get(\"error_description\") ?? error;\n\t\t\tpending.reject(new Error(description));\n\t\t\tthis.reply(response, 200, {\n\t\t\t\tok: false,\n\t\t\t\tmessage: \"Authorization failed. You may close this window.\",\n\t\t\t\tdetails: description,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst code = url.searchParams.get(\"code\");\n\t\tif (!code) {\n\t\t\tpending.reject(new Error(\"OAuth callback did not include an authorization code\"));\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Missing authorization code\" });\n\t\t\treturn;\n\t\t}\n\t\tconst iss = url.searchParams.get(\"iss\");\n\t\tpending.resolve({ code, state, ...(iss ? { iss } : {}) });\n\t\tthis.reply(response, 200, { ok: true });\n\t}\n}\n"]}
1
+ {"version":3,"file":"callback.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/callback.ts"],"names":[],"mappings":"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","sourcesContent":["import { createServer, type Server, type ServerResponse } from \"node:http\";\n\nexport interface OAuthCallback {\n\tcode: string;\n\tstate: string;\n\tiss?: string;\n}\n\n/** Outcome shown on the browser page after the redirect. */\nexport type OAuthCallbackPage = { ok: true } | { ok: false; message: string; details?: string };\n\nexport interface OAuthCallbackServerOptions {\n\t/** Address to listen on. Default: `127.0.0.1`. */\n\thost?: string;\n\t/**\n\t * Host name in `redirectUrl`, for example `localhost` for a client registered with it while\n\t * listening on `127.0.0.1`. Default: `host`.\n\t */\n\tredirectHost?: string;\n\tport?: number;\n\tpath?: string;\n\t/** Additional callback paths, for server-specific redirect URIs. */\n\textraPaths?: string[];\n\ttimeoutMs?: number;\n\t/** Render the browser page as HTML. Default: a plain-text message. */\n\trenderPage?: (page: OAuthCallbackPage) => string;\n}\n\nfunction plainText(page: OAuthCallbackPage): string {\n\tif (page.ok) return \"Authorization complete. You may close this window.\";\n\treturn page.details ? `${page.message}\\n\\n${page.details}` : page.message;\n}\n\nexport class OAuthCallbackServer {\n\treadonly redirectUrl: string;\n\tprivate server: Server;\n\tprivate paths: string[];\n\tprivate timeoutMs: number;\n\tprivate renderPage: ((page: OAuthCallbackPage) => string) | undefined;\n\tprivate pending = new Map<\n\t\tstring,\n\t\t{\n\t\t\tresolve: (callback: OAuthCallback) => void;\n\t\t\treject: (error: Error) => void;\n\t\t\ttimer: ReturnType<typeof setTimeout>;\n\t\t\tpath: string | undefined;\n\t\t}\n\t>();\n\n\tprivate constructor(\n\t\tserver: Server,\n\t\tredirectUrl: string,\n\t\tpaths: string[],\n\t\ttimeoutMs: number,\n\t\trenderPage: ((page: OAuthCallbackPage) => string) | undefined,\n\t) {\n\t\tthis.server = server;\n\t\tthis.redirectUrl = redirectUrl;\n\t\tthis.paths = paths;\n\t\tthis.timeoutMs = timeoutMs;\n\t\tthis.renderPage = renderPage;\n\t}\n\n\tstatic async listen(options: OAuthCallbackServerOptions = {}): Promise<OAuthCallbackServer> {\n\t\tconst host = options.host ?? \"127.0.0.1\";\n\t\tconst redirectHost = options.redirectHost ?? host;\n\t\tconst path = options.path ?? \"/callback\";\n\t\tlet instance: OAuthCallbackServer | undefined;\n\t\tconst server = createServer((request, response) => instance?.handle(request.url ?? \"/\", response));\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tserver.once(\"error\", reject);\n\t\t\tserver.listen(options.port ?? 0, host, () => {\n\t\t\t\tserver.off(\"error\", reject);\n\t\t\t\tresolve();\n\t\t\t});\n\t\t});\n\t\tconst address = server.address();\n\t\tif (!address || typeof address === \"string\") throw new Error(\"OAuth callback server did not bind to TCP\");\n\t\tinstance = new OAuthCallbackServer(\n\t\t\tserver,\n\t\t\t`http://${redirectHost.includes(\":\") ? `[${redirectHost}]` : redirectHost}:${address.port}${path}`,\n\t\t\t[path, ...(options.extraPaths ?? [])],\n\t\t\toptions.timeoutMs ?? 5 * 60_000,\n\t\t\toptions.renderPage,\n\t\t);\n\t\treturn instance;\n\t}\n\n\twaitForCallback(state: string, path?: string): Promise<OAuthCallback> {\n\t\tif (this.pending.has(state)) throw new Error(\"OAuth state is already pending\");\n\t\treturn new Promise((resolve, reject) => {\n\t\t\tconst timer = setTimeout(() => {\n\t\t\t\tthis.pending.delete(state);\n\t\t\t\treject(new Error(\"OAuth callback timed out\"));\n\t\t\t}, this.timeoutMs);\n\t\t\tthis.pending.set(state, { resolve, reject, timer, path });\n\t\t});\n\t}\n\n\tasync close(): Promise<void> {\n\t\tfor (const pending of this.pending.values()) {\n\t\t\tclearTimeout(pending.timer);\n\t\t\tpending.reject(new Error(\"OAuth callback server closed\"));\n\t\t}\n\t\tthis.pending.clear();\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tthis.server.close((error) => (error ? reject(error) : resolve()));\n\t\t});\n\t}\n\n\tprivate reply(response: ServerResponse, status: number, page: OAuthCallbackPage): void {\n\t\tif (this.renderPage) {\n\t\t\tresponse.writeHead(status, { \"content-type\": \"text/html; charset=utf-8\", \"cache-control\": \"no-store\" });\n\t\t\tresponse.end(this.renderPage(page));\n\t\t} else {\n\t\t\tresponse.writeHead(status, { \"content-type\": \"text/plain; charset=utf-8\" }).end(plainText(page));\n\t\t}\n\t}\n\n\tprivate handle(rawUrl: string, response: ServerResponse): void {\n\t\tconst url = new URL(rawUrl, this.redirectUrl);\n\t\tif (!this.paths.includes(url.pathname)) {\n\t\t\tthis.reply(response, 404, { ok: false, message: \"Not found\" });\n\t\t\treturn;\n\t\t}\n\t\tconst state = url.searchParams.get(\"state\");\n\t\tconst pending = state ? this.pending.get(state) : undefined;\n\t\tif (!state || !pending) {\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Invalid or expired OAuth state\" });\n\t\t\treturn;\n\t\t}\n\t\tclearTimeout(pending.timer);\n\t\tthis.pending.delete(state);\n\t\tif (pending.path !== undefined && url.pathname !== pending.path) {\n\t\t\tpending.reject(new Error(\"The authorization response arrived on another redirect URI\"));\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Unexpected redirect URI\" });\n\t\t\treturn;\n\t\t}\n\t\tconst error = url.searchParams.get(\"error\");\n\t\tif (error) {\n\t\t\tconst description = url.searchParams.get(\"error_description\") ?? error;\n\t\t\tpending.reject(new Error(description));\n\t\t\tthis.reply(response, 200, {\n\t\t\t\tok: false,\n\t\t\t\tmessage: \"Authorization failed. You may close this window.\",\n\t\t\t\tdetails: description,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\t\tconst code = url.searchParams.get(\"code\");\n\t\tif (!code) {\n\t\t\tpending.reject(new Error(\"OAuth callback did not include an authorization code\"));\n\t\t\tthis.reply(response, 400, { ok: false, message: \"Missing authorization code\" });\n\t\t\treturn;\n\t\t}\n\t\tconst iss = url.searchParams.get(\"iss\");\n\t\tpending.resolve({ code, state, ...(iss ? { iss } : {}) });\n\t\tthis.reply(response, 200, { ok: true });\n\t}\n}\n"]}
@@ -1,10 +1,16 @@
1
1
  import type { AuthProvider, McpFetch } from "../auth-provider.js";
2
2
  import { type AuthorizationServerMetadata, type OAuthClientInformationFull, type OAuthClientInformationMixed, type OAuthClientMetadata, type OAuthDiscoveryState, type OAuthTokens } from "./types.js";
3
3
  export type AddClientAuthentication = (headers: Headers, params: URLSearchParams, url: string | URL, metadata?: AuthorizationServerMetadata) => void | Promise<void>;
4
+ /** A Client ID Metadata Document URL and a redirect URI it lists. */
5
+ export interface OAuthClientMetadataDocument {
6
+ url: string;
7
+ redirectUrl: string;
8
+ }
4
9
  export interface OAuthClientProvider {
5
10
  readonly redirectUrl: string | URL;
6
11
  readonly clientMetadata: OAuthClientMetadata;
7
- readonly clientMetadataUrl?: string;
12
+ /** Called without stored client information. The caller checks server support; the document is not stored. */
13
+ clientMetadataDocument?(metadata: AuthorizationServerMetadata | undefined): OAuthClientMetadataDocument | undefined;
8
14
  state?(): string | Promise<string>;
9
15
  clientInformation(): OAuthClientInformationMixed | undefined | Promise<OAuthClientInformationMixed | undefined>;
10
16
  saveClientInformation?(information: OAuthClientInformationMixed): void | Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/flow.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flow.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/flow.ts"],"names":[],"mappings":"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"}
@@ -175,29 +175,28 @@ async function runFlow(provider, options) {
175
175
  const resource = selectResource(options.serverUrl, discovered.resourceMetadata);
176
176
  // `||`, not `??`: an empty scope (for example from `scopes_supported: []`) falls through to the next source.
177
177
  const scope = options.scope || discovered.resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope;
178
- let client = await provider.clientInformation();
178
+ const stored = await provider.clientInformation();
179
+ const clientDocument = stored ? undefined : provider.clientMetadataDocument?.(metadata);
180
+ if (clientDocument) {
181
+ const url = new URL(clientDocument.url);
182
+ if (url.protocol !== "https:" || url.pathname === "/")
183
+ throw new Error("Invalid OAuth client metadata URL");
184
+ }
185
+ let client = stored ?? (clientDocument && { client_id: clientDocument.url });
179
186
  if (!client) {
180
187
  if (options.authorizationCode)
181
188
  throw new Error("OAuth client information is missing during code exchange");
182
- if (metadata?.client_id_metadata_document_supported && provider.clientMetadataUrl) {
183
- const url = new URL(provider.clientMetadataUrl);
184
- if (url.protocol !== "https:" || url.pathname === "/")
185
- throw new Error("Invalid OAuth client metadata URL");
186
- client = { client_id: provider.clientMetadataUrl };
187
- await provider.saveClientInformation?.(client);
188
- }
189
- else {
190
- if (!provider.saveClientInformation)
191
- throw new Error("OAuth client information cannot be persisted");
192
- client = await registerClient(discovered.authorizationServerUrl, {
193
- metadata,
194
- clientMetadata: provider.clientMetadata,
195
- scope,
196
- fetch: options.fetch,
197
- });
198
- await provider.saveClientInformation(client);
199
- }
189
+ if (!provider.saveClientInformation)
190
+ throw new Error("OAuth client information cannot be persisted");
191
+ client = await registerClient(discovered.authorizationServerUrl, {
192
+ metadata,
193
+ clientMetadata: provider.clientMetadata,
194
+ scope,
195
+ fetch: options.fetch,
196
+ });
197
+ await provider.saveClientInformation(client);
200
198
  }
199
+ const redirectUrl = clientDocument?.redirectUrl ?? provider.redirectUrl;
201
200
  const tokenOptions = {
202
201
  metadata,
203
202
  clientInformation: client,
@@ -216,7 +215,7 @@ async function runFlow(provider, options) {
216
215
  ...tokenOptions,
217
216
  code: options.authorizationCode,
218
217
  codeVerifier: await provider.codeVerifier(),
219
- redirectUrl: provider.redirectUrl,
218
+ redirectUrl,
220
219
  });
221
220
  // A response without `scope` grants the requested scope (RFC 6749 §5.1). Recorded so a step-up can
222
221
  // keep it. Callers pass the options of the authorization request, so `scope` is what was requested.
@@ -245,7 +244,7 @@ async function runFlow(provider, options) {
245
244
  const authorization = await startAuthorization(discovered.authorizationServerUrl, {
246
245
  metadata,
247
246
  clientInformation: client,
248
- redirectUrl: provider.redirectUrl,
247
+ redirectUrl,
249
248
  scope,
250
249
  state,
251
250
  resource,
@@ -1 +1 @@
1
- {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/flow.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Adapted from modelcontextprotocol/typescript-sdk v1.29.0 src/client/auth.ts.\n * Copyright (c) 2024 Anthropic, PBC. Licensed under MIT; see LICENSES/.\n * Modified to remove SDK/Zod dependencies and use WebCrypto for PKCE.\n */\n\nimport type { AuthProvider, McpFetch, UnauthorizedContext } from \"../auth-provider.js\";\nimport { isObject } from \"../protocol/jsonrpc.js\";\nimport {\n\tdiscoverAuthorizationServerMetadata,\n\tdiscoverOAuthServerInfo,\n\tparseWwwAuthenticate,\n\tselectResource,\n} from \"./discovery.js\";\nimport {\n\tMcpOAuthAuthorizationRequiredError,\n\tOAuthError,\n\tOAuthInsecureEndpointError,\n\tOAuthIssuerMismatchError,\n\tOAuthRegistrationError,\n} from \"./errors.js\";\nimport {\n\ttype AuthorizationServerMetadata,\n\ttype OAuthClientInformation,\n\ttype OAuthClientInformationFull,\n\ttype OAuthClientInformationMixed,\n\ttype OAuthClientMetadata,\n\ttype OAuthDiscoveryState,\n\ttype OAuthTokens,\n\tparseClientInformation,\n\tparseOAuthTokens,\n} from \"./types.js\";\n\nexport type AddClientAuthentication = (\n\theaders: Headers,\n\tparams: URLSearchParams,\n\turl: string | URL,\n\tmetadata?: AuthorizationServerMetadata,\n) => void | Promise<void>;\n\nexport interface OAuthClientProvider {\n\treadonly redirectUrl: string | URL;\n\treadonly clientMetadata: OAuthClientMetadata;\n\treadonly clientMetadataUrl?: string;\n\tstate?(): string | Promise<string>;\n\tclientInformation(): OAuthClientInformationMixed | undefined | Promise<OAuthClientInformationMixed | undefined>;\n\tsaveClientInformation?(information: OAuthClientInformationMixed): void | Promise<void>;\n\ttokens(): OAuthTokens | undefined | Promise<OAuthTokens | undefined>;\n\tsaveTokens(tokens: OAuthTokens): void | Promise<void>;\n\tredirectToAuthorization(url: URL): void | Promise<void>;\n\tsaveCodeVerifier(verifier: string): void | Promise<void>;\n\tcodeVerifier(): string | Promise<string>;\n\taddClientAuthentication?: AddClientAuthentication;\n\tinvalidateCredentials?(kind: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"): void | Promise<void>;\n\tsaveDiscoveryState?(state: OAuthDiscoveryState): void | Promise<void>;\n\tdiscoveryState?(): OAuthDiscoveryState | undefined | Promise<OAuthDiscoveryState | undefined>;\n}\n\nexport interface OAuthFlowOptions {\n\tserverUrl: string | URL;\n\tauthorizationCode?: string;\n\t/** `iss` parameter of the authorization response that delivered `authorizationCode` (RFC 9207). */\n\tiss?: string;\n\tscope?: string;\n\tresourceMetadataUrl?: URL;\n\t/**\n\t * Authorization server metadata document to use instead of discovery, for servers that advertise a\n\t * wrong authorization server or none. It is trusted as configured. Must use https, except on loopback.\n\t */\n\tauthorizationServerMetadataUrl?: URL;\n\tfetch?: McpFetch;\n\tskipIssuerValidation?: boolean;\n\t/**\n\t * Go straight to the authorization redirect instead of refreshing stored tokens, for example when the\n\t * server asks for scopes the current grant lacks (a refresh keeps the old scope).\n\t */\n\tskipRefresh?: boolean;\n}\n\nexport type OAuthFlowResult = \"AUTHORIZED\" | \"REDIRECT\";\ntype ClientAuthMethod = \"client_secret_basic\" | \"client_secret_post\" | \"none\";\n\nexport interface TokenRequestOptions {\n\tmetadata?: AuthorizationServerMetadata;\n\tclientInformation: OAuthClientInformationMixed;\n\tresource?: string;\n\taddClientAuthentication?: AddClientAuthentication;\n\tfetch?: McpFetch;\n}\n\nfunction loopback(hostname: string): boolean {\n\treturn hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\" || hostname === \"::1\";\n}\n\nfunction secureEndpoint(value: string | URL): URL {\n\tconst url = new URL(value);\n\tif (url.protocol !== \"https:\" && !loopback(url.hostname)) throw new OAuthInsecureEndpointError(url.href);\n\treturn url;\n}\n\nfunction selectClientAuthMethod(information: OAuthClientInformationMixed, supported: string[]): ClientAuthMethod {\n\tconst hinted = \"token_endpoint_auth_method\" in information ? information.token_endpoint_auth_method : undefined;\n\tif (\n\t\thinted &&\n\t\t[\"client_secret_basic\", \"client_secret_post\", \"none\"].includes(hinted) &&\n\t\t(supported.length === 0 || supported.includes(hinted))\n\t) {\n\t\treturn hinted as ClientAuthMethod;\n\t}\n\tif (supported.length === 0) return information.client_secret ? \"client_secret_basic\" : \"none\";\n\tif (information.client_secret && supported.includes(\"client_secret_basic\")) return \"client_secret_basic\";\n\tif (information.client_secret && supported.includes(\"client_secret_post\")) return \"client_secret_post\";\n\tif (supported.includes(\"none\")) return \"none\";\n\treturn information.client_secret ? \"client_secret_post\" : \"none\";\n}\n\nfunction applyClientAuthentication(\n\tmethod: ClientAuthMethod,\n\tinformation: OAuthClientInformation,\n\theaders: Headers,\n\tparams: URLSearchParams,\n): void {\n\tif (method === \"client_secret_basic\") {\n\t\tif (!information.client_secret) throw new Error(\"client_secret_basic requires a client secret\");\n\t\theaders.set(\n\t\t\t\"Authorization\",\n\t\t\t`Basic ${Buffer.from(`${information.client_id}:${information.client_secret}`).toString(\"base64\")}`,\n\t\t);\n\t} else {\n\t\tparams.set(\"client_id\", information.client_id);\n\t\tif (method === \"client_secret_post\" && information.client_secret)\n\t\t\tparams.set(\"client_secret\", information.client_secret);\n\t}\n}\n\nasync function pkce(): Promise<{ verifier: string; challenge: string }> {\n\tconst bytes = crypto.getRandomValues(new Uint8Array(32));\n\tconst verifier = Buffer.from(bytes).toString(\"base64url\");\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(verifier));\n\treturn { verifier, challenge: Buffer.from(digest).toString(\"base64url\") };\n}\n\nexport async function startAuthorization(\n\tauthorizationServerUrl: string | URL,\n\toptions: {\n\t\tmetadata?: AuthorizationServerMetadata;\n\t\tclientInformation: OAuthClientInformationMixed;\n\t\tredirectUrl: string | URL;\n\t\tscope?: string;\n\t\tstate?: string;\n\t\tresource?: string;\n\t},\n): Promise<{ authorizationUrl: URL; codeVerifier: string }> {\n\tconst metadata = options.metadata;\n\tif (metadata && !metadata.response_types_supported.includes(\"code\")) {\n\t\tthrow new Error(\"Authorization server does not support authorization codes\");\n\t}\n\tif (metadata?.code_challenge_methods_supported && !metadata.code_challenge_methods_supported.includes(\"S256\")) {\n\t\tthrow new Error(\"Authorization server does not support PKCE S256\");\n\t}\n\tconst url = new URL(metadata?.authorization_endpoint ?? new URL(\"/authorize\", authorizationServerUrl));\n\tconst { verifier, challenge } = await pkce();\n\turl.searchParams.set(\"response_type\", \"code\");\n\turl.searchParams.set(\"client_id\", options.clientInformation.client_id);\n\turl.searchParams.set(\"code_challenge\", challenge);\n\turl.searchParams.set(\"code_challenge_method\", \"S256\");\n\turl.searchParams.set(\"redirect_uri\", String(options.redirectUrl));\n\tif (options.state) url.searchParams.set(\"state\", options.state);\n\tif (options.scope) url.searchParams.set(\"scope\", options.scope);\n\tif (options.scope?.split(/\\s+/).includes(\"offline_access\")) url.searchParams.set(\"prompt\", \"consent\");\n\tif (options.resource) url.searchParams.set(\"resource\", options.resource);\n\treturn { authorizationUrl: url, codeVerifier: verifier };\n}\n\nasync function tokenRequest(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions,\n\tparams: URLSearchParams,\n): Promise<OAuthTokens> {\n\tconst url = secureEndpoint(options.metadata?.token_endpoint ?? new URL(\"/token\", authorizationServerUrl));\n\tconst headers = new Headers({ Accept: \"application/json\", \"content-type\": \"application/x-www-form-urlencoded\" });\n\tif (options.resource) params.set(\"resource\", options.resource);\n\tif (options.addClientAuthentication) {\n\t\tawait options.addClientAuthentication(headers, params, url, options.metadata);\n\t} else {\n\t\tapplyClientAuthentication(\n\t\t\tselectClientAuthMethod(\n\t\t\t\toptions.clientInformation,\n\t\t\t\toptions.metadata?.token_endpoint_auth_methods_supported ?? [],\n\t\t\t),\n\t\t\toptions.clientInformation,\n\t\t\theaders,\n\t\t\tparams,\n\t\t);\n\t}\n\tconst response = await (options.fetch ?? globalThis.fetch)(url, { method: \"POST\", headers, body: params });\n\tconst text = await response.text();\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(text);\n\t} catch {}\n\t// Servers may report OAuth errors with any status, so check the body before the status.\n\tif (isObject(value) && typeof value.error === \"string\") {\n\t\tthrow new OAuthError(\n\t\t\tvalue.error,\n\t\t\ttypeof value.error_description === \"string\" ? value.error_description : value.error,\n\t\t\ttypeof value.error_uri === \"string\" ? value.error_uri : undefined,\n\t\t);\n\t}\n\tif (!response.ok) throw new OAuthError(\"server_error\", `HTTP ${response.status}: ${text}`);\n\treturn parseOAuthTokens(value);\n}\n\nexport async function registerClient(\n\tauthorizationServerUrl: string | URL,\n\toptions: {\n\t\tmetadata?: AuthorizationServerMetadata;\n\t\tclientMetadata: OAuthClientMetadata;\n\t\tscope?: string;\n\t\tfetch?: McpFetch;\n\t},\n): Promise<OAuthClientInformationFull> {\n\tconst endpoint = options.metadata?.registration_endpoint;\n\tif (options.metadata && !endpoint)\n\t\tthrow new Error(\"Authorization server does not support dynamic client registration\");\n\tconst response = await (options.fetch ?? globalThis.fetch)(\n\t\tnew URL(endpoint ?? new URL(\"/register\", authorizationServerUrl)),\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Accept: \"application/json\", \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ ...options.clientMetadata, ...(options.scope ? { scope: options.scope } : {}) }),\n\t\t},\n\t);\n\tif (!response.ok) throw new OAuthRegistrationError(response.status, await response.text());\n\treturn parseClientInformation(await response.json());\n}\n\nexport async function exchangeAuthorizationCode(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions & { code: string; codeVerifier: string; redirectUrl: string | URL },\n): Promise<OAuthTokens> {\n\treturn tokenRequest(\n\t\tauthorizationServerUrl,\n\t\toptions,\n\t\tnew URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode: options.code,\n\t\t\tcode_verifier: options.codeVerifier,\n\t\t\tredirect_uri: String(options.redirectUrl),\n\t\t}),\n\t);\n}\n\nexport async function refreshAuthorization(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions & { refreshToken: string },\n): Promise<OAuthTokens> {\n\tconst tokens = await tokenRequest(\n\t\tauthorizationServerUrl,\n\t\toptions,\n\t\tnew URLSearchParams({ grant_type: \"refresh_token\", refresh_token: options.refreshToken }),\n\t);\n\treturn { refresh_token: options.refreshToken, ...tokens };\n}\n\nfunction withScope(tokens: OAuthTokens, scope: string | undefined): OAuthTokens {\n\treturn tokens.scope === undefined && scope ? { ...tokens, scope } : tokens;\n}\n\n/**\n * Scopes for a step-up authorization: the challenged scopes plus the ones granted so far, since a\n * challenge may list only the missing scopes and a token with just those would lose access the old\n * one had (SEP-2350). Without challenged scopes, `undefined` lets the flow pick its default.\n */\nexport function stepUpScope(granted: string | undefined, challenged: string | undefined): string | undefined {\n\tif (!challenged) return undefined;\n\tconst scopes = [granted, challenged].flatMap((scope) => scope?.split(/\\s+/).filter(Boolean) ?? []);\n\treturn [...new Set(scopes)].join(\" \");\n}\n\nasync function runFlow(provider: OAuthClientProvider, options: OAuthFlowOptions): Promise<OAuthFlowResult> {\n\tconst metadataUrl = options.authorizationServerMetadataUrl && secureEndpoint(options.authorizationServerMetadataUrl);\n\t// With a configured metadata URL, discovery is not cached, so changing the URL applies at once.\n\tlet cached = metadataUrl ? undefined : await provider.discoveryState?.();\n\tif (options.resourceMetadataUrl && options.resourceMetadataUrl.href !== cached?.resourceMetadataUrl)\n\t\tcached = undefined;\n\tconst discovered = cached?.authorizationServerUrl\n\t\t? {\n\t\t\t\tauthorizationServerUrl: cached.authorizationServerUrl,\n\t\t\t\tauthorizationServerMetadata:\n\t\t\t\t\tcached.authorizationServerMetadata ??\n\t\t\t\t\t(await discoverAuthorizationServerMetadata(cached.authorizationServerUrl, {\n\t\t\t\t\t\tfetch: options.fetch,\n\t\t\t\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t\t\t\t})),\n\t\t\t\tresourceMetadata: cached.resourceMetadata,\n\t\t\t}\n\t\t: await discoverOAuthServerInfo(options.serverUrl, {\n\t\t\t\tresourceMetadataUrl: options.resourceMetadataUrl,\n\t\t\t\tauthorizationServerMetadataUrl: metadataUrl,\n\t\t\t\tfetch: options.fetch,\n\t\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t\t});\n\tif (!metadataUrl) {\n\t\tawait provider.saveDiscoveryState?.({\n\t\t\t...discovered,\n\t\t\t...(options.resourceMetadataUrl || cached?.resourceMetadataUrl\n\t\t\t\t? { resourceMetadataUrl: options.resourceMetadataUrl?.href ?? cached?.resourceMetadataUrl }\n\t\t\t\t: {}),\n\t\t});\n\t}\n\tconst metadata = discovered.authorizationServerMetadata;\n\tconst resource = selectResource(options.serverUrl, discovered.resourceMetadata);\n\t// `||`, not `??`: an empty scope (for example from `scopes_supported: []`) falls through to the next source.\n\tconst scope =\n\t\toptions.scope || discovered.resourceMetadata?.scopes_supported?.join(\" \") || provider.clientMetadata.scope;\n\tlet client = await provider.clientInformation();\n\tif (!client) {\n\t\tif (options.authorizationCode) throw new Error(\"OAuth client information is missing during code exchange\");\n\t\tif (metadata?.client_id_metadata_document_supported && provider.clientMetadataUrl) {\n\t\t\tconst url = new URL(provider.clientMetadataUrl);\n\t\t\tif (url.protocol !== \"https:\" || url.pathname === \"/\") throw new Error(\"Invalid OAuth client metadata URL\");\n\t\t\tclient = { client_id: provider.clientMetadataUrl };\n\t\t\tawait provider.saveClientInformation?.(client);\n\t\t} else {\n\t\t\tif (!provider.saveClientInformation) throw new Error(\"OAuth client information cannot be persisted\");\n\t\t\tclient = await registerClient(discovered.authorizationServerUrl, {\n\t\t\t\tmetadata,\n\t\t\t\tclientMetadata: provider.clientMetadata,\n\t\t\t\tscope,\n\t\t\t\tfetch: options.fetch,\n\t\t\t});\n\t\t\tawait provider.saveClientInformation(client);\n\t\t}\n\t}\n\tconst tokenOptions: TokenRequestOptions = {\n\t\tmetadata,\n\t\tclientInformation: client,\n\t\tresource,\n\t\taddClientAuthentication: provider.addClientAuthentication,\n\t\tfetch: options.fetch,\n\t};\n\tif (options.authorizationCode) {\n\t\t// RFC 9207: never send a code from another authorization server to this one.\n\t\tconst iss = options.iss;\n\t\tif (metadata && (iss !== undefined || metadata.authorization_response_iss_parameter_supported)) {\n\t\t\tif (iss !== metadata.issuer) throw new OAuthIssuerMismatchError(metadata.issuer, iss);\n\t\t}\n\t\tconst tokens = await exchangeAuthorizationCode(discovered.authorizationServerUrl, {\n\t\t\t...tokenOptions,\n\t\t\tcode: options.authorizationCode,\n\t\t\tcodeVerifier: await provider.codeVerifier(),\n\t\t\tredirectUrl: provider.redirectUrl,\n\t\t});\n\t\t// A response without `scope` grants the requested scope (RFC 6749 §5.1). Recorded so a step-up can\n\t\t// keep it. Callers pass the options of the authorization request, so `scope` is what was requested.\n\t\tawait provider.saveTokens(withScope(tokens, scope));\n\t\treturn \"AUTHORIZED\";\n\t}\n\tconst existing = options.skipRefresh ? undefined : await provider.tokens();\n\tif (existing?.refresh_token) {\n\t\ttry {\n\t\t\tconst tokens = await refreshAuthorization(discovered.authorizationServerUrl, {\n\t\t\t\t...tokenOptions,\n\t\t\t\trefreshToken: existing.refresh_token,\n\t\t\t});\n\t\t\t// A refresh without `scope` keeps the scope of the grant (RFC 6749 §6).\n\t\t\tawait provider.saveTokens(withScope(tokens, existing.scope));\n\t\t\treturn \"AUTHORIZED\";\n\t\t} catch (error) {\n\t\t\tif (error instanceof OAuthInsecureEndpointError) throw error;\n\t\t\tif (error instanceof OAuthError && error.code !== \"server_error\") throw error;\n\t\t}\n\t}\n\tconst state = await provider.state?.();\n\tconst authorization = await startAuthorization(discovered.authorizationServerUrl, {\n\t\tmetadata,\n\t\tclientInformation: client,\n\t\tredirectUrl: provider.redirectUrl,\n\t\tscope,\n\t\tstate,\n\t\tresource,\n\t});\n\tawait provider.saveCodeVerifier(authorization.codeVerifier);\n\tawait provider.redirectToAuthorization(authorization.authorizationUrl);\n\treturn \"REDIRECT\";\n}\n\nexport async function authorizeMcp(provider: OAuthClientProvider, options: OAuthFlowOptions): Promise<OAuthFlowResult> {\n\ttry {\n\t\treturn await runFlow(provider, options);\n\t} catch (error) {\n\t\tif (error instanceof OAuthError && [\"invalid_client\", \"unauthorized_client\"].includes(error.code)) {\n\t\t\tawait provider.invalidateCredentials?.(\"all\");\n\t\t\treturn runFlow(provider, options);\n\t\t}\n\t\tif (error instanceof OAuthError && error.code === \"invalid_grant\") {\n\t\t\tawait provider.invalidateCredentials?.(\"tokens\");\n\t\t\treturn runFlow(provider, options);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Auth provider for `StreamableHttpTransport`. After a 401 it refreshes the tokens, or throws\n * `McpOAuthAuthorizationRequiredError` when the user has to authorize (again). Concurrent 401s share\n * one refresh, and a request whose token was already replaced is just retried: with rotating refresh\n * tokens, a second refresh with the old refresh token would fail and discard the new grant.\n */\nexport function adaptOAuthProvider(provider: OAuthClientProvider): AuthProvider {\n\tlet inFlight: Promise<void> | undefined;\n\treturn {\n\t\ttoken: async () => (await provider.tokens())?.access_token,\n\t\tonUnauthorized: async (context: UnauthorizedContext) => {\n\t\t\tconst challenge = parseWwwAuthenticate(context.response.headers.get(\"www-authenticate\"));\n\t\t\tconst insufficientScope = challenge.error === \"insufficient_scope\";\n\t\t\tif (!insufficientScope && !inFlight && context.token !== undefined) {\n\t\t\t\tconst current = (await provider.tokens())?.access_token;\n\t\t\t\tif (current !== undefined && current !== context.token) return;\n\t\t\t}\n\t\t\tinFlight ??= Promise.resolve(insufficientScope ? provider.tokens() : undefined)\n\t\t\t\t.then((granted) =>\n\t\t\t\t\tauthorizeMcp(provider, {\n\t\t\t\t\t\tserverUrl: context.serverUrl,\n\t\t\t\t\t\tresourceMetadataUrl: challenge.resourceMetadataUrl,\n\t\t\t\t\t\tscope: insufficientScope ? stepUpScope(granted?.scope, challenge.scope) : challenge.scope,\n\t\t\t\t\t\tfetch: context.fetch,\n\t\t\t\t\t\tskipRefresh: insufficientScope,\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.then((result) => {\n\t\t\t\t\tif (result === \"REDIRECT\") throw new McpOAuthAuthorizationRequiredError();\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tinFlight = undefined;\n\t\t\t\t});\n\t\t\tawait inFlight;\n\t\t},\n\t};\n}\n"]}
1
+ {"version":3,"file":"flow.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/flow.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Adapted from modelcontextprotocol/typescript-sdk v1.29.0 src/client/auth.ts.\n * Copyright (c) 2024 Anthropic, PBC. Licensed under MIT; see LICENSES/.\n * Modified to remove SDK/Zod dependencies and use WebCrypto for PKCE.\n */\n\nimport type { AuthProvider, McpFetch, UnauthorizedContext } from \"../auth-provider.js\";\nimport { isObject } from \"../protocol/jsonrpc.js\";\nimport {\n\tdiscoverAuthorizationServerMetadata,\n\tdiscoverOAuthServerInfo,\n\tparseWwwAuthenticate,\n\tselectResource,\n} from \"./discovery.js\";\nimport {\n\tMcpOAuthAuthorizationRequiredError,\n\tOAuthError,\n\tOAuthInsecureEndpointError,\n\tOAuthIssuerMismatchError,\n\tOAuthRegistrationError,\n} from \"./errors.js\";\nimport {\n\ttype AuthorizationServerMetadata,\n\ttype OAuthClientInformation,\n\ttype OAuthClientInformationFull,\n\ttype OAuthClientInformationMixed,\n\ttype OAuthClientMetadata,\n\ttype OAuthDiscoveryState,\n\ttype OAuthTokens,\n\tparseClientInformation,\n\tparseOAuthTokens,\n} from \"./types.js\";\n\nexport type AddClientAuthentication = (\n\theaders: Headers,\n\tparams: URLSearchParams,\n\turl: string | URL,\n\tmetadata?: AuthorizationServerMetadata,\n) => void | Promise<void>;\n\n/** A Client ID Metadata Document URL and a redirect URI it lists. */\nexport interface OAuthClientMetadataDocument {\n\turl: string;\n\tredirectUrl: string;\n}\n\nexport interface OAuthClientProvider {\n\treadonly redirectUrl: string | URL;\n\treadonly clientMetadata: OAuthClientMetadata;\n\t/** Called without stored client information. The caller checks server support; the document is not stored. */\n\tclientMetadataDocument?(metadata: AuthorizationServerMetadata | undefined): OAuthClientMetadataDocument | undefined;\n\tstate?(): string | Promise<string>;\n\tclientInformation(): OAuthClientInformationMixed | undefined | Promise<OAuthClientInformationMixed | undefined>;\n\tsaveClientInformation?(information: OAuthClientInformationMixed): void | Promise<void>;\n\ttokens(): OAuthTokens | undefined | Promise<OAuthTokens | undefined>;\n\tsaveTokens(tokens: OAuthTokens): void | Promise<void>;\n\tredirectToAuthorization(url: URL): void | Promise<void>;\n\tsaveCodeVerifier(verifier: string): void | Promise<void>;\n\tcodeVerifier(): string | Promise<string>;\n\taddClientAuthentication?: AddClientAuthentication;\n\tinvalidateCredentials?(kind: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"): void | Promise<void>;\n\tsaveDiscoveryState?(state: OAuthDiscoveryState): void | Promise<void>;\n\tdiscoveryState?(): OAuthDiscoveryState | undefined | Promise<OAuthDiscoveryState | undefined>;\n}\n\nexport interface OAuthFlowOptions {\n\tserverUrl: string | URL;\n\tauthorizationCode?: string;\n\t/** `iss` parameter of the authorization response that delivered `authorizationCode` (RFC 9207). */\n\tiss?: string;\n\tscope?: string;\n\tresourceMetadataUrl?: URL;\n\t/**\n\t * Authorization server metadata document to use instead of discovery, for servers that advertise a\n\t * wrong authorization server or none. It is trusted as configured. Must use https, except on loopback.\n\t */\n\tauthorizationServerMetadataUrl?: URL;\n\tfetch?: McpFetch;\n\tskipIssuerValidation?: boolean;\n\t/**\n\t * Go straight to the authorization redirect instead of refreshing stored tokens, for example when the\n\t * server asks for scopes the current grant lacks (a refresh keeps the old scope).\n\t */\n\tskipRefresh?: boolean;\n}\n\nexport type OAuthFlowResult = \"AUTHORIZED\" | \"REDIRECT\";\ntype ClientAuthMethod = \"client_secret_basic\" | \"client_secret_post\" | \"none\";\n\nexport interface TokenRequestOptions {\n\tmetadata?: AuthorizationServerMetadata;\n\tclientInformation: OAuthClientInformationMixed;\n\tresource?: string;\n\taddClientAuthentication?: AddClientAuthentication;\n\tfetch?: McpFetch;\n}\n\nfunction loopback(hostname: string): boolean {\n\treturn hostname === \"localhost\" || hostname === \"127.0.0.1\" || hostname === \"[::1]\" || hostname === \"::1\";\n}\n\nfunction secureEndpoint(value: string | URL): URL {\n\tconst url = new URL(value);\n\tif (url.protocol !== \"https:\" && !loopback(url.hostname)) throw new OAuthInsecureEndpointError(url.href);\n\treturn url;\n}\n\nfunction selectClientAuthMethod(information: OAuthClientInformationMixed, supported: string[]): ClientAuthMethod {\n\tconst hinted = \"token_endpoint_auth_method\" in information ? information.token_endpoint_auth_method : undefined;\n\tif (\n\t\thinted &&\n\t\t[\"client_secret_basic\", \"client_secret_post\", \"none\"].includes(hinted) &&\n\t\t(supported.length === 0 || supported.includes(hinted))\n\t) {\n\t\treturn hinted as ClientAuthMethod;\n\t}\n\tif (supported.length === 0) return information.client_secret ? \"client_secret_basic\" : \"none\";\n\tif (information.client_secret && supported.includes(\"client_secret_basic\")) return \"client_secret_basic\";\n\tif (information.client_secret && supported.includes(\"client_secret_post\")) return \"client_secret_post\";\n\tif (supported.includes(\"none\")) return \"none\";\n\treturn information.client_secret ? \"client_secret_post\" : \"none\";\n}\n\nfunction applyClientAuthentication(\n\tmethod: ClientAuthMethod,\n\tinformation: OAuthClientInformation,\n\theaders: Headers,\n\tparams: URLSearchParams,\n): void {\n\tif (method === \"client_secret_basic\") {\n\t\tif (!information.client_secret) throw new Error(\"client_secret_basic requires a client secret\");\n\t\theaders.set(\n\t\t\t\"Authorization\",\n\t\t\t`Basic ${Buffer.from(`${information.client_id}:${information.client_secret}`).toString(\"base64\")}`,\n\t\t);\n\t} else {\n\t\tparams.set(\"client_id\", information.client_id);\n\t\tif (method === \"client_secret_post\" && information.client_secret)\n\t\t\tparams.set(\"client_secret\", information.client_secret);\n\t}\n}\n\nasync function pkce(): Promise<{ verifier: string; challenge: string }> {\n\tconst bytes = crypto.getRandomValues(new Uint8Array(32));\n\tconst verifier = Buffer.from(bytes).toString(\"base64url\");\n\tconst digest = await crypto.subtle.digest(\"SHA-256\", new TextEncoder().encode(verifier));\n\treturn { verifier, challenge: Buffer.from(digest).toString(\"base64url\") };\n}\n\nexport async function startAuthorization(\n\tauthorizationServerUrl: string | URL,\n\toptions: {\n\t\tmetadata?: AuthorizationServerMetadata;\n\t\tclientInformation: OAuthClientInformationMixed;\n\t\tredirectUrl: string | URL;\n\t\tscope?: string;\n\t\tstate?: string;\n\t\tresource?: string;\n\t},\n): Promise<{ authorizationUrl: URL; codeVerifier: string }> {\n\tconst metadata = options.metadata;\n\tif (metadata && !metadata.response_types_supported.includes(\"code\")) {\n\t\tthrow new Error(\"Authorization server does not support authorization codes\");\n\t}\n\tif (metadata?.code_challenge_methods_supported && !metadata.code_challenge_methods_supported.includes(\"S256\")) {\n\t\tthrow new Error(\"Authorization server does not support PKCE S256\");\n\t}\n\tconst url = new URL(metadata?.authorization_endpoint ?? new URL(\"/authorize\", authorizationServerUrl));\n\tconst { verifier, challenge } = await pkce();\n\turl.searchParams.set(\"response_type\", \"code\");\n\turl.searchParams.set(\"client_id\", options.clientInformation.client_id);\n\turl.searchParams.set(\"code_challenge\", challenge);\n\turl.searchParams.set(\"code_challenge_method\", \"S256\");\n\turl.searchParams.set(\"redirect_uri\", String(options.redirectUrl));\n\tif (options.state) url.searchParams.set(\"state\", options.state);\n\tif (options.scope) url.searchParams.set(\"scope\", options.scope);\n\tif (options.scope?.split(/\\s+/).includes(\"offline_access\")) url.searchParams.set(\"prompt\", \"consent\");\n\tif (options.resource) url.searchParams.set(\"resource\", options.resource);\n\treturn { authorizationUrl: url, codeVerifier: verifier };\n}\n\nasync function tokenRequest(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions,\n\tparams: URLSearchParams,\n): Promise<OAuthTokens> {\n\tconst url = secureEndpoint(options.metadata?.token_endpoint ?? new URL(\"/token\", authorizationServerUrl));\n\tconst headers = new Headers({ Accept: \"application/json\", \"content-type\": \"application/x-www-form-urlencoded\" });\n\tif (options.resource) params.set(\"resource\", options.resource);\n\tif (options.addClientAuthentication) {\n\t\tawait options.addClientAuthentication(headers, params, url, options.metadata);\n\t} else {\n\t\tapplyClientAuthentication(\n\t\t\tselectClientAuthMethod(\n\t\t\t\toptions.clientInformation,\n\t\t\t\toptions.metadata?.token_endpoint_auth_methods_supported ?? [],\n\t\t\t),\n\t\t\toptions.clientInformation,\n\t\t\theaders,\n\t\t\tparams,\n\t\t);\n\t}\n\tconst response = await (options.fetch ?? globalThis.fetch)(url, { method: \"POST\", headers, body: params });\n\tconst text = await response.text();\n\tlet value: unknown;\n\ttry {\n\t\tvalue = JSON.parse(text);\n\t} catch {}\n\t// Servers may report OAuth errors with any status, so check the body before the status.\n\tif (isObject(value) && typeof value.error === \"string\") {\n\t\tthrow new OAuthError(\n\t\t\tvalue.error,\n\t\t\ttypeof value.error_description === \"string\" ? value.error_description : value.error,\n\t\t\ttypeof value.error_uri === \"string\" ? value.error_uri : undefined,\n\t\t);\n\t}\n\tif (!response.ok) throw new OAuthError(\"server_error\", `HTTP ${response.status}: ${text}`);\n\treturn parseOAuthTokens(value);\n}\n\nexport async function registerClient(\n\tauthorizationServerUrl: string | URL,\n\toptions: {\n\t\tmetadata?: AuthorizationServerMetadata;\n\t\tclientMetadata: OAuthClientMetadata;\n\t\tscope?: string;\n\t\tfetch?: McpFetch;\n\t},\n): Promise<OAuthClientInformationFull> {\n\tconst endpoint = options.metadata?.registration_endpoint;\n\tif (options.metadata && !endpoint)\n\t\tthrow new Error(\"Authorization server does not support dynamic client registration\");\n\tconst response = await (options.fetch ?? globalThis.fetch)(\n\t\tnew URL(endpoint ?? new URL(\"/register\", authorizationServerUrl)),\n\t\t{\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { Accept: \"application/json\", \"content-type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ ...options.clientMetadata, ...(options.scope ? { scope: options.scope } : {}) }),\n\t\t},\n\t);\n\tif (!response.ok) throw new OAuthRegistrationError(response.status, await response.text());\n\treturn parseClientInformation(await response.json());\n}\n\nexport async function exchangeAuthorizationCode(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions & { code: string; codeVerifier: string; redirectUrl: string | URL },\n): Promise<OAuthTokens> {\n\treturn tokenRequest(\n\t\tauthorizationServerUrl,\n\t\toptions,\n\t\tnew URLSearchParams({\n\t\t\tgrant_type: \"authorization_code\",\n\t\t\tcode: options.code,\n\t\t\tcode_verifier: options.codeVerifier,\n\t\t\tredirect_uri: String(options.redirectUrl),\n\t\t}),\n\t);\n}\n\nexport async function refreshAuthorization(\n\tauthorizationServerUrl: string | URL,\n\toptions: TokenRequestOptions & { refreshToken: string },\n): Promise<OAuthTokens> {\n\tconst tokens = await tokenRequest(\n\t\tauthorizationServerUrl,\n\t\toptions,\n\t\tnew URLSearchParams({ grant_type: \"refresh_token\", refresh_token: options.refreshToken }),\n\t);\n\treturn { refresh_token: options.refreshToken, ...tokens };\n}\n\nfunction withScope(tokens: OAuthTokens, scope: string | undefined): OAuthTokens {\n\treturn tokens.scope === undefined && scope ? { ...tokens, scope } : tokens;\n}\n\n/**\n * Scopes for a step-up authorization: the challenged scopes plus the ones granted so far, since a\n * challenge may list only the missing scopes and a token with just those would lose access the old\n * one had (SEP-2350). Without challenged scopes, `undefined` lets the flow pick its default.\n */\nexport function stepUpScope(granted: string | undefined, challenged: string | undefined): string | undefined {\n\tif (!challenged) return undefined;\n\tconst scopes = [granted, challenged].flatMap((scope) => scope?.split(/\\s+/).filter(Boolean) ?? []);\n\treturn [...new Set(scopes)].join(\" \");\n}\n\nasync function runFlow(provider: OAuthClientProvider, options: OAuthFlowOptions): Promise<OAuthFlowResult> {\n\tconst metadataUrl = options.authorizationServerMetadataUrl && secureEndpoint(options.authorizationServerMetadataUrl);\n\t// With a configured metadata URL, discovery is not cached, so changing the URL applies at once.\n\tlet cached = metadataUrl ? undefined : await provider.discoveryState?.();\n\tif (options.resourceMetadataUrl && options.resourceMetadataUrl.href !== cached?.resourceMetadataUrl)\n\t\tcached = undefined;\n\tconst discovered = cached?.authorizationServerUrl\n\t\t? {\n\t\t\t\tauthorizationServerUrl: cached.authorizationServerUrl,\n\t\t\t\tauthorizationServerMetadata:\n\t\t\t\t\tcached.authorizationServerMetadata ??\n\t\t\t\t\t(await discoverAuthorizationServerMetadata(cached.authorizationServerUrl, {\n\t\t\t\t\t\tfetch: options.fetch,\n\t\t\t\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t\t\t\t})),\n\t\t\t\tresourceMetadata: cached.resourceMetadata,\n\t\t\t}\n\t\t: await discoverOAuthServerInfo(options.serverUrl, {\n\t\t\t\tresourceMetadataUrl: options.resourceMetadataUrl,\n\t\t\t\tauthorizationServerMetadataUrl: metadataUrl,\n\t\t\t\tfetch: options.fetch,\n\t\t\t\tskipIssuerValidation: options.skipIssuerValidation,\n\t\t\t});\n\tif (!metadataUrl) {\n\t\tawait provider.saveDiscoveryState?.({\n\t\t\t...discovered,\n\t\t\t...(options.resourceMetadataUrl || cached?.resourceMetadataUrl\n\t\t\t\t? { resourceMetadataUrl: options.resourceMetadataUrl?.href ?? cached?.resourceMetadataUrl }\n\t\t\t\t: {}),\n\t\t});\n\t}\n\tconst metadata = discovered.authorizationServerMetadata;\n\tconst resource = selectResource(options.serverUrl, discovered.resourceMetadata);\n\t// `||`, not `??`: an empty scope (for example from `scopes_supported: []`) falls through to the next source.\n\tconst scope =\n\t\toptions.scope || discovered.resourceMetadata?.scopes_supported?.join(\" \") || provider.clientMetadata.scope;\n\tconst stored = await provider.clientInformation();\n\tconst clientDocument = stored ? undefined : provider.clientMetadataDocument?.(metadata);\n\tif (clientDocument) {\n\t\tconst url = new URL(clientDocument.url);\n\t\tif (url.protocol !== \"https:\" || url.pathname === \"/\") throw new Error(\"Invalid OAuth client metadata URL\");\n\t}\n\tlet client = stored ?? (clientDocument && { client_id: clientDocument.url });\n\tif (!client) {\n\t\tif (options.authorizationCode) throw new Error(\"OAuth client information is missing during code exchange\");\n\t\tif (!provider.saveClientInformation) throw new Error(\"OAuth client information cannot be persisted\");\n\t\tclient = await registerClient(discovered.authorizationServerUrl, {\n\t\t\tmetadata,\n\t\t\tclientMetadata: provider.clientMetadata,\n\t\t\tscope,\n\t\t\tfetch: options.fetch,\n\t\t});\n\t\tawait provider.saveClientInformation(client);\n\t}\n\tconst redirectUrl = clientDocument?.redirectUrl ?? provider.redirectUrl;\n\tconst tokenOptions: TokenRequestOptions = {\n\t\tmetadata,\n\t\tclientInformation: client,\n\t\tresource,\n\t\taddClientAuthentication: provider.addClientAuthentication,\n\t\tfetch: options.fetch,\n\t};\n\tif (options.authorizationCode) {\n\t\t// RFC 9207: never send a code from another authorization server to this one.\n\t\tconst iss = options.iss;\n\t\tif (metadata && (iss !== undefined || metadata.authorization_response_iss_parameter_supported)) {\n\t\t\tif (iss !== metadata.issuer) throw new OAuthIssuerMismatchError(metadata.issuer, iss);\n\t\t}\n\t\tconst tokens = await exchangeAuthorizationCode(discovered.authorizationServerUrl, {\n\t\t\t...tokenOptions,\n\t\t\tcode: options.authorizationCode,\n\t\t\tcodeVerifier: await provider.codeVerifier(),\n\t\t\tredirectUrl,\n\t\t});\n\t\t// A response without `scope` grants the requested scope (RFC 6749 §5.1). Recorded so a step-up can\n\t\t// keep it. Callers pass the options of the authorization request, so `scope` is what was requested.\n\t\tawait provider.saveTokens(withScope(tokens, scope));\n\t\treturn \"AUTHORIZED\";\n\t}\n\tconst existing = options.skipRefresh ? undefined : await provider.tokens();\n\tif (existing?.refresh_token) {\n\t\ttry {\n\t\t\tconst tokens = await refreshAuthorization(discovered.authorizationServerUrl, {\n\t\t\t\t...tokenOptions,\n\t\t\t\trefreshToken: existing.refresh_token,\n\t\t\t});\n\t\t\t// A refresh without `scope` keeps the scope of the grant (RFC 6749 §6).\n\t\t\tawait provider.saveTokens(withScope(tokens, existing.scope));\n\t\t\treturn \"AUTHORIZED\";\n\t\t} catch (error) {\n\t\t\tif (error instanceof OAuthInsecureEndpointError) throw error;\n\t\t\tif (error instanceof OAuthError && error.code !== \"server_error\") throw error;\n\t\t}\n\t}\n\tconst state = await provider.state?.();\n\tconst authorization = await startAuthorization(discovered.authorizationServerUrl, {\n\t\tmetadata,\n\t\tclientInformation: client,\n\t\tredirectUrl,\n\t\tscope,\n\t\tstate,\n\t\tresource,\n\t});\n\tawait provider.saveCodeVerifier(authorization.codeVerifier);\n\tawait provider.redirectToAuthorization(authorization.authorizationUrl);\n\treturn \"REDIRECT\";\n}\n\nexport async function authorizeMcp(provider: OAuthClientProvider, options: OAuthFlowOptions): Promise<OAuthFlowResult> {\n\ttry {\n\t\treturn await runFlow(provider, options);\n\t} catch (error) {\n\t\tif (error instanceof OAuthError && [\"invalid_client\", \"unauthorized_client\"].includes(error.code)) {\n\t\t\tawait provider.invalidateCredentials?.(\"all\");\n\t\t\treturn runFlow(provider, options);\n\t\t}\n\t\tif (error instanceof OAuthError && error.code === \"invalid_grant\") {\n\t\t\tawait provider.invalidateCredentials?.(\"tokens\");\n\t\t\treturn runFlow(provider, options);\n\t\t}\n\t\tthrow error;\n\t}\n}\n\n/**\n * Auth provider for `StreamableHttpTransport`. After a 401 it refreshes the tokens, or throws\n * `McpOAuthAuthorizationRequiredError` when the user has to authorize (again). Concurrent 401s share\n * one refresh, and a request whose token was already replaced is just retried: with rotating refresh\n * tokens, a second refresh with the old refresh token would fail and discard the new grant.\n */\nexport function adaptOAuthProvider(provider: OAuthClientProvider): AuthProvider {\n\tlet inFlight: Promise<void> | undefined;\n\treturn {\n\t\ttoken: async () => (await provider.tokens())?.access_token,\n\t\tonUnauthorized: async (context: UnauthorizedContext) => {\n\t\t\tconst challenge = parseWwwAuthenticate(context.response.headers.get(\"www-authenticate\"));\n\t\t\tconst insufficientScope = challenge.error === \"insufficient_scope\";\n\t\t\tif (!insufficientScope && !inFlight && context.token !== undefined) {\n\t\t\t\tconst current = (await provider.tokens())?.access_token;\n\t\t\t\tif (current !== undefined && current !== context.token) return;\n\t\t\t}\n\t\t\tinFlight ??= Promise.resolve(insufficientScope ? provider.tokens() : undefined)\n\t\t\t\t.then((granted) =>\n\t\t\t\t\tauthorizeMcp(provider, {\n\t\t\t\t\t\tserverUrl: context.serverUrl,\n\t\t\t\t\t\tresourceMetadataUrl: challenge.resourceMetadataUrl,\n\t\t\t\t\t\tscope: insufficientScope ? stepUpScope(granted?.scope, challenge.scope) : challenge.scope,\n\t\t\t\t\t\tfetch: context.fetch,\n\t\t\t\t\t\tskipRefresh: insufficientScope,\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\t.then((result) => {\n\t\t\t\t\tif (result === \"REDIRECT\") throw new McpOAuthAuthorizationRequiredError();\n\t\t\t\t})\n\t\t\t\t.finally(() => {\n\t\t\t\t\tinFlight = undefined;\n\t\t\t\t});\n\t\t\tawait inFlight;\n\t\t},\n\t};\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  export { type OAuthCallback, type OAuthCallbackPage, OAuthCallbackServer, type OAuthCallbackServerOptions, } from "./callback.js";
2
2
  export { buildAuthorizationServerDiscoveryUrls, discoverAuthorizationServerMetadata, discoverOAuthServerInfo, discoverProtectedResourceMetadata, parseWwwAuthenticate, resourceUrlFromServerUrl, selectResource, } from "./discovery.js";
3
3
  export { McpOAuthAuthorizationRequiredError, OAuthError, OAuthInsecureEndpointError, OAuthIssuerMismatchError, OAuthRegistrationError, } from "./errors.js";
4
- export { type AddClientAuthentication, adaptOAuthProvider, authorizeMcp, exchangeAuthorizationCode, type OAuthClientProvider, type OAuthFlowOptions, type OAuthFlowResult, refreshAuthorization, registerClient, startAuthorization, stepUpScope, type TokenRequestOptions, } from "./flow.js";
4
+ export { type AddClientAuthentication, adaptOAuthProvider, authorizeMcp, exchangeAuthorizationCode, type OAuthClientMetadataDocument, type OAuthClientProvider, type OAuthFlowOptions, type OAuthFlowResult, refreshAuthorization, registerClient, startAuthorization, stepUpScope, type TokenRequestOptions, } from "./flow.js";
5
5
  export { McpOAuthProvider, type McpOAuthProviderOptions, type McpOAuthState, type McpOAuthStateStore, MemoryOAuthStateStore, } from "./provider.js";
6
6
  export type { AuthorizationServerMetadata, OAuthChallenge, OAuthClientInformation, OAuthClientInformationFull, OAuthClientInformationMixed, OAuthClientMetadata, OAuthDiscoveryState, OAuthProtectedResourceMetadata, OAuthServerInfo, OAuthTokens, } from "./types.js";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,mBAAmB,EACnB,KAAK,0BAA0B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,qCAAqC,EACrC,mCAAmC,EACnC,uBAAuB,EACvB,iCAAiC,EACjC,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,kCAAkC,EAClC,UAAU,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,KAAK,uBAAuB,EAC5B,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EACzB,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,KAAK,mBAAmB,GACxB,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,qBAAqB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EACX,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,8BAA8B,EAC9B,eAAe,EACf,WAAW,GACX,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,mBAAmB,EACnB,KAAK,0BAA0B,GAC/B,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,qCAAqC,EACrC,mCAAmC,EACnC,uBAAuB,EACvB,iCAAiC,EACjC,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,kCAAkC,EAClC,UAAU,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EACN,KAAK,uBAAuB,EAC5B,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EACzB,KAAK,2BAA2B,EAChC,KAAK,mBAAmB,EACxB,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,WAAW,EACX,KAAK,mBAAmB,GACxB,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAChB,KAAK,uBAAuB,EAC5B,KAAK,aAAa,EAClB,KAAK,kBAAkB,EACvB,qBAAqB,GACrB,MAAM,eAAe,CAAC;AACvB,YAAY,EACX,2BAA2B,EAC3B,cAAc,EACd,sBAAsB,EACtB,0BAA0B,EAC1B,2BAA2B,EAC3B,mBAAmB,EACnB,mBAAmB,EACnB,8BAA8B,EAC9B,eAAe,EACf,WAAW,GACX,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,mBAAmB,GAEnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,qCAAqC,EACrC,mCAAmC,EACnC,uBAAuB,EACvB,iCAAiC,EACjC,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,kCAAkC,EAClC,UAAU,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEN,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EAIzB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,WAAW,GAEX,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAIhB,qBAAqB,GACrB,MAAM,eAAe,CAAC","sourcesContent":["export {\n\ttype OAuthCallback,\n\ttype OAuthCallbackPage,\n\tOAuthCallbackServer,\n\ttype OAuthCallbackServerOptions,\n} from \"./callback.js\";\nexport {\n\tbuildAuthorizationServerDiscoveryUrls,\n\tdiscoverAuthorizationServerMetadata,\n\tdiscoverOAuthServerInfo,\n\tdiscoverProtectedResourceMetadata,\n\tparseWwwAuthenticate,\n\tresourceUrlFromServerUrl,\n\tselectResource,\n} from \"./discovery.js\";\nexport {\n\tMcpOAuthAuthorizationRequiredError,\n\tOAuthError,\n\tOAuthInsecureEndpointError,\n\tOAuthIssuerMismatchError,\n\tOAuthRegistrationError,\n} from \"./errors.js\";\nexport {\n\ttype AddClientAuthentication,\n\tadaptOAuthProvider,\n\tauthorizeMcp,\n\texchangeAuthorizationCode,\n\ttype OAuthClientProvider,\n\ttype OAuthFlowOptions,\n\ttype OAuthFlowResult,\n\trefreshAuthorization,\n\tregisterClient,\n\tstartAuthorization,\n\tstepUpScope,\n\ttype TokenRequestOptions,\n} from \"./flow.js\";\nexport {\n\tMcpOAuthProvider,\n\ttype McpOAuthProviderOptions,\n\ttype McpOAuthState,\n\ttype McpOAuthStateStore,\n\tMemoryOAuthStateStore,\n} from \"./provider.js\";\nexport type {\n\tAuthorizationServerMetadata,\n\tOAuthChallenge,\n\tOAuthClientInformation,\n\tOAuthClientInformationFull,\n\tOAuthClientInformationMixed,\n\tOAuthClientMetadata,\n\tOAuthDiscoveryState,\n\tOAuthProtectedResourceMetadata,\n\tOAuthServerInfo,\n\tOAuthTokens,\n} from \"./types.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAGN,mBAAmB,GAEnB,MAAM,eAAe,CAAC;AACvB,OAAO,EACN,qCAAqC,EACrC,mCAAmC,EACnC,uBAAuB,EACvB,iCAAiC,EACjC,oBAAoB,EACpB,wBAAwB,EACxB,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACN,kCAAkC,EAClC,UAAU,EACV,0BAA0B,EAC1B,wBAAwB,EACxB,sBAAsB,GACtB,MAAM,aAAa,CAAC;AACrB,OAAO,EAEN,kBAAkB,EAClB,YAAY,EACZ,yBAAyB,EAKzB,oBAAoB,EACpB,cAAc,EACd,kBAAkB,EAClB,WAAW,GAEX,MAAM,WAAW,CAAC;AACnB,OAAO,EACN,gBAAgB,EAIhB,qBAAqB,GACrB,MAAM,eAAe,CAAC","sourcesContent":["export {\n\ttype OAuthCallback,\n\ttype OAuthCallbackPage,\n\tOAuthCallbackServer,\n\ttype OAuthCallbackServerOptions,\n} from \"./callback.js\";\nexport {\n\tbuildAuthorizationServerDiscoveryUrls,\n\tdiscoverAuthorizationServerMetadata,\n\tdiscoverOAuthServerInfo,\n\tdiscoverProtectedResourceMetadata,\n\tparseWwwAuthenticate,\n\tresourceUrlFromServerUrl,\n\tselectResource,\n} from \"./discovery.js\";\nexport {\n\tMcpOAuthAuthorizationRequiredError,\n\tOAuthError,\n\tOAuthInsecureEndpointError,\n\tOAuthIssuerMismatchError,\n\tOAuthRegistrationError,\n} from \"./errors.js\";\nexport {\n\ttype AddClientAuthentication,\n\tadaptOAuthProvider,\n\tauthorizeMcp,\n\texchangeAuthorizationCode,\n\ttype OAuthClientMetadataDocument,\n\ttype OAuthClientProvider,\n\ttype OAuthFlowOptions,\n\ttype OAuthFlowResult,\n\trefreshAuthorization,\n\tregisterClient,\n\tstartAuthorization,\n\tstepUpScope,\n\ttype TokenRequestOptions,\n} from \"./flow.js\";\nexport {\n\tMcpOAuthProvider,\n\ttype McpOAuthProviderOptions,\n\ttype McpOAuthState,\n\ttype McpOAuthStateStore,\n\tMemoryOAuthStateStore,\n} from \"./provider.js\";\nexport type {\n\tAuthorizationServerMetadata,\n\tOAuthChallenge,\n\tOAuthClientInformation,\n\tOAuthClientInformationFull,\n\tOAuthClientInformationMixed,\n\tOAuthClientMetadata,\n\tOAuthDiscoveryState,\n\tOAuthProtectedResourceMetadata,\n\tOAuthServerInfo,\n\tOAuthTokens,\n} from \"./types.js\";\n"]}
@@ -1,5 +1,5 @@
1
- import type { OAuthClientProvider } from "./flow.js";
2
- import type { OAuthClientInformationMixed, OAuthClientMetadata, OAuthDiscoveryState, OAuthTokens } from "./types.js";
1
+ import type { OAuthClientMetadataDocument, OAuthClientProvider } from "./flow.js";
2
+ import type { AuthorizationServerMetadata, OAuthClientInformationMixed, OAuthClientMetadata, OAuthDiscoveryState, OAuthTokens } from "./types.js";
3
3
  export interface McpOAuthState {
4
4
  serverUrl: string;
5
5
  clientInformation?: OAuthClientInformationMixed;
@@ -20,6 +20,8 @@ export interface McpOAuthProviderOptions {
20
20
  clientMetadata: Omit<OAuthClientMetadata, "redirect_uris"> & {
21
21
  redirect_uris?: string[];
22
22
  };
23
+ /** See `OAuthClientProvider.clientMetadataDocument`. */
24
+ clientMetadataDocument?: (metadata: AuthorizationServerMetadata | undefined) => OAuthClientMetadataDocument | undefined;
23
25
  clientId?: string;
24
26
  clientSecret?: string;
25
27
  store?: McpOAuthStateStore;
@@ -34,6 +36,7 @@ export declare class MemoryOAuthStateStore implements McpOAuthStateStore {
34
36
  export declare class McpOAuthProvider implements OAuthClientProvider {
35
37
  readonly redirectUrl: string;
36
38
  readonly clientMetadata: OAuthClientMetadata;
39
+ readonly clientMetadataDocument?: (metadata: AuthorizationServerMetadata | undefined) => OAuthClientMetadataDocument | undefined;
37
40
  private serverUrl;
38
41
  private configuredClient;
39
42
  private store;
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,WAAW,CAAC;AACrD,OAAO,KAAK,EAAE,2BAA2B,EAAE,mBAAmB,EAAE,mBAAmB,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAErH,MAAM,WAAW,aAAa;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,iBAAiB,CAAC,EAAE,2BAA2B,CAAC;IAChD,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,kHAAkH;IAClH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,mBAAmB,CAAC;CAChC;AAED,MAAM,WAAW,kBAAkB;IAClC,IAAI,IAAI,aAAa,GAAG,SAAS,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IACvE,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,uBAAuB;IACvC,SAAS,EAAE,MAAM,GAAG,GAAG,CAAC;IACxB,WAAW,EAAE,MAAM,GAAG,GAAG,CAAC;IAC1B,cAAc,EAAE,IAAI,CAAC,mBAAmB,EAAE,eAAe,CAAC,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC1F,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,kBAAkB,CAAC;IAC3B,UAAU,CAAC,GAAG,EAAE,GAAG,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC3C;AAED,qBAAa,qBAAsB,YAAW,kBAAkB;IAC/D,OAAO,CAAC,KAAK,CAA4B;IAEzC,IAAI,IAAI,aAAa,GAAG,SAAS,CAEhC;IAED,IAAI,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAE/B;CACD;AAED,6GAA6G;AAC7G,qBAAa,gBAAiB,YAAW,mBAAmB;IAC3D,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,cAAc,EAAE,mBAAmB,CAAC;IAC7C,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,gBAAgB,CAA0C;IAClE,OAAO,CAAC,KAAK,CAAqB;IAClC,OAAO,CAAC,UAAU,CAAqC;IACvD,OAAO,CAAC,MAAM,CAAoC;IAElD,YAAY,OAAO,EAAE,uBAAuB,EAgB3C;IAEK,KAAK,IAAI,OAAO,CAAC,MAAM,CAAC,CAM7B;IAEK,iBAAiB,IAAI,OAAO,CAAC,2BAA2B,GAAG,SAAS,CAAC,CAE1E;IAEK,qBAAqB,CAAC,WAAW,EAAE,2BAA2B,GAAG,OAAO,CAAC,IAAI,CAAC,CAGnF;IAEK,MAAM,IAAI,OAAO,CAAC,WAAW,GAAG,SAAS,CAAC,CAE/C;IAEK,UAAU,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAQnD;IAEK,uBAAuB,CAAC,GAAG,EAAE,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAErD;IAEK,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtD;IAEK,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAIpC;IAEK,qBAAqB,CAAC,IAAI,EAAE,KAAK,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,GAAG,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAavG;IAEK,kBAAkB,CAAC,SAAS,EAAE,mBAAmB,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtE;IAEK,cAAc,IAAI,OAAO,CAAC,mBAAmB,GAAG,SAAS,CAAC,CAE/D;YAEa,IAAI;YAKJ,MAAM;IAOpB,+FAA+F;IAC/F,OAAO,CAAC,GAAG;CAGX"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/provider.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,7 @@ export class MemoryOAuthStateStore {
11
11
  export class McpOAuthProvider {
12
12
  redirectUrl;
13
13
  clientMetadata;
14
+ clientMetadataDocument;
14
15
  serverUrl;
15
16
  configuredClient;
16
17
  store;
@@ -26,6 +27,7 @@ export class McpOAuthProvider {
26
27
  response_types: options.clientMetadata.response_types ?? ["code"],
27
28
  token_endpoint_auth_method: options.clientMetadata.token_endpoint_auth_method ?? (options.clientSecret ? "client_secret_post" : "none"),
28
29
  };
30
+ this.clientMetadataDocument = options.clientMetadataDocument;
29
31
  this.configuredClient = options.clientId
30
32
  ? { client_id: options.clientId, ...(options.clientSecret ? { client_secret: options.clientSecret } : {}) }
31
33
  : undefined;
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/provider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OAuthClientProvider } from \"./flow.js\";\nimport type { OAuthClientInformationMixed, OAuthClientMetadata, OAuthDiscoveryState, OAuthTokens } from \"./types.js\";\n\nexport interface McpOAuthState {\n\tserverUrl: string;\n\tclientInformation?: OAuthClientInformationMixed;\n\ttokens?: OAuthTokens;\n\t/** When the access token expires, in milliseconds since the epoch, from `expires_in` at the time it was saved. */\n\ttokensExpireAt?: number;\n\tcodeVerifier?: string;\n\toauthState?: string;\n\tdiscovery?: OAuthDiscoveryState;\n}\n\nexport interface McpOAuthStateStore {\n\tload(): McpOAuthState | undefined | Promise<McpOAuthState | undefined>;\n\tsave(state: McpOAuthState): void | Promise<void>;\n}\n\nexport interface McpOAuthProviderOptions {\n\tserverUrl: string | URL;\n\tredirectUrl: string | URL;\n\tclientMetadata: Omit<OAuthClientMetadata, \"redirect_uris\"> & { redirect_uris?: string[] };\n\tclientId?: string;\n\tclientSecret?: string;\n\tstore?: McpOAuthStateStore;\n\tonRedirect(url: URL): void | Promise<void>;\n}\n\nexport class MemoryOAuthStateStore implements McpOAuthStateStore {\n\tprivate value: McpOAuthState | undefined;\n\n\tload(): McpOAuthState | undefined {\n\t\treturn this.value === undefined ? undefined : structuredClone(this.value);\n\t}\n\n\tsave(state: McpOAuthState): void {\n\t\tthis.value = structuredClone(state);\n\t}\n}\n\n/** Default stateful provider for one exact MCP server URL. Applications inject durable storage if needed. */\nexport class McpOAuthProvider implements OAuthClientProvider {\n\treadonly redirectUrl: string;\n\treadonly clientMetadata: OAuthClientMetadata;\n\tprivate serverUrl: string;\n\tprivate configuredClient: OAuthClientInformationMixed | undefined;\n\tprivate store: McpOAuthStateStore;\n\tprivate onRedirect: (url: URL) => void | Promise<void>;\n\tprivate writes: Promise<void> = Promise.resolve();\n\n\tconstructor(options: McpOAuthProviderOptions) {\n\t\tthis.serverUrl = String(new URL(options.serverUrl));\n\t\tthis.redirectUrl = String(options.redirectUrl);\n\t\tthis.clientMetadata = {\n\t\t\t...options.clientMetadata,\n\t\t\tredirect_uris: options.clientMetadata.redirect_uris ?? [this.redirectUrl],\n\t\t\tgrant_types: options.clientMetadata.grant_types ?? [\"authorization_code\", \"refresh_token\"],\n\t\t\tresponse_types: options.clientMetadata.response_types ?? [\"code\"],\n\t\t\ttoken_endpoint_auth_method:\n\t\t\t\toptions.clientMetadata.token_endpoint_auth_method ?? (options.clientSecret ? \"client_secret_post\" : \"none\"),\n\t\t};\n\t\tthis.configuredClient = options.clientId\n\t\t\t? { client_id: options.clientId, ...(options.clientSecret ? { client_secret: options.clientSecret } : {}) }\n\t\t\t: undefined;\n\t\tthis.store = options.store ?? new MemoryOAuthStateStore();\n\t\tthis.onRedirect = options.onRedirect;\n\t}\n\n\tasync state(): Promise<string> {\n\t\tconst existing = (await this.load()).oauthState;\n\t\tif (existing) return existing;\n\t\tconst state = Buffer.from(crypto.getRandomValues(new Uint8Array(32))).toString(\"hex\");\n\t\tawait this.update((value) => ({ ...value, oauthState: state }));\n\t\treturn state;\n\t}\n\n\tasync clientInformation(): Promise<OAuthClientInformationMixed | undefined> {\n\t\treturn this.configuredClient ?? (await this.load()).clientInformation;\n\t}\n\n\tasync saveClientInformation(information: OAuthClientInformationMixed): Promise<void> {\n\t\tif (this.configuredClient) return;\n\t\tawait this.update((value) => ({ ...value, clientInformation: information }));\n\t}\n\n\tasync tokens(): Promise<OAuthTokens | undefined> {\n\t\treturn (await this.load()).tokens;\n\t}\n\n\tasync saveTokens(tokens: OAuthTokens): Promise<void> {\n\t\tconst expiresAt = tokens.expires_in === undefined ? undefined : Date.now() + tokens.expires_in * 1000;\n\t\tawait this.update((value) => {\n\t\t\tconst next: McpOAuthState = { ...value, tokens };\n\t\t\tif (expiresAt === undefined) delete next.tokensExpireAt;\n\t\t\telse next.tokensExpireAt = expiresAt;\n\t\t\treturn next;\n\t\t});\n\t}\n\n\tasync redirectToAuthorization(url: URL): Promise<void> {\n\t\tawait this.onRedirect(url);\n\t}\n\n\tasync saveCodeVerifier(verifier: string): Promise<void> {\n\t\tawait this.update((value) => ({ ...value, codeVerifier: verifier }));\n\t}\n\n\tasync codeVerifier(): Promise<string> {\n\t\tconst verifier = (await this.load()).codeVerifier;\n\t\tif (!verifier) throw new Error(\"No OAuth PKCE code verifier is stored\");\n\t\treturn verifier;\n\t}\n\n\tasync invalidateCredentials(kind: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"): Promise<void> {\n\t\tawait this.update((value) => {\n\t\t\tconst next = { ...value };\n\t\t\tif (kind === \"all\" || kind === \"client\") delete next.clientInformation;\n\t\t\tif (kind === \"all\" || kind === \"tokens\") {\n\t\t\t\tdelete next.tokens;\n\t\t\t\tdelete next.tokensExpireAt;\n\t\t\t}\n\t\t\tif (kind === \"all\" || kind === \"verifier\") delete next.codeVerifier;\n\t\t\tif (kind === \"all\" || kind === \"discovery\") delete next.discovery;\n\t\t\tif (kind === \"all\") delete next.oauthState;\n\t\t\treturn next;\n\t\t});\n\t}\n\n\tasync saveDiscoveryState(discovery: OAuthDiscoveryState): Promise<void> {\n\t\tawait this.update((value) => ({ ...value, discovery }));\n\t}\n\n\tasync discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n\t\treturn (await this.load()).discovery;\n\t}\n\n\tprivate async load(): Promise<McpOAuthState> {\n\t\tawait this.writes;\n\t\treturn this.own(await this.store.load());\n\t}\n\n\tprivate async update(update: (state: McpOAuthState) => McpOAuthState): Promise<void> {\n\t\tthis.writes = this.writes.then(async () => {\n\t\t\tawait this.store.save(update(this.own(await this.store.load())));\n\t\t});\n\t\tawait this.writes;\n\t}\n\n\t/** Stored state for another server URL is ignored so credentials never leak across servers. */\n\tprivate own(state: McpOAuthState | undefined): McpOAuthState {\n\t\treturn state?.serverUrl === this.serverUrl ? state : { serverUrl: this.serverUrl };\n\t}\n}\n"]}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../../../../src/extensions/mcp/client/oauth/provider.ts"],"names":[],"mappings":"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","sourcesContent":["import type { OAuthClientMetadataDocument, OAuthClientProvider } from \"./flow.js\";\nimport type {\n\tAuthorizationServerMetadata,\n\tOAuthClientInformationMixed,\n\tOAuthClientMetadata,\n\tOAuthDiscoveryState,\n\tOAuthTokens,\n} from \"./types.js\";\n\nexport interface McpOAuthState {\n\tserverUrl: string;\n\tclientInformation?: OAuthClientInformationMixed;\n\ttokens?: OAuthTokens;\n\t/** When the access token expires, in milliseconds since the epoch, from `expires_in` at the time it was saved. */\n\ttokensExpireAt?: number;\n\tcodeVerifier?: string;\n\toauthState?: string;\n\tdiscovery?: OAuthDiscoveryState;\n}\n\nexport interface McpOAuthStateStore {\n\tload(): McpOAuthState | undefined | Promise<McpOAuthState | undefined>;\n\tsave(state: McpOAuthState): void | Promise<void>;\n}\n\nexport interface McpOAuthProviderOptions {\n\tserverUrl: string | URL;\n\tredirectUrl: string | URL;\n\tclientMetadata: Omit<OAuthClientMetadata, \"redirect_uris\"> & { redirect_uris?: string[] };\n\t/** See `OAuthClientProvider.clientMetadataDocument`. */\n\tclientMetadataDocument?: (\n\t\tmetadata: AuthorizationServerMetadata | undefined,\n\t) => OAuthClientMetadataDocument | undefined;\n\tclientId?: string;\n\tclientSecret?: string;\n\tstore?: McpOAuthStateStore;\n\tonRedirect(url: URL): void | Promise<void>;\n}\n\nexport class MemoryOAuthStateStore implements McpOAuthStateStore {\n\tprivate value: McpOAuthState | undefined;\n\n\tload(): McpOAuthState | undefined {\n\t\treturn this.value === undefined ? undefined : structuredClone(this.value);\n\t}\n\n\tsave(state: McpOAuthState): void {\n\t\tthis.value = structuredClone(state);\n\t}\n}\n\n/** Default stateful provider for one exact MCP server URL. Applications inject durable storage if needed. */\nexport class McpOAuthProvider implements OAuthClientProvider {\n\treadonly redirectUrl: string;\n\treadonly clientMetadata: OAuthClientMetadata;\n\treadonly clientMetadataDocument?: (\n\t\tmetadata: AuthorizationServerMetadata | undefined,\n\t) => OAuthClientMetadataDocument | undefined;\n\tprivate serverUrl: string;\n\tprivate configuredClient: OAuthClientInformationMixed | undefined;\n\tprivate store: McpOAuthStateStore;\n\tprivate onRedirect: (url: URL) => void | Promise<void>;\n\tprivate writes: Promise<void> = Promise.resolve();\n\n\tconstructor(options: McpOAuthProviderOptions) {\n\t\tthis.serverUrl = String(new URL(options.serverUrl));\n\t\tthis.redirectUrl = String(options.redirectUrl);\n\t\tthis.clientMetadata = {\n\t\t\t...options.clientMetadata,\n\t\t\tredirect_uris: options.clientMetadata.redirect_uris ?? [this.redirectUrl],\n\t\t\tgrant_types: options.clientMetadata.grant_types ?? [\"authorization_code\", \"refresh_token\"],\n\t\t\tresponse_types: options.clientMetadata.response_types ?? [\"code\"],\n\t\t\ttoken_endpoint_auth_method:\n\t\t\t\toptions.clientMetadata.token_endpoint_auth_method ?? (options.clientSecret ? \"client_secret_post\" : \"none\"),\n\t\t};\n\t\tthis.clientMetadataDocument = options.clientMetadataDocument;\n\t\tthis.configuredClient = options.clientId\n\t\t\t? { client_id: options.clientId, ...(options.clientSecret ? { client_secret: options.clientSecret } : {}) }\n\t\t\t: undefined;\n\t\tthis.store = options.store ?? new MemoryOAuthStateStore();\n\t\tthis.onRedirect = options.onRedirect;\n\t}\n\n\tasync state(): Promise<string> {\n\t\tconst existing = (await this.load()).oauthState;\n\t\tif (existing) return existing;\n\t\tconst state = Buffer.from(crypto.getRandomValues(new Uint8Array(32))).toString(\"hex\");\n\t\tawait this.update((value) => ({ ...value, oauthState: state }));\n\t\treturn state;\n\t}\n\n\tasync clientInformation(): Promise<OAuthClientInformationMixed | undefined> {\n\t\treturn this.configuredClient ?? (await this.load()).clientInformation;\n\t}\n\n\tasync saveClientInformation(information: OAuthClientInformationMixed): Promise<void> {\n\t\tif (this.configuredClient) return;\n\t\tawait this.update((value) => ({ ...value, clientInformation: information }));\n\t}\n\n\tasync tokens(): Promise<OAuthTokens | undefined> {\n\t\treturn (await this.load()).tokens;\n\t}\n\n\tasync saveTokens(tokens: OAuthTokens): Promise<void> {\n\t\tconst expiresAt = tokens.expires_in === undefined ? undefined : Date.now() + tokens.expires_in * 1000;\n\t\tawait this.update((value) => {\n\t\t\tconst next: McpOAuthState = { ...value, tokens };\n\t\t\tif (expiresAt === undefined) delete next.tokensExpireAt;\n\t\t\telse next.tokensExpireAt = expiresAt;\n\t\t\treturn next;\n\t\t});\n\t}\n\n\tasync redirectToAuthorization(url: URL): Promise<void> {\n\t\tawait this.onRedirect(url);\n\t}\n\n\tasync saveCodeVerifier(verifier: string): Promise<void> {\n\t\tawait this.update((value) => ({ ...value, codeVerifier: verifier }));\n\t}\n\n\tasync codeVerifier(): Promise<string> {\n\t\tconst verifier = (await this.load()).codeVerifier;\n\t\tif (!verifier) throw new Error(\"No OAuth PKCE code verifier is stored\");\n\t\treturn verifier;\n\t}\n\n\tasync invalidateCredentials(kind: \"all\" | \"client\" | \"tokens\" | \"verifier\" | \"discovery\"): Promise<void> {\n\t\tawait this.update((value) => {\n\t\t\tconst next = { ...value };\n\t\t\tif (kind === \"all\" || kind === \"client\") delete next.clientInformation;\n\t\t\tif (kind === \"all\" || kind === \"tokens\") {\n\t\t\t\tdelete next.tokens;\n\t\t\t\tdelete next.tokensExpireAt;\n\t\t\t}\n\t\t\tif (kind === \"all\" || kind === \"verifier\") delete next.codeVerifier;\n\t\t\tif (kind === \"all\" || kind === \"discovery\") delete next.discovery;\n\t\t\tif (kind === \"all\") delete next.oauthState;\n\t\t\treturn next;\n\t\t});\n\t}\n\n\tasync saveDiscoveryState(discovery: OAuthDiscoveryState): Promise<void> {\n\t\tawait this.update((value) => ({ ...value, discovery }));\n\t}\n\n\tasync discoveryState(): Promise<OAuthDiscoveryState | undefined> {\n\t\treturn (await this.load()).discovery;\n\t}\n\n\tprivate async load(): Promise<McpOAuthState> {\n\t\tawait this.writes;\n\t\treturn this.own(await this.store.load());\n\t}\n\n\tprivate async update(update: (state: McpOAuthState) => McpOAuthState): Promise<void> {\n\t\tthis.writes = this.writes.then(async () => {\n\t\t\tawait this.store.save(update(this.own(await this.store.load())));\n\t\t});\n\t\tawait this.writes;\n\t}\n\n\t/** Stored state for another server URL is ignored so credentials never leak across servers. */\n\tprivate own(state: McpOAuthState | undefined): McpOAuthState {\n\t\treturn state?.serverUrl === this.serverUrl ? state : { serverUrl: this.serverUrl };\n\t}\n}\n"]}
@@ -2,10 +2,15 @@
2
2
  * MCP server configuration.
3
3
  *
4
4
  * Servers are read from `mcp.json` in the agent directory and, for trusted projects, from
5
- * `<project>/.pi/mcp.json`. Both use the `mcpServers` shape shared by other MCP clients, so
5
+ * `<project>/.atomic/mcp.json`. Both use the `mcpServers` shape shared by other MCP clients, so
6
6
  * existing configurations can be copied over. Project entries replace global entries with the
7
7
  * same name.
8
8
  *
9
+ * A project entry without `command`, `url`, or `type` overrides only `enabled`, `exposure`, and
10
+ * `toolExposure` of the global server with the same name, for example to turn it off in one project:
11
+ * `{ "mcpServers": { "internal-tools": { "enabled": false } } }`. The rest of the global entry is kept,
12
+ * including credentials the project could not set itself.
13
+ *
9
14
  * ```json
10
15
  * {
11
16
  * "mcpServers": {
@@ -36,12 +41,16 @@ export interface McpServerEntry {
36
41
  * `pi.registerMcpServer()`. Changes to extension servers are not saved.
37
42
  */
38
43
  scope?: "global" | "project" | "extension";
44
+ /** Project `mcp.json` with an override of this global server's `enabled`, `exposure`, or `toolExposure`. */
45
+ override?: string;
39
46
  }
40
47
  export interface LoadedMcpConfig {
41
48
  servers: McpServerEntry[];
42
49
  /** Activate the codemode tool when `codemode` servers connect. Default: true. */
43
50
  autoEnableCodemode?: boolean;
44
51
  errors: string[];
52
+ /** The project `mcp.json` when the project is trusted, where `/mcp` saves project overrides. */
53
+ projectConfig?: string;
45
54
  }
46
55
  /**
47
56
  * Load global and (when trusted) project MCP configuration. Disabled servers are included with
@@ -58,10 +67,13 @@ export interface McpServerConfigPatch {
58
67
  exposure?: McpExposure;
59
68
  }
60
69
  /**
61
- * Change one server's settings in the `mcp.json` that defines it. Other content is kept; the file is
62
- * rewritten with its indentation.
70
+ * Change one server's settings in the `mcp.json` that defines or overrides it. With `override`, a
71
+ * missing entry is added as an override. Overrides keep default values, since they replace the global
72
+ * server's. Other content is kept; the file is rewritten with its indentation.
63
73
  */
64
- export declare function updateMcpServerConfig(path: string, name: string, patch: McpServerConfigPatch): void;
74
+ export declare function updateMcpServerConfig(path: string, name: string, patch: McpServerConfigPatch, options?: {
75
+ override?: boolean;
76
+ }): void;
65
77
  /**
66
78
  * Add a server to an `mcp.json`, creating the file when missing. An existing entry with the same
67
79
  * name is replaced. Returns true when an entry was replaced.
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/extensions/mcp/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAKH,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,eAAe,EAGpB,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACX,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,oBAAoB,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;CACjB;AAgDD;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GAAG,eAAe,CASlH;AAED,+GAA+G;AAC/G,MAAM,WAAW,oBAAoB;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,WAAW,CAAC;CACvB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,oBAAoB,GAAG,IAAI,CAcnG;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAU/F;AAED,0FAA0F;AAC1F,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAUzE"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../src/extensions/mcp/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AAKH,OAAO,EACN,KAAK,WAAW,EAChB,KAAK,eAAe,EAGpB,MAAM,2BAA2B,CAAC;AAEnC,YAAY,EACX,WAAW,EACX,mBAAmB,EACnB,cAAc,EACd,eAAe,EACf,oBAAoB,GACpB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE/D,MAAM,WAAW,cAAc;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,eAAe,CAAC;IACxB,2FAA2F;IAC3F,MAAM,EAAE,MAAM,CAAC;IACf;;;OAGG;IACH,KAAK,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,WAAW,CAAC;IAC3C,4GAA4G;IAC5G,QAAQ,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,eAAe;IAC/B,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,gGAAgG;IAChG,aAAa,CAAC,EAAE,MAAM,CAAC;CACvB;AAuED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,cAAc,EAAE,OAAO,CAAA;CAAE,GAAG,eAAe,CAWlH;AAED,+GAA+G;AAC/G,MAAM,WAAW,oBAAoB;IACpC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,QAAQ,CAAC,EAAE,WAAW,CAAC;CACvB;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CACpC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,oBAAoB,EAC3B,OAAO,GAAE;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAO,GAClC,IAAI,CAqBN;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,eAAe,GAAG,OAAO,CAU/F;AAED,0FAA0F;AAC1F,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAUzE"}