@noodleseed/one 0.95.1 → 0.96.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/auth-live-doctor.d.ts +1 -0
- package/dist/commands/auth-live-doctor.d.ts.map +1 -1
- package/dist/commands/auth-live-doctor.js +7 -6
- package/dist/commands/auth-live-doctor.js.map +1 -1
- package/dist/commands/auth-metadata-readiness.d.ts +2 -0
- package/dist/commands/auth-metadata-readiness.d.ts.map +1 -1
- package/dist/commands/auth-metadata-readiness.js +7 -0
- package/dist/commands/auth-metadata-readiness.js.map +1 -1
- package/dist/commands/auth-ops.d.ts +1 -0
- package/dist/commands/auth-ops.d.ts.map +1 -1
- package/dist/commands/auth-ops.js +26 -7
- package/dist/commands/auth-ops.js.map +1 -1
- package/dist/commands/author-loop.d.ts.map +1 -1
- package/dist/commands/author-loop.js +3 -2
- package/dist/commands/author-loop.js.map +1 -1
- package/dist/commands/catalog-data-auth-discovery.d.ts.map +1 -1
- package/dist/commands/catalog-data-auth-discovery.js +7 -0
- package/dist/commands/catalog-data-auth-discovery.js.map +1 -1
- package/dist/commands/connect-oauth.d.ts.map +1 -1
- package/dist/commands/connect-oauth.js +1 -0
- package/dist/commands/connect-oauth.js.map +1 -1
- package/dist/dev.d.ts +6 -1
- package/dist/dev.d.ts.map +1 -1
- package/dist/dev.js +120 -34
- package/dist/dev.js.map +1 -1
- package/dist/device-login.js +1 -0
- package/dist/device-login.js.map +1 -1
- package/dist/devtools-preview.d.ts.map +1 -1
- package/dist/devtools-preview.js +82 -8
- package/dist/devtools-preview.js.map +1 -1
- package/dist/plugin-mode/build-readiness-server.d.ts +1 -1
- package/dist/plugin-mode/build-readiness-server.d.ts.map +1 -1
- package/dist/plugin-mode/build-readiness-server.js +3 -4
- package/dist/plugin-mode/build-readiness-server.js.map +1 -1
- package/dist/plugin-mode/plugin-operation-contract.d.ts +1 -1
- package/dist/plugin-mode/plugin-operation-contract.d.ts.map +1 -1
- package/dist/plugin-mode/plugin-operation-tools.d.ts +1 -2
- package/dist/plugin-mode/plugin-operation-tools.d.ts.map +1 -1
- package/dist/plugin-mode/plugin-operation-tools.js.map +1 -1
- package/dist/saas-scaffold-template.d.ts.map +1 -1
- package/dist/saas-scaffold-template.js +2 -1
- package/dist/saas-scaffold-template.js.map +1 -1
- package/node_modules/@modelcontextprotocol/client/LICENSE +216 -0
- package/node_modules/@modelcontextprotocol/client/README.md +26 -0
- package/node_modules/@modelcontextprotocol/client/dist/ajvProvider-1b6pVpkg.cjs +7531 -0
- package/node_modules/@modelcontextprotocol/client/dist/ajvProvider-1b6pVpkg.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/ajvProvider-97rDpkRx.mjs +7514 -0
- package/node_modules/@modelcontextprotocol/client/dist/ajvProvider-97rDpkRx.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/ajvProvider-FOQRM7up.d.cts +1071 -0
- package/node_modules/@modelcontextprotocol/client/dist/ajvProvider-FOQRM7up.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/ajvProvider-INpkxUi1.d.mts +1071 -0
- package/node_modules/@modelcontextprotocol/client/dist/ajvProvider-INpkxUi1.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/cfWorkerProvider-B3ZJEoRM.d.mts +74 -0
- package/node_modules/@modelcontextprotocol/client/dist/cfWorkerProvider-B3ZJEoRM.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/cfWorkerProvider-B3dvjU3F.cjs +986 -0
- package/node_modules/@modelcontextprotocol/client/dist/cfWorkerProvider-B3dvjU3F.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/cfWorkerProvider-BylNJ1R5.mjs +981 -0
- package/node_modules/@modelcontextprotocol/client/dist/cfWorkerProvider-BylNJ1R5.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/cfWorkerProvider-doTkZbTr.d.cts +74 -0
- package/node_modules/@modelcontextprotocol/client/dist/cfWorkerProvider-doTkZbTr.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/chunk-Bnu9O96Y.cjs +60 -0
- package/node_modules/@modelcontextprotocol/client/dist/chunk-Br0eD_fh.mjs +42 -0
- package/node_modules/@modelcontextprotocol/client/dist/dialects-BGO_ZrYF.cjs +46 -0
- package/node_modules/@modelcontextprotocol/client/dist/dialects-BGO_ZrYF.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/dialects-BOhdv1Fc.mjs +34 -0
- package/node_modules/@modelcontextprotocol/client/dist/dialects-BOhdv1Fc.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/index-CHhhk6PQ.d.cts +2526 -0
- package/node_modules/@modelcontextprotocol/client/dist/index-CHhhk6PQ.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/index-D4xIIEF6.d.mts +2523 -0
- package/node_modules/@modelcontextprotocol/client/dist/index-D4xIIEF6.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/index.cjs +5690 -0
- package/node_modules/@modelcontextprotocol/client/dist/index.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/index.d.cts +3252 -0
- package/node_modules/@modelcontextprotocol/client/dist/index.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/index.d.mts +3252 -0
- package/node_modules/@modelcontextprotocol/client/dist/index.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/index.mjs +5481 -0
- package/node_modules/@modelcontextprotocol/client/dist/index.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsBrowser.cjs +14 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsBrowser.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsBrowser.d.cts +13 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsBrowser.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsBrowser.d.mts +13 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsBrowser.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsBrowser.mjs +13 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsBrowser.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsNode.cjs +14 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsNode.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsNode.d.cts +13 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsNode.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsNode.d.mts +13 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsNode.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsNode.mjs +13 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsNode.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.cjs +21 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.d.cts +13 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.d.mts +13 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.mjs +20 -0
- package/node_modules/@modelcontextprotocol/client/dist/shimsWorkerd.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/src-D_zzAWoS.mjs +7063 -0
- package/node_modules/@modelcontextprotocol/client/dist/src-D_zzAWoS.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/src-NAgB4Mp8.cjs +7431 -0
- package/node_modules/@modelcontextprotocol/client/dist/src-NAgB4Mp8.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/stdio.cjs +217 -0
- package/node_modules/@modelcontextprotocol/client/dist/stdio.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/stdio.d.cts +96 -0
- package/node_modules/@modelcontextprotocol/client/dist/stdio.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/stdio.d.mts +96 -0
- package/node_modules/@modelcontextprotocol/client/dist/stdio.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/stdio.mjs +212 -0
- package/node_modules/@modelcontextprotocol/client/dist/stdio.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/types-DsbMXNFL.d.cts +1099 -0
- package/node_modules/@modelcontextprotocol/client/dist/types-DsbMXNFL.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/types-mS0yxCL0.d.mts +1099 -0
- package/node_modules/@modelcontextprotocol/client/dist/types-mS0yxCL0.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/client/dist/validators/ajv.cjs +5 -0
- package/node_modules/@modelcontextprotocol/client/dist/validators/ajv.d.cts +2 -0
- package/node_modules/@modelcontextprotocol/client/dist/validators/ajv.d.mts +2 -0
- package/node_modules/@modelcontextprotocol/client/dist/validators/ajv.mjs +3 -0
- package/node_modules/@modelcontextprotocol/client/dist/validators/cfWorker.cjs +3 -0
- package/node_modules/@modelcontextprotocol/client/dist/validators/cfWorker.d.cts +2 -0
- package/node_modules/@modelcontextprotocol/client/dist/validators/cfWorker.d.mts +2 -0
- package/node_modules/@modelcontextprotocol/client/dist/validators/cfWorker.mjs +3 -0
- package/node_modules/@modelcontextprotocol/client/package.json +166 -0
- package/node_modules/@modelcontextprotocol/core/LICENSE +216 -0
- package/node_modules/@modelcontextprotocol/core/README.md +40 -0
- package/node_modules/@modelcontextprotocol/core/dist/auth-BWdKR39I.d.mts +8501 -0
- package/node_modules/@modelcontextprotocol/core/dist/auth-BWdKR39I.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/core/dist/auth-CUe6YdwF.mjs +1678 -0
- package/node_modules/@modelcontextprotocol/core/dist/auth-CUe6YdwF.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/core/dist/auth-CfDMXiII.cjs +2899 -0
- package/node_modules/@modelcontextprotocol/core/dist/auth-CfDMXiII.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/core/dist/auth-hYtaIUZm.d.cts +8501 -0
- package/node_modules/@modelcontextprotocol/core/dist/auth-hYtaIUZm.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/core/dist/index.cjs +175 -0
- package/node_modules/@modelcontextprotocol/core/dist/index.d.cts +2 -0
- package/node_modules/@modelcontextprotocol/core/dist/index.d.mts +2 -0
- package/node_modules/@modelcontextprotocol/core/dist/index.mjs +3 -0
- package/node_modules/@modelcontextprotocol/core/dist/internal.cjs +201 -0
- package/node_modules/@modelcontextprotocol/core/dist/internal.d.cts +99 -0
- package/node_modules/@modelcontextprotocol/core/dist/internal.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/core/dist/internal.d.mts +99 -0
- package/node_modules/@modelcontextprotocol/core/dist/internal.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/core/dist/internal.mjs +3 -0
- package/node_modules/@modelcontextprotocol/core/package.json +85 -0
- package/node_modules/@modelcontextprotocol/server/LICENSE +216 -0
- package/node_modules/@modelcontextprotocol/server/README.md +30 -0
- package/node_modules/@modelcontextprotocol/server/dist/ajvProvider-CEoC__sr.mjs +7514 -0
- package/node_modules/@modelcontextprotocol/server/dist/ajvProvider-CEoC__sr.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/ajvProvider-CgI-5L6O.d.mts +1071 -0
- package/node_modules/@modelcontextprotocol/server/dist/ajvProvider-CgI-5L6O.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/ajvProvider-FOQRM7up.d.cts +1071 -0
- package/node_modules/@modelcontextprotocol/server/dist/ajvProvider-FOQRM7up.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/ajvProvider-ZaoO9afR.cjs +7531 -0
- package/node_modules/@modelcontextprotocol/server/dist/ajvProvider-ZaoO9afR.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-BwbPzsdI.cjs +986 -0
- package/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-BwbPzsdI.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-C03CSigr.d.mts +74 -0
- package/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-C03CSigr.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-doTkZbTr.d.cts +74 -0
- package/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-doTkZbTr.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-p3WaZPqB.mjs +981 -0
- package/node_modules/@modelcontextprotocol/server/dist/cfWorkerProvider-p3WaZPqB.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/chunk-Bnu9O96Y.cjs +60 -0
- package/node_modules/@modelcontextprotocol/server/dist/chunk-Br0eD_fh.mjs +42 -0
- package/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-CLhGwQTn.d.mts +4043 -0
- package/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-CLhGwQTn.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-dBHMsxwf.d.cts +4045 -0
- package/node_modules/@modelcontextprotocol/server/dist/createMcpHandler-dBHMsxwf.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/dialects-D8eXzoGv.cjs +46 -0
- package/node_modules/@modelcontextprotocol/server/dist/dialects-D8eXzoGv.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/dialects-DoSzNhcb.mjs +34 -0
- package/node_modules/@modelcontextprotocol/server/dist/dialects-DoSzNhcb.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/index.cjs +2055 -0
- package/node_modules/@modelcontextprotocol/server/dist/index.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/index.d.cts +739 -0
- package/node_modules/@modelcontextprotocol/server/dist/index.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/index.d.mts +739 -0
- package/node_modules/@modelcontextprotocol/server/dist/index.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/index.mjs +1870 -0
- package/node_modules/@modelcontextprotocol/server/dist/index.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/mcp-D7GmuPnv.cjs +2022 -0
- package/node_modules/@modelcontextprotocol/server/dist/mcp-D7GmuPnv.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/mcp-DXXb3Vv3.mjs +1931 -0
- package/node_modules/@modelcontextprotocol/server/dist/mcp-DXXb3Vv3.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.cjs +23 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.d.cts +11 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.d.mts +11 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.mjs +22 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsBrowser.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsNode.cjs +12 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsNode.d.cts +3 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsNode.d.mts +3 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsNode.mjs +4 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.cjs +30 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.d.cts +10 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.d.mts +10 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.mjs +29 -0
- package/node_modules/@modelcontextprotocol/server/dist/shimsWorkerd.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/src-CX2iR2pK.mjs +7606 -0
- package/node_modules/@modelcontextprotocol/server/dist/src-CX2iR2pK.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/src-STyD_Vvf.cjs +8104 -0
- package/node_modules/@modelcontextprotocol/server/dist/src-STyD_Vvf.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/stdio.cjs +564 -0
- package/node_modules/@modelcontextprotocol/server/dist/stdio.cjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/stdio.d.cts +107 -0
- package/node_modules/@modelcontextprotocol/server/dist/stdio.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/stdio.d.mts +107 -0
- package/node_modules/@modelcontextprotocol/server/dist/stdio.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/stdio.mjs +562 -0
- package/node_modules/@modelcontextprotocol/server/dist/stdio.mjs.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/types-DUs7mGBv.d.mts +1099 -0
- package/node_modules/@modelcontextprotocol/server/dist/types-DUs7mGBv.d.mts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/types-DsbMXNFL.d.cts +1099 -0
- package/node_modules/@modelcontextprotocol/server/dist/types-DsbMXNFL.d.cts.map +1 -0
- package/node_modules/@modelcontextprotocol/server/dist/validators/ajv.cjs +5 -0
- package/node_modules/@modelcontextprotocol/server/dist/validators/ajv.d.cts +2 -0
- package/node_modules/@modelcontextprotocol/server/dist/validators/ajv.d.mts +2 -0
- package/node_modules/@modelcontextprotocol/server/dist/validators/ajv.mjs +3 -0
- package/node_modules/@modelcontextprotocol/server/dist/validators/cfWorker.cjs +3 -0
- package/node_modules/@modelcontextprotocol/server/dist/validators/cfWorker.d.cts +2 -0
- package/node_modules/@modelcontextprotocol/server/dist/validators/cfWorker.d.mts +2 -0
- package/node_modules/@modelcontextprotocol/server/dist/validators/cfWorker.mjs +3 -0
- package/node_modules/@modelcontextprotocol/server/package.json +160 -0
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js +4 -4
- package/node_modules/@noodle-borg/agent-kit/dist/generated/example-files.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-auth-ref.js +3 -3
- package/node_modules/@noodle-borg/agent-kit/dist/skill-authoring-auth-ref.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-server-playbook-ref.d.ts.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/dist/skill-server-playbook-ref.js +1 -0
- package/node_modules/@noodle-borg/agent-kit/dist/skill-server-playbook-ref.js.map +1 -1
- package/node_modules/@noodle-borg/agent-kit/package.json +1 -1
- package/node_modules/@noodle-borg/capabilities/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/capabilities/dist/index.js +11 -4
- package/node_modules/@noodle-borg/capabilities/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/prompts.d.ts +1 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/prompts.d.ts.map +1 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/resources.d.ts +1 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/resources.d.ts.map +1 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/server.d.ts +1 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/server.d.ts.map +1 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/server.js +3 -1
- package/node_modules/@noodle-borg/developer-mcp/dist/server.js.map +1 -1
- package/node_modules/@noodle-borg/developer-mcp/package.json +2 -1
- package/node_modules/@noodle-borg/module/dist/contract.d.ts +3 -1
- package/node_modules/@noodle-borg/module/dist/contract.d.ts.map +1 -1
- package/node_modules/@noodle-borg/module/dist/contract.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/error-codes.d.ts +11 -0
- package/node_modules/@noodle-borg/protocol/dist/error-codes.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/error-codes.js +11 -0
- package/node_modules/@noodle-borg/protocol/dist/error-codes.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/prompts.d.ts +6 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/prompts.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/prompts.js +31 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/prompts.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/resources.d.ts +6 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/resources.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/resources.js +50 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/resources.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/tools.d.ts +6 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/tools.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/tools.js +126 -0
- package/node_modules/@noodle-borg/protocol/dist/handlers/tools.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/index.d.ts +6 -2
- package/node_modules/@noodle-borg/protocol/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/index.js +4 -1
- package/node_modules/@noodle-borg/protocol/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/interaction-envelope.d.ts +10 -0
- package/node_modules/@noodle-borg/protocol/dist/interaction-envelope.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/interaction-envelope.js +66 -0
- package/node_modules/@noodle-borg/protocol/dist/interaction-envelope.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/jsonrpc.d.ts +1 -0
- package/node_modules/@noodle-borg/protocol/dist/jsonrpc.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/jsonrpc.js +1 -0
- package/node_modules/@noodle-borg/protocol/dist/jsonrpc.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/observation.d.ts +27 -0
- package/node_modules/@noodle-borg/protocol/dist/observation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/observation.js +20 -0
- package/node_modules/@noodle-borg/protocol/dist/observation.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/request-deps.d.ts +6 -0
- package/node_modules/@noodle-borg/protocol/dist/request-deps.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/request-deps.js +16 -0
- package/node_modules/@noodle-borg/protocol/dist/request-deps.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/request-state.d.ts +50 -0
- package/node_modules/@noodle-borg/protocol/dist/request-state.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/request-state.js +195 -0
- package/node_modules/@noodle-borg/protocol/dist/request-state.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.d.ts +16 -23
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.js +7 -341
- package/node_modules/@noodle-borg/protocol/dist/sdk-server.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-authorization.d.ts +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-authorization.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-authorization.js +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-authorization.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts +7 -2
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.d.ts.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js +8 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-interaction.js.map +1 -1
- package/node_modules/@noodle-borg/protocol/dist/tool-results.d.ts +7 -0
- package/node_modules/@noodle-borg/protocol/dist/tool-results.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/tool-results.js +49 -0
- package/node_modules/@noodle-borg/protocol/dist/tool-results.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/cache-hints.d.ts +11 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/cache-hints.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/cache-hints.js +14 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/cache-hints.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/confirmation.d.ts +16 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/confirmation.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/confirmation.js +57 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/confirmation.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/handler.d.ts +11 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/handler.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/handler.js +154 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/handler.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/input-required.d.ts +12 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/input-required.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/input-required.js +78 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/input-required.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/server.d.ts +5 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/server.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/server.js +314 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/server.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/tool-list.d.ts +4 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/tool-list.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/tool-list.js +25 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/tool-list.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/versions.d.ts +6 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/versions.d.ts.map +1 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/versions.js +11 -0
- package/node_modules/@noodle-borg/protocol/dist/v2/versions.js.map +1 -0
- package/node_modules/@noodle-borg/protocol/package.json +3 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.js +15 -7
- package/node_modules/@noodle-borg/service/dist/billing/usage-identity.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/customer-auth-audience-binding.d.ts +37 -0
- package/node_modules/@noodle-borg/service/dist/customer-auth-audience-binding.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/customer-auth-audience-binding.js +182 -0
- package/node_modules/@noodle-borg/service/dist/customer-auth-audience-binding.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/customer-auth-audience-quarantine.d.ts +5 -0
- package/node_modules/@noodle-borg/service/dist/customer-auth-audience-quarantine.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/customer-auth-audience-quarantine.js +14 -0
- package/node_modules/@noodle-borg/service/dist/customer-auth-audience-quarantine.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/customer-verifier.js +5 -4
- package/node_modules/@noodle-borg/service/dist/customer-verifier.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/developer-mcp/mount.d.ts +2 -1
- package/node_modules/@noodle-borg/service/dist/developer-mcp/mount.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/developer-mcp/mount.js +16 -14
- package/node_modules/@noodle-borg/service/dist/developer-mcp/mount.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/developer-mcp/service-options.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/developer-mcp/service-options.js +1 -0
- package/node_modules/@noodle-borg/service/dist/developer-mcp/service-options.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/index.js +2 -0
- package/node_modules/@noodle-borg/service/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/main.js +3 -0
- package/node_modules/@noodle-borg/service/dist/main.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/mcp-confirmation-nonce-postgres.d.ts +14 -0
- package/node_modules/@noodle-borg/service/dist/mcp-confirmation-nonce-postgres.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/mcp-confirmation-nonce-postgres.js +35 -0
- package/node_modules/@noodle-borg/service/dist/mcp-confirmation-nonce-postgres.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/mcp-protocol-runtime.d.ts +16 -0
- package/node_modules/@noodle-borg/service/dist/mcp-protocol-runtime.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/mcp-protocol-runtime.js +21 -0
- package/node_modules/@noodle-borg/service/dist/mcp-protocol-runtime.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/app.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/app.js +47 -0
- package/node_modules/@noodle-borg/service/dist/oauth/app.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/authorization-response.d.ts +4 -0
- package/node_modules/@noodle-borg/service/dist/oauth/authorization-response.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/authorization-response.js +6 -0
- package/node_modules/@noodle-borg/service/dist/oauth/authorization-response.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/consent-decision.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/consent-decision.js +2 -1
- package/node_modules/@noodle-borg/service/dist/oauth/consent-decision.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.js +2 -1
- package/node_modules/@noodle-borg/service/dist/oauth/developer-grant-flow.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/first-party-client.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/first-party-client.js +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/first-party-client.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/metadata.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/metadata.js +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/metadata.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/provider.js +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/provider.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/token-issuer.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/token-issuer.js +2 -1
- package/node_modules/@noodle-borg/service/dist/oauth/token-issuer.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-handler.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-handler.js +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-handler.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-support.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-support.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-support.js +2 -1
- package/node_modules/@noodle-borg/service/dist/oauth/upstream-callback-support.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/options.d.ts +10 -3
- package/node_modules/@noodle-borg/service/dist/options.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/platform-account-reset-quarantine-postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/platform-account-reset-quarantine-postgres.js +20 -8
- package/node_modules/@noodle-borg/service/dist/platform-account-reset-quarantine-postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/platform-account-reset-rollback-postgres.d.ts +2 -0
- package/node_modules/@noodle-borg/service/dist/platform-account-reset-rollback-postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/platform-account-reset-rollback-postgres.js +58 -13
- package/node_modules/@noodle-borg/service/dist/platform-account-reset-rollback-postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/platform-auth-inventory-source-fence-transaction-postgres.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/platform-auth-inventory-source-fence-transaction-postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/platform-auth-inventory-source-fence-transaction-postgres.js +3 -0
- package/node_modules/@noodle-borg/service/dist/platform-auth-inventory-source-fence-transaction-postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/platform-auth-operator.d.ts +24 -24
- package/node_modules/@noodle-borg/service/dist/platform-auth-runtime.d.ts +2 -1
- package/node_modules/@noodle-borg/service/dist/platform-auth-runtime.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/platform-auth-runtime.js +4 -1
- package/node_modules/@noodle-borg/service/dist/platform-auth-runtime.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-access.d.ts +5 -1
- package/node_modules/@noodle-borg/service/dist/registry-access.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-access.js +64 -15
- package/node_modules/@noodle-borg/service/dist/registry-access.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-rollback.d.ts +19 -0
- package/node_modules/@noodle-borg/service/dist/registry-rollback.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/registry-rollback.js +91 -0
- package/node_modules/@noodle-borg/service/dist/registry-rollback.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/registry-state.d.ts +18 -2
- package/node_modules/@noodle-borg/service/dist/registry-state.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-state.js +83 -7
- package/node_modules/@noodle-borg/service/dist/registry-state.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-targets.d.ts +8 -0
- package/node_modules/@noodle-borg/service/dist/registry-targets.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-targets.js +24 -0
- package/node_modules/@noodle-borg/service/dist/registry-targets.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-types.d.ts +1 -1
- package/node_modules/@noodle-borg/service/dist/registry-types.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry.d.ts +2 -1
- package/node_modules/@noodle-borg/service/dist/registry.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/registry.js +72 -83
- package/node_modules/@noodle-borg/service/dist/registry.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/archive.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/archive.js +14 -0
- package/node_modules/@noodle-borg/service/dist/routes/archive.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/auth-doctor-dispatch.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/auth-doctor-dispatch.js +4 -0
- package/node_modules/@noodle-borg/service/dist/routes/auth-doctor-dispatch.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/auth-doctor-live.d.ts +1 -0
- package/node_modules/@noodle-borg/service/dist/routes/auth-doctor-live.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/auth-doctor-live.js +17 -4
- package/node_modules/@noodle-borg/service/dist/routes/auth-doctor-live.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/contracts.d.ts +9 -9
- package/node_modules/@noodle-borg/service/dist/routes/private-platform-auth-dispatch.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/private-platform-auth-dispatch.js +1 -1
- package/node_modules/@noodle-borg/service/dist/routes/private-platform-auth-dispatch.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/serve.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/serve.js +19 -2
- package/node_modules/@noodle-borg/service/dist/serve.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/service.js +5 -0
- package/node_modules/@noodle-borg/service/dist/service.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/in-memory.d.ts +5 -2
- package/node_modules/@noodle-borg/service/dist/store/in-memory.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/in-memory.js +51 -8
- package/node_modules/@noodle-borg/service/dist/store/in-memory.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/json-file.d.ts +5 -2
- package/node_modules/@noodle-borg/service/dist/store/json-file.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/json-file.js +55 -6
- package/node_modules/@noodle-borg/service/dist/store/json-file.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-apps.d.ts +2 -2
- package/node_modules/@noodle-borg/service/dist/store/postgres-apps.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-apps.js +30 -15
- package/node_modules/@noodle-borg/service/dist/store/postgres-apps.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-customer-auth-audience-schema.d.ts +16 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-customer-auth-audience-schema.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-customer-auth-audience-schema.js +329 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-customer-auth-audience-schema.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-customer-auth-audience.d.ts +5 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-customer-auth-audience.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-customer-auth-audience.js +24 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-customer-auth-audience.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-deploy-records.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-deploy-records.js +2 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-deploy-records.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-deployment-access.d.ts +9 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-deployment-access.d.ts.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-deployment-access.js +53 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-deployment-access.js.map +1 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.js +2 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-github-runs.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-rows.d.ts +2 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-rows.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-rows.js +2 -24
- package/node_modules/@noodle-borg/service/dist/store/postgres-rows.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-schema.d.ts +2 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-schema.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres-schema.js +3 -0
- package/node_modules/@noodle-borg/service/dist/store/postgres-schema.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts +7 -2
- package/node_modules/@noodle-borg/service/dist/store/postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/postgres.js +27 -31
- package/node_modules/@noodle-borg/service/dist/store/postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/request-events-postgres.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/request-events-postgres.js +9 -2
- package/node_modules/@noodle-borg/service/dist/store/request-events-postgres.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/request-events.d.ts.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store/request-events.js +1 -0
- package/node_modules/@noodle-borg/service/dist/store/request-events.js.map +1 -1
- package/node_modules/@noodle-borg/service/dist/store.d.ts +20 -1
- package/node_modules/@noodle-borg/service/dist/store.d.ts.map +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/handler.d.ts +19 -67
- package/node_modules/@noodle-borg/transport-http/dist/handler.d.ts.map +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/handler.js +12 -281
- package/node_modules/@noodle-borg/transport-http/dist/handler.js.map +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/index.d.ts +2 -1
- package/node_modules/@noodle-borg/transport-http/dist/index.d.ts.map +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/index.js +1 -0
- package/node_modules/@noodle-borg/transport-http/dist/index.js.map +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/request-capture.d.ts.map +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/request-capture.js +38 -4
- package/node_modules/@noodle-borg/transport-http/dist/request-capture.js.map +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/responses.d.ts +28 -0
- package/node_modules/@noodle-borg/transport-http/dist/responses.d.ts.map +1 -0
- package/node_modules/@noodle-borg/transport-http/dist/responses.js +50 -0
- package/node_modules/@noodle-borg/transport-http/dist/responses.js.map +1 -0
- package/node_modules/@noodle-borg/transport-http/dist/routing.d.ts +28 -0
- package/node_modules/@noodle-borg/transport-http/dist/routing.d.ts.map +1 -0
- package/node_modules/@noodle-borg/transport-http/dist/routing.js +52 -0
- package/node_modules/@noodle-borg/transport-http/dist/routing.js.map +1 -0
- package/node_modules/@noodle-borg/transport-http/dist/serve-request.d.ts +35 -0
- package/node_modules/@noodle-borg/transport-http/dist/serve-request.d.ts.map +1 -0
- package/node_modules/@noodle-borg/transport-http/dist/serve-request.js +190 -0
- package/node_modules/@noodle-borg/transport-http/dist/serve-request.js.map +1 -0
- package/node_modules/@noodle-borg/transport-http/dist/tool-dispatch.d.ts +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/tool-dispatch.d.ts.map +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/tool-dispatch.js +17 -5
- package/node_modules/@noodle-borg/transport-http/dist/tool-dispatch.js.map +1 -1
- package/node_modules/@noodle-borg/transport-http/dist/web-bridge.d.ts +9 -0
- package/node_modules/@noodle-borg/transport-http/dist/web-bridge.d.ts.map +1 -0
- package/node_modules/@noodle-borg/transport-http/dist/web-bridge.js +61 -0
- package/node_modules/@noodle-borg/transport-http/dist/web-bridge.js.map +1 -0
- package/package.json +6 -2
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["brandedHasInstance","recordedIssuer: string","currentIssuer: string","brandedHasInstance","OAuthError","url: URL","OAuthErrorResponseSchema","OAuthErrorCode","resourceMetadata: OAuthProtectedResourceMetadata | undefined","authorizationServerUrl: string | URL","metadata: AuthorizationServerMetadata | undefined","freshDiscoveryState: OAuthDiscoveryState | undefined","infoCtx: OAuthClientInformationContext","resource: URL | undefined","tokens","resourceUrlFromServerUrl","checkResourceAllowed","resourceMetadataUrl: URL | undefined","OAuthProtectedResourceMetadataSchema","CORS_IS_POSSIBLE","LATEST_PROTOCOL_VERSION","OAuthMetadataSchema","urlsToTry: { url: URL; type: 'oauth' | 'oidc' }[]","OpenIdProviderDiscoveryMetadataSchema","authorizationServerUrl: string | undefined","authorizationUrl: URL","json: unknown","OAuthTokensSchema","tokenRequestParams: URLSearchParams | undefined","registrationUrl: URL","submittedMetadata: OAuthClientMetadata","OAuthClientInformationFullSchema","key: unknown","CAP_EXEMPT_METHODS: ReadonlySet<string>","_store: ResponseCacheStore","_isUserSupplied: boolean","_reportError: (error: unknown) => void","_cachePartition: string","_now: () => number","parsed: unknown","json: string | undefined","SdkError","SdkErrorCode","codecForVersion","MODERN_WIRE_REVISION","UnsupportedProtocolVersionError","modernProtocolVersions","SdkHttpError","parsed: unknown","DEFAULT_VERSION_NEGOTIATION_MODE: VersionNegotiationMode","isModernProtocolVersion","modernProtocolVersions","SUPPORTED_MODERN_PROTOCOL_VERSIONS","legacyProtocolVersions","_transport: Transport","isJSONRPCResultResponse","isJSONRPCErrorResponse","codecForVersion","SdkHttpError","verdict: ProbeVerdict","SdkError","SdkErrorCode","result: NegotiationResult","signalClosed: (() => void) | undefined","SERVER_INFO_META_KEY","isSpecType","DiscoverResultSchema","SdkError","SdkErrorCode","LIST_CHANGED_EVICTIONS: Readonly<Record<string, readonly string[]>>","Protocol","_clientInfo: Implementation","DefaultJsonSchemaValidator","resolveInputRequiredDriverConfig","isModernProtocolVersion","isJSONRPCRequest","runInputRequiredFlow","mergeCapabilities","codecForVersion","ProtocolError","ProtocolErrorCode","legacyProtocolVersions","result: Awaited<ReturnType<typeof negotiateEra>>","DEFAULT_REQUEST_TIMEOUT_MSEC","effective: ListChangedHandlers","filter: SubscriptionFilter","modernProtocolVersions","SUPPORTED_MODERN_PROTOCOL_VERSIONS","scope: CacheScope","scanXMcpHeaderDeclarations","state: 'opening' | 'open' | 'closed'","ackTimer: ReturnType<typeof setTimeout> | undefined","onCallerAbort: (() => void) | undefined","resolveOpening!: (honored: SubscriptionFilter) => void","rejectOpening!: (error: Error) => void","resolveClosed!: (cause: 'local' | 'graceful' | 'remote') => void","jsonrpcRequest: JSONRPCRequest","SUBSCRIPTION_ID_META_KEY","isJSONRPCErrorResponse","scan: XMcpHeaderScanResult | undefined","buildMcpParamHeaders","result: CallToolResult","HEADER_MISMATCH_ERROR_CODE","parseSchema","ListChangedOptionsBaseSchema","parseResult","OAuthErrorResponseSchema","IdJagTokenExchangeResponseSchema","OAuthTokensSchema","defaultLogger: RequestLogger","brandedHasInstance","code: number | undefined","event: ErrorEvent","createFetchWithInit","headers: RequestInit['headers'] & Record<string, string>","token: string | undefined","normalizeHeaders","EventSource","error","message: JSONRPCMessage","JSONRPCMessageSchema","SdkError","SdkErrorCode","SdkHttpError","DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS: StreamableHTTPReconnectionOptions","RESERVED_REQUEST_HEADER_NAMES: ReadonlySet<string>","createFetchWithInit","SdkHttpError","SdkErrorCode","headers: RequestInit['headers'] & Record<string, string>","token: string | undefined","normalizeHeaders","isJSONRPCRequest","PROTOCOL_VERSION_META_KEY","encodeMcpParamValue","isModernProtocolVersion","lastEventId: string | undefined","EventSourceParserStream","JSONRPCMessageSchema","isJSONRPCResultResponse","isJSONRPCErrorResponse","error","isInitializeRequest","isInitializedNotification","mediaTypeEssence","SdkError","_defaultValidator: jsonSchemaValidator | undefined","coreFromJsonSchema","DefaultJsonSchemaValidator"],"sources":["../src/client/authErrors.ts","../src/client/auth.ts","../src/client/authExtensions.ts","../src/client/responseCache.ts","../src/client/authSeam.ts","../src/client/probeClassifier.ts","../src/client/versionNegotiation.ts","../src/client/client.ts","../src/client/crossAppAccess.ts","../src/client/middleware.ts","../src/client/sse.ts","../src/client/streamableHttp.ts","../src/fromJsonSchema.ts"],"sourcesContent":["/**\n * Error classes thrown by the OAuth client flow ({@linkcode auth} and helpers).\n *\n * Each behavior change in the 2026-07-28 authorization requirements adds its\n * dedicated error class to this module so callers can `instanceof`-dispatch on\n * the failure mode without string-matching messages.\n */\n\nimport type { OAuthClientMetadata } from '@modelcontextprotocol/core-internal';\nimport { brandedHasInstance, stampErrorBrands } from '@modelcontextprotocol/core-internal';\n\n/**\n * Base class for the OAuth-client-flow error family. Concrete subclasses are\n * added to this module alongside the SEP-2468/837/2207/2350/2352 behavior\n * changes that throw them, so callers can catch the whole family with a single\n * `instanceof OAuthClientFlowError` guard once those land.\n *\n * @remarks Nothing in the SDK throws this base class directly. In the release\n * that introduces it no subclass exists yet — the guard is a forward-compat\n * hook and will not match anything until the first behavior change ships.\n */\nexport class OAuthClientFlowError extends Error {\n static {\n Object.defineProperty(this, 'mcpBrand', { value: 'mcp.OAuthClientFlowError' });\n }\n\n static override [Symbol.hasInstance](value: unknown): boolean {\n return brandedHasInstance(this, value);\n }\n\n /**\n * Brand-based type guard: equivalent to `value instanceof this`, as an\n * explicit static predicate (the axios/AWS-SDK `isInstance` style). Reads\n * the caller's own brand via `this`, so every branded subclass gets a\n * correctly-scoped guard by inheritance. Must be invoked on the class —\n * in callback position write `v => SdkError.isInstance(v)`, not\n * `.filter(SdkError.isInstance)` (detached calls throw rather than\n * silently matching nothing).\n */\n static isInstance<T extends abstract new (...args: never[]) => unknown>(this: T, value: unknown): value is InstanceType<T> {\n if (typeof this !== 'function') {\n throw new TypeError(\n 'isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`'\n );\n }\n return brandedHasInstance(this, value);\n }\n\n constructor(message: string) {\n super(message);\n this.name = new.target.name;\n stampErrorBrands(this, new.target);\n }\n}\n\n/**\n * Thrown when an authorization-server issuer identifier fails validation.\n *\n * Two checks raise this error, distinguished by {@linkcode IssuerMismatchError.kind | kind}:\n * - `'metadata'` — the `issuer` in fetched authorization-server metadata does\n * not match the issuer identifier the well-known URL was constructed from\n * (RFC 8414 §3.3 / OpenID Connect Discovery §4.3).\n * - `'authorization_response'` — the `iss` parameter on the authorization\n * callback failed RFC 9207 §2.4 validation against the recorded issuer.\n *\n * Intentionally does **not** extend `OAuthError`: the `auth()`\n * orchestrator's `OAuthError` retry block must not swallow this — a mix-up\n * indication is fatal for the flow, not a retryable credential problem.\n *\n * On the `'authorization_response'` path the {@linkcode IssuerMismatchError.received | received}\n * value is attacker-controllable in a mix-up attack; callers **MUST NOT** display\n * it (or any `error`/`error_description`/`error_uri` from the same callback) to\n * end users. The values are JSON-encoded in the message to neutralize log-injection.\n */\nexport class IssuerMismatchError extends OAuthClientFlowError {\n static {\n Object.defineProperty(this, 'mcpBrand', { value: 'mcp.IssuerMismatchError' });\n }\n\n /** Which check failed — metadata echo (RFC 8414 §3.3) or authorization-response `iss` (RFC 9207). */\n readonly kind: 'metadata' | 'authorization_response';\n /** The issuer the client expected (from validated metadata / discovery input). */\n readonly expected: string | undefined;\n /** The issuer value that was received. Attacker-controllable on the `'authorization_response'` path. */\n readonly received: string | undefined;\n\n constructor(kind: 'metadata' | 'authorization_response', expected: string | undefined, received: string | undefined) {\n const where = kind === 'metadata' ? 'authorization server metadata (RFC 8414 §3.3)' : 'authorization response (RFC 9207)';\n // JSON-stringify embedded values so attacker-supplied control characters cannot forge log lines.\n super(`Issuer mismatch in ${where}: expected ${JSON.stringify(expected)}, received ${JSON.stringify(received)}`);\n this.kind = kind;\n this.expected = expected;\n this.received = received;\n }\n}\n\n/**\n * Thrown by `registerClient()` when the authorization server rejects a\n * Dynamic Client Registration request. Carries the HTTP status, the raw\n * response body, and the metadata that was submitted, so callers can inspect\n * the AS's `error` / `error_description` and retry with adjusted metadata\n * (for example a different `application_type`) per SEP-837.\n *\n * The `body` is the raw RFC 7591 error JSON; compare `JSON.parse(body).error`\n * against `OAuthErrorCode` (e.g. `OAuthErrorCode.InvalidRedirectUri`,\n * `OAuthErrorCode.InvalidClientMetadata`).\n *\n * Intentionally does **not** extend `OAuthError`: registration rejection is\n * not a recoverable-by-credential-invalidation condition, and staying outside\n * that hierarchy keeps it from being caught by `auth()`'s `OAuthError` retry\n * path.\n */\nexport class RegistrationRejectedError extends OAuthClientFlowError {\n static {\n Object.defineProperty(this, 'mcpBrand', { value: 'mcp.RegistrationRejectedError' });\n }\n\n /** HTTP status code returned by the registration endpoint. */\n public readonly status: number;\n /** Raw response body text (typically an RFC 7591 error JSON document). */\n public readonly body: string;\n /** The exact client metadata that was POSTed (after SDK defaults were applied). */\n public readonly submittedMetadata: OAuthClientMetadata;\n\n constructor(args: { status: number; body: string; submittedMetadata: OAuthClientMetadata }) {\n super(`Dynamic Client Registration rejected (HTTP ${args.status}): ${args.body}`);\n this.status = args.status;\n this.body = args.body;\n this.submittedMetadata = args.submittedMetadata;\n }\n}\n\n/**\n * Thrown by the token-exchange and refresh paths when the resolved token\n * endpoint is not `https:` and is not a loopback host (SEP-2207). This is a\n * configuration error — re-authorizing cannot fix it — so it intentionally does\n * **not** extend `OAuthError` and `auth()`'s refresh branch rethrows it instead\n * of falling through to a fresh `/authorize` redirect.\n */\nexport class InsecureTokenEndpointError extends OAuthClientFlowError {\n static {\n Object.defineProperty(this, 'mcpBrand', { value: 'mcp.InsecureTokenEndpointError' });\n }\n\n /** The token endpoint URL that was rejected. */\n public readonly tokenEndpoint: string;\n\n constructor(tokenEndpoint: string) {\n super(\n `Refusing to send credentials to non-https token endpoint '${tokenEndpoint}'. ` +\n `OAuth token requests MUST use TLS (localhost / 127.0.0.1 / ::1 are exempt).`\n );\n this.tokenEndpoint = tokenEndpoint;\n }\n}\n\n/**\n * Thrown by the HTTP client transport when the server responds with\n * `403 Forbidden` and `WWW-Authenticate: Bearer error=\"insufficient_scope\"`,\n * and either (a) the transport's `onInsufficientScope` option is `'throw'`, or\n * (b) `onInsufficientScope` is the default `'reauthorize'` but the transport\n * has no {@linkcode index.OAuthClientProvider | OAuthClientProvider} to drive\n * step-up (e.g. a minimal `AuthProvider`, `requestInit`-only headers, or no\n * `authProvider`).\n *\n * Carries the challenge parameters so the host can decide whether to initiate\n * step-up authorization itself (e.g., behind a UX gate) or surface the error.\n *\n * Does **not** extend `OAuthError`: that class represents OAuth protocol errors\n * from the authorization server; this is a resource-server challenge surfaced\n * at the transport layer.\n *\n * All fields originate from the resource server's `WWW-Authenticate` header;\n * treat them as untrusted input when displaying or logging (this includes\n * `requiredScope`, which appears in the error message).\n */\n/**\n * Thrown by `auth()` on the authorization-code callback leg when the\n * authorization server resolved by discovery differs from the one recorded in\n * `discoveryState()` at redirect time. The `authorization_code` and PKCE\n * `code_verifier` are bound to the AS that minted the code (RFC 7636); sending\n * them to a different AS's token endpoint is a credential-exfiltration vector.\n *\n * This is the only runtime check left in the SEP-2352 model — stored tokens and\n * client credentials are protected structurally by the `issuer` stamp instead.\n */\nexport class AuthorizationServerMismatchError extends OAuthClientFlowError {\n static {\n Object.defineProperty(this, 'mcpBrand', { value: 'mcp.AuthorizationServerMismatchError' });\n }\n\n constructor(\n /** The issuer recorded in `discoveryState()` when the authorization redirect was issued. */\n public readonly recordedIssuer: string,\n /** The issuer resolved by discovery on this call. */\n public readonly currentIssuer: string\n ) {\n super(\n `Authorization server changed between redirect and callback ` +\n `(redirected to ${JSON.stringify(recordedIssuer)}, callback resolved ${JSON.stringify(currentIssuer)}); ` +\n `refusing to send authorization_code/code_verifier to a different token endpoint`\n );\n }\n}\n\nexport class InsufficientScopeError extends OAuthClientFlowError {\n static {\n Object.defineProperty(this, 'mcpBrand', { value: 'mcp.InsufficientScopeError' });\n }\n\n /** The `scope` value from the `WWW-Authenticate` challenge — the scopes the resource server says are required. */\n readonly requiredScope?: string;\n /** The `resource_metadata` URL from the `WWW-Authenticate` challenge, if present. */\n readonly resourceMetadataUrl?: URL;\n /** The `error_description` from the `WWW-Authenticate` challenge, if present. */\n readonly errorDescription?: string;\n\n constructor(init: { requiredScope?: string; resourceMetadataUrl?: URL; errorDescription?: string }) {\n super(`Insufficient scope${init.requiredScope ? `: required \"${init.requiredScope}\"` : ''}`);\n this.requiredScope = init.requiredScope;\n this.resourceMetadataUrl = init.resourceMetadataUrl;\n this.errorDescription = init.errorDescription;\n }\n}\n","import { CORS_IS_POSSIBLE } from '@modelcontextprotocol/client/_shims';\nimport type {\n AuthorizationServerMetadata,\n FetchLike,\n OAuthClientInformation,\n OAuthClientInformationFull,\n OAuthClientInformationMixed,\n OAuthClientMetadata,\n OAuthMetadata,\n OAuthProtectedResourceMetadata,\n OAuthTokens,\n StoredOAuthClientInformation,\n StoredOAuthTokens\n} from '@modelcontextprotocol/core-internal';\nimport {\n brandedHasInstance,\n checkResourceAllowed,\n LATEST_PROTOCOL_VERSION,\n OAuthClientInformationFullSchema,\n OAuthError,\n OAuthErrorCode,\n OAuthErrorResponseSchema,\n OAuthMetadataSchema,\n OAuthProtectedResourceMetadataSchema,\n OAuthTokensSchema,\n OpenIdProviderDiscoveryMetadataSchema,\n resourceUrlFromServerUrl,\n stampErrorBrands\n} from '@modelcontextprotocol/core-internal';\nimport pkceChallenge from 'pkce-challenge';\n\nimport { AuthorizationServerMismatchError, InsecureTokenEndpointError, IssuerMismatchError, RegistrationRejectedError } from './authErrors';\n\n// Re-exported for back-compat — the canonical home is ./authErrors.js.\nexport { AuthorizationServerMismatchError, InsecureTokenEndpointError, IssuerMismatchError, RegistrationRejectedError } from './authErrors';\n\n/**\n * Function type for adding client authentication to token requests.\n */\nexport type AddClientAuthentication = (\n headers: Headers,\n params: URLSearchParams,\n url: string | URL,\n metadata?: AuthorizationServerMetadata\n) => void | Promise<void>;\n\n/**\n * Context passed to {@linkcode AuthProvider.onUnauthorized} when the server\n * responds with 401. Provides everything needed to refresh credentials.\n */\nexport interface UnauthorizedContext {\n /** The 401 response — inspect `WWW-Authenticate` for resource metadata, scope, etc. */\n response: Response;\n /** The MCP server URL, for passing to {@linkcode auth} or discovery helpers. */\n serverUrl: URL;\n /** Fetch function configured with the transport's `requestInit`, for making auth requests. */\n fetchFn: FetchLike;\n}\n\n/**\n * Minimal interface for authenticating MCP client transports with bearer tokens.\n *\n * Transports call {@linkcode AuthProvider.token | token()} before every request\n * to obtain the current token, and {@linkcode AuthProvider.onUnauthorized | onUnauthorized()}\n * (if provided) when the server responds with 401, giving the provider a chance\n * to refresh credentials before the transport retries once.\n *\n * For simple cases (API keys, gateway-managed tokens), implement only `token()`:\n * ```typescript\n * const authProvider: AuthProvider = { token: async () => process.env.API_KEY };\n * ```\n *\n * For OAuth flows, pass an {@linkcode OAuthClientProvider} directly — transports\n * accept either shape and adapt OAuth providers automatically via {@linkcode adaptOAuthProvider}.\n */\nexport interface AuthProvider {\n /**\n * Returns the current bearer token, or `undefined` if no token is available.\n * Called before every request.\n */\n token(): Promise<string | undefined>;\n\n /**\n * Called when the server responds with 401. If provided, the transport will\n * await this, then retry the request once. If the retry also gets 401, or if\n * this method is not provided, the transport throws {@linkcode UnauthorizedError}.\n *\n * Implementations should refresh tokens, re-authenticate, etc. — whatever is\n * needed so the next `token()` call returns a valid token.\n */\n onUnauthorized?(ctx: UnauthorizedContext): Promise<void>;\n}\n\n/**\n * Context passed to the credential-persistence methods on\n * {@linkcode OAuthClientProvider} — `clientInformation` / `saveClientInformation`\n * and `tokens` / `saveTokens`. Carries the resolved authorization-server `issuer`\n * so provider implementations can key persisted credentials per authorization\n * server (RFC 6749 §2.2 — client identifiers are unique to the AS that issued\n * them). Providers that store a single credential set may ignore it.\n */\nexport interface OAuthClientInformationContext {\n /**\n * The authorization server's `issuer` identifier from its validated metadata\n * document, used as the binding key for persisted credentials.\n */\n issuer: string;\n}\n\n/**\n * SEP-2352 stamp check: returns `stored` only when its `issuer` stamp matches the\n * resolved authorization server. A stamp that names a *different* issuer reads back\n * as `undefined`, so a credential issued by one authorization server is never reused\n * at another — the flow falls through to re-registration / re-authorization exactly\n * as if nothing were stored. An unstamped value (legacy provider or pre-SEP-2352\n * storage) is returned as-is with a `console.warn`; {@linkcode auth} writes the\n * stamp back on first use so the window closes after one call.\n *\n * {@linkcode auth} stamps every value it writes via `saveTokens` / `saveClientInformation`,\n * so a provider that round-trips the stored object verbatim is protected with no extra\n * code. Providers that hold credentials for multiple authorization servers key their\n * storage on `ctx.issuer` instead.\n *\n * @param opts.canPersistStamp - When `false`, suppresses the unstamped-credential\n * warning: the caller cannot back-stamp (no `saveClientInformation`), so the\n * \"binding on first use\" claim would be false and would fire on every call.\n */\nexport function discardIfIssuerMismatch<T extends { issuer?: string }>(\n stored: T | undefined,\n issuer: string,\n opts?: { canPersistStamp?: boolean }\n): T | undefined {\n if (stored === undefined) return undefined;\n if (stored.issuer === undefined) {\n if (opts?.canPersistStamp !== false) {\n console.warn(\n `[mcp-sdk] SEP-2352: stored OAuth credential has no 'issuer' stamp (pre-upgrade storage or ` +\n `provider not round-tripping the value). SEP-2352 isolation is inactive for this read; ` +\n `ensure your provider round-trips the issuer field.`\n );\n }\n return stored;\n }\n return issuersMatch(stored.issuer, issuer) ? stored : undefined;\n}\n\n/**\n * SEP-2352 issuer-identity comparison. Tolerates a single trailing `/` difference,\n * mirroring the RFC 8414 §3.3 \"one narrow tolerance\" applied at metadata-echo\n * validation in {@linkcode discoverAuthorizationServerMetadata}: when the SDK\n * derives an issuer from `String(new URL(...))` (always slash-suffixed) and the AS\n * publishes a slash-free `metadata.issuer`, the two name the same authorization\n * server.\n */\nfunction issuersMatch(a: string, b: string): boolean {\n return a === b || (a.endsWith('/') && a.slice(0, -1) === b) || (b.endsWith('/') && b.slice(0, -1) === a);\n}\n\n/**\n * Type guard distinguishing `OAuthClientProvider` from a minimal `AuthProvider`.\n * Transports use this at construction time to classify the `authProvider` option.\n *\n * Checks for `tokens()` + `clientInformation()` — two required `OAuthClientProvider`\n * methods that a minimal `AuthProvider` `{ token: ... }` would never have.\n */\nexport function isOAuthClientProvider(provider: AuthProvider | OAuthClientProvider | undefined): provider is OAuthClientProvider {\n if (provider == null) return false;\n const p = provider as OAuthClientProvider;\n return typeof p.tokens === 'function' && typeof p.clientInformation === 'function';\n}\n\n/**\n * Standard `onUnauthorized` behavior for OAuth providers: extracts\n * `WWW-Authenticate` parameters from the 401 response and runs {@linkcode auth}.\n * Used by {@linkcode adaptOAuthProvider} to bridge `OAuthClientProvider` to `AuthProvider`.\n */\nexport async function handleOAuthUnauthorized(\n provider: OAuthClientProvider,\n ctx: UnauthorizedContext,\n extraAuthOptions?: Pick<AuthOptions, 'skipIssuerMetadataValidation'>\n): Promise<void> {\n const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(ctx.response);\n const result = await auth(provider, {\n serverUrl: ctx.serverUrl,\n resourceMetadataUrl,\n scope,\n fetchFn: ctx.fetchFn,\n ...extraAuthOptions\n });\n if (result !== 'AUTHORIZED') {\n throw new UnauthorizedError();\n }\n}\n\n/**\n * Adapts an `OAuthClientProvider` to the minimal `AuthProvider` interface that\n * transports consume. Called once at transport construction — the transport stores\n * the adapted provider for `_commonHeaders()` and 401 handling, while keeping the\n * original `OAuthClientProvider` for OAuth-specific paths (`finishAuth()`, 403 `insufficient_scope` step-up).\n *\n * SEP-2352 note: `token()` here is the per-request `Authorization: Bearer …` read for\n * the *resource server* (the MCP transport URL), not an authorization server. No OAuth\n * discovery has run at this layer, so there is no `issuer` to pass as `ctx` and no\n * {@linkcode discardIfIssuerMismatch} check to apply — the access token is sent only to\n * the resource server, never to an AS, so the SEP-2352 cross-AS isolation invariant is\n * not in scope. Providers that key storage on `ctx.issuer` MUST treat `ctx === undefined`\n * as \"return the most-recently-saved token set\" (the only consumer is the resource server\n * the token was minted for); providers that round-trip a single blob need no change.\n */\nexport function adaptOAuthProvider(\n provider: OAuthClientProvider,\n extraAuthOptions?: Pick<AuthOptions, 'skipIssuerMetadataValidation'>\n): AuthProvider {\n return {\n token: async () => {\n const tokens = await provider.tokens();\n return tokens?.access_token;\n },\n onUnauthorized: async ctx => handleOAuthUnauthorized(provider, ctx, extraAuthOptions)\n };\n}\n\n/**\n * Implements an end-to-end OAuth client to be used with one MCP server.\n *\n * This client relies upon a concept of an authorized \"session,\" the exact\n * meaning of which is application-defined. Tokens, authorization codes, and\n * code verifiers should not cross different sessions.\n *\n * Transports accept `OAuthClientProvider` directly via the `authProvider` option —\n * they adapt it to {@linkcode AuthProvider} internally via {@linkcode adaptOAuthProvider}.\n * No changes are needed to existing implementations.\n */\nexport interface OAuthClientProvider {\n /**\n * The URL to redirect the user agent to after authorization.\n * Return `undefined` for non-interactive flows that don't require user interaction\n * (e.g., `client_credentials`, `jwt-bearer`).\n */\n get redirectUrl(): string | URL | undefined;\n\n /**\n * External URL the server should use to fetch client metadata document\n */\n clientMetadataUrl?: string;\n\n /**\n * Metadata about this OAuth client.\n */\n get clientMetadata(): OAuthClientMetadata;\n\n /**\n * Returns an OAuth2 state parameter.\n */\n state?(): string | Promise<string>;\n\n /**\n * Loads information about this OAuth client, as registered already with the\n * server, or returns `undefined` if the client is not registered with the\n * server.\n *\n * @param ctx - Carries the resolved authorization-server `issuer`. Providers\n * that persist credentials per authorization server should return the entry\n * keyed by `ctx.issuer`. Providers with a single credential set may ignore it.\n */\n clientInformation(\n ctx?: OAuthClientInformationContext\n ): StoredOAuthClientInformation | undefined | Promise<StoredOAuthClientInformation | undefined>;\n\n /**\n * If implemented, this permits the OAuth client to dynamically register with\n * the server. Client information saved this way should later be read via\n * {@linkcode OAuthClientProvider.clientInformation | clientInformation()}.\n *\n * This method is not required to be implemented if client information is\n * statically known (e.g., pre-registered).\n *\n * @param ctx - Carries the resolved authorization-server `issuer`. Providers\n * that persist credentials per authorization server should store the entry\n * keyed by `ctx.issuer`.\n */\n saveClientInformation?(clientInformation: StoredOAuthClientInformation, ctx?: OAuthClientInformationContext): void | Promise<void>;\n\n /**\n * Loads any existing OAuth tokens for the current session, or returns\n * `undefined` if there are no saved tokens.\n *\n * @param ctx - Carries the resolved authorization-server `issuer`. Providers\n * that persist tokens per authorization server should return the entry\n * keyed by `ctx.issuer`. Providers with a single token set may ignore it.\n * When called with no `ctx` — the transport's per-request bearer-token\n * read — return the most-recently-saved token set; do not return\n * `undefined` for `ctx === undefined`.\n */\n tokens(ctx?: OAuthClientInformationContext): StoredOAuthTokens | undefined | Promise<StoredOAuthTokens | undefined>;\n\n /**\n * Stores new OAuth tokens for the current session, after a successful\n * authorization.\n *\n * @param ctx - Carries the resolved authorization-server `issuer`. Providers\n * that persist tokens per authorization server should store the entry\n * keyed by `ctx.issuer`.\n */\n saveTokens(tokens: StoredOAuthTokens, ctx?: OAuthClientInformationContext): void | Promise<void>;\n\n /**\n * Invoked to redirect the user agent to the given URL to begin the authorization flow.\n */\n redirectToAuthorization(authorizationUrl: URL): void | Promise<void>;\n\n /**\n * Saves a PKCE code verifier for the current session, before redirecting to\n * the authorization flow.\n */\n saveCodeVerifier(codeVerifier: string): void | Promise<void>;\n\n /**\n * Loads the PKCE code verifier for the current session, necessary to validate\n * the authorization result.\n */\n codeVerifier(): string | Promise<string>;\n\n /**\n * Adds custom client authentication to OAuth token requests.\n *\n * This optional method allows implementations to customize how client credentials\n * are included in token exchange and refresh requests. When provided, this method\n * is called instead of the default authentication logic, giving full control over\n * the authentication mechanism.\n *\n * Common use cases include:\n * - Supporting authentication methods beyond the standard OAuth 2.0 methods\n * - Adding custom headers for proprietary authentication schemes\n * - Implementing client assertion-based authentication (e.g., JWT bearer tokens)\n *\n * @param headers - The request headers (can be modified to add authentication)\n * @param params - The request body parameters (can be modified to add credentials)\n * @param url - The token endpoint URL being called\n * @param metadata - Optional OAuth metadata for the server, which may include supported authentication methods\n */\n addClientAuthentication?: AddClientAuthentication;\n\n /**\n * If defined, overrides the selection and validation of the\n * RFC 8707 Resource Indicator. If left undefined, default\n * validation behavior will be used.\n *\n * Implementations must verify the returned resource matches the MCP server.\n */\n validateResourceURL?(serverUrl: string | URL, resource?: string): Promise<URL | undefined>;\n\n /**\n * If implemented, provides a way for the client to invalidate (e.g. delete) the specified\n * credentials, in the case where the server has indicated that they are no longer valid.\n * This avoids requiring the user to intervene manually.\n */\n invalidateCredentials?(scope: 'all' | 'client' | 'tokens' | 'verifier' | 'discovery'): void | Promise<void>;\n\n /**\n * Prepares grant-specific parameters for a token request.\n *\n * This optional method allows providers to customize the token request based on\n * the grant type they support. When implemented, it returns the grant type and\n * any grant-specific parameters needed for the token exchange.\n *\n * If not implemented, the default behavior depends on the flow:\n * - For authorization code flow: uses `code`, `code_verifier`, and `redirect_uri`\n * - For `client_credentials`: detected via `grant_types` in {@linkcode OAuthClientProvider.clientMetadata | clientMetadata}\n *\n * @param scope - Optional scope to request\n * @returns Grant type and parameters, or `undefined` to use default behavior\n *\n * @example\n * // For client_credentials grant:\n * prepareTokenRequest(scope) {\n * return {\n * grantType: 'client_credentials',\n * params: scope ? { scope } : {}\n * };\n * }\n *\n * @example\n * // For authorization_code grant (default behavior):\n * async prepareTokenRequest() {\n * return {\n * grantType: 'authorization_code',\n * params: {\n * code: this.authorizationCode,\n * code_verifier: await this.codeVerifier(),\n * redirect_uri: String(this.redirectUrl)\n * }\n * };\n * }\n */\n prepareTokenRequest?(scope?: string): URLSearchParams | Promise<URLSearchParams | undefined> | undefined;\n\n /**\n * Saves the resolved authorization-server **issuer**. Called after a successful\n * token exchange (timing changed in v2: was post-discovery, now post-`saveTokens`).\n *\n * @deprecated Superseded by the `issuer` stamp on stored tokens / client credentials\n * (SEP-2352). {@linkcode auth} still **writes** this for back-compat with providers\n * that read it (e.g. Cross-App Access), but the SDK never reads it. Prefer reading\n * the `issuer` field on the value passed to {@linkcode saveTokens} /\n * {@linkcode saveClientInformation}, or the `ctx.issuer` argument.\n */\n saveAuthorizationServerUrl?(authorizationServerUrl: string): void | Promise<void>;\n\n /**\n * Returns the previously saved authorization server URL, if available.\n *\n * @deprecated Superseded by the `issuer` stamp on stored tokens / client credentials\n * (SEP-2352). The SDK never reads this method; it remains for provider implementations\n * that consume the value internally (e.g. Cross-App Access).\n */\n authorizationServerUrl?(): string | undefined | Promise<string | undefined>;\n\n /**\n * Saves the resource URL after RFC 9728 discovery.\n * This method is called by {@linkcode auth} after successful discovery of the\n * resource metadata.\n *\n * Providers implementing Cross-App Access or other flows that need access to\n * the discovered resource URL should implement this method.\n *\n * @param resourceUrl - The resource URL discovered via RFC 9728\n */\n saveResourceUrl?(resourceUrl: string): void | Promise<void>;\n\n /**\n * Returns the previously saved resource URL, if available.\n *\n * Providers implementing Cross-App Access can use this to access the\n * resource URL discovered during the OAuth flow.\n *\n * @returns The resource URL, or `undefined` if not available\n */\n resourceUrl?(): string | undefined | Promise<string | undefined>;\n\n /**\n * Saves the OAuth discovery state after RFC 9728 and authorization server metadata\n * discovery. Providers can persist this state to avoid redundant discovery requests\n * on subsequent {@linkcode auth} calls.\n *\n * This state can also be provided out-of-band (e.g., from a previous session or\n * external configuration) to bootstrap the OAuth flow without discovery.\n *\n * Called by {@linkcode auth} after successful discovery.\n *\n * MUST persist with the same durability as `codeVerifier` (survives the redirect\n * round-trip).\n */\n saveDiscoveryState?(state: OAuthDiscoveryState): void | Promise<void>;\n\n /**\n * Returns previously saved discovery state, or `undefined` if none is cached.\n *\n * When available, {@linkcode auth} restores the discovery state (authorization server\n * URL, resource metadata, etc.) instead of performing RFC 9728 discovery, reducing\n * latency on subsequent calls.\n *\n * Hosts should call {@linkcode invalidateCredentials} with scope `'discovery'`\n * on repeated 401s so a changed `authorization_servers` list is picked up; the\n * SDK does not invoke that scope itself.\n *\n * MUST persist with the same durability as `codeVerifier` (survives the redirect\n * round-trip).\n */\n discoveryState?(): OAuthDiscoveryState | undefined | Promise<OAuthDiscoveryState | undefined>;\n}\n\n/**\n * Discovery state that can be persisted across sessions by an {@linkcode OAuthClientProvider}.\n *\n * Contains the results of RFC 9728 protected resource metadata discovery and\n * authorization server metadata discovery. Persisting this state avoids\n * redundant discovery HTTP requests on subsequent {@linkcode auth} calls.\n */\n// TODO: Consider adding `authorizationServerMetadataUrl` to capture the exact well-known URL\n// at which authorization server metadata was discovered. This would require\n// `discoverAuthorizationServerMetadata()` to return the successful discovery URL.\nexport interface OAuthDiscoveryState extends OAuthServerInfo {\n /** The URL at which the protected resource metadata was found, if available. */\n resourceMetadataUrl?: string;\n}\n\nexport type AuthResult = 'AUTHORIZED' | 'REDIRECT';\n\nexport class UnauthorizedError extends Error {\n static {\n Object.defineProperty(this, 'mcpBrand', { value: 'mcp.UnauthorizedError' });\n }\n\n static override [Symbol.hasInstance](value: unknown): boolean {\n return brandedHasInstance(this, value);\n }\n\n /**\n * Brand-based type guard: equivalent to `value instanceof this`, as an\n * explicit static predicate (the axios/AWS-SDK `isInstance` style). Reads\n * the caller's own brand via `this`, so every branded subclass gets a\n * correctly-scoped guard by inheritance. Must be invoked on the class —\n * in callback position write `v => SdkError.isInstance(v)`, not\n * `.filter(SdkError.isInstance)` (detached calls throw rather than\n * silently matching nothing).\n */\n static isInstance<T extends abstract new (...args: never[]) => unknown>(this: T, value: unknown): value is InstanceType<T> {\n if (typeof this !== 'function') {\n throw new TypeError(\n 'isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`'\n );\n }\n return brandedHasInstance(this, value);\n }\n\n constructor(message?: string) {\n super(message ?? 'Unauthorized');\n this.name = 'UnauthorizedError';\n stampErrorBrands(this, new.target);\n }\n}\n\n/**\n * Validates the `iss` parameter from an authorization response against the\n * issuer recorded from the authorization server's validated metadata, per\n * RFC 9207 §2.4 and the MCP specification's four-row decision table.\n *\n * | `issParameterSupported` | `iss` | Action |\n * | ----------------------- | ------- | ------------------------------------------------ |\n * | `true` | present | compare; throw {@linkcode IssuerMismatchError} on mismatch |\n * | `true` | absent | throw {@linkcode IssuerMismatchError} |\n * | `false` | present | compare; throw {@linkcode IssuerMismatchError} on mismatch |\n * | `false` | absent | proceed (no-op) |\n *\n * Comparison is **simple string equality** (RFC 3986 §6.2.1). Scheme/host case\n * folding, default-port elision, trailing-slash, and percent-encoding\n * normalization are explicitly **not** applied — any difference is a mismatch.\n *\n * When `expectedIssuer` is `undefined` (no validated metadata document exists),\n * the check has no authentic baseline and degenerates to a no-op.\n *\n * @throws {IssuerMismatchError} with `kind: 'authorization_response'`\n */\n/**\n * Reads RFC 9207's `authorization_response_iss_parameter_supported` from\n * authorization-server metadata. Only a literal `true` counts as advertised;\n * absent, `false`, or a non-boolean wire value (coerced to `undefined` by the\n * schema) means not advertised.\n */\nfunction isIssParameterSupported(metadata: AuthorizationServerMetadata | undefined): boolean {\n return metadata?.authorization_response_iss_parameter_supported === true;\n}\n\nexport function validateAuthorizationResponseIssuer({\n iss,\n expectedIssuer,\n issParameterSupported\n}: {\n /** The form-urldecoded `iss` query parameter from the authorization callback, or `undefined` if absent. */\n iss: string | undefined;\n /** The `issuer` value from the authorization server's validated metadata document. */\n expectedIssuer: string | undefined;\n /** Whether the metadata advertised `authorization_response_iss_parameter_supported: true`. */\n issParameterSupported: boolean;\n}): void {\n if (expectedIssuer === undefined) {\n // No validated metadata document → no recorded issuer → no comparison (table row 4).\n return;\n }\n if (iss === undefined) {\n if (issParameterSupported) {\n // Row 2: AS advertised that it always sends `iss`; absence is a stripped-parameter attack indicator.\n throw new IssuerMismatchError('authorization_response', expectedIssuer, undefined);\n }\n // Row 4: not advertised, not present → proceed.\n return;\n }\n // Rows 1 & 3: present → compare with simple string comparison only.\n if (iss !== expectedIssuer) {\n throw new IssuerMismatchError('authorization_response', expectedIssuer, iss);\n }\n}\n\n/**\n * Computes the union of one or more OAuth `scope` strings.\n *\n * Each argument is a space-delimited scope string per RFC 6749 §3.3, or\n * `undefined`. The result is a single space-delimited string containing each\n * distinct scope token exactly once, in first-seen order, or `undefined` if\n * every input is empty/undefined.\n *\n * No hierarchical deduplication is performed: a union may contain semantically\n * redundant entries (e.g., a broad scope alongside a narrower one it implies).\n * Authorization servers normalize such redundancy during token issuance; the\n * spec's step-up flow does not require clients to.\n *\n * Used by the transport's `403 insufficient_scope` step-up path to accumulate\n * previously-requested scopes with newly-challenged scopes so re-authorization\n * does not lose previously-granted permissions.\n */\nexport function computeScopeUnion(...scopes: ReadonlyArray<string | undefined>): string | undefined {\n const seen = new Set<string>();\n for (const scope of scopes) {\n if (!scope) continue;\n for (const token of scope.split(/\\s+/)) {\n if (token) seen.add(token);\n }\n }\n return seen.size > 0 ? [...seen].join(' ') : undefined;\n}\n\n/**\n * Whether `union` contains at least one scope token not present in `current`.\n * Both arguments are space-delimited scope strings per RFC 6749 §3.3.\n *\n * Used to gate the step-up refresh bypass: when the union of previously-requested\n * and newly-challenged scopes is a strict superset of the current token's\n * granted scope, refreshing cannot widen the grant (RFC 6749 §6), so the\n * transport must force a fresh authorization request instead. When the current\n * token already covers the union, refresh remains valid.\n *\n * An undefined or empty `current` is treated as the empty set, so any non-empty\n * `union` is a strict superset. Note that per RFC 6749 §3.3 an authorization\n * server MAY omit the token's `scope` field when it equals the requested scope;\n * this helper is conservative and treats an absent token `scope` as empty, so\n * step-up always forces a fresh authorization request in that case rather than\n * risking a refresh that silently drops the widened scope.\n */\nexport function isStrictScopeSuperset(union: string | undefined, current: string | undefined): boolean {\n if (!union) return false;\n const currentSet = new Set((current ?? '').split(/\\s+/).filter(Boolean));\n for (const token of union.split(/\\s+/)) {\n if (token && !currentSet.has(token)) return true;\n }\n return false;\n}\n\n/**\n * Shared `finishAuth` resolver for the `(code, iss?)` and `(URLSearchParams)` overloads.\n *\n * For the `URLSearchParams` form, only `iss` and `code` are read up front. When a `code` is\n * present the returned values flow into {@linkcode auth}, which runs\n * {@linkcode validateAuthorizationResponseIssuer} against freshly-discovered metadata before\n * the code is redeemed — so on mismatch the thrown {@linkcode IssuerMismatchError} carries no\n * `error`/`error_description`/`error_uri` text from the callback (those are attacker-controlled\n * in a mix-up). When no `code` is present (an error-shaped callback), `iss` is validated here\n * against the provider's recorded discovery state — or, when the provider does not implement\n * `discoveryState`, against freshly-discovered metadata mirroring what {@linkcode auth} does on\n * the code-present path — **before** the callback's error parameters are read; only after that\n * passes are they surfaced as an {@linkcode OAuthError}. When no issuer baseline can be\n * obtained either way, a generic {@linkcode UnauthorizedError} is thrown without surfacing the\n * callback's `error`/`error_description`/`error_uri`.\n *\n * @internal Exported for the transport `finishAuth` overloads; not part of the public barrel.\n */\nexport async function resolveAuthorizationCallbackParams(\n codeOrParams: string | URLSearchParams,\n iss: string | undefined,\n provider: OAuthClientProvider,\n serverUrl: string | URL,\n opts?: { fetchFn?: FetchLike; resourceMetadataUrl?: URL }\n): Promise<{ authorizationCode: string; iss: string | undefined }> {\n if (typeof codeOrParams === 'string') {\n return { authorizationCode: codeOrParams, iss };\n }\n const issParam = codeOrParams.get('iss') ?? undefined;\n const code = codeOrParams.get('code');\n if (code) {\n return { authorizationCode: code, iss: issParam };\n }\n // No code → error response. Gate the (potentially attacker-supplied) error params on the\n // issuer first. Prefer the provider's recorded discovery state; when absent, mirror auth()'s\n // code-present path and run a fresh discovery so the iss gate has an authentic baseline.\n const discoveryState = await provider.discoveryState?.();\n let metadata = discoveryState?.authorizationServerMetadata;\n if (!metadata) {\n try {\n const serverInfo = await discoverOAuthServerInfo(serverUrl, opts);\n metadata = serverInfo.authorizationServerMetadata;\n } catch {\n metadata = undefined;\n }\n }\n if (!metadata) {\n // No authentic baseline → cannot prove the error params came from our AS. Do NOT surface\n // attacker-controllable `error`/`error_description`/`error_uri` here.\n throw new UnauthorizedError('Authorization callback failed and the issuer could not be verified');\n }\n validateAuthorizationResponseIssuer({\n iss: issParam,\n expectedIssuer: metadata.issuer,\n issParameterSupported: isIssParameterSupported(metadata)\n });\n const error = codeOrParams.get('error');\n if (error) {\n throw new OAuthError(error, codeOrParams.get('error_description') ?? error, codeOrParams.get('error_uri') ?? undefined);\n }\n throw new UnauthorizedError('Authorization callback contained neither `code` nor `error`');\n}\n\nexport type ClientAuthMethod = 'client_secret_basic' | 'client_secret_post' | 'none';\n\nfunction isClientAuthMethod(method: string): method is ClientAuthMethod {\n return ['client_secret_basic', 'client_secret_post', 'none'].includes(method);\n}\n\nconst AUTHORIZATION_CODE_RESPONSE_TYPE = 'code';\nconst AUTHORIZATION_CODE_CHALLENGE_METHOD = 'S256';\n\n/**\n * Determines the best client authentication method to use based on server support and client configuration.\n *\n * Priority order (highest to lowest):\n * 1. `client_secret_basic` (if client secret is available)\n * 2. `client_secret_post` (if client secret is available)\n * 3. `none` (for public clients)\n *\n * @param clientInformation - OAuth client information containing credentials\n * @param supportedMethods - Authentication methods supported by the authorization server\n * @returns The selected authentication method\n */\nexport function selectClientAuthMethod(clientInformation: OAuthClientInformationMixed, supportedMethods: string[]): ClientAuthMethod {\n const hasClientSecret = clientInformation.client_secret !== undefined;\n\n // Prefer the method returned by the server during client registration, if valid.\n // When server metadata is present we also require the method to be listed as supported;\n // when supportedMethods is empty (metadata omitted the field) the DCR hint stands alone.\n if (\n 'token_endpoint_auth_method' in clientInformation &&\n clientInformation.token_endpoint_auth_method &&\n isClientAuthMethod(clientInformation.token_endpoint_auth_method) &&\n (supportedMethods.length === 0 || supportedMethods.includes(clientInformation.token_endpoint_auth_method))\n ) {\n return clientInformation.token_endpoint_auth_method;\n }\n\n // If server metadata omits token_endpoint_auth_methods_supported, RFC 8414 §2 says the\n // default is client_secret_basic. RFC 6749 §2.3.1 also requires servers to support HTTP\n // Basic authentication for clients with a secret, making it the safest default.\n if (supportedMethods.length === 0) {\n return hasClientSecret ? 'client_secret_basic' : 'none';\n }\n\n // Try methods in priority order (most secure first)\n if (hasClientSecret && supportedMethods.includes('client_secret_basic')) {\n return 'client_secret_basic';\n }\n\n if (hasClientSecret && supportedMethods.includes('client_secret_post')) {\n return 'client_secret_post';\n }\n\n if (supportedMethods.includes('none')) {\n return 'none';\n }\n\n // Fallback: use what we have\n return hasClientSecret ? 'client_secret_post' : 'none';\n}\n\n/**\n * Applies client authentication to the request based on the specified method.\n *\n * Implements OAuth 2.1 client authentication methods:\n * - `client_secret_basic`: HTTP Basic authentication (RFC 6749 Section 2.3.1)\n * - `client_secret_post`: Credentials in request body (RFC 6749 Section 2.3.1)\n * - `none`: Public client authentication (RFC 6749 Section 2.1)\n *\n * @param method - The authentication method to use\n * @param clientInformation - OAuth client information containing credentials\n * @param headers - HTTP headers object to modify\n * @param params - URL search parameters to modify\n * @throws {Error} When required credentials are missing\n */\nexport function applyClientAuthentication(\n method: ClientAuthMethod,\n clientInformation: OAuthClientInformation,\n headers: Headers,\n params: URLSearchParams\n): void {\n const { client_id, client_secret } = clientInformation;\n\n switch (method) {\n case 'client_secret_basic': {\n applyBasicAuth(client_id, client_secret, headers);\n return;\n }\n case 'client_secret_post': {\n applyPostAuth(client_id, client_secret, params);\n return;\n }\n case 'none': {\n applyPublicAuth(client_id, params);\n return;\n }\n default: {\n throw new Error(`Unsupported client authentication method: ${method}`);\n }\n }\n}\n\n/**\n * Applies HTTP Basic authentication (RFC 6749 Section 2.3.1)\n */\nexport function applyBasicAuth(clientId: string, clientSecret: string | undefined, headers: Headers): void {\n if (!clientSecret) {\n throw new Error('client_secret_basic authentication requires a client_secret');\n }\n\n const credentials = btoa(`${clientId}:${clientSecret}`);\n headers.set('Authorization', `Basic ${credentials}`);\n}\n\n/**\n * Applies POST body authentication (RFC 6749 Section 2.3.1)\n */\nexport function applyPostAuth(clientId: string, clientSecret: string | undefined, params: URLSearchParams): void {\n params.set('client_id', clientId);\n if (clientSecret) {\n params.set('client_secret', clientSecret);\n }\n}\n\n/**\n * Applies public client authentication (RFC 6749 Section 2.1)\n */\nexport function applyPublicAuth(clientId: string, params: URLSearchParams): void {\n params.set('client_id', clientId);\n}\n\n/** Loopback hosts exempt from the in-transit `https:` requirement (RFC 8252 §7.3). */\nfunction isLoopbackHost(hostname: string): boolean {\n return hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '[::1]' || hostname === '::1';\n}\n\n/**\n * SEP-2207: refuse to send credentials to a non-TLS, non-loopback token endpoint.\n * Throws {@linkcode InsecureTokenEndpointError}. Loopback hosts are exempt.\n */\nexport function assertSecureTokenEndpoint(tokenEndpoint: string | URL): URL {\n const url = new URL(String(tokenEndpoint));\n if (url.protocol !== 'https:' && !isLoopbackHost(url.hostname)) {\n throw new InsecureTokenEndpointError(url.href);\n }\n return url;\n}\n\n/**\n * Derives an OIDC `application_type` from a client's registered redirect URIs\n * when the consumer has not set one explicitly (SEP-837). Loopback hosts and\n * non-`http(s)` custom URI schemes indicate a native application (RFC 8252);\n * everything else is treated as a web application. The result is a heuristic\n * default — callers that know better should set `clientMetadata.application_type`\n * themselves, which {@linkcode resolveClientMetadata} never overwrites.\n *\n * A mixed redirect set (for example a public `https:` URI alongside a loopback\n * URI) is inherently ambiguous under OIDC DCR §2 — neither value satisfies the\n * AS for both URIs — so consumers with mixed sets should set `application_type`\n * explicitly rather than relying on this heuristic.\n */\nfunction deriveApplicationType(redirectUris: readonly string[] | undefined): 'native' | 'web' {\n for (const raw of redirectUris ?? []) {\n let url: URL;\n try {\n url = new URL(raw);\n } catch {\n continue;\n }\n if (url.protocol !== 'http:' && url.protocol !== 'https:') return 'native';\n if (isLoopbackHost(url.hostname)) return 'native';\n }\n return 'web';\n}\n\n/**\n * Reads {@linkcode OAuthClientProvider.clientMetadata | clientMetadata} from the\n * provider and fills the SEP-837 / SEP-2207 defaults the SDK relies on, so\n * {@linkcode registerClient} sees a consistent, fully-populated document.\n *\n * - `grant_types` defaults to `['authorization_code', 'refresh_token']` for\n * interactive providers (those with a {@linkcode OAuthClientProvider.redirectUrl | redirectUrl})\n * so authorization servers that gate refresh-token issuance on the registered\n * grant types issue one (SEP-2207). Non-interactive providers (no\n * `redirectUrl`) get no `grant_types` default. This default applies to the\n * Dynamic Client Registration body only — it does **not** drive\n * {@linkcode determineScope}'s `offline_access` augmentation.\n * - `application_type` defaults from `redirect_uris`: loopback redirect hosts\n * and custom URI schemes → `'native'`, otherwise `'web'` (SEP-837 / RFC 8252).\n *\n * A field the consumer set explicitly is **never** overwritten. {@linkcode auth}\n * calls this once at the top of the flow; direct callers of\n * {@linkcode registerClient} that want the same defaults should pass the result\n * of this function as `clientMetadata`.\n */\nexport function resolveClientMetadata(provider: Pick<OAuthClientProvider, 'clientMetadata' | 'redirectUrl'>): OAuthClientMetadata {\n const clientMetadata = provider.clientMetadata;\n return {\n ...clientMetadata,\n grant_types:\n clientMetadata.grant_types ?? (provider.redirectUrl === undefined ? undefined : ['authorization_code', 'refresh_token']),\n application_type: clientMetadata.application_type ?? deriveApplicationType(clientMetadata.redirect_uris)\n };\n}\n\n/**\n * Parses an OAuth error response from a string or Response object.\n *\n * If the input is a standard OAuth2.0 error response, it will be parsed according to the spec\n * and an {@linkcode OAuthError} will be returned with the appropriate error code.\n * If parsing fails, it falls back to a generic {@linkcode OAuthErrorCode.ServerError | ServerError} that includes\n * the response status (if available) and original content.\n *\n * @param input - A Response object or string containing the error response\n * @returns A Promise that resolves to an {@linkcode OAuthError} instance\n */\nexport async function parseErrorResponse(input: Response | string): Promise<OAuthError> {\n const statusCode = input instanceof Response ? input.status : undefined;\n const body = input instanceof Response ? await input.text() : input;\n\n try {\n const result = OAuthErrorResponseSchema.parse(JSON.parse(body));\n return OAuthError.fromResponse(result);\n } catch (error) {\n // Not a valid OAuth error response, but try to inform the user of the raw data anyway\n const errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ''}Invalid OAuth error response: ${error}. Raw body: ${body}`;\n return new OAuthError(OAuthErrorCode.ServerError, errorMessage);\n }\n}\n\n/**\n * Options for {@linkcode auth}. The full OAuth flow orchestrator's input.\n */\nexport interface AuthOptions {\n /** The MCP server URL — the protected resource the flow authorizes against. */\n serverUrl: string | URL;\n /**\n * The authorization code returned by the authorization server on the redirect\n * callback. When set, {@linkcode auth} exchanges it for tokens; when unset,\n * {@linkcode auth} runs discovery and either refreshes or initiates redirect.\n */\n authorizationCode?: string;\n /**\n * The form-urldecoded `iss` query parameter from the authorization callback,\n * if present. Passed through to RFC 9207 §2.4 issuer validation alongside\n * `authorizationCode`. Validated against the recorded issuer per RFC 9207\n * §2.4 before the code is redeemed — see\n * {@linkcode validateAuthorizationResponseIssuer} and the migration guide's\n * *Authorization-server mix-up defense* section.\n */\n iss?: string;\n /** Scope to request; computed by Scope Selection Strategy when omitted. */\n scope?: string;\n /** Explicit `resource_metadata` URL from a `WWW-Authenticate` challenge. */\n resourceMetadataUrl?: URL;\n /** Custom `fetch` implementation. */\n fetchFn?: FetchLike;\n /**\n * Opt-out for the RFC 8414 §3.3 issuer-echo check during authorization\n * server discovery. Disabling it is **security-weakening** and intended only\n * for authorization servers known to publish a mismatched `issuer`.\n *\n * @default false\n */\n skipIssuerMetadataValidation?: boolean;\n /**\n * When `true`, {@linkcode auth} skips the refresh-token branch even when a\n * `refresh_token` is available, and proceeds directly to a fresh\n * authorization request ({@linkcode startAuthorization}).\n *\n * Set by the transport's `403 insufficient_scope` step-up path when the\n * required scope is a strict superset of the current token's granted scope:\n * the refresh grant cannot widen scope (RFC 6749 §6), so refreshing would\n * silently drop the new scope and the next request would 403 again. Forcing\n * a fresh authorization request ensures the widened scope reaches the\n * authorization server.\n *\n * Hosts driving step-up themselves (with `onInsufficientScope: 'throw'`)\n * should set this when {@linkcode isStrictScopeSuperset} of the union over\n * the current token's `scope` is `true`.\n *\n * @default false\n */\n forceReauthorization?: boolean;\n}\n\n/**\n * Orchestrates the full auth flow with a server.\n *\n * This can be used as a single entry point for all authorization functionality,\n * instead of linking together the other lower-level functions in this module.\n */\nexport async function auth(provider: OAuthClientProvider, options: AuthOptions): Promise<AuthResult> {\n try {\n return await authInternal(provider, options);\n } catch (error) {\n // Handle recoverable error types by invalidating credentials and retrying\n if (error instanceof OAuthError) {\n if (error.code === OAuthErrorCode.InvalidClient || error.code === OAuthErrorCode.UnauthorizedClient) {\n // Not 'all' — preserve discoveryState so the callback-leg gate on retry doesn't\n // fire a false 'discoveryState was not available on the callback leg' AuthorizationServerMismatchError that masks the\n // real invalid_client.\n await provider.invalidateCredentials?.('client');\n await provider.invalidateCredentials?.('tokens');\n return await authInternal(provider, options);\n } else if (error.code === OAuthErrorCode.InvalidGrant) {\n await provider.invalidateCredentials?.('tokens');\n return await authInternal(provider, options);\n }\n }\n\n // Throw otherwise\n throw error;\n }\n}\n\n/**\n * Selects scopes per the MCP spec and augment for refresh token support.\n */\nexport function determineScope(options: {\n requestedScope?: string;\n resourceMetadata?: OAuthProtectedResourceMetadata;\n authServerMetadata?: AuthorizationServerMetadata;\n clientMetadata: OAuthClientMetadata;\n}): string | undefined {\n const { requestedScope, resourceMetadata, authServerMetadata, clientMetadata } = options;\n\n // Scope selection priority (MCP spec):\n // 1. WWW-Authenticate header scope\n // 2. PRM scopes_supported\n // 3. clientMetadata.scope (SDK fallback)\n // 4. Omit scope parameter\n let effectiveScope = requestedScope || resourceMetadata?.scopes_supported?.join(' ') || clientMetadata.scope;\n\n // SEP-2207: Append offline_access when the AS advertises it and the client\n // supports the refresh_token grant. Gated on consumer-supplied grant_types;\n // SDK DCR default intentionally NOT applied here so statically-registered/CIMD\n // clients are not pushed into offline_access + prompt=consent.\n if (\n effectiveScope &&\n authServerMetadata?.scopes_supported?.includes('offline_access') &&\n !effectiveScope.split(' ').includes('offline_access') &&\n clientMetadata.grant_types?.includes('refresh_token')\n ) {\n effectiveScope = `${effectiveScope} offline_access`;\n }\n\n return effectiveScope;\n}\n\nasync function authInternal(\n provider: OAuthClientProvider,\n {\n serverUrl,\n authorizationCode,\n iss,\n scope,\n resourceMetadataUrl,\n fetchFn,\n skipIssuerMetadataValidation,\n forceReauthorization\n }: AuthOptions\n): Promise<AuthResult> {\n // SEP-837 / SEP-2207: resolve spec defaults for the DCR body. determineScope()\n // intentionally reads the raw provider.clientMetadata instead.\n const clientMetadata = resolveClientMetadata(provider);\n\n // Check if the provider has cached discovery state to skip discovery\n const cachedState = await provider.discoveryState?.();\n\n let resourceMetadata: OAuthProtectedResourceMetadata | undefined;\n let authorizationServerUrl: string | URL;\n let metadata: AuthorizationServerMetadata | undefined;\n let freshDiscoveryState: OAuthDiscoveryState | undefined;\n\n // If resourceMetadataUrl is not provided, try to load it from cached state\n // This handles browser redirects where the URL was saved before navigation\n let effectiveResourceMetadataUrl = resourceMetadataUrl;\n if (!effectiveResourceMetadataUrl && cachedState?.resourceMetadataUrl) {\n effectiveResourceMetadataUrl = new URL(cachedState.resourceMetadataUrl);\n }\n\n if (cachedState?.authorizationServerUrl) {\n // Restore discovery state from cache\n authorizationServerUrl = cachedState.authorizationServerUrl;\n resourceMetadata = cachedState.resourceMetadata;\n metadata =\n cachedState.authorizationServerMetadata ??\n (await discoverAuthorizationServerMetadata(authorizationServerUrl, {\n fetchFn,\n skipIssuerValidation: skipIssuerMetadataValidation\n }));\n\n // If resource metadata wasn't cached, try to fetch it for selectResourceURL\n if (!resourceMetadata) {\n try {\n resourceMetadata = await discoverOAuthProtectedResourceMetadata(\n serverUrl,\n { resourceMetadataUrl: effectiveResourceMetadataUrl },\n fetchFn\n );\n } catch (error) {\n // Network failures (DNS, connection refused) surface as TypeError — propagate\n // those rather than masking a transient reachability problem.\n if (error instanceof TypeError) {\n throw error;\n }\n // RFC 9728 not available — selectResourceURL will handle undefined\n }\n }\n\n // Re-save if we enriched the cached state with missing metadata\n if (metadata !== cachedState.authorizationServerMetadata || resourceMetadata !== cachedState.resourceMetadata) {\n await provider.saveDiscoveryState?.({\n authorizationServerUrl: String(authorizationServerUrl),\n resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),\n resourceMetadata,\n authorizationServerMetadata: metadata\n });\n }\n } else {\n // Full discovery via RFC 9728\n const serverInfo = await discoverOAuthServerInfo(serverUrl, {\n resourceMetadataUrl: effectiveResourceMetadataUrl,\n fetchFn,\n skipIssuerMetadataValidation\n });\n authorizationServerUrl = serverInfo.authorizationServerUrl;\n metadata = serverInfo.authorizationServerMetadata;\n resourceMetadata = serverInfo.resourceMetadata;\n\n // Captured now, persisted only after the SEP-2352 callback-leg gate below — so a\n // gate throw cannot leave a freshly resolved (potentially PRM-poisoned) AS recorded\n // for the retry to read back as `recordedIssuer`.\n // TODO: resourceMetadataUrl is only populated when explicitly provided via options\n // or loaded from cached state. The URL derived internally by\n // discoverOAuthProtectedResourceMetadata() is not captured back here.\n freshDiscoveryState = {\n authorizationServerUrl: String(authorizationServerUrl),\n resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),\n resourceMetadata,\n authorizationServerMetadata: metadata\n };\n }\n\n // SEP-2352: the canonical authorization-server identity for this flow. `metadata.issuer`\n // is RFC 8414 §3.3-validated to equal the discovery URL; when no metadata document was\n // found (legacy fallback) the discovery URL itself is the only identifier available.\n const issuer = metadata?.issuer ?? String(authorizationServerUrl);\n const infoCtx: OAuthClientInformationContext = { issuer };\n\n // Deprecated write-only hook, kept for providers (e.g. Cross-App Access) that read it\n // internally. The SDK never reads `authorizationServerUrl()`.\n await provider.saveAuthorizationServerUrl?.(issuer);\n\n // SEP-2352 callback-leg gate. Stored credentials are protected structurally by the\n // issuer stamp, but the in-flight `authorization_code` + PKCE `code_verifier` are not\n // stored — they are bound to the AS the redirect targeted, recorded in `discoveryState()`.\n // Fail-closed: a provider that implements saveDiscoveryState but returned no discovery\n // state on the callback leg (e.g. not persisted alongside codeVerifier across page navigation) MUST NOT\n // proceed — fresh discovery may have resolved a different AS than the one the user\n // approved at /authorize, and the clientInformation stamp alone does not protect a keyed\n // multi-AS provider here. Providers that do not implement saveDiscoveryState at all keep\n // the (legacy) warn-and-proceed behavior.\n if (authorizationCode !== undefined) {\n const recordedIssuer = cachedState?.authorizationServerMetadata?.issuer ?? cachedState?.authorizationServerUrl;\n if (recordedIssuer === undefined) {\n if (provider.saveDiscoveryState !== undefined) {\n throw new AuthorizationServerMismatchError(\n 'discoveryState was not available on the callback leg; ensure your provider persists discoveryState alongside codeVerifier',\n issuer\n );\n }\n console.warn(\n '[mcp-sdk] OAuthClientProvider does not implement saveDiscoveryState()/discoveryState(); ' +\n 'the SEP-2352 callback-leg authorization-server binding cannot be checked. ' +\n 'Implement discoveryState (persist alongside codeVerifier) — see docs/migration/upgrade-to-v2.md §SEP-2352.'\n );\n } else if (!issuersMatch(recordedIssuer, issuer)) {\n throw new AuthorizationServerMismatchError(recordedIssuer, issuer);\n }\n }\n\n if (freshDiscoveryState) {\n await provider.saveDiscoveryState?.(freshDiscoveryState);\n }\n\n const resource: URL | undefined = await selectResourceURL(serverUrl, provider, resourceMetadata);\n\n // Save resource URL for providers that need it (e.g., CrossAppAccessProvider)\n if (resource) {\n await provider.saveResourceUrl?.(String(resource));\n }\n\n // Scope selection used consistently for DCR and the authorization request.\n const resolvedScope = determineScope({\n requestedScope: scope,\n resourceMetadata,\n authServerMetadata: metadata,\n clientMetadata: provider.clientMetadata\n });\n\n // Handle client registration if needed. SEP-2352: a stored credential whose `issuer`\n // stamp names a different authorization server reads back as `undefined`, so the flow\n // re-registers exactly as if nothing were stored.\n const rawClientInfo = await Promise.resolve(provider.clientInformation(infoCtx));\n let clientInformation = discardIfIssuerMismatch(rawClientInfo, issuer, {\n canPersistStamp: provider.saveClientInformation !== undefined\n });\n if (clientInformation === undefined && rawClientInfo?.issuer && provider.saveClientInformation === undefined) {\n // Static-credential provider (no DCR) whose `expectedIssuer` stamp names a different\n // AS — surface the typed error with both issuers rather than the generic\n // \"client information must be saveable for dynamic registration\" fallback.\n throw new AuthorizationServerMismatchError(rawClientInfo.issuer, issuer);\n }\n if (clientInformation && clientInformation.issuer === undefined) {\n // SEP-2352 back-stamp: legacy (pre-SEP-2352) storage returned an unstamped value.\n // Bind it to the first AS resolved after upgrade so subsequent calls have a real\n // stamp to compare against — closes the otherwise-permanent unstamped window.\n clientInformation = { ...clientInformation, issuer };\n await provider.saveClientInformation?.(clientInformation, infoCtx);\n }\n if (!clientInformation) {\n if (authorizationCode !== undefined) {\n throw new Error('Existing OAuth client information is required when exchanging an authorization code');\n }\n\n const supportsUrlBasedClientId = metadata?.client_id_metadata_document_supported === true;\n const clientMetadataUrl = provider.clientMetadataUrl;\n\n if (clientMetadataUrl && !isHttpsUrl(clientMetadataUrl)) {\n throw new OAuthError(\n OAuthErrorCode.InvalidClientMetadata,\n `clientMetadataUrl must be a valid HTTPS URL with a non-root pathname, got: ${clientMetadataUrl}`\n );\n }\n\n const shouldUseUrlBasedClientId = supportsUrlBasedClientId && clientMetadataUrl;\n\n if (shouldUseUrlBasedClientId) {\n // SEP-991: URL-based Client IDs\n clientInformation = { client_id: clientMetadataUrl, issuer };\n await provider.saveClientInformation?.(clientInformation, infoCtx);\n } else {\n // Fallback to dynamic registration\n if (!provider.saveClientInformation) {\n throw new Error('OAuth client information must be saveable for dynamic registration');\n }\n\n const fullInformation = await registerClient(authorizationServerUrl, {\n metadata,\n clientMetadata,\n scope: resolvedScope,\n fetchFn\n });\n\n clientInformation = { ...fullInformation, issuer };\n await provider.saveClientInformation(clientInformation, infoCtx);\n }\n }\n\n // Non-interactive flows (e.g., client_credentials, jwt-bearer) don't need a redirect URL\n const nonInteractiveFlow = !provider.redirectUrl;\n\n // Exchange authorization code for tokens, or fetch tokens directly for non-interactive flows\n if (authorizationCode !== undefined || nonInteractiveFlow) {\n // RFC 9207: validate the callback `iss` against the recorded issuer before the\n // authorization code is sent to any token endpoint. Non-interactive flows have no\n // authorization response, so the gate is keyed on `authorizationCode`.\n if (authorizationCode !== undefined) {\n validateAuthorizationResponseIssuer({\n iss,\n expectedIssuer: metadata?.issuer,\n issParameterSupported: isIssParameterSupported(metadata)\n });\n }\n\n const tokens = await fetchToken(provider, authorizationServerUrl, {\n metadata,\n resource,\n authorizationCode,\n iss,\n scope: resolvedScope,\n fetchFn\n });\n\n await provider.saveTokens({ ...tokens, issuer }, infoCtx);\n return 'AUTHORIZED';\n }\n\n // SEP-2352: a refresh_token stamped for a different authorization server reads back\n // as `undefined`, so it is never POSTed to this AS's token endpoint.\n let tokens = discardIfIssuerMismatch(await provider.tokens(infoCtx), issuer);\n if (tokens && tokens.issuer === undefined) {\n // SEP-2352 back-stamp: bind a legacy unstamped token set to the first-resolved AS\n // so the stamp check is effective from the next call onward.\n tokens = { ...tokens, issuer };\n await provider.saveTokens(tokens, infoCtx);\n }\n\n // Handle token refresh or new authorization. The step-up path sets\n // `forceReauthorization` when the requested scope strictly exceeds the\n // current token's granted scope — refreshing would not widen it (RFC 6749\n // §6), so skip straight to a fresh authorization request.\n if (tokens?.refresh_token && !forceReauthorization) {\n try {\n // Attempt to refresh the token\n const newTokens = await refreshAuthorization(authorizationServerUrl, {\n metadata,\n clientInformation,\n refreshToken: tokens.refresh_token,\n resource,\n addClientAuthentication: provider.addClientAuthentication,\n fetchFn\n });\n\n await provider.saveTokens({ ...newTokens, issuer }, infoCtx);\n return 'AUTHORIZED';\n } catch (error) {\n // A non-TLS token endpoint is a configuration error — re-authorizing cannot\n // fix it. Surface it so the consumer sees the misconfiguration instead of an\n // unexplained re-auth prompt.\n if (error instanceof InsecureTokenEndpointError) {\n throw error;\n }\n // If this is a ServerError, or an unknown type, log it out and try to continue. Otherwise, escalate so we can fix things and retry.\n if (!(error instanceof OAuthError) || error.code === OAuthErrorCode.ServerError) {\n // Could not refresh OAuth tokens\n } else {\n // Refresh failed for another reason, re-throw\n throw error;\n }\n }\n }\n\n const state = provider.state ? await provider.state() : undefined;\n\n // Start new authorization flow\n const { authorizationUrl, codeVerifier } = await startAuthorization(authorizationServerUrl, {\n metadata,\n clientInformation,\n state,\n redirectUrl: provider.redirectUrl,\n scope: resolvedScope,\n resource\n });\n\n await provider.saveCodeVerifier(codeVerifier);\n await provider.redirectToAuthorization(authorizationUrl);\n return 'REDIRECT';\n}\n\n/**\n * Validates that the given `clientMetadataUrl` is a valid HTTPS URL with a non-root pathname.\n *\n * No-op when `url` is `undefined` or empty (providers that do not use URL-based client IDs\n * are unaffected). When the value is defined but invalid, throws an {@linkcode OAuthError}\n * with code {@linkcode OAuthErrorCode.InvalidClientMetadata}.\n *\n * {@linkcode OAuthClientProvider} implementations that accept a `clientMetadataUrl` should\n * call this in their constructors for early validation.\n *\n * @param url - The `clientMetadataUrl` value to validate (from `OAuthClientProvider.clientMetadataUrl`)\n * @throws {OAuthError} When `url` is defined but is not a valid HTTPS URL with a non-root pathname\n */\nexport function validateClientMetadataUrl(url: string | undefined): void {\n if (url && !isHttpsUrl(url)) {\n throw new OAuthError(\n OAuthErrorCode.InvalidClientMetadata,\n `clientMetadataUrl must be a valid HTTPS URL with a non-root pathname, got: ${url}`\n );\n }\n}\n\n/**\n * SEP-991: URL-based Client IDs\n * Validate that the `client_id` is a valid URL with `https` scheme\n */\nexport function isHttpsUrl(value?: string): boolean {\n if (!value) return false;\n try {\n const url = new URL(value);\n return url.protocol === 'https:' && url.pathname !== '/';\n } catch {\n return false;\n }\n}\n\nexport async function selectResourceURL(\n serverUrl: string | URL,\n provider: OAuthClientProvider,\n resourceMetadata?: OAuthProtectedResourceMetadata\n): Promise<URL | undefined> {\n const defaultResource = resourceUrlFromServerUrl(serverUrl);\n\n // If provider has custom validation, delegate to it\n if (provider.validateResourceURL) {\n return await provider.validateResourceURL(defaultResource, resourceMetadata?.resource);\n }\n\n // Only include resource parameter when Protected Resource Metadata is present\n if (!resourceMetadata) {\n return undefined;\n }\n\n // Validate that the metadata's resource is compatible with our request\n if (!checkResourceAllowed({ requestedResource: defaultResource, configuredResource: resourceMetadata.resource })) {\n throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${defaultResource} (or origin)`);\n }\n // Prefer the resource from metadata since it's what the server is telling us to request\n return new URL(resourceMetadata.resource);\n}\n\n/**\n * Extract `resource_metadata`, `scope`, `error`, and `error_description` from a\n * `WWW-Authenticate` header.\n */\nexport function extractWWWAuthenticateParams(res: Response): {\n resourceMetadataUrl?: URL;\n scope?: string;\n error?: string;\n errorDescription?: string;\n} {\n const authenticateHeader = res.headers.get('WWW-Authenticate');\n if (!authenticateHeader) {\n return {};\n }\n\n const [type, scheme] = authenticateHeader.split(' ');\n if (type?.toLowerCase() !== 'bearer' || !scheme) {\n return {};\n }\n\n const resourceMetadataMatch = extractFieldFromWwwAuth(res, 'resource_metadata') || undefined;\n\n let resourceMetadataUrl: URL | undefined;\n if (resourceMetadataMatch) {\n try {\n resourceMetadataUrl = new URL(resourceMetadataMatch);\n } catch {\n // Ignore invalid URL\n }\n }\n\n const scope = extractFieldFromWwwAuth(res, 'scope') || undefined;\n const error = extractFieldFromWwwAuth(res, 'error') || undefined;\n const errorDescription = extractFieldFromWwwAuth(res, 'error_description') || undefined;\n\n return {\n resourceMetadataUrl,\n scope,\n error,\n errorDescription\n };\n}\n\n/**\n * Extracts a specific field's value from the `WWW-Authenticate` header string.\n *\n * @param response The HTTP response object containing the headers.\n * @param fieldName The name of the field to extract (e.g., `\"realm\"`, `\"nonce\"`).\n * @returns The field value\n */\nfunction extractFieldFromWwwAuth(response: Response, fieldName: string): string | null {\n const wwwAuthHeader = response.headers.get('WWW-Authenticate');\n if (!wwwAuthHeader) {\n return null;\n }\n\n const pattern = new RegExp(String.raw`${fieldName}=(?:\"([^\"]+)\"|([^\\s,]+))`);\n const match = wwwAuthHeader.match(pattern);\n\n if (match) {\n // Pattern matches: field_name=\"value\" or field_name=value (unquoted)\n const result = match[1] || match[2];\n if (result) {\n return result;\n }\n }\n\n return null;\n}\n\n/**\n * Extract `resource_metadata` from response header.\n * @deprecated Use {@linkcode extractWWWAuthenticateParams} instead.\n */\nexport function extractResourceMetadataUrl(res: Response): URL | undefined {\n const authenticateHeader = res.headers.get('WWW-Authenticate');\n if (!authenticateHeader) {\n return undefined;\n }\n\n const [type, scheme] = authenticateHeader.split(' ');\n if (type?.toLowerCase() !== 'bearer' || !scheme) {\n return undefined;\n }\n const regex = /resource_metadata=\"([^\"]*)\"/;\n const match = regex.exec(authenticateHeader);\n\n if (!match || !match[1]) {\n return undefined;\n }\n\n try {\n return new URL(match[1]);\n } catch {\n return undefined;\n }\n}\n\n/**\n * Looks up {@link https://datatracker.ietf.org/doc/html/rfc9728 | RFC 9728}\n * OAuth 2.0 Protected Resource Metadata.\n *\n * If the server returns a 404 for the well-known endpoint, this function will\n * return `undefined`. Any other errors will be thrown as exceptions.\n */\nexport async function discoverOAuthProtectedResourceMetadata(\n serverUrl: string | URL,\n opts?: { protocolVersion?: string; resourceMetadataUrl?: string | URL },\n fetchFn: FetchLike = fetch\n): Promise<OAuthProtectedResourceMetadata> {\n const response = await discoverMetadataWithFallback(serverUrl, 'oauth-protected-resource', fetchFn, {\n protocolVersion: opts?.protocolVersion,\n metadataUrl: opts?.resourceMetadataUrl\n });\n\n if (!response || response.status === 404) {\n await response?.text?.().catch(() => {});\n throw new Error(`Resource server does not implement OAuth 2.0 Protected Resource Metadata.`);\n }\n\n if (!response.ok) {\n await response.text?.().catch(() => {});\n throw new Error(`HTTP ${response.status} trying to load well-known OAuth protected resource metadata.`);\n }\n return OAuthProtectedResourceMetadataSchema.parse(await response.json());\n}\n\n/**\n * Fetch with a retry heuristic for CORS errors caused by custom headers.\n *\n * In browsers, adding a custom header (e.g. `MCP-Protocol-Version`) triggers a CORS preflight.\n * If the server doesn't allow that header, the browser throws a `TypeError` before any response\n * is received. Retrying without custom headers often succeeds because the request becomes\n * \"simple\" (no preflight). If the server sends no CORS headers at all, the retry also fails\n * with `TypeError` and we return `undefined` so callers can fall through to an alternate URL.\n *\n * However, `fetch()` also throws `TypeError` for non-CORS failures (DNS resolution, connection\n * refused, invalid URL). Swallowing those and returning `undefined` masks real errors and can\n * cause callers to silently fall through to a different discovery URL. CORS is a browser-only\n * concept, so in non-browser runtimes (Node.js, Workers) a `TypeError` from `fetch` is never a\n * CORS error — there we propagate the error instead of swallowing it.\n *\n * In browsers, we cannot reliably distinguish CORS `TypeError` from network `TypeError` from the\n * error object alone, so the swallow-and-fallthrough heuristic is preserved there.\n */\nasync function fetchWithCorsRetry(url: URL, headers?: Record<string, string>, fetchFn: FetchLike = fetch): Promise<Response | undefined> {\n try {\n return await fetchFn(url, { headers });\n } catch (error) {\n if (!(error instanceof TypeError) || !CORS_IS_POSSIBLE) {\n throw error;\n }\n if (headers) {\n // Could be a CORS preflight rejection caused by our custom header. Retry as a simple\n // request: if that succeeds, we've sidestepped the preflight.\n try {\n return await fetchFn(url, {});\n } catch (retryError) {\n if (!(retryError instanceof TypeError)) {\n throw retryError;\n }\n // Retry also got CORS-blocked (server sends no CORS headers at all).\n // Return undefined so the caller tries the next discovery URL.\n return undefined;\n }\n }\n return undefined;\n }\n}\n\n/**\n * Constructs the well-known path for auth-related metadata discovery\n */\nfunction buildWellKnownPath(\n wellKnownPrefix: 'oauth-authorization-server' | 'oauth-protected-resource' | 'openid-configuration',\n pathname: string = '',\n options: { prependPathname?: boolean } = {}\n): string {\n // Strip trailing slash from pathname to avoid double slashes\n if (pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1);\n }\n\n return options.prependPathname ? `${pathname}/.well-known/${wellKnownPrefix}` : `/.well-known/${wellKnownPrefix}${pathname}`;\n}\n\n/**\n * Tries to discover OAuth metadata at a specific URL\n */\nasync function tryMetadataDiscovery(url: URL, protocolVersion: string, fetchFn: FetchLike = fetch): Promise<Response | undefined> {\n const headers = {\n 'MCP-Protocol-Version': protocolVersion\n };\n return await fetchWithCorsRetry(url, headers, fetchFn);\n}\n\n/**\n * Determines if fallback to root discovery should be attempted\n */\nfunction shouldAttemptFallback(response: Response | undefined, pathname: string): boolean {\n if (!response) return true; // CORS error — always try fallback\n if (pathname === '/') return false; // Already at root\n return (response.status >= 400 && response.status < 500) || response.status === 502;\n}\n\n/**\n * Generic function for discovering OAuth metadata with fallback support\n */\nasync function discoverMetadataWithFallback(\n serverUrl: string | URL,\n wellKnownType: 'oauth-authorization-server' | 'oauth-protected-resource',\n fetchFn: FetchLike,\n opts?: { protocolVersion?: string; metadataUrl?: string | URL; metadataServerUrl?: string | URL }\n): Promise<Response | undefined> {\n const issuer = new URL(serverUrl);\n const protocolVersion = opts?.protocolVersion ?? LATEST_PROTOCOL_VERSION;\n\n let url: URL;\n if (opts?.metadataUrl) {\n url = new URL(opts.metadataUrl);\n } else {\n // Try path-aware discovery first\n const wellKnownPath = buildWellKnownPath(wellKnownType, issuer.pathname);\n url = new URL(wellKnownPath, opts?.metadataServerUrl ?? issuer);\n url.search = issuer.search;\n }\n\n let response = await tryMetadataDiscovery(url, protocolVersion, fetchFn);\n\n // If path-aware discovery fails (4xx or 502 Bad Gateway) and we're not already at root, try fallback to root discovery\n if (!opts?.metadataUrl && shouldAttemptFallback(response, issuer.pathname)) {\n const rootUrl = new URL(`/.well-known/${wellKnownType}`, issuer);\n response = await tryMetadataDiscovery(rootUrl, protocolVersion, fetchFn);\n }\n\n return response;\n}\n\n/**\n * Looks up RFC 8414 OAuth 2.0 Authorization Server Metadata.\n *\n * If the server returns a 404 for the well-known endpoint, this function will\n * return `undefined`. Any other errors will be thrown as exceptions.\n *\n * @deprecated This function is deprecated in favor of {@linkcode discoverAuthorizationServerMetadata}.\n */\nexport async function discoverOAuthMetadata(\n issuer: string | URL,\n {\n authorizationServerUrl,\n protocolVersion\n }: {\n authorizationServerUrl?: string | URL;\n protocolVersion?: string;\n } = {},\n fetchFn: FetchLike = fetch\n): Promise<OAuthMetadata | undefined> {\n if (typeof issuer === 'string') {\n issuer = new URL(issuer);\n }\n if (!authorizationServerUrl) {\n authorizationServerUrl = issuer;\n }\n if (typeof authorizationServerUrl === 'string') {\n authorizationServerUrl = new URL(authorizationServerUrl);\n }\n protocolVersion ??= LATEST_PROTOCOL_VERSION;\n\n const response = await discoverMetadataWithFallback(authorizationServerUrl, 'oauth-authorization-server', fetchFn, {\n protocolVersion,\n metadataServerUrl: authorizationServerUrl\n });\n\n if (!response || response.status === 404) {\n await response?.text?.().catch(() => {});\n return undefined;\n }\n\n if (!response.ok) {\n await response.text?.().catch(() => {});\n throw new Error(`HTTP ${response.status} trying to load well-known OAuth metadata`);\n }\n\n return OAuthMetadataSchema.parse(await response.json());\n}\n\n/**\n * Builds a list of discovery URLs to try for authorization server metadata.\n * URLs are returned in priority order:\n * 1. OAuth metadata at the given URL\n * 2. OIDC metadata endpoints at the given URL\n */\nexport function buildDiscoveryUrls(authorizationServerUrl: string | URL): { url: URL; type: 'oauth' | 'oidc' }[] {\n const url = typeof authorizationServerUrl === 'string' ? new URL(authorizationServerUrl) : authorizationServerUrl;\n const hasPath = url.pathname !== '/';\n const urlsToTry: { url: URL; type: 'oauth' | 'oidc' }[] = [];\n\n if (!hasPath) {\n urlsToTry.push(\n // Root path: https://example.com/.well-known/oauth-authorization-server\n\n {\n url: new URL('/.well-known/oauth-authorization-server', url.origin),\n type: 'oauth'\n },\n // OIDC: https://example.com/.well-known/openid-configuration\n\n {\n url: new URL(`/.well-known/openid-configuration`, url.origin),\n type: 'oidc'\n }\n );\n\n return urlsToTry;\n }\n\n // Strip trailing slash from pathname to avoid double slashes\n let pathname = url.pathname;\n if (pathname.endsWith('/')) {\n pathname = pathname.slice(0, -1);\n }\n\n urlsToTry.push(\n // 1. OAuth metadata at the given URL\n // Insert well-known before the path: https://example.com/.well-known/oauth-authorization-server/tenant1\n {\n url: new URL(`/.well-known/oauth-authorization-server${pathname}`, url.origin),\n type: 'oauth'\n },\n // 2. OIDC metadata endpoints\n // RFC 8414 style: Insert /.well-known/openid-configuration before the path\n {\n url: new URL(`/.well-known/openid-configuration${pathname}`, url.origin),\n type: 'oidc'\n },\n // OIDC Discovery 1.0 style: Append /.well-known/openid-configuration after the path\n\n {\n url: new URL(`${pathname}/.well-known/openid-configuration`, url.origin),\n type: 'oidc'\n }\n );\n\n return urlsToTry;\n}\n\n/**\n * Discovers authorization server metadata with support for\n * {@link https://datatracker.ietf.org/doc/html/rfc8414 | RFC 8414} OAuth 2.0\n * Authorization Server Metadata and\n * {@link https://openid.net/specs/openid-connect-discovery-1_0.html | OpenID Connect Discovery 1.0}\n * specifications.\n *\n * This function implements a fallback strategy for authorization server discovery:\n * 1. Attempts RFC 8414 OAuth metadata discovery first\n * 2. If OAuth discovery fails, falls back to OpenID Connect Discovery\n *\n * @param authorizationServerUrl - The authorization server URL obtained from the MCP Server's\n * protected resource metadata, or the MCP server's URL if the\n * metadata was not found.\n * The returned metadata's `issuer` is validated against `authorizationServerUrl`\n * per RFC 8414 §3.3 (and OIDC Discovery §4.3): if they differ the metadata is\n * **rejected** with {@linkcode IssuerMismatchError} and not returned. Set\n * `skipIssuerValidation: true` to suppress this check — **security-weakening**,\n * intended only for known-misconfigured authorization servers.\n *\n * @param options - Configuration options\n * @param options.fetchFn - Optional fetch function for making HTTP requests, defaults to global fetch\n * @param options.protocolVersion - MCP protocol version to use, defaults to {@linkcode LATEST_PROTOCOL_VERSION}\n * @param options.skipIssuerValidation - Skip the RFC 8414 §3.3 `issuer` echo check. **Security-weakening.**\n * @returns Promise resolving to authorization server metadata, or undefined if discovery fails\n * @throws {IssuerMismatchError} when the metadata's `issuer` does not match `authorizationServerUrl`\n */\nexport async function discoverAuthorizationServerMetadata(\n authorizationServerUrl: string | URL,\n {\n fetchFn = fetch,\n protocolVersion = LATEST_PROTOCOL_VERSION,\n skipIssuerValidation = false\n }: {\n fetchFn?: FetchLike;\n protocolVersion?: string;\n skipIssuerValidation?: boolean;\n } = {}\n): Promise<AuthorizationServerMetadata | undefined> {\n const headers = {\n 'MCP-Protocol-Version': protocolVersion,\n Accept: 'application/json'\n };\n\n // Get the list of URLs to try\n const urlsToTry = buildDiscoveryUrls(authorizationServerUrl);\n\n // Try each URL in order\n for (const { url: endpointUrl, type } of urlsToTry) {\n const response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);\n\n if (!response) {\n /**\n * CORS error occurred - don't throw as the endpoint may not allow CORS,\n * continue trying other possible endpoints\n */\n continue;\n }\n\n if (!response.ok) {\n await response.text?.().catch(() => {});\n if ((response.status >= 400 && response.status < 500) || response.status === 502) {\n continue; // Try next URL for 4xx or 502 (Bad Gateway)\n }\n throw new Error(\n `HTTP ${response.status} trying to load ${type === 'oauth' ? 'OAuth' : 'OpenID provider'} metadata from ${endpointUrl}`\n );\n }\n\n // Parse and validate based on type\n const parsed =\n type === 'oauth'\n ? OAuthMetadataSchema.parse(await response.json())\n : OpenIdProviderDiscoveryMetadataSchema.parse(await response.json());\n\n if (!skipIssuerValidation) {\n // RFC 8414 §3.3 / OIDC Discovery §4.3: the `issuer` value in the document MUST be\n // identical to the issuer identifier used to construct the well-known URL. Compare\n // against the raw input string — callers pass the exact issuer string the AS published.\n const expectedIssuer = typeof authorizationServerUrl === 'string' ? authorizationServerUrl : authorizationServerUrl.href;\n // One narrow tolerance: the SDK's own legacy-fallback path synthesizes the AS URL via\n // `String(new URL('/', serverUrl))`, which always carries a trailing `/`. That value is\n // SDK-generated (not attacker-controlled), so accept the slash-only difference here.\n // The tolerance is one-directional and end-anchored — a different host or path is still\n // a mismatch.\n const matches =\n parsed.issuer === expectedIssuer || (expectedIssuer.endsWith('/') && parsed.issuer === expectedIssuer.slice(0, -1));\n if (!matches) {\n throw new IssuerMismatchError('metadata', expectedIssuer, parsed.issuer);\n }\n }\n\n return parsed;\n }\n\n return undefined;\n}\n\n/**\n * Result of {@linkcode discoverOAuthServerInfo}.\n */\nexport interface OAuthServerInfo {\n /**\n * The authorization server URL, either discovered via RFC 9728\n * or derived from the MCP server URL as a fallback.\n */\n authorizationServerUrl: string;\n\n /**\n * The authorization server metadata (endpoints, capabilities),\n * or `undefined` if metadata discovery failed.\n */\n authorizationServerMetadata?: AuthorizationServerMetadata;\n\n /**\n * The OAuth 2.0 Protected Resource Metadata from RFC 9728,\n * or `undefined` if the server does not support it.\n */\n resourceMetadata?: OAuthProtectedResourceMetadata;\n}\n\n/**\n * Discovers the authorization server for an MCP server following\n * {@link https://datatracker.ietf.org/doc/html/rfc9728 | RFC 9728} (OAuth 2.0 Protected\n * Resource Metadata), with fallback to treating the server URL as the\n * authorization server.\n *\n * This function combines two discovery steps into one call:\n * 1. Probes `/.well-known/oauth-protected-resource` on the MCP server to find the\n * authorization server URL (RFC 9728).\n * 2. Fetches authorization server metadata from that URL (RFC 8414 / OpenID Connect Discovery).\n *\n * Use this when you need the authorization server metadata for operations outside the\n * {@linkcode auth} orchestrator, such as token refresh or token revocation.\n *\n * @param serverUrl - The MCP resource server URL\n * @param opts - Optional configuration\n * @param opts.resourceMetadataUrl - Override URL for the protected resource metadata endpoint\n * @param opts.fetchFn - Custom fetch function for HTTP requests\n * @returns Authorization server URL, metadata, and resource metadata (if available)\n */\nexport async function discoverOAuthServerInfo(\n serverUrl: string | URL,\n opts?: {\n resourceMetadataUrl?: URL;\n fetchFn?: FetchLike;\n /**\n * Forwarded to {@linkcode discoverAuthorizationServerMetadata} as\n * `skipIssuerValidation`. **Security-weakening** — see {@linkcode AuthOptions.skipIssuerMetadataValidation}.\n */\n skipIssuerMetadataValidation?: boolean;\n }\n): Promise<OAuthServerInfo> {\n let resourceMetadata: OAuthProtectedResourceMetadata | undefined;\n let authorizationServerUrl: string | undefined;\n\n try {\n resourceMetadata = await discoverOAuthProtectedResourceMetadata(\n serverUrl,\n { resourceMetadataUrl: opts?.resourceMetadataUrl },\n opts?.fetchFn\n );\n if (resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0) {\n authorizationServerUrl = resourceMetadata.authorization_servers[0];\n }\n } catch (error) {\n // Network failures (DNS, connection refused) surface as TypeError from fetch. Those are\n // transient reachability problems, not \"server doesn't support PRM\" — propagate so the\n // caller sees the real error instead of silently falling back to a different auth server.\n if (error instanceof TypeError) {\n throw error;\n }\n // RFC 9728 not supported -- fall back to treating the server URL as the authorization server\n }\n\n // If we don't get a valid authorization server from protected resource metadata,\n // fall back to the legacy MCP spec behavior: MCP server base URL acts as the authorization server\n if (!authorizationServerUrl) {\n authorizationServerUrl = String(new URL('/', serverUrl));\n }\n\n const authorizationServerMetadata = await discoverAuthorizationServerMetadata(authorizationServerUrl, {\n fetchFn: opts?.fetchFn,\n skipIssuerValidation: opts?.skipIssuerMetadataValidation\n });\n\n return {\n authorizationServerUrl,\n authorizationServerMetadata,\n resourceMetadata\n };\n}\n\n/**\n * Begins the authorization flow with the given server, by generating a PKCE challenge and constructing the authorization URL.\n */\nexport async function startAuthorization(\n authorizationServerUrl: string | URL,\n {\n metadata,\n clientInformation,\n redirectUrl,\n scope,\n state,\n resource\n }: {\n metadata?: AuthorizationServerMetadata;\n clientInformation: OAuthClientInformationMixed;\n redirectUrl: string | URL;\n scope?: string;\n state?: string;\n resource?: URL;\n }\n): Promise<{ authorizationUrl: URL; codeVerifier: string }> {\n let authorizationUrl: URL;\n if (metadata) {\n authorizationUrl = new URL(metadata.authorization_endpoint);\n\n if (!metadata.response_types_supported.includes(AUTHORIZATION_CODE_RESPONSE_TYPE)) {\n throw new Error(`Incompatible auth server: does not support response type ${AUTHORIZATION_CODE_RESPONSE_TYPE}`);\n }\n\n if (\n metadata.code_challenge_methods_supported &&\n !metadata.code_challenge_methods_supported.includes(AUTHORIZATION_CODE_CHALLENGE_METHOD)\n ) {\n throw new Error(`Incompatible auth server: does not support code challenge method ${AUTHORIZATION_CODE_CHALLENGE_METHOD}`);\n }\n } else {\n authorizationUrl = new URL('/authorize', authorizationServerUrl);\n }\n\n // Generate PKCE challenge\n const challenge = await pkceChallenge();\n const codeVerifier = challenge.code_verifier;\n const codeChallenge = challenge.code_challenge;\n\n authorizationUrl.searchParams.set('response_type', AUTHORIZATION_CODE_RESPONSE_TYPE);\n authorizationUrl.searchParams.set('client_id', clientInformation.client_id);\n authorizationUrl.searchParams.set('code_challenge', codeChallenge);\n authorizationUrl.searchParams.set('code_challenge_method', AUTHORIZATION_CODE_CHALLENGE_METHOD);\n authorizationUrl.searchParams.set('redirect_uri', String(redirectUrl));\n\n if (state) {\n authorizationUrl.searchParams.set('state', state);\n }\n\n if (scope) {\n authorizationUrl.searchParams.set('scope', scope);\n }\n\n if (scope?.split(' ').includes('offline_access')) {\n // if the request includes the OIDC-only \"offline_access\" scope,\n // we need to set the prompt to \"consent\" to ensure the user is prompted to grant offline access\n // https://openid.net/specs/openid-connect-core-1_0.html#OfflineAccess\n authorizationUrl.searchParams.append('prompt', 'consent');\n }\n\n if (resource) {\n authorizationUrl.searchParams.set('resource', resource.href);\n }\n\n return { authorizationUrl, codeVerifier };\n}\n\n/**\n * Prepares token request parameters for an authorization code exchange.\n *\n * This is the default implementation used by {@linkcode fetchToken} when the provider\n * doesn't implement {@linkcode OAuthClientProvider.prepareTokenRequest | prepareTokenRequest}.\n *\n * @param authorizationCode - The authorization code received from the authorization endpoint\n * @param codeVerifier - The PKCE code verifier\n * @param redirectUri - The redirect URI used in the authorization request\n * @returns URLSearchParams for the `authorization_code` grant\n */\nexport function prepareAuthorizationCodeRequest(\n authorizationCode: string,\n codeVerifier: string,\n redirectUri: string | URL\n): URLSearchParams {\n return new URLSearchParams({\n grant_type: 'authorization_code',\n code: authorizationCode,\n code_verifier: codeVerifier,\n redirect_uri: String(redirectUri)\n });\n}\n\n/**\n * Internal helper to execute a token request with the given parameters.\n * Used by {@linkcode exchangeAuthorization}, {@linkcode refreshAuthorization}, and {@linkcode fetchToken}.\n */\nexport async function executeTokenRequest(\n authorizationServerUrl: string | URL,\n {\n metadata,\n tokenRequestParams,\n clientInformation,\n addClientAuthentication,\n resource,\n fetchFn\n }: {\n metadata?: AuthorizationServerMetadata;\n tokenRequestParams: URLSearchParams;\n clientInformation?: OAuthClientInformationMixed;\n addClientAuthentication?: OAuthClientProvider['addClientAuthentication'];\n resource?: URL;\n fetchFn?: FetchLike;\n }\n): Promise<OAuthTokens> {\n const tokenUrl = assertSecureTokenEndpoint(metadata?.token_endpoint ?? new URL('/token', authorizationServerUrl));\n\n const headers = new Headers({\n 'Content-Type': 'application/x-www-form-urlencoded',\n Accept: 'application/json'\n });\n\n if (resource) {\n tokenRequestParams.set('resource', resource.href);\n }\n\n if (addClientAuthentication) {\n await addClientAuthentication(headers, tokenRequestParams, tokenUrl, metadata);\n } else if (clientInformation) {\n const supportedMethods = metadata?.token_endpoint_auth_methods_supported ?? [];\n const authMethod = selectClientAuthMethod(clientInformation, supportedMethods);\n applyClientAuthentication(authMethod, clientInformation as OAuthClientInformation, headers, tokenRequestParams);\n }\n\n const response = await (fetchFn ?? fetch)(tokenUrl, {\n method: 'POST',\n headers,\n body: tokenRequestParams\n });\n\n if (!response.ok) {\n throw await parseErrorResponse(response);\n }\n\n const json: unknown = await response.json();\n\n try {\n return OAuthTokensSchema.parse(json);\n } catch (parseError) {\n // Some OAuth servers (e.g., GitHub) return error responses with HTTP 200 status.\n // Check for error field only if token parsing failed.\n if (typeof json === 'object' && json !== null && 'error' in json) {\n throw await parseErrorResponse(JSON.stringify(json));\n }\n throw parseError;\n }\n}\n\n/**\n * Exchanges an authorization code for an access token with the given server.\n *\n * Supports multiple client authentication methods as specified in OAuth 2.1:\n * - Automatically selects the best authentication method based on server support\n * - Falls back to appropriate defaults when server metadata is unavailable\n *\n * @param authorizationServerUrl - The authorization server's base URL\n * @param options - Configuration object containing client info, auth code, etc.\n * @returns Promise resolving to OAuth tokens\n * @throws {Error} When token exchange fails or authentication is invalid\n */\nexport async function exchangeAuthorization(\n authorizationServerUrl: string | URL,\n {\n metadata,\n clientInformation,\n authorizationCode,\n iss,\n codeVerifier,\n redirectUri,\n resource,\n addClientAuthentication,\n fetchFn\n }: {\n metadata?: AuthorizationServerMetadata;\n clientInformation: OAuthClientInformationMixed;\n authorizationCode: string;\n /**\n * The form-urldecoded `iss` query parameter from the authorization callback.\n * Validated per RFC 9207 §2.4 against `metadata.issuer` before the code is\n * redeemed; see {@linkcode validateAuthorizationResponseIssuer}.\n */\n iss?: string;\n codeVerifier: string;\n redirectUri: string | URL;\n resource?: URL;\n addClientAuthentication?: OAuthClientProvider['addClientAuthentication'];\n fetchFn?: FetchLike;\n }\n): Promise<OAuthTokens> {\n validateAuthorizationResponseIssuer({\n iss,\n expectedIssuer: metadata?.issuer,\n issParameterSupported: isIssParameterSupported(metadata)\n });\n\n const tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, redirectUri);\n\n return executeTokenRequest(authorizationServerUrl, {\n metadata,\n tokenRequestParams,\n clientInformation,\n addClientAuthentication,\n resource,\n fetchFn\n });\n}\n\n/**\n * Exchange a refresh token for an updated access token.\n *\n * Supports multiple client authentication methods as specified in OAuth 2.1:\n * - Automatically selects the best authentication method based on server support\n * - Preserves the original refresh token if a new one is not returned\n *\n * @param authorizationServerUrl - The authorization server's base URL\n * @param options - Configuration object containing client info, refresh token, etc.\n * @returns Promise resolving to OAuth tokens (preserves original `refresh_token` if not replaced)\n * @throws {Error} When token refresh fails or authentication is invalid\n */\nexport async function refreshAuthorization(\n authorizationServerUrl: string | URL,\n {\n metadata,\n clientInformation,\n refreshToken,\n resource,\n addClientAuthentication,\n fetchFn\n }: {\n metadata?: AuthorizationServerMetadata;\n clientInformation: OAuthClientInformationMixed;\n refreshToken: string;\n resource?: URL;\n addClientAuthentication?: OAuthClientProvider['addClientAuthentication'];\n fetchFn?: FetchLike;\n }\n): Promise<OAuthTokens> {\n const tokenRequestParams = new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken\n });\n\n const tokens = await executeTokenRequest(authorizationServerUrl, {\n metadata,\n tokenRequestParams,\n clientInformation,\n addClientAuthentication,\n resource,\n fetchFn\n });\n\n // Preserve original refresh token if server didn't return a new one\n return { refresh_token: refreshToken, ...tokens };\n}\n\n/**\n * Unified token fetching that works with any grant type via {@linkcode OAuthClientProvider.prepareTokenRequest | prepareTokenRequest()}.\n *\n * This function provides a single entry point for obtaining tokens regardless of the\n * OAuth grant type. The provider's `prepareTokenRequest()` method determines which grant\n * to use and supplies the grant-specific parameters.\n *\n * @param provider - OAuth client provider that implements `prepareTokenRequest()`\n * @param authorizationServerUrl - The authorization server's base URL\n * @param options - Configuration for the token request\n * @returns Promise resolving to OAuth tokens\n * @throws {Error} When provider doesn't implement `prepareTokenRequest` or token fetch fails\n *\n * @example\n * ```ts source=\"./auth.examples.ts#fetchToken_clientCredentials\"\n * // Provider for client_credentials:\n * class MyProvider extends MyProviderBase implements OAuthClientProvider {\n * prepareTokenRequest(scope?: string) {\n * const params = new URLSearchParams({ grant_type: 'client_credentials' });\n * if (scope) params.set('scope', scope);\n * return params;\n * }\n * }\n *\n * const tokens = await fetchToken(new MyProvider(), authServerUrl, { metadata });\n * ```\n */\nexport async function fetchToken(\n provider: OAuthClientProvider,\n authorizationServerUrl: string | URL,\n {\n metadata,\n resource,\n authorizationCode,\n iss,\n scope,\n fetchFn\n }: {\n metadata?: AuthorizationServerMetadata;\n resource?: URL;\n /** Authorization code for the default `authorization_code` grant flow */\n authorizationCode?: string;\n /**\n * The form-urldecoded `iss` query parameter from the authorization callback.\n * Validated per RFC 9207 §2.4 when `authorizationCode` is present;\n * see {@linkcode validateAuthorizationResponseIssuer}.\n */\n iss?: string;\n /** Optional scope parameter from auth() options */\n scope?: string;\n fetchFn?: FetchLike;\n } = {}\n): Promise<OAuthTokens> {\n if (authorizationCode !== undefined) {\n validateAuthorizationResponseIssuer({\n iss,\n expectedIssuer: metadata?.issuer,\n issParameterSupported: isIssParameterSupported(metadata)\n });\n }\n\n // Prefer scope from options, fallback to provider.clientMetadata.scope\n const effectiveScope = scope ?? provider.clientMetadata.scope;\n\n // Use provider's prepareTokenRequest if available, otherwise fall back to authorization_code\n let tokenRequestParams: URLSearchParams | undefined;\n if (provider.prepareTokenRequest) {\n tokenRequestParams = await provider.prepareTokenRequest(effectiveScope);\n }\n\n // Default to authorization_code grant if no custom prepareTokenRequest\n if (!tokenRequestParams) {\n if (!authorizationCode) {\n throw new Error('Either provider.prepareTokenRequest() or authorizationCode is required');\n }\n if (!provider.redirectUrl) {\n throw new Error('redirectUrl is required for authorization_code flow');\n }\n const codeVerifier = await provider.codeVerifier();\n tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, provider.redirectUrl);\n }\n\n const clientInformation = await provider.clientInformation({ issuer: metadata?.issuer ?? String(authorizationServerUrl) });\n\n return executeTokenRequest(authorizationServerUrl, {\n metadata,\n tokenRequestParams,\n clientInformation: clientInformation ?? undefined,\n addClientAuthentication: provider.addClientAuthentication,\n resource,\n fetchFn\n });\n}\n\n/**\n * Performs OAuth 2.0 Dynamic Client Registration according to\n * {@link https://datatracker.ietf.org/doc/html/rfc7591 | RFC 7591}.\n *\n * If `scope` is provided, it overrides `clientMetadata.scope` in the registration\n * request body. This allows callers to apply the Scope Selection Strategy (SEP-835)\n * consistently across both DCR and the subsequent authorization request.\n *\n * @deprecated Dynamic Client Registration is deprecated as of protocol version\n * 2026-07-28 (SEP-2577) in favor of Client ID Metadata Documents (SEP-991).\n * Remains functional during the deprecation window (at least twelve months).\n * Prefer a CIMD URL `client_id` when the authorization server advertises\n * `client_id_metadata_document_supported`; the SDK already gates on this for you.\n */\nexport async function registerClient(\n authorizationServerUrl: string | URL,\n {\n metadata,\n clientMetadata,\n scope,\n fetchFn\n }: {\n metadata?: AuthorizationServerMetadata;\n clientMetadata: OAuthClientMetadata;\n scope?: string;\n fetchFn?: FetchLike;\n }\n): Promise<OAuthClientInformationFull> {\n let registrationUrl: URL;\n\n if (metadata) {\n if (!metadata.registration_endpoint) {\n throw new Error('Incompatible auth server: does not support dynamic client registration');\n }\n\n registrationUrl = new URL(metadata.registration_endpoint);\n } else {\n registrationUrl = new URL('/register', authorizationServerUrl);\n }\n\n // `clientMetadata` arrives via resolveClientMetadata() inside auth(), so the\n // SEP-837/2207 defaults are already applied. Direct callers that want the\n // same defaults should pass resolveClientMetadata(provider) here.\n const submittedMetadata: OAuthClientMetadata = {\n ...clientMetadata,\n ...(scope === undefined ? {} : { scope })\n };\n\n const response = await (fetchFn ?? fetch)(registrationUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json'\n },\n body: JSON.stringify(submittedMetadata)\n });\n\n if (!response.ok) {\n throw new RegistrationRejectedError({ status: response.status, body: await response.text(), submittedMetadata });\n }\n\n return OAuthClientInformationFullSchema.parse(await response.json());\n}\n","/**\n * OAuth provider extensions for specialized authentication flows.\n *\n * This module provides ready-to-use {@linkcode OAuthClientProvider} implementations\n * for common machine-to-machine authentication scenarios.\n */\n\nimport type { FetchLike, OAuthClientMetadata, StoredOAuthClientInformation, StoredOAuthTokens } from '@modelcontextprotocol/core-internal';\nimport type { CryptoKey, JWK } from 'jose';\n\nimport type { AddClientAuthentication, OAuthClientProvider } from './auth';\n\n/**\n * Helper to produce a `private_key_jwt` client authentication function.\n *\n * @example\n * ```ts source=\"./authExtensions.examples.ts#createPrivateKeyJwtAuth_basicUsage\"\n * const addClientAuth = createPrivateKeyJwtAuth({\n * issuer: 'my-client',\n * subject: 'my-client',\n * privateKey: pemEncodedPrivateKey,\n * alg: 'RS256'\n * });\n * // pass addClientAuth as provider.addClientAuthentication implementation\n * ```\n */\nexport function createPrivateKeyJwtAuth(options: {\n issuer: string;\n subject: string;\n privateKey: string | Uint8Array | Record<string, unknown>;\n alg: string;\n audience?: string | URL;\n lifetimeSeconds?: number;\n claims?: Record<string, unknown>;\n}): AddClientAuthentication {\n return async (_headers, params, url, metadata) => {\n // Lazy import to avoid heavy dependency unless used\n if (globalThis.crypto === undefined) {\n throw new TypeError(\n 'crypto is not available, please ensure you have Web Crypto API support for older Node.js versions (see https://github.com/modelcontextprotocol/typescript-sdk#nodejs-web-crypto-globalthiscrypto-compatibility)'\n );\n }\n\n const jose = await import('jose');\n\n const audience = String(options.audience ?? metadata?.issuer ?? url);\n const lifetimeSeconds = options.lifetimeSeconds ?? 300;\n\n const now = Math.floor(Date.now() / 1000);\n const jti = `${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\n const baseClaims = {\n iss: options.issuer,\n sub: options.subject,\n aud: audience,\n exp: now + lifetimeSeconds,\n iat: now,\n jti\n };\n const claims = options.claims ? { ...baseClaims, ...options.claims } : baseClaims;\n\n // Import key for the requested algorithm\n const alg = options.alg;\n let key: unknown;\n if (typeof options.privateKey === 'string') {\n if (alg.startsWith('RS') || alg.startsWith('ES') || alg.startsWith('PS')) {\n key = await jose.importPKCS8(options.privateKey, alg);\n } else if (alg.startsWith('HS')) {\n key = new TextEncoder().encode(options.privateKey);\n } else {\n throw new Error(`Unsupported algorithm ${alg}`);\n }\n } else if (options.privateKey instanceof Uint8Array) {\n // Assume PKCS#8 DER in Uint8Array for asymmetric algorithms\n key = alg.startsWith('HS') ? options.privateKey : await jose.importPKCS8(new TextDecoder().decode(options.privateKey), alg);\n } else {\n // Treat as JWK\n key = await jose.importJWK(options.privateKey as JWK, alg);\n }\n\n // Sign JWT\n const assertion = await new jose.SignJWT(claims)\n .setProtectedHeader({ alg, typ: 'JWT' })\n .setIssuer(options.issuer)\n .setSubject(options.subject)\n .setAudience(audience)\n .setIssuedAt(now)\n .setExpirationTime(now + lifetimeSeconds)\n .setJti(jti)\n .sign(key as unknown as Uint8Array | CryptoKey);\n\n params.set('client_assertion', assertion);\n params.set('client_assertion_type', 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer');\n };\n}\n\n/**\n * Options for creating a {@linkcode ClientCredentialsProvider}.\n */\nexport interface ClientCredentialsProviderOptions {\n /**\n * The `client_id` for this OAuth client.\n */\n clientId: string;\n\n /**\n * The `client_secret` for `client_secret_basic` authentication.\n */\n clientSecret: string;\n\n /**\n * Optional client name for metadata.\n */\n clientName?: string;\n\n /**\n * Space-separated scopes values requested by the client.\n */\n scope?: string;\n\n /**\n * The authorization server's `issuer` identifier these credentials were registered with.\n * Stamped onto the stored client information so `auth()`'s SEP-2352 issuer check\n * refuses to send the credential to any other authorization server. Hosts supplying\n * static client credentials SHOULD set this; omitting it preserves the legacy\n * (no-binding) behaviour for back-compat.\n */\n expectedIssuer?: string;\n}\n\n/**\n * OAuth provider for `client_credentials` grant with `client_secret_basic` authentication.\n *\n * This provider is designed for machine-to-machine authentication where\n * the client authenticates using a `client_id` and `client_secret`.\n *\n * @example\n * ```ts source=\"./authExtensions.examples.ts#ClientCredentialsProvider_basicUsage\"\n * const provider = new ClientCredentialsProvider({\n * clientId: 'my-client',\n * clientSecret: 'my-secret'\n * });\n *\n * const transport = new StreamableHTTPClientTransport(serverUrl, {\n * authProvider: provider\n * });\n * ```\n */\nexport class ClientCredentialsProvider implements OAuthClientProvider {\n private _tokens?: StoredOAuthTokens;\n private _clientInfo: StoredOAuthClientInformation;\n private _clientMetadata: OAuthClientMetadata;\n\n constructor(options: ClientCredentialsProviderOptions) {\n this._clientInfo = {\n client_id: options.clientId,\n client_secret: options.clientSecret,\n issuer: options.expectedIssuer\n };\n this._clientMetadata = {\n client_name: options.clientName ?? 'client-credentials-client',\n redirect_uris: [],\n grant_types: ['client_credentials'],\n token_endpoint_auth_method: 'client_secret_basic',\n scope: options.scope\n };\n }\n\n get redirectUrl(): undefined {\n return undefined;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return this._clientMetadata;\n }\n\n clientInformation(): StoredOAuthClientInformation {\n return this._clientInfo;\n }\n\n // No saveClientInformation: credentials are constructor-supplied and bound to a single\n // authorization server. When `expectedIssuer` is set and the resolved AS differs, the\n // SEP-2352 stamp check discards `clientInformation()` and auth() throws\n // AuthorizationServerMismatchError(expectedIssuer, resolved) rather than sending the credential.\n\n tokens(): StoredOAuthTokens | undefined {\n return this._tokens;\n }\n\n saveTokens(tokens: StoredOAuthTokens): void {\n this._tokens = tokens;\n }\n\n redirectToAuthorization(): void {\n throw new Error('redirectToAuthorization is not used for client_credentials flow');\n }\n\n saveCodeVerifier(): void {\n // Not used for client_credentials\n }\n\n codeVerifier(): string {\n throw new Error('codeVerifier is not used for client_credentials flow');\n }\n\n prepareTokenRequest(scope?: string): URLSearchParams {\n const params = new URLSearchParams({ grant_type: 'client_credentials' });\n if (scope) params.set('scope', scope);\n return params;\n }\n}\n\n/**\n * Options for creating a {@linkcode PrivateKeyJwtProvider}.\n */\nexport interface PrivateKeyJwtProviderOptions {\n /**\n * The `client_id` for this OAuth client.\n */\n clientId: string;\n\n /**\n * The private key for signing JWT assertions.\n * Can be a PEM string, Uint8Array, or JWK object.\n */\n privateKey: string | Uint8Array | Record<string, unknown>;\n\n /**\n * The algorithm to use for signing (e.g., 'RS256', 'ES256').\n */\n algorithm: string;\n\n /**\n * Optional client name for metadata.\n */\n clientName?: string;\n\n /**\n * Optional JWT lifetime in seconds (default: 300).\n */\n jwtLifetimeSeconds?: number;\n\n /**\n * Space-separated scopes values requested by the client.\n */\n scope?: string;\n\n /**\n * Optional custom claims to include in the JWT assertion.\n * These are merged with the standard claims (`iss`, `sub`, `aud`, `exp`, `iat`, `jti`),\n * with custom claims taking precedence for any overlapping keys.\n *\n * Useful for including additional claims that help scope the access token\n * with finer granularity than what scopes alone allow.\n */\n claims?: Record<string, unknown>;\n\n /**\n * The authorization server's `issuer` identifier these credentials were registered with.\n * Seeds the SEP-2352 issuer stamp — see {@linkcode ClientCredentialsProviderOptions.expectedIssuer}.\n */\n expectedIssuer?: string;\n}\n\n/**\n * OAuth provider for `client_credentials` grant with `private_key_jwt` authentication.\n *\n * This provider is designed for machine-to-machine authentication where\n * the client authenticates using a signed JWT assertion\n * ({@link https://datatracker.ietf.org/doc/html/rfc7523#section-2.2 | RFC 7523 Section 2.2}).\n *\n * @example\n * ```ts source=\"./authExtensions.examples.ts#PrivateKeyJwtProvider_basicUsage\"\n * const provider = new PrivateKeyJwtProvider({\n * clientId: 'my-client',\n * privateKey: pemEncodedPrivateKey,\n * algorithm: 'RS256'\n * });\n *\n * const transport = new StreamableHTTPClientTransport(serverUrl, {\n * authProvider: provider\n * });\n * ```\n */\nexport class PrivateKeyJwtProvider implements OAuthClientProvider {\n private _tokens?: StoredOAuthTokens;\n private _clientInfo: StoredOAuthClientInformation;\n private _clientMetadata: OAuthClientMetadata;\n addClientAuthentication: AddClientAuthentication;\n\n constructor(options: PrivateKeyJwtProviderOptions) {\n this._clientInfo = {\n client_id: options.clientId,\n issuer: options.expectedIssuer\n };\n this._clientMetadata = {\n client_name: options.clientName ?? 'private-key-jwt-client',\n redirect_uris: [],\n grant_types: ['client_credentials'],\n token_endpoint_auth_method: 'private_key_jwt',\n scope: options.scope\n };\n this.addClientAuthentication = createPrivateKeyJwtAuth({\n issuer: options.clientId,\n subject: options.clientId,\n privateKey: options.privateKey,\n alg: options.algorithm,\n lifetimeSeconds: options.jwtLifetimeSeconds,\n claims: options.claims\n });\n }\n\n get redirectUrl(): undefined {\n return undefined;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return this._clientMetadata;\n }\n\n clientInformation(): StoredOAuthClientInformation {\n return this._clientInfo;\n }\n\n // No saveClientInformation: credentials are constructor-supplied; the SEP-2352 stamp\n // check enforces `expectedIssuer` and auth() throws\n // AuthorizationServerMismatchError(expectedIssuer, resolved) on mismatch.\n\n tokens(): StoredOAuthTokens | undefined {\n return this._tokens;\n }\n\n saveTokens(tokens: StoredOAuthTokens): void {\n this._tokens = tokens;\n }\n\n redirectToAuthorization(): void {\n throw new Error('redirectToAuthorization is not used for client_credentials flow');\n }\n\n saveCodeVerifier(): void {\n // Not used for client_credentials\n }\n\n codeVerifier(): string {\n throw new Error('codeVerifier is not used for client_credentials flow');\n }\n\n prepareTokenRequest(scope?: string): URLSearchParams {\n const params = new URLSearchParams({ grant_type: 'client_credentials' });\n if (scope) params.set('scope', scope);\n return params;\n }\n}\n\n/**\n * Options for creating a {@linkcode StaticPrivateKeyJwtProvider}.\n */\nexport interface StaticPrivateKeyJwtProviderOptions {\n /**\n * The `client_id` for this OAuth client.\n */\n clientId: string;\n\n /**\n * A pre-built JWT client assertion to use for authentication.\n *\n * This token should already contain the appropriate claims\n * (`iss`, `sub`, `aud`, `exp`, etc.) and be signed by the client's key.\n */\n jwtBearerAssertion: string;\n\n /**\n * Optional client name for metadata.\n */\n clientName?: string;\n\n /**\n * Space-separated scopes values requested by the client.\n */\n scope?: string;\n\n /**\n * The authorization server's `issuer` identifier this assertion was minted for.\n * Seeds the SEP-2352 issuer stamp — see {@linkcode ClientCredentialsProviderOptions.expectedIssuer}.\n */\n expectedIssuer?: string;\n}\n\n/**\n * OAuth provider for `client_credentials` grant with a static `private_key_jwt` assertion.\n *\n * This provider mirrors {@linkcode PrivateKeyJwtProvider} but instead of constructing and\n * signing a JWT on each request, it accepts a pre-built JWT assertion string and\n * uses it directly for authentication.\n */\nexport class StaticPrivateKeyJwtProvider implements OAuthClientProvider {\n private _tokens?: StoredOAuthTokens;\n private _clientInfo: StoredOAuthClientInformation;\n private _clientMetadata: OAuthClientMetadata;\n addClientAuthentication: AddClientAuthentication;\n\n constructor(options: StaticPrivateKeyJwtProviderOptions) {\n this._clientInfo = {\n client_id: options.clientId,\n issuer: options.expectedIssuer\n };\n this._clientMetadata = {\n client_name: options.clientName ?? 'static-private-key-jwt-client',\n redirect_uris: [],\n grant_types: ['client_credentials'],\n token_endpoint_auth_method: 'private_key_jwt',\n scope: options.scope\n };\n\n const assertion = options.jwtBearerAssertion;\n this.addClientAuthentication = async (_headers, params) => {\n params.set('client_assertion', assertion);\n params.set('client_assertion_type', 'urn:ietf:params:oauth:client-assertion-type:jwt-bearer');\n };\n }\n\n get redirectUrl(): undefined {\n return undefined;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return this._clientMetadata;\n }\n\n clientInformation(): StoredOAuthClientInformation {\n return this._clientInfo;\n }\n\n // No saveClientInformation: credentials are constructor-supplied; the SEP-2352 stamp\n // check enforces `expectedIssuer` and auth() throws\n // AuthorizationServerMismatchError(expectedIssuer, resolved) on mismatch.\n\n tokens(): StoredOAuthTokens | undefined {\n return this._tokens;\n }\n\n saveTokens(tokens: StoredOAuthTokens): void {\n this._tokens = tokens;\n }\n\n redirectToAuthorization(): void {\n throw new Error('redirectToAuthorization is not used for client_credentials flow');\n }\n\n saveCodeVerifier(): void {\n // Not used for client_credentials\n }\n\n codeVerifier(): string {\n throw new Error('codeVerifier is not used for client_credentials flow');\n }\n\n prepareTokenRequest(scope?: string): URLSearchParams {\n const params = new URLSearchParams({ grant_type: 'client_credentials' });\n if (scope) params.set('scope', scope);\n return params;\n }\n}\n\n/**\n * Context provided to the assertion callback in {@linkcode CrossAppAccessProvider}.\n * Contains orchestrator-discovered information needed for JWT Authorization Grant requests.\n */\nexport interface CrossAppAccessContext {\n /**\n * The authorization server URL of the target MCP server.\n * Discovered via RFC 9728 protected resource metadata.\n */\n authorizationServerUrl: string;\n\n /**\n * The resource URL of the target MCP server.\n * Discovered via RFC 9728 protected resource metadata.\n */\n resourceUrl: string;\n\n /**\n * Optional scope being requested for the MCP server.\n */\n scope?: string;\n\n /**\n * Fetch function to use for HTTP requests (e.g., for IdP token exchange).\n */\n fetchFn: FetchLike;\n}\n\n/**\n * Callback function type that provides a JWT Authorization Grant (ID-JAG).\n *\n * The callback receives context about the target MCP server (authorization server URL,\n * resource URL, scope) and should return a JWT Authorization Grant that will be used\n * to obtain an access token from the MCP server.\n */\nexport type AssertionCallback = (context: CrossAppAccessContext) => string | Promise<string>;\n\n/**\n * Options for creating a {@linkcode CrossAppAccessProvider}.\n */\nexport interface CrossAppAccessProviderOptions {\n /**\n * Callback function that provides a JWT Authorization Grant (ID-JAG).\n *\n * The callback receives the MCP server's authorization server URL, resource URL,\n * and requested scope, and should return a JWT Authorization Grant obtained from\n * the enterprise IdP via RFC 8693 token exchange.\n *\n * You can use the utility functions from the `crossAppAccess` module\n * for standard flows, or implement custom logic.\n *\n * @example\n * ```ts\n * assertion: async (ctx) => {\n * const result = await discoverAndRequestJwtAuthGrant({\n * idpUrl: 'https://idp.example.com',\n * audience: ctx.authorizationServerUrl,\n * resource: ctx.resourceUrl,\n * idToken: await getIdToken(),\n * clientId: 'my-idp-client',\n * clientSecret: 'my-idp-secret',\n * scope: ctx.scope,\n * fetchFn: ctx.fetchFn\n * });\n * return result.jwtAuthGrant;\n * }\n * ```\n */\n assertion: AssertionCallback;\n\n /**\n * The `client_id` registered with the MCP server's authorization server.\n */\n clientId: string;\n\n /**\n * The `client_secret` for authenticating with the MCP server's authorization server.\n */\n clientSecret: string;\n\n /**\n * Optional client name for metadata.\n */\n clientName?: string;\n\n /**\n * Custom fetch implementation. Defaults to global fetch.\n */\n fetchFn?: FetchLike;\n\n /**\n * The MCP authorization server's `issuer` identifier these credentials were registered with.\n * Seeds the SEP-2352 issuer stamp — see {@linkcode ClientCredentialsProviderOptions.expectedIssuer}.\n */\n expectedIssuer?: string;\n}\n\n/**\n * OAuth provider for Cross-App Access (Enterprise Managed Authorization) using JWT Authorization Grant.\n *\n * This provider implements the Enterprise Managed Authorization flow (SEP-990) where:\n * 1. User authenticates with an enterprise IdP and the client obtains an ID Token\n * 2. Client exchanges the ID Token for a JWT Authorization Grant (ID-JAG) via RFC 8693 token exchange\n * 3. Client uses the JAG to obtain an access token from the MCP server via RFC 7523 JWT bearer grant\n *\n * The provider handles steps 2-3 automatically, with the JAG acquisition delegated to\n * a callback function that you provide. This allows flexibility in how you obtain and\n * cache ID Tokens from the IdP.\n *\n * @see https://github.com/modelcontextprotocol/ext-auth/blob/main/specification/stable/enterprise-managed-authorization.mdx\n *\n * @example\n * ```ts\n * const provider = new CrossAppAccessProvider({\n * assertion: async (ctx) => {\n * const result = await discoverAndRequestJwtAuthGrant({\n * idpUrl: 'https://idp.example.com',\n * audience: ctx.authorizationServerUrl,\n * resource: ctx.resourceUrl,\n * idToken: await getIdToken(), // Your function to get ID token\n * clientId: 'my-idp-client',\n * clientSecret: 'my-idp-secret',\n * scope: ctx.scope,\n * fetchFn: ctx.fetchFn\n * });\n * return result.jwtAuthGrant;\n * },\n * clientId: 'my-mcp-client',\n * clientSecret: 'my-mcp-secret'\n * });\n *\n * const transport = new StreamableHTTPClientTransport(serverUrl, {\n * authProvider: provider\n * });\n * ```\n */\nexport class CrossAppAccessProvider implements OAuthClientProvider {\n private _tokens?: StoredOAuthTokens;\n private _clientInfo: StoredOAuthClientInformation;\n private _clientMetadata: OAuthClientMetadata;\n private _assertionCallback: AssertionCallback;\n private _fetchFn: FetchLike;\n private _authorizationServerUrl?: string;\n private _resourceUrl?: string;\n private _scope?: string;\n\n constructor(options: CrossAppAccessProviderOptions) {\n this._clientInfo = {\n client_id: options.clientId,\n client_secret: options.clientSecret,\n issuer: options.expectedIssuer\n };\n this._clientMetadata = {\n client_name: options.clientName ?? 'cross-app-access-client',\n redirect_uris: [],\n grant_types: ['urn:ietf:params:oauth:grant-type:jwt-bearer'],\n token_endpoint_auth_method: 'client_secret_basic'\n };\n this._assertionCallback = options.assertion;\n this._fetchFn = options.fetchFn ?? fetch;\n }\n\n get redirectUrl(): undefined {\n return undefined;\n }\n\n get clientMetadata(): OAuthClientMetadata {\n return this._clientMetadata;\n }\n\n clientInformation(): StoredOAuthClientInformation {\n return this._clientInfo;\n }\n\n // No saveClientInformation: credentials are constructor-supplied; the SEP-2352 stamp\n // check enforces `expectedIssuer` and auth() throws\n // AuthorizationServerMismatchError(expectedIssuer, resolved) on mismatch.\n\n tokens(): StoredOAuthTokens | undefined {\n return this._tokens;\n }\n\n saveTokens(tokens: StoredOAuthTokens): void {\n this._tokens = tokens;\n }\n\n redirectToAuthorization(): void {\n throw new Error('redirectToAuthorization is not used for jwt-bearer flow');\n }\n\n saveCodeVerifier(): void {\n // Not used for jwt-bearer\n }\n\n codeVerifier(): string {\n throw new Error('codeVerifier is not used for jwt-bearer flow');\n }\n\n /**\n * Saves the authorization server URL discovered during OAuth flow.\n * This is called by the auth() function after RFC 9728 discovery.\n */\n saveAuthorizationServerUrl(authorizationServerUrl: string): void {\n this._authorizationServerUrl = authorizationServerUrl;\n }\n\n /**\n * Returns the cached authorization server URL if available.\n */\n authorizationServerUrl(): string | undefined {\n return this._authorizationServerUrl;\n }\n\n /**\n * Saves the resource URL discovered during OAuth flow.\n * This is called by the auth() function after RFC 9728 discovery.\n */\n saveResourceUrl?(resourceUrl: string): void {\n this._resourceUrl = resourceUrl;\n }\n\n /**\n * Returns the cached resource URL if available.\n */\n resourceUrl?(): string | undefined {\n return this._resourceUrl;\n }\n\n async prepareTokenRequest(scope?: string): Promise<URLSearchParams> {\n // Get the authorization server URL and resource URL from cached state\n const authServerUrl = this._authorizationServerUrl;\n const resourceUrl = this._resourceUrl;\n\n if (!authServerUrl) {\n throw new Error('Authorization server URL not available. Ensure auth() has been called first.');\n }\n\n if (!resourceUrl) {\n throw new Error(\n 'Resource URL not available — server may not implement RFC 9728 ' +\n 'Protected Resource Metadata (required for Cross-App Access), or ' +\n 'auth() has not been called'\n );\n }\n\n // Store scope for assertion callback\n this._scope = scope;\n\n // Call the assertion callback to get the JWT Authorization Grant\n const jwtAuthGrant = await this._assertionCallback({\n authorizationServerUrl: authServerUrl,\n resourceUrl: resourceUrl,\n scope: this._scope,\n fetchFn: this._fetchFn\n });\n\n // Return params for JWT bearer grant per RFC 7523\n const params = new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n assertion: jwtAuthGrant\n });\n\n if (scope) {\n params.set('scope', scope);\n }\n\n return params;\n }\n}\n","import type { ListToolsResult, Tool } from '@modelcontextprotocol/core-internal';\n\n/**\n * Client-side response cache for SEP-2549 (`CacheableResult`) freshness hints.\n *\n * The store is a dumb keyed-value carrier: every freshness, scope and\n * invalidation decision lives in the {@linkcode ClientResponseCache} (the\n * `Client`'s single cache-coordination collaborator). The `stamp` field is\n * mcp.d's re-derivation key — a derived view (e.g. the `name → Tool` index)\n * re-computes only when the backing entry's stamp changes.\n *\n * Reference design: mcp.d `client/cache.d` / `client/client.d` (`CacheStore`,\n * `cachedTool`, `cachedFetch`, `invalidateLogical`).\n */\n\n/** A value or a promise of one. The store interface is async-ready; the in-memory default returns plain values. */\nexport type MaybePromise<T> = T | Promise<T>;\n\n/** The freshness scope of a cached entry (SEP-2549 `cacheHints.scope`). */\nexport type CacheScope = 'public' | 'private';\n\n/**\n * Per-call cache disposition for the cacheable verbs (`listTools()` /\n * `listPrompts()` / `listResources()` / `listResourceTemplates()` /\n * `readResource()`):\n *\n * - `'use'` (the default) — serve a still-fresh cached entry without a round\n * trip; on miss/stale, fetch and write.\n * - `'refresh'` — always fetch (ignore any held entry) and write the fresh\n * result.\n * - `'bypass'` — fetch without consulting OR writing the cache (the result is\n * not stored). The `tools/list`-derived index (mirroring / output\n * validation) is therefore unaffected by a `'bypass'` call.\n */\nexport type CacheMode = 'use' | 'refresh' | 'bypass';\n\n/**\n * A logical cache address. `params` is the canonical result-affecting params\n * key (`''` for the four list ops, the `uri` for `resources/read`); omitted is\n * equivalent to `''`. `partition` namespaces the entry by connected-server\n * identity AND per-principal scope: the `Client` writes a JSON-encoded\n * `[serverIdentity, principal]` pair (so a server-controlled `serverInfo`\n * string cannot bleed into the principal slot regardless of what characters\n * it contains). A `'public'`-scoped entry lives at `[serverIdentity, '']`; a\n * `'private'`-scoped entry at `[serverIdentity, cachePartition]`. Omitted is\n * equivalent to `''`.\n */\nexport interface CacheKey {\n readonly method: string;\n readonly params?: string;\n readonly partition?: string;\n}\n\n/**\n * One cached response body. `value` is the JSON-serialized result document —\n * a store is a dumb string carrier and persists it verbatim; the cache owns\n * both codec halves. `stamp` is the store-generated monotonically increasing write counter —\n * opaque to callers. Derived views (e.g. a `name → Tool` index) memoize\n * against it and re-derive only when it changes. `expiresAt` (absolute ms\n * epoch, `now + ttlMs`) and `scope` are the client-computed freshness\n * metadata; the store MUST persist them and hand them back on `get` so the\n * read path can decide freshness and gate the shared-partition fallback on\n * `scope === 'public'`.\n */\nexport interface CacheEntry {\n readonly value: string;\n readonly stamp: number;\n readonly expiresAt?: number;\n readonly scope?: CacheScope;\n}\n\n/**\n * The pluggable response-cache store. The interface is intentionally narrow;\n * the in-memory default is the only implementation the SDK ships.\n *\n * Every method is async-ready ({@linkcode MaybePromise}) so a Redis-style\n * store can implement the same interface without a later breaking change; the\n * in-memory default stays synchronous (plain values are valid under\n * `MaybePromise`). The `Client` `await`s every call site.\n *\n * Entries are keyed by `{method, params, partition}` where `partition` is the\n * `Client`-derived `[serverIdentity, principal]` JSON pair, so one store\n * instance is safe to share across `Client` instances connected to different\n * servers and/or principals: writes from distinct connections never collide,\n * the shared-partition read fallback is gated on the stored\n * `scope === 'public'`, and `list_changed` / `HEADER_MISMATCH` evictions are\n * scoped to the connected server's two partitions — co-tenants on a shared\n * store are unaffected. The `Client` constructor still allocates a fresh\n * {@linkcode InMemoryResponseCacheStore} per instance by default; supply your\n * own to share or persist.\n */\nexport interface ResponseCacheStore {\n get(key: CacheKey): MaybePromise<CacheEntry | undefined>;\n /**\n * Writes `entry` under `key` and returns the store-generated stamp the\n * resulting {@linkcode CacheEntry} carries. The store owns the stamp\n * counter; callers do not supply one. The caller owns `expiresAt` and\n * `scope` (the client-computed freshness metadata); the store MUST persist\n * them and hand them back on `get`.\n */\n set(key: CacheKey, entry: { value: string; expiresAt?: number; scope?: CacheScope }): MaybePromise<number>;\n /**\n * Drop the single entry under `key` (no-op if absent). Called for both\n * `notifications/resources/updated` (per-URI) and the `list_changed`\n * notifications (the list singletons live at `{method, params: '', partition}`).\n */\n delete(key: CacheKey): MaybePromise<void>;\n /**\n * Drop every entry for `method` across every partition. The `Client` does\n * NOT call this (its `list_changed` path issues two partition-scoped\n * `delete()` calls so co-tenants on a shared store keep their entries);\n * kept on the interface for callers that want a method-wide bulk-clear.\n */\n evict(method: string): MaybePromise<void>;\n /** Drop every entry (connection reset). */\n clear(): MaybePromise<void>;\n}\n\n/** Options for {@linkcode InMemoryResponseCacheStore}. */\nexport interface InMemoryResponseCacheStoreOptions {\n /**\n * Maximum number of held `resources/read` entries (the only\n * unbounded-keyspace method). When inserting a new `resources/read` key\n * would exceed this, the oldest such entry (by insertion order) is\n * evicted first. The list-singleton methods (`tools/list`,\n * `prompts/list`, `resources/list`, `resources/templates/list`,\n * `server/discover`) are **exempt** — they hold at most one entry per\n * partition and back the `tools/list`-derived index, so an unbounded URI\n * working set never displaces them. The default of `512` bounds growth on\n * a long-lived client against template-expanded URIs. `0` disables the\n * bound.\n */\n maxEntries?: number;\n}\n\n/**\n * Methods whose entries are exempt from the\n * {@linkcode InMemoryResponseCacheStoreOptions.maxEntries} cap. Each holds at\n * most one entry per partition (a small bounded set) and the\n * `tools/list`-derived index depends on its entry surviving regardless of the\n * `resources/read` working-set size. Only `resources/read` keys count toward\n * the cap and are eligible for FIFO eviction.\n */\nconst CAP_EXEMPT_METHODS: ReadonlySet<string> = new Set([\n 'tools/list',\n 'prompts/list',\n 'resources/list',\n 'resources/templates/list',\n 'server/discover'\n]);\n\n/**\n * In-memory default. Bounded by an insertion-ordered size cap (default `512`;\n * see {@linkcode InMemoryResponseCacheStoreOptions.maxEntries}) on the\n * `resources/read` keyspace so an unbounded stream of distinct URIs cannot\n * grow it without limit; the list-singleton methods are exempt and never\n * evicted by the cap. `Map` preserves insertion order, so the oldest live\n * capped key is the first matching iteration entry.\n */\nexport class InMemoryResponseCacheStore implements ResponseCacheStore {\n private readonly _entries = new Map<string, CacheEntry>();\n private readonly _maxEntries: number;\n private _stamp = 0;\n /** Count of held entries that are subject to the cap (i.e. not in {@linkcode CAP_EXEMPT_METHODS}). */\n private _cappedSize = 0;\n\n constructor(options?: InMemoryResponseCacheStoreOptions) {\n this._maxEntries = options?.maxEntries ?? 512;\n }\n\n /** Number of held entries (for diagnostics / bounding tests). */\n get size(): number {\n return this._entries.size;\n }\n\n get(key: CacheKey): CacheEntry | undefined {\n return this._entries.get(keyOf(key));\n }\n\n set(key: CacheKey, entry: { value: string; expiresAt?: number; scope?: CacheScope }): number {\n const k = keyOf(key);\n const exempt = CAP_EXEMPT_METHODS.has(key.method);\n const isNew = !this._entries.has(k);\n // Evict the oldest CAPPED entry first when adding a NEW capped key\n // would exceed the cap (re-set of an existing key never evicts; an\n // exempt-method write never evicts). `Map` iteration order is\n // insertion order, so the first non-exempt key is the oldest one.\n if (!exempt && isNew && this._maxEntries > 0 && this._cappedSize >= this._maxEntries) {\n for (const oldKey of this._entries.keys()) {\n if (!CAP_EXEMPT_METHODS.has(oldKey.slice(0, oldKey.indexOf('\\0')))) {\n this._entries.delete(oldKey);\n this._cappedSize--;\n break;\n }\n }\n }\n const stamp = ++this._stamp;\n this._entries.set(k, { ...entry, stamp });\n if (isNew && !exempt) this._cappedSize++;\n return stamp;\n }\n\n delete(key: CacheKey): void {\n if (this._entries.delete(keyOf(key)) && !CAP_EXEMPT_METHODS.has(key.method)) this._cappedSize--;\n }\n\n evict(method: string): void {\n const prefix = `${method}\\0`;\n const exempt = CAP_EXEMPT_METHODS.has(method);\n for (const k of this._entries.keys()) {\n if (k.startsWith(prefix)) {\n this._entries.delete(k);\n if (!exempt) this._cappedSize--;\n }\n }\n }\n\n clear(): void {\n this._entries.clear();\n this._cappedSize = 0;\n }\n}\n\n/**\n * Serialize a {@linkcode CacheKey} for the in-memory map. `method` is always\n * an SDK-set MCP method string (never contains a NUL), so the `\\0` prefix\n * delimiter is safe and lets {@linkcode InMemoryResponseCacheStore.evict} do a\n * cheap prefix scan. `partition` (already a JSON-encoded\n * `[serverIdentity, principal]` pair) and `params` (a resource URI on the\n * `resources/read` path — caller-controlled) are JSON-array-encoded together,\n * which is collision-free regardless of any NUL or delimiter characters they\n * carry.\n */\nfunction keyOf(key: CacheKey): string {\n return `${key.method}\\0${JSON.stringify([key.partition ?? '', key.params ?? ''])}`;\n}\n\n/**\n * Serialize a `{method, params}` pair for the eviction-generation map. The\n * list singletons key on `method` alone (their {@linkcode ClientResponseCache.evict}\n * is whole-method); `resources/read` keys on `` `${method}\\0${uri}` `` so\n * {@linkcode ClientResponseCache.evictKey} bumps a per-URI counter.\n */\nfunction genKey(method: string, params?: string): string {\n return params === undefined ? method : `${method}\\0${params}`;\n}\n\n/**\n * Upper bound on the server-supplied `ttlMs` honoured by\n * {@linkcode ClientResponseCache} (24h). A server cannot pin an entry\n * indefinitely.\n */\nexport const MAX_CACHE_TTL_MS = 86_400_000;\n\n/**\n * The `Client`'s cache-coordination collaborator.\n *\n * Owns the per-connection cache state that used to live as five private\n * fields on `Client` — the backing {@linkcode ResponseCacheStore}, the\n * per-method eviction-generation counter, the user-supplied/default flag, and\n * the stamp-memoized derived indices over the `tools/list` entry. `Client`\n * holds exactly one instance and never reaches past it to the store.\n *\n * Not exported from the package index — internal to the client package.\n *\n * @internal\n */\nexport class ClientResponseCache {\n /**\n * Per-logical-key eviction-generation counter. {@linkcode evict} (whole\n * method) and {@linkcode evictKey} (single `{method, params}`) bump it\n * before touching the store; {@linkcode captureGeneration} reads it before\n * the request; {@linkcode write} skips when it moved — so a `list_changed`\n * arriving mid-walk, or a `resources/updated` arriving while a\n * `readResource()` for the same URI is in flight, is not overwritten by\n * the in-flight request's stale write. The map key is `method` for the\n * list singletons and `` `${method}\\0${params}` `` for per-URI keys.\n *\n * Growth is bounded by keys the CLIENT has issued a `captureGeneration`\n * for: {@linkcode captureGeneration} records the key (so an interleaved\n * {@linkcode evictKey} sees there is an in-flight write to suppress);\n * {@linkcode evictKey} only bumps a key that is already recorded — a\n * server streaming `notifications/resources/updated` for URIs the client\n * has never read therefore cannot grow this map.\n */\n private readonly _evictionGeneration = new Map<string, number>();\n /**\n * `name → Tool` index derived from the cached `tools/list` entry, memoized\n * against the entry's `stamp` so it re-derives only when the backing entry\n * changes (mcp.d's `cachedTool` pattern).\n */\n private _toolIndex?: { stamp: number; byName: Map<string, Tool> };\n /**\n * `name → compiled output-schema validator` derived from the cached\n * `tools/list` entry; same stamp-keyed memoization as `_toolIndex`. Typed\n * `unknown` so this class stays free of any validator-provider dependency\n * — the compile callback supplied to {@linkcode outputValidator} owns the\n * concrete type.\n */\n private _toolOutputValidatorIndex?: { stamp: number; byName: Map<string, unknown> };\n /**\n * The connected server's identity (`serverInfo.name@version`, the\n * transport's `sessionId`, or a client-generated per-connection\n * surrogate). Set by the `Client` immediately after a successful connect;\n * `''` is the pre-connect sentinel. Every storage partition is derived\n * from this (see `_partitionFor`), so two clients sharing one store but\n * connected to different servers never collide on `tools/list` and a\n * server cannot read another server's `'public'` entries.\n */\n private _serverIdentity = '';\n\n constructor(\n private readonly _store: ResponseCacheStore,\n /**\n * Whether `_store` was supplied by the caller. A user-supplied store is\n * never `clear()`ed by {@linkcode resetForReconnect} (defeats the only\n * reason to supply one).\n */\n private readonly _isUserSupplied: boolean,\n /**\n * Sink for a custom store's `set()`/`evict()` failure. {@linkcode write}\n * never lets a store rejection cost the caller a result it already\n * fetched — the failure is reported here and the write resolves. The\n * `Client` wires this to `onerror`.\n */\n private readonly _reportError: (error: unknown) => void = () => {},\n /**\n * The opaque per-principal identifier for this client (the\n * `private`-scope storage slot within the connected server's\n * namespace). `''` (the default) makes the `private` slot identical to\n * the server's shared `public` slot — the safe single-tenant posture.\n * See `_partitionFor`.\n */\n private readonly _cachePartition: string = '',\n /**\n * Clock seam (testing). The freshness check (`entry.expiresAt > now()`)\n * and the `expiresAt = now() + ttlMs` stamp both read it via\n * {@linkcode now}. Default `Date.now`.\n */\n private readonly _now: () => number = Date.now\n ) {}\n\n /** The clock used for every freshness computation and check. */\n now(): number {\n return this._now();\n }\n\n /**\n * Record the connected server's identity. Called by `Client` immediately\n * after a successful connect: `serverInfo.name@version` when the server\n * identified itself, else the transport's `sessionId`, else a\n * client-generated per-connection surrogate (`serverInfo` is a spec\n * SHOULD on 2026-07-28, so anonymous servers exist). Surrogate-keyed\n * partitions are NOT stable across reconnects — no identity means no\n * cross-connection cache reuse, and a shared long-lived store should\n * bound its own size accordingly. Every partition derived after this\n * call is scoped to this identity; entries written under the pre-connect\n * `''` sentinel are no longer reachable.\n */\n setServerIdentity(identity: string): void {\n this._serverIdentity = identity;\n }\n\n /**\n * Derive the storage partition for `scope`. The encoding is\n * `JSON.stringify([serverIdentity, principal])` — JSON escaping makes it\n * collision-free by construction: a malicious server cannot craft a\n * `serverInfo.name`/`version` whose concatenated form bleeds into another\n * server's namespace or another principal's slot, regardless of `@` / `|`\n * / `\"` / NUL in the server-controlled strings. `'public'` →\n * `[serverIdentity, '']` (shared within this server); `'private'` →\n * `[serverIdentity, cachePartition]`. When `cachePartition` is `''` the\n * two coincide.\n */\n private _partitionFor(scope: CacheScope): string {\n return JSON.stringify([this._serverIdentity, scope === 'public' ? '' : this._cachePartition]);\n }\n\n /**\n * Two-probe lookup: this client's own (private) partition first, then the\n * connected server's shared (public) partition. The shared probe is gated\n * on `entry.scope === 'public'` — a co-tenant client that omits\n * `cachePartition` writes its `'private'`-scoped entries at the public\n * partition, and serving those to a correctly-partitioned client would\n * leak private bodies (mcp.d's `cachedEntry` two-probe order; the scope\n * gate is defence-in-depth on top of the partition split). When\n * `cachePartition` is `''` the two partitions are identical and only one\n * probe is issued.\n */\n private async _probe(method: string, params?: string): Promise<CacheEntry | undefined> {\n const key = { method, params: params ?? '' };\n const ownPartition = this._partitionFor('private');\n const own = await this._store.get({ ...key, partition: ownPartition });\n if (own !== undefined) return own;\n const sharedPartition = this._partitionFor('public');\n if (sharedPartition === ownPartition) return undefined;\n const shared = await this._store.get({ ...key, partition: sharedPartition });\n return shared?.scope === 'public' ? shared : undefined;\n }\n\n /**\n * Bump the per-method generation (so an in-flight {@linkcode write} for the\n * same method becomes a no-op) and drop the connected server's two list\n * singletons (own + shared partition; `params: ''`). The generation bump\n * is unconditional and FIRST — the {@linkcode write} race guard relies on\n * the bump, not on the store's deletes completing.\n *\n * Eviction is scoped to this client's `[serverIdentity, principal]`\n * partitions (mirroring {@linkcode evictKey}) — the method-wide\n * `store.evict()` is NOT called, so on a shared store one server's\n * `list_changed` cannot wipe a co-tenant's entry. A custom store's\n * `delete()` may throw or reject; each partition is guarded\n * independently so a failure on one does not skip the other, the failure\n * is reported via the constructor's sink, and the call resolves so\n * dispatch proceeds.\n */\n async evict(method: string): Promise<void> {\n this._evictionGeneration.set(method, (this._evictionGeneration.get(method) ?? 0) + 1);\n await this._deleteBoth(method, '');\n }\n\n /**\n * Guarded two-partition delete of `{method, params}`: each partition's\n * `delete` is independently wrapped so a custom store's failure on one is\n * reported and does not skip the other, and the call always resolves.\n */\n private async _deleteBoth(method: string, params: string): Promise<void> {\n const ownPartition = this._partitionFor('private');\n const sharedPartition = this._partitionFor('public');\n try {\n await this._store.delete({ method, params, partition: ownPartition });\n } catch (error) {\n this._reportError(error);\n }\n if (sharedPartition !== ownPartition) {\n try {\n await this._store.delete({ method, params, partition: sharedPartition });\n } catch (error) {\n this._reportError(error);\n }\n }\n }\n\n /**\n * Drop the single logical entry `{method, params}` from BOTH the private\n * and public partitions for this client's connected server (mcp.d's\n * `invalidateLogical`). Used for `notifications/resources/updated`'s\n * per-URI eviction. The per-key generation is bumped FIRST (so an\n * in-flight {@linkcode write} for the same `{method, params}` becomes a\n * no-op and cannot re-cache the now-stale body) but only when the key was\n * already recorded by {@linkcode captureGeneration} — bounding the map to\n * keys the client has actually read. A custom store's `delete()` may\n * throw or reject; each partition's delete is guarded independently so a\n * failure on one does not skip the other, and the call resolves so\n * dispatch proceeds.\n */\n async evictKey(method: string, params: string): Promise<void> {\n const gk = genKey(method, params);\n // Only bump a key the client has actually captured: if no entry is\n // present there is no in-flight write to suppress, and an\n // unconditional bump would let a server streaming distinct-URI\n // `resources/updated` notifications grow this map without bound. The\n // store deletes still run regardless (a previously-written entry may\n // be held even when the generation entry has since been cleared by\n // `resetForReconnect`).\n const current = this._evictionGeneration.get(gk);\n if (current !== undefined) this._evictionGeneration.set(gk, current + 1);\n await this._deleteBoth(method, params);\n }\n\n /**\n * Snapshot the eviction generation for `{method, params}` before issuing\n * the request (a list walk's page 1, or a `resources/read` for `params`).\n * Records the key so an interleaved {@linkcode evictKey} for the same\n * `{method, params}` knows there is an in-flight write to suppress and\n * bumps; without the record, `evictKey`'s recorded-only bump would skip\n * and the stale body would be cached.\n */\n captureGeneration(method: string, params?: string): number {\n const gk = genKey(method, params);\n const current = this._evictionGeneration.get(gk) ?? 0;\n this._evictionGeneration.set(gk, current);\n return current;\n }\n\n /**\n * Write `value` under `{method}` unless the per-method generation moved\n * since `capturedGen` was taken — a `list_changed` that landed mid-walk has\n * already invalidated the result the caller is about to write, and\n * overwriting the eviction with the stale aggregate would lose the\n * invalidation.\n *\n * The value is stored as its JSON-serialized document; serialization\n * doubles as the mutation barrier, so a caller mutating the returned\n * aggregate cannot reach the cache or its derived indices. A value that\n * is not JSON-serializable (reachable only via in-process transports)\n * fails the write loudly into the `reportError` sink. A custom store\n * whose `set()` throws or rejects is routed to the same sink and the\n * write resolves — cache bookkeeping never costs the caller a result it\n * already fetched.\n *\n * `freshness` carries the client-computed `expiresAt` (absolute ms epoch,\n * `now + ttlMs`) and the server-reported `cacheScope`. The storage\n * `partition` is derived from the scope via `_partitionFor`:\n * `'public'` → `[serverIdentity, '']` (shared within this server);\n * `'private'` → `[serverIdentity, cachePartition]` (so a shared store\n * never serves a private entry to another identity). Absent `freshness`\n * preserves the substrate write (no `expiresAt`, private partition) — the\n * `tools/list` retain-for-schema posture: never served by\n * {@linkcode read}'s freshness gate, always readable by\n * {@linkcode toolDefinition}.\n *\n * After storing under the derived partition, the same `{method, params}`\n * is deleted from the OPPOSITE partition (mirroring {@linkcode evictKey}'s\n * two-partition posture). A server that flips a result's `cacheScope` for\n * the same key would otherwise leave the previous entry in the other slot\n * — and since `_probe` checks own-partition first, a stale private entry\n * would shadow the fresh public one (or a stale public entry would keep\n * serving co-tenants). Both store calls are independently guarded so a\n * custom store's failure on one does not skip the other.\n */\n async write(\n method: string,\n value: unknown,\n capturedGen: number,\n freshness?: { expiresAt: number; scope: CacheScope; params?: string }\n ): Promise<void> {\n if ((this._evictionGeneration.get(genKey(method, freshness?.params)) ?? 0) !== capturedGen) return;\n const params = freshness?.params ?? '';\n const ownPartition = this._partitionFor('private');\n const sharedPartition = this._partitionFor('public');\n const partition = (freshness?.scope ?? 'private') === 'public' ? sharedPartition : ownPartition;\n try {\n await this._store.set(\n { method, params, partition },\n { value: encodeCacheValue(value), expiresAt: freshness?.expiresAt, scope: freshness?.scope }\n );\n } catch (error) {\n this._reportError(error);\n }\n if (sharedPartition !== ownPartition) {\n try {\n await this._store.delete({\n method,\n params,\n partition: partition === ownPartition ? sharedPartition : ownPartition\n });\n } catch (error) {\n this._reportError(error);\n }\n }\n }\n\n /**\n * Serve the fresh cached result for `{method, params}`, or `undefined`.\n * Lookup is the two-probe order (own-partition then this server's shared\n * partition, gated on `scope === 'public'`); freshness is\n * `entry.expiresAt > now()` (a missing `expiresAt` is never fresh),\n * checked BEFORE decoding so stale entries cost no parse. Every hit is\n * freshly parsed, so the caller owns the value outright. An entry whose\n * document does not parse or is not an object (corrupted external\n * store) is reported,\n * deleted, and treated as a miss — deleted because a fresh-but-corrupt\n * entry would otherwise re-parse and re-report on every read until its\n * `expiresAt` passes.\n */\n async read(method: string, params?: string): Promise<{ value: unknown } | undefined> {\n const entry = await this._probe(method, params);\n if (entry?.expiresAt === undefined || !(entry.expiresAt > this.now())) return undefined;\n try {\n const parsed: unknown = JSON.parse(entry.value);\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw new TypeError('cached document is not an object');\n }\n return { value: parsed };\n } catch (error) {\n this._reportError(error);\n await this._deleteBoth(method, params ?? '');\n return undefined;\n }\n }\n\n /**\n * Connection reset. The per-instance default store IS cleared\n * (connection-scoped); a user-supplied store is NOT — that would defeat\n * the only reason to supply one. The generation map and every derived\n * index are dropped regardless: they are connection-scoped even when the\n * backing store survives, so the next read re-derives from whatever the\n * store still holds. The server identity returns to the pre-connect\n * sentinel. The default impl is synchronous, so the `MaybePromise<void>`\n * return is a plain void here and the caller need not await.\n */\n resetForReconnect(): void {\n if (!this._isUserSupplied) void this._store.clear();\n this._evictionGeneration.clear();\n this._toolIndex = undefined;\n this._toolOutputValidatorIndex = undefined;\n this._serverIdentity = '';\n }\n\n /**\n * The descriptor for tool `name` taken from the cached `tools/list` entry.\n * The `name → Tool` index is memoized against the entry's `stamp` and\n * re-derived only when the backing entry changes (mcp.d's `cachedTool`).\n * Returns `undefined` only when no `tools/list` response is held at all,\n * or the held list does not contain `name`.\n *\n * Consumed by `callTool()`'s SEP-2243 `_resolveXMcpHeaderScan` (mirroring)\n * and, via {@linkcode outputValidator}, its output-schema validation.\n */\n async toolDefinition(name: string): Promise<Tool | undefined> {\n const entry = await this._probe('tools/list');\n if (entry === undefined) {\n this._toolIndex = undefined;\n return undefined;\n }\n if (this._toolIndex?.stamp !== entry.stamp) {\n const list = this._decodeListTools(entry);\n const byName = new Map<string, Tool>();\n if (list !== undefined) for (const tool of list.tools) byName.set(tool.name, tool);\n // A failed decode memoizes an EMPTY index under the same stamp, so\n // the corrupt document is parsed (and reported) once per stamp —\n // not once per callTool — and a later rewrite re-derives.\n this._toolIndex = { stamp: entry.stamp, byName };\n }\n return this._toolIndex.byName.get(name);\n }\n\n /**\n * The compiled output-schema validator for tool `name`, derived from the\n * cached `tools/list` entry — same source and same stamp-keyed\n * memoization as {@linkcode toolDefinition}. The `name → validator` index\n * re-derives only when the backing entry's stamp changes (a refetched\n * `tools/list` recompiles; a `list_changed` eviction drops it). Returns\n * `undefined` when no `tools/list` is held, the tool is absent, or it has\n * no `outputSchema`.\n *\n * `compile` is the caller-supplied validator-compile callback (the\n * `Client` passes its `_jsonSchemaValidator` wrapper) so this\n * class carries no validator-provider dependency. One tool's uncompilable\n * `outputSchema` (e.g. an invalid `pattern` regex or unresolvable `$ref`)\n * must not poison every other tool's `callTool` — the callback isolates\n * that compile error per tool by returning a per-tool error variant which\n * the index stores alongside the good ones, and `callTool` surfaces it as\n * a typed `InvalidParams` only for that name. Because the error is held on\n * this stamp-keyed substrate (not a parallel map), it inherits the\n * substrate's invalidation lifecycle: a `list_changed` eviction drops it,\n * a refetched `tools/list` re-derives it, and `resetForReconnect` clears\n * the lot.\n */\n async outputValidator<V>(name: string, compile: (tool: Tool) => V | undefined): Promise<V | undefined> {\n const entry = await this._probe('tools/list');\n if (entry === undefined) {\n this._toolOutputValidatorIndex = undefined;\n return undefined;\n }\n if (this._toolOutputValidatorIndex?.stamp !== entry.stamp) {\n const list = this._decodeListTools(entry) ?? { tools: [] };\n const byName = new Map<string, unknown>();\n for (const tool of list.tools) {\n const compiled = compile(tool);\n if (compiled !== undefined) byName.set(tool.name, compiled);\n }\n this._toolOutputValidatorIndex = { stamp: entry.stamp, byName };\n }\n return this._toolOutputValidatorIndex.byName.get(name) as V | undefined;\n }\n\n /** Parse a held `tools/list` document for the index builders; a document\n * that does not parse OR whose `tools` is not an array of objects\n * (both mean a corrupted external store) is reported and treated as if\n * nothing were held. Callers memoize the outcome against the entry's\n * stamp, so a corrupt document costs one parse + report per stamp, not\n * per lookup. */\n private _decodeListTools(entry: CacheEntry): ListToolsResult | undefined {\n try {\n const parsed = JSON.parse(entry.value) as ListToolsResult | null;\n if (!Array.isArray(parsed?.tools) || !parsed.tools.every(t => t !== null && typeof t === 'object')) {\n throw new TypeError('cached tools/list document has a malformed tools array');\n }\n return parsed;\n } catch (error) {\n this._reportError(error);\n return undefined;\n }\n }\n}\n\n/**\n * Serialize a result for storage; throws TypeError for anything without a\n * JSON representation (legal wire results always have one). Two failure\n * modes need folding into that one throw: `JSON.stringify` throws on cycles\n * and BigInt, but silently returns `undefined` (not a string) for a\n * top-level function, symbol, or `undefined`.\n */\nfunction encodeCacheValue(value: unknown): string {\n let json: string | undefined;\n try {\n json = JSON.stringify(value);\n } catch (error) {\n throw new TypeError(`cache value is not JSON-serializable: ${error instanceof Error ? error.message : String(error)}`);\n }\n if (typeof json !== 'string') throw new TypeError('cache value is not JSON-serializable: it has no JSON representation');\n return json;\n}\n","/**\n * Auth-seam provenance stamp (internal — not part of the public API).\n *\n * Errors escaping a transport auth seam — the `authProvider.token()` read,\n * an `onUnauthorized` invocation (SDK adapter or custom user callback), the\n * 403 step-up flow, the transport's own auth-failure constructions — are\n * stamped at the throw boundary. The version-negotiation probe routes stamped\n * errors as auth outcomes; provenance is recorded where it is known, never\n * reconstructed from error types downstream.\n *\n * `Symbol.for` uses the global symbol registry, so the stamp survives a\n * duplicated SDK copy in one process (bundler double-install, version skew)\n * by design: both copies resolve the same symbol.\n */\nconst AUTH_SEAM = Symbol.for('mcp.authSeamEscape');\n\n/**\n * Stamp `error` as an auth-seam escape and return it — identity-preserving\n * (the same object flows on, `instanceof` and `.cause` chains intact). A\n * frozen/sealed object is returned unstamped rather than replaced: identity\n * outranks provenance. Primitive throws cannot carry the stamp.\n */\nexport function markAuthSeamEscape<T>(error: T): T {\n if ((typeof error === 'object' && error !== null) || typeof error === 'function') {\n try {\n Object.defineProperty(error, AUTH_SEAM, { value: true, configurable: true });\n } catch {\n // Frozen/sealed: leave unstamped.\n }\n }\n return error;\n}\n\n/** Whether `error` escaped through a transport auth seam. */\nexport function isAuthSeamEscape(error: unknown): boolean {\n return (\n ((typeof error === 'object' && error !== null) || typeof error === 'function') &&\n (error as Record<PropertyKey, unknown>)[AUTH_SEAM] === true\n );\n}\n","/**\n * Probe outcome classifier (pure module): maps the outcome of the connect-time\n * `server/discover` probe onto one of four verdicts — modern era, the\n * spec-mandated `-32022` corrective continuation, legacy fallback (the plain\n * 2025 `initialize` handshake — on the probed connection for in-place probes,\n * on the session child's fresh pipe when the probe rode a disposable\n * sibling), or a typed connect error.\n *\n * The classifier is deliberately conservative: anything it does not positively\n * recognize as modern resolves to the legacy fallback, and a network outage or\n * an auth-status rejection (HTTP 401/403) is a typed connect error, never an\n * era verdict. The verdicts apply to the\n * negotiation phase only — an established modern connection is never silently\n * demoted to `initialize` by a later failure.\n */\nimport type { DiscoverResult } from '@modelcontextprotocol/core-internal';\nimport {\n codecForVersion,\n MODERN_WIRE_REVISION,\n modernProtocolVersions,\n SdkError,\n SdkErrorCode,\n SdkHttpError,\n UnsupportedProtocolVersionError\n} from '@modelcontextprotocol/core-internal';\n\n/**\n * The runtime environment the probe executed in. Only consulted for the\n * network-failure row: a browser CORS-preflight rejection is treated as a\n * legacy signal, while in Node a network failure stays a typed connect error.\n */\nexport type ProbeEnvironment = 'node' | 'browser';\n\n/**\n * The transport class the probe ran on. Consulted for the timeout and closed\n * rows: a stdio probe that times out — or whose child exits, closing the\n * connection — signals a legacy server, while an HTTP timeout or close stays\n * a typed error. Anything that is not the stdio child-process transport is\n * treated like HTTP.\n */\nexport type ProbeTransportKind = 'stdio' | 'http';\n\n/**\n * A normalized probe outcome, produced by the connect-time wiring from the raw\n * transport exchange.\n */\nexport type ProbeOutcome =\n | { kind: 'result'; result: unknown }\n /** Answered with a JSON-RPC error (any HTTP status, including 200-bodied errors and stdio in-band errors). */\n | { kind: 'rpc-error'; code: number; message: string; data?: unknown }\n /** The HTTP layer rejected the probe POST (non-2xx); `body` is the raw response text and `statusText` the HTTP reason phrase, when available. */\n | { kind: 'http-error'; status: number; body?: string; statusText?: string }\n | { kind: 'network-error'; error: unknown }\n /** The transport's auth flow challenged or failed during the probe send — an error stamped at a transport auth seam, or an `UnauthorizedError` (the foreign-transport contract). `error` propagates unchanged. */\n | { kind: 'auth-required'; error: Error }\n /** The transport reported close while the probe awaited its reply. */\n | { kind: 'closed' }\n /** No response arrived within the probe timeout. */\n | { kind: 'timeout'; timeoutMs: number };\n\nexport interface ProbeClassifierContext {\n /** Modern-era versions this client can negotiate, in preference order (never empty). */\n clientModernVersions: readonly string[];\n /** The version the probe carried in its `_meta` envelope (used to synthesize `data.requested` on typed errors). */\n requestedVersion: string;\n /**\n * Whether a legacy `initialize` fallback is possible — `false` for a\n * modern-only client and for `pin` mode. Without a fallback, rows carrying\n * modern evidence but no usable version overlap — a `DiscoverResult` with\n * no overlapping version, or a `-32022` whose `data.supported` lists only\n * legacy revisions — yield a typed `UnsupportedProtocolVersionError` built\n * from that evidence; the remaining rows that would have fallen back still\n * classify as `legacy`, and the caller reports them as a typed negotiation\n * error instead of starting an `initialize` handshake.\n */\n fallbackAvailable: boolean;\n /** See {@linkcode ProbeEnvironment}. */\n environment: ProbeEnvironment;\n /** See {@linkcode ProbeTransportKind}. */\n transportKind: ProbeTransportKind;\n}\n\nexport type ProbeVerdict =\n /** Definitive modern evidence: select `version` and continue without `initialize`. */\n | { kind: 'modern'; version: string; discover: DiscoverResult }\n /**\n * `-32022` with a mutual modern version: re-send the probe at `version`.\n * Spec-mandated select-and-continue — the caller runs it exactly once and\n * arms a loop guard on the second rejection, throwing `error`.\n */\n | { kind: 'corrective'; version: string; error: UnsupportedProtocolVersionError }\n /** Definitive legacy signal or unrecognized shape: perform the plain legacy `initialize` handshake (on the probed connection in the in-place modes; on the session child's fresh pipe on the sibling path). */\n | { kind: 'legacy' }\n /** Typed connect error — never converted to an era verdict. */\n | { kind: 'error'; error: Error };\n\n/**\n * A cached era verdict for `connect({ prior })` — the persistable subset of\n * the {@linkcode ProbeVerdict} vocabulary (`'modern'` = speaks 2026-07-28+,\n * `'legacy'` = 2025-era `initialize` only). Freshness is the supplying host's\n * responsibility: a stale modern verdict fails loudly at the first request,\n * but a stale legacy verdict succeeds silently forever (an upgraded server\n * still answers `initialize`) — date cached legacy verdicts in your own\n * storage and stop supplying them past your policy horizon. Full recipe:\n * the gateway guide (`docs/advanced/gateway.md`).\n */\nexport type PriorDiscovery =\n /** Adopt `discover` directly: zero round trips. */\n | { kind: 'modern'; discover: DiscoverResult }\n /** Known-legacy server: skip the `server/discover` probe and run the plain legacy `initialize` handshake. */\n | { kind: 'legacy' };\n\n/** The `-32022` UnsupportedProtocolVersion protocol error code (negotiation-phase recognition). */\nconst UNSUPPORTED_PROTOCOL_VERSION = -32_022;\n/**\n * Deliberately not probe-recognized in either direction: deployed servers\n * overload `-32001` (the SDK-conventional `Session not found` body on a 2025\n * stateful server), and the spec-assigned `-32020` (`HeaderMismatch`) /\n * `-32021` (`MissingRequiredClientCapability`) are not era evidence — all\n * fall into the conservative legacy default.\n */\nconst NOT_PROBE_RECOGNIZED = new Set([-32_001, -32_020, -32_021]);\n\n/**\n * Classify a single probe outcome. Pure: no I/O, no state — loop-guard and\n * retry state live in the caller.\n */\nexport function classifyProbeOutcome(outcome: ProbeOutcome, context: ProbeClassifierContext): ProbeVerdict {\n switch (outcome.kind) {\n case 'result': {\n return classifyResult(outcome.result, context);\n }\n case 'rpc-error': {\n return classifyRpcError(outcome, context);\n }\n case 'http-error': {\n return classifyHttpError(outcome, context);\n }\n case 'network-error': {\n return classifyNetworkError(outcome.error, context);\n }\n case 'auth-required': {\n // Not era evidence: propagate the auth challenge unchanged so the\n // caller can run finishAuth() and reconnect — the reconnect probes\n // again with the token and settles the era with real evidence.\n // Converting to a legacy fallback here would re-run the auth flow\n // inside the same connect (a second authorization prompt) and then\n // handshake an auth-gated modern server as legacy.\n return { kind: 'error', error: outcome.error };\n }\n case 'closed': {\n if (context.transportKind === 'stdio') {\n // A stdio child that exits on the unrecognized probe instead of\n // answering is a legacy signal — the same backward-compatibility\n // rule as the timeout row below (SDKs like the official Rust one\n // terminate the server on ANY pre-initialize request).\n return { kind: 'legacy' };\n }\n // On HTTP a mid-probe close is an ambiguous network condition — the\n // same typed connect error as any probe transport failure.\n return classifyNetworkError(new Error('Connection closed during the version negotiation probe'), context);\n }\n case 'timeout': {\n if (context.transportKind === 'stdio') {\n // Per the stdio transport's backward-compatibility rule, a probe\n // nobody answers within the timeout indicates a legacy server —\n // fall back to `initialize` (the sibling path runs it on the\n // session child's fresh pipe; in-place probes reuse the stream).\n return { kind: 'legacy' };\n }\n // On HTTP a deployed server answers, so silence is an outage, not a\n // legacy signal: keep the typed timeout error (the compatibility\n // matrix keys the HTTP legacy signal to a 4xx, never to silence).\n return {\n kind: 'error',\n error: new SdkError(SdkErrorCode.RequestTimeout, `Version negotiation probe timed out after ${outcome.timeoutMs}ms`, {\n timeout: outcome.timeoutMs\n })\n };\n }\n }\n}\n\nfunction classifyResult(result: unknown, context: ProbeClassifierContext): ProbeVerdict {\n // The 2026 wire schema carries the spec receiver-side leniency for\n // `resultType` ('complete'), `ttlMs` (0) and `cacheScope` ('private'), so\n // routing through the codec is behavior-neutral with the prior public-schema\n // parse for absent and malformed cache hints (`.catch()` per spec receiver\n // leniency): a server that omits or malforms them still classifies `modern`.\n const parsed = codecForVersion(MODERN_WIRE_REVISION).validateResult('server/discover', result);\n if (!parsed.ok) {\n // Unrecognized result shape: not modern evidence — conservative legacy fallback.\n return { kind: 'legacy' };\n }\n const supportedVersions = parsed.value.supportedVersions;\n const overlap = context.clientModernVersions.find(version => supportedVersions.includes(version));\n if (overlap !== undefined) {\n return { kind: 'modern', version: overlap, discover: parsed.value };\n }\n // A DiscoverResult with no overlap still drives era selection: the legacy\n // `initialize` fallback when available, otherwise a typed error.\n if (context.fallbackAvailable) {\n return { kind: 'legacy' };\n }\n return {\n kind: 'error',\n error: new UnsupportedProtocolVersionError({ supported: [...supportedVersions], requested: context.requestedVersion })\n };\n}\n\nfunction classifyRpcError(outcome: { code: number; message: string; data?: unknown }, context: ProbeClassifierContext): ProbeVerdict {\n const { code, message, data } = outcome;\n\n if (code === UNSUPPORTED_PROTOCOL_VERSION) {\n const supported = parseSupportedList(data);\n if (supported === undefined) {\n // -32022 without a valid data.supported list is not actionable modern evidence.\n return { kind: 'legacy' };\n }\n const requested = parseRequested(data) ?? context.requestedVersion;\n const error = new UnsupportedProtocolVersionError({ supported, requested }, message);\n const supportedModern = modernProtocolVersions(supported);\n const mutual = context.clientModernVersions.find(version => supportedModern.includes(version));\n if (mutual !== undefined) {\n // Mutual modern version: spec-mandated select-and-continue — never\n // fall back to initialize here.\n return { kind: 'corrective', version: mutual, error };\n }\n if (supportedModern.length > 0) {\n // Disjoint-but-modern list: typed error, never initialize.\n return { kind: 'error', error };\n }\n // Legacy-only list: definitive legacy signal (typed error for a modern-only client).\n return context.fallbackAvailable ? { kind: 'legacy' } : { kind: 'error', error };\n }\n\n if (NOT_PROBE_RECOGNIZED.has(code)) {\n return { kind: 'legacy' };\n }\n\n // Everything else — -32601, the deployed -32000 literals/free-text, code 0,\n // any unrecognized code — is a legacy signal or the conservative default.\n return { kind: 'legacy' };\n}\n\nfunction classifyHttpError(outcome: { status: number; body?: string; statusText?: string }, context: ProbeClassifierContext): ProbeVerdict {\n // Auth statuses are never era evidence, and a 401/403 body is the auth\n // layer's, not the server/discover handler's — this row ranks above the\n // JSON-RPC body parse. Parallel to the auth-required row: a typed failure\n // naming the status (response text on `data.text`), never a legacy\n // fallback. The codes are the auth ones, NOT EraNegotiationFailed: hosts\n // key era-recovery recipes (e.g. the gateway guide's cached-verdict flow)\n // on EraNegotiationFailed, and an auth wall must never enter era recovery\n // — persisting a legacy verdict for it would recreate the silent-legacy\n // bug at the fleet level.\n if (outcome.status === 401 || outcome.status === 403) {\n const isDenial = outcome.status === 403;\n return {\n kind: 'error',\n error: new SdkHttpError(\n isDenial ? SdkErrorCode.ClientHttpForbidden : SdkErrorCode.ClientHttpAuthentication,\n `Version negotiation failed: ${isDenial ? 'the server denied access (HTTP 403)' : 'the server requires authorization (HTTP 401)'}`,\n {\n status: outcome.status,\n statusText: outcome.statusText,\n text: outcome.body\n }\n )\n };\n }\n if (outcome.status >= 500) {\n // A server failure is not era evidence, whatever the body says — this\n // row too ranks above the JSON-RPC body parse (a 5xx body is the\n // infrastructure's: a mid-deploy gateway's JSON error page, a crashed\n // handler's -32603, neither a server/discover verdict). The spec keys\n // the HTTP legacy signal to client-error rejections (a 2025 server\n // answers the unknown probe 4xx), never to 5xx.\n return {\n kind: 'error',\n error: new SdkHttpError(\n SdkErrorCode.EraNegotiationFailed,\n `Version negotiation failed: the server answered the probe with HTTP ${outcome.status}`,\n {\n status: outcome.status,\n statusText: outcome.statusText,\n text: outcome.body\n }\n )\n };\n }\n // HTTP-rejected probes carry their JSON-RPC error in the response body — classify it like an in-band error.\n const rpcError = parseJsonRpcErrorBody(outcome.body);\n if (rpcError !== undefined) {\n return classifyRpcError(rpcError, context);\n }\n // Unparseable or unrecognized 4xx rejection: conservative legacy fallback.\n // With the auth and 5xx rows above, this row's legacy set now equals the\n // spec-licensed set exactly — the 4xx a deployed 2025 server answers a\n // request it does not recognize.\n return { kind: 'legacy' };\n}\n\nfunction classifyNetworkError(error: unknown, context: ProbeClassifierContext): ProbeVerdict {\n if (context.environment === 'browser' && isOpaqueFetchTypeError(error)) {\n // A browser CORS-preflight rejection against a deployed 2025 server is\n // an opaque TypeError. The legacy fallback also preflights (its JSON\n // Content-Type is non-simple), but carries only the pre-2026 headers a\n // deployed server's CORS allowlist already covers — so it can proceed\n // where the probe's 2026 headers could not.\n return { kind: 'legacy' };\n }\n return {\n kind: 'error',\n error: new SdkError(SdkErrorCode.EraNegotiationFailed, `Version negotiation probe failed: ${describeError(error)}`, {\n cause: error\n })\n };\n}\n\nfunction isOpaqueFetchTypeError(error: unknown): boolean {\n // Cross-realm safe: a bundled or sandboxed fetch may not share this realm's TypeError identity.\n return error instanceof TypeError || (error instanceof Error && error.name === 'TypeError');\n}\n\nfunction describeError(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nfunction parseSupportedList(data: unknown): string[] | undefined {\n if (typeof data !== 'object' || data === null) return undefined;\n const supported = (data as { supported?: unknown }).supported;\n if (!Array.isArray(supported) || supported.length === 0 || !supported.every(v => typeof v === 'string')) {\n return undefined;\n }\n return supported as string[];\n}\n\nfunction parseRequested(data: unknown): string | undefined {\n if (typeof data !== 'object' || data === null) return undefined;\n const requested = (data as { requested?: unknown }).requested;\n return typeof requested === 'string' ? requested : undefined;\n}\n\nfunction parseJsonRpcErrorBody(body: string | undefined): { code: number; message: string; data?: unknown } | undefined {\n if (body === undefined || body === '') return undefined;\n let parsed: unknown;\n try {\n parsed = JSON.parse(body);\n } catch {\n return undefined;\n }\n if (typeof parsed !== 'object' || parsed === null) return undefined;\n const error = (parsed as { error?: unknown }).error;\n if (typeof error !== 'object' || error === null) return undefined;\n const { code, message, data } = error as { code?: unknown; message?: unknown; data?: unknown };\n if (typeof code !== 'number') return undefined;\n return { code, message: typeof message === 'string' ? message : '', data };\n}\n","/**\n * Connect-time protocol version negotiation (opt-in via\n * `ClientOptions.versionNegotiation`): the option surface, the probe window (a\n * raw transport exchange run before the Protocol machinery attaches), and the\n * negotiation engine driving the pure {@linkcode classifyProbeOutcome} classifier.\n *\n * Invariants: the probe uses string ids and consumes no Protocol message ids, so\n * a legacy fallback's `initialize` is byte-equivalent to a plain legacy connect;\n * the transport's protocol-version slot is never mutated during negotiation\n * (probe headers derive from the probe message body) and is set exactly once\n * after a modern resolution; while the probe window is open, inbound messages\n * that are not the probe response are dropped with zero bytes written back.\n */\nimport type { ClientCapabilities, DiscoverResult, Implementation, JSONRPCRequest, Transport } from '@modelcontextprotocol/core-internal';\nimport {\n codecForVersion,\n isJSONRPCErrorResponse,\n isJSONRPCResultResponse,\n isModernProtocolVersion,\n legacyProtocolVersions,\n modernProtocolVersions,\n SdkError,\n SdkErrorCode,\n SdkHttpError,\n SUPPORTED_MODERN_PROTOCOL_VERSIONS\n} from '@modelcontextprotocol/core-internal';\n\nimport { UnauthorizedError } from './auth';\nimport { isAuthSeamEscape } from './authSeam';\nimport type { ProbeEnvironment, ProbeOutcome, ProbeTransportKind, ProbeVerdict } from './probeClassifier';\nimport { classifyProbeOutcome } from './probeClassifier';\n\n/**\n * Probe policy for `'auto'` and pinned negotiation modes.\n *\n * There is no special probe timeout opinion: the probe inherits the client's\n * STANDARD request timeout unless `timeoutMs` overrides it.\n */\nexport interface VersionNegotiationProbeOptions {\n /**\n * Timeout for the probe exchange, in milliseconds.\n *\n * The timeout verdict is transport-aware: on stdio, a probe that gets no\n * response within the timeout indicates a legacy server and falls back to\n * the `initialize` handshake (measured on the disposable sibling for the\n * SDK's own stdio transport, with the fallback running on the session\n * child's fresh pipe; in place for custom stdio-shaped transports); on\n * HTTP, where a deployed server answers and silence means an outage,\n * `connect()` rejects with the standard typed timeout error instead.\n *\n * @default the standard request timeout (`DEFAULT_REQUEST_TIMEOUT_MSEC`, or the `timeout` passed to `connect()`)\n */\n timeoutMs?: number;\n\n /**\n * Number of times to re-send the probe after a timeout before reaching the\n * timeout verdict. Governs timeout re-sends only — the spec-mandated\n * `-32022` corrective continuation (select-and-continue with a mutual\n * version) is a separate negotiation step and is never counted against\n * `maxRetries`.\n *\n * @default 0 (no retries)\n */\n maxRetries?: number;\n}\n\n/**\n * Negotiation mode:\n *\n * - `'legacy'` — no negotiation: the plain 2025 connect sequence, byte-identical\n * to a client without this option.\n * - `'auto'` — probe with `server/discover` at connect; conservative fallback to\n * the plain legacy `initialize` handshake unless the outcome is definitive\n * modern evidence. Network outage rejects with a typed connect error; a\n * probe timeout falls back to `initialize` on stdio (a silent server on a\n * local pipe is a legacy server) and rejects with a typed timeout error on\n * HTTP (silence there is an outage). On the SDK's stdio transport (the base\n * `StdioClientTransport` exactly; subclasses probe in place) the probe\n * runs on a short-lived sibling process spawned from the same parameters\n * (its stderr is discarded) and the caller's transport starts once, after\n * the era is known — so a child that exits on the unrecognized probe, the\n * shape of servers built on SDKs that terminate on any pre-`initialize`\n * request, is simply a legacy server. A mid-probe connection close on HTTP\n * (or on a custom stdio-shaped transport, which probes in place) rejects\n * with the typed connect error.\n * - `{ pin: '<version>' }` — modern era at exactly the pinned revision: the\n * connect-time `server/discover` must offer it. No fallback — anything else\n * fails loudly with a typed error.\n */\nexport type VersionNegotiationMode = 'legacy' | 'auto' | { pin: string };\n\n/**\n * Opt-in protocol version negotiation, configured on\n * `ClientOptions.versionNegotiation`.\n */\nexport interface VersionNegotiationOptions {\n /**\n * @default 'legacy'\n */\n mode?: VersionNegotiationMode;\n\n /**\n * Probe timeout/retry policy (only consulted by the probing modes).\n */\n probe?: VersionNegotiationProbeOptions;\n}\n\n/**\n * The default mode when `versionNegotiation` (or its `mode`) is absent;\n * changing the default later is a flip of this single line.\n */\nconst DEFAULT_VERSION_NEGOTIATION_MODE: VersionNegotiationMode = 'legacy';\n\n/** A fully resolved negotiation plan for one `connect()` call. */\nexport type ResolvedVersionNegotiation =\n | { kind: 'legacy' }\n | {\n kind: 'auto';\n /** Modern versions this client offers, in preference order (never empty). */\n modernVersions: string[];\n /** Whether this client can fall back to the legacy `initialize` handshake. */\n fallbackAvailable: boolean;\n probe: VersionNegotiationProbeOptions;\n }\n | { kind: 'pin'; version: string; probe: VersionNegotiationProbeOptions };\n\n/**\n * Resolve the negotiation options into a per-connect plan. The raw (not\n * defaulted) `supportedProtocolVersions` option supplies the modern offer list;\n * a list without any legacy version makes this a modern-only client (no fallback).\n */\nexport function resolveVersionNegotiation(\n options: VersionNegotiationOptions | undefined,\n supportedProtocolVersionsOption: readonly string[] | undefined\n): ResolvedVersionNegotiation {\n const mode = options?.mode ?? DEFAULT_VERSION_NEGOTIATION_MODE;\n if (mode === 'legacy') {\n return { kind: 'legacy' };\n }\n const probe = options?.probe ?? {};\n if (typeof mode === 'object') {\n if (!isModernProtocolVersion(mode.pin)) {\n throw new TypeError(\n `versionNegotiation: { pin: '${mode.pin}' } is not a modern protocol revision — ` +\n `pinning is for 2026-07-28 and later; omit versionNegotiation (or use mode: 'legacy') for 2025-era servers.`\n );\n }\n return { kind: 'pin', version: mode.pin, probe };\n }\n const explicitModern = supportedProtocolVersionsOption ? modernProtocolVersions(supportedProtocolVersionsOption) : [];\n const modernVersions = explicitModern.length > 0 ? explicitModern : [...SUPPORTED_MODERN_PROTOCOL_VERSIONS];\n const fallbackAvailable = supportedProtocolVersionsOption ? legacyProtocolVersions(supportedProtocolVersionsOption).length > 0 : true;\n return { kind: 'auto', modernVersions, fallbackAvailable, probe };\n}\n\n/** Detect the probe environment for the network-failure row — see {@linkcode ProbeEnvironment}. */\nexport function detectProbeEnvironment(): ProbeEnvironment {\n const g = globalThis as { window?: unknown; document?: unknown };\n return g.window !== undefined && g.document !== undefined ? 'browser' : 'node';\n}\n\n/**\n * Detect the transport class for the transport-aware timeout and closed verdicts (see\n * {@linkcode ProbeTransportKind}). The stdio child-process transport is\n * recognized structurally (`stderr`/`pid` accessors, no `instanceof` — safe\n * across bundles); everything else is treated like HTTP.\n */\nexport function detectProbeTransportKind(transport: Transport): ProbeTransportKind {\n return 'stderr' in transport && 'pid' in transport ? 'stdio' : 'http';\n}\n\n/** Raw reply from one probe exchange, before normalization. */\ntype RawProbeReply =\n | { kind: 'response'; result?: unknown; error?: { code: number; message: string; data?: unknown } }\n | { kind: 'send-error'; error: unknown }\n | { kind: 'closed' }\n | { kind: 'timeout' };\n\n/**\n * Temporary ownership of a raw transport for the negotiation exchange, before\n * the Protocol machinery attaches. `open()` installs the window's handlers and\n * starts the transport; `release()` detaches them and arms a one-shot `start()`\n * pass-through so the subsequent Protocol connect (which always starts its\n * transport) takes over the already-started channel without a double-start error.\n *\n * Handlers a caller pre-set on the transport before `connect()` are saved on\n * open and restored on detach, so `Protocol.connect()` finds and chains them\n * exactly as it would on a plain (non-negotiating) connect. Error and close\n * events are forwarded to the saved handlers during the window, so negotiation\n * does not change what a pre-attached observer sees of the transport\n * lifecycle. (Inbound messages are deliberately NOT forwarded — the window's\n * drop-guard is a module invariant, and the probe reply has no plain-connect\n * counterpart; a pre-set `onmessage` is restored at detach and chained by\n * `Protocol.connect()` like the others.)\n */\nclass ProbeWindow {\n private _pending: { id: string; resolve: (reply: RawProbeReply) => void } | undefined;\n private _probeCounter = 0;\n private readonly _savedOnMessage: Transport['onmessage'];\n private readonly _savedOnError: Transport['onerror'];\n private readonly _savedOnClose: Transport['onclose'];\n private _closeDelivered = false;\n\n private constructor(private readonly _transport: Transport) {\n this._savedOnMessage = _transport.onmessage;\n this._savedOnError = _transport.onerror;\n this._savedOnClose = _transport.onclose;\n }\n\n static async open(transport: Transport): Promise<ProbeWindow> {\n const window = new ProbeWindow(transport);\n transport.onmessage = message => {\n const pending = window._pending;\n if (\n pending !== undefined &&\n (isJSONRPCResultResponse(message) || isJSONRPCErrorResponse(message)) &&\n message.id === pending.id\n ) {\n window._pending = undefined;\n if (isJSONRPCResultResponse(message)) {\n pending.resolve({ kind: 'response', result: message.result });\n } else {\n pending.resolve({ kind: 'response', error: message.error });\n }\n return;\n }\n // Probe-window guard: drop everything else with zero bytes written back (see module doc).\n };\n transport.onerror = error => {\n // Out-of-band transport errors are not necessarily fatal; the probe\n // resolves via a send failure, the close signal, or the timeout.\n window._savedOnError?.(error);\n };\n transport.onclose = () => {\n const pending = window._pending;\n if (pending !== undefined) {\n window._pending = undefined;\n pending.resolve({ kind: 'closed' });\n }\n // Forward exactly once: after a mid-window close is delivered, the\n // restored handler must not re-deliver it when cleanup paths call\n // `transport.close()` again.\n window._closeDelivered = true;\n window._savedOnClose?.();\n };\n try {\n await transport.start();\n } catch (error) {\n window.detach();\n throw error;\n }\n return window;\n }\n\n /**\n * Send one probe request and await its reply. Probe ids are strings, so they\n * never collide with Protocol's numeric ids (e.g. on a shared stdio pipe).\n */\n async exchange(buildRequest: (id: string) => JSONRPCRequest, timeoutMs: number): Promise<RawProbeReply> {\n const id = `server-discover-probe-${++this._probeCounter}`;\n return new Promise<RawProbeReply>(resolve => {\n let settled = false;\n const settle = (reply: RawProbeReply) => {\n if (settled) return;\n settled = true;\n clearTimeout(timer);\n if (this._pending?.id === id) {\n this._pending = undefined;\n }\n resolve(reply);\n };\n const timer = setTimeout(() => settle({ kind: 'timeout' }), timeoutMs);\n this._pending = { id, resolve: settle };\n this._transport.send(buildRequest(id)).catch((error: unknown) => settle({ kind: 'send-error', error }));\n });\n }\n\n /** Detach the window's handlers, restoring any the caller pre-set, leaving the transport's own `start` untouched. */\n detach(): void {\n this._pending = undefined;\n this._transport.onmessage = this._savedOnMessage;\n this._transport.onerror = this._savedOnError;\n if (this._closeDelivered && this._savedOnClose !== undefined) {\n // The forwarded mid-window close is spent — the caller's cleanup\n // close() must not re-deliver it — but the slot must not be emptied\n // either: the caller still owns the transport, and its observer must\n // keep seeing later closes. The skip is scoped to the cleanup close\n // via disarmSpentCloseGuard(): transports whose close() re-fires\n // onclose (HTTP) consume it there; transports that never re-fire\n // (stdio: onclose comes only from the child's close event, which\n // already happened) would otherwise leave it armed to swallow the\n // NEXT genuine close after a restart.\n const saved = this._savedOnClose;\n const transport = this._transport;\n let spent = false;\n const wrapper = () => {\n if (!spent) {\n spent = true;\n return;\n }\n saved();\n };\n transport.onclose = wrapper;\n pendingSpentCloseGuards.set(transport, () => {\n // Restore by identity — never clobber a handler the caller\n // replaced in the meantime.\n if (transport.onclose === wrapper) {\n transport.onclose = saved;\n }\n });\n } else {\n this._transport.onclose = this._savedOnClose;\n }\n }\n\n /** Detach the handlers and arm the one-shot `start()` pass-through for the `Protocol.connect()` handover. */\n release(): void {\n this.detach();\n const transport = this._transport;\n // Save the raw property value (not a bound copy) so the restore below\n // returns `transport.start` to its original identity — no wrapper or\n // bind layer accretes across repeated connects on the same transport.\n const originalStart = transport.start;\n let armed = true;\n transport.start = async function (this: unknown): Promise<void> {\n if (armed) {\n armed = false;\n transport.start = originalStart;\n return;\n }\n return originalStart.call(transport);\n };\n }\n}\n\n/**\n * Spent-close guards from failed negotiations, pending disarm by the cleanup\n * site (keyed weakly — an abandoned transport carries its guard to GC).\n */\nconst pendingSpentCloseGuards = new WeakMap<Transport, () => void>();\n\n/**\n * Disarm a failed negotiation's spent-close guard once the cleanup `close()`\n * has settled. Any re-delivery of the spent mid-window close happens DURING\n * that close (HTTP transports re-fire `onclose` there; stdio transports never\n * do — their close event already fired), so after it every close is genuine\n * and must reach the caller's pre-set observer.\n */\nexport function disarmSpentCloseGuard(transport: Transport): void {\n const disarm = pendingSpentCloseGuards.get(transport);\n pendingSpentCloseGuards.delete(transport);\n disarm?.();\n}\n\n/** Build the probe request: `server/discover` carrying the full per-request `_meta` envelope. */\nexport function buildProbeRequest(\n id: string,\n protocolVersion: string,\n clientInfo: Implementation,\n capabilities: ClientCapabilities\n): JSONRPCRequest {\n return {\n jsonrpc: '2.0',\n id,\n method: 'server/discover',\n params: {\n // The era codec owns the keyed-envelope shape; the probe is sent\n // for a modern version, so this is always the 2026 envelope.\n _meta: codecForVersion(protocolVersion).outboundEnvelope({\n protocolVersion,\n clientInfo,\n clientCapabilities: capabilities\n })\n }\n };\n}\n\nfunction normalizeReply(reply: RawProbeReply, timeoutMs: number): ProbeOutcome {\n switch (reply.kind) {\n case 'response': {\n return reply.error === undefined ? { kind: 'result', result: reply.result } : { kind: 'rpc-error', ...reply.error };\n }\n case 'send-error': {\n const error = reply.error;\n const isAuthOutcome =\n // Provenance recorded at the throw boundary: the transport\n // stamps every error escaping one of its auth seams (the\n // token() read, onUnauthorized invocations — SDK flow and\n // custom callbacks alike — the 403 step-up method, and its\n // own auth-failure constructions). Never reconstructed here\n // from error types.\n isAuthSeamEscape(error) ||\n // The published contract for foreign transports: an\n // UnauthorizedError by brand, or by name for one thrown by a\n // differently bundled SDK copy at a skewed version or an auth\n // middleware's own class.\n error instanceof UnauthorizedError ||\n (error instanceof Error && error.name === 'UnauthorizedError');\n if (isAuthOutcome) {\n // Auth-gated server: propagate unchanged.\n return { kind: 'auth-required', error: error as Error };\n }\n if (error instanceof SdkHttpError) {\n const text = (error.data as { text?: unknown } | undefined)?.text;\n return {\n kind: 'http-error',\n status: error.data.status,\n body: typeof text === 'string' ? text : undefined,\n statusText: error.data.statusText\n };\n }\n return { kind: 'network-error', error };\n }\n case 'closed': {\n // Not folded into network-error: the classifier's closed row is\n // transport-aware (stdio legacy signal vs typed error).\n return { kind: 'closed' };\n }\n case 'timeout': {\n return { kind: 'timeout', timeoutMs };\n }\n }\n}\n\nexport interface NegotiationDeps {\n transport: Transport;\n clientInfo: Implementation;\n capabilities: ClientCapabilities;\n environment: ProbeEnvironment;\n /** The transport class, for the transport-aware timeout and closed verdicts (see {@linkcode ProbeTransportKind}). */\n transportKind: ProbeTransportKind;\n /** The standard request timeout for this connect (probe inherits it unless `probe.timeoutMs` overrides). */\n defaultTimeoutMs: number;\n /**\n * The probe transport is a disposable sibling (see\n * {@linkcode negotiateStdioViaSibling}): a mid-probe close is ordinary\n * legacy evidence — the probe child spent itself — never a connect-fatal\n * condition. Absent for in-place probes, where a closed connection has no\n * fallback stream and stays a typed error.\n */\n disposableProbe?: boolean;\n}\n\nexport type NegotiationResult = { era: 'modern'; version: string; discover: DiscoverResult } | { era: 'legacy' };\n\n/**\n * Run the negotiation probe state machine on a raw (not yet Protocol-connected)\n * transport. Resolves with the negotiated era; throws typed connect errors. On\n * return the probe window has been released: the transport is started,\n * handler-free, and ready for `Protocol.connect()` handover. On throw the\n * window is detached and the transport's `start` is left untouched.\n */\nexport async function negotiateEra(\n negotiation: Extract<ResolvedVersionNegotiation, { kind: 'auto' | 'pin' }>,\n deps: NegotiationDeps\n): Promise<NegotiationResult> {\n const timeoutMs = negotiation.probe.timeoutMs ?? deps.defaultTimeoutMs;\n const maxRetries = Math.max(0, negotiation.probe.maxRetries ?? 0);\n const clientModernVersions = negotiation.kind === 'pin' ? [negotiation.version] : negotiation.modernVersions;\n const fallbackAvailable = negotiation.kind === 'auto' && negotiation.fallbackAvailable;\n\n const window = await ProbeWindow.open(deps.transport);\n\n const probe = async (): Promise<NegotiationResult> => {\n let requestedVersion = clientModernVersions[0]!;\n // The -32022 corrective continuation runs exactly once (even when the\n // mutual version equals the just-rejected one); the loop guard arms on\n // the second rejection.\n let correctiveUsed = false;\n // `maxRetries` governs timeout re-sends only — independent of (and\n // never counted against) the corrective continuation.\n let timeoutRetriesRemaining = maxRetries;\n for (;;) {\n const reply = await window.exchange(\n id => buildProbeRequest(id, requestedVersion, deps.clientInfo, deps.capabilities),\n timeoutMs\n );\n\n if (reply.kind === 'timeout' && timeoutRetriesRemaining > 0) {\n timeoutRetriesRemaining--;\n continue;\n }\n\n const outcome = normalizeReply(reply, timeoutMs);\n const verdict: ProbeVerdict = classifyProbeOutcome(outcome, {\n clientModernVersions,\n requestedVersion,\n fallbackAvailable,\n environment: deps.environment,\n transportKind: deps.transportKind\n });\n\n switch (verdict.kind) {\n case 'modern': {\n return { era: 'modern', version: verdict.version, discover: verdict.discover };\n }\n case 'corrective': {\n if (correctiveUsed) {\n // Second rejection: loop guard.\n throw verdict.error;\n }\n correctiveUsed = true;\n requestedVersion = verdict.version;\n continue;\n }\n case 'legacy': {\n // A closed outcome carries its own cause — diagnostics must\n // name the close instead of implying a server/discover\n // verdict that never happened.\n const closedCause = outcome.kind === 'closed' ? 'the connection closed during the server/discover probe' : undefined;\n if (negotiation.kind === 'pin') {\n throw new SdkError(\n SdkErrorCode.EraNegotiationFailed,\n closedCause === undefined\n ? `Version negotiation failed: the server did not offer pinned protocol version ${negotiation.version} ` +\n `via server/discover (no fallback in pin mode)`\n : `Version negotiation failed: ${closedCause} before the server offered ` +\n `pinned protocol version ${negotiation.version} (no fallback in pin mode)`\n );\n }\n if (!negotiation.fallbackAvailable) {\n // Modern-only client: the legacy initialize fallback is\n // unavailable and must never carry a 2026-era version string.\n throw new SdkError(\n SdkErrorCode.EraNegotiationFailed,\n closedCause === undefined\n ? 'Version negotiation failed: the server gave no modern evidence and this client supports no ' +\n 'pre-2026-07-28 protocol version to fall back to'\n : `Version negotiation failed: ${closedCause} and this client supports no ` +\n 'pre-2026-07-28 protocol version to fall back to'\n );\n }\n if (closedCause !== undefined && deps.disposableProbe !== true) {\n // In-place probe: the connection died with the child and\n // there is no disposable sibling to spend — the\n // same-stream initialize fallback is impossible, so this\n // stays a typed connect error.\n throw new SdkError(\n SdkErrorCode.EraNegotiationFailed,\n `Version negotiation failed: ${closedCause} ` +\n \"(this transport probed in place — the disposable sibling probe requires the SDK's base StdioClientTransport)\"\n );\n }\n return { era: 'legacy' };\n }\n case 'error': {\n throw verdict.error;\n }\n }\n }\n };\n\n let result: NegotiationResult;\n try {\n result = await probe();\n } catch (error) {\n // A failed negotiation leaves the transport exactly as it found it:\n // handlers detached, original start untouched (no pass-through armed).\n window.detach();\n throw error;\n }\n window.release();\n return result;\n}\n\n/**\n * Structural read of the SDK stdio transport's retained spawn parameters —\n * `undefined` for stdio-shaped transports that do not expose them, and for\n * SUBCLASSES of the SDK transport (those probe in place, where a mid-probe\n * close stays a typed connect error). The sibling path requires the transport\n * to be exactly the base class: a subclass cannot be faithfully cloned by\n * re-invoking its constructor with the retained params alone (extra ctor\n * arguments, transformed state, side effects). Exactness is checked without\n * importing the class (the negotiation graph must stay runtime-neutral): only\n * the base class's own prototype carries the internal `_dispose` reaper the\n * sibling flow depends on — a subclass's prototype does not own it.\n */\nexport function readStdioServerParams(transport: Transport): Record<string, unknown> | undefined {\n const proto = Object.getPrototypeOf(transport) as object | null;\n if (proto === null || !Object.prototype.hasOwnProperty.call(proto, '_dispose')) {\n return undefined;\n }\n const params = (transport as { _serverParams?: unknown })._serverParams;\n return typeof params === 'object' && params !== null && typeof (params as { command?: unknown }).command === 'string'\n ? (params as Record<string, unknown>)\n : undefined;\n}\n\n/**\n * stdio era negotiation on a DISPOSABLE SIBLING: stdio servers built on SDKs\n * that terminate on any pre-`initialize` request exit when the probe arrives,\n * so the probe must not spend the caller's one process life. `server/discover`\n * runs on a short-lived sibling spawned from the same parameters; the caller's\n * transport starts exactly once, after the era is known. The sibling is\n * invisible infrastructure: its stderr is discarded, and it is reaped before\n * this resolves (signal escalation awaiting process exit — a helper holding\n * its pipes never blocks disposal). A caller `close()` on the session\n * transport during the probe aborts the connect with the typed negotiation\n * error, and the session transport is never started.\n */\nexport async function negotiateStdioViaSibling(\n negotiation: Extract<ResolvedVersionNegotiation, { kind: 'auto' | 'pin' }>,\n sessionTransport: Transport,\n params: Record<string, unknown>,\n deps: Omit<NegotiationDeps, 'transport' | 'transportKind' | 'disposableProbe'>\n): Promise<NegotiationResult> {\n const SiblingTransport = sessionTransport.constructor as new (params: Record<string, unknown>) => Transport;\n const sibling = new SiblingTransport({ ...params, stderr: 'ignore' });\n\n // The session transport is unstarted while the sibling probes, and closing\n // an unstarted transport records nothing — so watch its close() for the\n // window's duration (raw property saved; identity restored in the finally).\n // The abort races the probe: a caller close rejects promptly instead of\n // waiting out the probe timeout.\n const originalClose = sessionTransport.close;\n let callerClosed = false;\n let signalClosed: (() => void) | undefined;\n const closedSignal = new Promise<never>((_, reject) => {\n signalClosed = () => reject(callerCloseAbortError());\n });\n sessionTransport.close = async function (): Promise<void> {\n callerClosed = true;\n signalClosed?.();\n return originalClose.call(sessionTransport);\n };\n\n let result: NegotiationResult;\n try {\n const negotiated = negotiateEra(negotiation, {\n ...deps,\n transport: sibling,\n transportKind: 'stdio',\n disposableProbe: true\n });\n // The abort may orphan the probe promise; its late settlement (the\n // disposed sibling's close, a timeout) must not surface anywhere.\n negotiated.catch(() => {});\n result = await Promise.race([negotiated, closedSignal]);\n } finally {\n // Dispose FIRST, with the close watch still armed: a caller close()\n // landing during the disposal window must still trip the abort below —\n // only once the sibling is reaped does the caller get its close back.\n await disposeSibling(sibling);\n sessionTransport.close = originalClose;\n }\n if (callerClosed) {\n // Checked AFTER the finally so a close during either the probe or the\n // disposal window aborts: the session transport is never started.\n throw callerCloseAbortError();\n }\n return result;\n}\n\n/** The typed abort for a caller `close()` landing while the sibling probes. */\nfunction callerCloseAbortError(): SdkError {\n return new SdkError(\n SdkErrorCode.EraNegotiationFailed,\n 'Version negotiation failed: the transport was closed during the server/discover probe'\n );\n}\n\n/** Reap a probe sibling — best-effort; a sibling that cannot be reaped must not turn a settled verdict into an error. */\nasync function disposeSibling(sibling: Transport): Promise<void> {\n try {\n const dispose = (sibling as { _dispose?: () => Promise<void> })._dispose;\n await (typeof dispose === 'function' ? dispose.call(sibling) : sibling.close());\n } catch {\n // ignore\n }\n}\n","import { DefaultJsonSchemaValidator } from '@modelcontextprotocol/client/_shims';\nimport type {\n BaseContext,\n CallToolRequest,\n CallToolResult,\n ClientCapabilities,\n ClientContext,\n ClientNotification,\n ClientRequest,\n CompleteRequest,\n CompleteResult,\n DiscoverResult,\n EmptyResult,\n GetPromptRequest,\n GetPromptResult,\n Implementation,\n InputRequiredOptions,\n JSONRPCNotification,\n JSONRPCRequest,\n JSONRPCResponse,\n JsonSchemaType,\n JsonSchemaValidator,\n jsonSchemaValidator,\n ListChangedHandlers,\n ListChangedOptions,\n ListPromptsRequest,\n ListPromptsResult,\n ListResourcesRequest,\n ListResourcesResult,\n ListResourceTemplatesRequest,\n ListResourceTemplatesResult,\n ListToolsRequest,\n ListToolsResult,\n LoggingLevel,\n MessageExtraInfo,\n NonCompleteResultFlow,\n NotificationMethod,\n ProtocolEra,\n ProtocolOptions,\n ReadResourceRequest,\n ReadResourceResult,\n RequestMethod,\n RequestOptions,\n ResolvedInputRequiredDriverConfig,\n Result,\n ServerCapabilities,\n StandardSchemaV1,\n SubscribeRequest,\n SubscriptionFilter,\n Tool,\n Transport,\n UnsubscribeRequest,\n XMcpHeaderScanResult\n} from '@modelcontextprotocol/core-internal';\nimport {\n buildMcpParamHeaders,\n codecForVersion,\n DEFAULT_REQUEST_TIMEOUT_MSEC,\n DiscoverResultSchema,\n HEADER_MISMATCH_ERROR_CODE,\n isJSONRPCErrorResponse,\n isJSONRPCRequest,\n isModernProtocolVersion,\n isSpecType,\n legacyProtocolVersions,\n ListChangedOptionsBaseSchema,\n mergeCapabilities,\n modernProtocolVersions,\n parseSchema,\n Protocol,\n ProtocolError,\n ProtocolErrorCode,\n resolveInputRequiredDriverConfig,\n runInputRequiredFlow,\n scanXMcpHeaderDeclarations,\n SdkError,\n SdkErrorCode,\n SERVER_INFO_META_KEY,\n SUBSCRIPTION_ID_META_KEY,\n SUPPORTED_MODERN_PROTOCOL_VERSIONS\n} from '@modelcontextprotocol/core-internal';\n\nimport type { PriorDiscovery } from './probeClassifier';\nimport type { CacheMode, CacheScope, ResponseCacheStore } from './responseCache';\nimport { ClientResponseCache, InMemoryResponseCacheStore, MAX_CACHE_TTL_MS } from './responseCache';\nimport type { ResolvedVersionNegotiation, VersionNegotiationOptions } from './versionNegotiation';\nimport {\n detectProbeEnvironment,\n detectProbeTransportKind,\n disarmSpentCloseGuard,\n negotiateEra,\n negotiateStdioViaSibling,\n readStdioServerParams,\n resolveVersionNegotiation\n} from './versionNegotiation';\n\n/**\n * The server identity a `DiscoverResult` carries in\n * `_meta['io.modelcontextprotocol/serverInfo']` (a spec SHOULD — absent means\n * the server offered no identity). Runtime-validated with the spec-type\n * guard because `connect({ prior })` accepts caller-supplied values that\n * never saw a wire parse.\n */\nfunction serverInfoFromDiscover(discover: DiscoverResult): Implementation | undefined {\n const fromMeta = discover._meta?.[SERVER_INFO_META_KEY];\n return isSpecType.Implementation(fromMeta) ? fromMeta : undefined;\n}\n\n/**\n * Elicitation default application helper. Applies defaults to the `data` based on the `schema`.\n *\n * @param schema - The schema to apply defaults to.\n * @param data - The data to apply defaults to.\n */\nfunction applyElicitationDefaults(schema: JsonSchemaType | undefined, data: unknown): void {\n if (!schema || data === null || typeof data !== 'object') return;\n\n // Handle object properties\n if (schema.type === 'object' && schema.properties && typeof schema.properties === 'object') {\n const obj = data as Record<string, unknown>;\n const props = schema.properties as Record<string, JsonSchemaType & { default?: unknown }>;\n for (const key of Object.keys(props)) {\n const propSchema = props[key]!;\n // If missing or explicitly undefined, apply default if present\n if (obj[key] === undefined && Object.prototype.hasOwnProperty.call(propSchema, 'default')) {\n obj[key] = propSchema.default;\n }\n // Recurse into existing nested objects/arrays\n if (obj[key] !== undefined) {\n applyElicitationDefaults(propSchema, obj[key]);\n }\n }\n }\n\n if (Array.isArray(schema.anyOf)) {\n for (const sub of schema.anyOf) {\n // Skip boolean schemas (true/false are valid JSON Schemas but have no defaults)\n if (typeof sub !== 'boolean') {\n applyElicitationDefaults(sub, data);\n }\n }\n }\n\n // Combine schemas\n if (Array.isArray(schema.oneOf)) {\n for (const sub of schema.oneOf) {\n // Skip boolean schemas (true/false are valid JSON Schemas but have no defaults)\n if (typeof sub !== 'boolean') {\n applyElicitationDefaults(sub, data);\n }\n }\n }\n}\n\n/**\n * Determines which elicitation modes are supported based on declared client capabilities.\n *\n * According to the spec:\n * - An empty elicitation capability object defaults to form mode support (backwards compatibility)\n * - URL mode is only supported if explicitly declared\n *\n * @param capabilities - The client's elicitation capabilities\n * @returns An object indicating which modes are supported\n */\nexport function getSupportedElicitationModes(capabilities: ClientCapabilities['elicitation']): {\n supportsFormMode: boolean;\n supportsUrlMode: boolean;\n} {\n if (!capabilities) {\n return { supportsFormMode: false, supportsUrlMode: false };\n }\n\n const hasFormCapability = capabilities.form !== undefined;\n const hasUrlCapability = capabilities.url !== undefined;\n\n // If neither form nor url are explicitly declared, form mode is supported (backwards compatibility)\n const supportsFormMode = hasFormCapability || (!hasFormCapability && !hasUrlCapability);\n const supportsUrlMode = hasUrlCapability;\n\n return { supportsFormMode, supportsUrlMode };\n}\n\nexport type ClientOptions = ProtocolOptions & {\n /**\n * Capabilities to advertise as being supported by this client.\n */\n capabilities?: ClientCapabilities;\n\n /**\n * JSON Schema validator for tool output validation.\n *\n * The validator is used to validate structured content returned by tools\n * against their declared output schemas.\n *\n * @default Runtime-selected validator (AJV-backed on Node.js, `@cfworker/json-schema`-backed on browser/workerd runtimes)\n */\n jsonSchemaValidator?: jsonSchemaValidator;\n\n /**\n * Opt-in protocol version negotiation (protocol revision 2026-07-28 and later).\n *\n * **The default is `'legacy'`**: absent (or `mode: 'legacy'`), `connect()`\n * runs the plain 2025 sequence, byte-identical to today's behavior (no\n * probe, no new headers). Opt into `'auto'` or pin to talk to a 2026-07-28\n * server.\n *\n * - `mode: 'auto'` — `connect()` probes the server with `server/discover` first:\n * definitive modern evidence selects the modern era; definitive legacy signals\n * (and anything unrecognized) fall back to the plain legacy `initialize`\n * handshake, byte-equivalent to a 2025 client. On the SDK's own stdio\n * transport (the base `StdioClientTransport` exactly; subclasses probe in\n * place) the probe runs on a short-lived sibling process spawned from the\n * same parameters (one extra spawn per connect; its stderr is discarded) and\n * the caller's transport starts once, after the era is known; HTTP — and\n * custom or subclassed stdio-shaped transports — probe on the connection itself. A\n * network outage rejects with a typed connect error. A probe timeout is\n * transport-aware: on stdio it indicates a legacy server (some legacy servers\n * never answer unknown pre-`initialize` requests) and falls back to\n * `initialize`; on HTTP it rejects with a typed timeout\n * error (silence on a deployed server is an outage, not a legacy signal).\n * - `mode: { pin: '2026-07-28' }` — modern era at exactly the pinned revision;\n * no probe-and-fallback: anything else fails loudly.\n *\n * Probe policy lives under `probe: { timeoutMs?, maxRetries? }`; the probe\n * inherits the client's standard request timeout unless overridden, and\n * `maxRetries` (default `0`) governs timeout re-sends only — the\n * spec-mandated `-32022` corrective continuation is never counted against it.\n *\n * Once a modern era is negotiated, the client automatically attaches the\n * per-request `_meta` envelope (the reserved protocol-version / client-info /\n * client-capabilities keys) to every outgoing request and notification;\n * user-supplied `_meta` keys take precedence over the auto-attached ones.\n */\n versionNegotiation?: VersionNegotiationOptions;\n\n /**\n * Multi-round-trip auto-fulfilment (protocol revision 2026-07-28).\n *\n * On the 2026-07-28 era, servers obtain client input (elicitation,\n * sampling, roots) by answering `tools/call`, `prompts/get`, or\n * `resources/read` with an `input_required` result instead of sending a\n * server→client request. By default the client fulfils those embedded\n * requests automatically through the SAME handlers registered via\n * {@linkcode Client.setRequestHandler | setRequestHandler} (e.g.\n * `elicitation/create`), then retries the original call with the\n * collected `inputResponses` and a byte-exact echo of the opaque\n * `requestState`, on a fresh request id, up to `maxRounds` rounds.\n * `client.callTool()` (and its siblings) keep returning their plain\n * result type — the interactive rounds happen inside the call.\n *\n * Set `autoFulfill: false` for manual mode: an `input_required` response\n * then surfaces as a typed error unless the individual call passes\n * `allowInputRequired: true` (pair it with `withInputRequired()` on the\n * explicit-schema path to type both outcomes).\n *\n * Has no effect on 2025-era connections, which have no `input_required`\n * vocabulary.\n */\n inputRequired?: InputRequiredOptions;\n\n /**\n * Configure handlers for list changed notifications (tools, prompts, resources).\n *\n * @example\n * ```ts source=\"./client.examples.ts#ClientOptions_listChanged\"\n * const client = new Client(\n * { name: 'my-client', version: '1.0.0' },\n * {\n * listChanged: {\n * tools: {\n * onChanged: (error, tools) => {\n * if (error) {\n * console.error('Failed to refresh tools:', error);\n * return;\n * }\n * console.log('Tools updated:', tools);\n * }\n * },\n * prompts: {\n * onChanged: (error, prompts) => console.log('Prompts updated:', prompts)\n * }\n * }\n * }\n * );\n * ```\n */\n listChanged?: ListChangedHandlers;\n\n /**\n * Cap on the number of pages the auto-aggregating\n * {@linkcode Client.listTools | listTools()} /\n * {@linkcode Client.listPrompts | listPrompts()} /\n * {@linkcode Client.listResources | listResources()} /\n * {@linkcode Client.listResourceTemplates | listResourceTemplates()} walk\n * fetches before throwing (a defence against a server whose `nextCursor`\n * never converges). `0` disables the cap. Default: `64`. Applies only to\n * the no-argument auto-aggregate path; an explicit-`cursor` per-page call\n * is never capped.\n */\n listMaxPages?: number;\n\n /**\n * The response-cache store backing the client's derived views (the cached\n * `tools/list` result that {@linkcode Client.callTool | callTool}'s output\n * validation and SEP-2243 header mirroring read) and the SEP-2549\n * cache-hint serving on the cacheable verbs. Defaults to a fresh\n * {@linkcode InMemoryResponseCacheStore} per client.\n *\n * Entries are automatically scoped by connected-server identity (derived\n * from `serverInfo` after connect) AND, for `'private'`-scoped results,\n * by `cachePartition` — encoded collision-free via `JSON.stringify`, so a\n * server cannot craft a `serverInfo` that bleeds into another server's\n * namespace or another principal's slot. One store may therefore back\n * several clients (e.g. a host pool against the same server, or one\n * persistent KV across servers); `list_changed` evictions are scoped to\n * the connected server's partitions, so co-tenants are unaffected. Set\n * `cachePartition` to your principal identifier (e.g. the auth subject)\n * when sharing across principals. Note `serverInfo` is self-reported — a\n * server that deliberately impersonates\n * another's `name`/`version` shares its `'public'` slot; the\n * per-principal isolation via `cachePartition` holds regardless.\n */\n responseCacheStore?: ResponseCacheStore;\n\n /**\n * Opaque per-principal identifier for response-cache writes whose\n * server-reported `cacheScope` is `'private'` (the spec's \"MUST NOT share\n * across authorization contexts\"). Within the connected server's\n * namespace, `'public'`-scoped entries live at the shared\n * `[serverIdentity, '']` partition and `'private'`-scoped entries at\n * `[serverIdentity, cachePartition]`. Set this to a stable identity of\n * the authorization context (e.g. the auth subject) when one\n * `responseCacheStore` backs several principals; with the\n * default `''` every entry — public or private — lives at the server's\n * shared partition, which is the safe single-tenant posture.\n */\n cachePartition?: string;\n\n /**\n * TTL (ms) applied when a cacheable result arrives without a `ttlMs`\n * field. Default `0` — a result without an explicit hint is never served\n * from cache (every call refetches), but it is still **stored** so the\n * `tools/list`-derived index that {@linkcode Client.callTool | callTool}'s\n * SEP-2243 mirroring and output-schema validation read keeps working\n * regardless. The spec defines absent-or-≤0 as \"immediately stale\".\n */\n defaultCacheTtlMs?: number;\n};\n\n/**\n * Options for {@linkcode Client.connect}. Extends {@linkcode RequestOptions}\n * (the timeout/signal apply to the connect-time handshake or probe) with the\n * cached-era-verdict knob.\n */\nexport type ConnectOptions = RequestOptions & {\n /**\n * A cached era verdict, taking precedence over `versionNegotiation`:\n * `{ kind: 'modern', discover }` adopts a prior {@linkcode DiscoverResult}\n * with zero round trips (throws `SdkError(EraNegotiationFailed)` on no\n * 2026-07-28+ overlap); `{ kind: 'legacy' }` skips the probe and runs the\n * plain legacy `initialize` handshake. Freshness is the supplying host's\n * responsibility — see {@linkcode PriorDiscovery}. Reuse only within one\n * authorization context.\n */\n prior?: PriorDiscovery;\n};\n\n/**\n * Rejects malformed persisted blobs with a typed `SdkError` before any state\n * change: unrecognized `kind`, a legacy verdict also carrying\n * DiscoverResult-shaped members (a corrupt blob must never era-choose), or a\n * modern `discover` payload failing the wire path's schema.\n */\nfunction validatePrior(prior: PriorDiscovery): PriorDiscovery {\n if (typeof prior === 'object' && prior !== null) {\n if (prior.kind === 'legacy' && !('supportedVersions' in prior) && !('discover' in prior)) {\n return prior;\n }\n // Validation only: the blob is adopted verbatim, so unknown nested\n // members survive re-persistence via getDiscoverResult().\n if (prior.kind === 'modern' && DiscoverResultSchema.safeParse(prior.discover).success) {\n return prior;\n }\n }\n throw new SdkError(\n SdkErrorCode.EraNegotiationFailed,\n \"connect({ prior }): unrecognized prior — expected { kind: 'modern', discover } or { kind: 'legacy' }\"\n );\n}\n\n/**\n * {@linkcode RequestOptions} extended with the per-call cache disposition for\n * the cacheable verbs (`listTools()` / `listPrompts()` / `listResources()` /\n * `listResourceTemplates()` / `readResource()`). See {@linkcode CacheMode}.\n */\nexport type CacheableRequestOptions = RequestOptions & {\n /**\n * `'use'` (default) serves a still-fresh cached entry without a round\n * trip; `'refresh'` always fetches and re-stores; `'bypass'` fetches\n * without consulting or writing the cache. Applies to the no-`cursor`\n * auto-aggregate path on the list verbs and to `readResource`; ignored\n * elsewhere.\n */\n cacheMode?: CacheMode;\n};\n\n/**\n * Options for {@linkcode Client.callTool}. Extends {@linkcode RequestOptions}\n * with an escape hatch for callers that already hold the tool definition\n * (e.g. from a previous session or configuration) — pass it via\n * `toolDefinition` so SEP-2243 `Mcp-Param-*` header mirroring can run without a\n * prior `tools/list`.\n */\nexport type CallToolRequestOptions = RequestOptions & {\n /**\n * The tool definition to use for SEP-2243 `Mcp-Param-*` header mirroring on\n * a 2026-07-28 connection over Streamable HTTP, AND for output-schema\n * validation of the result. When set, the client uses this definition's\n * `inputSchema` and `outputSchema` instead of (and without consulting) the\n * cached `tools/list` result, so the two derived views agree.\n */\n toolDefinition?: Tool;\n};\n\n/**\n * `list_changed` notification → response-cache method(s) to evict. `resources`\n * covers both list verbs (the spec's \"relevant notification ⇒ immediately\n * stale\").\n */\nconst LIST_CHANGED_EVICTIONS: Readonly<Record<string, readonly string[]>> = {\n 'notifications/tools/list_changed': ['tools/list'],\n 'notifications/prompts/list_changed': ['prompts/list'],\n 'notifications/resources/list_changed': ['resources/list', 'resources/templates/list']\n};\n\nconst DEFAULT_LIST_MAX_PAGES = 64;\n\n/**\n * A handle to an open `subscriptions/listen` stream (protocol revision\n * 2026-07-28). Change notifications delivered on the stream dispatch to the\n * existing {@linkcode Client.setNotificationHandler} registrations.\n */\nexport interface McpSubscription {\n /**\n * The subset of the requested filter the server agreed to honor (from\n * `notifications/subscriptions/acknowledged`).\n */\n readonly honoredFilter: SubscriptionFilter;\n /**\n * Tears the subscription down. Idempotent. Aborts the listen request's\n * stream (where the transport supports it) AND sends\n * `notifications/cancelled` referencing the listen request id — both,\n * always, so close works on any transport.\n */\n close(): Promise<void>;\n /**\n * Resolves exactly once when the subscription has terminated. Never\n * rejects — this is an observation, not an operation.\n *\n * - `'local'` — you called {@linkcode close} (or aborted the\n * `RequestOptions.signal` you passed to `listen()`).\n * - `'graceful'` — the server ended the subscription deliberately by\n * sending the empty `subscriptions/listen` response (e.g. on shutdown).\n * - `'remote'` — the stream ended without a response, or the transport\n * dropped — an unexpected disconnect. Re-listen if you still want\n * events.\n */\n readonly closed: Promise<'local' | 'graceful' | 'remote'>;\n}\n\n/** @internal */\ninterface ListenStateEntry {\n /**\n * The single funnel for the per-listen `opening → open → closed` state\n * machine. Every transport-level feed source — the `_onnotification` /\n * `_onresponse` / `_onclose` overrides, `onRequestStreamEnd`, send\n * failure, ack timeout, caller-signal abort, `_resetConnectionState` —\n * routes through it.\n */\n settle: (outcome: { ack: SubscriptionFilter } | { cause: 'local' | 'graceful' | 'remote'; error?: Error }) => void;\n}\n\n/**\n * Per-tool result of compiling an `outputSchema` (SEP-2106). Stored on the\n * response-cache substrate's stamp-keyed `name → validator` index so it\n * inherits that substrate's invalidation lifecycle (`list_changed` evicts,\n * a refetched `tools/list` re-derives, `resetForReconnect` clears) — no\n * parallel map to keep in sync.\n *\n * @internal\n */\ntype OutputSchemaCompileResult =\n | { ok: true; validator: JsonSchemaValidator<unknown> }\n | { ok: false; validator?: undefined; compileError: unknown };\n\n/**\n * An MCP client on top of a pluggable transport.\n *\n * The client will automatically begin the initialization flow with the server when {@linkcode connect} is called.\n *\n * To handle server-initiated requests (sampling, elicitation, roots), call {@linkcode setRequestHandler}.\n * The client must declare the corresponding capability for the handler to be accepted. For\n * `sampling/createMessage` and `elicitation/create`, the handler is automatically wrapped with\n * schema validation for both the incoming request and the returned result.\n *\n * Note: the `roots/list` and `sampling/createMessage` handler surfaces (and the corresponding\n * `roots` and `sampling` capabilities) are deprecated as of protocol version 2026-07-28\n * (SEP-2577). They remain functional during the deprecation window (at least twelve months).\n * Migrate sampling to calling LLM provider APIs directly, and roots to passing paths via tool\n * parameters, resource URIs, or configuration.\n *\n * @example Handling a sampling request\n * ```ts source=\"./client.examples.ts#Client_setRequestHandler_sampling\"\n * client.setRequestHandler('sampling/createMessage', async request => {\n * const lastMessage = request.params.messages.at(-1);\n * console.log('Sampling request:', lastMessage);\n *\n * // In production, send messages to your LLM here\n * return {\n * model: 'my-model',\n * role: 'assistant' as const,\n * content: {\n * type: 'text' as const,\n * text: 'Response from the model'\n * }\n * };\n * });\n * ```\n */\nexport class Client extends Protocol<ClientContext> {\n private _serverCapabilities?: ServerCapabilities;\n private _serverVersion?: Implementation;\n private _capabilities: ClientCapabilities;\n private _instructions?: string;\n private _jsonSchemaValidator: jsonSchemaValidator;\n /**\n * The response-cache substrate. Owns the backing store, the per-method\n * eviction-generation counter, the user-supplied/default flag, and the\n * stamp-memoized derived `name → Tool` / `name → output-validator`\n * indices — the cache-coordination state that used to live as separate\n * private fields here. The internal aggregating walk writes one entry per\n * list verb; `list_changed` evicts the matching method;\n * `_resetConnectionState` resets the lot. {@linkcode callTool}'s\n * output-schema validation reads the derived `outputValidator` index (the\n * substrate's first production caller); the stacked SEP-2243 PR wires\n * `Mcp-Param-*` mirroring through `toolDefinition` on top.\n */\n private readonly _cache: ClientResponseCache;\n private readonly _defaultCacheTtlMs: number;\n private readonly _listMaxPages: number;\n private _listChangedDebounceTimers: Map<string, ReturnType<typeof setTimeout>> = new Map();\n /**\n * The constructor `listChanged` configuration. Durable across reconnects:\n * read fresh on every connect (legacy or modern), never consumed.\n */\n private readonly _listChangedConfig?: ListChangedHandlers;\n private _enforceStrictCapabilities: boolean;\n private _versionNegotiation?: VersionNegotiationOptions;\n private _supportedProtocolVersionsOption?: string[];\n private _inputRequiredDriverConfig: ResolvedInputRequiredDriverConfig;\n /**\n * Active subscriptions/listen state, keyed by subscription id (= the\n * listen request's JSON-RPC id verbatim). The id is a STRING from a\n * Client-owned counter (`'listen:' + N`) — JSON-RPC permits string ids,\n * and Protocol's numeric `_requestMessageId` counter only ever issues\n * numbers, so listen ids cannot collide with ordinary request ids.\n */\n private _listenState = new Map<string, ListenStateEntry>();\n private _nextListenId = 0;\n /** The auto-opened subscription backing ClientOptions.listChanged on a modern connection. */\n private _autoOpenedSubscription?: McpSubscription;\n /** Backing store for {@linkcode getDiscoverResult}. Per-connection. */\n private _discoverResult?: DiscoverResult;\n\n /**\n * Clears every per-connection field in one place. Called at the start of\n * each fresh (non-resuming) connect and from `close()`, so a stale\n * negotiated era / server identity / auto-opened subscription cannot\n * survive a reconnect.\n */\n private _resetConnectionState(): void {\n this._negotiatedProtocolVersion = undefined;\n this._serverCapabilities = undefined;\n this._serverVersion = undefined;\n this._instructions = undefined;\n this._discoverResult = undefined;\n this._autoOpenedSubscription = undefined;\n // Settle every live per-listen state machine before clearing the map:\n // a fresh connect (or close) on a connection whose prior transport\n // never fired onclose would otherwise leave an in-flight listen()\n // promise hanging forever. Each entry's settle() deletes only itself\n // (Map self-delete during iteration is well-defined).\n if (this._listenState.size > 0) {\n const reason = new SdkError(\n SdkErrorCode.ConnectionClosed,\n 'subscriptions/listen: client reconnected or closed; subscription state from the previous connection was reset'\n );\n for (const entry of this._listenState.values()) {\n entry.settle({ cause: 'remote', error: reason });\n }\n }\n this._listenState.clear();\n // Debounce timers are connection-scoped: a callback armed on a\n // connection that is now gone must not fire onto whatever connection\n // (if any) replaces it.\n for (const timer of this._listChangedDebounceTimers.values()) {\n clearTimeout(timer);\n }\n this._listChangedDebounceTimers.clear();\n // A user-supplied store is NOT cleared on reconnect/close — that would\n // defeat the only reason to supply one. The per-instance default IS\n // cleared (it is connection-scoped); derived indices and the\n // generation map are dropped regardless. The default impl is\n // synchronous, so the call returns plain void here.\n this._cache.resetForReconnect();\n }\n\n override async close(): Promise<void> {\n try {\n await super.close();\n } finally {\n // Per-connection state is cleared even when the transport's close\n // rejects, so a stale negotiated era / live listen state cannot\n // survive a failed close.\n this._resetConnectionState();\n }\n }\n\n /**\n * Initializes this client with the given name and version information.\n */\n constructor(\n private _clientInfo: Implementation,\n options?: ClientOptions\n ) {\n super(options);\n this._capabilities = options?.capabilities ? { ...options.capabilities } : {};\n this._jsonSchemaValidator = options?.jsonSchemaValidator ?? new DefaultJsonSchemaValidator();\n this._enforceStrictCapabilities = options?.enforceStrictCapabilities ?? false;\n this._versionNegotiation = options?.versionNegotiation;\n this._supportedProtocolVersionsOption = options?.supportedProtocolVersions;\n // Multi-round-trip auto-fulfilment driver (2026-07-28): on by default,\n // configurable via ClientOptions.inputRequired.\n this._inputRequiredDriverConfig = resolveInputRequiredDriverConfig(options?.inputRequired);\n // Response-cache substrate. A fresh in-memory store is allocated when\n // the caller does not supply one — never share a default across\n // instances (see ClientOptions.responseCacheStore).\n this._cache = new ClientResponseCache(\n options?.responseCacheStore ?? new InMemoryResponseCacheStore(),\n options?.responseCacheStore !== undefined,\n error => this._reportStoreError(error),\n options?.cachePartition ?? ''\n );\n this._defaultCacheTtlMs = options?.defaultCacheTtlMs ?? 0;\n this._listMaxPages = options?.listMaxPages ?? DEFAULT_LIST_MAX_PAGES;\n\n // Store list changed config for setup after connection (when we know server capabilities)\n if (options?.listChanged) {\n this._listChangedConfig = options.listChanged;\n }\n }\n\n protected override buildContext(ctx: BaseContext, _transportInfo?: MessageExtraInfo): ClientContext {\n return ctx;\n }\n\n /**\n * Era-keyed direction enforcement for inbound traffic on channels whose\n * transport does not classify (e.g. stdio): the 2026-07-28 era has no\n * server→client JSON-RPC request channel — server-to-client interactions\n * are carried in-band in `input_required` results — and on stdio the\n * client must never write JSON-RPC responses. An inbound request arriving\n * on a connection that negotiated a modern era is therefore dropped\n * (surfaced via `onerror`) rather than answered. Connections on a legacy\n * era — and all responses and notifications — keep today's dispatch path.\n */\n protected override _shouldDropInbound(message: JSONRPCRequest | JSONRPCNotification): 'drop' | undefined {\n if (\n this._negotiatedProtocolVersion !== undefined &&\n isModernProtocolVersion(this._negotiatedProtocolVersion) &&\n isJSONRPCRequest(message)\n ) {\n return 'drop';\n }\n return undefined;\n }\n\n /**\n * Per-request `_meta` envelope auto-emission (protocol revision 2026-07-28):\n * on a connection that negotiated a modern era — auto-negotiated or pinned —\n * every outgoing request and notification automatically carries the reserved\n * protocol-version / client-info / client-capabilities `_meta` keys (the\n * same envelope the connect-time `server/discover` probe sends).\n * User-supplied `_meta` keys take precedence over the auto-attached ones.\n *\n * Legacy-era connections return `undefined`: the envelope seam is a no-op\n * and outbound traffic is byte-identical to a 2025 client (the legacy\n * `'auto'` fallback included).\n */\n protected override _outboundMetaEnvelope(): Readonly<Record<string, unknown>> | undefined {\n const version = this._negotiatedProtocolVersion;\n if (version === undefined) return undefined;\n // The era branch lives in the codec: the 2025 era's `outboundEnvelope`\n // is `undefined` (legacy bytes stay identical); the 2026 era builds\n // the keyed object.\n return this._wireCodec().outboundEnvelope({\n protocolVersion: version,\n clientInfo: this._clientInfo,\n clientCapabilities: this._capabilities\n });\n }\n\n /**\n * Wires the multi-round-trip auto-fulfilment engine (protocol revision\n * 2026-07-28) into the response funnel: an `input_required` answer is\n * fulfilled through the registered elicitation/sampling/roots handlers\n * and the original request retried via `flow.retry`, up to\n * `inputRequired.maxRounds` rounds. With auto-fulfilment disabled the\n * response surfaces as a typed error steering to manual mode.\n */\n protected override _resolveNonCompleteResult<T extends StandardSchemaV1>(\n decoded: { kind: 'input_required'; inputRequests: Record<string, unknown>; requestState?: string },\n flow: NonCompleteResultFlow<T>\n ): Promise<unknown> {\n if (!this._inputRequiredDriverConfig.autoFulfill) {\n return Promise.reject(\n new SdkError(\n SdkErrorCode.UnsupportedResultType,\n `Unsupported result type 'input_required' for ${flow.request.method}: ` +\n `multi-round-trip auto-fulfilment is not enabled on this instance — ` +\n `pass allowInputRequired: true to handle it manually, or enable inputRequired.autoFulfill`,\n { resultType: 'input_required', method: flow.request.method }\n )\n );\n }\n return runInputRequiredFlow(\n {\n getRequestHandler: method =>\n this._getRequestHandler(method) as ((request: JSONRPCRequest, ctx: unknown) => Promise<Result>) | undefined,\n buildContext: baseCtx => this.buildContext(baseCtx, undefined),\n sessionId: this.transport?.sessionId\n },\n this._inputRequiredDriverConfig,\n decoded,\n flow\n );\n }\n\n /**\n * Set up handlers for list changed notifications based on config and server capabilities.\n * This should only be called after initialization when server capabilities are known.\n * Handlers are silently skipped if the server doesn't advertise the corresponding listChanged capability.\n * @internal\n */\n private _setupListChangedHandlers(config: ListChangedHandlers): void {\n // Every autoRefresh fetcher forces `cacheMode: 'refresh'`: the\n // notification handler's `_cache.evict()` runs first, but a custom\n // store whose `delete()` no-ops (or rejects) leaves the stale entry\n // in place — a default-mode `list*()` would then cache-serve the very\n // entry the notification declared stale. `'refresh'` bypasses the\n // cache read so the fetcher always reaches the wire and overwrites.\n if (config.tools && this._serverCapabilities?.tools?.listChanged) {\n this._setupListChangedHandler('tools', 'notifications/tools/list_changed', config.tools, async () => {\n const result = await this.listTools(undefined, { cacheMode: 'refresh' });\n return result.tools;\n });\n }\n\n if (config.prompts && this._serverCapabilities?.prompts?.listChanged) {\n this._setupListChangedHandler('prompts', 'notifications/prompts/list_changed', config.prompts, async () => {\n const result = await this.listPrompts(undefined, { cacheMode: 'refresh' });\n return result.prompts;\n });\n }\n\n if (config.resources && this._serverCapabilities?.resources?.listChanged) {\n this._setupListChangedHandler('resources', 'notifications/resources/list_changed', config.resources, async () => {\n const result = await this.listResources(undefined, { cacheMode: 'refresh' });\n return result.resources;\n });\n }\n }\n\n /**\n * Registers new capabilities. This can only be called before connecting to a transport.\n *\n * The new capabilities will be merged with any existing capabilities previously given (e.g., at initialization).\n */\n public registerCapabilities(capabilities: ClientCapabilities): void {\n if (this.transport) {\n throw new Error('Cannot register capabilities after connecting to transport');\n }\n\n this._capabilities = mergeCapabilities(this._capabilities, capabilities);\n }\n\n /**\n * Configure protocol version negotiation before connecting (equivalent to\n * passing `versionNegotiation` at construction time). Can only be called\n * before connecting to a transport. Passing `undefined` clears a previously\n * configured negotiation, restoring the default `'legacy'` posture.\n *\n * See {@linkcode ClientOptions | ClientOptions.versionNegotiation} for the mode semantics.\n */\n public setVersionNegotiation(options: VersionNegotiationOptions | undefined): void {\n if (this.transport) {\n throw new Error('Cannot configure version negotiation after connecting to transport');\n }\n this._versionNegotiation = options;\n }\n\n /**\n * Enforces client-side validation for `elicitation/create` and `sampling/createMessage`\n * regardless of how the handler was registered.\n */\n protected override _wrapHandler(\n method: string,\n handler: (request: JSONRPCRequest, ctx: ClientContext) => Promise<Result>\n ): (request: JSONRPCRequest, ctx: ClientContext) => Promise<Result> {\n if (method === 'elicitation/create') {\n return async (request, ctx) => {\n // Era-exact validation via the function-only WireCodec\n // contract: resolved from the instance era at dispatch time.\n // On the 2025 era the method is a wire request (registry\n // validator); on the 2026 era it is in-band vocabulary\n // reached only via the multi-round-trip driver, so the wire\n // validator returns `not-in-era` and we fall through to the\n // in-band one. The era registry entry IS the plain\n // ElicitResult schema (the result map is aligned to the\n // typed map — no widened unions), so no narrower surface is\n // needed.\n const codec = codecForVersion(this._negotiatedProtocolVersion);\n let validatedRequest = codec.validateRequest('elicitation/create', request);\n if (!validatedRequest.ok && validatedRequest.reason === 'not-in-era') {\n validatedRequest = codec.validateInputRequest('elicitation/create', request);\n }\n if (!validatedRequest.ok) {\n throw new ProtocolError(\n validatedRequest.reason === 'not-in-era' ? ProtocolErrorCode.InternalError : ProtocolErrorCode.InvalidParams,\n validatedRequest.reason === 'not-in-era'\n ? 'No wire schema for elicitation/create in the resolved era'\n : `Invalid elicitation request: ${validatedRequest.message}`\n );\n }\n\n const { params } = validatedRequest.value;\n params.mode = params.mode ?? 'form';\n const { supportsFormMode, supportsUrlMode } = getSupportedElicitationModes(this._capabilities.elicitation);\n\n if (params.mode === 'form' && !supportsFormMode) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Client does not support form-mode elicitation requests');\n }\n\n if (params.mode === 'url' && !supportsUrlMode) {\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, 'Client does not support URL-mode elicitation requests');\n }\n\n const result = await handler(request, ctx);\n\n let validationResult = codec.validateResult('elicitation/create', result);\n if (!validationResult.ok && validationResult.reason === 'not-in-era') {\n validationResult = codec.validateInputResponse('elicitation/create', result);\n }\n if (!validationResult.ok) {\n throw new ProtocolError(\n validationResult.reason === 'not-in-era' ? ProtocolErrorCode.InternalError : ProtocolErrorCode.InvalidParams,\n validationResult.reason === 'not-in-era'\n ? 'No wire schema for elicitation/create in the resolved era'\n : `Invalid elicitation result: ${validationResult.message}`\n );\n }\n\n const validatedResult = validationResult.value;\n const requestedSchema = params.mode === 'form' ? (params.requestedSchema as JsonSchemaType) : undefined;\n\n if (\n params.mode === 'form' &&\n validatedResult.action === 'accept' &&\n validatedResult.content &&\n requestedSchema &&\n this._capabilities.elicitation?.form?.applyDefaults\n ) {\n try {\n applyElicitationDefaults(requestedSchema, validatedResult.content);\n } catch {\n // gracefully ignore errors in default application\n }\n }\n\n return validatedResult;\n };\n }\n\n if (method === 'sampling/createMessage') {\n return async (request, ctx) => {\n // Era-exact validation via the instance era (see above): wire\n // request validator on the 2025 era; on the 2026 era sampling\n // is in-band vocabulary (it reaches the handler only as an\n // embedded input request) so the wire validator returns\n // `not-in-era` and we fall through to the in-band one.\n const codec = codecForVersion(this._negotiatedProtocolVersion);\n let validatedRequest = codec.validateRequest('sampling/createMessage', request);\n if (!validatedRequest.ok && validatedRequest.reason === 'not-in-era') {\n validatedRequest = codec.validateInputRequest('sampling/createMessage', request);\n }\n if (!validatedRequest.ok) {\n throw new ProtocolError(\n validatedRequest.reason === 'not-in-era' ? ProtocolErrorCode.InternalError : ProtocolErrorCode.InvalidParams,\n validatedRequest.reason === 'not-in-era'\n ? 'No wire schema for sampling/createMessage in the resolved era'\n : `Invalid sampling request: ${validatedRequest.message}`\n );\n }\n\n const { params } = validatedRequest.value;\n\n const result = await handler(request, ctx);\n\n // The result-side validator mirrors the request-side selection\n // so both stay on the same era's vocabulary. On the 2025 era\n // the schema depends on the REQUEST params (tools vs no tools)\n // — `samplingResultVariant` owns that pair. On the 2026 era\n // it returns `not-in-era` and we fall through to the embedded\n // response validator (it covers plain and tool-bearing\n // responses alike).\n const hasTools = Boolean(params.tools || params.toolChoice);\n let validatedResult = codec.samplingResultVariant(hasTools, result);\n if (!validatedResult.ok && validatedResult.reason === 'not-in-era') {\n validatedResult = codec.validateInputResponse('sampling/createMessage', result);\n }\n if (!validatedResult.ok) {\n throw new ProtocolError(\n validatedResult.reason === 'not-in-era' ? ProtocolErrorCode.InternalError : ProtocolErrorCode.InvalidParams,\n validatedResult.reason === 'not-in-era'\n ? 'No result schema for sampling/createMessage in the resolved era'\n : `Invalid sampling result: ${validatedResult.message}`\n );\n }\n\n return validatedResult.value;\n };\n }\n\n return handler;\n }\n\n protected assertCapability(capability: keyof ServerCapabilities, method: string): void {\n if (!this._serverCapabilities?.[capability]) {\n throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support ${capability} (required for ${method})`);\n }\n }\n\n /**\n * Connects to a server via the given transport and performs the MCP initialization handshake.\n *\n * @example Basic usage (stdio)\n * ```ts source=\"./client.examples.ts#Client_connect_stdio\"\n * const client = new Client({ name: 'my-client', version: '1.0.0' });\n * const transport = new StdioClientTransport({ command: 'my-mcp-server' });\n * await client.connect(transport);\n * ```\n *\n * @example Streamable HTTP with SSE fallback\n * ```ts source=\"./client.examples.ts#Client_connect_sseFallback\"\n * const baseUrl = new URL(url);\n *\n * try {\n * // Try modern Streamable HTTP transport first\n * const client = new Client({ name: 'my-client', version: '1.0.0' });\n * const transport = new StreamableHTTPClientTransport(baseUrl);\n * await client.connect(transport);\n * return { client, transport };\n * } catch {\n * // Fall back to legacy SSE transport\n * const client = new Client({ name: 'my-client', version: '1.0.0' });\n * const transport = new SSEClientTransport(baseUrl);\n * await client.connect(transport);\n * return { client, transport };\n * }\n * ```\n */\n override async connect(transport: Transport, options?: ConnectOptions): Promise<void> {\n // `!= null`: a persisted prior slot naturally revives as JSON `null`\n // — treat it like an absent option, not a shape error.\n if (options?.prior != null) {\n // Cached era verdict: bypasses versionNegotiation resolution entirely.\n return this._connectFromPrior(transport, validatePrior(options.prior), options);\n }\n // The configured versionNegotiation mode decides the era.\n const negotiation = resolveVersionNegotiation(this._versionNegotiation, this._supportedProtocolVersionsOption);\n if (negotiation.kind !== 'legacy') {\n return this._connectNegotiated(transport, negotiation, options);\n }\n return this._connectPlainLegacy(transport, options);\n }\n\n /**\n * Plain legacy connect — the pinned 2025 sequence, byte-untouched. The\n * `mode: 'legacy'` connect body, shared with the `prior` legacy verdict.\n */\n private async _connectPlainLegacy(transport: Transport, options?: RequestOptions): Promise<void> {\n await super.connect(transport);\n // When transport sessionId is already set this means we are trying to reconnect.\n // Restore the protocol version negotiated during the original initialize handshake\n // so HTTP transports include the required mcp-protocol-version header, but skip re-init.\n if (transport.sessionId !== undefined) {\n const negotiatedProtocolVersion = this._negotiatedProtocolVersion;\n if (negotiatedProtocolVersion !== undefined) {\n // Resuming keeps the original negotiation: the instance still\n // holds the negotiated version (and with it the wire era) —\n // only the new transport needs the header pushed again.\n transport.setProtocolVersion?.(negotiatedProtocolVersion);\n }\n return;\n }\n // Fresh connect: per-connection state left over from a previous\n // connection must not survive into a new handshake. Clearing it puts\n // the instance back in the pre-negotiation phase, so the initialize\n // exchange below rides the bootstrap method pins (legacy era) instead\n // of a dead session's era. Without this, an instance that once\n // negotiated a modern era could never re-run a fresh handshake:\n // `initialize` is physically absent from the modern registry. (The\n // resume branch above keeps it instead.)\n this._resetConnectionState();\n await this._legacyHandshake(transport, options);\n }\n\n /**\n * The 2025 `initialize` handshake — the body of the plain legacy connect and\n * the `'auto'`-mode fallback path (same `initialize` body, zero 2026 headers;\n * on the stdio sibling path it opens the session child's fresh pipe, in the\n * in-place modes it rides the probed connection). Callers clear the negotiated protocol version before\n * the handshake; its completion sets the negotiated (legacy) version.\n */\n private async _legacyHandshake(transport: Transport, options?: RequestOptions): Promise<void> {\n // initialize is a legacy-era handshake: only the legacy subset of the\n // supported versions is ever offered or accepted here — a 2026-era\n // revision is negotiated exclusively via server/discover.\n const legacyVersions = legacyProtocolVersions(this._supportedProtocolVersions);\n try {\n const offeredVersion = legacyVersions[0];\n if (offeredVersion === undefined) {\n throw new SdkError(\n SdkErrorCode.EraNegotiationFailed,\n 'Cannot run the initialize handshake: supportedProtocolVersions contains no pre-2026-07-28 protocol version'\n );\n }\n const result = await this.request(\n {\n method: 'initialize',\n params: {\n protocolVersion: offeredVersion,\n capabilities: this._capabilities,\n clientInfo: this._clientInfo\n }\n },\n options\n );\n\n if (result === undefined) {\n throw new Error(`Server sent invalid initialize result: ${result}`);\n }\n\n if (!legacyVersions.includes(result.protocolVersion)) {\n throw new Error(`Server's protocol version is not supported: ${result.protocolVersion}`);\n }\n\n this._serverCapabilities = result.capabilities;\n this._serverVersion = result.serverInfo;\n this._cache.setServerIdentity(this._deriveServerIdentity(transport));\n // HTTP transports must set the protocol version in each header after initialization.\n if (transport.setProtocolVersion) {\n transport.setProtocolVersion(result.protocolVersion);\n }\n\n this._instructions = result.instructions;\n\n await this.notification({\n method: 'notifications/initialized'\n });\n\n // Handshake completion: the negotiated version becomes the\n // instance's connection state, and with it the wire era for\n // everything this connection sends/receives from here on (the\n // negotiated version cashes out as the negotiated wire ERA —\n // Q1-SD1). Set AFTER the initialized notification: the initialize\n // EXCHANGE is the legacy handshake by definition and completes on\n // that era.\n this._negotiatedProtocolVersion = result.protocolVersion;\n\n // Set up list changed handlers now that we know server capabilities\n if (this._listChangedConfig) {\n this._setupListChangedHandlers(this._listChangedConfig);\n }\n } catch (error) {\n // Disconnect if initialization fails.\n void this.close();\n throw error;\n }\n }\n\n /**\n * Negotiated connect (mode `'auto'` or `{ pin }`): probe with `server/discover`\n * before the Protocol machinery attaches — on a disposable sibling process for\n * the SDK's stdio transport, in place otherwise — then either establish the\n * modern era or perform the plain legacy handshake.\n */\n private async _connectNegotiated(\n transport: Transport,\n negotiation: Extract<ResolvedVersionNegotiation, { kind: 'auto' | 'pin' }>,\n options?: RequestOptions\n ): Promise<void> {\n // Session-resuming reconnect: restore the previously negotiated version,\n // never re-probe mid-session.\n if (transport.sessionId !== undefined) {\n await super.connect(transport);\n const negotiatedProtocolVersion = this._negotiatedProtocolVersion;\n if (negotiatedProtocolVersion !== undefined && transport.setProtocolVersion) {\n transport.setProtocolVersion(negotiatedProtocolVersion);\n }\n return;\n }\n\n // Fresh connect: stale connection state must not survive into a new\n // negotiation — every fresh negotiated connect re-runs the probe.\n this._resetConnectionState();\n\n let result: Awaited<ReturnType<typeof negotiateEra>>;\n try {\n const transportKind = detectProbeTransportKind(transport);\n const baseDeps = {\n clientInfo: this._clientInfo,\n capabilities: this._capabilities,\n environment: detectProbeEnvironment(),\n defaultTimeoutMs: options?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MSEC\n };\n // The SDK's stdio transport probes on a disposable sibling process,\n // so the caller's transport spends its one child life on the\n // session, never on the probe. Stdio-shaped transports without\n // readable spawn parameters (and HTTP) probe in place, as before.\n const stdioParams = transportKind === 'stdio' ? readStdioServerParams(transport) : undefined;\n result =\n stdioParams === undefined\n ? await negotiateEra(negotiation, { ...baseDeps, transport, transportKind })\n : await negotiateStdioViaSibling(negotiation, transport, stdioParams, baseDeps);\n } catch (error) {\n // Typed connect error — close the channel like a failed initialize does.\n await transport.close().catch(() => {});\n // The cleanup close has settled: any re-delivery of a spent\n // mid-probe close has happened by now, so the spent-close guard\n // must not outlive it — on transports whose close() never re-fires\n // onclose (stdio), an armed guard would swallow the next GENUINE\n // close after a restart.\n disarmSpentCloseGuard(transport);\n throw error;\n }\n\n // Success path: no cleanup close ever runs here, so no re-delivery of a\n // spent mid-window close is coming — disarm any guard NOW, before\n // Protocol chains the handler slot, or an in-place negotiation that\n // succeeded after a same-tick reply-then-close would carry the armed\n // skip into the live session and swallow its first genuine close.\n disarmSpentCloseGuard(transport);\n\n await super.connect(transport);\n\n if (result.era === 'legacy') {\n // Conservative fallback: the in-place probing modes run the plain\n // legacy handshake on the probed connection; the sibling path runs\n // it as the session child's first exchange (the probe never touched\n // the transport version slot either way).\n await this._legacyHandshake(transport, options);\n return;\n }\n\n this._serverCapabilities = result.discover.capabilities;\n this._serverVersion = serverInfoFromDiscover(result.discover);\n this._cache.setServerIdentity(this._deriveServerIdentity(transport));\n this._instructions = result.discover.instructions;\n this._discoverResult = result.discover;\n // Modern selection: the same connection state the legacy handshake completion sets.\n this._negotiatedProtocolVersion = result.version;\n // The single setProtocolVersion call site on this path, mirroring the legacy path after initialize.\n if (transport.setProtocolVersion) {\n transport.setProtocolVersion(result.version);\n }\n // The modern era has no notifications/initialized; list-changed handlers\n // are configured straight from the advertised capabilities. On a modern\n // connection the configured handlers are fed by an auto-opened\n // subscriptions/listen stream (the modern era never delivers change\n // notifications unsolicited); on a legacy connection they fire on the\n // 2025-era unsolicited notifications, no listen needed.\n if (this._listChangedConfig) {\n const config = this._listChangedConfig;\n // Compute configured ∩ server-advertised ONCE and use that single\n // value for BOTH handler registration and the auto-open filter, so\n // a configured-but-not-advertised type is neither subscribed to\n // nor handled (the two stay in lockstep).\n const advertised = this._serverCapabilities;\n const effective: ListChangedHandlers = {\n ...(config.tools && advertised?.tools?.listChanged && { tools: config.tools }),\n ...(config.prompts && advertised?.prompts?.listChanged && { prompts: config.prompts }),\n ...(config.resources && advertised?.resources?.listChanged && { resources: config.resources })\n };\n // Handler registration validates the per-type options and can\n // throw on misconfiguration; the modern connection IS established\n // at this point and is fully usable without listChanged handlers,\n // so a misconfiguration surfaces via onerror and connect resolves\n // (matching the auto-open soft-fail posture). When registration\n // fails the auto-open is SKIPPED — opening a listen stream for\n // types whose handler never registered would consume a server\n // slot to deliver notifications nothing handles.\n let handlersRegistered = true;\n try {\n this._setupListChangedHandlers(effective);\n } catch (error) {\n handlersRegistered = false;\n this.onerror?.(error instanceof Error ? error : new Error(String(error)));\n }\n const filter: SubscriptionFilter = handlersRegistered\n ? {\n ...(effective.tools && { toolsListChanged: true as const }),\n ...(effective.prompts && { promptsListChanged: true as const }),\n ...(effective.resources && { resourcesListChanged: true as const })\n }\n : {};\n if (Object.keys(filter).length > 0) {\n // A failed auto-open MUST NOT fail connect: the modern\n // connection is fully usable without a listen stream (the\n // server may not support it, or refuse on capacity). Surface\n // via onerror; the consumer can call listen() later.\n //\n // listen() binds RequestOptions.signal to the SUBSCRIPTION\n // lifetime, so connect()'s signal must NOT be forwarded\n // verbatim — a connect-scoped `AbortSignal.timeout(30_000)`\n // would silently tear the auto-opened stream down the moment\n // it fires after connect has resolved. But connect()'s signal\n // MUST still cancel the in-connect ack WAIT (otherwise an\n // aborted connect blocks here for the full ack timeout).\n // Derived one-shot: bound to connect()'s signal only for the\n // duration of the listen() await; the listener is removed in\n // `finally` so the auto-opened subscription outlives connect's\n // signal.\n const ackAbort = new AbortController();\n const onConnectAbort = (): void => ackAbort.abort(options?.signal?.reason);\n // Handle the already-aborted case (aborted between the\n // discover leg resolving and now): the listener never fires\n // for a past event.\n if (options?.signal?.aborted) onConnectAbort();\n options?.signal?.addEventListener('abort', onConnectAbort);\n try {\n this._autoOpenedSubscription = await this.listen(filter, {\n timeout: options?.timeout,\n signal: ackAbort.signal\n });\n } catch (error) {\n // Connect-signal abort during the ack wait propagates as a\n // connect() rejection (caller asked to abort connect). The\n // transport is already started, so close it before\n // rethrowing — a connect() rejection MUST NOT leave a\n // half-open connection. A server-side refusal stays a\n // soft onerror (connect succeeds, no listen stream).\n if (options?.signal?.aborted) {\n await this.close().catch(() => {});\n throw error;\n }\n this.onerror?.(error instanceof Error ? error : new Error(String(error)));\n } finally {\n options?.signal?.removeEventListener('abort', onConnectAbort);\n }\n }\n }\n }\n\n /**\n * Connect from a validated {@linkcode PriorDiscovery}: the modern arm\n * adopts the `DiscoverResult` (zero round trips; `EraNegotiationFailed`\n * on no 2026-07-28+ overlap), the legacy arm runs the plain legacy connect.\n */\n private async _connectFromPrior(transport: Transport, prior: PriorDiscovery, options?: RequestOptions): Promise<void> {\n if (prior.kind === 'legacy') {\n // Known-legacy verdict: byte-identical to a mode: 'legacy' connect.\n return this._connectPlainLegacy(transport, options);\n }\n const discover = prior.discover;\n this._resetConnectionState();\n\n const explicit = this._supportedProtocolVersionsOption;\n const clientModern =\n explicit && modernProtocolVersions(explicit).length > 0 ? modernProtocolVersions(explicit) : SUPPORTED_MODERN_PROTOCOL_VERSIONS;\n const version = clientModern.find(v => discover.supportedVersions.includes(v));\n if (version === undefined) {\n throw new SdkError(\n SdkErrorCode.EraNegotiationFailed,\n 'connect({ prior }) with a modern verdict requires a 2026-07-28+ mutual protocol version; the supplied DiscoverResult and ' +\n \"this client's supportedProtocolVersions have no modern overlap. For a server known to be legacy, pass \" +\n \"prior: { kind: 'legacy' } to skip the probe and initialize directly, or use \" +\n \"versionNegotiation: { mode: 'auto' } to re-probe with legacy fallback.\"\n );\n }\n\n await super.connect(transport);\n\n this._discoverResult = discover;\n this._serverCapabilities = discover.capabilities;\n this._serverVersion = serverInfoFromDiscover(discover);\n this._cache.setServerIdentity(this._deriveServerIdentity(transport));\n this._instructions = discover.instructions;\n this._negotiatedProtocolVersion = version;\n transport.setProtocolVersion?.(version);\n\n // No auto-opened listen stream on this path (request-only workers).\n if (this._listChangedConfig) {\n try {\n this._setupListChangedHandlers(this._listChangedConfig);\n } catch (error) {\n this.onerror?.(error instanceof Error ? error : new Error(String(error)));\n }\n }\n }\n\n /**\n * After initialization has completed, this will be populated with the server's reported capabilities.\n */\n getServerCapabilities(): ServerCapabilities | undefined {\n return this._serverCapabilities;\n }\n\n /**\n * The connected server's self-reported name and version, when it\n * identified itself: required on the legacy `initialize` result; a spec\n * SHOULD in the discover result's `_meta` on 2026-07-28, so a successful\n * modern connect against an anonymous server leaves this `undefined`.\n */\n getServerVersion(): Implementation | undefined {\n return this._serverVersion;\n }\n\n /**\n * The connected server's identity for response-cache partitioning. The\n * `serverInfo` `name@version` pair when available (required on\n * `initialize`; a SHOULD in the discover result's `_meta` since spec PR\n * #3002); falls back to the transport's `sessionId`, then to a\n * per-connection surrogate. The surrogate matters since #3002 made\n * identity optional: without it, two identity-less servers reached over\n * sessionId-less transports would share the cache's pre-connect `''`\n * partition and read each other's entries — no stable identity means no\n * cross-connection cache reuse. The value itself is server-controlled —\n * the collision-safety of the storage partition comes from\n * {@linkcode ClientResponseCache}'s JSON-array encoding around it, not\n * from any character it does or does not contain.\n */\n private _deriveServerIdentity(transport: Transport): string {\n const v = this._serverVersion;\n if (v !== undefined) return `${v.name}@${v.version}`;\n return transport.sessionId ?? `anonymous:${Date.now()}-${Math.random().toString(36).slice(2)}`;\n }\n\n /**\n * After initialization has completed, this will be populated with the protocol version negotiated\n * during the initialize handshake. When manually reconstructing a transport for reconnection, pass this\n * value to the new transport so it continues sending the required `mcp-protocol-version` header.\n */\n getNegotiatedProtocolVersion(): string | undefined {\n return this._negotiatedProtocolVersion;\n }\n\n /**\n * After initialization has completed, this returns the protocol era of the\n * connection: `'modern'` when the connection negotiated a 2026-07-28+\n * revision (via `server/discover`), `'legacy'` for the 2025-era\n * `initialize` handshake, or `undefined` before the connection is\n * established.\n */\n getProtocolEra(): ProtocolEra | undefined {\n const version = this._negotiatedProtocolVersion;\n if (version === undefined) return undefined;\n return isModernProtocolVersion(version) ? 'modern' : 'legacy';\n }\n\n /**\n * After initialization has completed, this may be populated with information about the server's instructions.\n */\n getInstructions(): string | undefined {\n return this._instructions;\n }\n\n /**\n * The {@linkcode DiscoverResult} from the last `'auto'`/pinned probe,\n * {@linkcode discover} call, or `connect({ prior })` that adopted a\n * modern verdict (a legacy verdict leaves this `undefined` — there is no\n * `DiscoverResult` on that path). Persistable via `JSON.stringify`; wrap\n * as `{ kind: 'modern', discover }` and feed to {@linkcode ConnectOptions}\n * `prior`.\n */\n getDiscoverResult(): DiscoverResult | undefined {\n return this._discoverResult;\n }\n\n protected assertCapabilityForMethod(method: RequestMethod | string): void {\n switch (method as ClientRequest['method']) {\n // Deprecated as of protocol version 2026-07-28 (SEP-2577); remains\n // functional during the deprecation window (at least twelve months).\n case 'logging/setLevel': {\n if (!this._serverCapabilities?.logging) {\n throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support logging (required for ${method})`);\n }\n break;\n }\n\n case 'prompts/get':\n case 'prompts/list': {\n if (!this._serverCapabilities?.prompts) {\n throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support prompts (required for ${method})`);\n }\n break;\n }\n\n case 'resources/list':\n case 'resources/templates/list':\n case 'resources/read':\n case 'resources/subscribe':\n case 'resources/unsubscribe': {\n if (!this._serverCapabilities?.resources) {\n throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support resources (required for ${method})`);\n }\n\n if (method === 'resources/subscribe' && !this._serverCapabilities.resources.subscribe) {\n throw new SdkError(\n SdkErrorCode.CapabilityNotSupported,\n `Server does not support resource subscriptions (required for ${method})`\n );\n }\n\n break;\n }\n\n case 'tools/call':\n case 'tools/list': {\n if (!this._serverCapabilities?.tools) {\n throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support tools (required for ${method})`);\n }\n break;\n }\n\n case 'completion/complete': {\n if (!this._serverCapabilities?.completions) {\n throw new SdkError(SdkErrorCode.CapabilityNotSupported, `Server does not support completions (required for ${method})`);\n }\n break;\n }\n\n case 'initialize': {\n // No specific capability required for initialize\n break;\n }\n\n case 'server/discover': {\n // No specific capability required for discover (protocol revision\n // 2026-07-28; servers on that revision MUST implement it)\n break;\n }\n\n case 'ping': {\n // No specific capability required for ping\n break;\n }\n }\n }\n\n protected assertNotificationCapability(method: NotificationMethod | string): void {\n switch (method as ClientNotification['method']) {\n // Deprecated as of protocol version 2026-07-28 (SEP-2577); remains\n // functional during the deprecation window (at least twelve months).\n case 'notifications/roots/list_changed': {\n if (!this._capabilities.roots?.listChanged) {\n throw new SdkError(\n SdkErrorCode.CapabilityNotSupported,\n `Client does not support roots list changed notifications (required for ${method})`\n );\n }\n break;\n }\n\n case 'notifications/initialized': {\n // No specific capability required for initialized\n break;\n }\n\n case 'notifications/cancelled': {\n // Cancellation notifications are always allowed\n break;\n }\n\n case 'notifications/progress': {\n // Progress notifications are always allowed\n break;\n }\n }\n }\n\n protected assertRequestHandlerCapability(method: string): void {\n switch (method) {\n // Deprecated as of protocol version 2026-07-28 (SEP-2577); remains\n // functional during the deprecation window (at least twelve months).\n case 'sampling/createMessage': {\n if (!this._capabilities.sampling) {\n throw new SdkError(\n SdkErrorCode.CapabilityNotSupported,\n `Client does not support sampling capability (required for ${method})`\n );\n }\n break;\n }\n\n case 'elicitation/create': {\n if (!this._capabilities.elicitation) {\n throw new SdkError(\n SdkErrorCode.CapabilityNotSupported,\n `Client does not support elicitation capability (required for ${method})`\n );\n }\n break;\n }\n\n // Deprecated as of protocol version 2026-07-28 (SEP-2577); remains\n // functional during the deprecation window (at least twelve months).\n case 'roots/list': {\n if (!this._capabilities.roots) {\n throw new SdkError(\n SdkErrorCode.CapabilityNotSupported,\n `Client does not support roots capability (required for ${method})`\n );\n }\n break;\n }\n\n case 'ping': {\n // No specific capability required for ping\n break;\n }\n }\n }\n\n async ping(options?: RequestOptions): Promise<EmptyResult> {\n return this.request({ method: 'ping' }, options);\n }\n\n /**\n * Send `server/discover` (2026-07-28+) and record the result for\n * {@linkcode getDiscoverResult}.\n */\n async discover(options?: RequestOptions): Promise<DiscoverResult> {\n const result = await this._requestWithSchema({ method: 'server/discover' }, DiscoverResultSchema, options);\n this._discoverResult = result;\n return result;\n }\n\n /** Requests argument autocompletion suggestions from the server for a prompt or resource. */\n async complete(params: CompleteRequest['params'], options?: RequestOptions): Promise<CompleteResult> {\n return this.request({ method: 'completion/complete', params }, options);\n }\n\n /**\n * Sets the minimum severity level for log messages sent by the server.\n *\n * @deprecated Deprecated as of protocol version 2026-07-28 (SEP-2577).\n * Remains functional during the deprecation window (at least twelve months).\n * Migrate to stderr logging (STDIO servers) or OpenTelemetry.\n */\n async setLoggingLevel(level: LoggingLevel, options?: RequestOptions): Promise<EmptyResult> {\n return this.request({ method: 'logging/setLevel', params: { level } }, options);\n }\n\n /** Retrieves a prompt by name from the server, passing the given arguments for template substitution. */\n async getPrompt(params: GetPromptRequest['params'], options?: RequestOptions): Promise<GetPromptResult> {\n return this.request({ method: 'prompts/get', params }, options);\n }\n\n /**\n * Lists available prompts.\n *\n * Called without a `cursor` (the common case), this walks every page and\n * returns the complete aggregated list with no `nextCursor`; the\n * aggregate is also written to the {@linkcode ResponseCacheStore}. Pass an\n * explicit `{ cursor }` to fetch a single page and walk pagination\n * yourself — the per-page path returns the server's raw page (with\n * `nextCursor` for the next call) and does not write the response cache.\n * The auto-aggregate path is capped by\n * {@linkcode ClientOptions | ClientOptions.listMaxPages} (default 64); the per-page path\n * is not.\n *\n * Returns an empty list if the server does not advertise prompts capability\n * (or throws if {@linkcode ClientOptions.enforceStrictCapabilities} is enabled).\n *\n * @example\n * ```ts source=\"./client.examples.ts#Client_listPrompts_pagination\"\n * // No cursor → all pages aggregated for you.\n * const { prompts } = await client.listPrompts();\n * console.log(\n * 'Available prompts:',\n * prompts.map(p => p.name)\n * );\n * ```\n */\n async listPrompts(params?: ListPromptsRequest['params'], options?: CacheableRequestOptions): Promise<ListPromptsResult> {\n if (!this._serverCapabilities?.prompts && !this._enforceStrictCapabilities) {\n // Respect capability negotiation: server does not support prompts\n console.debug('Client.listPrompts() called but server does not advertise prompts capability - returning empty list');\n return { prompts: [] };\n }\n if (params?.cursor !== undefined) {\n return this.request({ method: 'prompts/list', params }, options);\n }\n const hit = await this._serveFromCache<ListPromptsResult>('prompts/list', undefined, options);\n if (hit !== undefined) return hit;\n return this._listAllPages<ListPromptsResult>('prompts/list', params, options, (acc, page) => acc.prompts.push(...page.prompts));\n }\n\n /**\n * Lists available resources.\n *\n * Called without a `cursor` (the common case), this walks every page and\n * returns the complete aggregated list with no `nextCursor`; the\n * aggregate is also written to the {@linkcode ResponseCacheStore}. Pass an\n * explicit `{ cursor }` to fetch a single page and walk pagination\n * yourself — the per-page path returns the server's raw page (with\n * `nextCursor` for the next call) and does not write the response cache.\n * The auto-aggregate path is capped by\n * {@linkcode ClientOptions | ClientOptions.listMaxPages} (default 64); the per-page path\n * is not.\n *\n * Returns an empty list if the server does not advertise resources capability\n * (or throws if {@linkcode ClientOptions.enforceStrictCapabilities} is enabled).\n *\n * @example\n * ```ts source=\"./client.examples.ts#Client_listResources_pagination\"\n * // No cursor → all pages aggregated for you.\n * const { resources } = await client.listResources();\n * console.log(\n * 'Available resources:',\n * resources.map(r => r.name)\n * );\n * ```\n */\n async listResources(params?: ListResourcesRequest['params'], options?: CacheableRequestOptions): Promise<ListResourcesResult> {\n if (!this._serverCapabilities?.resources && !this._enforceStrictCapabilities) {\n // Respect capability negotiation: server does not support resources\n console.debug('Client.listResources() called but server does not advertise resources capability - returning empty list');\n return { resources: [] };\n }\n if (params?.cursor !== undefined) {\n return this.request({ method: 'resources/list', params }, options);\n }\n const hit = await this._serveFromCache<ListResourcesResult>('resources/list', undefined, options);\n if (hit !== undefined) return hit;\n return this._listAllPages<ListResourcesResult>('resources/list', params, options, (acc, page) =>\n acc.resources.push(...page.resources)\n );\n }\n\n /**\n * Lists available resource URI templates for dynamic resources.\n *\n * Called without a `cursor`, this walks every page and returns the\n * complete aggregated list with no `nextCursor`; the aggregate is\n * also written to the {@linkcode ResponseCacheStore}. Pass an explicit\n * `{ cursor }` to fetch a single page — see\n * {@linkcode listResources | listResources()} for the per-page contract.\n *\n * Returns an empty list if the server does not advertise resources capability\n * (or throws if {@linkcode ClientOptions.enforceStrictCapabilities} is enabled).\n */\n async listResourceTemplates(\n params?: ListResourceTemplatesRequest['params'],\n options?: CacheableRequestOptions\n ): Promise<ListResourceTemplatesResult> {\n if (!this._serverCapabilities?.resources && !this._enforceStrictCapabilities) {\n // Respect capability negotiation: server does not support resources\n console.debug(\n 'Client.listResourceTemplates() called but server does not advertise resources capability - returning empty list'\n );\n return { resourceTemplates: [] };\n }\n if (params?.cursor !== undefined) {\n return this.request({ method: 'resources/templates/list', params }, options);\n }\n const hit = await this._serveFromCache<ListResourceTemplatesResult>('resources/templates/list', undefined, options);\n if (hit !== undefined) return hit;\n return this._listAllPages<ListResourceTemplatesResult>('resources/templates/list', params, options, (acc, page) =>\n acc.resourceTemplates.push(...page.resourceTemplates)\n );\n }\n\n /**\n * Walk every page of a paginated list verb, aggregate, and write ONE\n * entry to the response cache. Internal — backs the public `list*`\n * methods' no-`cursor` auto-aggregate path. Page 1's result object is\n * mutated in place (its items array is extended; `nextCursor` is\n * cleared); page-1 metadata (`ttlMs`, `cacheScope`, `_meta`) is preserved.\n * A `nextCursor` that repeats stops the walk (defence against a\n * non-converging server, mcp.d's `drainList` guard);\n * {@linkcode ClientOptions.listMaxPages} is a hard cap — hitting it\n * throws, so a partial aggregate is never cached. The\n * captured-generation guard skips the write when a `list_changed` landed\n * mid-walk, so the eviction is never overwritten by a stale aggregate.\n * `finalize` runs on the complete aggregate before the cache write — the\n * SEP-2243 invalid-`x-mcp-header` exclusion hooks here so the cached\n * `tools/list` entry is already filtered.\n *\n * The caller's `baseParams` (everything except `cursor`) is threaded into\n * every page request — page 1 sends `{...baseParams}`, later pages\n * `{...baseParams, cursor}` — so a typed, documented `_meta` (e.g. W3C\n * trace context) supplied to the public `list*()` reaches every wire\n * request the walk issues.\n */\n private async _listAllPages<R extends { nextCursor?: string }>(\n method: RequestMethod,\n baseParams: { readonly [key: string]: unknown } | undefined,\n options: CacheableRequestOptions | undefined,\n append: (acc: R, page: R) => void,\n finalize?: (acc: R) => void\n ): Promise<R> {\n // `'bypass'` is the no-touch path: the cache is neither read nor\n // written, so the substrate is byte-untouched (the `tools/list`\n // derived index keeps whatever it held).\n const bypass = options?.cacheMode === 'bypass';\n // Capture the eviction generation BEFORE page 1: a `list_changed` that\n // lands mid-walk bumps the counter, and the terminal `write` skips\n // when it observes the bump (the result still returns to the caller —\n // it just is not cached).\n const generation = this._cache.captureGeneration(method);\n const acc = (await this.request({ method, ...(baseParams && { params: { ...baseParams } }) }, options)) as R;\n let cursor = acc.nextCursor;\n const seen = new Set<string>();\n let pages = 1;\n while (cursor !== undefined && !seen.has(cursor)) {\n if (this._listMaxPages !== 0 && pages >= this._listMaxPages) {\n throw new SdkError(\n SdkErrorCode.ListPaginationExceeded,\n `${method}: exceeded listMaxPages (${this._listMaxPages}); server pagination did not terminate`,\n { method, listMaxPages: this._listMaxPages }\n );\n }\n seen.add(cursor);\n const page = (await this.request({ method, params: { ...baseParams, cursor } }, options)) as R;\n append(acc, page);\n cursor = page.nextCursor;\n pages++;\n }\n // delete, not `= undefined`: the cache's JSON codec drops\n // explicit-undefined properties, so only absence keeps\n // `'nextCursor' in result` identical between wire and cache hit.\n delete acc.nextCursor;\n finalize?.(acc);\n if (bypass) return acc;\n // The aggregate is ALWAYS written: even when the resolved TTL is ≤0\n // the entry is stored already-stale (mcp.d's `retainForSchema`\n // posture) so the `tools/list`-derived index keeps working regardless,\n // while the freshness gate in `_serveFromCache` never serves it.\n // Page-1 carries the result-level `ttlMs`/`cacheScope` (`acc` IS the\n // mutated page-1 object).\n await this._cache.write(method, acc, generation, this._freshness(acc));\n return acc;\n }\n\n /**\n * Compute the {@linkcode ClientResponseCache.write} freshness payload from\n * a cacheable result body. The single seam through which the client reads\n * `ttlMs`/`cacheScope` (mcp.d's `cachedFetch` engine). The fields pass\n * through the loose result schema, so they are read off the runtime body;\n * a missing `ttlMs` falls back to\n * {@linkcode ClientOptions | ClientOptions.defaultCacheTtlMs}; an explicit server-sent\n * `ttlMs` (including `0` — the spec's \"immediately stale\") is honoured\n * as-is. The default of `0` means `expiresAt === now()` ⇒ never served,\n * only stored. A missing `cacheScope` is treated as `'private'` — the\n * spec's `'public'` grant (\"any client … MAY serve to any user\") is too\n * strong to infer by default, and matches this SDK's server-side stamp\n * default.\n */\n private _freshness(result: unknown, params?: string): { expiresAt: number; scope: CacheScope; params?: string } {\n const body = result as { ttlMs?: unknown; cacheScope?: unknown };\n const ttlMs = typeof body.ttlMs === 'number' ? body.ttlMs : this._defaultCacheTtlMs;\n const scope: CacheScope = body.cacheScope === 'public' ? 'public' : 'private';\n // Clamp at 24h (`MAX_CACHE_TTL_MS`) so a server cannot pin an entry\n // indefinitely; floor at 0 so a negative `ttlMs` is treated as\n // immediately stale (the spec's absent-or-≤0 rule).\n return { expiresAt: this._cache.now() + Math.min(Math.max(0, ttlMs), MAX_CACHE_TTL_MS), scope, params };\n }\n\n /**\n * The cache-serving front of every cacheable verb (mcp.d's `cachedFetch`\n * read half): under `cacheMode: 'use'` (the default), a fresh held entry\n * is served and the round trip is skipped. `'refresh'` and `'bypass'`\n * always fetch (the caller decides whether to write). Freshness and\n * decoding live in {@linkcode ClientResponseCache.read}; every hit is\n * freshly parsed, so the caller owns it outright. A custom store\n * whose `get()` rejects is routed to `onerror` and treated as a miss —\n * cache bookkeeping never blocks a request from reaching the wire.\n */\n private async _serveFromCache<R>(\n method: string,\n params: string | undefined,\n options: CacheableRequestOptions | undefined\n ): Promise<R | undefined> {\n if (options?.cacheMode === 'bypass' || options?.cacheMode === 'refresh') return undefined;\n const hit = await this._cache.read(method, params).catch(error => void this._reportStoreError(error));\n if (hit !== undefined) {\n // A pre-aborted caller signal must reject the same way it would on\n // the wire path (`Protocol.request()` wraps an already-aborted\n // signal as `SdkError(RequestTimeout, reason)`); without this guard\n // a cache hit would resolve successfully and silently swallow the\n // abort.\n if (options?.signal?.aborted) {\n const reason = options.signal.reason;\n throw reason instanceof SdkError ? reason : new SdkError(SdkErrorCode.RequestTimeout, String(reason));\n }\n return hit.value as R;\n }\n return undefined;\n }\n\n /** Route a custom-store failure to `onerror` without aborting the surrounding dispatch. */\n private _reportStoreError(e: unknown): void {\n this.onerror?.(e instanceof Error ? e : new Error(String(e)));\n }\n\n /**\n * Compile a single tool's `outputSchema`. Passed as the compile callback to\n * {@linkcode ClientResponseCache.outputValidator} so the cache class stays\n * free of any validator-provider dependency, and called directly for the\n * `options.toolDefinition` path of {@linkcode callTool} (a one-off\n * caller-supplied definition is compiled in isolation and never enters the\n * cache, so it cannot poison the listed tool of the same name).\n *\n * Returns `undefined` when the tool has no `outputSchema`, or a\n * discriminated `{ok}` result otherwise. SEP-2106: ANY throw from the\n * validator engine — unsupported `$schema` dialect, invalid `pattern`\n * regex, unresolvable `$ref`, or any other engine error — is captured as\n * `{ok: false, compileError}` so one bad schema does not poison the rest\n * of the listing; `callTool()` surfaces it as an `InvalidParams` error\n * before the request. The `{ok}` discriminator (not\n * `compileError !== undefined`) means a custom provider that does\n * `throw undefined` is still treated as a captured failure.\n */\n private _compileOutputValidator(tool: Tool): OutputSchemaCompileResult | undefined {\n if (!tool.outputSchema) return undefined;\n try {\n return { ok: true, validator: this._jsonSchemaValidator.getValidator(tool.outputSchema as JsonSchemaType) };\n } catch (error) {\n return { ok: false, compileError: error };\n }\n }\n\n /**\n * Resolve the SEP-2243 `x-mcp-header` declaration scan for a tool name.\n *\n * The caller-supplied `toolDefinition` escape hatch wins; otherwise the\n * cached `tools/list` entry (via the cache's `toolDefinition`) is the\n * source. Freshness is the response cache's lifecycle: `list_changed`\n * evicts, otherwise the held schema is the best information available\n * regardless of age, and a stale schema is recovered through the\n * `HEADER_MISMATCH` → evict-refetch-retry path in {@linkcode callTool}.\n * On a miss the call proceeds without `Mcp-Param-*` headers (the spec's\n * \"client SHOULD send without custom headers\" guidance) and relies on the\n * same recovery.\n */\n private async _resolveXMcpHeaderScan(name: string, override: Tool | undefined): Promise<XMcpHeaderScanResult | undefined> {\n const tool = override ?? (await this._cache.toolDefinition(name));\n return tool === undefined ? undefined : scanXMcpHeaderDeclarations(tool.inputSchema);\n }\n\n /**\n * Reads the contents of a resource by URI.\n *\n * Honours the result's `ttlMs`/`cacheScope` (SEP-2549): a still-fresh\n * cached body for the same `uri` is returned without a round trip\n * (`cacheMode: 'use'`, the default). The cache key is `{method, uri}`\n * partitioned by the resolved scope — `'private'` (the default when the\n * server omits the field) is stored under this client's\n * {@linkcode ClientOptions | ClientOptions.cachePartition}, so a shared\n * store cannot serve one principal's resource body to another. Unlike the\n * list verbs, a result whose resolved TTL is ≤0 is **not** stored\n * (`resources/read` has no derived index and the URI keyspace is\n * unbounded).\n */\n async readResource(params: ReadResourceRequest['params'], options?: CacheableRequestOptions): Promise<ReadResourceResult> {\n const hit = await this._serveFromCache<ReadResourceResult>('resources/read', params.uri, options);\n if (hit !== undefined) return hit;\n // Capture the per-URI eviction generation BEFORE the request: a\n // `notifications/resources/updated` for this URI arriving while the\n // read is in flight bumps it (via `evictKey`), and the terminal\n // `write` skips so the now-stale body is not re-cached. Same guard as\n // the list verbs' `_listAllPages`, keyed by `{method, uri}`.\n const generation = this._cache.captureGeneration('resources/read', params.uri);\n const result = await this.request({ method: 'resources/read', params }, options);\n if (options?.cacheMode !== 'bypass') {\n const freshness = this._freshness(result, params.uri);\n if (freshness.expiresAt > this._cache.now()) {\n await this._cache.write('resources/read', result, generation, freshness);\n } else if (options?.cacheMode === 'refresh') {\n // ttl≤0 → drop any held positive-TTL entry so the next\n // default-mode read fetches fresh — a `'refresh'` that\n // returns ttl≤0 must not leave the previously-warm entry\n // serving stale until its old expiry (mcp.d's `cachedFetch`\n // write half evicts on the no-store branch). Only on the\n // `'refresh'` path: a default-mode miss already proved\n // nothing fresh is held (`_serveFromCache` returned\n // `undefined`), so `evictKey`'s store deletes would be wasted\n // round trips against an async store on a ttl≤0 working set.\n await this._cache.evictKey('resources/read', params.uri);\n }\n }\n return result;\n }\n\n /** Subscribes to change notifications for a resource. The server must support resource subscriptions. */\n async subscribeResource(params: SubscribeRequest['params'], options?: RequestOptions): Promise<EmptyResult> {\n return this.request({ method: 'resources/subscribe', params }, options);\n }\n\n /** Unsubscribes from change notifications for a resource. */\n async unsubscribeResource(params: UnsubscribeRequest['params'], options?: RequestOptions): Promise<EmptyResult> {\n return this.request({ method: 'resources/unsubscribe', params }, options);\n }\n\n /**\n * Opens a `subscriptions/listen` stream (protocol revision 2026-07-28).\n *\n * Resolves once the server's `notifications/subscriptions/acknowledged`\n * arrives (the standard request timeout applies to this ack phase). Change\n * notifications delivered on the stream are dispatched to the existing\n * {@linkcode setNotificationHandler} registrations — the same handlers the\n * 2025-era unsolicited notifications fire on a legacy connection — so\n * `listen()` is era-transparent for consumers that already register those.\n *\n * `close()` tears the subscription down by aborting the listen request's\n * `requestSignal` (closes the SSE stream where the transport honors it)\n * AND sending `notifications/cancelled` referencing the listen request id\n * — both, unconditionally, so any spec-compliant server on any transport\n * sees the cancel. No automatic re-listen — call `listen()` again to\n * re-establish.\n *\n * On a 2025-era connection this throws a typed\n * {@linkcode SdkErrorCode.MethodNotSupportedByProtocolVersion} steering to\n * `resources/subscribe` and `ClientOptions.listChanged` (the legacy\n * unsolicited delivery model still applies there); no transparent shim.\n */\n async listen(filter: SubscriptionFilter, options?: RequestOptions): Promise<McpSubscription> {\n // Connectivity is checked first so a closed instance rejects with\n // NotConnected (no setup or ack timer is started); after close(),\n // `_resetConnectionState` has also cleared the negotiated era, so the\n // era guard alone would surface a misleading\n // MethodNotSupportedByProtocolVersion.\n if (this.transport === undefined) {\n throw new SdkError(SdkErrorCode.NotConnected, 'Not connected');\n }\n const negotiated = this._negotiatedProtocolVersion;\n if (negotiated === undefined || !isModernProtocolVersion(negotiated)) {\n throw new SdkError(\n SdkErrorCode.MethodNotSupportedByProtocolVersion,\n `subscriptions/listen requires a 2026-07-28-era connection (negotiated: ${negotiated ?? 'none'}). ` +\n 'On a 2025-era connection, change notifications are delivered unsolicited: use ClientOptions.listChanged ' +\n 'and resources/subscribe instead.',\n { method: 'subscriptions/listen', protocolVersion: negotiated }\n );\n }\n\n // Honor RequestOptions.signal exactly as request() does: an\n // already-aborted signal rejects synchronously before any setup, and\n // the rejection is the same `SdkError(RequestTimeout, reason)` wrap\n // request() / `_serveFromCache` apply (unless `reason` is already an\n // SdkError — preserved verbatim).\n if (options?.signal?.aborted) {\n const reason = options.signal.reason;\n throw reason instanceof SdkError ? reason : new SdkError(SdkErrorCode.RequestTimeout, String(reason));\n }\n\n const requestAbort = new AbortController();\n // The listen request's JSON-RPC id (= the spec's subscription id\n // verbatim). A STRING from a Client-owned counter so it cannot\n // collide with Protocol's numeric `_requestMessageId` counter — the\n // `_onresponse`/`_onnotification` overrides demux by string-id alone.\n const listenId = `listen:${this._nextListenId++}`;\n\n // Explicit `opening → open → closed` state machine. Every termination\n // path — ack-arrives, ack-timeout, server-cancelled, user-close,\n // stream-end, transport-close, send-failure — funnels through the\n // single `settle` below, which clears the ack timer, transitions\n // state, and resolves/rejects the opening promise exactly once. The\n // cancelled-before-ack / close-before-ack hangs are impossible by\n // construction.\n let state: 'opening' | 'open' | 'closed' = 'opening';\n let ackTimer: ReturnType<typeof setTimeout> | undefined;\n let onCallerAbort: (() => void) | undefined;\n let resolveOpening!: (honored: SubscriptionFilter) => void;\n let rejectOpening!: (error: Error) => void;\n const opening = new Promise<SubscriptionFilter>((resolve, reject) => {\n resolveOpening = resolve;\n rejectOpening = reject;\n });\n // The McpSubscription.closed observation. Resolved exactly once by\n // settle()'s `→ closed` transition; never rejects. When listen()\n // itself rejects (pre-ack) there is no McpSubscription to observe it\n // on — settle() resolves it anyway so nothing dangles.\n let resolveClosed!: (cause: 'local' | 'graceful' | 'remote') => void;\n const closed = new Promise<'local' | 'graceful' | 'remote'>(resolve => {\n resolveClosed = resolve;\n });\n\n const settle = (outcome: { ack: SubscriptionFilter } | { cause: 'local' | 'graceful' | 'remote'; error?: Error }): void => {\n if (state === 'closed') return;\n const wasOpening = state === 'opening';\n if (ackTimer !== undefined) {\n clearTimeout(ackTimer);\n ackTimer = undefined;\n }\n if ('ack' in outcome) {\n // The single `opening → open` transition; an ack after close\n // hits the `closed` guard above and is a no-op.\n state = 'open';\n resolveOpening(outcome.ack);\n return;\n }\n state = 'closed';\n if (onCallerAbort !== undefined) {\n options?.signal?.removeEventListener('abort', onCallerAbort);\n }\n this._listenState.delete(listenId);\n // Abort the per-request signal so an HTTP SSE reader stops on a\n // remote-initiated close too (server-cancel / stream-end /\n // transport-drop). Idempotent; a no-op on transports that ignore\n // requestSignal. wireTeardown() also aborts on the local paths —\n // harmless redundancy.\n requestAbort.abort();\n resolveClosed(outcome.cause);\n if (wasOpening) {\n rejectOpening(\n outcome.error ??\n new SdkError(SdkErrorCode.ConnectionClosed, 'subscriptions/listen closed before the server acknowledged')\n );\n }\n };\n\n // Wire-level teardown for a locally-initiated close (user close, ack\n // timeout, caller-signal abort). Transport-agnostic: ALWAYS abort the\n // request signal (closes the SSE stream where the transport honors\n // `requestSignal` — HTTP does, stdio does not) AND send\n // `notifications/cancelled` referencing the listen id (which the\n // stdio listen router and any spec-compliant server honor). Sent via\n // `notification()` so the modern auto-envelope is attached exactly as\n // for every other outbound. Idempotent over HTTP — the cancelled\n // notification is a no-op once the stream is gone; correct on every\n // other transport. Not called when the server already terminated.\n const wireTeardown = async (): Promise<void> => {\n requestAbort.abort();\n await this.notification({ method: 'notifications/cancelled', params: { requestId: listenId } }).catch(() => {});\n };\n\n const close = async (): Promise<void> => {\n if (state === 'closed') return;\n settle({ cause: 'local' });\n await wireTeardown();\n };\n\n // The per-subscription state is registered BEFORE the request is sent\n // so a synchronously-delivered ack (an in-process transport) cannot\n // race the registration.\n this._listenState.set(listenId, { settle });\n\n const ackTimeout = options?.timeout ?? DEFAULT_REQUEST_TIMEOUT_MSEC;\n ackTimer = setTimeout(() => {\n settle({\n cause: 'remote',\n error: new SdkError(SdkErrorCode.RequestTimeout, 'subscriptions/listen ack timed out', { timeout: ackTimeout })\n });\n void wireTeardown().catch(() => {});\n }, ackTimeout);\n\n // RequestOptions.signal aborts the subscription at any point in its\n // lifecycle (mirrors request()'s cancel path). While `opening`, settle\n // rejects the pending listen() promise with the signal's reason; while\n // `open`, it transitions to `closed` (`closed` resolves `'local'`) and\n // tears the wire down. The listener is removed by `settle()` once the\n // subscription has closed.\n if (options?.signal) {\n const callerSignal = options.signal;\n onCallerAbort = () => {\n if (state === 'closed') return;\n const reason = callerSignal.reason;\n settle({ cause: 'local', error: reason instanceof Error ? reason : new Error(String(reason ?? 'Aborted')) });\n void wireTeardown().catch(() => {});\n };\n callerSignal.addEventListener('abort', onCallerAbort, { once: true });\n }\n\n // Send the listen request directly on the transport. The `_meta`\n // envelope is built via the same `_outboundMetaEnvelope()` seam every\n // other outbound uses (so a future envelope key cannot silently\n // diverge here). `onRequestStreamEnd` feeds the per-request stream's\n // non-deliberate end into the state machine on transports that open\n // one (Streamable HTTP); stdio/InMemory ignore it.\n const jsonrpcRequest: JSONRPCRequest = {\n jsonrpc: '2.0',\n id: listenId,\n method: 'subscriptions/listen',\n params: { _meta: { ...this._outboundMetaEnvelope() }, notifications: filter }\n };\n try {\n await this.transport.send(jsonrpcRequest, {\n requestSignal: requestAbort.signal,\n onRequestStreamEnd: () => settle({ cause: 'remote', error: new Error('subscriptions/listen: stream ended') })\n });\n } catch (error) {\n // Synchronous OR awaited send failure (including a per-request\n // abort fired before response headers — `streamableHttp._send`\n // rethrows with onerror suppressed). `settle()` is idempotent so\n // a locally-aborted send hitting this path after `close()` is a\n // no-op.\n settle({ cause: 'remote', error: error instanceof Error ? error : new Error(String(error)) });\n }\n\n const honored = await opening;\n return { honoredFilter: honored, close, closed };\n }\n\n /**\n * The subscription auto-opened by `ClientOptions.listChanged` on a modern\n * connection — the listen filter is the intersection of the configured\n * sub-options and the server-advertised `listChanged` capabilities.\n * `undefined` on a legacy connection, before connect, or when that\n * intersection is empty (auto-open skipped). Exposed so the consumer can\n * `close()` it.\n */\n get autoOpenedSubscription(): McpSubscription | undefined {\n return this._autoOpenedSubscription;\n }\n\n /**\n * Transport-level demux for `subscriptions/listen` notifications, before\n * any decoding/era-gating/handler dispatch. Consumes the leading\n * `notifications/subscriptions/acknowledged` referencing a live\n * subscription id (resolves the ack waiter) and an inbound\n * `notifications/cancelled` referencing a live string-typed subscription\n * id (server-side teardown on stdio). Change notifications carrying a\n * subscription id pass through to the existing registered handlers via\n * `super`. An unmatched ack/cancelled is NOT consumed: it reaches\n * `setNotificationHandler` / `fallbackNotificationHandler` instead of\n * being silently swallowed.\n */\n protected override _onnotification(raw: JSONRPCNotification, extra?: MessageExtraInfo): void {\n // Response-cache invalidation: a `list_changed` notification means the\n // matching cached list result is stale. Evict (do NOT refetch) before\n // dispatch so a handler that reaches the cache observes the cleared\n // entry. Runs regardless of whether the user\n // configured `listChanged` — derived views (the tool index, output\n // validators) must drop the stale entry either way. `raw.method` is\n // server-controlled; guard with `Object.hasOwn` so an inherited\n // `Object.prototype` member name (`constructor`, `toString`, …) does\n // not reach the iteration as a non-iterable function.\n const evicted = Object.hasOwn(LIST_CHANGED_EVICTIONS, raw.method) ? LIST_CHANGED_EVICTIONS[raw.method] : undefined;\n if (raw.method === 'notifications/resources/updated') {\n // Per-URI eviction (mcp.d's `invalidateLogical`): the now-cached\n // `resources/read` body for this URI is stale on receipt; drop it\n // from BOTH partitions so the next `readResource` for the same URI\n // refetches even within TTL (the documented subscribe → updated →\n // re-read flow). Fire-and-forget like the `list_changed` path —\n // dispatch must not block on an async store.\n const uri = (raw.params as { uri?: unknown } | undefined)?.uri;\n if (typeof uri === 'string') void this._cache.evictKey('resources/read', uri);\n } else if (evicted !== undefined) {\n for (const method of evicted) {\n // `evict()` bumps the generation FIRST and unconditionally\n // (the `ClientResponseCache.write` race guard relies on the\n // bump, not on the store's deletes completing), then drops only THIS\n // server's two partition singletons — co-tenants on a shared\n // store keep their entries. Store failures are reported via\n // `onerror` inside `evict()` and the call resolves, so\n // dispatch (and the user's `listChanged` handler) runs\n // regardless. Fire-and-forget — dispatch must not block on\n // an async store.\n void this._cache.evict(method);\n }\n }\n if (raw.method === 'notifications/subscriptions/acknowledged') {\n const params = raw.params as { _meta?: Record<string, unknown>; notifications?: unknown } | undefined;\n const subscriptionId = params?._meta?.[SUBSCRIPTION_ID_META_KEY];\n const entry = typeof subscriptionId === 'string' ? this._listenState.get(subscriptionId) : undefined;\n if (entry !== undefined) {\n // Route through the era codec (the ack is 2026-only\n // vocabulary): a malformed honored filter still settles the\n // listen — `{}` means \"nothing honored\".\n const honored = this._wireCodec().validateNotification('notifications/subscriptions/acknowledged', raw);\n entry.settle({ ack: honored.ok ? honored.value.params.notifications : {} });\n return;\n }\n }\n if (raw.method === 'notifications/cancelled') {\n const cancelledId = (raw.params as { requestId?: unknown } | undefined)?.requestId;\n const entry = typeof cancelledId === 'string' ? this._listenState.get(cancelledId) : undefined;\n if (entry !== undefined) {\n // Handles BOTH the pre-ack and post-ack server-side cancel:\n // while opening, settle rejects the pending listen() promise;\n // once open, settle transitions to closed and `closed` resolves\n // 'remote' so the consumer can observe the server-initiated\n // close.\n entry.settle({ cause: 'remote', error: new Error('subscriptions/listen: server cancelled the subscription') });\n return;\n }\n }\n super._onnotification(raw, extra);\n }\n\n /**\n * Transport-level demux for `subscriptions/listen` responses. A JSON-RPC\n * ERROR for the listen id is the server's pre-ack capacity/params\n * rejection; a JSON-RPC RESULT for the listen id is the spec's\n * `SubscriptionsListenResult` — the server's GRACEFUL-close signal (sent\n * on shutdown). A string-id response that matches a live `_listenState`\n * entry is consumed here (Protocol's `_responseHandlers` map is keyed by\n * NUMBER and never holds a listen id, so passing a string-id response\n * through would surface as \"unknown message ID\" via `onerror`).\n */\n protected override _onresponse(response: JSONRPCResponse): void {\n const id = response.id;\n const entry = typeof id === 'string' ? this._listenState.get(id) : undefined;\n if (entry !== undefined) {\n if (isJSONRPCErrorResponse(response)) {\n entry.settle({\n cause: 'remote',\n error: ProtocolError.fromError(response.error.code, response.error.message, response.error.data)\n });\n } else {\n // The empty `SubscriptionsListenResult` — the server ended\n // the subscription deliberately. Handles both pre-ack and\n // post-ack: while opening, settle rejects the pending listen()\n // promise with a ConnectionClosed (a server that answers\n // before the ack is shutting down before serving); once open,\n // settle transitions to closed and `closed` resolves\n // 'graceful'. Per Q8, the result body itself is not validated\n // — receipt for the listen id IS the signal (foreign servers\n // may omit `_meta`).\n entry.settle({\n cause: 'graceful',\n error: new SdkError(\n SdkErrorCode.ConnectionClosed,\n 'subscriptions/listen: server closed the subscription gracefully before acknowledging'\n )\n });\n }\n return;\n }\n super._onresponse(response);\n }\n\n /**\n * Settle every live per-listen state machine on a transport-initiated\n * close (the server dropping the connection on stdio/InMemory) before\n * Protocol's `_onclose` tears the transport down. The base\n * `_responseHandlers` settlement does not reach `_listenState` (listen\n * ids are never registered there), so without this override a remote\n * close would leave an in-flight `listen()` / open `McpSubscription`\n * hanging.\n */\n protected override _onclose(): void {\n if (this._listenState.size > 0) {\n const reason = new SdkError(SdkErrorCode.ConnectionClosed, 'Connection closed');\n for (const entry of this._listenState.values()) {\n entry.settle({ cause: 'remote', error: reason });\n }\n this._listenState.clear();\n }\n super._onclose();\n }\n\n /**\n * Calls a tool on the connected server and returns the result. Automatically validates structured output\n * if the tool has an `outputSchema`.\n *\n * Tool results have two error surfaces: `result.isError` for tool-level failures (the tool ran but reported\n * a problem), and thrown {@linkcode ProtocolError} for protocol-level failures or {@linkcode SdkError} for\n * SDK-level issues (timeouts, missing capabilities).\n *\n * @example Basic usage\n * ```ts source=\"./client.examples.ts#Client_callTool_basic\"\n * const result = await client.callTool({\n * name: 'calculate-bmi',\n * arguments: { weightKg: 70, heightM: 1.75 }\n * });\n *\n * // Tool-level errors are returned in the result, not thrown\n * if (result.isError) {\n * console.error('Tool error:', result.content);\n * return;\n * }\n *\n * console.log(result.content);\n * ```\n *\n * @example Structured output\n * ```ts source=\"./client.examples.ts#Client_callTool_structuredOutput\"\n * const result = await client.callTool({\n * name: 'calculate-bmi',\n * arguments: { weightKg: 70, heightM: 1.75 }\n * });\n *\n * // Machine-readable output for the client application. SEP-2106: structuredContent is\n * // `unknown` (any JSON value). Check for presence with `!== undefined` and narrow before use.\n * if (result.structuredContent !== undefined) {\n * const sc: unknown = result.structuredContent; // e.g. { bmi: 22.86 }\n * if (typeof sc === 'object' && sc !== null && 'bmi' in sc) {\n * console.log(sc.bmi);\n * }\n * }\n * ```\n */\n async callTool(params: CallToolRequest['params'], options?: CallToolRequestOptions): Promise<CallToolResult> {\n // SEP-2243 `Mcp-Param-*` mirroring (protocol revision 2026-07-28; the\n // 5-step client algorithm, steps 3–5). Modern-era only — the legacy\n // `callTool` path is byte-untouched. Transports that share a single\n // channel (stdio, in-memory) ignore the per-request `headers` option,\n // so the spec's stdio MAY-ignore exemption holds without an explicit\n // branch. In a browser environment, dynamically named `Mcp-Param-*`\n // headers cannot be statically allow-listed for credentialed CORS\n // (`Access-Control-Allow-Headers` admits no wildcard with\n // credentials), so mirroring is skipped. NOTE: a conforming SEP-2243\n // server (including this SDK's own `createMcpHandler`) rejects a\n // `tools/call` whose body carries a non-null value for an\n // `x-mcp-header`-declared parameter when the matching `Mcp-Param-*`\n // header is absent — so a browser client of this SDK cannot\n // successfully call such a tool with that argument present unless the\n // server relaxes the missing-header check. This is a known limitation\n // of running SEP-2243 from a browser; pass `null` for the designated\n // argument or supply `options.toolDefinition` against a relaxed server.\n const mirroringActive = this.getProtocolEra() === 'modern' && detectProbeEnvironment() !== 'browser';\n // Mirroring (and output-schema validation below) read the cached\n // `tools/list` entry directly via `_cache.toolDefinition` /\n // `_cache.outputValidator`. `callTool` never issues a `tools/list`\n // itself — the cache is populated by the caller's own\n // {@linkcode listTools | listTools()} (which now auto-aggregates) and\n // by the `HEADER_MISMATCH` recovery path below. A cold cache means\n // the call proceeds without `Mcp-Param-*` headers (the spec's\n // \"client SHOULD send without custom headers\" guidance) and without\n // output-schema validation (the v1.x opportunistic behaviour, kept so\n // a legacy/stdio `callTool` still issues zero extra requests).\n const buildSendOptions = async (): Promise<CallToolRequestOptions | undefined> => {\n if (!mirroringActive) return options;\n // A custom store's `get()` may reject (the documented store\n // contract); route that to `onerror` and degrade to sending\n // without `Mcp-Param-*` headers — same posture as a cold cache —\n // rather than aborting the call before it reaches the wire.\n let scan: XMcpHeaderScanResult | undefined;\n try {\n scan = await this._resolveXMcpHeaderScan(params.name, options?.toolDefinition);\n } catch (error) {\n this._reportStoreError(error);\n }\n if (!scan?.valid || scan.declarations.length === 0) return options;\n const paramHeaders = buildMcpParamHeaders(scan.declarations, params.arguments);\n return Object.keys(paramHeaders).length === 0 ? options : { ...options, headers: { ...options?.headers, ...paramHeaders } };\n };\n\n // SEP-2106: resolve the output validator BEFORE the request so a tool whose outputSchema\n // fails to compile (unsupported `$schema` dialect / invalid pattern / unresolvable `$ref` /\n // any engine error) is surfaced here, per-tool, without a wasted network round-trip and\n // server-side handler execution. When the caller supplied `toolDefinition`, that definition\n // is the source for BOTH the `Mcp-Param-*` mirroring above AND output validation — the two\n // derived views must agree — and is compiled in isolation (never written to the cache). The\n // cache read is guarded: a custom store whose `get()` rejects routes to `onerror` and\n // degrades to skipping validation (same outcome as a cold cache).\n let compiled =\n options?.toolDefinition === undefined\n ? await this._cache\n .outputValidator(params.name, tool => this._compileOutputValidator(tool))\n .catch(error => void this._reportStoreError(error))\n : this._compileOutputValidator(options.toolDefinition);\n const assertCompiled = (): void => {\n if (compiled === undefined || compiled.ok) return;\n const err = compiled.compileError;\n const message = (err instanceof Error ? err.message : String(err)).slice(0, 200);\n throw new ProtocolError(ProtocolErrorCode.InvalidParams, `Tool '${params.name}' has an invalid outputSchema: ${message}`);\n };\n assertCompiled();\n\n // The method-keyed request() path validates the era registry's plain\n // CallToolResult schema — with the result map aligned to the typed\n // map there is no wider union to narrow away.\n let result: CallToolResult;\n try {\n result = await this.request({ method: 'tools/call', params }, await buildSendOptions());\n } catch (error) {\n // SEP-2243 one-refresh-on-miss: a `HEADER_MISMATCH` rejection on a\n // modern connection means the server enforced an `Mcp-Param-*`\n // header we did not (or could not) send — the cached `tools/list`\n // entry is stale (or cold). Evict it, repopulate via\n // {@linkcode listTools | listTools()} (which auto-aggregates and\n // writes the cache), and retry once with the now-known schema.\n // Never on the legacy era; never when the caller supplied\n // `toolDefinition` (their schema is authoritative).\n const isHeaderMismatch = error instanceof ProtocolError && error.code === HEADER_MISMATCH_ERROR_CODE;\n if (!mirroringActive || !isHeaderMismatch || options?.toolDefinition !== undefined) {\n throw error;\n }\n // `cacheMode: 'refresh'` so the recovery refetch always reaches\n // the wire — `evict()` reports a custom store's `delete()`\n // failure via `onerror` and resolves, but a no-op/failing\n // `delete()` leaves the stale entry in place; without `'refresh'`\n // the `listTools()` below would cache-serve the very entry whose\n // staleness triggered this recovery. The generation bump still\n // happens regardless, so the refetch's write overwrites.\n const refreshOptions = { signal: options?.signal, timeout: options?.timeout, cacheMode: 'refresh' as const };\n await this._cache.evict('tools/list');\n // The recovery refetch may itself fail (e.g. `listMaxPages`, a\n // transient error that hits only the `tools/list` walk). Surface\n // it via `onerror` so the real cause is observable, then proceed\n // to the retry. NOTE: when the refetch fails the cache stays\n // empty and the retry goes out without `Mcp-Param-*` headers, so\n // a conforming server will likely answer a second\n // `HEADER_MISMATCH` — the refetch failure is observable only\n // through `onerror`.\n await this.listTools(undefined, refreshOptions).catch(error_ => this._reportStoreError(error_));\n // Re-resolve the output validator against the freshly-fetched entry — the pre-flight\n // `compiled` was resolved from the now-evicted cache and may be stale (different\n // outputSchema) or absent (cold cache on the first attempt). The recovery path is only\n // entered when `options.toolDefinition` is undefined, so the cache is the sole source.\n // Re-run the same fail-fast compile-error check before issuing the retry.\n compiled = await this._cache\n .outputValidator(params.name, tool => this._compileOutputValidator(tool))\n .catch(error_ => void this._reportStoreError(error_));\n assertCompiled();\n result = await this.request({ method: 'tools/call', params }, await buildSendOptions());\n }\n\n const validator = compiled !== undefined && compiled.ok ? compiled.validator : undefined;\n if (validator) {\n // If tool has outputSchema, it MUST return structuredContent (unless it's an error).\n // SEP-2106: presence is `=== undefined`, not falsy — `null`/`0`/`false`/`\"\"` are legal\n // values and are validated below (so a falsy value against an object-typed schema still\n // fails; this is not a guard weakening).\n if (result.structuredContent === undefined && !result.isError) {\n throw new ProtocolError(\n ProtocolErrorCode.InvalidRequest,\n `Tool ${params.name} has an output schema but did not return structured content`\n );\n }\n\n // Only validate structured content if present (not when there's an error)\n if (result.structuredContent !== undefined && !result.isError) {\n try {\n // Validate the structured content against the schema\n const validationResult = validator(result.structuredContent);\n\n if (!validationResult.valid) {\n throw new ProtocolError(\n ProtocolErrorCode.InvalidParams,\n `Structured content does not match the tool's output schema: ${validationResult.errorMessage}`\n );\n }\n } catch (error) {\n if (error instanceof ProtocolError) {\n throw error;\n }\n throw new ProtocolError(\n ProtocolErrorCode.InvalidParams,\n `Failed to validate structured content: ${error instanceof Error ? error.message : String(error)}`\n );\n }\n }\n }\n\n return result;\n }\n\n /**\n * Lists available tools.\n *\n * Called without a `cursor` (the common case), this walks every page and\n * returns the complete aggregated list with no `nextCursor`; the\n * aggregate is also written to the {@linkcode ResponseCacheStore} (the\n * source for {@linkcode callTool | callTool()}'s output-schema validation\n * and SEP-2243 `Mcp-Param-*` header mirroring). Pass an explicit\n * `{ cursor }` to fetch a single page and walk pagination yourself — the\n * per-page path returns the server's raw page (with `nextCursor` for the\n * next call) and does not write the response cache. The auto-aggregate\n * path is capped by {@linkcode ClientOptions | ClientOptions.listMaxPages} (default 64);\n * the per-page path is not.\n *\n * Returns an empty list if the server does not advertise tools capability\n * (or throws if {@linkcode ClientOptions.enforceStrictCapabilities} is enabled).\n *\n * @example\n * ```ts source=\"./client.examples.ts#Client_listTools_pagination\"\n * // No cursor → all pages aggregated for you.\n * const { tools } = await client.listTools();\n * console.log(\n * 'Available tools:',\n * tools.map(t => t.name)\n * );\n * ```\n */\n async listTools(params?: ListToolsRequest['params'], options?: CacheableRequestOptions): Promise<ListToolsResult> {\n if (!this._serverCapabilities?.tools && !this._enforceStrictCapabilities) {\n // Respect capability negotiation: server does not support tools\n console.debug('Client.listTools() called but server does not advertise tools capability - returning empty list');\n return { tools: [] };\n }\n if (params?.cursor !== undefined) {\n // Per-page: single request, never written to the response cache.\n // SEP-2243: the spec's MUST has no carve-out for paginated reads,\n // so the per-page result is filtered (on a non-stdio modern\n // connection) before returning — the suppressed tool is never\n // observable.\n const page = await this.request({ method: 'tools/list', params }, options);\n this._excludeInvalidXMcpHeaderTools(page);\n return page;\n }\n const hit = await this._serveFromCache<ListToolsResult>('tools/list', undefined, options);\n if (hit !== undefined) return hit;\n // Auto-aggregate: SEP-2243 invalid-`x-mcp-header` exclusion runs on\n // the complete aggregate via the `finalize` hook before the cache\n // write, so the cached entry never holds an unmirrorable tool.\n return this._listAllPages<ListToolsResult>(\n 'tools/list',\n params,\n options,\n (acc, page) => acc.tools.push(...page.tools),\n acc => this._excludeInvalidXMcpHeaderTools(acc)\n );\n }\n\n /**\n * SEP-2243 (protocol revision 2026-07-28): a Streamable HTTP client MUST\n * exclude tool definitions whose `x-mcp-header` declarations violate the\n * constraints, and SHOULD log a warning naming the tool and the reason.\n * Applied to the CACHED aggregated `tools/list` result (so the entry\n * mirroring reads never holds an unmirrorable tool) AND to every public\n * per-page {@linkcode listTools | listTools()} return (the spec's MUST\n * has no carve-out for paginated reads). The gate is era-only on\n * non-stdio transports — `detectProbeTransportKind` cannot distinguish a\n * real HTTP transport from in-memory/custom transports (it only\n * positively recognizes stdio), and over-excluding on a non-HTTP modern\n * connection is harmless: those transports never carry per-request\n * headers, so an excluded tool would have been uncallable on a Streamable\n * HTTP arm of the same server. Mutates `result.tools` in place.\n */\n private _excludeInvalidXMcpHeaderTools(result: ListToolsResult): void {\n if (this.getProtocolEra() !== 'modern' || !this.transport || detectProbeTransportKind(this.transport) === 'stdio') return;\n const filtered = result.tools.filter(tool => {\n const scan = scanXMcpHeaderDeclarations(tool.inputSchema);\n if (!scan.valid) {\n console.warn(`[mcp-sdk] excluding tool '${tool.name}' from tools/list: invalid x-mcp-header declaration — ${scan.reason}`);\n return false;\n }\n return true;\n });\n if (filtered.length !== result.tools.length) result.tools = filtered;\n }\n\n /**\n * Set up a single list changed handler.\n * @internal\n */\n private _setupListChangedHandler<T>(\n listType: string,\n notificationMethod: NotificationMethod,\n options: ListChangedOptions<T>,\n fetcher: () => Promise<T[]>\n ): void {\n // Validate options using Zod schema (validates autoRefresh and debounceMs)\n const parseResult = parseSchema(ListChangedOptionsBaseSchema, options);\n if (!parseResult.success) {\n throw new Error(`Invalid ${listType} listChanged options: ${parseResult.error.message}`);\n }\n\n // Validate callback\n if (typeof options.onChanged !== 'function') {\n throw new TypeError(`Invalid ${listType} listChanged options: onChanged must be a function`);\n }\n\n const { autoRefresh, debounceMs } = parseResult.data;\n const { onChanged } = options;\n\n const refresh = async () => {\n if (!autoRefresh) {\n onChanged(null, null);\n return;\n }\n\n try {\n const items = await fetcher();\n onChanged(null, items);\n } catch (error) {\n const newError = error instanceof Error ? error : new Error(String(error));\n onChanged(newError, null);\n }\n };\n\n const handler = () => {\n if (debounceMs) {\n // Clear any pending debounce timer for this list type\n const existingTimer = this._listChangedDebounceTimers.get(listType);\n if (existingTimer) {\n clearTimeout(existingTimer);\n }\n\n // Set up debounced refresh\n const timer = setTimeout(refresh, debounceMs);\n this._listChangedDebounceTimers.set(listType, timer);\n } else {\n // No debounce, refresh immediately\n refresh();\n }\n };\n\n // Register notification handler\n this.setNotificationHandler(notificationMethod, handler);\n }\n\n /**\n * Notifies the server that the client's root list has changed. Requires the `roots.listChanged` capability.\n *\n * @deprecated Deprecated as of protocol version 2026-07-28 (SEP-2577).\n * Remains functional during the deprecation window (at least twelve months).\n * Migrate to passing paths via tool parameters, resource URIs, or configuration.\n */\n async sendRootsListChanged() {\n return this.notification({ method: 'notifications/roots/list_changed' });\n }\n}\n","/**\n * Cross-App Access (Enterprise Managed Authorization) Layer 2 utilities.\n *\n * Provides standalone functions for RFC 8693 Token Exchange and RFC 7523 JWT Authorization Grant\n * flows as specified in the Enterprise Managed Authorization specification (SEP-990).\n *\n * @see https://github.com/modelcontextprotocol/ext-auth/blob/main/specification/stable/enterprise-managed-authorization.mdx\n * @module\n */\n\nimport type { FetchLike } from '@modelcontextprotocol/core-internal';\nimport { IdJagTokenExchangeResponseSchema, OAuthErrorResponseSchema, OAuthTokensSchema } from '@modelcontextprotocol/core-internal';\n\nimport type { ClientAuthMethod } from './auth';\nimport { applyClientAuthentication, assertSecureTokenEndpoint, discoverAuthorizationServerMetadata } from './auth';\n\n/**\n * Options for requesting a JWT Authorization Grant via RFC 8693 Token Exchange.\n */\nexport interface RequestJwtAuthGrantOptions {\n /**\n * The IdP's token endpoint URL where the token exchange request will be sent.\n */\n tokenEndpoint: string | URL;\n\n /**\n * The authorization server URL of the target MCP server (used as `audience` in the token exchange request).\n */\n audience: string | URL;\n\n /**\n * The resource identifier of the target MCP server (RFC 9728).\n */\n resource: string | URL;\n\n /**\n * The identity assertion (ID Token) from the enterprise IdP.\n * This should be the OpenID Connect ID Token obtained during user authentication.\n */\n idToken: string;\n\n /**\n * The client ID registered with the IdP for token exchange.\n */\n clientId: string;\n\n /**\n * The client secret for authenticating with the IdP.\n *\n * Optional: the IdP may register the MCP client as a public client. RFC 8693 does\n * not mandate confidential clients for token exchange. Omitting this parameter\n * omits `client_secret` from the request body.\n */\n clientSecret?: string;\n\n /**\n * Optional space-separated list of scopes to request for the target MCP server.\n */\n scope?: string;\n\n /**\n * Custom fetch implementation. Defaults to global fetch.\n */\n fetchFn?: FetchLike;\n}\n\n/**\n * Options for discovering the IdP's token endpoint and requesting a JWT Authorization Grant.\n * Extends {@linkcode RequestJwtAuthGrantOptions} with IdP discovery.\n */\nexport interface DiscoverAndRequestJwtAuthGrantOptions extends Omit<RequestJwtAuthGrantOptions, 'tokenEndpoint'> {\n /**\n * The IdP's issuer URL for OAuth metadata discovery.\n * Will be used to discover the token endpoint via `.well-known/oauth-authorization-server`.\n */\n idpUrl: string | URL;\n}\n\n/**\n * Result from a successful JWT Authorization Grant token exchange.\n */\nexport interface JwtAuthGrantResult {\n /**\n * The JWT Authorization Grant (ID-JAG) that can be used to request an access token from the MCP server.\n */\n jwtAuthGrant: string;\n\n /**\n * Optional expiration time in seconds for the JWT Authorization Grant.\n */\n expiresIn?: number;\n\n /**\n * Optional scope granted by the IdP (may differ from requested scope).\n */\n scope?: string;\n}\n\n/**\n * Requests a JWT Authorization Grant (ID-JAG) from an enterprise IdP using RFC 8693 Token Exchange.\n *\n * This function performs step 2 of the Enterprise Managed Authorization flow:\n * exchanges an ID Token for a JWT Authorization Grant that can be used with the target MCP server.\n *\n * @param options - Configuration for the token exchange request\n * @returns The JWT Authorization Grant and related metadata\n * @throws {Error} If the token exchange fails or returns an error response\n *\n * @example\n * ```ts\n * const result = await requestJwtAuthorizationGrant({\n * tokenEndpoint: 'https://idp.example.com/token',\n * audience: 'https://auth.chat.example/',\n * resource: 'https://mcp.chat.example/',\n * idToken: 'eyJhbGciOiJS...',\n * clientId: 'my-idp-client',\n * clientSecret: 'my-idp-secret',\n * scope: 'chat.read chat.history'\n * });\n *\n * // Use result.jwtAuthGrant with the MCP server's authorization server\n * ```\n */\nexport async function requestJwtAuthorizationGrant(options: RequestJwtAuthGrantOptions): Promise<JwtAuthGrantResult> {\n const { tokenEndpoint, audience, resource, idToken, clientId, clientSecret, scope, fetchFn = fetch } = options;\n\n const tokenUrl = assertSecureTokenEndpoint(tokenEndpoint);\n\n // Prepare token exchange request per RFC 8693\n const params = new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:token-exchange',\n requested_token_type: 'urn:ietf:params:oauth:token-type:id-jag',\n audience: String(audience),\n resource: String(resource),\n subject_token: idToken,\n subject_token_type: 'urn:ietf:params:oauth:token-type:id_token',\n client_id: clientId\n });\n\n // Only include client_secret when provided — sending an empty/undefined secret\n // triggers `invalid_client` on strict IdPs that registered this as a public client.\n if (clientSecret) {\n params.set('client_secret', clientSecret);\n }\n\n if (scope) {\n params.set('scope', scope);\n }\n\n const response = await fetchFn(tokenUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded'\n },\n body: params.toString()\n });\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({}));\n\n // Try to parse as OAuth error response\n const parseResult = OAuthErrorResponseSchema.safeParse(errorBody);\n if (parseResult.success) {\n const { error, error_description } = parseResult.data;\n throw new Error(`Token exchange failed: ${error}${error_description ? ` - ${error_description}` : ''}`);\n }\n\n throw new Error(`Token exchange failed with status ${response.status}: ${JSON.stringify(errorBody)}`);\n }\n\n const parseResult = IdJagTokenExchangeResponseSchema.safeParse(await response.json());\n if (!parseResult.success) {\n throw new Error(`Invalid token exchange response: ${parseResult.error.message}`);\n }\n\n return {\n jwtAuthGrant: parseResult.data.access_token,\n expiresIn: parseResult.data.expires_in,\n scope: parseResult.data.scope\n };\n}\n\n/**\n * Discovers the IdP's token endpoint and requests a JWT Authorization Grant.\n *\n * This is a convenience wrapper around {@linkcode requestJwtAuthorizationGrant} that\n * first performs OAuth metadata discovery to find the token endpoint.\n *\n * @param options - Configuration including IdP URL for discovery\n * @returns The JWT Authorization Grant and related metadata\n * @throws {Error} If discovery fails or the token exchange fails\n *\n * @example\n * ```ts\n * const result = await discoverAndRequestJwtAuthGrant({\n * idpUrl: 'https://idp.example.com',\n * audience: 'https://auth.chat.example/',\n * resource: 'https://mcp.chat.example/',\n * idToken: await getIdToken(),\n * clientId: 'my-idp-client',\n * clientSecret: 'my-idp-secret'\n * });\n * ```\n */\nexport async function discoverAndRequestJwtAuthGrant(options: DiscoverAndRequestJwtAuthGrantOptions): Promise<JwtAuthGrantResult> {\n const { idpUrl, fetchFn = fetch, ...restOptions } = options;\n\n // Discover IdP's authorization server metadata\n const metadata = await discoverAuthorizationServerMetadata(String(idpUrl), { fetchFn });\n\n if (!metadata?.token_endpoint) {\n throw new Error(`Failed to discover token endpoint for IdP: ${idpUrl}`);\n }\n\n // Perform token exchange\n return requestJwtAuthorizationGrant({\n ...restOptions,\n tokenEndpoint: metadata.token_endpoint,\n fetchFn\n });\n}\n\n/**\n * Exchanges a JWT Authorization Grant for an access token at the MCP server's authorization server.\n *\n * This function performs step 3 of the Enterprise Managed Authorization flow:\n * uses the JWT Authorization Grant to obtain an access token from the MCP server.\n *\n * @param options - Configuration for the JWT grant exchange\n * @returns OAuth tokens (access token, token type, etc.)\n * @throws {Error} If the exchange fails or returns an error response\n *\n * Defaults to `client_secret_basic` (HTTP Basic Authorization header), matching\n * `CrossAppAccessProvider`'s declared `token_endpoint_auth_method` and the\n * SEP-990 conformance test requirements. Use `authMethod: 'client_secret_post'` only\n * when the authorization server explicitly requires it.\n *\n * @example\n * ```ts\n * const tokens = await exchangeJwtAuthGrant({\n * tokenEndpoint: 'https://auth.chat.example/token',\n * jwtAuthGrant: 'eyJhbGci...',\n * clientId: 'my-mcp-client',\n * clientSecret: 'my-mcp-secret'\n * });\n *\n * // Use tokens.access_token to access the MCP server\n * ```\n */\nexport async function exchangeJwtAuthGrant(options: {\n tokenEndpoint: string | URL;\n jwtAuthGrant: string;\n clientId: string;\n clientSecret?: string;\n /**\n * Client authentication method. Defaults to `'client_secret_basic'` to align with\n * `CrossAppAccessProvider` and SEP-990 conformance requirements.\n * Callers with no `clientSecret` should pass `'none'` for public-client auth.\n */\n authMethod?: ClientAuthMethod;\n fetchFn?: FetchLike;\n}): Promise<{ access_token: string; token_type: string; expires_in?: number; scope?: string }> {\n const { tokenEndpoint, jwtAuthGrant, clientId, clientSecret, authMethod = 'client_secret_basic', fetchFn = fetch } = options;\n\n const tokenUrl = assertSecureTokenEndpoint(tokenEndpoint);\n\n // Prepare JWT bearer grant request per RFC 7523\n const params = new URLSearchParams({\n grant_type: 'urn:ietf:params:oauth:grant-type:jwt-bearer',\n assertion: jwtAuthGrant\n });\n\n const headers = new Headers({\n 'Content-Type': 'application/x-www-form-urlencoded'\n });\n\n applyClientAuthentication(authMethod, { client_id: clientId, client_secret: clientSecret }, headers, params);\n\n const response = await fetchFn(tokenUrl, {\n method: 'POST',\n headers,\n body: params.toString()\n });\n\n if (!response.ok) {\n const errorBody = await response.json().catch(() => ({}));\n\n // Try to parse as OAuth error response\n const parseResult = OAuthErrorResponseSchema.safeParse(errorBody);\n if (parseResult.success) {\n const { error, error_description } = parseResult.data;\n throw new Error(`JWT grant exchange failed: ${error}${error_description ? ` - ${error_description}` : ''}`);\n }\n\n throw new Error(`JWT grant exchange failed with status ${response.status}: ${JSON.stringify(errorBody)}`);\n }\n\n const responseBody = await response.json();\n\n // Validate response using core schema\n const parseResult = OAuthTokensSchema.safeParse(responseBody);\n if (!parseResult.success) {\n throw new Error(`Invalid token response: ${parseResult.error.message}`);\n }\n\n return parseResult.data;\n}\n","import type { FetchLike } from '@modelcontextprotocol/core-internal';\n\nimport type { OAuthClientProvider } from './auth';\nimport { auth, extractWWWAuthenticateParams, UnauthorizedError } from './auth';\n\n/**\n * Middleware function that wraps and enhances fetch functionality.\n * Takes a fetch handler and returns an enhanced fetch handler.\n */\nexport type Middleware = (next: FetchLike) => FetchLike;\n\n/**\n * Creates a fetch wrapper that handles OAuth authentication automatically.\n *\n * This wrapper will:\n * - Add `Authorization` headers with access tokens\n * - Handle 401 responses by attempting re-authentication\n * - Retry the original request after successful auth\n * - Handle OAuth errors appropriately ({@linkcode index.OAuthErrorCode.InvalidClient | OAuthErrorCode.InvalidClient}, etc.)\n *\n * The `baseUrl` parameter is optional and defaults to using the domain from the request URL.\n * However, you should explicitly provide `baseUrl` when:\n * - Making requests to multiple subdomains (e.g., api.example.com, cdn.example.com)\n * - Using API paths that differ from OAuth discovery paths (e.g., requesting /api/v1/data but OAuth is at /)\n * - The OAuth server is on a different domain than your API requests\n * - You want to ensure consistent OAuth behavior regardless of request URLs\n *\n * For MCP transports, set `baseUrl` to the same URL you pass to the transport constructor.\n *\n * Note: This wrapper is designed for general-purpose fetch operations.\n * MCP transports (SSE and StreamableHTTP) already have built-in OAuth handling\n * and should not need this wrapper.\n *\n * @param provider - OAuth client provider for authentication\n * @param baseUrl - Base URL for OAuth server discovery (defaults to request URL domain)\n * @returns A fetch middleware function\n */\nexport const withOAuth =\n (provider: OAuthClientProvider, baseUrl?: string | URL): Middleware =>\n next => {\n return async (input, init) => {\n const makeRequest = async (): Promise<Response> => {\n const headers = new Headers(init?.headers);\n\n // Add authorization header if tokens are available\n const tokens = await provider.tokens();\n if (tokens) {\n headers.set('Authorization', `Bearer ${tokens.access_token}`);\n }\n\n return await next(input, { ...init, headers });\n };\n\n let response = await makeRequest();\n\n // Handle 401 responses by attempting re-authentication\n if (response.status === 401) {\n try {\n const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n\n // Use provided baseUrl or extract from request URL\n const serverUrl = baseUrl || (typeof input === 'string' ? new URL(input).origin : input.origin);\n\n const result = await auth(provider, {\n serverUrl,\n resourceMetadataUrl,\n scope,\n fetchFn: next\n });\n\n if (result === 'REDIRECT') {\n throw new UnauthorizedError('Authentication requires user authorization - redirect initiated');\n }\n\n if (result !== 'AUTHORIZED') {\n throw new UnauthorizedError(`Authentication failed with result: ${result}`);\n }\n\n // Retry the request with fresh tokens\n response = await makeRequest();\n } catch (error) {\n if (error instanceof UnauthorizedError) {\n throw error;\n }\n throw new UnauthorizedError(`Failed to re-authenticate: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n // If we still have a 401 after re-auth attempt, throw an error\n if (response.status === 401) {\n const url = typeof input === 'string' ? input : input.toString();\n throw new UnauthorizedError(`Authentication failed for ${url}`);\n }\n\n return response;\n };\n };\n\n/**\n * Logger function type for HTTP requests\n */\nexport type RequestLogger = (input: {\n method: string;\n url: string | URL;\n status: number;\n statusText: string;\n duration: number;\n requestHeaders?: Headers;\n responseHeaders?: Headers;\n error?: Error;\n}) => void;\n\n/**\n * Configuration options for the logging middleware\n */\nexport type LoggingOptions = {\n /**\n * Custom logger function, defaults to console logging\n */\n logger?: RequestLogger;\n\n /**\n * Whether to include request headers in logs\n * @default false\n */\n includeRequestHeaders?: boolean;\n\n /**\n * Whether to include response headers in logs\n * @default false\n */\n includeResponseHeaders?: boolean;\n\n /**\n * Status level filter - only log requests with status >= this value\n * Set to `0` to log all requests, `400` to log only errors\n * @default 0\n */\n statusLevel?: number;\n};\n\n/**\n * Creates a fetch middleware that logs HTTP requests and responses.\n *\n * When called without arguments `withLogging()`, it uses the default logger that:\n * - Logs successful requests (2xx) to `console.log`\n * - Logs error responses (4xx/5xx) and network errors to `console.error`\n * - Logs all requests regardless of status (`statusLevel: 0`)\n * - Does not include request or response headers in logs\n * - Measures and displays request duration in milliseconds\n *\n * Important: the default logger uses both `console.log` and `console.error` so it should not be used with\n * `stdio` transports and applications.\n *\n * @param options - Logging configuration options\n * @returns A fetch middleware function\n */\nexport const withLogging = (options: LoggingOptions = {}): Middleware => {\n const { logger, includeRequestHeaders = false, includeResponseHeaders = false, statusLevel = 0 } = options;\n\n const defaultLogger: RequestLogger = input => {\n const { method, url, status, statusText, duration, requestHeaders, responseHeaders, error } = input;\n\n let message = error\n ? `HTTP ${method} ${url} failed: ${error.message} (${duration}ms)`\n : `HTTP ${method} ${url} ${status} ${statusText} (${duration}ms)`;\n\n // Add headers to message if requested\n if (includeRequestHeaders && requestHeaders) {\n const reqHeaders = [...requestHeaders.entries()].map(([key, value]) => `${key}: ${value}`).join(', ');\n message += `\\n Request Headers: {${reqHeaders}}`;\n }\n\n if (includeResponseHeaders && responseHeaders) {\n const resHeaders = [...responseHeaders.entries()].map(([key, value]) => `${key}: ${value}`).join(', ');\n message += `\\n Response Headers: {${resHeaders}}`;\n }\n\n if (error || status >= 400) {\n // eslint-disable-next-line no-console\n console.error(message);\n } else {\n // eslint-disable-next-line no-console\n console.log(message);\n }\n };\n\n const logFn = logger || defaultLogger;\n\n return next => async (input, init) => {\n const startTime = performance.now();\n const method = init?.method || 'GET';\n const url = typeof input === 'string' ? input : input.toString();\n const requestHeaders = includeRequestHeaders ? new Headers(init?.headers) : undefined;\n\n try {\n const response = await next(input, init);\n const duration = performance.now() - startTime;\n\n // Only log if status meets the log level threshold\n if (response.status >= statusLevel) {\n logFn({\n method,\n url,\n status: response.status,\n statusText: response.statusText,\n duration,\n requestHeaders,\n responseHeaders: includeResponseHeaders ? response.headers : undefined\n });\n }\n\n return response;\n } catch (error) {\n const duration = performance.now() - startTime;\n\n // Always log errors regardless of log level\n logFn({\n method,\n url,\n status: 0,\n statusText: 'Network Error',\n duration,\n requestHeaders,\n error: error as Error\n });\n\n throw error;\n }\n };\n};\n\n/**\n * Composes multiple fetch middleware functions into a single middleware pipeline.\n * Middleware are applied in the order they appear, creating a chain of handlers.\n *\n * @example\n * ```ts source=\"./middleware.examples.ts#applyMiddlewares_basicUsage\"\n * // Create a middleware pipeline that handles both OAuth and logging\n * const enhancedFetch = applyMiddlewares(withOAuth(oauthProvider, 'https://api.example.com'), withLogging({ statusLevel: 400 }))(fetch);\n *\n * // Use the enhanced fetch - it will handle auth and log errors\n * const response = await enhancedFetch('https://api.example.com/data');\n * ```\n *\n * @param middleware - Array of fetch middleware to compose into a pipeline\n * @returns A single composed middleware function\n */\nexport const applyMiddlewares = (...middleware: Middleware[]): Middleware => {\n return next => {\n let handler = next;\n for (const mw of middleware) {\n handler = mw(handler);\n }\n return handler;\n };\n};\n\n/**\n * Helper function to create custom fetch middleware with cleaner syntax.\n * Provides the next handler and request details as separate parameters for easier access.\n *\n * @example\n * ```ts source=\"./middleware.examples.ts#createMiddleware_examples\"\n * // Create custom authentication middleware\n * const customAuthMiddleware = createMiddleware(async (next, input, init) => {\n * const headers = new Headers(init?.headers);\n * headers.set('X-Custom-Auth', 'my-token');\n *\n * const response = await next(input, { ...init, headers });\n *\n * if (response.status === 401) {\n * console.log('Authentication failed');\n * }\n *\n * return response;\n * });\n *\n * // Create conditional middleware\n * const conditionalMiddleware = createMiddleware(async (next, input, init) => {\n * const url = typeof input === 'string' ? input : input.toString();\n *\n * // Only add headers for API routes\n * if (url.includes('/api/')) {\n * const headers = new Headers(init?.headers);\n * headers.set('X-API-Version', 'v2');\n * return next(input, { ...init, headers });\n * }\n *\n * // Pass through for non-API routes\n * return next(input, init);\n * });\n *\n * // Create caching middleware\n * const cacheMiddleware = createMiddleware(async (next, input, init) => {\n * const cacheKey = typeof input === 'string' ? input : input.toString();\n *\n * // Check cache first\n * const cached = await getFromCache(cacheKey);\n * if (cached) {\n * return new Response(cached, { status: 200 });\n * }\n *\n * // Make request and cache result\n * const response = await next(input, init);\n * if (response.ok) {\n * await saveToCache(cacheKey, await response.clone().text());\n * }\n *\n * return response;\n * });\n * ```\n *\n * @param handler - Function that receives the next handler and request parameters\n * @returns A fetch middleware function\n */\nexport const createMiddleware = (handler: (next: FetchLike, input: string | URL, init?: RequestInit) => Promise<Response>): Middleware => {\n return next => (input, init) => handler(next, input as string | URL, init);\n};\n","import type { FetchLike, JSONRPCMessage, Transport } from '@modelcontextprotocol/core-internal';\nimport {\n brandedHasInstance,\n createFetchWithInit,\n JSONRPCMessageSchema,\n normalizeHeaders,\n SdkError,\n SdkErrorCode,\n SdkHttpError,\n stampErrorBrands\n} from '@modelcontextprotocol/core-internal';\nimport type { ErrorEvent, EventSourceInit } from 'eventsource';\nimport { EventSource } from 'eventsource';\n\nimport type { AuthProvider, OAuthClientProvider } from './auth';\nimport {\n adaptOAuthProvider,\n auth,\n extractWWWAuthenticateParams,\n isOAuthClientProvider,\n resolveAuthorizationCallbackParams,\n UnauthorizedError\n} from './auth';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- referenced in JSDoc {@linkcode}\nimport type { IssuerMismatchError } from './authErrors';\nimport { markAuthSeamEscape } from './authSeam';\n\nexport class SseError extends Error {\n static {\n Object.defineProperty(this, 'mcpBrand', { value: 'mcp.SseError' });\n }\n\n static override [Symbol.hasInstance](value: unknown): boolean {\n return brandedHasInstance(this, value);\n }\n\n /**\n * Brand-based type guard: equivalent to `value instanceof this`, as an\n * explicit static predicate (the axios/AWS-SDK `isInstance` style). Reads\n * the caller's own brand via `this`, so every branded subclass gets a\n * correctly-scoped guard by inheritance. Must be invoked on the class —\n * in callback position write `v => SdkError.isInstance(v)`, not\n * `.filter(SdkError.isInstance)` (detached calls throw rather than\n * silently matching nothing).\n */\n static isInstance<T extends abstract new (...args: never[]) => unknown>(this: T, value: unknown): value is InstanceType<T> {\n if (typeof this !== 'function') {\n throw new TypeError(\n 'isInstance must be called on the class (e.g. `SdkError.isInstance(value)`); for callbacks use `v => SdkError.isInstance(v)`'\n );\n }\n return brandedHasInstance(this, value);\n }\n\n constructor(\n public readonly code: number | undefined,\n message: string | undefined,\n public readonly event: ErrorEvent\n ) {\n super(`SSE error: ${message}`);\n stampErrorBrands(this, new.target);\n }\n}\n\n/**\n * Configuration options for the {@linkcode SSEClientTransport}.\n */\nexport type SSEClientTransportOptions = {\n /**\n * An OAuth client provider to use for authentication.\n *\n * {@linkcode AuthProvider.token | token()} is called before every request to obtain the\n * bearer token. When the server responds with 401, {@linkcode AuthProvider.onUnauthorized | onUnauthorized()}\n * is called (if provided) to refresh credentials, then the request is retried once. If\n * the retry also gets 401, or `onUnauthorized` is not provided, {@linkcode UnauthorizedError}\n * is thrown.\n *\n * For simple bearer tokens: `{ token: async () => myApiKey }`.\n *\n * For OAuth flows, pass an {@linkcode index.OAuthClientProvider | OAuthClientProvider} implementation.\n * Interactive flows: after {@linkcode UnauthorizedError}, redirect the user, then call\n * {@linkcode SSEClientTransport.finishAuth | finishAuth} with the authorization code before reconnecting.\n */\n authProvider?: AuthProvider | OAuthClientProvider;\n\n /**\n * Opt-out for the RFC 8414 §3.3 issuer-echo check during authorization-server\n * metadata discovery. **Security-weakening** — see\n * {@linkcode index.AuthOptions.skipIssuerMetadataValidation | AuthOptions.skipIssuerMetadataValidation}.\n * Only honoured when {@linkcode SSEClientTransportOptions.authProvider | authProvider}\n * is an `OAuthClientProvider`.\n */\n skipIssuerMetadataValidation?: boolean;\n\n /**\n * Customizes the initial SSE request to the server (the request that begins the stream).\n *\n * NOTE: Setting this property will prevent an `Authorization` header from\n * being automatically attached to the SSE request, if an {@linkcode SSEClientTransportOptions.authProvider | authProvider} is\n * also given. This can be worked around by setting the `Authorization` header\n * manually.\n */\n eventSourceInit?: EventSourceInit;\n\n /**\n * Customizes recurring `POST` requests to the server.\n */\n requestInit?: RequestInit;\n\n /**\n * Custom fetch implementation used for all network requests.\n */\n fetch?: FetchLike;\n};\n\n/**\n * Client transport for SSE: this will connect to a server using Server-Sent Events for receiving\n * messages and make separate `POST` requests for sending messages.\n * @deprecated SSEClientTransport is deprecated. Prefer to use {@linkcode index.StreamableHTTPClientTransport | StreamableHTTPClientTransport} where possible instead. Note that because some servers are still using SSE, clients may need to support both transports during the migration period.\n */\nexport class SSEClientTransport implements Transport {\n private _eventSource?: EventSource;\n private _endpoint?: URL;\n private _abortController?: AbortController;\n private _url: URL;\n private _resourceMetadataUrl?: URL;\n private _scope?: string;\n private _eventSourceInit?: EventSourceInit;\n private _requestInit?: RequestInit;\n private _authProvider?: AuthProvider;\n private _oauthProvider?: OAuthClientProvider;\n private _skipIssuerMetadataValidation?: boolean;\n private _fetch?: FetchLike;\n private _fetchWithInit: FetchLike;\n private _protocolVersion?: string;\n\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n constructor(url: URL, opts?: SSEClientTransportOptions) {\n this._url = url;\n this._resourceMetadataUrl = undefined;\n this._scope = undefined;\n this._eventSourceInit = opts?.eventSourceInit;\n this._requestInit = opts?.requestInit;\n this._skipIssuerMetadataValidation = opts?.skipIssuerMetadataValidation;\n if (isOAuthClientProvider(opts?.authProvider)) {\n this._oauthProvider = opts.authProvider;\n this._authProvider = adaptOAuthProvider(opts.authProvider, {\n skipIssuerMetadataValidation: opts.skipIssuerMetadataValidation\n });\n } else {\n this._authProvider = opts?.authProvider;\n }\n this._fetch = opts?.fetch;\n this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);\n }\n\n private _last401Response?: Response;\n\n private async _commonHeaders(): Promise<Headers> {\n const headers: RequestInit['headers'] & Record<string, string> = {};\n let token: string | undefined;\n try {\n token = await this._authProvider?.token();\n } catch (error) {\n // Auth-seam stamp: a throwing token() is an auth failure, never a\n // network failure.\n throw markAuthSeamEscape(error);\n }\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n if (this._protocolVersion) {\n headers['mcp-protocol-version'] = this._protocolVersion;\n }\n\n const extraHeaders = normalizeHeaders(this._requestInit?.headers);\n\n return new Headers({\n ...headers,\n ...extraHeaders\n });\n }\n\n private _startOrAuth(): Promise<void> {\n const fetchImpl = (this?._eventSourceInit?.fetch ?? this._fetch ?? fetch) as typeof fetch;\n return new Promise((resolve, reject) => {\n this._eventSource = new EventSource(this._url.href, {\n ...this._eventSourceInit,\n fetch: async (url, init) => {\n const headers = await this._commonHeaders();\n headers.set('Accept', 'text/event-stream');\n const response = await fetchImpl(url, {\n ...init,\n headers\n });\n\n if (response.status === 401) {\n this._last401Response = response;\n if (response.headers.has('www-authenticate')) {\n const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n this._resourceMetadataUrl = resourceMetadataUrl;\n this._scope = scope;\n }\n }\n\n return response;\n }\n });\n this._abortController = new AbortController();\n\n this._eventSource.onerror = event => {\n if (event.code === 401 && this._authProvider) {\n if (this._authProvider.onUnauthorized && this._last401Response) {\n const response = this._last401Response;\n this._last401Response = undefined;\n this._eventSource?.close();\n this._authProvider.onUnauthorized({ response, serverUrl: this._url, fetchFn: this._fetchWithInit }).then(\n // onUnauthorized succeeded → retry fresh. Its onerror handles its own onerror?.() + reject.\n () => this._startOrAuth().then(resolve, reject),\n // onUnauthorized failed → not yet reported. Auth-seam\n // stamp: covers the SDK's OAuth flow and custom\n // callbacks alike.\n (error: unknown) => {\n markAuthSeamEscape(error);\n this.onerror?.(error as Error);\n reject(error);\n }\n );\n return;\n }\n const error = markAuthSeamEscape(new UnauthorizedError());\n reject(error);\n this.onerror?.(error);\n return;\n }\n\n const error = new SseError(event.code, event.message, event);\n reject(error);\n this.onerror?.(error);\n };\n\n this._eventSource.onopen = () => {\n // The connection is open, but we need to wait for the endpoint to be received.\n };\n\n this._eventSource.addEventListener('endpoint', (event: Event) => {\n const messageEvent = event as MessageEvent;\n\n try {\n this._endpoint = new URL(messageEvent.data, this._url);\n if (this._endpoint.origin !== this._url.origin) {\n throw new Error(`Endpoint origin does not match connection origin: ${this._endpoint.origin}`);\n }\n } catch (error) {\n reject(error);\n this.onerror?.(error as Error);\n\n void this.close();\n return;\n }\n\n resolve();\n });\n\n this._eventSource.onmessage = (event: Event) => {\n const messageEvent = event as MessageEvent;\n let message: JSONRPCMessage;\n try {\n message = JSONRPCMessageSchema.parse(JSON.parse(messageEvent.data));\n } catch (error) {\n this.onerror?.(error as Error);\n return;\n }\n\n this.onmessage?.(message);\n };\n });\n }\n\n async start() {\n if (this._eventSource) {\n throw new Error('SSEClientTransport already started! If using Client class, note that connect() calls start() automatically.');\n }\n\n return await this._startOrAuth();\n }\n\n /**\n * Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.\n *\n * **Preferred:** pass the callback URL's `searchParams` directly. The SDK extracts `code`\n * and `iss`, validates `iss` against the recorded issuer (RFC 9207) **before** reading any\n * other parameter, and on mismatch throws an {@linkcode IssuerMismatchError} that carries\n * none of the callback's `error`/`error_description`/`error_uri` text. The `(code, iss?)`\n * positional form remains supported for back-compat.\n *\n * The SDK does **not** validate `state`; compare it to your stored value before calling\n * `finishAuth`.\n *\n * @param callbackParams - The `URLSearchParams` from the authorization callback URL\n * (e.g. `new URL(callbackUrl).searchParams`). `code` and `iss` are read from it.\n */\n async finishAuth(callbackParams: URLSearchParams): Promise<void>;\n /**\n * @param authorizationCode - The `code` query parameter from the authorization callback URL.\n * @param iss - The form-urldecoded `iss` query parameter from the same callback URL, if\n * present. Validated per RFC 9207 against the recorded issuer before the code is redeemed.\n */\n async finishAuth(authorizationCode: string, iss?: string): Promise<void>;\n async finishAuth(codeOrParams: string | URLSearchParams, iss?: string): Promise<void> {\n if (!this._oauthProvider) {\n throw new UnauthorizedError('finishAuth requires an OAuthClientProvider');\n }\n\n const { authorizationCode, iss: issParam } = await resolveAuthorizationCallbackParams(\n codeOrParams,\n iss,\n this._oauthProvider,\n this._url,\n { fetchFn: this._fetchWithInit, resourceMetadataUrl: this._resourceMetadataUrl }\n );\n\n const result = await auth(this._oauthProvider, {\n serverUrl: this._url,\n authorizationCode,\n iss: issParam,\n resourceMetadataUrl: this._resourceMetadataUrl,\n scope: this._scope,\n fetchFn: this._fetchWithInit,\n skipIssuerMetadataValidation: this._skipIssuerMetadataValidation\n });\n if (result !== 'AUTHORIZED') {\n throw new UnauthorizedError('Failed to authorize');\n }\n }\n\n async close(): Promise<void> {\n this._abortController?.abort();\n this._eventSource?.close();\n this.onclose?.();\n }\n\n async send(message: JSONRPCMessage): Promise<void> {\n return this._send(message, false);\n }\n\n private async _send(message: JSONRPCMessage, isAuthRetry: boolean): Promise<void> {\n if (!this._endpoint) {\n throw new SdkError(SdkErrorCode.NotConnected, 'Not connected');\n }\n\n try {\n const headers = await this._commonHeaders();\n headers.set('content-type', 'application/json');\n const init = {\n ...this._requestInit,\n method: 'POST',\n headers,\n body: JSON.stringify(message),\n signal: this._abortController?.signal\n };\n\n const response = await (this._fetch ?? fetch)(this._endpoint, init);\n if (!response.ok) {\n if (response.status === 401 && this._authProvider) {\n if (response.headers.has('www-authenticate')) {\n const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n this._resourceMetadataUrl = resourceMetadataUrl;\n this._scope = scope;\n }\n\n if (this._authProvider.onUnauthorized && !isAuthRetry) {\n try {\n await this._authProvider.onUnauthorized({\n response,\n serverUrl: this._url,\n fetchFn: this._fetchWithInit\n });\n } catch (error) {\n // Auth-seam stamp: covers the SDK's OAuth flow and\n // custom onUnauthorized callbacks alike.\n throw markAuthSeamEscape(error);\n }\n await response.text?.().catch(() => {});\n // Purposely _not_ awaited, so we don't call onerror twice\n return this._send(message, true);\n }\n await response.text?.().catch(() => {});\n if (isAuthRetry) {\n throw markAuthSeamEscape(\n new SdkHttpError(SdkErrorCode.ClientHttpAuthentication, 'Server returned 401 after re-authentication', {\n status: 401,\n statusText: response.statusText\n })\n );\n }\n throw markAuthSeamEscape(new UnauthorizedError());\n }\n\n const text = await response.text?.().catch(() => null);\n throw new Error(`Error POSTing to endpoint (HTTP ${response.status}): ${text}`);\n }\n\n // Release connection - POST responses don't have content we need\n await response.text?.().catch(() => {});\n } catch (error) {\n this.onerror?.(error as Error);\n throw error;\n }\n }\n\n setProtocolVersion(version: string): void {\n this._protocolVersion = version;\n }\n}\n","import type { ReadableWritablePair } from 'node:stream/web';\n\nimport type { FetchLike, JSONRPCMessage, Transport } from '@modelcontextprotocol/core-internal';\nimport {\n createFetchWithInit,\n encodeMcpParamValue,\n isInitializedNotification,\n isInitializeRequest,\n isJSONRPCErrorResponse,\n isJSONRPCRequest,\n isJSONRPCResultResponse,\n isModernProtocolVersion,\n JSONRPCMessageSchema,\n mediaTypeEssence,\n normalizeHeaders,\n PROTOCOL_VERSION_META_KEY,\n SdkError,\n SdkErrorCode,\n SdkHttpError\n} from '@modelcontextprotocol/core-internal';\nimport { EventSourceParserStream } from 'eventsource-parser/stream';\n\nimport type { AuthProvider, OAuthClientProvider } from './auth';\nimport {\n adaptOAuthProvider,\n auth,\n computeScopeUnion,\n extractWWWAuthenticateParams,\n isOAuthClientProvider,\n isStrictScopeSuperset,\n resolveAuthorizationCallbackParams,\n UnauthorizedError\n} from './auth';\n// eslint-disable-next-line @typescript-eslint/no-unused-vars -- referenced via {@linkcode} in finishAuth JSDoc\nimport type { IssuerMismatchError } from './authErrors';\nimport { InsufficientScopeError } from './authErrors';\nimport { markAuthSeamEscape } from './authSeam';\n\n/** Default cap on step-up re-authorization retries within a single send/stream-open. */\nconst DEFAULT_MAX_STEP_UP_RETRIES = 1;\n\n/** The parsed 403 `insufficient_scope` challenge handed to the step-up flow. */\ntype StepUpChallenge = { scope?: string; resourceMetadataUrl?: URL; errorDescription?: string; statusText?: string; text?: string | null };\n\n// Default reconnection options for StreamableHTTP connections\nconst DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS: StreamableHTTPReconnectionOptions = {\n initialReconnectionDelay: 1000,\n maxReconnectionDelay: 30_000,\n reconnectionDelayGrowFactor: 1.5,\n maxRetries: 2\n};\n\n/**\n * Options for starting or authenticating an SSE connection\n */\nexport interface StartSSEOptions {\n /**\n * The resumption token used to continue long-running requests that were interrupted.\n *\n * This allows clients to reconnect and continue from where they left off.\n */\n resumptionToken?: string;\n\n /**\n * A callback that is invoked when the resumption token changes.\n *\n * This allows clients to persist the latest token for potential reconnection.\n */\n onresumptiontoken?: (token: string) => void;\n\n /**\n * Override Message ID to associate with the replay message\n * so that the response can be associated with the new resumed request.\n */\n replayMessageId?: string | number;\n\n /**\n * The per-request abort signal supplied by the caller via\n * `TransportSendOptions.requestSignal`. When this signal is aborted the\n * originating POST and its SSE response stream are torn down\n * intentionally — `_handleSseStream` treats it exactly like the\n * transport-level abort: no `onerror`, no reconnect.\n */\n requestSignal?: AbortSignal;\n\n /**\n * The per-request stream-end callback supplied via\n * `TransportSendOptions.onRequestStreamEnd`. Fired when the SSE response\n * stream for the originating POST ends or errors for any non-deliberate\n * reason (server closed, network dropped, reconnection exhausted) — never\n * when `requestSignal` was aborted.\n */\n onRequestStreamEnd?: () => void;\n}\n\n/**\n * Configuration options for reconnection behavior of the {@linkcode StreamableHTTPClientTransport}.\n */\nexport interface StreamableHTTPReconnectionOptions {\n /**\n * Maximum backoff time between reconnection attempts in milliseconds.\n * Default is 30000 (30 seconds).\n */\n maxReconnectionDelay: number;\n\n /**\n * Initial backoff time between reconnection attempts in milliseconds.\n * Default is 1000 (1 second).\n */\n initialReconnectionDelay: number;\n\n /**\n * The factor by which the reconnection delay increases after each attempt.\n * Default is 1.5.\n */\n reconnectionDelayGrowFactor: number;\n\n /**\n * Maximum number of reconnection attempts before giving up.\n * Default is 2.\n */\n maxRetries: number;\n}\n\n/**\n * Custom scheduler for SSE stream reconnection attempts.\n *\n * Called instead of `setTimeout` when the transport needs to schedule a reconnection.\n * Useful in environments where `setTimeout` is unsuitable (serverless functions that\n * terminate before the timer fires, mobile apps that need platform background scheduling,\n * desktop apps handling sleep/wake).\n *\n * @param reconnect - Call this to perform the reconnection attempt.\n * @param delay - Suggested delay in milliseconds (from backoff calculation).\n * @param attemptCount - Zero-indexed retry attempt number.\n * @returns An optional cancel function. If returned, it will be called on\n * {@linkcode StreamableHTTPClientTransport.close | transport.close()} to abort the\n * pending reconnection.\n *\n * @example\n * ```ts source=\"./streamableHttp.examples.ts#ReconnectionScheduler_basicUsage\"\n * const scheduler: ReconnectionScheduler = (reconnect, delay) => {\n * const id = platformBackgroundTask.schedule(reconnect, delay);\n * return () => platformBackgroundTask.cancel(id);\n * };\n * ```\n */\nexport type ReconnectionScheduler = (reconnect: () => void, delay: number, attemptCount: number) => (() => void) | void;\n\n/**\n * Configuration options for the {@linkcode StreamableHTTPClientTransport}.\n */\nexport type StreamableHTTPClientTransportOptions = {\n /**\n * An OAuth client provider to use for authentication.\n *\n * {@linkcode AuthProvider.token | token()} is called before every request to obtain the\n * bearer token. When the server responds with 401, {@linkcode AuthProvider.onUnauthorized | onUnauthorized()}\n * is called (if provided) to refresh credentials, then the request is retried once. If\n * the retry also gets 401, or `onUnauthorized` is not provided, {@linkcode UnauthorizedError}\n * is thrown.\n *\n * For simple bearer tokens: `{ token: async () => myApiKey }`.\n *\n * For OAuth flows, pass an {@linkcode index.OAuthClientProvider | OAuthClientProvider} implementation\n * directly — the transport adapts it to `AuthProvider` internally. Interactive flows: after\n * {@linkcode UnauthorizedError}, redirect the user, then call\n * {@linkcode StreamableHTTPClientTransport.finishAuth | finishAuth} with the authorization code before\n * reconnecting.\n */\n authProvider?: AuthProvider | OAuthClientProvider;\n\n /**\n * Opt-out for the RFC 8414 §3.3 issuer-echo check during authorization-server\n * metadata discovery. **Security-weakening** — see\n * {@linkcode index.AuthOptions.skipIssuerMetadataValidation | AuthOptions.skipIssuerMetadataValidation}.\n * Only honoured when {@linkcode StreamableHTTPClientTransportOptions.authProvider | authProvider}\n * is an `OAuthClientProvider`.\n */\n skipIssuerMetadataValidation?: boolean;\n\n /**\n * Customizes HTTP requests to the server.\n */\n requestInit?: RequestInit;\n\n /**\n * Custom fetch implementation used for all network requests.\n */\n fetch?: FetchLike;\n\n /**\n * Options to configure the reconnection behavior.\n */\n reconnectionOptions?: StreamableHTTPReconnectionOptions;\n\n /**\n * Custom scheduler for reconnection attempts. If not provided, `setTimeout` is used.\n * See {@linkcode ReconnectionScheduler}.\n */\n reconnectionScheduler?: ReconnectionScheduler;\n\n /**\n * Session ID for the connection. This is used to identify the session on the server.\n * When not provided and connecting to a server that supports session IDs, the server will generate a new session ID.\n */\n sessionId?: string;\n\n /**\n * The MCP protocol version to include in the `mcp-protocol-version` header on all requests.\n * When reconnecting with a preserved `sessionId`, set this to the version negotiated during the original\n * handshake so the reconnected transport continues sending the required header.\n */\n protocolVersion?: string;\n\n /**\n * How the transport reacts to a `403 Forbidden` response carrying\n * `WWW-Authenticate: Bearer error=\"insufficient_scope\"`.\n *\n * - `'reauthorize'` (default): the transport runs the step-up authorization\n * flow — computes the union of the previously-requested scope and the\n * challenged scope, calls {@linkcode index.auth | auth()} (forcing a\n * fresh authorization request when the union strictly exceeds the current\n * token's granted scope, since refresh cannot widen scope per RFC 6749\n * §6), and retries the request once. Retries are bounded by\n * {@linkcode StreamableHTTPClientTransportOptions.maxStepUpRetries | maxStepUpRetries}.\n * If no {@linkcode index.OAuthClientProvider | OAuthClientProvider} is\n * configured, step-up cannot run and the transport throws\n * {@linkcode index.InsufficientScopeError | InsufficientScopeError} instead.\n * - `'throw'`: the transport throws {@linkcode index.InsufficientScopeError | InsufficientScopeError}\n * carrying the challenge parameters and does not re-authorize. Use this\n * for `client_credentials` / m2m clients where re-authorization cannot\n * widen scope, or for interactive clients that want to gate the consent\n * prompt behind UX.\n *\n * @default 'reauthorize'\n */\n onInsufficientScope?: 'reauthorize' | 'throw';\n\n /**\n * Maximum number of step-up re-authorization attempts the transport makes\n * per send (and per GET stream open) before giving up. Only consulted when\n * {@linkcode StreamableHTTPClientTransportOptions.onInsufficientScope | onInsufficientScope}\n * is `'reauthorize'`. Cross-request tracking (\"this resource+operation\n * already failed N times across the session\") is host responsibility.\n *\n * @default 1\n */\n maxStepUpRetries?: number;\n};\n\n/**\n * Standard/auth header names the transport owns. The per-request\n * `TransportSendOptions.headers` carrier MUST NOT be able to override these —\n * they are derived from connection state (`authorization`, `mcp-session-id`)\n * or from the message body itself (`mcp-protocol-version`, `mcp-method`,\n * `mcp-name`), and a per-request override would let a caller produce a\n * header/body disagreement the server's SEP-2243 cross-checks reject.\n */\nconst RESERVED_REQUEST_HEADER_NAMES: ReadonlySet<string> = new Set([\n 'authorization',\n 'content-type',\n 'mcp-protocol-version',\n 'mcp-method',\n 'mcp-name',\n 'mcp-session-id'\n]);\n\n/**\n * `AbortSignal.any` with a manual fallback. `AbortSignal.any` landed in\n * Node 20.3; this package's `engines` floor is `>=20`, so 20.0–20.2 must be\n * served by the fallback combinator (a controller that aborts on the first\n * of `a` or `b`). The native path is preferred because it propagates the\n * originating signal's `reason` and participates in GC the way the spec\n * defines.\n */\nfunction anySignal(a: AbortSignal, b: AbortSignal): AbortSignal {\n if (typeof AbortSignal.any === 'function') {\n return AbortSignal.any([a, b]);\n }\n const controller = new AbortController();\n if (a.aborted) return (controller.abort(a.reason), controller.signal);\n if (b.aborted) return (controller.abort(b.reason), controller.signal);\n // Standard polyfill shape: when EITHER input fires, remove the listener\n // registered on the OTHER input too. `{once:true}` alone leaks the\n // sibling listener — for `_send()`, `a` is the transport-lifetime signal,\n // so every request-scoped `b` that aborts would otherwise leave one\n // listener + closure pinned on `a` for the life of the transport.\n const cleanup = (): void => {\n a.removeEventListener('abort', onA);\n b.removeEventListener('abort', onB);\n };\n function onA(): void {\n cleanup();\n controller.abort(a.reason);\n }\n function onB(): void {\n cleanup();\n controller.abort(b.reason);\n }\n a.addEventListener('abort', onA, { once: true });\n b.addEventListener('abort', onB, { once: true });\n return controller.signal;\n}\n\n/**\n * Client transport for Streamable HTTP: this implements the MCP Streamable HTTP transport specification.\n * It will connect to a server using HTTP `POST` for sending messages and HTTP `GET` with Server-Sent Events\n * for receiving messages.\n */\nexport class StreamableHTTPClientTransport implements Transport {\n private _abortController?: AbortController;\n private _url: URL;\n private _resourceMetadataUrl?: URL;\n private _scope?: string;\n private _requestInit?: RequestInit;\n private _authProvider?: AuthProvider;\n private _oauthProvider?: OAuthClientProvider;\n private _skipIssuerMetadataValidation?: boolean;\n private _fetch?: FetchLike;\n private _fetchWithInit: FetchLike;\n private _sessionId?: string;\n private _reconnectionOptions: StreamableHTTPReconnectionOptions;\n private _protocolVersion?: string;\n private _onInsufficientScope: 'reauthorize' | 'throw';\n private _maxStepUpRetries: number;\n private _serverRetryMs?: number; // Server-provided retry delay from SSE retry field\n private readonly _reconnectionScheduler?: ReconnectionScheduler;\n private _cancelReconnection?: () => void;\n\n onclose?: () => void;\n onerror?: (error: Error) => void;\n onmessage?: (message: JSONRPCMessage) => void;\n\n /**\n * Streamable HTTP opens one POST (and SSE response stream) per outbound\n * request and honors `TransportSendOptions.requestSignal`. On a 2026-era\n * connection the protocol layer aborts that per-request stream as the\n * spec cancellation signal instead of POSTing `notifications/cancelled`.\n */\n readonly hasPerRequestStream = true;\n\n constructor(url: URL, opts?: StreamableHTTPClientTransportOptions) {\n this._url = url;\n this._resourceMetadataUrl = undefined;\n this._scope = undefined;\n this._requestInit = opts?.requestInit;\n this._skipIssuerMetadataValidation = opts?.skipIssuerMetadataValidation;\n if (isOAuthClientProvider(opts?.authProvider)) {\n this._oauthProvider = opts.authProvider;\n this._authProvider = adaptOAuthProvider(opts.authProvider, {\n skipIssuerMetadataValidation: opts.skipIssuerMetadataValidation\n });\n } else {\n this._authProvider = opts?.authProvider;\n }\n this._fetch = opts?.fetch;\n this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit);\n this._sessionId = opts?.sessionId;\n this._protocolVersion = opts?.protocolVersion;\n this._reconnectionOptions = opts?.reconnectionOptions ?? DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;\n this._reconnectionScheduler = opts?.reconnectionScheduler;\n this._onInsufficientScope = opts?.onInsufficientScope ?? 'reauthorize';\n this._maxStepUpRetries = Math.max(0, opts?.maxStepUpRetries ?? DEFAULT_MAX_STEP_UP_RETRIES);\n }\n\n /**\n * SEP-2350 step-up: compute the union scope, decide whether refresh must be\n * bypassed, and run {@linkcode auth}. Returns the auth result so the caller\n * can decide whether to retry. Shared by the POST `_send` path and the GET\n * `_startOrAuthSse` path so both apply the same `'throw'` short-circuit,\n * the same superset-gated refresh bypass, and the same retry cap.\n */\n private async _stepUpAuthorize(challenge: StepUpChallenge, stepUpRetries: number): Promise<'AUTHORIZED' | 'REDIRECT'> {\n // Auth-seam stamp, method-level: covers the InsufficientScopeError\n // throws, the retry-limit SdkHttpError, the tokens() read, and every\n // auth() escape (typed or not).\n try {\n return await this._stepUpAuthorizeInner(challenge, stepUpRetries);\n } catch (error) {\n throw markAuthSeamEscape(error);\n }\n }\n\n private async _stepUpAuthorizeInner(challenge: StepUpChallenge, stepUpRetries: number): Promise<'AUTHORIZED' | 'REDIRECT'> {\n if (this._onInsufficientScope === 'throw') {\n throw new InsufficientScopeError({\n requiredScope: challenge.scope,\n resourceMetadataUrl: challenge.resourceMetadataUrl,\n errorDescription: challenge.errorDescription\n });\n }\n if (!this._oauthProvider) {\n // No OAuth provider to drive step-up; surface the typed error so the\n // host can act on it.\n throw new InsufficientScopeError({\n requiredScope: challenge.scope,\n resourceMetadataUrl: challenge.resourceMetadataUrl,\n errorDescription: challenge.errorDescription\n });\n }\n if (stepUpRetries >= this._maxStepUpRetries) {\n throw new SdkHttpError(\n SdkErrorCode.ClientHttpForbidden,\n `Server returned 403 insufficient_scope after step-up re-authorization (retry limit ${this._maxStepUpRetries} reached)`,\n { status: 403, statusText: challenge.statusText ?? 'Forbidden', text: challenge.text }\n );\n }\n\n if (challenge.resourceMetadataUrl) {\n this._resourceMetadataUrl = challenge.resourceMetadataUrl;\n }\n\n // Spec step-up: union of previously-requested scope and challenged scope,\n // so previously-granted permissions are not lost on re-authorization.\n const tokens = await this._oauthProvider.tokens();\n const unionScope = computeScopeUnion(this._scope, tokens?.scope, challenge.scope);\n this._scope = unionScope;\n\n // Superset-gated refresh bypass: refresh cannot widen scope (RFC 6749 §6),\n // so when the union strictly exceeds what the current token was granted\n // we must force a fresh authorization request.\n const forceReauthorization = isStrictScopeSuperset(unionScope, tokens?.scope);\n\n return auth(this._oauthProvider, {\n serverUrl: this._url,\n resourceMetadataUrl: this._resourceMetadataUrl,\n scope: unionScope,\n forceReauthorization,\n fetchFn: this._fetchWithInit,\n skipIssuerMetadataValidation: this._skipIssuerMetadataValidation\n });\n }\n\n private async _commonHeaders(): Promise<Headers> {\n const headers: RequestInit['headers'] & Record<string, string> = {};\n let token: string | undefined;\n try {\n token = await this._authProvider?.token();\n } catch (error) {\n // Auth-seam stamp: a throwing token() is an auth failure, never a\n // network failure.\n throw markAuthSeamEscape(error);\n }\n if (token) {\n headers['Authorization'] = `Bearer ${token}`;\n }\n\n if (this._sessionId) {\n headers['mcp-session-id'] = this._sessionId;\n }\n if (this._protocolVersion) {\n headers['mcp-protocol-version'] = this._protocolVersion;\n }\n\n const extraHeaders = normalizeHeaders(this._requestInit?.headers);\n\n return new Headers({\n ...headers,\n ...extraHeaders\n });\n }\n\n /**\n * Body-derived per-request headers: when an outgoing request carries a\n * protocol-version claim in its `_meta` envelope (the version negotiation\n * probe is the first such sender), `MCP-Protocol-Version` and `Mcp-Method`\n * derive from the message itself. The connection-level version slot is\n * neither consulted nor mutated; messages without an envelope claim are\n * untouched, so no 2026 header can appear on a legacy exchange.\n */\n private _applyBodyDerivedHeaders(headers: Headers, message: JSONRPCMessage | JSONRPCMessage[]): void {\n if (Array.isArray(message) || !isJSONRPCRequest(message)) {\n return;\n }\n const meta = (message.params as { _meta?: Record<string, unknown> } | undefined)?._meta;\n const envelopeVersion = meta?.[PROTOCOL_VERSION_META_KEY];\n if (typeof envelopeVersion !== 'string') {\n return;\n }\n headers.set('mcp-protocol-version', envelopeVersion);\n headers.set('mcp-method', message.method);\n // SEP-2243 standard headers, step 2 of the 5-step client algorithm:\n // Mcp-Name mirrors `params.name` (tools/call, prompts/get) or\n // `params.uri` (resources/read). The value is run through the same\n // `=?base64?…?=` sentinel encoding the `Mcp-Param-*` codec uses so a\n // non-ASCII name/URI (or one with leading/trailing whitespace,\n // control characters, or CR/LF) cannot make `Headers.set()` throw a\n // TypeError or silently normalize to a value that differs from the\n // body. The spec's value-encoding rules apply to `Mcp-Name`; the SDK\n // server's `validateStandardRequestHeaders` decodes the sentinel via\n // `decodeMcpParamValue` before the `Mcp-Name` ↔ body cross-check.\n const params = message.params as { name?: unknown; uri?: unknown } | undefined;\n const nameHeader =\n message.method === 'resources/read'\n ? typeof params?.uri === 'string'\n ? params.uri\n : undefined\n : typeof params?.name === 'string'\n ? params.name\n : undefined;\n if (nameHeader !== undefined) {\n headers.set('mcp-name', encodeMcpParamValue(nameHeader));\n }\n }\n\n /**\n * `true` when the outbound message is a single request carrying a\n * modern-era protocol-version envelope claim — the same predicate that\n * gates body-derived `mcp-method`/`mcp-name` emission. Used to confine the\n * 400-body-as-ProtocolError delivery to modern-era exchanges only.\n */\n private _isModernEnvelopedRequest(message: JSONRPCMessage | JSONRPCMessage[]): boolean {\n if (Array.isArray(message) || !isJSONRPCRequest(message)) return false;\n const meta = (message.params as { _meta?: Record<string, unknown> } | undefined)?._meta;\n const v = meta?.[PROTOCOL_VERSION_META_KEY];\n return typeof v === 'string' && isModernProtocolVersion(v);\n }\n\n private async _startOrAuthSse(options: StartSSEOptions, isAuthRetry = false, stepUpRetries = 0): Promise<void> {\n const { resumptionToken, requestSignal } = options;\n // Same guard as `_handleSseStream`: a resurrected listen stream (the\n // POST-SSE → GET reconnect path threads `requestSignal` through\n // `StartSSEOptions`) must honour the per-request abort exactly as the\n // original POST did — both as a fetch signal and as a \"do not surface\n // onerror\" gate.\n const isIntentionalAbort = (): boolean => this._abortController?.signal.aborted === true || requestSignal?.aborted === true;\n\n try {\n // Try to open an initial SSE stream with GET to listen for server messages\n // This is optional according to the spec - server may not support it\n const headers = await this._commonHeaders();\n const userAccept = headers.get('accept');\n const types = [...(userAccept?.split(',').map(s => s.trim().toLowerCase()) ?? []), 'text/event-stream'];\n headers.set('accept', [...new Set(types)].join(', '));\n\n // Include Last-Event-ID header for resumable streams if provided\n if (resumptionToken) {\n headers.set('last-event-id', resumptionToken);\n }\n\n const transportSignal = this._abortController?.signal;\n const signal =\n requestSignal !== undefined && transportSignal !== undefined\n ? anySignal(transportSignal, requestSignal)\n : (requestSignal ?? transportSignal);\n const response = await (this._fetch ?? fetch)(this._url, {\n ...this._requestInit,\n method: 'GET',\n headers,\n signal\n });\n\n if (!response.ok) {\n if (response.status === 401 && this._authProvider) {\n if (response.headers.has('www-authenticate')) {\n const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n this._resourceMetadataUrl = resourceMetadataUrl;\n // Preserve any union accumulated by `_stepUpAuthorize` so a 401\n // mid-chain does not narrow `_scope` back to the challenge value.\n this._scope = computeScopeUnion(this._scope, scope);\n }\n\n if (this._authProvider.onUnauthorized && !isAuthRetry) {\n try {\n await this._authProvider.onUnauthorized({\n response,\n serverUrl: this._url,\n fetchFn: this._fetchWithInit\n });\n } catch (error) {\n // Auth-seam stamp: covers the SDK's OAuth flow and\n // custom onUnauthorized callbacks alike.\n throw markAuthSeamEscape(error);\n }\n await response.text?.().catch(() => {});\n // Purposely _not_ awaited, so we don't call onerror twice\n return this._startOrAuthSse(options, true, stepUpRetries);\n }\n await response.text?.().catch(() => {});\n if (isAuthRetry) {\n throw markAuthSeamEscape(\n new SdkHttpError(SdkErrorCode.ClientHttpAuthentication, 'Server returned 401 after re-authentication', {\n status: 401,\n statusText: response.statusText\n })\n );\n }\n throw markAuthSeamEscape(new UnauthorizedError());\n }\n\n if (response.status === 403) {\n const { resourceMetadataUrl, scope, error, errorDescription } = extractWWWAuthenticateParams(response);\n if (error === 'insufficient_scope') {\n const text = await response.text?.().catch(() => null);\n const result = await this._stepUpAuthorize(\n { scope, resourceMetadataUrl, errorDescription, statusText: response.statusText, text },\n stepUpRetries\n );\n if (result !== 'AUTHORIZED') {\n throw markAuthSeamEscape(new UnauthorizedError());\n }\n return this._startOrAuthSse(options, isAuthRetry, stepUpRetries + 1);\n }\n }\n\n await response.text?.().catch(() => {});\n\n // 405 indicates that the server does not offer an SSE stream at GET endpoint\n // This is an expected case that should not trigger an error\n if (response.status === 405) {\n // A 405 on the standalone-GET path is benign (the caller\n // never had a per-request stream). On the POST→GET resume\n // path it is a TERMINAL non-resumable outcome for a\n // per-request stream the caller is observing — fire the\n // stream-end callback so the caller can settle (otherwise\n // a resumed listen subscription dead-ends silently). The\n // standalone-GET callers never pass `onRequestStreamEnd`,\n // so this is a no-op for them.\n options.onRequestStreamEnd?.();\n return;\n }\n\n throw new SdkHttpError(SdkErrorCode.ClientHttpFailedToOpenStream, `Failed to open SSE stream: ${response.statusText}`, {\n status: response.status,\n statusText: response.statusText\n });\n }\n\n this._handleSseStream(response.body, options, true);\n } catch (error) {\n if (!isIntentionalAbort()) {\n this.onerror?.(error as Error);\n }\n throw error;\n }\n }\n\n /**\n * Calculates the next reconnection delay using a backoff algorithm\n *\n * @param attempt Current reconnection attempt count for the specific stream\n * @returns Time to wait in milliseconds before next reconnection attempt\n */\n private _getNextReconnectionDelay(attempt: number): number {\n // Use server-provided retry value if available\n if (this._serverRetryMs !== undefined) {\n return this._serverRetryMs;\n }\n\n // Fall back to exponential backoff\n const initialDelay = this._reconnectionOptions.initialReconnectionDelay;\n const growFactor = this._reconnectionOptions.reconnectionDelayGrowFactor;\n const maxDelay = this._reconnectionOptions.maxReconnectionDelay;\n\n // Cap at maximum delay\n return Math.min(initialDelay * Math.pow(growFactor, attempt), maxDelay);\n }\n\n /**\n * Schedule a reconnection attempt using server-provided retry interval or backoff\n *\n * @param lastEventId The ID of the last received event for resumability\n * @param attemptCount Current reconnection attempt count for this specific stream\n */\n private _scheduleReconnection(options: StartSSEOptions, attemptCount = 0): void {\n // Use provided options or default options\n const maxRetries = this._reconnectionOptions.maxRetries;\n\n // Check if we've exceeded maximum retry attempts\n if (attemptCount >= maxRetries) {\n this.onerror?.(new Error(`Maximum reconnection attempts (${maxRetries}) exceeded.`));\n // The per-request stream is now definitively gone.\n options.onRequestStreamEnd?.();\n return;\n }\n\n // Calculate next delay based on current attempt count\n const delay = this._getNextReconnectionDelay(attemptCount);\n\n const reconnect = (): void => {\n this._cancelReconnection = undefined;\n // Honour BOTH the transport-wide abort and the per-request abort\n // (a listen subscription closed during the backoff delay): do not\n // resurrect a stream the caller already tore down.\n if (this._abortController?.signal.aborted || options.requestSignal?.aborted) return;\n this._startOrAuthSse(options).catch(error => {\n if (this._abortController?.signal.aborted || options.requestSignal?.aborted) return;\n this.onerror?.(new Error(`Failed to reconnect SSE stream: ${error instanceof Error ? error.message : String(error)}`));\n try {\n this._scheduleReconnection(options, attemptCount + 1);\n } catch (scheduleError) {\n this.onerror?.(scheduleError instanceof Error ? scheduleError : new Error(String(scheduleError)));\n }\n });\n };\n\n if (this._reconnectionScheduler) {\n const cancel = this._reconnectionScheduler(reconnect, delay, attemptCount);\n this._cancelReconnection = typeof cancel === 'function' ? cancel : undefined;\n } else {\n const handle = setTimeout(reconnect, delay);\n this._cancelReconnection = () => clearTimeout(handle);\n }\n }\n\n private _handleSseStream(stream: ReadableStream<Uint8Array> | null, options: StartSSEOptions, isReconnectable: boolean): void {\n if (!stream) {\n // A null body on a per-request stream (or its GET resume) is the\n // same terminal non-resumable outcome as a 405 — fire the\n // stream-end callback so the caller can settle. No-op for\n // standalone-GET callers (they never pass `onRequestStreamEnd`).\n options.onRequestStreamEnd?.();\n return;\n }\n const { onresumptiontoken, replayMessageId, requestSignal, onRequestStreamEnd } = options;\n // An intentional abort — transport-wide close OR a per-request abort\n // (McpSubscription.close() aborting its `requestSignal`) — must read as\n // a clean shutdown: no misleading \"SSE stream disconnected\" onerror,\n // and no GET+Last-Event-ID reconnect that would resurrect a stream the\n // caller just tore down.\n const isIntentionalAbort = (): boolean => this._abortController?.signal.aborted === true || requestSignal?.aborted === true;\n\n let lastEventId: string | undefined;\n // Track whether we've received a priming event (event with ID)\n // Per spec, server SHOULD send a priming event with ID before closing\n let hasPrimingEvent = false;\n // Track whether we've received a response - if so, no need to reconnect\n // Reconnection is for when server disconnects BEFORE sending response\n let receivedResponse = false;\n const processStream = async () => {\n // this is the closest we can get to trying to catch network errors\n // if something happens reader will throw\n try {\n // Create a pipeline: binary stream -> text decoder -> SSE parser\n const reader = stream\n .pipeThrough(new TextDecoderStream() as ReadableWritablePair<string, Uint8Array>)\n .pipeThrough(\n new EventSourceParserStream({\n onRetry: (retryMs: number) => {\n // Capture server-provided retry value for reconnection timing\n this._serverRetryMs = retryMs;\n }\n })\n )\n .getReader();\n\n while (true) {\n const { value: event, done } = await reader.read();\n if (done) {\n break;\n }\n\n // Update last event ID if provided\n if (event.id) {\n lastEventId = event.id;\n // Mark that we've received a priming event - stream is now resumable\n hasPrimingEvent = true;\n onresumptiontoken?.(event.id);\n }\n\n // Skip events with no data (priming events, keep-alives)\n if (!event.data) {\n continue;\n }\n\n if (!event.event || event.event === 'message') {\n try {\n const message = JSONRPCMessageSchema.parse(JSON.parse(event.data));\n // Handle both success AND error responses for completion detection and ID remapping\n if (isJSONRPCResultResponse(message) || isJSONRPCErrorResponse(message)) {\n // Mark that we received a response - no need to reconnect for this request\n receivedResponse = true;\n if (replayMessageId !== undefined) {\n message.id = replayMessageId;\n }\n }\n this.onmessage?.(message);\n } catch (error) {\n this.onerror?.(error as Error);\n }\n }\n }\n\n // Handle graceful server-side disconnect\n // Server may close connection after sending event ID and retry field\n // Reconnect if: already reconnectable (GET stream) OR received a priming event (POST stream with event ID)\n // BUT don't reconnect if we already received a response - the request is complete\n const canResume = isReconnectable || hasPrimingEvent;\n const needsReconnect = canResume && !receivedResponse;\n if (needsReconnect && this._abortController && !isIntentionalAbort()) {\n this._scheduleReconnection(\n {\n resumptionToken: lastEventId,\n onresumptiontoken,\n replayMessageId,\n requestSignal,\n onRequestStreamEnd\n },\n 0\n );\n } else if (!isIntentionalAbort()) {\n // The per-request stream ended without reconnecting (no\n // priming event for a POST stream, or response already\n // received). Not a deliberate abort — notify the caller.\n onRequestStreamEnd?.();\n }\n } catch (error) {\n if (isIntentionalAbort()) {\n // The reader threw because we aborted it. Not an error; do\n // not surface onerror, do not reconnect.\n return;\n }\n // Handle stream errors - likely a network disconnect\n this.onerror?.(new Error(`SSE stream disconnected: ${error}`));\n\n // Attempt to reconnect if the stream disconnects unexpectedly and we aren't closing\n // Reconnect if: already reconnectable (GET stream) OR received a priming event (POST stream with event ID)\n // BUT don't reconnect if we already received a response - the request is complete\n const canResume = isReconnectable || hasPrimingEvent;\n const needsReconnect = canResume && !receivedResponse;\n if (needsReconnect && this._abortController && !isIntentionalAbort()) {\n // Use the exponential backoff reconnection strategy\n try {\n this._scheduleReconnection(\n {\n resumptionToken: lastEventId,\n onresumptiontoken,\n replayMessageId,\n requestSignal,\n onRequestStreamEnd\n },\n 0\n );\n } catch (error) {\n this.onerror?.(new Error(`Failed to reconnect: ${error instanceof Error ? error.message : String(error)}`));\n onRequestStreamEnd?.();\n }\n } else {\n // Non-deliberate stream error without reconnection: the\n // per-request stream is gone — notify the caller.\n onRequestStreamEnd?.();\n }\n }\n };\n processStream();\n }\n\n async start() {\n if (this._abortController) {\n throw new Error(\n 'StreamableHTTPClientTransport already started! If using Client class, note that connect() calls start() automatically.'\n );\n }\n\n this._abortController = new AbortController();\n }\n\n /**\n * Call this method after the user has finished authorizing via their user agent and is redirected back to the MCP client application. This will exchange the authorization code for an access token, enabling the next connection attempt to successfully auth.\n *\n * **Preferred:** pass the callback URL's `searchParams` directly. The SDK extracts `code`\n * and `iss`, validates `iss` against the recorded issuer (RFC 9207) **before** reading any\n * other parameter, and on mismatch throws an {@linkcode IssuerMismatchError} that carries\n * none of the callback's `error`/`error_description`/`error_uri` text — those are\n * attacker-controlled in a mix-up attack and MUST NOT be displayed. The `(code, iss?)`\n * positional form remains supported for back-compat.\n *\n * The SDK does **not** validate `state`; compare it to your stored value before calling\n * `finishAuth`.\n *\n * @param callbackParams - The `URLSearchParams` from the authorization callback URL\n * (e.g. `new URL(callbackUrl).searchParams`). `code` and `iss` are read from it.\n */\n async finishAuth(callbackParams: URLSearchParams): Promise<void>;\n /**\n * @param authorizationCode - The `code` query parameter from the authorization callback URL.\n * @param iss - The form-urldecoded `iss` query parameter from the same callback URL, if\n * present. Validated per RFC 9207 against the recorded issuer before the code is redeemed.\n * When the authorization server advertises `authorization_response_iss_parameter_supported: true`,\n * omitting this causes the exchange to be **rejected** with {@linkcode IssuerMismatchError}.\n */\n async finishAuth(authorizationCode: string, iss?: string): Promise<void>;\n async finishAuth(codeOrParams: string | URLSearchParams, iss?: string): Promise<void> {\n if (!this._oauthProvider) {\n throw new UnauthorizedError('finishAuth requires an OAuthClientProvider');\n }\n\n const { authorizationCode, iss: issParam } = await resolveAuthorizationCallbackParams(\n codeOrParams,\n iss,\n this._oauthProvider,\n this._url,\n { fetchFn: this._fetchWithInit, resourceMetadataUrl: this._resourceMetadataUrl }\n );\n\n const result = await auth(this._oauthProvider, {\n serverUrl: this._url,\n authorizationCode,\n iss: issParam,\n resourceMetadataUrl: this._resourceMetadataUrl,\n scope: this._scope,\n fetchFn: this._fetchWithInit,\n skipIssuerMetadataValidation: this._skipIssuerMetadataValidation\n });\n if (result !== 'AUTHORIZED') {\n throw new UnauthorizedError('Failed to authorize');\n }\n }\n\n async close(): Promise<void> {\n try {\n this._cancelReconnection?.();\n } finally {\n this._cancelReconnection = undefined;\n this._abortController?.abort();\n this.onclose?.();\n }\n }\n\n async send(\n message: JSONRPCMessage | JSONRPCMessage[],\n options?: {\n resumptionToken?: string;\n onresumptiontoken?: (token: string) => void;\n requestSignal?: AbortSignal;\n onRequestStreamEnd?: () => void;\n headers?: Readonly<Record<string, string>>;\n }\n ): Promise<void> {\n return this._send(message, options, false);\n }\n\n private async _send(\n message: JSONRPCMessage | JSONRPCMessage[],\n options:\n | {\n resumptionToken?: string;\n onresumptiontoken?: (token: string) => void;\n requestSignal?: AbortSignal;\n onRequestStreamEnd?: () => void;\n headers?: Readonly<Record<string, string>>;\n }\n | undefined,\n isAuthRetry: boolean,\n stepUpRetries = 0\n ): Promise<void> {\n try {\n const { resumptionToken, onresumptiontoken } = options || {};\n\n if (resumptionToken) {\n // If we have a last event ID, we need to reconnect the SSE stream.\n // Thread `requestSignal` through so the resumed GET honours the\n // same per-request abort as the original POST — modern-era\n // cancel-via-stream-close routes through `requestSignal`, and\n // without it a resumed long-running request would not cancel.\n this._startOrAuthSse({\n resumptionToken,\n replayMessageId: isJSONRPCRequest(message) ? message.id : undefined,\n requestSignal: options?.requestSignal\n }).catch(error => this.onerror?.(error));\n return;\n }\n\n const headers = await this._commonHeaders();\n this._applyBodyDerivedHeaders(headers, message);\n // A new session starts \"without a session ID attached\" (2025-11-25 transports §Session Management).\n const isHandshake = Array.isArray(message) ? message.some(m => isInitializeRequest(m)) : isInitializeRequest(message);\n if (isHandshake) {\n headers.delete('mcp-session-id');\n }\n // Per-request additional headers (the Client passes SEP-2243\n // `Mcp-Param-*` here on a 2026-07-28 connection). Reserved\n // standard/auth header names are skipped so a caller cannot\n // accidentally override the body-derived or connection-level\n // headers — `Headers.set` overwrites, so the only way to keep the\n // transport-owned values authoritative is to refuse to write over\n // them here.\n if (options?.headers !== undefined) {\n for (const [name, value] of Object.entries(options.headers)) {\n if (RESERVED_REQUEST_HEADER_NAMES.has(name.toLowerCase())) continue;\n headers.set(name, value);\n }\n }\n headers.set('content-type', 'application/json');\n const userAccept = headers.get('accept');\n const types = [...(userAccept?.split(',').map(s => s.trim().toLowerCase()) ?? []), 'application/json', 'text/event-stream'];\n headers.set('accept', [...new Set(types)].join(', '));\n\n // Per-request abort: when the caller supplies a request-scoped\n // signal (the `subscriptions/listen` driver), aborting it cancels\n // this POST and its SSE response stream without closing the\n // transport.\n const transportSignal = this._abortController?.signal;\n const signal =\n options?.requestSignal !== undefined && transportSignal !== undefined\n ? anySignal(transportSignal, options.requestSignal)\n : (options?.requestSignal ?? transportSignal);\n const init = {\n ...this._requestInit,\n method: 'POST',\n headers,\n body: JSON.stringify(message),\n signal\n };\n\n const response = await (this._fetch ?? fetch)(this._url, init);\n\n // The spec assigns the session id \"at initialization time … on the HTTP response containing the InitializeResult\"; it is ignored everywhere else.\n // Clients include only an id \"returned by the server during initialization\", so a sessionless handshake clears any stale id.\n if (isHandshake && response.ok) {\n this._sessionId = response.headers.get('mcp-session-id') || undefined;\n }\n\n if (!response.ok) {\n if (response.status === 401 && this._authProvider) {\n // Store WWW-Authenticate params for interactive finishAuth() path\n if (response.headers.has('www-authenticate')) {\n const { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);\n this._resourceMetadataUrl = resourceMetadataUrl;\n // Preserve any union accumulated by `_stepUpAuthorize` so a 401\n // mid-chain does not narrow `_scope` back to the challenge value.\n this._scope = computeScopeUnion(this._scope, scope);\n }\n\n if (this._authProvider.onUnauthorized && !isAuthRetry) {\n try {\n await this._authProvider.onUnauthorized({\n response,\n serverUrl: this._url,\n fetchFn: this._fetchWithInit\n });\n } catch (error) {\n // Auth-seam stamp: covers the SDK's OAuth flow and\n // custom onUnauthorized callbacks alike.\n throw markAuthSeamEscape(error);\n }\n await response.text?.().catch(() => {});\n // Purposely _not_ awaited, so we don't call onerror twice\n return this._send(message, options, true, stepUpRetries);\n }\n await response.text?.().catch(() => {});\n if (isAuthRetry) {\n throw markAuthSeamEscape(\n new SdkHttpError(SdkErrorCode.ClientHttpAuthentication, 'Server returned 401 after re-authentication', {\n status: 401,\n statusText: response.statusText\n })\n );\n }\n throw markAuthSeamEscape(new UnauthorizedError());\n }\n\n const text = await response.text?.().catch(() => null);\n\n if (response.status === 403) {\n const { resourceMetadataUrl, scope, error, errorDescription } = extractWWWAuthenticateParams(response);\n\n if (error === 'insufficient_scope') {\n const result = await this._stepUpAuthorize(\n { scope, resourceMetadataUrl, errorDescription, statusText: response.statusText, text },\n stepUpRetries\n );\n if (result !== 'AUTHORIZED') {\n throw markAuthSeamEscape(new UnauthorizedError());\n }\n return this._send(message, options, isAuthRetry, stepUpRetries + 1);\n }\n }\n\n // SEP-2243 (and the rest of the inbound validation ladder)\n // emit ladder rejections as HTTP 400 carrying a JSON-RPC error\n // response body. Surface those in-band so `Protocol._onresponse`\n // converts them to a typed `ProtocolError` matched to the\n // pending request id — instead of an opaque transport error.\n // Any 400 whose body is not a well-formed JSON-RPC error\n // response (or whose id does not match an outstanding request)\n // still falls through to the generic `SdkHttpError`.\n //\n // Modern-era only: gated on the outbound message carrying a\n // 2026-07-28 envelope claim (the same gate the body-derived\n // `mcp-method`/`mcp-name` headers use), so a legacy-era\n // exchange keeps surfacing 400 as `SdkHttpError` exactly as\n // before — the changeset's \"legacy-era paths are unchanged\"\n // claim stays true and existing\n // `e instanceof SdkHttpError && e.status === 400` callers do\n // not silently stop matching.\n if (response.status === 400 && typeof text === 'string' && this._isModernEnvelopedRequest(message)) {\n try {\n const parsed = JSONRPCMessageSchema.parse(JSON.parse(text));\n const requests = (Array.isArray(message) ? message : [message]).filter(m => isJSONRPCRequest(m));\n if (isJSONRPCErrorResponse(parsed) && requests.some(r => r.id === parsed.id)) {\n this.onmessage?.(parsed);\n return;\n }\n } catch {\n // not a JSON-RPC error body — fall through to the generic SdkHttpError below.\n }\n }\n\n throw new SdkHttpError(SdkErrorCode.ClientHttpNotImplemented, `Error POSTing to endpoint: ${text}`, {\n status: response.status,\n statusText: response.statusText,\n text\n });\n }\n\n // If the response is 202 Accepted, there's no body to process\n if (response.status === 202) {\n await response.text?.().catch(() => {});\n // if the accepted notification is initialized, we start the SSE stream\n // if it's supported by the server\n if (isInitializedNotification(message)) {\n // Start without a lastEventId since this is a fresh connection\n this._startOrAuthSse({ resumptionToken: undefined }).catch(error => this.onerror?.(error));\n }\n return;\n }\n\n // Get original message(s) for detecting request IDs\n const messages = Array.isArray(message) ? message : [message];\n\n const hasRequests = messages.some(msg => 'method' in msg && 'id' in msg && msg.id !== undefined);\n\n // Check the response type (parsed media type — see mediaTypeEssence)\n const contentType = response.headers.get('content-type');\n const responseMediaType = mediaTypeEssence(contentType);\n\n if (hasRequests) {\n if (responseMediaType === 'text/event-stream') {\n // Handle SSE stream responses for requests\n // We use the same handler as standalone streams, which now supports\n // reconnection with the last event ID\n this._handleSseStream(\n response.body,\n {\n onresumptiontoken,\n requestSignal: options?.requestSignal,\n onRequestStreamEnd: options?.onRequestStreamEnd\n },\n false\n );\n } else if (responseMediaType === 'application/json') {\n // For non-streaming servers, we might get direct JSON responses\n const data = await response.json();\n const responseMessages = Array.isArray(data)\n ? data.map(msg => JSONRPCMessageSchema.parse(msg))\n : [JSONRPCMessageSchema.parse(data)];\n\n for (const msg of responseMessages) {\n this.onmessage?.(msg);\n }\n } else {\n await response.text?.().catch(() => {});\n throw new SdkError(SdkErrorCode.ClientHttpUnexpectedContent, `Unexpected content type: ${contentType}`, {\n contentType\n });\n }\n } else {\n // No requests in message but got 200 OK - still need to release connection\n await response.text?.().catch(() => {});\n }\n } catch (error) {\n // Intentional per-request abort BEFORE response headers (the\n // `subscriptions/listen` driver aborting its `requestSignal`):\n // fetch rejects with AbortError. Same guard as\n // `_handleSseStream`'s `isIntentionalAbort` — do not surface a\n // misleading onerror; still rethrow so `listen()`'s send-catch\n // settles the per-subscription state machine.\n if (options?.requestSignal?.aborted !== true) {\n this.onerror?.(error as Error);\n }\n throw error;\n }\n }\n\n get sessionId(): string | undefined {\n return this._sessionId;\n }\n\n /**\n * Terminates the current session by sending a `DELETE` request to the server.\n *\n * Clients that no longer need a particular session\n * (e.g., because the user is leaving the client application) SHOULD send an\n * HTTP `DELETE` to the MCP endpoint with the `Mcp-Session-Id` header to explicitly\n * terminate the session.\n *\n * The server MAY respond with HTTP `405 Method Not Allowed`, indicating that\n * the server does not allow clients to terminate sessions.\n */\n async terminateSession(): Promise<void> {\n if (!this._sessionId) {\n return; // No session to terminate\n }\n\n try {\n const headers = await this._commonHeaders();\n\n const init = {\n ...this._requestInit,\n method: 'DELETE',\n headers,\n signal: this._abortController?.signal\n };\n\n const response = await (this._fetch ?? fetch)(this._url, init);\n await response.text?.().catch(() => {});\n\n // We specifically handle 405 as a valid response according to the spec,\n // meaning the server does not support explicit session termination\n if (!response.ok && response.status !== 405) {\n throw new SdkHttpError(\n SdkErrorCode.ClientHttpFailedToTerminateSession,\n `Failed to terminate session: ${response.statusText}`,\n {\n status: response.status,\n statusText: response.statusText\n }\n );\n }\n\n this._sessionId = undefined;\n } catch (error) {\n this.onerror?.(error as Error);\n throw error;\n }\n }\n\n setProtocolVersion(version: string): void {\n this._protocolVersion = version;\n }\n get protocolVersion(): string | undefined {\n return this._protocolVersion;\n }\n\n /**\n * Resume an SSE stream from a previous event ID.\n * Opens a `GET` SSE connection with `Last-Event-ID` header to replay missed events.\n *\n * @param lastEventId The event ID to resume from\n * @param options Optional callback to receive new resumption tokens\n */\n async resumeStream(lastEventId: string, options?: { onresumptiontoken?: (token: string) => void }): Promise<void> {\n await this._startOrAuthSse({\n resumptionToken: lastEventId,\n onresumptiontoken: options?.onresumptiontoken\n });\n }\n}\n","import { DefaultJsonSchemaValidator } from '@modelcontextprotocol/client/_shims';\nimport type { JsonSchemaType, jsonSchemaValidator, StandardSchemaWithJSON } from '@modelcontextprotocol/core-internal';\nimport { fromJsonSchema as coreFromJsonSchema } from '@modelcontextprotocol/core-internal';\n\nlet _defaultValidator: jsonSchemaValidator | undefined;\n\nexport function fromJsonSchema<T = unknown>(schema: JsonSchemaType, validator?: jsonSchemaValidator): StandardSchemaWithJSON<T, T> {\n return coreFromJsonSchema<T>(schema, validator ?? (_defaultValidator ??= new DefaultJsonSchemaValidator()));\n}\n"],"mappings":"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"}
|