@ashx-j/lunr-dev 0.2.13-dev.8.1 → 0.2.19-dev.10.1
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/CHANGELOG.md +60 -1
- package/README.md +7 -1
- package/dist/builtin-extensions/ashxj-thinking.d.ts +1 -0
- package/dist/builtin-extensions/ashxj-thinking.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-thinking.js +44 -19
- package/dist/builtin-extensions/ashxj-thinking.js.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.d.ts +14 -0
- package/dist/builtin-extensions/ashxj-tui.d.ts.map +1 -1
- package/dist/builtin-extensions/ashxj-tui.js +37 -3
- package/dist/builtin-extensions/ashxj-tui.js.map +1 -1
- package/dist/builtin-extensions/index.d.ts +1 -15
- package/dist/builtin-extensions/index.d.ts.map +1 -1
- package/dist/builtin-extensions/index.js +8 -21
- package/dist/builtin-extensions/index.js.map +1 -1
- package/dist/builtin-extensions/lunr-computer-use.d.ts +3 -0
- package/dist/builtin-extensions/lunr-computer-use.d.ts.map +1 -0
- package/dist/builtin-extensions/lunr-computer-use.js +157 -0
- package/dist/builtin-extensions/lunr-computer-use.js.map +1 -0
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.d.ts.map +1 -1
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js +6 -2
- package/dist/builtin-extensions/narumiruna-pi-goal/src/goal.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts +4 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/index.js +172 -171
- package/dist/builtin-extensions/pi-lsp-extension/src/index.js.map +1 -1
- package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts +50 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/runtime.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js +131 -0
- package/dist/builtin-extensions/pi-lsp-extension/src/runtime.js.map +1 -0
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts +7 -0
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js +211 -0
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tool-executor.js.map +1 -0
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts +0 -5
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js +0 -202
- package/dist/builtin-extensions/pi-mcp-adapter/direct-tools.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/index.js +276 -109
- package/dist/builtin-extensions/pi-mcp-adapter/index.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts +4 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/init.js +10 -3
- package/dist/builtin-extensions/pi-mcp-adapter/init.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js +6 -1
- package/dist/builtin-extensions/pi-mcp-adapter/metadata-cache.js.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts +6 -1
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js +33 -8
- package/dist/builtin-extensions/pi-mcp-adapter/server-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js +2 -1
- package/dist/builtin-extensions/pi-prompt-template-model/prompt-loader.js.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js +1 -1
- package/dist/builtin-extensions/pi-prompt-template-model/tool-manager.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js +68 -15
- package/dist/builtin-extensions/pi-subagents/src/extension/index.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js +6 -2
- package/dist/builtin-extensions/pi-subagents/src/extension/schemas.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js +5 -2
- package/dist/builtin-extensions/pi-subagents/src/runs/background/wait-tool.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts +10 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js +38 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/request-params.js.map +1 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js +3 -16
- package/dist/builtin-extensions/pi-subagents/src/runs/foreground/subagent-executor.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js +2 -0
- package/dist/builtin-extensions/pi-subagents/src/runs/shared/child-tools.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/shared/fork-context.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js +1 -1
- package/dist/builtin-extensions/pi-subagents/src/slash/slash-commands.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts +2 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js +72 -31
- package/dist/builtin-extensions/pi-subagents/src/tui/render.js.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js +2 -1
- package/dist/builtin-extensions/pi-subagents/src/watchdog/review.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/extract.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/extract.js +105 -54
- package/dist/builtin-extensions/pi-web-access/extract.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts +1 -1
- package/dist/builtin-extensions/pi-web-access/gemini-search.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/gemini-search.js +82 -65
- package/dist/builtin-extensions/pi-web-access/gemini-search.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/github-extract.js +2 -0
- package/dist/builtin-extensions/pi-web-access/github-extract.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.d.ts.map +1 -1
- package/dist/builtin-extensions/pi-web-access/index.js +259 -168
- package/dist/builtin-extensions/pi-web-access/index.js.map +1 -1
- package/dist/builtin-extensions/pi-web-access/lazy.d.ts +18 -0
- package/dist/builtin-extensions/pi-web-access/lazy.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-web-access/lazy.js +19 -0
- package/dist/builtin-extensions/pi-web-access/lazy.js.map +1 -0
- package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts +6 -0
- package/dist/builtin-extensions/pi-web-access/session-cleanup.d.ts.map +1 -0
- package/dist/builtin-extensions/pi-web-access/session-cleanup.js +17 -0
- package/dist/builtin-extensions/pi-web-access/session-cleanup.js.map +1 -0
- package/dist/catalog/publication.json +12 -12
- package/dist/cli-runtime.d.ts +3 -0
- package/dist/cli-runtime.d.ts.map +1 -0
- package/dist/cli-runtime.js +73 -0
- package/dist/cli-runtime.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +14 -53
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +1 -0
- package/dist/config.js.map +1 -1
- package/dist/core/agent-session-services.d.ts.map +1 -1
- package/dist/core/agent-session-services.js +1 -1
- package/dist/core/agent-session-services.js.map +1 -1
- package/dist/core/agent-session.d.ts +3 -0
- package/dist/core/agent-session.d.ts.map +1 -1
- package/dist/core/agent-session.js +56 -12
- package/dist/core/agent-session.js.map +1 -1
- package/dist/core/compaction/compaction.d.ts.map +1 -1
- package/dist/core/compaction/compaction.js +10 -5
- package/dist/core/compaction/compaction.js.map +1 -1
- package/dist/core/computer-use/adapter.d.ts +23 -0
- package/dist/core/computer-use/adapter.d.ts.map +1 -0
- package/dist/core/computer-use/adapter.js +116 -0
- package/dist/core/computer-use/adapter.js.map +1 -0
- package/dist/core/computer-use/lease.d.ts +18 -0
- package/dist/core/computer-use/lease.d.ts.map +1 -0
- package/dist/core/computer-use/lease.js +129 -0
- package/dist/core/computer-use/lease.js.map +1 -0
- package/dist/core/computer-use/macos-runtime.d.ts +14 -0
- package/dist/core/computer-use/macos-runtime.d.ts.map +1 -0
- package/dist/core/computer-use/macos-runtime.js +148 -0
- package/dist/core/computer-use/macos-runtime.js.map +1 -0
- package/dist/core/computer-use/policy.d.ts +19 -0
- package/dist/core/computer-use/policy.d.ts.map +1 -0
- package/dist/core/computer-use/policy.js +66 -0
- package/dist/core/computer-use/policy.js.map +1 -0
- package/dist/core/computer-use/release.generated.d.ts +31 -0
- package/dist/core/computer-use/release.generated.d.ts.map +1 -0
- package/dist/core/computer-use/release.generated.js +36 -0
- package/dist/core/computer-use/release.generated.js.map +1 -0
- package/dist/core/computer-use/runtime.d.ts +13 -0
- package/dist/core/computer-use/runtime.d.ts.map +1 -0
- package/dist/core/computer-use/runtime.js +158 -0
- package/dist/core/computer-use/runtime.js.map +1 -0
- package/dist/core/computer-use/schemas.d.ts +88 -0
- package/dist/core/computer-use/schemas.d.ts.map +1 -0
- package/dist/core/computer-use/schemas.js +80 -0
- package/dist/core/computer-use/schemas.js.map +1 -0
- package/dist/core/computer-use/windows-desktop.d.ts +3 -0
- package/dist/core/computer-use/windows-desktop.d.ts.map +1 -0
- package/dist/core/computer-use/windows-desktop.js +48 -0
- package/dist/core/computer-use/windows-desktop.js.map +1 -0
- package/dist/core/computer-use/workflow.d.ts +24 -0
- package/dist/core/computer-use/workflow.d.ts.map +1 -0
- package/dist/core/computer-use/workflow.js +330 -0
- package/dist/core/computer-use/workflow.js.map +1 -0
- package/dist/core/extensions/host-static.d.ts.map +1 -1
- package/dist/core/extensions/host-static.js +34 -12
- package/dist/core/extensions/host-static.js.map +1 -1
- package/dist/core/extensions/loader.d.ts +1 -2
- package/dist/core/extensions/loader.d.ts.map +1 -1
- package/dist/core/extensions/loader.js +10 -64
- package/dist/core/extensions/loader.js.map +1 -1
- package/dist/core/extensions/types.d.ts +2 -2
- package/dist/core/extensions/types.d.ts.map +1 -1
- package/dist/core/extensions/types.js.map +1 -1
- package/dist/core/footer-data-provider.d.ts.map +1 -1
- package/dist/core/footer-data-provider.js +2 -0
- package/dist/core/footer-data-provider.js.map +1 -1
- package/dist/core/keybindings.d.ts +2 -2
- package/dist/core/keybindings.d.ts.map +1 -1
- package/dist/core/keybindings.js +2 -2
- package/dist/core/keybindings.js.map +1 -1
- package/dist/core/model-runtime.d.ts +0 -3
- package/dist/core/model-runtime.d.ts.map +1 -1
- package/dist/core/model-runtime.js +1 -10
- package/dist/core/model-runtime.js.map +1 -1
- package/dist/core/package-manager.d.ts.map +1 -1
- package/dist/core/package-manager.js +1 -1
- package/dist/core/package-manager.js.map +1 -1
- package/dist/core/permissions.d.ts +1 -3
- package/dist/core/permissions.d.ts.map +1 -1
- package/dist/core/permissions.js +33 -25
- package/dist/core/permissions.js.map +1 -1
- package/dist/core/plan-mode.d.ts.map +1 -1
- package/dist/core/plan-mode.js +9 -0
- package/dist/core/plan-mode.js.map +1 -1
- package/dist/core/rollback.d.ts.map +1 -1
- package/dist/core/rollback.js +13 -90
- package/dist/core/rollback.js.map +1 -1
- package/dist/core/sdk.d.ts +1 -1
- package/dist/core/sdk.d.ts.map +1 -1
- package/dist/core/sdk.js +1 -1
- package/dist/core/sdk.js.map +1 -1
- package/dist/core/session-manager.d.ts +0 -1
- package/dist/core/session-manager.d.ts.map +1 -1
- package/dist/core/session-manager.js +21 -79
- package/dist/core/session-manager.js.map +1 -1
- package/dist/core/settings-manager.d.ts +6 -0
- package/dist/core/settings-manager.d.ts.map +1 -1
- package/dist/core/settings-manager.js +19 -0
- package/dist/core/settings-manager.js.map +1 -1
- package/dist/core/slash-commands.d.ts.map +1 -1
- package/dist/core/slash-commands.js +0 -1
- package/dist/core/slash-commands.js.map +1 -1
- package/dist/core/timings.d.ts +2 -1
- package/dist/core/timings.d.ts.map +1 -1
- package/dist/core/timings.js +17 -2
- package/dist/core/timings.js.map +1 -1
- package/dist/dev-cli.js +0 -0
- package/dist/gateway/agent-bridge.d.ts +6 -1
- package/dist/gateway/agent-bridge.d.ts.map +1 -1
- package/dist/gateway/agent-bridge.js +23 -6
- package/dist/gateway/agent-bridge.js.map +1 -1
- package/dist/gateway/commands.d.ts +1 -1
- package/dist/gateway/commands.d.ts.map +1 -1
- package/dist/gateway/commands.js +1 -18
- package/dist/gateway/commands.js.map +1 -1
- package/dist/gateway/cron.d.ts +1 -1
- package/dist/gateway/cron.d.ts.map +1 -1
- package/dist/gateway/cron.js +23 -7
- package/dist/gateway/cron.js.map +1 -1
- package/dist/main.d.ts +2 -2
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +57 -48
- package/dist/main.js.map +1 -1
- package/dist/modes/interactive/components/footer.d.ts +4 -2
- package/dist/modes/interactive/components/footer.d.ts.map +1 -1
- package/dist/modes/interactive/components/footer.js +23 -32
- package/dist/modes/interactive/components/footer.js.map +1 -1
- package/dist/modes/interactive/components/processes-selector.d.ts +2 -3
- package/dist/modes/interactive/components/processes-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/processes-selector.js +5 -10
- package/dist/modes/interactive/components/processes-selector.js.map +1 -1
- package/dist/modes/interactive/components/settings-selector.d.ts +4 -0
- package/dist/modes/interactive/components/settings-selector.d.ts.map +1 -1
- package/dist/modes/interactive/components/settings-selector.js +20 -0
- package/dist/modes/interactive/components/settings-selector.js.map +1 -1
- package/dist/modes/interactive/interactive-mode.d.ts +12 -21
- package/dist/modes/interactive/interactive-mode.d.ts.map +1 -1
- package/dist/modes/interactive/interactive-mode.js +138 -152
- package/dist/modes/interactive/interactive-mode.js.map +1 -1
- package/dist/modes/interactive/theme/theme.d.ts.map +1 -1
- package/dist/modes/interactive/theme/theme.js +95 -84
- package/dist/modes/interactive/theme/theme.js.map +1 -1
- package/dist/modes/interactive/thinking-level-slash.d.ts +4 -0
- package/dist/modes/interactive/thinking-level-slash.d.ts.map +1 -0
- package/dist/modes/interactive/thinking-level-slash.js +23 -0
- package/dist/modes/interactive/thinking-level-slash.js.map +1 -0
- package/dist/node-runtime/adapter-AZMY335J.js +279 -0
- package/dist/node-runtime/agent-session-services-RSGP5GDN.js +39 -0
- package/dist/node-runtime/benchmark-request-UC7PD3V3.js +57 -0
- package/dist/node-runtime/brave-UWDA3I22.js +143 -0
- package/dist/node-runtime/builtin-extensions-7STLFW3A.js +29 -0
- package/dist/node-runtime/chunk-2IDTZAG5.js +1415 -0
- package/dist/node-runtime/chunk-3GHXVUAK.js +21 -0
- package/dist/node-runtime/chunk-3RCWXWAY.js +466 -0
- package/dist/node-runtime/chunk-3WFAEVKS.js +115 -0
- package/dist/node-runtime/chunk-3X3KZKMI.js +49 -0
- package/dist/node-runtime/chunk-4HXHDDCF.js +16 -0
- package/dist/node-runtime/chunk-4SJWFTUP.js +24 -0
- package/dist/node-runtime/chunk-4ZWGEEAS.js +69 -0
- package/dist/node-runtime/chunk-53YJI7JU.js +137 -0
- package/dist/node-runtime/chunk-5NWQCSKR.js +19218 -0
- package/dist/node-runtime/chunk-5OLJGVCB.js +68 -0
- package/dist/node-runtime/chunk-5Q45AVQG.js +108 -0
- package/dist/node-runtime/chunk-5SQDLSZJ.js +949 -0
- package/dist/node-runtime/chunk-6SPPH4FY.js +1269 -0
- package/dist/node-runtime/chunk-6UB6NKA3.js +860 -0
- package/dist/node-runtime/chunk-7AFOFSDY.js +105 -0
- package/dist/node-runtime/chunk-7N3YHTYF.js +26 -0
- package/dist/node-runtime/chunk-ARC4KOTI.js +11178 -0
- package/dist/node-runtime/chunk-AUXVGBO4.js +19 -0
- package/dist/node-runtime/chunk-AY6CAJSL.js +30 -0
- package/dist/node-runtime/chunk-BHO7O6E5.js +296 -0
- package/dist/node-runtime/chunk-BI3DHYCN.js +8845 -0
- package/dist/node-runtime/chunk-BKAZ6BKX.js +2185 -0
- package/dist/node-runtime/chunk-BR7YDUKA.js +109 -0
- package/dist/node-runtime/chunk-BRJX2PRC.js +53 -0
- package/dist/node-runtime/chunk-C4O2RSQQ.js +37 -0
- package/dist/node-runtime/chunk-CCZJ3PYY.js +17 -0
- package/dist/node-runtime/chunk-CGBXPL3E.js +1171 -0
- package/dist/node-runtime/chunk-CH6OL6P2.js +295 -0
- package/dist/node-runtime/chunk-CJECDQKP.js +19 -0
- package/dist/node-runtime/chunk-DAPBPCBP.js +53 -0
- package/dist/node-runtime/chunk-DDGMHUOW.js +305 -0
- package/dist/node-runtime/chunk-DMMTJQMQ.js +43 -0
- package/dist/node-runtime/chunk-DVGWF6A2.js +1180 -0
- package/dist/node-runtime/chunk-EH2LJQPM.js +64 -0
- package/dist/node-runtime/chunk-EHMBW7FA.js +772 -0
- package/dist/node-runtime/chunk-FLYMHKCS.js +966 -0
- package/dist/node-runtime/chunk-FVDOXRUD.js +96 -0
- package/dist/node-runtime/chunk-GZQHMEWL.js +126 -0
- package/dist/node-runtime/chunk-H2EOZYMP.js +57 -0
- package/dist/node-runtime/chunk-HQCKFM2O.js +56 -0
- package/dist/node-runtime/chunk-HRS4HMDX.js +610 -0
- package/dist/node-runtime/chunk-HYHJIRDW.js +19 -0
- package/dist/node-runtime/chunk-I6R76AG7.js +22 -0
- package/dist/node-runtime/chunk-ISQDQIZN.js +296 -0
- package/dist/node-runtime/chunk-J7QGQD45.js +24921 -0
- package/dist/node-runtime/chunk-JHYKXIMM.js +378 -0
- package/dist/node-runtime/chunk-JT6YCS5B.js +5648 -0
- package/dist/node-runtime/chunk-JZHEUQRL.js +180 -0
- package/dist/node-runtime/chunk-K72NVGUB.js +2834 -0
- package/dist/node-runtime/chunk-KKSIVROT.js +88 -0
- package/dist/node-runtime/chunk-LCACDWHJ.js +1743 -0
- package/dist/node-runtime/chunk-LTXUQJI4.js +173 -0
- package/dist/node-runtime/chunk-LWJXTA6Z.js +6814 -0
- package/dist/node-runtime/chunk-M3LZLQW2.js +98 -0
- package/dist/node-runtime/chunk-MGSB2C3M.js +46 -0
- package/dist/node-runtime/chunk-MGWCVY6Y.js +47 -0
- package/dist/node-runtime/chunk-MJQDX3BA.js +72 -0
- package/dist/node-runtime/chunk-MUMMMTW4.js +8392 -0
- package/dist/node-runtime/chunk-MX3GJNXJ.js +986 -0
- package/dist/node-runtime/chunk-NUIFPZWX.js +209 -0
- package/dist/node-runtime/chunk-OBMWP3I5.js +68 -0
- package/dist/node-runtime/chunk-OR4L3IB2.js +42 -0
- package/dist/node-runtime/chunk-OTT6JMPU.js +807 -0
- package/dist/node-runtime/chunk-PCIGF2XK.js +250 -0
- package/dist/node-runtime/chunk-PL6JKXWI.js +3622 -0
- package/dist/node-runtime/chunk-PVCDKGR6.js +55 -0
- package/dist/node-runtime/chunk-Q4Q6D4IY.js +364 -0
- package/dist/node-runtime/chunk-Q5ZU2VRT.js +83 -0
- package/dist/node-runtime/chunk-QFWG2RVL.js +5477 -0
- package/dist/node-runtime/chunk-RQ2Q5IYR.js +72 -0
- package/dist/node-runtime/chunk-RQ5DNUNG.js +429 -0
- package/dist/node-runtime/chunk-RRIZE6QQ.js +17 -0
- package/dist/node-runtime/chunk-SN6G4OU6.js +4753 -0
- package/dist/node-runtime/chunk-SWSN6HAB.js +53 -0
- package/dist/node-runtime/chunk-T5GM5BFH.js +7558 -0
- package/dist/node-runtime/chunk-TAP7QTUT.js +1346 -0
- package/dist/node-runtime/chunk-U6C7VTR5.js +2033 -0
- package/dist/node-runtime/chunk-URD2SLIT.js +1019 -0
- package/dist/node-runtime/chunk-VRB2IYGG.js +53 -0
- package/dist/node-runtime/chunk-W3CVH5RX.js +62 -0
- package/dist/node-runtime/chunk-W7S2REEG.js +9478 -0
- package/dist/node-runtime/chunk-XBWPBZBN.js +125 -0
- package/dist/node-runtime/chunk-XTHQ7XR7.js +509 -0
- package/dist/node-runtime/chunk-ZCHMJ34K.js +130 -0
- package/dist/node-runtime/chunk-ZRDIMBEQ.js +651 -0
- package/dist/node-runtime/chunk-ZSEZY3II.js +247 -0
- package/dist/node-runtime/cli-runtime.js +81 -0
- package/dist/node-runtime/clipboard-OZ63BBC6.js +12 -0
- package/dist/node-runtime/clipboard-image-7QR6GXVA.js +13 -0
- package/dist/node-runtime/command-6UXQ6XZN.js +13 -0
- package/dist/node-runtime/commands-LGR5VT5X.js +293 -0
- package/dist/node-runtime/config-FMEOZSWE.js +77 -0
- package/dist/node-runtime/curator-server-XCM43VEF.js +3816 -0
- package/dist/node-runtime/customize-XEXL2DGQ.js +12 -0
- package/dist/node-runtime/direct-tool-executor-TDJS7TBD.js +191 -0
- package/dist/node-runtime/exa-LL64QZR2.js +329 -0
- package/dist/node-runtime/export-html-E4DT6ZJQ.js +150 -0
- package/dist/node-runtime/extension-input-RV5N6APL.js +14 -0
- package/dist/node-runtime/extension-selector-CPD5LWDD.js +14 -0
- package/dist/node-runtime/extract-IUCVZCWC.js +17 -0
- package/dist/node-runtime/file-sync-HCOP2QVF.js +117 -0
- package/dist/node-runtime/gateway-3OLC4GQN.js +2139 -0
- package/dist/node-runtime/gemini-api-QE7ANVDZ.js +29 -0
- package/dist/node-runtime/gemini-search-NCIDF7NE.js +330 -0
- package/dist/node-runtime/gemini-url-context-OKIN7AIP.js +103 -0
- package/dist/node-runtime/gemini-web-MM446SEH.js +14 -0
- package/dist/node-runtime/github-extract-F64RZOEA.js +619 -0
- package/dist/node-runtime/goal-CZQ7FFQJ.js +1831 -0
- package/dist/node-runtime/image-resize-6ZPBFMWW.js +11 -0
- package/dist/node-runtime/index.js +863 -0
- package/dist/node-runtime/init-EKE277AG.js +30 -0
- package/dist/node-runtime/install-cli-TH7IJJQQ.js +308 -0
- package/dist/node-runtime/interactive-mode-S5M26CQ7.js +59 -0
- package/dist/node-runtime/interactive-view-N6F4KUIT.js +247 -0
- package/dist/node-runtime/lsp-manager-3ASUSO4T.js +1104 -0
- package/dist/node-runtime/lunr-computer-use-4X3KUNF4.js +206 -0
- package/dist/node-runtime/lunr-cron-KKBOGAEF.js +274 -0
- package/dist/node-runtime/main.js +57 -0
- package/dist/node-runtime/mcp-auth-flow-YL6RWPYG.js +33 -0
- package/dist/node-runtime/mcp-panel-IIGMXQGP.js +501 -0
- package/dist/node-runtime/mcp-setup-panel-FEK7663I.js +355 -0
- package/dist/node-runtime/memory-cap-3S4XRLNP.js +20 -0
- package/dist/node-runtime/model-tiers-NJLHUEGK.js +20 -0
- package/dist/node-runtime/openai-search-B3MSNCQA.js +288 -0
- package/dist/node-runtime/package-manager-cli-C4EJOO5Q.js +751 -0
- package/dist/node-runtime/parallel-AI2MNSCU.js +265 -0
- package/dist/node-runtime/parser-manager-TQHWYDH7.js +152 -0
- package/dist/node-runtime/pdf-extract-IPE6H4HP.js +57 -0
- package/dist/node-runtime/perplexity-QVJW3I35.js +12 -0
- package/dist/node-runtime/pi-intercom-EEMBGQID.js +2215 -0
- package/dist/node-runtime/pi-mcp-adapter-DPTJGAAL.js +428 -0
- package/dist/node-runtime/pi-ollama-cloud-4VZRMULP.js +1440 -0
- package/dist/node-runtime/pi-prompt-template-model-4QT4LLXF.js +3946 -0
- package/dist/node-runtime/pi-subagents-VKCLYIBY.js +6050 -0
- package/dist/node-runtime/pi-web-access-BV6DSZOP.js +1867 -0
- package/dist/node-runtime/print-mode-VWIRFDAC.js +12 -0
- package/dist/node-runtime/proxy-modes-R64LU6WZ.js +688 -0
- package/dist/node-runtime/rpc-entry.js +65 -0
- package/dist/node-runtime/rpc-mode-SJNSOA4G.js +13 -0
- package/dist/node-runtime/runtime-3SB5ATHQ.js +21 -0
- package/dist/node-runtime/runtime-bridges-UJ5WJJLN.js +14 -0
- package/dist/node-runtime/session-manager-QEMZBMTM.js +33 -0
- package/dist/node-runtime/session-selector-URVJLOTK.js +14 -0
- package/dist/node-runtime/settings-manager-K6IPIQTI.js +23 -0
- package/dist/node-runtime/src-GPFAU3N6.js +2427 -0
- package/dist/node-runtime/subagent-executor-EFLTO32A.js +8501 -0
- package/dist/node-runtime/summary-review-YSMXKITO.js +228 -0
- package/dist/node-runtime/tavily-WEZFVFP7.js +154 -0
- package/dist/node-runtime/timings-UAD5BEAS.js +16 -0
- package/dist/node-runtime/tool-renderer-MV5O452K.js +204 -0
- package/dist/node-runtime/update-cli-I6OVDRPL.js +75 -0
- package/dist/node-runtime/v4-5MNC3H7G.js +424 -0
- package/dist/node-runtime/video-extract-ETA5RA7U.js +304 -0
- package/dist/node-runtime/workflow-SA34S4VX.js +325 -0
- package/dist/node-runtime/workspace-index-6DBXSTJ6.js +163 -0
- package/dist/node-runtime/youtube-extract-SRVGNN26.js +264 -0
- package/dist/rpc.d.ts +3 -0
- package/dist/rpc.d.ts.map +1 -0
- package/dist/rpc.js +18 -0
- package/dist/rpc.js.map +1 -0
- package/dist/startup/benchmark-request.d.ts +3 -0
- package/dist/startup/benchmark-request.d.ts.map +1 -0
- package/dist/startup/benchmark-request.js +65 -0
- package/dist/startup/benchmark-request.js.map +1 -0
- package/dist/startup/{interactive-shell.d.ts → interactive-view.d.ts} +18 -18
- package/dist/startup/interactive-view.d.ts.map +1 -0
- package/dist/startup/{interactive-shell.js → interactive-view.js} +119 -52
- package/dist/startup/interactive-view.js.map +1 -0
- package/dist/startup/launch-routing.d.ts.map +1 -1
- package/dist/startup/launch-routing.js +9 -10
- package/dist/startup/launch-routing.js.map +1 -1
- package/dist/startup/startup-milestones.d.ts +1 -1
- package/dist/startup/startup-milestones.d.ts.map +1 -1
- package/dist/startup/startup-milestones.js +3 -2
- package/dist/startup/startup-milestones.js.map +1 -1
- package/dist/utils/await-with-abort.d.ts +2 -0
- package/dist/utils/await-with-abort.d.ts.map +1 -0
- package/dist/utils/await-with-abort.js +19 -0
- package/dist/utils/await-with-abort.js.map +1 -0
- package/dist/utils/syntax-highlight.d.ts.map +1 -1
- package/dist/utils/syntax-highlight.js +10 -4
- package/dist/utils/syntax-highlight.js.map +1 -1
- package/docs/compaction.md +5 -3
- package/docs/computer-use.md +277 -0
- package/docs/development.md +5 -33
- package/docs/features.md +2 -3
- package/docs/interactive-startup.md +105 -0
- package/docs/keybindings.md +2 -2
- package/docs/terminal-setup.md +1 -1
- package/docs/usage.md +1 -2
- package/examples/extensions/custom-provider-anthropic/package-lock.json +2 -2
- package/examples/extensions/custom-provider-anthropic/package.json +1 -1
- package/examples/extensions/custom-provider-gitlab-duo/package.json +1 -1
- package/examples/extensions/gondolin/package-lock.json +2 -2
- package/examples/extensions/gondolin/package.json +1 -1
- package/examples/extensions/hidden-thinking-label.ts +1 -1
- package/examples/extensions/sandbox/package-lock.json +2 -2
- package/examples/extensions/sandbox/package.json +1 -1
- package/examples/extensions/with-deps/package-lock.json +2 -2
- package/examples/extensions/with-deps/package.json +1 -1
- package/install-lock/package-lock.json +3827 -0
- package/install-lock/package.json +18 -0
- package/native/computer-use/LICENSE.md +21 -0
- package/npm-shrinkwrap.json +3808 -0
- package/package.json +30 -24
- package/dist/core/swarm.d.ts +0 -23
- package/dist/core/swarm.d.ts.map +0 -1
- package/dist/core/swarm.js +0 -45
- package/dist/core/swarm.js.map +0 -1
- package/dist/startup/interactive-shell.d.ts.map +0 -1
- package/dist/startup/interactive-shell.js.map +0 -1
|
@@ -0,0 +1,2033 @@
|
|
|
1
|
+
import { createRequire as __lunrRequire } from "node:module"; const require = __lunrRequire(import.meta.url);
|
|
2
|
+
import {
|
|
3
|
+
getAgentPath
|
|
4
|
+
} from "./chunk-4HXHDDCF.js";
|
|
5
|
+
import {
|
|
6
|
+
JSONRPCMessageSchema,
|
|
7
|
+
LATEST_PROTOCOL_VERSION,
|
|
8
|
+
isInitializedNotification,
|
|
9
|
+
isJSONRPCRequest,
|
|
10
|
+
isJSONRPCResultResponse
|
|
11
|
+
} from "./chunk-2IDTZAG5.js";
|
|
12
|
+
import {
|
|
13
|
+
NEVER,
|
|
14
|
+
ZodIssueCode,
|
|
15
|
+
any,
|
|
16
|
+
array,
|
|
17
|
+
boolean,
|
|
18
|
+
coerce_exports,
|
|
19
|
+
literal,
|
|
20
|
+
looseObject,
|
|
21
|
+
number,
|
|
22
|
+
object,
|
|
23
|
+
string,
|
|
24
|
+
url
|
|
25
|
+
} from "./chunk-BI3DHYCN.js";
|
|
26
|
+
import {
|
|
27
|
+
__commonJS,
|
|
28
|
+
__toESM
|
|
29
|
+
} from "./chunk-BRJX2PRC.js";
|
|
30
|
+
|
|
31
|
+
// node_modules/content-type/index.js
|
|
32
|
+
var require_content_type = __commonJS({
|
|
33
|
+
"node_modules/content-type/index.js"(exports) {
|
|
34
|
+
"use strict";
|
|
35
|
+
var PARAM_REGEXP = /; *([!#$%&'*+.^_`|~0-9A-Za-z-]+) *= *("(?:[\u000b\u0020\u0021\u0023-\u005b\u005d-\u007e\u0080-\u00ff]|\\[\u000b\u0020-\u00ff])*"|[!#$%&'*+.^_`|~0-9A-Za-z-]+) */g, TEXT_REGEXP = /^[\u000b\u0020-\u007e\u0080-\u00ff]+$/, TOKEN_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+$/, QESC_REGEXP = /\\([\u000b\u0020-\u00ff])/g, QUOTE_REGEXP = /([\\"])/g, TYPE_REGEXP = /^[!#$%&'*+.^_`|~0-9A-Za-z-]+\/[!#$%&'*+.^_`|~0-9A-Za-z-]+$/;
|
|
36
|
+
exports.format = format;
|
|
37
|
+
exports.parse = parse;
|
|
38
|
+
function format(obj) {
|
|
39
|
+
if (!obj || typeof obj != "object")
|
|
40
|
+
throw new TypeError("argument obj is required");
|
|
41
|
+
var parameters = obj.parameters, type = obj.type;
|
|
42
|
+
if (!type || !TYPE_REGEXP.test(type))
|
|
43
|
+
throw new TypeError("invalid type");
|
|
44
|
+
var string2 = type;
|
|
45
|
+
if (parameters && typeof parameters == "object")
|
|
46
|
+
for (var param, params = Object.keys(parameters).sort(), i = 0; i < params.length; i++) {
|
|
47
|
+
if (param = params[i], !TOKEN_REGEXP.test(param))
|
|
48
|
+
throw new TypeError("invalid parameter name");
|
|
49
|
+
string2 += "; " + param + "=" + qstring(parameters[param]);
|
|
50
|
+
}
|
|
51
|
+
return string2;
|
|
52
|
+
}
|
|
53
|
+
function parse(string2) {
|
|
54
|
+
if (!string2)
|
|
55
|
+
throw new TypeError("argument string is required");
|
|
56
|
+
var header = typeof string2 == "object" ? getcontenttype(string2) : string2;
|
|
57
|
+
if (typeof header != "string")
|
|
58
|
+
throw new TypeError("argument string is required to be a string");
|
|
59
|
+
var index = header.indexOf(";"), type = index !== -1 ? header.slice(0, index).trim() : header.trim();
|
|
60
|
+
if (!TYPE_REGEXP.test(type))
|
|
61
|
+
throw new TypeError("invalid media type");
|
|
62
|
+
var obj = new ContentType(type.toLowerCase());
|
|
63
|
+
if (index !== -1) {
|
|
64
|
+
var key, match, value;
|
|
65
|
+
for (PARAM_REGEXP.lastIndex = index; match = PARAM_REGEXP.exec(header); ) {
|
|
66
|
+
if (match.index !== index)
|
|
67
|
+
throw new TypeError("invalid parameter format");
|
|
68
|
+
index += match[0].length, key = match[1].toLowerCase(), value = match[2], value.charCodeAt(0) === 34 && (value = value.slice(1, -1), value.indexOf("\\") !== -1 && (value = value.replace(QESC_REGEXP, "$1"))), obj.parameters[key] = value;
|
|
69
|
+
}
|
|
70
|
+
if (index !== header.length)
|
|
71
|
+
throw new TypeError("invalid parameter format");
|
|
72
|
+
}
|
|
73
|
+
return obj;
|
|
74
|
+
}
|
|
75
|
+
function getcontenttype(obj) {
|
|
76
|
+
var header;
|
|
77
|
+
if (typeof obj.getHeader == "function" ? header = obj.getHeader("content-type") : typeof obj.headers == "object" && (header = obj.headers && obj.headers["content-type"]), typeof header != "string")
|
|
78
|
+
throw new TypeError("content-type header is missing from object");
|
|
79
|
+
return header;
|
|
80
|
+
}
|
|
81
|
+
function qstring(val) {
|
|
82
|
+
var str = String(val);
|
|
83
|
+
if (TOKEN_REGEXP.test(str))
|
|
84
|
+
return str;
|
|
85
|
+
if (str.length > 0 && !TEXT_REGEXP.test(str))
|
|
86
|
+
throw new TypeError("invalid parameter value");
|
|
87
|
+
return '"' + str.replace(QUOTE_REGEXP, "\\$1") + '"';
|
|
88
|
+
}
|
|
89
|
+
function ContentType(type) {
|
|
90
|
+
this.parameters = /* @__PURE__ */ Object.create(null), this.type = type;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
// node_modules/pkce-challenge/dist/index.node.js
|
|
96
|
+
var crypto2;
|
|
97
|
+
crypto2 = globalThis.crypto?.webcrypto ?? // Node.js [18-16] REPL
|
|
98
|
+
globalThis.crypto ?? // Node.js >18
|
|
99
|
+
import("node:crypto").then((m) => m.webcrypto);
|
|
100
|
+
async function getRandomValues(size) {
|
|
101
|
+
return (await crypto2).getRandomValues(new Uint8Array(size));
|
|
102
|
+
}
|
|
103
|
+
async function random(size) {
|
|
104
|
+
let mask = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~", evenDistCutoff = Math.pow(2, 8) - Math.pow(2, 8) % mask.length, result = "";
|
|
105
|
+
for (; result.length < size; ) {
|
|
106
|
+
let randomBytes = await getRandomValues(size - result.length);
|
|
107
|
+
for (let randomByte of randomBytes)
|
|
108
|
+
randomByte < evenDistCutoff && (result += mask[randomByte % mask.length]);
|
|
109
|
+
}
|
|
110
|
+
return result;
|
|
111
|
+
}
|
|
112
|
+
async function generateVerifier(length) {
|
|
113
|
+
return await random(length);
|
|
114
|
+
}
|
|
115
|
+
async function generateChallenge(code_verifier) {
|
|
116
|
+
let buffer = await (await crypto2).subtle.digest("SHA-256", new TextEncoder().encode(code_verifier));
|
|
117
|
+
return btoa(String.fromCharCode(...new Uint8Array(buffer))).replace(/\//g, "_").replace(/\+/g, "-").replace(/=/g, "");
|
|
118
|
+
}
|
|
119
|
+
async function pkceChallenge(length) {
|
|
120
|
+
if (length || (length = 43), length < 43 || length > 128)
|
|
121
|
+
throw `Expected a length between 43 and 128. Received ${length}.`;
|
|
122
|
+
let verifier = await generateVerifier(length), challenge = await generateChallenge(verifier);
|
|
123
|
+
return {
|
|
124
|
+
code_verifier: verifier,
|
|
125
|
+
code_challenge: challenge
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth.js
|
|
130
|
+
var SafeUrlSchema = url().superRefine((val, ctx) => {
|
|
131
|
+
if (!URL.canParse(val))
|
|
132
|
+
return ctx.addIssue({
|
|
133
|
+
code: ZodIssueCode.custom,
|
|
134
|
+
message: "URL must be parseable",
|
|
135
|
+
fatal: !0
|
|
136
|
+
}), NEVER;
|
|
137
|
+
}).refine((url2) => {
|
|
138
|
+
let u = new URL(url2);
|
|
139
|
+
return u.protocol !== "javascript:" && u.protocol !== "data:" && u.protocol !== "vbscript:";
|
|
140
|
+
}, { message: "URL cannot use javascript:, data:, or vbscript: scheme" }), OAuthProtectedResourceMetadataSchema = looseObject({
|
|
141
|
+
resource: string().url(),
|
|
142
|
+
authorization_servers: array(SafeUrlSchema).optional(),
|
|
143
|
+
jwks_uri: string().url().optional(),
|
|
144
|
+
scopes_supported: array(string()).optional(),
|
|
145
|
+
bearer_methods_supported: array(string()).optional(),
|
|
146
|
+
resource_signing_alg_values_supported: array(string()).optional(),
|
|
147
|
+
resource_name: string().optional(),
|
|
148
|
+
resource_documentation: string().optional(),
|
|
149
|
+
resource_policy_uri: string().url().optional(),
|
|
150
|
+
resource_tos_uri: string().url().optional(),
|
|
151
|
+
tls_client_certificate_bound_access_tokens: boolean().optional(),
|
|
152
|
+
authorization_details_types_supported: array(string()).optional(),
|
|
153
|
+
dpop_signing_alg_values_supported: array(string()).optional(),
|
|
154
|
+
dpop_bound_access_tokens_required: boolean().optional()
|
|
155
|
+
}), OAuthMetadataSchema = looseObject({
|
|
156
|
+
issuer: string(),
|
|
157
|
+
authorization_endpoint: SafeUrlSchema,
|
|
158
|
+
token_endpoint: SafeUrlSchema,
|
|
159
|
+
registration_endpoint: SafeUrlSchema.optional(),
|
|
160
|
+
scopes_supported: array(string()).optional(),
|
|
161
|
+
response_types_supported: array(string()),
|
|
162
|
+
response_modes_supported: array(string()).optional(),
|
|
163
|
+
grant_types_supported: array(string()).optional(),
|
|
164
|
+
token_endpoint_auth_methods_supported: array(string()).optional(),
|
|
165
|
+
token_endpoint_auth_signing_alg_values_supported: array(string()).optional(),
|
|
166
|
+
service_documentation: SafeUrlSchema.optional(),
|
|
167
|
+
revocation_endpoint: SafeUrlSchema.optional(),
|
|
168
|
+
revocation_endpoint_auth_methods_supported: array(string()).optional(),
|
|
169
|
+
revocation_endpoint_auth_signing_alg_values_supported: array(string()).optional(),
|
|
170
|
+
introspection_endpoint: string().optional(),
|
|
171
|
+
introspection_endpoint_auth_methods_supported: array(string()).optional(),
|
|
172
|
+
introspection_endpoint_auth_signing_alg_values_supported: array(string()).optional(),
|
|
173
|
+
code_challenge_methods_supported: array(string()).optional(),
|
|
174
|
+
client_id_metadata_document_supported: boolean().optional()
|
|
175
|
+
}), OpenIdProviderMetadataSchema = looseObject({
|
|
176
|
+
issuer: string(),
|
|
177
|
+
authorization_endpoint: SafeUrlSchema,
|
|
178
|
+
token_endpoint: SafeUrlSchema,
|
|
179
|
+
userinfo_endpoint: SafeUrlSchema.optional(),
|
|
180
|
+
jwks_uri: SafeUrlSchema,
|
|
181
|
+
registration_endpoint: SafeUrlSchema.optional(),
|
|
182
|
+
scopes_supported: array(string()).optional(),
|
|
183
|
+
response_types_supported: array(string()),
|
|
184
|
+
response_modes_supported: array(string()).optional(),
|
|
185
|
+
grant_types_supported: array(string()).optional(),
|
|
186
|
+
acr_values_supported: array(string()).optional(),
|
|
187
|
+
subject_types_supported: array(string()),
|
|
188
|
+
id_token_signing_alg_values_supported: array(string()),
|
|
189
|
+
id_token_encryption_alg_values_supported: array(string()).optional(),
|
|
190
|
+
id_token_encryption_enc_values_supported: array(string()).optional(),
|
|
191
|
+
userinfo_signing_alg_values_supported: array(string()).optional(),
|
|
192
|
+
userinfo_encryption_alg_values_supported: array(string()).optional(),
|
|
193
|
+
userinfo_encryption_enc_values_supported: array(string()).optional(),
|
|
194
|
+
request_object_signing_alg_values_supported: array(string()).optional(),
|
|
195
|
+
request_object_encryption_alg_values_supported: array(string()).optional(),
|
|
196
|
+
request_object_encryption_enc_values_supported: array(string()).optional(),
|
|
197
|
+
token_endpoint_auth_methods_supported: array(string()).optional(),
|
|
198
|
+
token_endpoint_auth_signing_alg_values_supported: array(string()).optional(),
|
|
199
|
+
display_values_supported: array(string()).optional(),
|
|
200
|
+
claim_types_supported: array(string()).optional(),
|
|
201
|
+
claims_supported: array(string()).optional(),
|
|
202
|
+
service_documentation: string().optional(),
|
|
203
|
+
claims_locales_supported: array(string()).optional(),
|
|
204
|
+
ui_locales_supported: array(string()).optional(),
|
|
205
|
+
claims_parameter_supported: boolean().optional(),
|
|
206
|
+
request_parameter_supported: boolean().optional(),
|
|
207
|
+
request_uri_parameter_supported: boolean().optional(),
|
|
208
|
+
require_request_uri_registration: boolean().optional(),
|
|
209
|
+
op_policy_uri: SafeUrlSchema.optional(),
|
|
210
|
+
op_tos_uri: SafeUrlSchema.optional(),
|
|
211
|
+
client_id_metadata_document_supported: boolean().optional()
|
|
212
|
+
}), OpenIdProviderDiscoveryMetadataSchema = object({
|
|
213
|
+
...OpenIdProviderMetadataSchema.shape,
|
|
214
|
+
...OAuthMetadataSchema.pick({
|
|
215
|
+
code_challenge_methods_supported: !0
|
|
216
|
+
}).shape
|
|
217
|
+
}), OAuthTokensSchema = object({
|
|
218
|
+
access_token: string(),
|
|
219
|
+
id_token: string().optional(),
|
|
220
|
+
// Optional for OAuth 2.1, but necessary in OpenID Connect
|
|
221
|
+
token_type: string(),
|
|
222
|
+
expires_in: coerce_exports.number().optional(),
|
|
223
|
+
scope: string().optional(),
|
|
224
|
+
refresh_token: string().optional()
|
|
225
|
+
}).strip(), OAuthErrorResponseSchema = object({
|
|
226
|
+
error: string(),
|
|
227
|
+
error_description: string().optional(),
|
|
228
|
+
error_uri: string().optional()
|
|
229
|
+
}), OptionalSafeUrlSchema = SafeUrlSchema.optional().or(literal("").transform(() => {
|
|
230
|
+
})), OAuthClientMetadataSchema = object({
|
|
231
|
+
redirect_uris: array(SafeUrlSchema),
|
|
232
|
+
token_endpoint_auth_method: string().optional(),
|
|
233
|
+
grant_types: array(string()).optional(),
|
|
234
|
+
response_types: array(string()).optional(),
|
|
235
|
+
client_name: string().optional(),
|
|
236
|
+
client_uri: SafeUrlSchema.optional(),
|
|
237
|
+
logo_uri: OptionalSafeUrlSchema,
|
|
238
|
+
scope: string().optional(),
|
|
239
|
+
contacts: array(string()).optional(),
|
|
240
|
+
tos_uri: OptionalSafeUrlSchema,
|
|
241
|
+
policy_uri: string().optional(),
|
|
242
|
+
jwks_uri: SafeUrlSchema.optional(),
|
|
243
|
+
jwks: any().optional(),
|
|
244
|
+
software_id: string().optional(),
|
|
245
|
+
software_version: string().optional(),
|
|
246
|
+
software_statement: string().optional()
|
|
247
|
+
}).strip(), OAuthClientInformationSchema = object({
|
|
248
|
+
client_id: string(),
|
|
249
|
+
client_secret: string().optional(),
|
|
250
|
+
client_id_issued_at: number().optional(),
|
|
251
|
+
client_secret_expires_at: number().optional()
|
|
252
|
+
}).strip(), OAuthClientInformationFullSchema = OAuthClientMetadataSchema.merge(OAuthClientInformationSchema), OAuthClientRegistrationErrorSchema = object({
|
|
253
|
+
error: string(),
|
|
254
|
+
error_description: string().optional()
|
|
255
|
+
}).strip(), OAuthTokenRevocationRequestSchema = object({
|
|
256
|
+
token: string(),
|
|
257
|
+
token_type_hint: string().optional()
|
|
258
|
+
}).strip();
|
|
259
|
+
|
|
260
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/shared/auth-utils.js
|
|
261
|
+
function resourceUrlFromServerUrl(url2) {
|
|
262
|
+
let resourceURL = typeof url2 == "string" ? new URL(url2) : new URL(url2.href);
|
|
263
|
+
return resourceURL.hash = "", resourceURL;
|
|
264
|
+
}
|
|
265
|
+
function checkResourceAllowed({ requestedResource, configuredResource }) {
|
|
266
|
+
let requested = typeof requestedResource == "string" ? new URL(requestedResource) : new URL(requestedResource.href), configured = typeof configuredResource == "string" ? new URL(configuredResource) : new URL(configuredResource.href);
|
|
267
|
+
if (requested.origin !== configured.origin || requested.pathname.length < configured.pathname.length)
|
|
268
|
+
return !1;
|
|
269
|
+
let requestedPath = requested.pathname.endsWith("/") ? requested.pathname : requested.pathname + "/", configuredPath = configured.pathname.endsWith("/") ? configured.pathname : configured.pathname + "/";
|
|
270
|
+
return requestedPath.startsWith(configuredPath);
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/server/auth/errors.js
|
|
274
|
+
var OAuthError = class extends Error {
|
|
275
|
+
constructor(message, errorUri) {
|
|
276
|
+
super(message), this.errorUri = errorUri, this.name = this.constructor.name;
|
|
277
|
+
}
|
|
278
|
+
/**
|
|
279
|
+
* Converts the error to a standard OAuth error response object
|
|
280
|
+
*/
|
|
281
|
+
toResponseObject() {
|
|
282
|
+
let response = {
|
|
283
|
+
error: this.errorCode,
|
|
284
|
+
error_description: this.message
|
|
285
|
+
};
|
|
286
|
+
return this.errorUri && (response.error_uri = this.errorUri), response;
|
|
287
|
+
}
|
|
288
|
+
get errorCode() {
|
|
289
|
+
return this.constructor.errorCode;
|
|
290
|
+
}
|
|
291
|
+
}, InvalidRequestError = class extends OAuthError {
|
|
292
|
+
};
|
|
293
|
+
InvalidRequestError.errorCode = "invalid_request";
|
|
294
|
+
var InvalidClientError = class extends OAuthError {
|
|
295
|
+
};
|
|
296
|
+
InvalidClientError.errorCode = "invalid_client";
|
|
297
|
+
var InvalidGrantError = class extends OAuthError {
|
|
298
|
+
};
|
|
299
|
+
InvalidGrantError.errorCode = "invalid_grant";
|
|
300
|
+
var UnauthorizedClientError = class extends OAuthError {
|
|
301
|
+
};
|
|
302
|
+
UnauthorizedClientError.errorCode = "unauthorized_client";
|
|
303
|
+
var UnsupportedGrantTypeError = class extends OAuthError {
|
|
304
|
+
};
|
|
305
|
+
UnsupportedGrantTypeError.errorCode = "unsupported_grant_type";
|
|
306
|
+
var InvalidScopeError = class extends OAuthError {
|
|
307
|
+
};
|
|
308
|
+
InvalidScopeError.errorCode = "invalid_scope";
|
|
309
|
+
var AccessDeniedError = class extends OAuthError {
|
|
310
|
+
};
|
|
311
|
+
AccessDeniedError.errorCode = "access_denied";
|
|
312
|
+
var ServerError = class extends OAuthError {
|
|
313
|
+
};
|
|
314
|
+
ServerError.errorCode = "server_error";
|
|
315
|
+
var TemporarilyUnavailableError = class extends OAuthError {
|
|
316
|
+
};
|
|
317
|
+
TemporarilyUnavailableError.errorCode = "temporarily_unavailable";
|
|
318
|
+
var UnsupportedResponseTypeError = class extends OAuthError {
|
|
319
|
+
};
|
|
320
|
+
UnsupportedResponseTypeError.errorCode = "unsupported_response_type";
|
|
321
|
+
var UnsupportedTokenTypeError = class extends OAuthError {
|
|
322
|
+
};
|
|
323
|
+
UnsupportedTokenTypeError.errorCode = "unsupported_token_type";
|
|
324
|
+
var InvalidTokenError = class extends OAuthError {
|
|
325
|
+
};
|
|
326
|
+
InvalidTokenError.errorCode = "invalid_token";
|
|
327
|
+
var MethodNotAllowedError = class extends OAuthError {
|
|
328
|
+
};
|
|
329
|
+
MethodNotAllowedError.errorCode = "method_not_allowed";
|
|
330
|
+
var TooManyRequestsError = class extends OAuthError {
|
|
331
|
+
};
|
|
332
|
+
TooManyRequestsError.errorCode = "too_many_requests";
|
|
333
|
+
var InvalidClientMetadataError = class extends OAuthError {
|
|
334
|
+
};
|
|
335
|
+
InvalidClientMetadataError.errorCode = "invalid_client_metadata";
|
|
336
|
+
var InsufficientScopeError = class extends OAuthError {
|
|
337
|
+
};
|
|
338
|
+
InsufficientScopeError.errorCode = "insufficient_scope";
|
|
339
|
+
var InvalidTargetError = class extends OAuthError {
|
|
340
|
+
};
|
|
341
|
+
InvalidTargetError.errorCode = "invalid_target";
|
|
342
|
+
var OAUTH_ERRORS = {
|
|
343
|
+
[InvalidRequestError.errorCode]: InvalidRequestError,
|
|
344
|
+
[InvalidClientError.errorCode]: InvalidClientError,
|
|
345
|
+
[InvalidGrantError.errorCode]: InvalidGrantError,
|
|
346
|
+
[UnauthorizedClientError.errorCode]: UnauthorizedClientError,
|
|
347
|
+
[UnsupportedGrantTypeError.errorCode]: UnsupportedGrantTypeError,
|
|
348
|
+
[InvalidScopeError.errorCode]: InvalidScopeError,
|
|
349
|
+
[AccessDeniedError.errorCode]: AccessDeniedError,
|
|
350
|
+
[ServerError.errorCode]: ServerError,
|
|
351
|
+
[TemporarilyUnavailableError.errorCode]: TemporarilyUnavailableError,
|
|
352
|
+
[UnsupportedResponseTypeError.errorCode]: UnsupportedResponseTypeError,
|
|
353
|
+
[UnsupportedTokenTypeError.errorCode]: UnsupportedTokenTypeError,
|
|
354
|
+
[InvalidTokenError.errorCode]: InvalidTokenError,
|
|
355
|
+
[MethodNotAllowedError.errorCode]: MethodNotAllowedError,
|
|
356
|
+
[TooManyRequestsError.errorCode]: TooManyRequestsError,
|
|
357
|
+
[InvalidClientMetadataError.errorCode]: InvalidClientMetadataError,
|
|
358
|
+
[InsufficientScopeError.errorCode]: InsufficientScopeError,
|
|
359
|
+
[InvalidTargetError.errorCode]: InvalidTargetError
|
|
360
|
+
};
|
|
361
|
+
|
|
362
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/client/auth.js
|
|
363
|
+
var UnauthorizedError = class extends Error {
|
|
364
|
+
constructor(message) {
|
|
365
|
+
super(message ?? "Unauthorized");
|
|
366
|
+
}
|
|
367
|
+
};
|
|
368
|
+
function isClientAuthMethod(method) {
|
|
369
|
+
return ["client_secret_basic", "client_secret_post", "none"].includes(method);
|
|
370
|
+
}
|
|
371
|
+
var AUTHORIZATION_CODE_RESPONSE_TYPE = "code", AUTHORIZATION_CODE_CHALLENGE_METHOD = "S256";
|
|
372
|
+
function selectClientAuthMethod(clientInformation, supportedMethods) {
|
|
373
|
+
let hasClientSecret = clientInformation.client_secret !== void 0;
|
|
374
|
+
return "token_endpoint_auth_method" in clientInformation && clientInformation.token_endpoint_auth_method && isClientAuthMethod(clientInformation.token_endpoint_auth_method) && (supportedMethods.length === 0 || supportedMethods.includes(clientInformation.token_endpoint_auth_method)) ? clientInformation.token_endpoint_auth_method : supportedMethods.length === 0 ? hasClientSecret ? "client_secret_basic" : "none" : hasClientSecret && supportedMethods.includes("client_secret_basic") ? "client_secret_basic" : hasClientSecret && supportedMethods.includes("client_secret_post") ? "client_secret_post" : supportedMethods.includes("none") ? "none" : hasClientSecret ? "client_secret_post" : "none";
|
|
375
|
+
}
|
|
376
|
+
function applyClientAuthentication(method, clientInformation, headers, params) {
|
|
377
|
+
let { client_id, client_secret } = clientInformation;
|
|
378
|
+
switch (method) {
|
|
379
|
+
case "client_secret_basic":
|
|
380
|
+
applyBasicAuth(client_id, client_secret, headers);
|
|
381
|
+
return;
|
|
382
|
+
case "client_secret_post":
|
|
383
|
+
applyPostAuth(client_id, client_secret, params);
|
|
384
|
+
return;
|
|
385
|
+
case "none":
|
|
386
|
+
applyPublicAuth(client_id, params);
|
|
387
|
+
return;
|
|
388
|
+
default:
|
|
389
|
+
throw new Error(`Unsupported client authentication method: ${method}`);
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
function applyBasicAuth(clientId, clientSecret, headers) {
|
|
393
|
+
if (!clientSecret)
|
|
394
|
+
throw new Error("client_secret_basic authentication requires a client_secret");
|
|
395
|
+
let credentials = btoa(`${clientId}:${clientSecret}`);
|
|
396
|
+
headers.set("Authorization", `Basic ${credentials}`);
|
|
397
|
+
}
|
|
398
|
+
function applyPostAuth(clientId, clientSecret, params) {
|
|
399
|
+
params.set("client_id", clientId), clientSecret && params.set("client_secret", clientSecret);
|
|
400
|
+
}
|
|
401
|
+
function applyPublicAuth(clientId, params) {
|
|
402
|
+
params.set("client_id", clientId);
|
|
403
|
+
}
|
|
404
|
+
async function parseErrorResponse(input) {
|
|
405
|
+
let statusCode = input instanceof Response ? input.status : void 0, body = input instanceof Response ? await input.text() : input;
|
|
406
|
+
try {
|
|
407
|
+
let result = OAuthErrorResponseSchema.parse(JSON.parse(body)), { error, error_description, error_uri } = result, errorClass = OAUTH_ERRORS[error] || ServerError;
|
|
408
|
+
return new errorClass(error_description || "", error_uri);
|
|
409
|
+
} catch (error) {
|
|
410
|
+
let errorMessage = `${statusCode ? `HTTP ${statusCode}: ` : ""}Invalid OAuth error response: ${error}. Raw body: ${body}`;
|
|
411
|
+
return new ServerError(errorMessage);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
async function auth(provider, options) {
|
|
415
|
+
try {
|
|
416
|
+
return await authInternal(provider, options);
|
|
417
|
+
} catch (error) {
|
|
418
|
+
if (error instanceof InvalidClientError || error instanceof UnauthorizedClientError)
|
|
419
|
+
return await provider.invalidateCredentials?.("all"), await authInternal(provider, options);
|
|
420
|
+
if (error instanceof InvalidGrantError)
|
|
421
|
+
return await provider.invalidateCredentials?.("tokens"), await authInternal(provider, options);
|
|
422
|
+
throw error;
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
async function authInternal(provider, { serverUrl, authorizationCode, scope, resourceMetadataUrl, fetchFn }) {
|
|
426
|
+
let cachedState = await provider.discoveryState?.(), resourceMetadata, authorizationServerUrl, metadata, effectiveResourceMetadataUrl = resourceMetadataUrl;
|
|
427
|
+
if (!effectiveResourceMetadataUrl && cachedState?.resourceMetadataUrl && (effectiveResourceMetadataUrl = new URL(cachedState.resourceMetadataUrl)), cachedState?.authorizationServerUrl) {
|
|
428
|
+
if (authorizationServerUrl = cachedState.authorizationServerUrl, resourceMetadata = cachedState.resourceMetadata, metadata = cachedState.authorizationServerMetadata ?? await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn }), !resourceMetadata)
|
|
429
|
+
try {
|
|
430
|
+
resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl, { resourceMetadataUrl: effectiveResourceMetadataUrl }, fetchFn);
|
|
431
|
+
} catch {
|
|
432
|
+
}
|
|
433
|
+
(metadata !== cachedState.authorizationServerMetadata || resourceMetadata !== cachedState.resourceMetadata) && await provider.saveDiscoveryState?.({
|
|
434
|
+
authorizationServerUrl: String(authorizationServerUrl),
|
|
435
|
+
resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),
|
|
436
|
+
resourceMetadata,
|
|
437
|
+
authorizationServerMetadata: metadata
|
|
438
|
+
});
|
|
439
|
+
} else {
|
|
440
|
+
let serverInfo = await discoverOAuthServerInfo(serverUrl, { resourceMetadataUrl: effectiveResourceMetadataUrl, fetchFn });
|
|
441
|
+
authorizationServerUrl = serverInfo.authorizationServerUrl, metadata = serverInfo.authorizationServerMetadata, resourceMetadata = serverInfo.resourceMetadata, await provider.saveDiscoveryState?.({
|
|
442
|
+
authorizationServerUrl: String(authorizationServerUrl),
|
|
443
|
+
resourceMetadataUrl: effectiveResourceMetadataUrl?.toString(),
|
|
444
|
+
resourceMetadata,
|
|
445
|
+
authorizationServerMetadata: metadata
|
|
446
|
+
});
|
|
447
|
+
}
|
|
448
|
+
let resource = await selectResourceURL(serverUrl, provider, resourceMetadata), resolvedScope = scope || resourceMetadata?.scopes_supported?.join(" ") || provider.clientMetadata.scope, clientInformation = await Promise.resolve(provider.clientInformation());
|
|
449
|
+
if (!clientInformation) {
|
|
450
|
+
if (authorizationCode !== void 0)
|
|
451
|
+
throw new Error("Existing OAuth client information is required when exchanging an authorization code");
|
|
452
|
+
let supportsUrlBasedClientId = metadata?.client_id_metadata_document_supported === !0, clientMetadataUrl = provider.clientMetadataUrl;
|
|
453
|
+
if (clientMetadataUrl && !isHttpsUrl(clientMetadataUrl))
|
|
454
|
+
throw new InvalidClientMetadataError(`clientMetadataUrl must be a valid HTTPS URL with a non-root pathname, got: ${clientMetadataUrl}`);
|
|
455
|
+
if (supportsUrlBasedClientId && clientMetadataUrl)
|
|
456
|
+
clientInformation = {
|
|
457
|
+
client_id: clientMetadataUrl
|
|
458
|
+
}, await provider.saveClientInformation?.(clientInformation);
|
|
459
|
+
else {
|
|
460
|
+
if (!provider.saveClientInformation)
|
|
461
|
+
throw new Error("OAuth client information must be saveable for dynamic registration");
|
|
462
|
+
let fullInformation = await registerClient(authorizationServerUrl, {
|
|
463
|
+
metadata,
|
|
464
|
+
clientMetadata: provider.clientMetadata,
|
|
465
|
+
scope: resolvedScope,
|
|
466
|
+
fetchFn
|
|
467
|
+
});
|
|
468
|
+
await provider.saveClientInformation(fullInformation), clientInformation = fullInformation;
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
let nonInteractiveFlow = !provider.redirectUrl;
|
|
472
|
+
if (authorizationCode !== void 0 || nonInteractiveFlow) {
|
|
473
|
+
let tokens2 = await fetchToken(provider, authorizationServerUrl, {
|
|
474
|
+
metadata,
|
|
475
|
+
resource,
|
|
476
|
+
authorizationCode,
|
|
477
|
+
fetchFn
|
|
478
|
+
});
|
|
479
|
+
return await provider.saveTokens(tokens2), "AUTHORIZED";
|
|
480
|
+
}
|
|
481
|
+
let tokens = await provider.tokens();
|
|
482
|
+
if (tokens?.refresh_token)
|
|
483
|
+
try {
|
|
484
|
+
let newTokens = await refreshAuthorization(authorizationServerUrl, {
|
|
485
|
+
metadata,
|
|
486
|
+
clientInformation,
|
|
487
|
+
refreshToken: tokens.refresh_token,
|
|
488
|
+
resource,
|
|
489
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
490
|
+
fetchFn
|
|
491
|
+
});
|
|
492
|
+
return await provider.saveTokens(newTokens), "AUTHORIZED";
|
|
493
|
+
} catch (error) {
|
|
494
|
+
if (!(!(error instanceof OAuthError) || error instanceof ServerError))
|
|
495
|
+
throw error;
|
|
496
|
+
}
|
|
497
|
+
let state = provider.state ? await provider.state() : void 0, { authorizationUrl, codeVerifier } = await startAuthorization(authorizationServerUrl, {
|
|
498
|
+
metadata,
|
|
499
|
+
clientInformation,
|
|
500
|
+
state,
|
|
501
|
+
redirectUrl: provider.redirectUrl,
|
|
502
|
+
scope: resolvedScope,
|
|
503
|
+
resource
|
|
504
|
+
});
|
|
505
|
+
return await provider.saveCodeVerifier(codeVerifier), await provider.redirectToAuthorization(authorizationUrl), "REDIRECT";
|
|
506
|
+
}
|
|
507
|
+
function isHttpsUrl(value) {
|
|
508
|
+
if (!value)
|
|
509
|
+
return !1;
|
|
510
|
+
try {
|
|
511
|
+
let url2 = new URL(value);
|
|
512
|
+
return url2.protocol === "https:" && url2.pathname !== "/";
|
|
513
|
+
} catch {
|
|
514
|
+
return !1;
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
async function selectResourceURL(serverUrl, provider, resourceMetadata) {
|
|
518
|
+
let defaultResource = resourceUrlFromServerUrl(serverUrl);
|
|
519
|
+
if (provider.validateResourceURL)
|
|
520
|
+
return await provider.validateResourceURL(defaultResource, resourceMetadata?.resource);
|
|
521
|
+
if (resourceMetadata) {
|
|
522
|
+
if (!checkResourceAllowed({ requestedResource: defaultResource, configuredResource: resourceMetadata.resource }))
|
|
523
|
+
throw new Error(`Protected resource ${resourceMetadata.resource} does not match expected ${defaultResource} (or origin)`);
|
|
524
|
+
return new URL(resourceMetadata.resource);
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
function extractWWWAuthenticateParams(res) {
|
|
528
|
+
let authenticateHeader = res.headers.get("WWW-Authenticate");
|
|
529
|
+
if (!authenticateHeader)
|
|
530
|
+
return {};
|
|
531
|
+
let [type, scheme] = authenticateHeader.split(" ");
|
|
532
|
+
if (type.toLowerCase() !== "bearer" || !scheme)
|
|
533
|
+
return {};
|
|
534
|
+
let resourceMetadataMatch = extractFieldFromWwwAuth(res, "resource_metadata") || void 0, resourceMetadataUrl;
|
|
535
|
+
if (resourceMetadataMatch)
|
|
536
|
+
try {
|
|
537
|
+
resourceMetadataUrl = new URL(resourceMetadataMatch);
|
|
538
|
+
} catch {
|
|
539
|
+
}
|
|
540
|
+
let scope = extractFieldFromWwwAuth(res, "scope") || void 0, error = extractFieldFromWwwAuth(res, "error") || void 0;
|
|
541
|
+
return {
|
|
542
|
+
resourceMetadataUrl,
|
|
543
|
+
scope,
|
|
544
|
+
error
|
|
545
|
+
};
|
|
546
|
+
}
|
|
547
|
+
function extractFieldFromWwwAuth(response, fieldName) {
|
|
548
|
+
let wwwAuthHeader = response.headers.get("WWW-Authenticate");
|
|
549
|
+
if (!wwwAuthHeader)
|
|
550
|
+
return null;
|
|
551
|
+
let pattern = new RegExp(`${fieldName}=(?:"([^"]+)"|([^\\s,]+))`), match = wwwAuthHeader.match(pattern);
|
|
552
|
+
return match ? match[1] || match[2] : null;
|
|
553
|
+
}
|
|
554
|
+
async function discoverOAuthProtectedResourceMetadata(serverUrl, opts, fetchFn = fetch) {
|
|
555
|
+
let response = await discoverMetadataWithFallback(serverUrl, "oauth-protected-resource", fetchFn, {
|
|
556
|
+
protocolVersion: opts?.protocolVersion,
|
|
557
|
+
metadataUrl: opts?.resourceMetadataUrl
|
|
558
|
+
});
|
|
559
|
+
if (!response || response.status === 404)
|
|
560
|
+
throw await response?.body?.cancel(), new Error("Resource server does not implement OAuth 2.0 Protected Resource Metadata.");
|
|
561
|
+
if (!response.ok)
|
|
562
|
+
throw await response.body?.cancel(), new Error(`HTTP ${response.status} trying to load well-known OAuth protected resource metadata.`);
|
|
563
|
+
return OAuthProtectedResourceMetadataSchema.parse(await response.json());
|
|
564
|
+
}
|
|
565
|
+
async function fetchWithCorsRetry(url2, headers, fetchFn = fetch) {
|
|
566
|
+
try {
|
|
567
|
+
return await fetchFn(url2, { headers });
|
|
568
|
+
} catch (error) {
|
|
569
|
+
if (error instanceof TypeError)
|
|
570
|
+
return headers ? fetchWithCorsRetry(url2, void 0, fetchFn) : void 0;
|
|
571
|
+
throw error;
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
function buildWellKnownPath(wellKnownPrefix, pathname = "", options = {}) {
|
|
575
|
+
return pathname.endsWith("/") && (pathname = pathname.slice(0, -1)), options.prependPathname ? `${pathname}/.well-known/${wellKnownPrefix}` : `/.well-known/${wellKnownPrefix}${pathname}`;
|
|
576
|
+
}
|
|
577
|
+
async function tryMetadataDiscovery(url2, protocolVersion, fetchFn = fetch) {
|
|
578
|
+
return await fetchWithCorsRetry(url2, {
|
|
579
|
+
"MCP-Protocol-Version": protocolVersion
|
|
580
|
+
}, fetchFn);
|
|
581
|
+
}
|
|
582
|
+
function shouldAttemptFallback(response, pathname) {
|
|
583
|
+
return !response || response.status >= 400 && response.status < 500 && pathname !== "/";
|
|
584
|
+
}
|
|
585
|
+
async function discoverMetadataWithFallback(serverUrl, wellKnownType, fetchFn, opts) {
|
|
586
|
+
let issuer = new URL(serverUrl), protocolVersion = opts?.protocolVersion ?? LATEST_PROTOCOL_VERSION, url2;
|
|
587
|
+
if (opts?.metadataUrl)
|
|
588
|
+
url2 = new URL(opts.metadataUrl);
|
|
589
|
+
else {
|
|
590
|
+
let wellKnownPath = buildWellKnownPath(wellKnownType, issuer.pathname);
|
|
591
|
+
url2 = new URL(wellKnownPath, opts?.metadataServerUrl ?? issuer), url2.search = issuer.search;
|
|
592
|
+
}
|
|
593
|
+
let response = await tryMetadataDiscovery(url2, protocolVersion, fetchFn);
|
|
594
|
+
if (!opts?.metadataUrl && shouldAttemptFallback(response, issuer.pathname)) {
|
|
595
|
+
let rootUrl = new URL(`/.well-known/${wellKnownType}`, issuer);
|
|
596
|
+
response = await tryMetadataDiscovery(rootUrl, protocolVersion, fetchFn);
|
|
597
|
+
}
|
|
598
|
+
return response;
|
|
599
|
+
}
|
|
600
|
+
function buildDiscoveryUrls(authorizationServerUrl) {
|
|
601
|
+
let url2 = typeof authorizationServerUrl == "string" ? new URL(authorizationServerUrl) : authorizationServerUrl, hasPath = url2.pathname !== "/", urlsToTry = [];
|
|
602
|
+
if (!hasPath)
|
|
603
|
+
return urlsToTry.push({
|
|
604
|
+
url: new URL("/.well-known/oauth-authorization-server", url2.origin),
|
|
605
|
+
type: "oauth"
|
|
606
|
+
}), urlsToTry.push({
|
|
607
|
+
url: new URL("/.well-known/openid-configuration", url2.origin),
|
|
608
|
+
type: "oidc"
|
|
609
|
+
}), urlsToTry;
|
|
610
|
+
let pathname = url2.pathname;
|
|
611
|
+
return pathname.endsWith("/") && (pathname = pathname.slice(0, -1)), urlsToTry.push({
|
|
612
|
+
url: new URL(`/.well-known/oauth-authorization-server${pathname}`, url2.origin),
|
|
613
|
+
type: "oauth"
|
|
614
|
+
}), urlsToTry.push({
|
|
615
|
+
url: new URL(`/.well-known/openid-configuration${pathname}`, url2.origin),
|
|
616
|
+
type: "oidc"
|
|
617
|
+
}), urlsToTry.push({
|
|
618
|
+
url: new URL(`${pathname}/.well-known/openid-configuration`, url2.origin),
|
|
619
|
+
type: "oidc"
|
|
620
|
+
}), urlsToTry;
|
|
621
|
+
}
|
|
622
|
+
async function discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn = fetch, protocolVersion = LATEST_PROTOCOL_VERSION } = {}) {
|
|
623
|
+
let headers = {
|
|
624
|
+
"MCP-Protocol-Version": protocolVersion,
|
|
625
|
+
Accept: "application/json"
|
|
626
|
+
}, urlsToTry = buildDiscoveryUrls(authorizationServerUrl);
|
|
627
|
+
for (let { url: endpointUrl, type } of urlsToTry) {
|
|
628
|
+
let response = await fetchWithCorsRetry(endpointUrl, headers, fetchFn);
|
|
629
|
+
if (response) {
|
|
630
|
+
if (!response.ok) {
|
|
631
|
+
if (await response.body?.cancel(), response.status >= 400 && response.status < 500)
|
|
632
|
+
continue;
|
|
633
|
+
throw new Error(`HTTP ${response.status} trying to load ${type === "oauth" ? "OAuth" : "OpenID provider"} metadata from ${endpointUrl}`);
|
|
634
|
+
}
|
|
635
|
+
return type === "oauth" ? OAuthMetadataSchema.parse(await response.json()) : OpenIdProviderDiscoveryMetadataSchema.parse(await response.json());
|
|
636
|
+
}
|
|
637
|
+
}
|
|
638
|
+
}
|
|
639
|
+
async function discoverOAuthServerInfo(serverUrl, opts) {
|
|
640
|
+
let resourceMetadata, authorizationServerUrl;
|
|
641
|
+
try {
|
|
642
|
+
resourceMetadata = await discoverOAuthProtectedResourceMetadata(serverUrl, { resourceMetadataUrl: opts?.resourceMetadataUrl }, opts?.fetchFn), resourceMetadata.authorization_servers && resourceMetadata.authorization_servers.length > 0 && (authorizationServerUrl = resourceMetadata.authorization_servers[0]);
|
|
643
|
+
} catch {
|
|
644
|
+
}
|
|
645
|
+
authorizationServerUrl || (authorizationServerUrl = String(new URL("/", serverUrl)));
|
|
646
|
+
let authorizationServerMetadata = await discoverAuthorizationServerMetadata(authorizationServerUrl, { fetchFn: opts?.fetchFn });
|
|
647
|
+
return {
|
|
648
|
+
authorizationServerUrl,
|
|
649
|
+
authorizationServerMetadata,
|
|
650
|
+
resourceMetadata
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
async function startAuthorization(authorizationServerUrl, { metadata, clientInformation, redirectUrl, scope, state, resource }) {
|
|
654
|
+
let authorizationUrl;
|
|
655
|
+
if (metadata) {
|
|
656
|
+
if (authorizationUrl = new URL(metadata.authorization_endpoint), !metadata.response_types_supported.includes(AUTHORIZATION_CODE_RESPONSE_TYPE))
|
|
657
|
+
throw new Error(`Incompatible auth server: does not support response type ${AUTHORIZATION_CODE_RESPONSE_TYPE}`);
|
|
658
|
+
if (metadata.code_challenge_methods_supported && !metadata.code_challenge_methods_supported.includes(AUTHORIZATION_CODE_CHALLENGE_METHOD))
|
|
659
|
+
throw new Error(`Incompatible auth server: does not support code challenge method ${AUTHORIZATION_CODE_CHALLENGE_METHOD}`);
|
|
660
|
+
} else
|
|
661
|
+
authorizationUrl = new URL("/authorize", authorizationServerUrl);
|
|
662
|
+
let challenge = await pkceChallenge(), codeVerifier = challenge.code_verifier, codeChallenge = challenge.code_challenge;
|
|
663
|
+
return authorizationUrl.searchParams.set("response_type", AUTHORIZATION_CODE_RESPONSE_TYPE), authorizationUrl.searchParams.set("client_id", clientInformation.client_id), authorizationUrl.searchParams.set("code_challenge", codeChallenge), authorizationUrl.searchParams.set("code_challenge_method", AUTHORIZATION_CODE_CHALLENGE_METHOD), authorizationUrl.searchParams.set("redirect_uri", String(redirectUrl)), state && authorizationUrl.searchParams.set("state", state), scope && authorizationUrl.searchParams.set("scope", scope), scope?.includes("offline_access") && authorizationUrl.searchParams.append("prompt", "consent"), resource && authorizationUrl.searchParams.set("resource", resource.href), { authorizationUrl, codeVerifier };
|
|
664
|
+
}
|
|
665
|
+
function prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, redirectUri) {
|
|
666
|
+
return new URLSearchParams({
|
|
667
|
+
grant_type: "authorization_code",
|
|
668
|
+
code: authorizationCode,
|
|
669
|
+
code_verifier: codeVerifier,
|
|
670
|
+
redirect_uri: String(redirectUri)
|
|
671
|
+
});
|
|
672
|
+
}
|
|
673
|
+
async function executeTokenRequest(authorizationServerUrl, { metadata, tokenRequestParams, clientInformation, addClientAuthentication, resource, fetchFn }) {
|
|
674
|
+
let tokenUrl = metadata?.token_endpoint ? new URL(metadata.token_endpoint) : new URL("/token", authorizationServerUrl), headers = new Headers({
|
|
675
|
+
"Content-Type": "application/x-www-form-urlencoded",
|
|
676
|
+
Accept: "application/json"
|
|
677
|
+
});
|
|
678
|
+
if (resource && tokenRequestParams.set("resource", resource.href), addClientAuthentication)
|
|
679
|
+
await addClientAuthentication(headers, tokenRequestParams, tokenUrl, metadata);
|
|
680
|
+
else if (clientInformation) {
|
|
681
|
+
let supportedMethods = metadata?.token_endpoint_auth_methods_supported ?? [], authMethod = selectClientAuthMethod(clientInformation, supportedMethods);
|
|
682
|
+
applyClientAuthentication(authMethod, clientInformation, headers, tokenRequestParams);
|
|
683
|
+
}
|
|
684
|
+
let response = await (fetchFn ?? fetch)(tokenUrl, {
|
|
685
|
+
method: "POST",
|
|
686
|
+
headers,
|
|
687
|
+
body: tokenRequestParams
|
|
688
|
+
});
|
|
689
|
+
if (!response.ok)
|
|
690
|
+
throw await parseErrorResponse(response);
|
|
691
|
+
return OAuthTokensSchema.parse(await response.json());
|
|
692
|
+
}
|
|
693
|
+
async function refreshAuthorization(authorizationServerUrl, { metadata, clientInformation, refreshToken, resource, addClientAuthentication, fetchFn }) {
|
|
694
|
+
let tokenRequestParams = new URLSearchParams({
|
|
695
|
+
grant_type: "refresh_token",
|
|
696
|
+
refresh_token: refreshToken
|
|
697
|
+
}), tokens = await executeTokenRequest(authorizationServerUrl, {
|
|
698
|
+
metadata,
|
|
699
|
+
tokenRequestParams,
|
|
700
|
+
clientInformation,
|
|
701
|
+
addClientAuthentication,
|
|
702
|
+
resource,
|
|
703
|
+
fetchFn
|
|
704
|
+
});
|
|
705
|
+
return { refresh_token: refreshToken, ...tokens };
|
|
706
|
+
}
|
|
707
|
+
async function fetchToken(provider, authorizationServerUrl, { metadata, resource, authorizationCode, fetchFn } = {}) {
|
|
708
|
+
let scope = provider.clientMetadata.scope, tokenRequestParams;
|
|
709
|
+
if (provider.prepareTokenRequest && (tokenRequestParams = await provider.prepareTokenRequest(scope)), !tokenRequestParams) {
|
|
710
|
+
if (!authorizationCode)
|
|
711
|
+
throw new Error("Either provider.prepareTokenRequest() or authorizationCode is required");
|
|
712
|
+
if (!provider.redirectUrl)
|
|
713
|
+
throw new Error("redirectUrl is required for authorization_code flow");
|
|
714
|
+
let codeVerifier = await provider.codeVerifier();
|
|
715
|
+
tokenRequestParams = prepareAuthorizationCodeRequest(authorizationCode, codeVerifier, provider.redirectUrl);
|
|
716
|
+
}
|
|
717
|
+
let clientInformation = await provider.clientInformation();
|
|
718
|
+
return executeTokenRequest(authorizationServerUrl, {
|
|
719
|
+
metadata,
|
|
720
|
+
tokenRequestParams,
|
|
721
|
+
clientInformation: clientInformation ?? void 0,
|
|
722
|
+
addClientAuthentication: provider.addClientAuthentication,
|
|
723
|
+
resource,
|
|
724
|
+
fetchFn
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
async function registerClient(authorizationServerUrl, { metadata, clientMetadata, scope, fetchFn }) {
|
|
728
|
+
let registrationUrl;
|
|
729
|
+
if (metadata) {
|
|
730
|
+
if (!metadata.registration_endpoint)
|
|
731
|
+
throw new Error("Incompatible auth server: does not support dynamic client registration");
|
|
732
|
+
registrationUrl = new URL(metadata.registration_endpoint);
|
|
733
|
+
} else
|
|
734
|
+
registrationUrl = new URL("/register", authorizationServerUrl);
|
|
735
|
+
let response = await (fetchFn ?? fetch)(registrationUrl, {
|
|
736
|
+
method: "POST",
|
|
737
|
+
headers: {
|
|
738
|
+
"Content-Type": "application/json"
|
|
739
|
+
},
|
|
740
|
+
body: JSON.stringify({
|
|
741
|
+
...clientMetadata,
|
|
742
|
+
...scope !== void 0 ? { scope } : {}
|
|
743
|
+
})
|
|
744
|
+
});
|
|
745
|
+
if (!response.ok)
|
|
746
|
+
throw await parseErrorResponse(response);
|
|
747
|
+
return OAuthClientInformationFullSchema.parse(await response.json());
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/shared/mediaType.js
|
|
751
|
+
var import_content_type = __toESM(require_content_type(), 1);
|
|
752
|
+
function mediaTypeEssence(header) {
|
|
753
|
+
if (header)
|
|
754
|
+
try {
|
|
755
|
+
return import_content_type.default.parse(header).type;
|
|
756
|
+
} catch {
|
|
757
|
+
let essence = (header.split(";", 1)[0] ?? "").trim().toLowerCase();
|
|
758
|
+
return essence === "" || header.slice(essence.length).includes(",") ? void 0 : essence;
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
|
|
762
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/shared/transport.js
|
|
763
|
+
function normalizeHeaders(headers) {
|
|
764
|
+
return headers ? headers instanceof Headers ? Object.fromEntries(headers.entries()) : Array.isArray(headers) ? Object.fromEntries(headers) : { ...headers } : {};
|
|
765
|
+
}
|
|
766
|
+
function createFetchWithInit(baseFetch = fetch, baseInit) {
|
|
767
|
+
return baseInit ? async (url2, init) => {
|
|
768
|
+
let mergedInit = {
|
|
769
|
+
...baseInit,
|
|
770
|
+
...init,
|
|
771
|
+
// Headers need special handling - merge instead of replace
|
|
772
|
+
headers: init?.headers ? { ...normalizeHeaders(baseInit.headers), ...normalizeHeaders(init.headers) } : baseInit.headers
|
|
773
|
+
};
|
|
774
|
+
return baseFetch(url2, mergedInit);
|
|
775
|
+
} : baseFetch;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
// node_modules/eventsource-parser/dist/index.js
|
|
779
|
+
var ParseError = class extends Error {
|
|
780
|
+
constructor(message, options) {
|
|
781
|
+
super(message), this.name = "ParseError", this.type = options.type, this.field = options.field, this.value = options.value, this.line = options.line;
|
|
782
|
+
}
|
|
783
|
+
}, LF = 10, CR = 13, SPACE = 32;
|
|
784
|
+
function noop(_arg) {
|
|
785
|
+
}
|
|
786
|
+
function createParser(config) {
|
|
787
|
+
if (typeof config == "function")
|
|
788
|
+
throw new TypeError(
|
|
789
|
+
"`config` must be an object, got a function instead. Did you mean `createParser({onEvent: fn})`?"
|
|
790
|
+
);
|
|
791
|
+
let { onEvent = noop, onError = noop, onRetry = noop, onComment, maxBufferSize } = config, pendingFragments = [], pendingFragmentsLength = 0, isFirstChunk = !0, id, data = "", dataLines = 0, eventType, terminated = !1;
|
|
792
|
+
function feed(chunk) {
|
|
793
|
+
if (terminated)
|
|
794
|
+
throw new Error(
|
|
795
|
+
"Cannot feed parser: it was terminated after exceeding the configured max buffer size. Call `reset()` to resume parsing."
|
|
796
|
+
);
|
|
797
|
+
if (isFirstChunk && (isFirstChunk = !1, chunk.charCodeAt(0) === 239 && chunk.charCodeAt(1) === 187 && chunk.charCodeAt(2) === 191 && (chunk = chunk.slice(3))), pendingFragments.length === 0) {
|
|
798
|
+
let trailing2 = processLines(chunk);
|
|
799
|
+
trailing2 !== "" && (pendingFragments.push(trailing2), pendingFragmentsLength = trailing2.length), checkBufferSize();
|
|
800
|
+
return;
|
|
801
|
+
}
|
|
802
|
+
if (chunk.indexOf(`
|
|
803
|
+
`) === -1 && chunk.indexOf("\r") === -1) {
|
|
804
|
+
pendingFragments.push(chunk), pendingFragmentsLength += chunk.length, checkBufferSize();
|
|
805
|
+
return;
|
|
806
|
+
}
|
|
807
|
+
pendingFragments.push(chunk);
|
|
808
|
+
let input = pendingFragments.join("");
|
|
809
|
+
pendingFragments.length = 0, pendingFragmentsLength = 0;
|
|
810
|
+
let trailing = processLines(input);
|
|
811
|
+
trailing !== "" && (pendingFragments.push(trailing), pendingFragmentsLength = trailing.length), checkBufferSize();
|
|
812
|
+
}
|
|
813
|
+
function checkBufferSize() {
|
|
814
|
+
maxBufferSize !== void 0 && (pendingFragmentsLength + data.length <= maxBufferSize || (terminated = !0, pendingFragments.length = 0, pendingFragmentsLength = 0, id = void 0, data = "", dataLines = 0, eventType = void 0, onError(
|
|
815
|
+
new ParseError(`Buffered data exceeded max buffer size of ${maxBufferSize} characters`, {
|
|
816
|
+
type: "max-buffer-size-exceeded"
|
|
817
|
+
})
|
|
818
|
+
)));
|
|
819
|
+
}
|
|
820
|
+
function processLines(chunk) {
|
|
821
|
+
let searchIndex = 0;
|
|
822
|
+
if (chunk.indexOf("\r") === -1) {
|
|
823
|
+
let lfIndex = chunk.indexOf(`
|
|
824
|
+
`, searchIndex);
|
|
825
|
+
for (; lfIndex !== -1; ) {
|
|
826
|
+
if (searchIndex === lfIndex) {
|
|
827
|
+
dataLines > 0 && onEvent({ id, event: eventType, data }), id = void 0, data = "", dataLines = 0, eventType = void 0, searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
828
|
+
`, searchIndex);
|
|
829
|
+
continue;
|
|
830
|
+
}
|
|
831
|
+
let firstCharCode = chunk.charCodeAt(searchIndex);
|
|
832
|
+
if (isDataPrefix(chunk, searchIndex, firstCharCode)) {
|
|
833
|
+
let valueStart = chunk.charCodeAt(searchIndex + 5) === SPACE ? searchIndex + 6 : searchIndex + 5, value = chunk.slice(valueStart, lfIndex);
|
|
834
|
+
if (dataLines === 0 && chunk.charCodeAt(lfIndex + 1) === LF) {
|
|
835
|
+
onEvent({ id, event: eventType, data: value }), id = void 0, data = "", eventType = void 0, searchIndex = lfIndex + 2, lfIndex = chunk.indexOf(`
|
|
836
|
+
`, searchIndex);
|
|
837
|
+
continue;
|
|
838
|
+
}
|
|
839
|
+
data = dataLines === 0 ? value : `${data}
|
|
840
|
+
${value}`, dataLines++;
|
|
841
|
+
} else isEventPrefix(chunk, searchIndex, firstCharCode) ? eventType = chunk.slice(
|
|
842
|
+
chunk.charCodeAt(searchIndex + 6) === SPACE ? searchIndex + 7 : searchIndex + 6,
|
|
843
|
+
lfIndex
|
|
844
|
+
) || void 0 : parseLine(chunk, searchIndex, lfIndex);
|
|
845
|
+
searchIndex = lfIndex + 1, lfIndex = chunk.indexOf(`
|
|
846
|
+
`, searchIndex);
|
|
847
|
+
}
|
|
848
|
+
return chunk.slice(searchIndex);
|
|
849
|
+
}
|
|
850
|
+
for (; searchIndex < chunk.length; ) {
|
|
851
|
+
let crIndex = chunk.indexOf("\r", searchIndex), lfIndex = chunk.indexOf(`
|
|
852
|
+
`, searchIndex), lineEnd = -1;
|
|
853
|
+
if (crIndex !== -1 && lfIndex !== -1 ? lineEnd = crIndex < lfIndex ? crIndex : lfIndex : crIndex !== -1 ? crIndex === chunk.length - 1 ? lineEnd = -1 : lineEnd = crIndex : lfIndex !== -1 && (lineEnd = lfIndex), lineEnd === -1)
|
|
854
|
+
break;
|
|
855
|
+
parseLine(chunk, searchIndex, lineEnd), searchIndex = lineEnd + 1, chunk.charCodeAt(searchIndex - 1) === CR && chunk.charCodeAt(searchIndex) === LF && searchIndex++;
|
|
856
|
+
}
|
|
857
|
+
return chunk.slice(searchIndex);
|
|
858
|
+
}
|
|
859
|
+
function parseLine(chunk, start, end) {
|
|
860
|
+
if (start === end) {
|
|
861
|
+
dispatchEvent();
|
|
862
|
+
return;
|
|
863
|
+
}
|
|
864
|
+
let firstCharCode = chunk.charCodeAt(start);
|
|
865
|
+
if (isDataPrefix(chunk, start, firstCharCode)) {
|
|
866
|
+
let valueStart = chunk.charCodeAt(start + 5) === SPACE ? start + 6 : start + 5, value2 = chunk.slice(valueStart, end);
|
|
867
|
+
data = dataLines === 0 ? value2 : `${data}
|
|
868
|
+
${value2}`, dataLines++;
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
if (isEventPrefix(chunk, start, firstCharCode)) {
|
|
872
|
+
eventType = chunk.slice(chunk.charCodeAt(start + 6) === SPACE ? start + 7 : start + 6, end) || void 0;
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
if (firstCharCode === 105 && chunk.charCodeAt(start + 1) === 100 && chunk.charCodeAt(start + 2) === 58) {
|
|
876
|
+
let value2 = chunk.slice(chunk.charCodeAt(start + 3) === SPACE ? start + 4 : start + 3, end);
|
|
877
|
+
id = value2.includes("\0") ? void 0 : value2;
|
|
878
|
+
return;
|
|
879
|
+
}
|
|
880
|
+
if (firstCharCode === 58) {
|
|
881
|
+
if (onComment) {
|
|
882
|
+
let line2 = chunk.slice(start, end);
|
|
883
|
+
onComment(line2.slice(chunk.charCodeAt(start + 1) === SPACE ? 2 : 1));
|
|
884
|
+
}
|
|
885
|
+
return;
|
|
886
|
+
}
|
|
887
|
+
let line = chunk.slice(start, end), fieldSeparatorIndex = line.indexOf(":");
|
|
888
|
+
if (fieldSeparatorIndex === -1) {
|
|
889
|
+
processField(line, "", line);
|
|
890
|
+
return;
|
|
891
|
+
}
|
|
892
|
+
let field = line.slice(0, fieldSeparatorIndex), offset = line.charCodeAt(fieldSeparatorIndex + 1) === SPACE ? 2 : 1, value = line.slice(fieldSeparatorIndex + offset);
|
|
893
|
+
processField(field, value, line);
|
|
894
|
+
}
|
|
895
|
+
function processField(field, value, line) {
|
|
896
|
+
switch (field) {
|
|
897
|
+
case "event":
|
|
898
|
+
eventType = value || void 0;
|
|
899
|
+
break;
|
|
900
|
+
case "data":
|
|
901
|
+
data = dataLines === 0 ? value : `${data}
|
|
902
|
+
${value}`, dataLines++;
|
|
903
|
+
break;
|
|
904
|
+
case "id":
|
|
905
|
+
id = value.includes("\0") ? void 0 : value;
|
|
906
|
+
break;
|
|
907
|
+
case "retry":
|
|
908
|
+
/^\d+$/.test(value) ? onRetry(parseInt(value, 10)) : onError(
|
|
909
|
+
new ParseError(`Invalid \`retry\` value: "${value}"`, {
|
|
910
|
+
type: "invalid-retry",
|
|
911
|
+
value,
|
|
912
|
+
line
|
|
913
|
+
})
|
|
914
|
+
);
|
|
915
|
+
break;
|
|
916
|
+
default:
|
|
917
|
+
onError(
|
|
918
|
+
new ParseError(
|
|
919
|
+
`Unknown field "${field.length > 20 ? `${field.slice(0, 20)}\u2026` : field}"`,
|
|
920
|
+
{ type: "unknown-field", field, value, line }
|
|
921
|
+
)
|
|
922
|
+
);
|
|
923
|
+
break;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
function dispatchEvent() {
|
|
927
|
+
dataLines > 0 && onEvent({
|
|
928
|
+
id,
|
|
929
|
+
event: eventType,
|
|
930
|
+
data
|
|
931
|
+
}), id = void 0, data = "", dataLines = 0, eventType = void 0;
|
|
932
|
+
}
|
|
933
|
+
function reset(options = {}) {
|
|
934
|
+
if (options.consume && pendingFragments.length > 0) {
|
|
935
|
+
let incompleteLine = pendingFragments.join("");
|
|
936
|
+
parseLine(incompleteLine, 0, incompleteLine.length);
|
|
937
|
+
}
|
|
938
|
+
isFirstChunk = !0, id = void 0, data = "", dataLines = 0, eventType = void 0, pendingFragments.length = 0, pendingFragmentsLength = 0, terminated = !1;
|
|
939
|
+
}
|
|
940
|
+
return { feed, reset };
|
|
941
|
+
}
|
|
942
|
+
function isDataPrefix(chunk, i, firstCharCode) {
|
|
943
|
+
return firstCharCode === 100 && chunk.charCodeAt(i + 1) === 97 && chunk.charCodeAt(i + 2) === 116 && chunk.charCodeAt(i + 3) === 97 && chunk.charCodeAt(i + 4) === 58;
|
|
944
|
+
}
|
|
945
|
+
function isEventPrefix(chunk, i, firstCharCode) {
|
|
946
|
+
return firstCharCode === 101 && chunk.charCodeAt(i + 1) === 118 && chunk.charCodeAt(i + 2) === 101 && chunk.charCodeAt(i + 3) === 110 && chunk.charCodeAt(i + 4) === 116 && chunk.charCodeAt(i + 5) === 58;
|
|
947
|
+
}
|
|
948
|
+
|
|
949
|
+
// node_modules/eventsource-parser/dist/stream.js
|
|
950
|
+
var EventSourceParserStream = class extends TransformStream {
|
|
951
|
+
constructor({ onError, onRetry, onComment, maxBufferSize } = {}) {
|
|
952
|
+
let parser;
|
|
953
|
+
super({
|
|
954
|
+
start(controller) {
|
|
955
|
+
parser = createParser({
|
|
956
|
+
onEvent: (event) => {
|
|
957
|
+
controller.enqueue(event);
|
|
958
|
+
},
|
|
959
|
+
onError(error) {
|
|
960
|
+
typeof onError == "function" && onError(error), (onError === "terminate" || error.type === "max-buffer-size-exceeded") && controller.error(error);
|
|
961
|
+
},
|
|
962
|
+
onRetry,
|
|
963
|
+
onComment,
|
|
964
|
+
maxBufferSize
|
|
965
|
+
});
|
|
966
|
+
},
|
|
967
|
+
transform(chunk) {
|
|
968
|
+
parser.feed(chunk);
|
|
969
|
+
}
|
|
970
|
+
});
|
|
971
|
+
}
|
|
972
|
+
};
|
|
973
|
+
|
|
974
|
+
// node_modules/@modelcontextprotocol/sdk/dist/esm/client/streamableHttp.js
|
|
975
|
+
var DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS = {
|
|
976
|
+
initialReconnectionDelay: 1e3,
|
|
977
|
+
maxReconnectionDelay: 3e4,
|
|
978
|
+
reconnectionDelayGrowFactor: 1.5,
|
|
979
|
+
maxRetries: 2
|
|
980
|
+
}, StreamableHTTPError = class extends Error {
|
|
981
|
+
constructor(code, message) {
|
|
982
|
+
super(`Streamable HTTP error: ${message}`), this.code = code;
|
|
983
|
+
}
|
|
984
|
+
}, StreamableHTTPClientTransport = class {
|
|
985
|
+
constructor(url2, opts) {
|
|
986
|
+
this._hasCompletedAuthFlow = !1, this._url = url2, this._resourceMetadataUrl = void 0, this._scope = void 0, this._requestInit = opts?.requestInit, this._authProvider = opts?.authProvider, this._fetch = opts?.fetch, this._fetchWithInit = createFetchWithInit(opts?.fetch, opts?.requestInit), this._sessionId = opts?.sessionId, this._reconnectionOptions = opts?.reconnectionOptions ?? DEFAULT_STREAMABLE_HTTP_RECONNECTION_OPTIONS;
|
|
987
|
+
}
|
|
988
|
+
async _authThenStart() {
|
|
989
|
+
if (!this._authProvider)
|
|
990
|
+
throw new UnauthorizedError("No auth provider");
|
|
991
|
+
let result;
|
|
992
|
+
try {
|
|
993
|
+
result = await auth(this._authProvider, {
|
|
994
|
+
serverUrl: this._url,
|
|
995
|
+
resourceMetadataUrl: this._resourceMetadataUrl,
|
|
996
|
+
scope: this._scope,
|
|
997
|
+
fetchFn: this._fetchWithInit
|
|
998
|
+
});
|
|
999
|
+
} catch (error) {
|
|
1000
|
+
throw this.onerror?.(error), error;
|
|
1001
|
+
}
|
|
1002
|
+
if (result !== "AUTHORIZED")
|
|
1003
|
+
throw new UnauthorizedError();
|
|
1004
|
+
return await this._startOrAuthSse({ resumptionToken: void 0 });
|
|
1005
|
+
}
|
|
1006
|
+
async _commonHeaders() {
|
|
1007
|
+
let headers = {};
|
|
1008
|
+
if (this._authProvider) {
|
|
1009
|
+
let tokens = await this._authProvider.tokens();
|
|
1010
|
+
tokens && (headers.Authorization = `Bearer ${tokens.access_token}`);
|
|
1011
|
+
}
|
|
1012
|
+
this._sessionId && (headers["mcp-session-id"] = this._sessionId), this._protocolVersion && (headers["mcp-protocol-version"] = this._protocolVersion);
|
|
1013
|
+
let extraHeaders = normalizeHeaders(this._requestInit?.headers);
|
|
1014
|
+
return new Headers({
|
|
1015
|
+
...headers,
|
|
1016
|
+
...extraHeaders
|
|
1017
|
+
});
|
|
1018
|
+
}
|
|
1019
|
+
async _startOrAuthSse(options) {
|
|
1020
|
+
let { resumptionToken } = options;
|
|
1021
|
+
try {
|
|
1022
|
+
let headers = await this._commonHeaders();
|
|
1023
|
+
headers.set("Accept", "text/event-stream"), resumptionToken && headers.set("last-event-id", resumptionToken);
|
|
1024
|
+
let response = await (this._fetch ?? fetch)(this._url, {
|
|
1025
|
+
method: "GET",
|
|
1026
|
+
headers,
|
|
1027
|
+
signal: this._abortController?.signal
|
|
1028
|
+
});
|
|
1029
|
+
if (!response.ok) {
|
|
1030
|
+
if (await response.body?.cancel(), response.status === 401 && this._authProvider)
|
|
1031
|
+
return await this._authThenStart();
|
|
1032
|
+
if (response.status === 405)
|
|
1033
|
+
return;
|
|
1034
|
+
throw new StreamableHTTPError(response.status, `Failed to open SSE stream: ${response.statusText}`);
|
|
1035
|
+
}
|
|
1036
|
+
this._handleSseStream(response.body, options, !0);
|
|
1037
|
+
} catch (error) {
|
|
1038
|
+
throw this.onerror?.(error), error;
|
|
1039
|
+
}
|
|
1040
|
+
}
|
|
1041
|
+
/**
|
|
1042
|
+
* Calculates the next reconnection delay using backoff algorithm
|
|
1043
|
+
*
|
|
1044
|
+
* @param attempt Current reconnection attempt count for the specific stream
|
|
1045
|
+
* @returns Time to wait in milliseconds before next reconnection attempt
|
|
1046
|
+
*/
|
|
1047
|
+
_getNextReconnectionDelay(attempt) {
|
|
1048
|
+
if (this._serverRetryMs !== void 0)
|
|
1049
|
+
return this._serverRetryMs;
|
|
1050
|
+
let initialDelay = this._reconnectionOptions.initialReconnectionDelay, growFactor = this._reconnectionOptions.reconnectionDelayGrowFactor, maxDelay = this._reconnectionOptions.maxReconnectionDelay;
|
|
1051
|
+
return Math.min(initialDelay * Math.pow(growFactor, attempt), maxDelay);
|
|
1052
|
+
}
|
|
1053
|
+
/**
|
|
1054
|
+
* Schedule a reconnection attempt using server-provided retry interval or backoff
|
|
1055
|
+
*
|
|
1056
|
+
* @param lastEventId The ID of the last received event for resumability
|
|
1057
|
+
* @param attemptCount Current reconnection attempt count for this specific stream
|
|
1058
|
+
*/
|
|
1059
|
+
_scheduleReconnection(options, attemptCount = 0) {
|
|
1060
|
+
let maxRetries = this._reconnectionOptions.maxRetries;
|
|
1061
|
+
if (attemptCount >= maxRetries) {
|
|
1062
|
+
this.onerror?.(new Error(`Maximum reconnection attempts (${maxRetries}) exceeded.`));
|
|
1063
|
+
return;
|
|
1064
|
+
}
|
|
1065
|
+
let delay = this._getNextReconnectionDelay(attemptCount);
|
|
1066
|
+
this._reconnectionTimeout = setTimeout(() => {
|
|
1067
|
+
this._startOrAuthSse(options).catch((error) => {
|
|
1068
|
+
this.onerror?.(new Error(`Failed to reconnect SSE stream: ${error instanceof Error ? error.message : String(error)}`)), this._scheduleReconnection(options, attemptCount + 1);
|
|
1069
|
+
});
|
|
1070
|
+
}, delay);
|
|
1071
|
+
}
|
|
1072
|
+
_handleSseStream(stream, options, isReconnectable) {
|
|
1073
|
+
if (!stream)
|
|
1074
|
+
return;
|
|
1075
|
+
let { onresumptiontoken, replayMessageId } = options, lastEventId, hasPrimingEvent = !1, receivedResponse = !1;
|
|
1076
|
+
(async () => {
|
|
1077
|
+
try {
|
|
1078
|
+
let reader = stream.pipeThrough(new TextDecoderStream()).pipeThrough(new EventSourceParserStream({
|
|
1079
|
+
onRetry: (retryMs) => {
|
|
1080
|
+
this._serverRetryMs = retryMs;
|
|
1081
|
+
}
|
|
1082
|
+
})).getReader();
|
|
1083
|
+
for (; ; ) {
|
|
1084
|
+
let { value: event, done } = await reader.read();
|
|
1085
|
+
if (done)
|
|
1086
|
+
break;
|
|
1087
|
+
if (event.id && (lastEventId = event.id, hasPrimingEvent = !0, onresumptiontoken?.(event.id)), !!event.data && (!event.event || event.event === "message"))
|
|
1088
|
+
try {
|
|
1089
|
+
let message = JSONRPCMessageSchema.parse(JSON.parse(event.data));
|
|
1090
|
+
isJSONRPCResultResponse(message) && (receivedResponse = !0, replayMessageId !== void 0 && (message.id = replayMessageId)), this.onmessage?.(message);
|
|
1091
|
+
} catch (error) {
|
|
1092
|
+
this.onerror?.(error);
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
(isReconnectable || hasPrimingEvent) && !receivedResponse && this._abortController && !this._abortController.signal.aborted && this._scheduleReconnection({
|
|
1096
|
+
resumptionToken: lastEventId,
|
|
1097
|
+
onresumptiontoken,
|
|
1098
|
+
replayMessageId
|
|
1099
|
+
}, 0);
|
|
1100
|
+
} catch (error) {
|
|
1101
|
+
if (this.onerror?.(new Error(`SSE stream disconnected: ${error}`)), (isReconnectable || hasPrimingEvent) && !receivedResponse && this._abortController && !this._abortController.signal.aborted)
|
|
1102
|
+
try {
|
|
1103
|
+
this._scheduleReconnection({
|
|
1104
|
+
resumptionToken: lastEventId,
|
|
1105
|
+
onresumptiontoken,
|
|
1106
|
+
replayMessageId
|
|
1107
|
+
}, 0);
|
|
1108
|
+
} catch (error2) {
|
|
1109
|
+
this.onerror?.(new Error(`Failed to reconnect: ${error2 instanceof Error ? error2.message : String(error2)}`));
|
|
1110
|
+
}
|
|
1111
|
+
}
|
|
1112
|
+
})();
|
|
1113
|
+
}
|
|
1114
|
+
async start() {
|
|
1115
|
+
if (this._abortController)
|
|
1116
|
+
throw new Error("StreamableHTTPClientTransport already started! If using Client class, note that connect() calls start() automatically.");
|
|
1117
|
+
this._abortController = new AbortController();
|
|
1118
|
+
}
|
|
1119
|
+
/**
|
|
1120
|
+
* 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.
|
|
1121
|
+
*/
|
|
1122
|
+
async finishAuth(authorizationCode) {
|
|
1123
|
+
if (!this._authProvider)
|
|
1124
|
+
throw new UnauthorizedError("No auth provider");
|
|
1125
|
+
if (await auth(this._authProvider, {
|
|
1126
|
+
serverUrl: this._url,
|
|
1127
|
+
authorizationCode,
|
|
1128
|
+
resourceMetadataUrl: this._resourceMetadataUrl,
|
|
1129
|
+
scope: this._scope,
|
|
1130
|
+
fetchFn: this._fetchWithInit
|
|
1131
|
+
}) !== "AUTHORIZED")
|
|
1132
|
+
throw new UnauthorizedError("Failed to authorize");
|
|
1133
|
+
}
|
|
1134
|
+
async close() {
|
|
1135
|
+
this._reconnectionTimeout && (clearTimeout(this._reconnectionTimeout), this._reconnectionTimeout = void 0), this._abortController?.abort(), this.onclose?.();
|
|
1136
|
+
}
|
|
1137
|
+
async send(message, options) {
|
|
1138
|
+
try {
|
|
1139
|
+
let { resumptionToken, onresumptiontoken } = options || {};
|
|
1140
|
+
if (resumptionToken) {
|
|
1141
|
+
this._startOrAuthSse({ resumptionToken, replayMessageId: isJSONRPCRequest(message) ? message.id : void 0 }).catch((err) => this.onerror?.(err));
|
|
1142
|
+
return;
|
|
1143
|
+
}
|
|
1144
|
+
let headers = await this._commonHeaders();
|
|
1145
|
+
headers.set("content-type", "application/json"), headers.set("accept", "application/json, text/event-stream");
|
|
1146
|
+
let init = {
|
|
1147
|
+
...this._requestInit,
|
|
1148
|
+
method: "POST",
|
|
1149
|
+
headers,
|
|
1150
|
+
body: JSON.stringify(message),
|
|
1151
|
+
signal: this._abortController?.signal
|
|
1152
|
+
}, response = await (this._fetch ?? fetch)(this._url, init), sessionId = response.headers.get("mcp-session-id");
|
|
1153
|
+
if (sessionId && (this._sessionId = sessionId), !response.ok) {
|
|
1154
|
+
let text = await response.text().catch(() => null);
|
|
1155
|
+
if (response.status === 401 && this._authProvider) {
|
|
1156
|
+
if (this._hasCompletedAuthFlow)
|
|
1157
|
+
throw new StreamableHTTPError(401, "Server returned 401 after successful authentication");
|
|
1158
|
+
let { resourceMetadataUrl, scope } = extractWWWAuthenticateParams(response);
|
|
1159
|
+
if (this._resourceMetadataUrl = resourceMetadataUrl, this._scope = scope, await auth(this._authProvider, {
|
|
1160
|
+
serverUrl: this._url,
|
|
1161
|
+
resourceMetadataUrl: this._resourceMetadataUrl,
|
|
1162
|
+
scope: this._scope,
|
|
1163
|
+
fetchFn: this._fetchWithInit
|
|
1164
|
+
}) !== "AUTHORIZED")
|
|
1165
|
+
throw new UnauthorizedError();
|
|
1166
|
+
return this._hasCompletedAuthFlow = !0, this.send(message);
|
|
1167
|
+
}
|
|
1168
|
+
if (response.status === 403 && this._authProvider) {
|
|
1169
|
+
let { resourceMetadataUrl, scope, error } = extractWWWAuthenticateParams(response);
|
|
1170
|
+
if (error === "insufficient_scope") {
|
|
1171
|
+
let wwwAuthHeader = response.headers.get("WWW-Authenticate");
|
|
1172
|
+
if (this._lastUpscopingHeader === wwwAuthHeader)
|
|
1173
|
+
throw new StreamableHTTPError(403, "Server returned 403 after trying upscoping");
|
|
1174
|
+
if (scope && (this._scope = scope), resourceMetadataUrl && (this._resourceMetadataUrl = resourceMetadataUrl), this._lastUpscopingHeader = wwwAuthHeader ?? void 0, await auth(this._authProvider, {
|
|
1175
|
+
serverUrl: this._url,
|
|
1176
|
+
resourceMetadataUrl: this._resourceMetadataUrl,
|
|
1177
|
+
scope: this._scope,
|
|
1178
|
+
fetchFn: this._fetch
|
|
1179
|
+
}) !== "AUTHORIZED")
|
|
1180
|
+
throw new UnauthorizedError();
|
|
1181
|
+
return this.send(message);
|
|
1182
|
+
}
|
|
1183
|
+
}
|
|
1184
|
+
throw new StreamableHTTPError(response.status, `Error POSTing to endpoint: ${text}`);
|
|
1185
|
+
}
|
|
1186
|
+
if (this._hasCompletedAuthFlow = !1, this._lastUpscopingHeader = void 0, response.status === 202) {
|
|
1187
|
+
await response.body?.cancel(), isInitializedNotification(message) && this._startOrAuthSse({ resumptionToken: void 0 }).catch((err) => this.onerror?.(err));
|
|
1188
|
+
return;
|
|
1189
|
+
}
|
|
1190
|
+
let hasRequests = (Array.isArray(message) ? message : [message]).filter((msg) => "method" in msg && "id" in msg && msg.id !== void 0).length > 0, contentType2 = response.headers.get("content-type"), responseMediaType = mediaTypeEssence(contentType2);
|
|
1191
|
+
if (hasRequests)
|
|
1192
|
+
if (responseMediaType === "text/event-stream")
|
|
1193
|
+
this._handleSseStream(response.body, { onresumptiontoken }, !1);
|
|
1194
|
+
else if (responseMediaType === "application/json") {
|
|
1195
|
+
let data = await response.json(), responseMessages = Array.isArray(data) ? data.map((msg) => JSONRPCMessageSchema.parse(msg)) : [JSONRPCMessageSchema.parse(data)];
|
|
1196
|
+
for (let msg of responseMessages)
|
|
1197
|
+
this.onmessage?.(msg);
|
|
1198
|
+
} else
|
|
1199
|
+
throw await response.body?.cancel(), new StreamableHTTPError(-1, `Unexpected content type: ${contentType2}`);
|
|
1200
|
+
else
|
|
1201
|
+
await response.body?.cancel();
|
|
1202
|
+
} catch (error) {
|
|
1203
|
+
throw this.onerror?.(error), error;
|
|
1204
|
+
}
|
|
1205
|
+
}
|
|
1206
|
+
get sessionId() {
|
|
1207
|
+
return this._sessionId;
|
|
1208
|
+
}
|
|
1209
|
+
/**
|
|
1210
|
+
* Terminates the current session by sending a DELETE request to the server.
|
|
1211
|
+
*
|
|
1212
|
+
* Clients that no longer need a particular session
|
|
1213
|
+
* (e.g., because the user is leaving the client application) SHOULD send an
|
|
1214
|
+
* HTTP DELETE to the MCP endpoint with the Mcp-Session-Id header to explicitly
|
|
1215
|
+
* terminate the session.
|
|
1216
|
+
*
|
|
1217
|
+
* The server MAY respond with HTTP 405 Method Not Allowed, indicating that
|
|
1218
|
+
* the server does not allow clients to terminate sessions.
|
|
1219
|
+
*/
|
|
1220
|
+
async terminateSession() {
|
|
1221
|
+
if (this._sessionId)
|
|
1222
|
+
try {
|
|
1223
|
+
let headers = await this._commonHeaders(), init = {
|
|
1224
|
+
...this._requestInit,
|
|
1225
|
+
method: "DELETE",
|
|
1226
|
+
headers,
|
|
1227
|
+
signal: this._abortController?.signal
|
|
1228
|
+
}, response = await (this._fetch ?? fetch)(this._url, init);
|
|
1229
|
+
if (await response.body?.cancel(), !response.ok && response.status !== 405)
|
|
1230
|
+
throw new StreamableHTTPError(response.status, `Failed to terminate session: ${response.statusText}`);
|
|
1231
|
+
this._sessionId = void 0;
|
|
1232
|
+
} catch (error) {
|
|
1233
|
+
throw this.onerror?.(error), error;
|
|
1234
|
+
}
|
|
1235
|
+
}
|
|
1236
|
+
setProtocolVersion(version) {
|
|
1237
|
+
this._protocolVersion = version;
|
|
1238
|
+
}
|
|
1239
|
+
get protocolVersion() {
|
|
1240
|
+
return this._protocolVersion;
|
|
1241
|
+
}
|
|
1242
|
+
/**
|
|
1243
|
+
* Resume an SSE stream from a previous event ID.
|
|
1244
|
+
* Opens a GET SSE connection with Last-Event-ID header to replay missed events.
|
|
1245
|
+
*
|
|
1246
|
+
* @param lastEventId The event ID to resume from
|
|
1247
|
+
* @param options Optional callback to receive new resumption tokens
|
|
1248
|
+
*/
|
|
1249
|
+
async resumeStream(lastEventId, options) {
|
|
1250
|
+
await this._startOrAuthSse({
|
|
1251
|
+
resumptionToken: lastEventId,
|
|
1252
|
+
onresumptiontoken: options?.onresumptiontoken
|
|
1253
|
+
});
|
|
1254
|
+
}
|
|
1255
|
+
};
|
|
1256
|
+
|
|
1257
|
+
// packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js
|
|
1258
|
+
import open from "open";
|
|
1259
|
+
|
|
1260
|
+
// packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/mcp-auth.js
|
|
1261
|
+
import { createHash } from "crypto";
|
|
1262
|
+
import { mkdirSync, readFileSync, writeFileSync, existsSync, rmSync } from "fs";
|
|
1263
|
+
import { join } from "path";
|
|
1264
|
+
function getAuthBaseDir() {
|
|
1265
|
+
let override = process.env.MCP_OAUTH_DIR?.trim();
|
|
1266
|
+
return override || getAgentPath("mcp-oauth");
|
|
1267
|
+
}
|
|
1268
|
+
function getServerDir(serverName) {
|
|
1269
|
+
if (typeof serverName != "string")
|
|
1270
|
+
throw new Error(`Invalid MCP server name: ${JSON.stringify(serverName)}`);
|
|
1271
|
+
let storageKey = createHash("sha256").update(serverName, "utf8").digest("hex");
|
|
1272
|
+
return join(getAuthBaseDir(), `sha256-${storageKey}`);
|
|
1273
|
+
}
|
|
1274
|
+
function getAuthEntryFilePath(serverName) {
|
|
1275
|
+
return join(getServerDir(serverName), "tokens.json");
|
|
1276
|
+
}
|
|
1277
|
+
function ensureServerDir(serverName) {
|
|
1278
|
+
let dir = getServerDir(serverName);
|
|
1279
|
+
existsSync(dir) || mkdirSync(dir, { recursive: !0, mode: 448 });
|
|
1280
|
+
}
|
|
1281
|
+
function readAuthEntry(serverName) {
|
|
1282
|
+
let filePath = getAuthEntryFilePath(serverName);
|
|
1283
|
+
try {
|
|
1284
|
+
if (!existsSync(filePath))
|
|
1285
|
+
return;
|
|
1286
|
+
let data = readFileSync(filePath, "utf-8");
|
|
1287
|
+
return JSON.parse(data);
|
|
1288
|
+
} catch (error) {
|
|
1289
|
+
console.error(`Failed to read auth entry for ${serverName}:`, error);
|
|
1290
|
+
return;
|
|
1291
|
+
}
|
|
1292
|
+
}
|
|
1293
|
+
function writeAuthEntry(serverName, entry) {
|
|
1294
|
+
ensureServerDir(serverName);
|
|
1295
|
+
let filePath = getAuthEntryFilePath(serverName);
|
|
1296
|
+
writeFileSync(filePath, JSON.stringify(entry, null, 2), { mode: 384 });
|
|
1297
|
+
}
|
|
1298
|
+
function getAuthEntry(serverName) {
|
|
1299
|
+
return readAuthEntry(serverName);
|
|
1300
|
+
}
|
|
1301
|
+
function getAuthForUrl(serverName, serverUrl) {
|
|
1302
|
+
let entry = getAuthEntry(serverName);
|
|
1303
|
+
if (entry && entry.serverUrl && entry.serverUrl === serverUrl)
|
|
1304
|
+
return entry;
|
|
1305
|
+
}
|
|
1306
|
+
function saveAuthEntry(serverName, entry, serverUrl) {
|
|
1307
|
+
serverUrl && (entry.serverUrl = serverUrl), writeAuthEntry(serverName, entry);
|
|
1308
|
+
}
|
|
1309
|
+
function removeAuthEntry(serverName) {
|
|
1310
|
+
try {
|
|
1311
|
+
let filePath = getAuthEntryFilePath(serverName);
|
|
1312
|
+
existsSync(filePath) && writeFileSync(filePath, "{}", { mode: 384 });
|
|
1313
|
+
let dir = getServerDir(serverName);
|
|
1314
|
+
if (existsSync(dir))
|
|
1315
|
+
try {
|
|
1316
|
+
rmSync(dir, { recursive: !0 });
|
|
1317
|
+
} catch {
|
|
1318
|
+
}
|
|
1319
|
+
} catch (error) {
|
|
1320
|
+
console.error(`Failed to remove auth entry for ${serverName}:`, error);
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
function updateTokens(serverName, tokens, serverUrl) {
|
|
1324
|
+
let entry = getAuthEntry(serverName) ?? {};
|
|
1325
|
+
serverUrl && entry.serverUrl !== serverUrl && (delete entry.clientInfo, delete entry.codeVerifier, delete entry.oauthState), entry.tokens = tokens, saveAuthEntry(serverName, entry, serverUrl);
|
|
1326
|
+
}
|
|
1327
|
+
function updateClientInfo(serverName, clientInfo, serverUrl) {
|
|
1328
|
+
let entry = getAuthEntry(serverName) ?? {};
|
|
1329
|
+
serverUrl && entry.serverUrl !== serverUrl && (delete entry.tokens, delete entry.codeVerifier, delete entry.oauthState), entry.clientInfo = clientInfo, saveAuthEntry(serverName, entry, serverUrl);
|
|
1330
|
+
}
|
|
1331
|
+
function updateCodeVerifier(serverName, codeVerifier, serverUrl) {
|
|
1332
|
+
let entry = getAuthEntry(serverName) ?? {};
|
|
1333
|
+
serverUrl && entry.serverUrl !== serverUrl && (delete entry.tokens, delete entry.clientInfo, delete entry.oauthState), entry.codeVerifier = codeVerifier, saveAuthEntry(serverName, entry, serverUrl);
|
|
1334
|
+
}
|
|
1335
|
+
function clearCodeVerifier(serverName) {
|
|
1336
|
+
let entry = getAuthEntry(serverName);
|
|
1337
|
+
entry && (delete entry.codeVerifier, saveAuthEntry(serverName, entry));
|
|
1338
|
+
}
|
|
1339
|
+
function updateOAuthState(serverName, state, serverUrl) {
|
|
1340
|
+
let entry = getAuthEntry(serverName) ?? {};
|
|
1341
|
+
serverUrl && entry.serverUrl !== serverUrl && (delete entry.tokens, delete entry.clientInfo, delete entry.codeVerifier), entry.oauthState = state, saveAuthEntry(serverName, entry, serverUrl);
|
|
1342
|
+
}
|
|
1343
|
+
function getOAuthState(serverName) {
|
|
1344
|
+
return getAuthEntry(serverName)?.oauthState;
|
|
1345
|
+
}
|
|
1346
|
+
function clearOAuthState(serverName) {
|
|
1347
|
+
let entry = getAuthEntry(serverName);
|
|
1348
|
+
entry && (delete entry.oauthState, saveAuthEntry(serverName, entry));
|
|
1349
|
+
}
|
|
1350
|
+
function isTokenExpired(serverName) {
|
|
1351
|
+
let entry = getAuthEntry(serverName);
|
|
1352
|
+
return entry?.tokens ? entry.tokens.expiresAt ? entry.tokens.expiresAt < Date.now() / 1e3 : !1 : null;
|
|
1353
|
+
}
|
|
1354
|
+
function hasStoredTokens(serverName) {
|
|
1355
|
+
return !!getAuthEntry(serverName)?.tokens;
|
|
1356
|
+
}
|
|
1357
|
+
function clearAllCredentials(serverName) {
|
|
1358
|
+
removeAuthEntry(serverName);
|
|
1359
|
+
}
|
|
1360
|
+
function clearClientInfo(serverName) {
|
|
1361
|
+
let entry = getAuthEntry(serverName);
|
|
1362
|
+
entry && (delete entry.clientInfo, saveAuthEntry(serverName, entry));
|
|
1363
|
+
}
|
|
1364
|
+
function clearTokens(serverName) {
|
|
1365
|
+
let entry = getAuthEntry(serverName);
|
|
1366
|
+
entry && (delete entry.tokens, saveAuthEntry(serverName, entry));
|
|
1367
|
+
}
|
|
1368
|
+
|
|
1369
|
+
// packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/mcp-oauth-provider.js
|
|
1370
|
+
var DEFAULT_OAUTH_CALLBACK_PORT = 19876, DEFAULT_OAUTH_CALLBACK_PATH = "/callback", configuredOAuthCallbackPort = DEFAULT_OAUTH_CALLBACK_PORT;
|
|
1371
|
+
if (process.env.MCP_OAUTH_CALLBACK_PORT) {
|
|
1372
|
+
let parsedPort = Number.parseInt(process.env.MCP_OAUTH_CALLBACK_PORT, 10);
|
|
1373
|
+
Number.isInteger(parsedPort) && parsedPort > 0 && parsedPort <= 65535 && (configuredOAuthCallbackPort = parsedPort);
|
|
1374
|
+
}
|
|
1375
|
+
var oauthCallbackPort = configuredOAuthCallbackPort, oauthCallbackPath = DEFAULT_OAUTH_CALLBACK_PATH;
|
|
1376
|
+
function getConfiguredOAuthCallbackPort() {
|
|
1377
|
+
return configuredOAuthCallbackPort;
|
|
1378
|
+
}
|
|
1379
|
+
function getOAuthCallbackPort() {
|
|
1380
|
+
return oauthCallbackPort;
|
|
1381
|
+
}
|
|
1382
|
+
function setOAuthCallbackPort(port) {
|
|
1383
|
+
oauthCallbackPort = port;
|
|
1384
|
+
}
|
|
1385
|
+
function getOAuthCallbackPath() {
|
|
1386
|
+
return oauthCallbackPath;
|
|
1387
|
+
}
|
|
1388
|
+
function setOAuthCallbackPath(path) {
|
|
1389
|
+
oauthCallbackPath = path.startsWith("/") ? path : `/${path}`;
|
|
1390
|
+
}
|
|
1391
|
+
var McpOAuthProvider = class {
|
|
1392
|
+
serverName;
|
|
1393
|
+
serverUrl;
|
|
1394
|
+
config;
|
|
1395
|
+
callbacks;
|
|
1396
|
+
redirectUrlSnapshot;
|
|
1397
|
+
constructor(serverName, serverUrl, config, callbacks) {
|
|
1398
|
+
this.serverName = serverName, this.serverUrl = serverUrl, this.config = config, this.callbacks = callbacks, this.redirectUrlSnapshot = config.grantType === "client_credentials" ? void 0 : config.redirectUri ?? `http://localhost:${getOAuthCallbackPort()}${getOAuthCallbackPath()}`;
|
|
1399
|
+
}
|
|
1400
|
+
get usesClientCredentials() {
|
|
1401
|
+
return this.config.grantType === "client_credentials";
|
|
1402
|
+
}
|
|
1403
|
+
/**
|
|
1404
|
+
* The redirect URL for OAuth callbacks.
|
|
1405
|
+
* This must match the redirect_uri in client metadata.
|
|
1406
|
+
*/
|
|
1407
|
+
get redirectUrl() {
|
|
1408
|
+
return this.redirectUrlSnapshot;
|
|
1409
|
+
}
|
|
1410
|
+
/**
|
|
1411
|
+
* Client metadata for dynamic registration.
|
|
1412
|
+
* Describes this client to the OAuth authorization server.
|
|
1413
|
+
*/
|
|
1414
|
+
get clientMetadata() {
|
|
1415
|
+
if (this.usesClientCredentials)
|
|
1416
|
+
return {
|
|
1417
|
+
client_name: this.config.clientName ?? "Pi Coding Agent",
|
|
1418
|
+
client_uri: this.config.clientUri ?? "https://github.com/nicobailon/pi-mcp-adapter",
|
|
1419
|
+
redirect_uris: [],
|
|
1420
|
+
grant_types: ["client_credentials"],
|
|
1421
|
+
token_endpoint_auth_method: this.config.clientSecret ? "client_secret_post" : "none"
|
|
1422
|
+
};
|
|
1423
|
+
let redirectUrl = this.redirectUrl;
|
|
1424
|
+
if (!redirectUrl)
|
|
1425
|
+
throw new Error("redirectUrl is required for authorization_code flow");
|
|
1426
|
+
return {
|
|
1427
|
+
redirect_uris: [redirectUrl],
|
|
1428
|
+
client_name: this.config.clientName ?? "Pi Coding Agent",
|
|
1429
|
+
client_uri: this.config.clientUri ?? "https://github.com/nicobailon/pi-mcp-adapter",
|
|
1430
|
+
grant_types: ["authorization_code", "refresh_token"],
|
|
1431
|
+
response_types: ["code"],
|
|
1432
|
+
token_endpoint_auth_method: this.config.clientSecret ? "client_secret_post" : "none",
|
|
1433
|
+
...this.config.scope !== void 0 ? { scope: this.config.scope } : {}
|
|
1434
|
+
};
|
|
1435
|
+
}
|
|
1436
|
+
/**
|
|
1437
|
+
* Get client information (for pre-registered or dynamically registered clients).
|
|
1438
|
+
* Returns undefined if no client info exists or if the server URL has changed.
|
|
1439
|
+
*/
|
|
1440
|
+
async clientInformation() {
|
|
1441
|
+
if (this.config.clientId)
|
|
1442
|
+
return {
|
|
1443
|
+
client_id: this.config.clientId,
|
|
1444
|
+
client_secret: this.config.clientSecret
|
|
1445
|
+
};
|
|
1446
|
+
let entry = await getAuthForUrl(this.serverName, this.serverUrl);
|
|
1447
|
+
if (entry?.clientInfo)
|
|
1448
|
+
return entry.clientInfo.clientSecretExpiresAt && entry.clientInfo.clientSecretExpiresAt < Date.now() / 1e3 ? void 0 : {
|
|
1449
|
+
client_id: entry.clientInfo.clientId,
|
|
1450
|
+
client_secret: entry.clientInfo.clientSecret
|
|
1451
|
+
};
|
|
1452
|
+
}
|
|
1453
|
+
/**
|
|
1454
|
+
* Save client information from dynamic registration.
|
|
1455
|
+
*/
|
|
1456
|
+
async saveClientInformation(info) {
|
|
1457
|
+
let redirectUris = info.redirect_uris ?? (this.redirectUrl ? [this.redirectUrl] : void 0), clientInfo = {
|
|
1458
|
+
clientId: info.client_id,
|
|
1459
|
+
clientSecret: info.client_secret,
|
|
1460
|
+
clientIdIssuedAt: info.client_id_issued_at,
|
|
1461
|
+
clientSecretExpiresAt: info.client_secret_expires_at,
|
|
1462
|
+
redirectUris
|
|
1463
|
+
};
|
|
1464
|
+
updateClientInfo(this.serverName, clientInfo, this.serverUrl);
|
|
1465
|
+
}
|
|
1466
|
+
/**
|
|
1467
|
+
* Get stored OAuth tokens.
|
|
1468
|
+
* Returns undefined if no tokens exist or if the server URL has changed.
|
|
1469
|
+
*/
|
|
1470
|
+
async tokens() {
|
|
1471
|
+
let entry = await getAuthForUrl(this.serverName, this.serverUrl);
|
|
1472
|
+
if (entry?.tokens)
|
|
1473
|
+
return {
|
|
1474
|
+
access_token: entry.tokens.accessToken,
|
|
1475
|
+
token_type: "Bearer",
|
|
1476
|
+
refresh_token: entry.tokens.refreshToken,
|
|
1477
|
+
expires_in: entry.tokens.expiresAt ? Math.max(0, Math.floor(entry.tokens.expiresAt - Date.now() / 1e3)) : void 0,
|
|
1478
|
+
scope: entry.tokens.scope
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
/**
|
|
1482
|
+
* Save OAuth tokens.
|
|
1483
|
+
*/
|
|
1484
|
+
async saveTokens(tokens) {
|
|
1485
|
+
let storedTokens = {
|
|
1486
|
+
accessToken: tokens.access_token,
|
|
1487
|
+
refreshToken: tokens.refresh_token,
|
|
1488
|
+
expiresAt: tokens.expires_in ? Date.now() / 1e3 + tokens.expires_in : void 0,
|
|
1489
|
+
scope: tokens.scope
|
|
1490
|
+
};
|
|
1491
|
+
updateTokens(this.serverName, storedTokens, this.serverUrl);
|
|
1492
|
+
}
|
|
1493
|
+
/**
|
|
1494
|
+
* Redirect the user to the authorization URL.
|
|
1495
|
+
* This opens the browser for the user to authenticate.
|
|
1496
|
+
*
|
|
1497
|
+
* Throws UnauthorizedError when called outside of a user-initiated flow
|
|
1498
|
+
* (no oauthState saved by startAuth). That path is reached when the SDK
|
|
1499
|
+
* falls through from a failed refresh into a fresh authorization_code
|
|
1500
|
+
* flow, which library hosts cannot complete in-process.
|
|
1501
|
+
*/
|
|
1502
|
+
async redirectToAuthorization(authorizationUrl) {
|
|
1503
|
+
if (this.usesClientCredentials)
|
|
1504
|
+
throw new Error("redirectToAuthorization is not used for client_credentials flow");
|
|
1505
|
+
if (!(await getAuthForUrl(this.serverName, this.serverUrl))?.oauthState)
|
|
1506
|
+
throw new UnauthorizedError(`Re-authentication required for MCP server: ${this.serverName}`);
|
|
1507
|
+
await this.callbacks.onRedirect(authorizationUrl);
|
|
1508
|
+
}
|
|
1509
|
+
/**
|
|
1510
|
+
* Save the PKCE code verifier.
|
|
1511
|
+
*/
|
|
1512
|
+
async saveCodeVerifier(codeVerifier) {
|
|
1513
|
+
updateCodeVerifier(this.serverName, codeVerifier, this.serverUrl);
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Get the stored PKCE code verifier.
|
|
1517
|
+
* @throws Error if no code verifier is stored
|
|
1518
|
+
*/
|
|
1519
|
+
async codeVerifier() {
|
|
1520
|
+
if (this.usesClientCredentials)
|
|
1521
|
+
throw new Error("codeVerifier is not used for client_credentials flow");
|
|
1522
|
+
let entry = await getAuthForUrl(this.serverName, this.serverUrl);
|
|
1523
|
+
if (!entry?.codeVerifier)
|
|
1524
|
+
throw new Error(`No code verifier saved for MCP server: ${this.serverName}`);
|
|
1525
|
+
return entry.codeVerifier;
|
|
1526
|
+
}
|
|
1527
|
+
/**
|
|
1528
|
+
* Save the OAuth state parameter for CSRF protection.
|
|
1529
|
+
*/
|
|
1530
|
+
async saveState(state) {
|
|
1531
|
+
updateOAuthState(this.serverName, state, this.serverUrl);
|
|
1532
|
+
}
|
|
1533
|
+
/**
|
|
1534
|
+
* Get the stored OAuth state parameter.
|
|
1535
|
+
* @throws UnauthorizedError if no flow is in progress (see redirectToAuthorization)
|
|
1536
|
+
*/
|
|
1537
|
+
async state() {
|
|
1538
|
+
if (this.usesClientCredentials)
|
|
1539
|
+
throw new Error("state is not used for client_credentials flow");
|
|
1540
|
+
let entry = await getAuthForUrl(this.serverName, this.serverUrl);
|
|
1541
|
+
if (!entry?.oauthState)
|
|
1542
|
+
throw new UnauthorizedError(`Re-authentication required for MCP server: ${this.serverName}`);
|
|
1543
|
+
return entry.oauthState;
|
|
1544
|
+
}
|
|
1545
|
+
/**
|
|
1546
|
+
* Invalidate credentials when authentication fails.
|
|
1547
|
+
* Clears tokens, client info, or all credentials based on the type.
|
|
1548
|
+
*/
|
|
1549
|
+
async invalidateCredentials(type) {
|
|
1550
|
+
switch (type) {
|
|
1551
|
+
case "all":
|
|
1552
|
+
clearAllCredentials(this.serverName);
|
|
1553
|
+
break;
|
|
1554
|
+
case "client":
|
|
1555
|
+
clearClientInfo(this.serverName);
|
|
1556
|
+
break;
|
|
1557
|
+
case "tokens":
|
|
1558
|
+
clearTokens(this.serverName);
|
|
1559
|
+
break;
|
|
1560
|
+
}
|
|
1561
|
+
}
|
|
1562
|
+
/**
|
|
1563
|
+
* Adds configured authorization-code scope without replacing the SDK's
|
|
1564
|
+
* default token endpoint authentication behavior.
|
|
1565
|
+
*/
|
|
1566
|
+
addClientAuthentication = async (headers, params, _url, metadata) => {
|
|
1567
|
+
params.get("grant_type") === "authorization_code" && !params.has("scope") && this.config.scope && params.set("scope", this.config.scope);
|
|
1568
|
+
let clientInfo = await this.clientInformation();
|
|
1569
|
+
if (!clientInfo)
|
|
1570
|
+
return;
|
|
1571
|
+
let supportedMethods = metadata?.token_endpoint_auth_methods_supported ?? [], hasClientSecret = clientInfo.client_secret !== void 0, authMethod;
|
|
1572
|
+
if (supportedMethods.length === 0 ? authMethod = hasClientSecret ? "client_secret_post" : "none" : hasClientSecret && supportedMethods.includes("client_secret_basic") ? authMethod = "client_secret_basic" : hasClientSecret && supportedMethods.includes("client_secret_post") ? authMethod = "client_secret_post" : supportedMethods.includes("none") ? authMethod = "none" : authMethod = hasClientSecret ? "client_secret_post" : "none", authMethod === "client_secret_basic") {
|
|
1573
|
+
if (!clientInfo.client_secret)
|
|
1574
|
+
throw new Error("client_secret_basic authentication requires a client_secret");
|
|
1575
|
+
headers.set("Authorization", `Basic ${Buffer.from(`${clientInfo.client_id}:${clientInfo.client_secret}`).toString("base64")}`);
|
|
1576
|
+
return;
|
|
1577
|
+
}
|
|
1578
|
+
params.has("client_id") || params.set("client_id", clientInfo.client_id), authMethod === "client_secret_post" && clientInfo.client_secret && !params.has("client_secret") && params.set("client_secret", clientInfo.client_secret);
|
|
1579
|
+
};
|
|
1580
|
+
prepareTokenRequest(scope) {
|
|
1581
|
+
if (!this.usesClientCredentials)
|
|
1582
|
+
return;
|
|
1583
|
+
let params = new URLSearchParams({ grant_type: "client_credentials" }), requestedScope = scope ?? this.config.scope;
|
|
1584
|
+
return requestedScope && params.set("scope", requestedScope), params;
|
|
1585
|
+
}
|
|
1586
|
+
};
|
|
1587
|
+
|
|
1588
|
+
// packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/mcp-callback-server.js
|
|
1589
|
+
import { createServer } from "http";
|
|
1590
|
+
var HTML_SUCCESS = `<!DOCTYPE html>
|
|
1591
|
+
<html>
|
|
1592
|
+
<head>
|
|
1593
|
+
<title>Pi - Authorization Successful</title>
|
|
1594
|
+
<style>
|
|
1595
|
+
body { font-family: system-ui, -apple-system, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #1a1a2e; color: #eee; }
|
|
1596
|
+
.container { text-align: center; padding: 2rem; }
|
|
1597
|
+
h1 { color: #4ade80; margin-bottom: 1rem; }
|
|
1598
|
+
p { color: #aaa; }
|
|
1599
|
+
</style>
|
|
1600
|
+
</head>
|
|
1601
|
+
<body>
|
|
1602
|
+
<div class="container">
|
|
1603
|
+
<h1>Authorization Successful</h1>
|
|
1604
|
+
<p>You can close this window and return to Pi.</p>
|
|
1605
|
+
</div>
|
|
1606
|
+
<script>setTimeout(() => window.close(), 2000);</script>
|
|
1607
|
+
</body>
|
|
1608
|
+
</html>`;
|
|
1609
|
+
function escapeHtml(value) {
|
|
1610
|
+
return value.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
1611
|
+
}
|
|
1612
|
+
var HTML_ERROR = (error) => `<!DOCTYPE html>
|
|
1613
|
+
<html>
|
|
1614
|
+
<head>
|
|
1615
|
+
<title>Pi - Authorization Failed</title>
|
|
1616
|
+
<style>
|
|
1617
|
+
body { font-family: system-ui, -apple-system, sans-serif; display: flex; justify-content: center; align-items: center; height: 100vh; margin: 0; background: #1a1a2e; color: #eee; }
|
|
1618
|
+
.container { text-align: center; padding: 2rem; }
|
|
1619
|
+
h1 { color: #f87171; margin-bottom: 1rem; }
|
|
1620
|
+
p { color: #aaa; }
|
|
1621
|
+
.error { color: #fca5a5; font-family: monospace; margin-top: 1rem; padding: 1rem; background: rgba(248,113,113,0.1); border-radius: 0.5rem; }
|
|
1622
|
+
</style>
|
|
1623
|
+
</head>
|
|
1624
|
+
<body>
|
|
1625
|
+
<div class="container">
|
|
1626
|
+
<h1>Authorization Failed</h1>
|
|
1627
|
+
<p>An error occurred during authorization.</p>
|
|
1628
|
+
<div class="error">${escapeHtml(error)}</div>
|
|
1629
|
+
</div>
|
|
1630
|
+
</body>
|
|
1631
|
+
</html>`, server, bindingPromise, pendingAuths = /* @__PURE__ */ new Map(), reservedAuthStates = /* @__PURE__ */ new Set(), CALLBACK_TIMEOUT_MS = 300 * 1e3, DEFAULT_OAUTH_CALLBACK_HOST = "localhost", callbackServerHost = DEFAULT_OAUTH_CALLBACK_HOST;
|
|
1632
|
+
function handleRequest(req, res) {
|
|
1633
|
+
let url2 = new URL(req.url || "/", `http://${req.headers.host}`);
|
|
1634
|
+
if (url2.pathname !== getOAuthCallbackPath()) {
|
|
1635
|
+
res.writeHead(404, { "Content-Type": "text/plain" }), res.end("Not found");
|
|
1636
|
+
return;
|
|
1637
|
+
}
|
|
1638
|
+
let code = url2.searchParams.get("code"), state = url2.searchParams.get("state"), error = url2.searchParams.get("error"), errorDescription = url2.searchParams.get("error_description");
|
|
1639
|
+
if (!state) {
|
|
1640
|
+
let errorMsg = "Missing required state parameter - potential CSRF attack";
|
|
1641
|
+
res.writeHead(400, { "Content-Type": "text/html" }), res.end(HTML_ERROR(errorMsg));
|
|
1642
|
+
return;
|
|
1643
|
+
}
|
|
1644
|
+
let pending = pendingAuths.get(state), isReserved = reservedAuthStates.has(state);
|
|
1645
|
+
if (error) {
|
|
1646
|
+
if (!pending && !isReserved) {
|
|
1647
|
+
let errorMsg2 = "Invalid or expired state parameter - potential CSRF attack";
|
|
1648
|
+
res.writeHead(400, { "Content-Type": "text/html" }), res.end(HTML_ERROR(errorMsg2));
|
|
1649
|
+
return;
|
|
1650
|
+
}
|
|
1651
|
+
let errorMsg = errorDescription || error;
|
|
1652
|
+
res.writeHead(200, { "Content-Type": "text/html" }), res.end(HTML_ERROR(errorMsg)), reservedAuthStates.delete(state), pending && (clearTimeout(pending.timeout), pendingAuths.delete(state), setTimeout(() => pending.reject(new Error(errorMsg)), 0));
|
|
1653
|
+
return;
|
|
1654
|
+
}
|
|
1655
|
+
if (!pending) {
|
|
1656
|
+
let errorMsg = "Invalid or expired state parameter - potential CSRF attack";
|
|
1657
|
+
res.writeHead(400, { "Content-Type": "text/html" }), res.end(HTML_ERROR(errorMsg));
|
|
1658
|
+
return;
|
|
1659
|
+
}
|
|
1660
|
+
if (!code) {
|
|
1661
|
+
res.writeHead(400, { "Content-Type": "text/html" }), res.end(HTML_ERROR("No authorization code provided"));
|
|
1662
|
+
return;
|
|
1663
|
+
}
|
|
1664
|
+
clearTimeout(pending.timeout), pendingAuths.delete(state), pending.resolve(code), res.writeHead(200, { "Content-Type": "text/html" }), res.end(HTML_SUCCESS);
|
|
1665
|
+
}
|
|
1666
|
+
async function ensureCallbackServer(options = {}) {
|
|
1667
|
+
for (; bindingPromise; )
|
|
1668
|
+
await bindingPromise;
|
|
1669
|
+
let operation = ensureCallbackServerLocked(options);
|
|
1670
|
+
bindingPromise = operation;
|
|
1671
|
+
try {
|
|
1672
|
+
await operation;
|
|
1673
|
+
} finally {
|
|
1674
|
+
bindingPromise === operation && (bindingPromise = void 0);
|
|
1675
|
+
}
|
|
1676
|
+
}
|
|
1677
|
+
async function ensureCallbackServerLocked(options = {}) {
|
|
1678
|
+
let requiredPort = options.port ?? getConfiguredOAuthCallbackPort(), strictPort = options.strictPort === !0, requestedHost = options.callbackHost ?? DEFAULT_OAUTH_CALLBACK_HOST, rawRequestedPath = options.callbackPath ?? DEFAULT_OAUTH_CALLBACK_PATH, requestedPath = rawRequestedPath.startsWith("/") ? rawRequestedPath : `/${rawRequestedPath}`;
|
|
1679
|
+
if (options.reserveState && !options.oauthState)
|
|
1680
|
+
throw new Error("OAuth callback reservation requires an oauthState");
|
|
1681
|
+
let reservedState, previousServer = server, needsStrictRebind = !!(previousServer && strictPort && getOAuthCallbackPort() !== requiredPort), needsHostSwitch = !!(previousServer && callbackServerHost !== requestedHost), needsPathSwitch = !!(previousServer && getOAuthCallbackPath() !== requestedPath);
|
|
1682
|
+
if (previousServer) {
|
|
1683
|
+
if (!needsStrictRebind && !needsHostSwitch) {
|
|
1684
|
+
if (needsPathSwitch) {
|
|
1685
|
+
if (pendingAuths.size > 0 || reservedAuthStates.size > 0)
|
|
1686
|
+
throw new Error(`OAuth callback server is using path ${getOAuthCallbackPath()}, but callback path ${requestedPath} is required and cannot be switched while authorizations are pending`);
|
|
1687
|
+
setOAuthCallbackPath(requestedPath);
|
|
1688
|
+
}
|
|
1689
|
+
options.reserveState && options.oauthState && (reservedAuthStates.add(options.oauthState), reservedState = options.oauthState);
|
|
1690
|
+
return;
|
|
1691
|
+
}
|
|
1692
|
+
if (pendingAuths.size > 0 || reservedAuthStates.size > 0)
|
|
1693
|
+
throw new Error(`OAuth callback server is running on ${callbackServerHost}:${getOAuthCallbackPort()}, but strict callback endpoint ${requestedHost}:${requiredPort} is required and cannot be switched while authorizations are pending`);
|
|
1694
|
+
}
|
|
1695
|
+
let candidateServer = createServer(handleRequest), listenPort = strictPort ? requiredPort : 0;
|
|
1696
|
+
try {
|
|
1697
|
+
if (await new Promise((resolve, reject) => {
|
|
1698
|
+
candidateServer.once("error", (err) => {
|
|
1699
|
+
reject(err);
|
|
1700
|
+
}), candidateServer.listen(listenPort, requestedHost, () => {
|
|
1701
|
+
resolve();
|
|
1702
|
+
});
|
|
1703
|
+
}), strictPort)
|
|
1704
|
+
setOAuthCallbackPort(requiredPort);
|
|
1705
|
+
else {
|
|
1706
|
+
let address = candidateServer.address();
|
|
1707
|
+
if (!address || typeof address == "string" || typeof address.port != "number")
|
|
1708
|
+
throw new Error("OAuth callback server did not report an assigned port");
|
|
1709
|
+
setOAuthCallbackPort(address.port);
|
|
1710
|
+
}
|
|
1711
|
+
previousServer && (needsStrictRebind || needsHostSwitch) && await new Promise((resolve) => {
|
|
1712
|
+
previousServer.close(() => resolve());
|
|
1713
|
+
}), callbackServerHost = requestedHost, setOAuthCallbackPath(requestedPath), server = candidateServer, options.reserveState && options.oauthState && (reservedAuthStates.add(options.oauthState), reservedState = options.oauthState), server.unref();
|
|
1714
|
+
} catch (error) {
|
|
1715
|
+
reservedState && reservedAuthStates.delete(reservedState);
|
|
1716
|
+
let nodeError = error;
|
|
1717
|
+
throw await new Promise((resolve) => {
|
|
1718
|
+
candidateServer.close(() => resolve());
|
|
1719
|
+
}), strictPort && nodeError.code === "EADDRINUSE" ? new Error(`OAuth callback port ${requiredPort} is already in use. Pre-registered OAuth clients require an exact redirect URI; set MCP_OAUTH_CALLBACK_PORT to your registered port or free port ${requiredPort}`, { cause: error }) : error;
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
function releaseCallbackServer(oauthState) {
|
|
1723
|
+
reservedAuthStates.delete(oauthState);
|
|
1724
|
+
}
|
|
1725
|
+
function waitForCallback(oauthState) {
|
|
1726
|
+
return reservedAuthStates.delete(oauthState), new Promise((resolve, reject) => {
|
|
1727
|
+
let timeout = setTimeout(() => {
|
|
1728
|
+
pendingAuths.has(oauthState) && (pendingAuths.delete(oauthState), reject(new Error("OAuth callback timeout - authorization took too long")));
|
|
1729
|
+
}, CALLBACK_TIMEOUT_MS);
|
|
1730
|
+
pendingAuths.set(oauthState, { resolve, reject, timeout });
|
|
1731
|
+
});
|
|
1732
|
+
}
|
|
1733
|
+
function cancelPendingCallback(oauthState) {
|
|
1734
|
+
reservedAuthStates.delete(oauthState);
|
|
1735
|
+
let pending = pendingAuths.get(oauthState);
|
|
1736
|
+
pending && (clearTimeout(pending.timeout), pendingAuths.delete(oauthState), pending.reject(new Error("Authorization cancelled")));
|
|
1737
|
+
}
|
|
1738
|
+
async function stopCallbackServer() {
|
|
1739
|
+
server && (await new Promise((resolve) => {
|
|
1740
|
+
server.close(() => {
|
|
1741
|
+
resolve();
|
|
1742
|
+
});
|
|
1743
|
+
}), server = void 0), setOAuthCallbackPort(getConfiguredOAuthCallbackPort()), callbackServerHost = DEFAULT_OAUTH_CALLBACK_HOST, setOAuthCallbackPath(DEFAULT_OAUTH_CALLBACK_PATH);
|
|
1744
|
+
let pendingList = Array.from(pendingAuths.entries());
|
|
1745
|
+
pendingAuths.clear(), reservedAuthStates.clear(), setTimeout(() => {
|
|
1746
|
+
for (let [, pending] of pendingList)
|
|
1747
|
+
clearTimeout(pending.timeout), pending.reject(new Error("OAuth callback server stopped"));
|
|
1748
|
+
}, 0);
|
|
1749
|
+
}
|
|
1750
|
+
|
|
1751
|
+
// packages/coding-agent/dist/builtin-extensions/pi-mcp-adapter/mcp-auth-flow.js
|
|
1752
|
+
var pendingTransports = /* @__PURE__ */ new Map(), pendingAuthStates = /* @__PURE__ */ new Map(), pendingAuthCleanupTimers = /* @__PURE__ */ new Map(), pendingAuthentications = /* @__PURE__ */ new Map(), MANUAL_AUTH_TIMEOUT_MS = 300 * 1e3;
|
|
1753
|
+
function generateState() {
|
|
1754
|
+
return Array.from(crypto.getRandomValues(new Uint8Array(32))).map((b) => b.toString(16).padStart(2, "0")).join("");
|
|
1755
|
+
}
|
|
1756
|
+
function extractOAuthConfig(definition) {
|
|
1757
|
+
if (definition.oauth === !1)
|
|
1758
|
+
return {};
|
|
1759
|
+
let config = {};
|
|
1760
|
+
if (definition.oauth?.grantType !== void 0 && (config.grantType = definition.oauth.grantType), definition.oauth?.clientId !== void 0 && (config.clientId = definition.oauth.clientId), definition.oauth?.clientSecret !== void 0 && (config.clientSecret = definition.oauth.clientSecret), definition.oauth?.scope !== void 0 && (config.scope = definition.oauth.scope), definition.oauth?.redirectUri !== void 0) {
|
|
1761
|
+
if (typeof definition.oauth.redirectUri != "string")
|
|
1762
|
+
throw new Error("OAuth redirectUri must be a string");
|
|
1763
|
+
let redirectUri = definition.oauth.redirectUri.trim();
|
|
1764
|
+
if (!redirectUri)
|
|
1765
|
+
throw new Error("OAuth redirectUri must not be empty");
|
|
1766
|
+
config.redirectUri = redirectUri;
|
|
1767
|
+
}
|
|
1768
|
+
if (definition.oauth?.clientName !== void 0) {
|
|
1769
|
+
if (typeof definition.oauth.clientName != "string")
|
|
1770
|
+
throw new Error("OAuth clientName must be a string");
|
|
1771
|
+
let clientName = definition.oauth.clientName.trim();
|
|
1772
|
+
if (!clientName)
|
|
1773
|
+
throw new Error("OAuth clientName must not be empty");
|
|
1774
|
+
config.clientName = clientName;
|
|
1775
|
+
}
|
|
1776
|
+
if (definition.oauth?.clientUri !== void 0) {
|
|
1777
|
+
if (typeof definition.oauth.clientUri != "string")
|
|
1778
|
+
throw new Error("OAuth clientUri must be a string");
|
|
1779
|
+
let clientUri = definition.oauth.clientUri.trim();
|
|
1780
|
+
if (!clientUri)
|
|
1781
|
+
throw new Error("OAuth clientUri must not be empty");
|
|
1782
|
+
config.clientUri = clientUri;
|
|
1783
|
+
}
|
|
1784
|
+
return config;
|
|
1785
|
+
}
|
|
1786
|
+
function parseOAuthRedirectUri(redirectUri) {
|
|
1787
|
+
let url2;
|
|
1788
|
+
try {
|
|
1789
|
+
url2 = new URL(redirectUri);
|
|
1790
|
+
} catch (error) {
|
|
1791
|
+
throw new Error(`Invalid OAuth redirectUri: ${redirectUri}`, { cause: error });
|
|
1792
|
+
}
|
|
1793
|
+
let hostname = url2.hostname.toLowerCase(), isLocalhost = hostname === "localhost" || hostname === "127.0.0.1" || hostname === "[::1]" || hostname === "::1";
|
|
1794
|
+
if (url2.protocol !== "http:" || !isLocalhost)
|
|
1795
|
+
throw new Error("OAuth redirectUri must be an http:// localhost or loopback URI");
|
|
1796
|
+
if (url2.username || url2.password)
|
|
1797
|
+
throw new Error("OAuth redirectUri must not include username or password");
|
|
1798
|
+
if (url2.hash)
|
|
1799
|
+
throw new Error("OAuth redirectUri must not include a fragment");
|
|
1800
|
+
if (!url2.port)
|
|
1801
|
+
throw new Error("OAuth redirectUri must include an explicit numeric port");
|
|
1802
|
+
let port = Number.parseInt(url2.port, 10);
|
|
1803
|
+
if (!Number.isInteger(port) || port <= 0 || port > 65535)
|
|
1804
|
+
throw new Error("OAuth redirectUri must include an explicit numeric port");
|
|
1805
|
+
return { port, callbackHost: hostname === "[::1]" ? "::1" : hostname, callbackPath: url2.pathname };
|
|
1806
|
+
}
|
|
1807
|
+
async function startAuth(serverName, serverUrl, definition) {
|
|
1808
|
+
let config = definition ? extractOAuthConfig(definition) : {};
|
|
1809
|
+
if (config.grantType === "client_credentials") {
|
|
1810
|
+
let storedAuth = await getAuthForUrl(serverName, serverUrl);
|
|
1811
|
+
storedAuth?.clientInfo && !storedAuth.tokens && !config.clientId && (clearClientInfo(serverName), clearCodeVerifier(serverName), await clearOAuthState(serverName));
|
|
1812
|
+
let authProvider2 = new McpOAuthProvider(serverName, serverUrl, config, {
|
|
1813
|
+
onRedirect: async () => {
|
|
1814
|
+
throw new Error("Browser redirect is not used for client_credentials flow");
|
|
1815
|
+
}
|
|
1816
|
+
});
|
|
1817
|
+
if (await auth(authProvider2, { serverUrl }) !== "AUTHORIZED")
|
|
1818
|
+
throw new UnauthorizedError("Failed to authorize");
|
|
1819
|
+
return { authorizationUrl: "" };
|
|
1820
|
+
}
|
|
1821
|
+
let redirectCallback = config.redirectUri !== void 0 ? parseOAuthRedirectUri(config.redirectUri) : void 0, oauthState = generateState();
|
|
1822
|
+
try {
|
|
1823
|
+
await ensureCallbackServer({
|
|
1824
|
+
strictPort: !!config.clientId || config.redirectUri !== void 0,
|
|
1825
|
+
oauthState,
|
|
1826
|
+
reserveState: !0,
|
|
1827
|
+
...redirectCallback ? { port: redirectCallback.port, callbackHost: redirectCallback.callbackHost, callbackPath: redirectCallback.callbackPath } : {}
|
|
1828
|
+
});
|
|
1829
|
+
} catch (error) {
|
|
1830
|
+
throw await clearOAuthState(serverName), error;
|
|
1831
|
+
}
|
|
1832
|
+
let capturedUrl, authProvider = new McpOAuthProvider(serverName, serverUrl, config, {
|
|
1833
|
+
onRedirect: async (url2) => {
|
|
1834
|
+
capturedUrl = url2;
|
|
1835
|
+
}
|
|
1836
|
+
});
|
|
1837
|
+
try {
|
|
1838
|
+
let storedAuth = await getAuthForUrl(serverName, serverUrl);
|
|
1839
|
+
if (storedAuth?.clientInfo && !config.clientId)
|
|
1840
|
+
if (!storedAuth.tokens)
|
|
1841
|
+
clearClientInfo(serverName), clearCodeVerifier(serverName), await clearOAuthState(serverName);
|
|
1842
|
+
else {
|
|
1843
|
+
let redirectUris = storedAuth.clientInfo.redirectUris;
|
|
1844
|
+
(!Array.isArray(redirectUris) || !redirectUris.includes(authProvider.redirectUrl ?? "")) && (clearClientInfo(serverName), clearTokens(serverName), clearCodeVerifier(serverName), await clearOAuthState(serverName));
|
|
1845
|
+
}
|
|
1846
|
+
if (await updateOAuthState(serverName, oauthState, serverUrl), await auth(authProvider, { serverUrl }) === "AUTHORIZED")
|
|
1847
|
+
return releaseCallbackServer(oauthState), await clearOAuthState(serverName), { authorizationUrl: "" };
|
|
1848
|
+
if (!capturedUrl)
|
|
1849
|
+
throw new UnauthorizedError("OAuth authorization URL was not provided");
|
|
1850
|
+
let pendingTransport = new StreamableHTTPClientTransport(new URL(serverUrl), { authProvider });
|
|
1851
|
+
return await setPendingTransport(serverName, pendingTransport, oauthState), { authorizationUrl: capturedUrl.toString() };
|
|
1852
|
+
} catch (error) {
|
|
1853
|
+
throw await clearPendingAuth(serverName, oauthState), error;
|
|
1854
|
+
}
|
|
1855
|
+
}
|
|
1856
|
+
async function setPendingTransport(serverName, transport, oauthState) {
|
|
1857
|
+
await clearPendingAuth(serverName), pendingTransports.set(serverName, transport), pendingAuthStates.set(serverName, oauthState);
|
|
1858
|
+
let cleanupTimer = setTimeout(() => {
|
|
1859
|
+
clearPendingAuth(serverName, oauthState);
|
|
1860
|
+
}, MANUAL_AUTH_TIMEOUT_MS);
|
|
1861
|
+
cleanupTimer.unref?.(), pendingAuthCleanupTimers.set(serverName, cleanupTimer);
|
|
1862
|
+
}
|
|
1863
|
+
async function clearPendingAuth(serverName, oauthState) {
|
|
1864
|
+
let pendingState = pendingAuthStates.get(serverName);
|
|
1865
|
+
if (oauthState && pendingState && pendingState !== oauthState)
|
|
1866
|
+
return;
|
|
1867
|
+
let timer = pendingAuthCleanupTimers.get(serverName);
|
|
1868
|
+
timer && (clearTimeout(timer), pendingAuthCleanupTimers.delete(serverName));
|
|
1869
|
+
let transport = pendingTransports.get(serverName);
|
|
1870
|
+
pendingTransports.delete(serverName), pendingAuthStates.delete(serverName);
|
|
1871
|
+
let stateToRelease = pendingState ?? oauthState;
|
|
1872
|
+
stateToRelease && (releaseCallbackServer(stateToRelease), await getOAuthState(serverName) === stateToRelease && await clearOAuthState(serverName)), transport && await transport.close().catch(() => {
|
|
1873
|
+
});
|
|
1874
|
+
}
|
|
1875
|
+
function getSearchParamsFromInput(input) {
|
|
1876
|
+
try {
|
|
1877
|
+
let url2 = new URL(input), params = new URLSearchParams(url2.search);
|
|
1878
|
+
if (url2.hash) {
|
|
1879
|
+
let hash = url2.hash.startsWith("#") ? url2.hash.slice(1) : url2.hash, hashParams = new URLSearchParams(hash);
|
|
1880
|
+
for (let [key, value] of hashParams)
|
|
1881
|
+
params.has(key) || params.set(key, value);
|
|
1882
|
+
}
|
|
1883
|
+
return params;
|
|
1884
|
+
} catch {
|
|
1885
|
+
let query = input.includes("?") ? input.slice(input.indexOf("?") + 1) : input, params = new URLSearchParams(query.startsWith("#") ? query.slice(1) : query);
|
|
1886
|
+
return params.has("code") || params.has("state") || params.has("error") ? params : void 0;
|
|
1887
|
+
}
|
|
1888
|
+
}
|
|
1889
|
+
function parseAuthorizationCodeInput(input, expectedState) {
|
|
1890
|
+
let trimmed = input.trim();
|
|
1891
|
+
if (!trimmed)
|
|
1892
|
+
throw new Error("Authorization code or redirect URL is required");
|
|
1893
|
+
let params = getSearchParamsFromInput(trimmed);
|
|
1894
|
+
if (params) {
|
|
1895
|
+
let error = params.get("error");
|
|
1896
|
+
if (error) {
|
|
1897
|
+
let description = params.get("error_description");
|
|
1898
|
+
throw new Error(description ? `${error}: ${description}` : error);
|
|
1899
|
+
}
|
|
1900
|
+
let state = params.get("state");
|
|
1901
|
+
if (expectedState && !state)
|
|
1902
|
+
throw new Error("OAuth state missing from redirect URL");
|
|
1903
|
+
if (expectedState && state !== expectedState)
|
|
1904
|
+
throw new Error("OAuth state mismatch - potential CSRF attack");
|
|
1905
|
+
let code = params.get("code");
|
|
1906
|
+
if (code)
|
|
1907
|
+
return code;
|
|
1908
|
+
}
|
|
1909
|
+
if (/^[A-Za-z0-9._~+/=-]+$/.test(trimmed))
|
|
1910
|
+
return trimmed;
|
|
1911
|
+
throw new Error("Could not find an OAuth authorization code in the provided input");
|
|
1912
|
+
}
|
|
1913
|
+
async function completeAuthFromInput(serverName, input) {
|
|
1914
|
+
let oauthState = await getOAuthState(serverName), code = parseAuthorizationCodeInput(input, oauthState);
|
|
1915
|
+
return completeAuth(serverName, code);
|
|
1916
|
+
}
|
|
1917
|
+
async function completeAuth(serverName, authorizationCode) {
|
|
1918
|
+
let transport = pendingTransports.get(serverName);
|
|
1919
|
+
if (!transport)
|
|
1920
|
+
throw new Error(`No pending OAuth flow for server: ${serverName}`);
|
|
1921
|
+
let oauthState = await getOAuthState(serverName);
|
|
1922
|
+
try {
|
|
1923
|
+
return await transport.finishAuth(authorizationCode), "authenticated";
|
|
1924
|
+
} finally {
|
|
1925
|
+
await clearPendingAuth(serverName, oauthState);
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
async function authenticate(serverName, serverUrl, definition, options = {}) {
|
|
1929
|
+
let inFlight = pendingAuthentications.get(serverName);
|
|
1930
|
+
if (inFlight)
|
|
1931
|
+
return inFlight;
|
|
1932
|
+
let operation = (async () => {
|
|
1933
|
+
let { authorizationUrl } = await startAuth(serverName, serverUrl, definition);
|
|
1934
|
+
if (!authorizationUrl)
|
|
1935
|
+
return "authenticated";
|
|
1936
|
+
let oauthState = await getOAuthState(serverName);
|
|
1937
|
+
if (!oauthState)
|
|
1938
|
+
throw new Error("OAuth state not found - this should not happen");
|
|
1939
|
+
let callbackPromise = waitForCallback(oauthState);
|
|
1940
|
+
try {
|
|
1941
|
+
options.onAuthorizationUrl ? await options.onAuthorizationUrl(authorizationUrl) : console.log(`MCP Auth: Open this URL to authenticate ${serverName}:
|
|
1942
|
+
${authorizationUrl}`);
|
|
1943
|
+
try {
|
|
1944
|
+
await open(authorizationUrl);
|
|
1945
|
+
} catch (error) {
|
|
1946
|
+
console.warn(`MCP Auth: Failed to open browser for ${serverName}; waiting for manual callback`, { error });
|
|
1947
|
+
}
|
|
1948
|
+
let code = await callbackPromise;
|
|
1949
|
+
if (await getOAuthState(serverName) !== oauthState)
|
|
1950
|
+
throw await clearOAuthState(serverName), new Error("OAuth state mismatch - potential CSRF attack");
|
|
1951
|
+
return await clearOAuthState(serverName), await completeAuth(serverName, code);
|
|
1952
|
+
} catch (error) {
|
|
1953
|
+
throw cancelPendingCallback(oauthState), await clearPendingAuth(serverName, oauthState), error;
|
|
1954
|
+
}
|
|
1955
|
+
})();
|
|
1956
|
+
pendingAuthentications.set(serverName, operation);
|
|
1957
|
+
try {
|
|
1958
|
+
return await operation;
|
|
1959
|
+
} finally {
|
|
1960
|
+
pendingAuthentications.get(serverName) === operation && pendingAuthentications.delete(serverName);
|
|
1961
|
+
}
|
|
1962
|
+
}
|
|
1963
|
+
async function getValidToken(serverName, serverUrl) {
|
|
1964
|
+
let entry = await getAuthForUrl(serverName, serverUrl);
|
|
1965
|
+
if (!entry?.tokens)
|
|
1966
|
+
return null;
|
|
1967
|
+
let expired = await isTokenExpired(serverName);
|
|
1968
|
+
if (expired === !1)
|
|
1969
|
+
return entry.tokens;
|
|
1970
|
+
if (expired === !0 && entry.tokens.refreshToken) {
|
|
1971
|
+
console.log(`MCP Auth: Token expired for ${serverName}, attempting refresh`);
|
|
1972
|
+
try {
|
|
1973
|
+
let authProvider = new McpOAuthProvider(serverName, serverUrl, {}, {
|
|
1974
|
+
onRedirect: async () => {
|
|
1975
|
+
}
|
|
1976
|
+
});
|
|
1977
|
+
return await authProvider.clientInformation() ? await auth(authProvider, { serverUrl }) !== "AUTHORIZED" ? null : (await getAuthForUrl(serverName, serverUrl))?.tokens ?? null : (console.log(`MCP Auth: No client info for refresh for ${serverName}`), null);
|
|
1978
|
+
} catch (error) {
|
|
1979
|
+
return console.error(`MCP Auth: Token refresh failed for ${serverName}`, { error }), null;
|
|
1980
|
+
}
|
|
1981
|
+
}
|
|
1982
|
+
return entry.tokens;
|
|
1983
|
+
}
|
|
1984
|
+
async function getAuthStatus(serverName) {
|
|
1985
|
+
return await hasStoredTokens(serverName) ? await isTokenExpired(serverName) ? "expired" : "authenticated" : "not_authenticated";
|
|
1986
|
+
}
|
|
1987
|
+
async function removeAuth(serverName) {
|
|
1988
|
+
let oauthState = await getOAuthState(serverName);
|
|
1989
|
+
oauthState && cancelPendingCallback(oauthState), await clearPendingAuth(serverName, oauthState), clearAllCredentials(serverName), await clearOAuthState(serverName), console.log(`MCP Auth: Removed credentials for ${serverName}`);
|
|
1990
|
+
}
|
|
1991
|
+
function supportsOAuth(definition) {
|
|
1992
|
+
return !definition.url || definition.auth === !1 || definition.oauth === !1 ? !1 : definition.auth === "oauth" ? !0 : definition.headers && Object.keys(definition.headers).length > 0 ? !1 : definition.auth === void 0;
|
|
1993
|
+
}
|
|
1994
|
+
async function initializeOAuth() {
|
|
1995
|
+
}
|
|
1996
|
+
async function shutdownOAuth() {
|
|
1997
|
+
for (let serverName of Array.from(pendingTransports.keys()))
|
|
1998
|
+
await clearPendingAuth(serverName);
|
|
1999
|
+
await stopCallbackServer();
|
|
2000
|
+
}
|
|
2001
|
+
|
|
2002
|
+
export {
|
|
2003
|
+
normalizeHeaders,
|
|
2004
|
+
createFetchWithInit,
|
|
2005
|
+
UnauthorizedError,
|
|
2006
|
+
auth,
|
|
2007
|
+
extractWWWAuthenticateParams,
|
|
2008
|
+
createParser,
|
|
2009
|
+
StreamableHTTPClientTransport,
|
|
2010
|
+
getAuthForUrl,
|
|
2011
|
+
McpOAuthProvider,
|
|
2012
|
+
extractOAuthConfig,
|
|
2013
|
+
startAuth,
|
|
2014
|
+
parseAuthorizationCodeInput,
|
|
2015
|
+
completeAuthFromInput,
|
|
2016
|
+
completeAuth,
|
|
2017
|
+
authenticate,
|
|
2018
|
+
getValidToken,
|
|
2019
|
+
getAuthStatus,
|
|
2020
|
+
removeAuth,
|
|
2021
|
+
supportsOAuth,
|
|
2022
|
+
initializeOAuth,
|
|
2023
|
+
shutdownOAuth
|
|
2024
|
+
};
|
|
2025
|
+
/*! Bundled license information:
|
|
2026
|
+
|
|
2027
|
+
content-type/index.js:
|
|
2028
|
+
(*!
|
|
2029
|
+
* content-type
|
|
2030
|
+
* Copyright(c) 2015 Douglas Christopher Wilson
|
|
2031
|
+
* MIT Licensed
|
|
2032
|
+
*)
|
|
2033
|
+
*/
|