@mcp-use/inspector 20.0.0-beta.5 → 20.0.0-beta.50
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/README.md +31 -78
- package/dist/app/inspector.css.gz +0 -0
- package/dist/app/inspector.js.gz +0 -0
- package/dist/app/providers/anthropic.png +0 -0
- package/dist/app/providers/google.png +0 -0
- package/dist/app/providers/openai.png +0 -0
- package/dist/cli.js +332 -1384
- package/dist/client/index.d.ts +1405 -50
- package/dist/client/index.js +165 -24019
- package/dist/server/index.d.ts +79 -7
- package/dist/server/index.js +370 -22
- package/package.json +77 -35
- package/dist/cdn/AnimatePresence-Dcw-FOy8.js +0 -393
- package/dist/cdn/ChatTab-B255lH5i.js +0 -6744
- package/dist/cdn/CheckboxIndicator-Bt4IICtv.js +0 -251
- package/dist/cdn/ConnectionSettingsForm-DF-NS58d.js +0 -929
- package/dist/cdn/ConnectionSettingsTab-dI-Cqe79.js +0 -150
- package/dist/cdn/ElicitationTab-CL1KJ0bz.js +0 -654
- package/dist/cdn/FormContext-tmgN_Vdr.js +0 -135
- package/dist/cdn/InspectorContext-UjtEbNod.js +0 -123
- package/dist/cdn/JSONDisplay-BFxf5oEu.js +0 -324
- package/dist/cdn/ListTabHeader-Cv-GmtGF.js +0 -88
- package/dist/cdn/ManufactOAuthCallback-B98kSYCj.js +0 -31
- package/dist/cdn/MarkdownRenderer-Ba7nA4Ie.js +0 -3610
- package/dist/cdn/NotificationsTab-CeImSrhx.js +0 -290
- package/dist/cdn/OAuthCallback-Blc2Asxc.js +0 -58
- package/dist/cdn/PromptsTab-BYKnY7Rp.js +0 -901
- package/dist/cdn/ResourcesTab-BGualKW-.js +0 -564
- package/dist/cdn/SamplingTab-BeZBUeni.js +0 -658
- package/dist/cdn/ServerMetadataTab-CvrKX8fz.js +0 -244
- package/dist/cdn/StatusIcon-D0-ARyOh.js +0 -66
- package/dist/cdn/ToolsTab-j6n4O_3s.js +0 -2033
- package/dist/cdn/ViewPreview-DihyG6Qd.js +0 -238
- package/dist/cdn/WidgetDebugContext-D4usL_MA.js +0 -324
- package/dist/cdn/WidgetWrapper-B4H3Fek7.js +0 -2210
- package/dist/cdn/basePath-B8HuhIMu.js +0 -25
- package/dist/cdn/bell-CGjAO_0s.js +0 -10
- package/dist/cdn/browser-CbQIH4w2.js +0 -42
- package/dist/cdn/brush-B_mKhyxG.js +0 -17
- package/dist/cdn/card-DgiYnSg-.js +0 -41
- package/dist/cdn/cfWorker-Bxcs9rNe.js +0 -10799
- package/dist/cdn/checkbox-By0FklhG.js +0 -20
- package/dist/cdn/chunk-QUQL4437-XnDcYQEx.js +0 -1508
- package/dist/cdn/clock-CmUbSx_B.js +0 -12
- package/dist/cdn/code-V_0nf5rg.js +0 -10
- package/dist/cdn/createLucideIcon-C5fZZ6oB.js +0 -38
- package/dist/cdn/dialog-BsDpuJd3.js +0 -1028
- package/dist/cdn/dist-DaMB0Su9.js +0 -616
- package/dist/cdn/dist-DbX5yidW.js +0 -2306
- package/dist/cdn/external-link-CjmfT6rW.js +0 -17
- package/dist/cdn/eye-B7H96av8.js +0 -29
- package/dist/cdn/folder-open-B3lu2rG_.js +0 -7
- package/dist/cdn/hash-BVQnWi7q.js +0 -33
- package/dist/cdn/history-Csw4rb44.js +0 -17
- package/dist/cdn/index-browser-DkQOzkvX.js +0 -1934
- package/dist/cdn/info-CNiOwqkf.js +0 -19
- package/dist/cdn/input-C2OBd4PJ.js +0 -12160
- package/dist/cdn/inspector-settings-layout-0VDsjeqb.js +0 -4
- package/dist/cdn/inspector.css +0 -2
- package/dist/cdn/inspector.js +0 -24523
- package/dist/cdn/jsx-runtime-CIxvMpEo.js +0 -180
- package/dist/cdn/label-B9Jmm9be.js +0 -60
- package/dist/cdn/loader-circle-BLy9A_pp.js +0 -7
- package/dist/cdn/manufact-auth-BQMHhbLV.js +0 -423
- package/dist/cdn/maximize-2-CH5Lq90B.js +0 -21
- package/dist/cdn/maximize-BALCV_ep.js +0 -21
- package/dist/cdn/message-square-BnxdpJxZ.js +0 -7
- package/dist/cdn/not-found-DEtSM_Wd.js +0 -34
- package/dist/cdn/play-vuZ5PLnI.js +0 -7
- package/dist/cdn/providerMeta-BQIfHuNL.js +0 -379
- package/dist/cdn/providers/anthropic.png +0 -0
- package/dist/cdn/providers/google.png +0 -0
- package/dist/cdn/providers/openai.png +0 -0
- package/dist/cdn/react-BIs9pQ3H.js +0 -926
- package/dist/cdn/react-BajV-X4P.js +0 -5425
- package/dist/cdn/refresh-cw-BXY-Pa0U.js +0 -21
- package/dist/cdn/save-Tgil_AJZ.js +0 -34
- package/dist/cdn/schemaHelpers-DTV38jGq.js +0 -16
- package/dist/cdn/select-DDdiIPR2.js +0 -2594
- package/dist/cdn/servers-Dm72iTpY.js +0 -26
- package/dist/cdn/shared-DaILIQPP.js +0 -1700
- package/dist/cdn/sheet-Br_l2kry.js +0 -2077
- package/dist/cdn/sparkles-BntO2rDR.js +0 -23
- package/dist/cdn/spinner-jQtC7EBj.js +0 -15
- package/dist/cdn/square-check-big-BvwQ17Bl.js +0 -10
- package/dist/cdn/switch-C3IyQuid.js +0 -664
- package/dist/cdn/tabs-subtle-CkdI6Mac.js +0 -787
- package/dist/cdn/telemetry-DabTAQ8x.js +0 -240
- package/dist/cdn/textarea-DSbwcFVt.js +0 -14
- package/dist/cdn/trash-2-RwpJY5SL.js +0 -25
- package/dist/cdn/useAriaLabelledBy-DqAdnppm.js +0 -29
- package/dist/cdn/useCompositeItem-BRqEzYh-.js +0 -26
- package/dist/cdn/useConfig-Btmh8wjJ.js +0 -235
- package/dist/cdn/useSavedRequests-Ci2I919u.js +0 -51
- package/dist/cdn/useViewHostProps-B6SKeeH9.js +0 -349
- package/dist/cdn/wrench-DzGmCfnb.js +0 -7
- package/dist/cdn/x-C3vRQIYu.js +0 -10
- package/dist/cdn/zap-Mb-pbw2X.js +0 -10
- package/dist/client/auth/manufact-auth.d.ts +0 -32
- package/dist/client/auth/manufact-auth.d.ts.map +0 -1
- package/dist/client/chat-history/ChatHistoryHeader.d.ts +0 -4
- package/dist/client/chat-history/ChatHistoryHeader.d.ts.map +0 -1
- package/dist/client/chat-history/ChatHistoryPanel.d.ts +0 -28
- package/dist/client/chat-history/ChatHistoryPanel.d.ts.map +0 -1
- package/dist/client/chat-history/ChatHistoryRail.d.ts +0 -5
- package/dist/client/chat-history/ChatHistoryRail.d.ts.map +0 -1
- package/dist/client/chat-history/ChatList.d.ts +0 -18
- package/dist/client/chat-history/ChatList.d.ts.map +0 -1
- package/dist/client/chat-history/ChatTitleReveal.d.ts +0 -10
- package/dist/client/chat-history/ChatTitleReveal.d.ts.map +0 -1
- package/dist/client/chat-history/chat-events-to-inspector-messages.d.ts +0 -13
- package/dist/client/chat-history/chat-events-to-inspector-messages.d.ts.map +0 -1
- package/dist/client/chat-history/chat-title.d.ts +0 -10
- package/dist/client/chat-history/chat-title.d.ts.map +0 -1
- package/dist/client/chat-history/providers/local-storage.d.ts +0 -21
- package/dist/client/chat-history/providers/local-storage.d.ts.map +0 -1
- package/dist/client/chat-history/types.d.ts +0 -39
- package/dist/client/chat-history/types.d.ts.map +0 -1
- package/dist/client/chat-history/useChatHistory.d.ts +0 -20
- package/dist/client/chat-history/useChatHistory.d.ts.map +0 -1
- package/dist/client/chat-history/useChatTitleGeneration.d.ts +0 -17
- package/dist/client/chat-history/useChatTitleGeneration.d.ts.map +0 -1
- package/dist/client/components/AddToClientDropdown.d.ts +0 -52
- package/dist/client/components/AddToClientDropdown.d.ts.map +0 -1
- package/dist/client/components/ChatTab.d.ts +0 -98
- package/dist/client/components/ChatTab.d.ts.map +0 -1
- package/dist/client/components/IframeConsole.d.ts +0 -7
- package/dist/client/components/IframeConsole.d.ts.map +0 -1
- package/dist/client/components/MCPAppsDebugControls.d.ts +0 -19
- package/dist/client/components/MCPAppsDebugControls.d.ts.map +0 -1
- package/dist/client/components/PromptsTab.d.ts +0 -34
- package/dist/client/components/PromptsTab.d.ts.map +0 -1
- package/dist/client/components/ResourcesTab.d.ts +0 -31
- package/dist/client/components/ResourcesTab.d.ts.map +0 -1
- package/dist/client/components/ToolsTab.d.ts +0 -39
- package/dist/client/components/ToolsTab.d.ts.map +0 -1
- package/dist/client/components/chat/AssistantMessage.d.ts +0 -10
- package/dist/client/components/chat/AssistantMessage.d.ts.map +0 -1
- package/dist/client/components/chat/ChatHeader.d.ts +0 -70
- package/dist/client/components/chat/ChatHeader.d.ts.map +0 -1
- package/dist/client/components/chat/ChatInput.d.ts +0 -29
- package/dist/client/components/chat/ChatInput.d.ts.map +0 -1
- package/dist/client/components/chat/ChatInputArea.d.ts +0 -65
- package/dist/client/components/chat/ChatInputArea.d.ts.map +0 -1
- package/dist/client/components/chat/ChatLandingForm.d.ts +0 -15
- package/dist/client/components/chat/ChatLandingForm.d.ts.map +0 -1
- package/dist/client/components/chat/ChatManagedNotice.d.ts +0 -10
- package/dist/client/components/chat/ChatManagedNotice.d.ts.map +0 -1
- package/dist/client/components/chat/ChatScrollToBottomButton.d.ts +0 -7
- package/dist/client/components/chat/ChatScrollToBottomButton.d.ts.map +0 -1
- package/dist/client/components/chat/ChatScrollTopFade.d.ts +0 -7
- package/dist/client/components/chat/ChatScrollTopFade.d.ts.map +0 -1
- package/dist/client/components/chat/ChatTraceView.d.ts +0 -7
- package/dist/client/components/chat/ChatTraceView.d.ts.map +0 -1
- package/dist/client/components/chat/ConfigurationDialog.d.ts +0 -42
- package/dist/client/components/chat/ConfigurationDialog.d.ts.map +0 -1
- package/dist/client/components/chat/ConfigureEmptyState.d.ts +0 -6
- package/dist/client/components/chat/ConfigureEmptyState.d.ts.map +0 -1
- package/dist/client/components/chat/CopyButton.d.ts +0 -10
- package/dist/client/components/chat/CopyButton.d.ts.map +0 -1
- package/dist/client/components/chat/FloatingChatElicitation.d.ts +0 -10
- package/dist/client/components/chat/FloatingChatElicitation.d.ts.map +0 -1
- package/dist/client/components/chat/McpReconnectBanner.d.ts +0 -10
- package/dist/client/components/chat/McpReconnectBanner.d.ts.map +0 -1
- package/dist/client/components/chat/MessageList.d.ts +0 -47
- package/dist/client/components/chat/MessageList.d.ts.map +0 -1
- package/dist/client/components/chat/MessageMetaActions.d.ts +0 -7
- package/dist/client/components/chat/MessageMetaActions.d.ts.map +0 -1
- package/dist/client/components/chat/PromptResultsList.d.ts +0 -8
- package/dist/client/components/chat/PromptResultsList.d.ts.map +0 -1
- package/dist/client/components/chat/PromptsDropdown.d.ts +0 -11
- package/dist/client/components/chat/PromptsDropdown.d.ts.map +0 -1
- package/dist/client/components/chat/StreamingAssistantContent.d.ts +0 -7
- package/dist/client/components/chat/StreamingAssistantContent.d.ts.map +0 -1
- package/dist/client/components/chat/SystemPromptButton.d.ts +0 -11
- package/dist/client/components/chat/SystemPromptButton.d.ts.map +0 -1
- package/dist/client/components/chat/ToolCallDisplay.d.ts +0 -10
- package/dist/client/components/chat/ToolCallDisplay.d.ts.map +0 -1
- package/dist/client/components/chat/ToolResultRenderer.d.ts +0 -15
- package/dist/client/components/chat/ToolResultRenderer.d.ts.map +0 -1
- package/dist/client/components/chat/ToolSelector.d.ts +0 -13
- package/dist/client/components/chat/ToolSelector.d.ts.map +0 -1
- package/dist/client/components/chat/UserMessage.d.ts +0 -10
- package/dist/client/components/chat/UserMessage.d.ts.map +0 -1
- package/dist/client/components/chat/chat-bar-styles.d.ts +0 -6
- package/dist/client/components/chat/chat-bar-styles.d.ts.map +0 -1
- package/dist/client/components/chat/chatModeStorage.d.ts +0 -11
- package/dist/client/components/chat/chatModeStorage.d.ts.map +0 -1
- package/dist/client/components/chat/conversion.d.ts +0 -19
- package/dist/client/components/chat/conversion.d.ts.map +0 -1
- package/dist/client/components/chat/freeTier.d.ts +0 -32
- package/dist/client/components/chat/freeTier.d.ts.map +0 -1
- package/dist/client/components/chat/managedChatNotice.d.ts +0 -16
- package/dist/client/components/chat/managedChatNotice.d.ts.map +0 -1
- package/dist/client/components/chat/providerMeta.d.ts +0 -27
- package/dist/client/components/chat/providerMeta.d.ts.map +0 -1
- package/dist/client/components/chat/system-prompt/local-storage.d.ts +0 -5
- package/dist/client/components/chat/system-prompt/local-storage.d.ts.map +0 -1
- package/dist/client/components/chat/system-prompt/types.d.ts +0 -8
- package/dist/client/components/chat/system-prompt/types.d.ts.map +0 -1
- package/dist/client/components/chat/system-prompt/useLocalSystemPrompt.d.ts +0 -3
- package/dist/client/components/chat/system-prompt/useLocalSystemPrompt.d.ts.map +0 -1
- package/dist/client/components/chat/system-prompt-default.d.ts +0 -2
- package/dist/client/components/chat/system-prompt-default.d.ts.map +0 -1
- package/dist/client/components/chat/trace.d.ts +0 -84
- package/dist/client/components/chat/trace.d.ts.map +0 -1
- package/dist/client/components/chat/types.d.ts +0 -75
- package/dist/client/components/chat/types.d.ts.map +0 -1
- package/dist/client/components/chat/useChatMessages.d.ts +0 -76
- package/dist/client/components/chat/useChatMessages.d.ts.map +0 -1
- package/dist/client/components/chat/useChatMessagesClientSide.d.ts +0 -43
- package/dist/client/components/chat/useChatMessagesClientSide.d.ts.map +0 -1
- package/dist/client/components/chat/useChatScrollToBottom.d.ts +0 -14
- package/dist/client/components/chat/useChatScrollToBottom.d.ts.map +0 -1
- package/dist/client/components/chat/useConfig.d.ts +0 -24
- package/dist/client/components/chat/useConfig.d.ts.map +0 -1
- package/dist/client/components/chat/useHostedChatMode.d.ts +0 -14
- package/dist/client/components/chat/useHostedChatMode.d.ts.map +0 -1
- package/dist/client/components/chat/useManagedCloudModel.d.ts +0 -14
- package/dist/client/components/chat/useManagedCloudModel.d.ts.map +0 -1
- package/dist/client/components/chat/utils.d.ts +0 -11
- package/dist/client/components/chat/utils.d.ts.map +0 -1
- package/dist/client/components/elicitation/shared/ElicitationAskUserPanel.d.ts +0 -12
- package/dist/client/components/elicitation/shared/ElicitationAskUserPanel.d.ts.map +0 -1
- package/dist/client/components/elicitation/shared/elicitationToAskUserQuestions.d.ts +0 -9
- package/dist/client/components/elicitation/shared/elicitationToAskUserQuestions.d.ts.map +0 -1
- package/dist/client/components/elicitation/shared/schemaHelpers.d.ts +0 -8
- package/dist/client/components/elicitation/shared/schemaHelpers.d.ts.map +0 -1
- package/dist/client/components/prompts/PromptExecutionPanel.d.ts +0 -13
- package/dist/client/components/prompts/PromptExecutionPanel.d.ts.map +0 -1
- package/dist/client/components/prompts/PromptInputForm.d.ts +0 -9
- package/dist/client/components/prompts/PromptInputForm.d.ts.map +0 -1
- package/dist/client/components/prompts/PromptMessageCard.d.ts +0 -29
- package/dist/client/components/prompts/PromptMessageCard.d.ts.map +0 -1
- package/dist/client/components/prompts/PromptResultDisplay.d.ts +0 -34
- package/dist/client/components/prompts/PromptResultDisplay.d.ts.map +0 -1
- package/dist/client/components/prompts/PromptsList.d.ts +0 -10
- package/dist/client/components/prompts/PromptsList.d.ts.map +0 -1
- package/dist/client/components/prompts/SavedPromptsList.d.ts +0 -19
- package/dist/client/components/prompts/SavedPromptsList.d.ts.map +0 -1
- package/dist/client/components/resources/PropsConfigDialog.d.ts +0 -16
- package/dist/client/components/resources/PropsConfigDialog.d.ts.map +0 -1
- package/dist/client/components/resources/ResourceResultDisplay.d.ts +0 -30
- package/dist/client/components/resources/ResourceResultDisplay.d.ts.map +0 -1
- package/dist/client/components/resources/ResourcesList.d.ts +0 -10
- package/dist/client/components/resources/ResourcesList.d.ts.map +0 -1
- package/dist/client/components/shared/CollapsibleJSON.d.ts +0 -6
- package/dist/client/components/shared/CollapsibleJSON.d.ts.map +0 -1
- package/dist/client/components/shared/InspectorScrollArea.d.ts +0 -9
- package/dist/client/components/shared/InspectorScrollArea.d.ts.map +0 -1
- package/dist/client/components/shared/JSONDisplay.d.ts +0 -12
- package/dist/client/components/shared/JSONDisplay.d.ts.map +0 -1
- package/dist/client/components/shared/ListItem.d.ts +0 -24
- package/dist/client/components/shared/ListItem.d.ts.map +0 -1
- package/dist/client/components/shared/ListTabHeader.d.ts +0 -47
- package/dist/client/components/shared/ListTabHeader.d.ts.map +0 -1
- package/dist/client/components/shared/MarkdownRenderer.d.ts +0 -15
- package/dist/client/components/shared/MarkdownRenderer.d.ts.map +0 -1
- package/dist/client/components/shared/SchemaFormField.d.ts +0 -12
- package/dist/client/components/shared/SchemaFormField.d.ts.map +0 -1
- package/dist/client/components/shared/SearchTabHeader.d.ts +0 -28
- package/dist/client/components/shared/SearchTabHeader.d.ts.map +0 -1
- package/dist/client/components/shared/StatusIcon.d.ts +0 -12
- package/dist/client/components/shared/StatusIcon.d.ts.map +0 -1
- package/dist/client/components/shared/index.d.ts +0 -7
- package/dist/client/components/shared/index.d.ts.map +0 -1
- package/dist/client/components/tools/SaveRequestDialog.d.ts +0 -11
- package/dist/client/components/tools/SaveRequestDialog.d.ts.map +0 -1
- package/dist/client/components/tools/SavedRequestsList.d.ts +0 -19
- package/dist/client/components/tools/SavedRequestsList.d.ts.map +0 -1
- package/dist/client/components/tools/ToolExecutionPanel.d.ts +0 -20
- package/dist/client/components/tools/ToolExecutionPanel.d.ts.map +0 -1
- package/dist/client/components/tools/ToolInputForm.d.ts +0 -14
- package/dist/client/components/tools/ToolInputForm.d.ts.map +0 -1
- package/dist/client/components/tools/ToolResultDisplay.d.ts +0 -24
- package/dist/client/components/tools/ToolResultDisplay.d.ts.map +0 -1
- package/dist/client/components/tools/ToolsList.d.ts +0 -10
- package/dist/client/components/tools/ToolsList.d.ts.map +0 -1
- package/dist/client/components/tools/schema-utils.d.ts +0 -13
- package/dist/client/components/tools/schema-utils.d.ts.map +0 -1
- package/dist/client/components/tools/useToolExecution.d.ts +0 -26
- package/dist/client/components/tools/useToolExecution.d.ts.map +0 -1
- package/dist/client/components/tools/useToolsTabNavigation.d.ts +0 -35
- package/dist/client/components/tools/useToolsTabNavigation.d.ts.map +0 -1
- package/dist/client/components/ui/MeshGradientCanvas.d.ts +0 -13
- package/dist/client/components/ui/MeshGradientCanvas.d.ts.map +0 -1
- package/dist/client/components/ui/WidgetWrapper.d.ts +0 -12
- package/dist/client/components/ui/WidgetWrapper.d.ts.map +0 -1
- package/dist/client/components/ui/alert-dialog.d.ts +0 -15
- package/dist/client/components/ui/alert-dialog.d.ts.map +0 -1
- package/dist/client/components/ui/ask-user-questions.d.ts +0 -80
- package/dist/client/components/ui/ask-user-questions.d.ts.map +0 -1
- package/dist/client/components/ui/badge.d.ts +0 -34
- package/dist/client/components/ui/badge.d.ts.map +0 -1
- package/dist/client/components/ui/blur-fade.d.ts +0 -25
- package/dist/client/components/ui/blur-fade.d.ts.map +0 -1
- package/dist/client/components/ui/button.d.ts +0 -34
- package/dist/client/components/ui/button.d.ts.map +0 -1
- package/dist/client/components/ui/chat-message.d.ts +0 -23
- package/dist/client/components/ui/chat-message.d.ts.map +0 -1
- package/dist/client/components/ui/checkbox.d.ts +0 -4
- package/dist/client/components/ui/checkbox.d.ts.map +0 -1
- package/dist/client/components/ui/client-icons.d.ts +0 -20
- package/dist/client/components/ui/client-icons.d.ts.map +0 -1
- package/dist/client/components/ui/command.d.ts +0 -17
- package/dist/client/components/ui/command.d.ts.map +0 -1
- package/dist/client/components/ui/dialog.d.ts +0 -37
- package/dist/client/components/ui/dialog.d.ts.map +0 -1
- package/dist/client/components/ui/dropdown-menu.d.ts +0 -25
- package/dist/client/components/ui/dropdown-menu.d.ts.map +0 -1
- package/dist/client/components/ui/dropdown.d.ts +0 -30
- package/dist/client/components/ui/dropdown.d.ts.map +0 -1
- package/dist/client/components/ui/file-thumbnail.d.ts +0 -9
- package/dist/client/components/ui/file-thumbnail.d.ts.map +0 -1
- package/dist/client/components/ui/input.d.ts +0 -4
- package/dist/client/components/ui/input.d.ts.map +0 -1
- package/dist/client/components/ui/kbd.d.ts +0 -3
- package/dist/client/components/ui/kbd.d.ts.map +0 -1
- package/dist/client/components/ui/label.d.ts +0 -4
- package/dist/client/components/ui/label.d.ts.map +0 -1
- package/dist/client/components/ui/menu-item.d.ts +0 -52
- package/dist/client/components/ui/menu-item.d.ts.map +0 -1
- package/dist/client/components/ui/mesh-tab-background.d.ts +0 -12
- package/dist/client/components/ui/mesh-tab-background.d.ts.map +0 -1
- package/dist/client/components/ui/not-found.d.ts +0 -9
- package/dist/client/components/ui/not-found.d.ts.map +0 -1
- package/dist/client/components/ui/popover.d.ts +0 -6
- package/dist/client/components/ui/popover.d.ts.map +0 -1
- package/dist/client/components/ui/resizable.d.ts +0 -10
- package/dist/client/components/ui/resizable.d.ts.map +0 -1
- package/dist/client/components/ui/scroll-area.d.ts +0 -4
- package/dist/client/components/ui/scroll-area.d.ts.map +0 -1
- package/dist/client/components/ui/select.d.ts +0 -52
- package/dist/client/components/ui/select.d.ts.map +0 -1
- package/dist/client/components/ui/sheet.d.ts +0 -14
- package/dist/client/components/ui/sheet.d.ts.map +0 -1
- package/dist/client/components/ui/skeleton.d.ts +0 -4
- package/dist/client/components/ui/skeleton.d.ts.map +0 -1
- package/dist/client/components/ui/spinner.d.ts +0 -3
- package/dist/client/components/ui/spinner.d.ts.map +0 -1
- package/dist/client/components/ui/switch.d.ts +0 -22
- package/dist/client/components/ui/switch.d.ts.map +0 -1
- package/dist/client/components/ui/table.d.ts +0 -9
- package/dist/client/components/ui/table.d.ts.map +0 -1
- package/dist/client/components/ui/tabs-subtle.d.ts +0 -25
- package/dist/client/components/ui/tabs-subtle.d.ts.map +0 -1
- package/dist/client/components/ui/text-shimmer.d.ts +0 -11
- package/dist/client/components/ui/text-shimmer.d.ts.map +0 -1
- package/dist/client/components/ui/textarea.d.ts +0 -4
- package/dist/client/components/ui/textarea.d.ts.map +0 -1
- package/dist/client/components/ui/tooltip.d.ts +0 -43
- package/dist/client/components/ui/tooltip.d.ts.map +0 -1
- package/dist/client/components/ui-playground/shared/SafeAreaInsetsEditor.d.ts +0 -19
- package/dist/client/components/ui-playground/shared/SafeAreaInsetsEditor.d.ts.map +0 -1
- package/dist/client/console-log-bus.d.ts +0 -24
- package/dist/client/console-log-bus.d.ts.map +0 -1
- package/dist/client/constants/debug-options.d.ts +0 -16
- package/dist/client/constants/debug-options.d.ts.map +0 -1
- package/dist/client/context/InspectorContext.d.ts +0 -134
- package/dist/client/context/InspectorContext.d.ts.map +0 -1
- package/dist/client/context/ThemeContext.d.ts +0 -17
- package/dist/client/context/ThemeContext.d.ts.map +0 -1
- package/dist/client/context/WidgetDebugContext.d.ts +0 -121
- package/dist/client/context/WidgetDebugContext.d.ts.map +0 -1
- package/dist/client/hooks/use-merge-split.d.ts +0 -36
- package/dist/client/hooks/use-merge-split.d.ts.map +0 -1
- package/dist/client/hooks/use-proximity-hover-index.d.ts +0 -27
- package/dist/client/hooks/use-proximity-hover-index.d.ts.map +0 -1
- package/dist/client/hooks/use-proximity-hover.d.ts +0 -26
- package/dist/client/hooks/use-proximity-hover.d.ts.map +0 -1
- package/dist/client/hooks/use-touch-primary.d.ts +0 -2
- package/dist/client/hooks/use-touch-primary.d.ts.map +0 -1
- package/dist/client/hooks/useDeviceViewport.d.ts +0 -18
- package/dist/client/hooks/useDeviceViewport.d.ts.map +0 -1
- package/dist/client/hooks/useHostedSession.d.ts +0 -9
- package/dist/client/hooks/useHostedSession.d.ts.map +0 -1
- package/dist/client/hooks/useIframeConsole.d.ts +0 -24
- package/dist/client/hooks/useIframeConsole.d.ts.map +0 -1
- package/dist/client/hooks/useKeyboardShortcuts.d.ts +0 -28
- package/dist/client/hooks/useKeyboardShortcuts.d.ts.map +0 -1
- package/dist/client/hooks/useMCPPrompts.d.ts +0 -94
- package/dist/client/hooks/useMCPPrompts.d.ts.map +0 -1
- package/dist/client/hooks/useMcpAppsHostContext.d.ts +0 -27
- package/dist/client/hooks/useMcpAppsHostContext.d.ts.map +0 -1
- package/dist/client/hooks/usePropsLLM.d.ts +0 -20
- package/dist/client/hooks/usePropsLLM.d.ts.map +0 -1
- package/dist/client/hooks/useResourceProps.d.ts +0 -14
- package/dist/client/hooks/useResourceProps.d.ts.map +0 -1
- package/dist/client/hooks/useSavedRequests.d.ts +0 -6
- package/dist/client/hooks/useSavedRequests.d.ts.map +0 -1
- package/dist/client/hooks/useViewHostProps.d.ts +0 -19
- package/dist/client/hooks/useViewHostProps.d.ts.map +0 -1
- package/dist/client/index.d.ts.map +0 -1
- package/dist/client/lib/elevated.d.ts +0 -28
- package/dist/client/lib/elevated.d.ts.map +0 -1
- package/dist/client/lib/font-weight.d.ts +0 -10
- package/dist/client/lib/font-weight.d.ts.map +0 -1
- package/dist/client/lib/icon-context.d.ts +0 -15
- package/dist/client/lib/icon-context.d.ts.map +0 -1
- package/dist/client/lib/shape-context.d.ts +0 -21
- package/dist/client/lib/shape-context.d.ts.map +0 -1
- package/dist/client/lib/springs.d.ts +0 -32
- package/dist/client/lib/springs.d.ts.map +0 -1
- package/dist/client/lib/surface-classes.d.ts +0 -2
- package/dist/client/lib/surface-classes.d.ts.map +0 -1
- package/dist/client/lib/surface-context.d.ts +0 -7
- package/dist/client/lib/surface-context.d.ts.map +0 -1
- package/dist/client/lib/utils.d.ts +0 -3
- package/dist/client/lib/utils.d.ts.map +0 -1
- package/dist/client/mcp-apps/csp.d.ts +0 -26
- package/dist/client/mcp-apps/csp.d.ts.map +0 -1
- package/dist/client/mcp-apps/debug/csp-suggestions.d.ts +0 -17
- package/dist/client/mcp-apps/debug/csp-suggestions.d.ts.map +0 -1
- package/dist/client/mcp-apps/logging-transport.d.ts +0 -13
- package/dist/client/mcp-apps/logging-transport.d.ts.map +0 -1
- package/dist/client/rpc-traffic-coalesce.d.ts +0 -7
- package/dist/client/rpc-traffic-coalesce.d.ts.map +0 -1
- package/dist/client/rpc-traffic-store.d.ts +0 -37
- package/dist/client/rpc-traffic-store.d.ts.map +0 -1
- package/dist/client/telemetry/capture.d.ts +0 -7
- package/dist/client/telemetry/capture.d.ts.map +0 -1
- package/dist/client/telemetry/events.d.ts +0 -168
- package/dist/client/telemetry/events.d.ts.map +0 -1
- package/dist/client/telemetry/index.d.ts +0 -5
- package/dist/client/telemetry/index.d.ts.map +0 -1
- package/dist/client/telemetry/init.d.ts +0 -2
- package/dist/client/telemetry/init.d.ts.map +0 -1
- package/dist/client/telemetry/utils.d.ts +0 -7
- package/dist/client/telemetry/utils.d.ts.map +0 -1
- package/dist/client/types/message-content-block.d.ts +0 -19
- package/dist/client/types/message-content-block.d.ts.map +0 -1
- package/dist/client/types/pending-requests.d.ts +0 -17
- package/dist/client/types/pending-requests.d.ts.map +0 -1
- package/dist/client/utils/basePath.d.ts +0 -34
- package/dist/client/utils/basePath.d.ts.map +0 -1
- package/dist/client/utils/browser.d.ts +0 -5
- package/dist/client/utils/browser.d.ts.map +0 -1
- package/dist/client/utils/format.d.ts +0 -4
- package/dist/client/utils/format.d.ts.map +0 -1
- package/dist/client/utils/highlightJson.d.ts +0 -11
- package/dist/client/utils/highlightJson.d.ts.map +0 -1
- package/dist/client/utils/jsonUtils.d.ts +0 -24
- package/dist/client/utils/jsonUtils.d.ts.map +0 -1
- package/dist/client/utils/mcpClientUtils.d.ts +0 -131
- package/dist/client/utils/mcpClientUtils.d.ts.map +0 -1
- package/dist/client/utils/servers.d.ts +0 -14
- package/dist/client/utils/servers.d.ts.map +0 -1
- package/dist/server/asset-urls.d.ts +0 -18
- package/dist/server/asset-urls.d.ts.map +0 -1
- package/dist/server/asset-urls.js +0 -17
- package/dist/server/cdn-shell.d.ts +0 -18
- package/dist/server/cdn-shell.d.ts.map +0 -1
- package/dist/server/cdn-shell.js +0 -12
- package/dist/server/chunk-DSTNUYWX.js +0 -148
- package/dist/server/chunk-H6ZCIKBS.js +0 -63
- package/dist/server/chunk-IKTZUWSX.js +0 -0
- package/dist/server/chunk-J4FNYLBF.js +0 -54
- package/dist/server/chunk-K2F2AJOI.js +0 -619
- package/dist/server/chunk-KD7K27XK.js +0 -77
- package/dist/server/chunk-M5TZA42I.js +0 -54
- package/dist/server/chunk-OWR2BIBW.js +0 -40
- package/dist/server/chunk-PKBMQBKP.js +0 -7
- package/dist/server/chunk-SQ4XNMLT.js +0 -72
- package/dist/server/chunk-UJLXHNQP.js +0 -43
- package/dist/server/chunk-WFT4JHYI.js +0 -24
- package/dist/server/chunk-XCNS5CIW.js +0 -199
- package/dist/server/chunk-ZCGLU5T7.js +0 -156
- package/dist/server/cli.d.ts +0 -3
- package/dist/server/cli.d.ts.map +0 -1
- package/dist/server/cli.js +0 -141
- package/dist/server/create-dev-api-app.d.ts +0 -4
- package/dist/server/create-dev-api-app.d.ts.map +0 -1
- package/dist/server/create-dev-api-app.js +0 -11
- package/dist/server/dev-callback-redirect.d.ts +0 -3
- package/dist/server/dev-callback-redirect.d.ts.map +0 -1
- package/dist/server/dev-callback-redirect.js +0 -18
- package/dist/server/favicon-links.d.ts +0 -12
- package/dist/server/favicon-links.d.ts.map +0 -1
- package/dist/server/favicon-links.js +0 -11
- package/dist/server/favicon-static.d.ts +0 -4
- package/dist/server/favicon-static.d.ts.map +0 -1
- package/dist/server/favicon-static.js +0 -8
- package/dist/server/index.d.ts.map +0 -1
- package/dist/server/middleware.d.ts +0 -40
- package/dist/server/middleware.d.ts.map +0 -1
- package/dist/server/middleware.js +0 -17
- package/dist/server/proxy/index.d.ts +0 -3
- package/dist/server/proxy/index.d.ts.map +0 -1
- package/dist/server/proxy/index.js +0 -12
- package/dist/server/proxy/mcp-proxy.d.ts +0 -101
- package/dist/server/proxy/mcp-proxy.d.ts.map +0 -1
- package/dist/server/proxy/mcp-proxy.js +0 -10
- package/dist/server/proxy/oauth-proxy.d.ts +0 -26
- package/dist/server/proxy/oauth-proxy.d.ts.map +0 -1
- package/dist/server/proxy/oauth-proxy.js +0 -9
- package/dist/server/proxy-routes.d.ts +0 -16
- package/dist/server/proxy-routes.d.ts.map +0 -1
- package/dist/server/proxy-routes.js +0 -10
- package/dist/server/rpc-log-bus.d.ts +0 -17
- package/dist/server/rpc-log-bus.d.ts.map +0 -1
- package/dist/server/rpc-log-bus.js +0 -77
- package/dist/server/server.d.ts +0 -15
- package/dist/server/server.d.ts.map +0 -1
- package/dist/server/server.js +0 -66
- package/dist/server/static-assets.d.ts +0 -5
- package/dist/server/static-assets.d.ts.map +0 -1
- package/dist/server/static-assets.js +0 -9
- package/dist/server/utils.d.ts +0 -33
- package/dist/server/utils.d.ts.map +0 -1
- package/dist/server/utils.js +0 -17
- package/dist/server/version.d.ts +0 -7
- package/dist/server/version.d.ts.map +0 -1
- package/dist/server/version.js +0 -9
- package/dist/server/vite-dev-api-plugin.d.ts +0 -4
- package/dist/server/vite-dev-api-plugin.d.ts.map +0 -1
- package/dist/server/vite-dev-api-plugin.js +0 -30
- package/dist/web/apple-touch-icon.png +0 -0
- package/dist/web/assets/AnimatePresence-C5p0yiY1.js +0 -9
- package/dist/web/assets/ChatTab-BCobuZDc.js +0 -18
- package/dist/web/assets/ConnectionSettingsTab-BjGkLwVu.js +0 -1
- package/dist/web/assets/ElicitationTab-D3ZUKHND.js +0 -1
- package/dist/web/assets/FormContext-DH2caWKO.js +0 -1
- package/dist/web/assets/ListTabHeader-R17w_JsB.js +0 -1
- package/dist/web/assets/ManufactOAuthCallback-CS3ydSZg.js +0 -1
- package/dist/web/assets/MarkdownRenderer-BeeBfQhv.js +0 -47
- package/dist/web/assets/NotificationsTab-Uj0_DrmK.js +0 -1
- package/dist/web/assets/OAuthCallback-C0ljgCiw.js +0 -1
- package/dist/web/assets/PromptsTab-Bns2u0G-.js +0 -15
- package/dist/web/assets/ResourcesTab-CO24312V.js +0 -2
- package/dist/web/assets/SamplingTab-7gtN7FwU.js +0 -1
- package/dist/web/assets/ServerMetadataTab-CQwqYSjL.js +0 -1
- package/dist/web/assets/ToolsTab-bDdRxI1b.js +0 -8
- package/dist/web/assets/ViewPreview-Ba1Ec5uA.js +0 -1
- package/dist/web/assets/WidgetWrapper-CYHfzrtb.js +0 -34
- package/dist/web/assets/brush--0LobUi4.js +0 -1
- package/dist/web/assets/checkbox-CzBkaNKa.js +0 -1
- package/dist/web/assets/code-tME-5H6D.js +0 -1
- package/dist/web/assets/createLucideIcon-B3b8EU0b.js +0 -1
- package/dist/web/assets/dist-C5JjLJN9.js +0 -21
- package/dist/web/assets/index-TQ5V7cM9.js +0 -492
- package/dist/web/assets/index-fBX3akc8.css +0 -1
- package/dist/web/assets/input-CLYhA7PK.js +0 -1
- package/dist/web/assets/inspector-settings-layout-yjKRJDai.js +0 -1
- package/dist/web/assets/jsx-runtime-Cjj9sGSy.js +0 -1
- package/dist/web/assets/label-Cdim77Jw.js +0 -1
- package/dist/web/assets/maximize-2-BTT9QQU9.js +0 -1
- package/dist/web/assets/maximize-_O55kFcr.js +0 -1
- package/dist/web/assets/react-CU_d2d5K.js +0 -1
- package/dist/web/assets/refresh-cw-C9wQl8_d.js +0 -1
- package/dist/web/assets/save-B-MsgxX9.js +0 -1
- package/dist/web/assets/schemaHelpers-DLNTQr_6.js +0 -1
- package/dist/web/assets/select-CJ57-Bor.js +0 -1
- package/dist/web/assets/shared-BF0rJNdE.js +0 -1
- package/dist/web/assets/sparkles-2OAsc1aP.js +0 -1
- package/dist/web/assets/tabs-subtle-6D79T1xd.js +0 -1
- package/dist/web/assets/textarea-DLAmNVf_.js +0 -1
- package/dist/web/assets/useConfig-BAgALiZg.js +0 -1
- package/dist/web/assets/useViewHostProps-BYitt_6K.js +0 -1
- package/dist/web/assets/zap-Du2Uc5pa.js +0 -1
- package/dist/web/favicon-96x96.png +0 -0
- package/dist/web/favicon-black.svg +0 -5
- package/dist/web/favicon-white.svg +0 -5
- package/dist/web/favicon.ico +0 -0
- package/dist/web/favicon.svg +0 -5
- package/dist/web/index.html +0 -89
- package/dist/web/providers/anthropic.png +0 -0
- package/dist/web/providers/google.png +0 -0
- package/dist/web/providers/openai.png +0 -0
- package/dist/web/site.webmanifest +0 -21
- package/dist/web/web-app-manifest-192x192.png +0 -0
- package/dist/web/web-app-manifest-512x512.png +0 -0
- /package/dist/{cdn → app}/apple-touch-icon.png +0 -0
- /package/dist/{cdn → app}/favicon-96x96.png +0 -0
- /package/dist/{cdn → app}/favicon-black.svg +0 -0
- /package/dist/{cdn → app}/favicon-white.svg +0 -0
- /package/dist/{cdn → app}/favicon.ico +0 -0
- /package/dist/{cdn → app}/favicon.svg +0 -0
- /package/dist/{cdn → app}/site.webmanifest +0 -0
- /package/dist/{cdn → app}/web-app-manifest-192x192.png +0 -0
- /package/dist/{cdn → app}/web-app-manifest-512x512.png +0 -0
package/dist/cli.js
CHANGED
|
@@ -1,392 +1,336 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
+
var hn=Object.create;var Pt=Object.defineProperty;var mn=Object.getOwnPropertyDescriptor;var gn=Object.getOwnPropertyNames;var wn=Object.getPrototypeOf,yn=Object.prototype.hasOwnProperty;var re=(e,t)=>()=>(t||e((t={exports:{}}).exports,t),t.exports);var bn=(e,t,r,n)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of gn(t))!yn.call(e,o)&&o!==r&&Pt(e,o,{get:()=>t[o],enumerable:!(n=mn(t,o))||n.enumerable});return e};var vn=(e,t,r)=>(r=e!=null?hn(wn(e)):{},bn(t||!e||!e.__esModule?Pt(r,"default",{value:e,enumerable:!0}):r,e));var Ar=re((bc,Pr)=>{"use strict";Pr.exports=class{constructor(t={}){this.points=t.points,this.duration=t.duration,this.blockDuration=t.blockDuration,this.execEvenly=t.execEvenly,this.execEvenlyMinDelayMs=t.execEvenlyMinDelayMs,this.keyPrefix=t.keyPrefix}get points(){return this._points}set points(t){if(Number.isFinite(t))this._points=t;else throw new Error("points must be set and must be a finite number")}get duration(){return this._duration}set duration(t){if(typeof t=="number"&&Number.isFinite(t)&&t>=0)this._duration=t;else throw new Error("duration must be set and must be a finite, non-negative number")}get msDuration(){return this.duration*1e3}get blockDuration(){return this._blockDuration}set blockDuration(t){this._blockDuration=typeof t>"u"?0:t}get msBlockDuration(){return this.blockDuration*1e3}get execEvenly(){return this._execEvenly}set execEvenly(t){this._execEvenly=typeof t>"u"?!1:!!t}get execEvenlyMinDelayMs(){return this._execEvenlyMinDelayMs===void 0?this._getExecEvenlyMinDelayMsDefault():this._execEvenlyMinDelayMs}set execEvenlyMinDelayMs(t){this._execEvenlyMinDelayMs=t}_getExecEvenlyMinDelayMsDefault(){return this.points>0?Math.ceil(this.msDuration/this.points):0}get keyPrefix(){return this._keyPrefix}set keyPrefix(t){if(typeof t>"u"&&(t="rlflx"),typeof t!="string")throw new Error("keyPrefix must be string");this._keyPrefix=t}_getKeySecDuration(t={}){return t&&t.customDuration>=0?t.customDuration:this.duration}getKey(t){return this.keyPrefix.length>0?`${this.keyPrefix}:${t}`:t}parseKey(t){return this.keyPrefix.length>0?t.substring(this.keyPrefix.length+1):t}consume(){throw new Error("You have to implement the method 'consume'!")}penalty(){throw new Error("You have to implement the method 'penalty'!")}reward(){throw new Error("You have to implement the method 'reward'!")}get(){throw new Error("You have to implement the method 'get'!")}set(){throw new Error("You have to implement the method 'set'!")}block(){throw new Error("You have to implement the method 'block'!")}delete(){throw new Error("You have to implement the method 'delete'!")}}});var Cr=re((xc,_r)=>{"use strict";_r.exports=class{constructor(t,r,n=null){this.value=t,this.expiresAt=r,this.timeoutId=n}get value(){return this._value}set value(t){this._value=parseInt(t,10)}get expiresAt(){return this._expiresAt}set expiresAt(t){t instanceof Date?this._expiresAt=t.getTime():this._expiresAt=t}get timeoutId(){return this._timeoutId}set timeoutId(t){this._timeoutId=t}}});var ht=re((Ec,Or)=>{"use strict";Or.exports=class{constructor(t,r,n,o){this.remainingPoints=typeof t>"u"?0:t,this.msBeforeNext=typeof r>"u"?0:r,this.consumedPoints=typeof n>"u"?0:n,this.isFirstInDuration=typeof o>"u"?!1:o}get msBeforeNext(){return this._msBeforeNext}set msBeforeNext(t){return this._msBeforeNext=t,this}get remainingPoints(){return this._remainingPoints}set remainingPoints(t){return this._remainingPoints=t,this}get consumedPoints(){return this._consumedPoints}set consumedPoints(t){return this._consumedPoints=t,this}get isFirstInDuration(){return this._isFirstInDuration}set isFirstInDuration(t){this._isFirstInDuration=!!t}_getDecoratedProperties(){return{remainingPoints:this.remainingPoints,msBeforeNext:this.msBeforeNext,consumedPoints:this.consumedPoints,isFirstInDuration:this.isFirstInDuration}}[Symbol.for("nodejs.util.inspect.custom")](){return this._getDecoratedProperties()}toString(){return JSON.stringify(this._getDecoratedProperties())}toJSON(){return this._getDecoratedProperties()}}});var Mr=re((Pc,Lr)=>{"use strict";var Tr=Cr(),mt=ht();Lr.exports=class{constructor(){this._storage=new Map}incrby(t,r,n){let o=this._storage.get(t);if(o){let s=o.expiresAt?o.expiresAt-Date.now():-1;return!o.expiresAt||s>0?(o.value=o.value+r,new mt(0,s,o.value,!1)):this.set(t,r,n)}return this.set(t,r,n)}set(t,r,n){let o=n*1e3,s=this._storage.get(t);s&&s.timeoutId&&clearTimeout(s.timeoutId);let i=new Tr(r,o>0?Date.now()+o:null);return this._storage.set(t,i),o>0&&(i.timeoutId=setTimeout(()=>{this._storage.delete(t)},o),i.timeoutId.unref&&i.timeoutId.unref()),new mt(0,o===0?-1:o,i.value,!0)}get(t){let r=this._storage.get(t);if(r){let n=r.expiresAt?r.expiresAt-Date.now():-1;return new mt(0,n,r.value,!1)}return null}delete(t){let r=this._storage.get(t);return r?(r.timeoutId&&clearTimeout(r.timeoutId),this._storage.delete(t),!0):!1}_restoreRecord(t,r,n){let o=Date.now(),s=n!==null;if(s&&!Number.isFinite(n)||s&&n<=o)return;let i=s?n-o:0,a=this._storage.get(t);a&&a.timeoutId&&clearTimeout(a.timeoutId);let c=new Tr(r,n);this._storage.set(t,c),i>0&&(c.timeoutId=setTimeout(()=>{this._storage.delete(t)},i),c.timeoutId.unref&&c.timeoutId.unref())}}});var Dr=re((Ac,kr)=>{"use strict";var $o=Ar(),Fo=Mr(),Ir=ht(),gt=class extends $o{constructor(t={}){super(t),this._memoryStorage=new Fo}consume(t,r=1,n={}){return new Promise((o,s)=>{let i=this.getKey(t),a=this._getKeySecDuration(n),c=this._memoryStorage.incrby(i,r,a);if(c.remainingPoints=Math.max(this.points-c.consumedPoints,0),c.consumedPoints>this.points)this.blockDuration>0&&c.consumedPoints<=this.points+r&&(c=this._memoryStorage.set(i,c.consumedPoints,this.blockDuration)),s(c);else if(this.execEvenly&&this.points>0&&c.msBeforeNext>0&&!c.isFirstInDuration){let l=Math.ceil(c.msBeforeNext/(c.remainingPoints+2));l<this.execEvenlyMinDelayMs&&(l=c.consumedPoints*this.execEvenlyMinDelayMs),c.msBeforeNext=Math.max(c.msBeforeNext-l,0),setTimeout(o,l,c)}else o(c)})}penalty(t,r=1,n={}){let o=this.getKey(t);return new Promise(s=>{let i=this._getKeySecDuration(n),a=this._memoryStorage.incrby(o,r,i);a.remainingPoints=Math.max(this.points-a.consumedPoints,0),s(a)})}reward(t,r=1,n={}){let o=this.getKey(t);return new Promise(s=>{let i=this._getKeySecDuration(n),a=this._memoryStorage.incrby(o,-r,i);a.remainingPoints=Math.max(this.points-a.consumedPoints,0),s(a)})}block(t,r){let n=r*1e3,o=this.points+1;return this._memoryStorage.set(this.getKey(t),o,r),Promise.resolve(new Ir(0,n===0?-1:n,o))}set(t,r,n){let o=(n>=0?n:this.duration)*1e3;return this._memoryStorage.set(this.getKey(t),r,n),Promise.resolve(new Ir(0,o===0?-1:o,r))}get(t){let r=this._memoryStorage.get(this.getKey(t));return r!==null&&(r.remainingPoints=Math.max(this.points-r.consumedPoints,0)),Promise.resolve(r)}delete(t){return Promise.resolve(this._memoryStorage.delete(this.getKey(t)))}dump(){let t=[];for(let[r,n]of this._memoryStorage._storage)t.push({key:this.parseKey(r),value:n.value,expiresAt:n.expiresAt});return{version:1,dumpedAt:Date.now(),storage:t}}restore(t,r=!1){if(!t||typeof t!="object"||t.version!==1)return;let n=r?{invalid:{count:0,keys:[]},expired:{count:0,keys:[]},restored:{count:0,keys:[]}}:{invalid:0,expired:0,restored:0},o=(s,i)=>{r?(n[s].count+=1,n[s].keys.push(i)):n[s]+=1};if(!Array.isArray(t.storage))return n;for(let s of t.storage){if(!s||typeof s!="object"){o("invalid","N/A");continue}let i=typeof s.key=="string"||typeof s.key=="number",a=Number.isFinite(s.value),c=s.expiresAt===null||Number.isFinite(s.expiresAt);if(!i||!a||!c){o("invalid",s.key);continue}if(s.expiresAt!==null&&s.expiresAt<=Date.now()){o("expired",s.key);continue}this._memoryStorage._restoreRecord(this.getKey(s.key),s.value,s.expiresAt),o("restored",s.key)}return n}};kr.exports=gt});import{createServer as xn}from"http";import{Http2ServerRequest as Ot,constants as Sn}from"http2";import{Http2ServerRequest as De}from"http2";import{Readable as At}from"stream";import kn from"crypto";var F=class extends Error{constructor(e,t){super(e,t),this.name="RequestError"}},En=e=>e instanceof F?e:new F(e.message,{cause:e}),Rn=global.Request,ne=class extends Rn{constructor(e,t){typeof e=="object"&&Y in e&&(e=e[Y]()),typeof t?.body?.getReader<"u"&&(t.duplex??="half"),super(e,t)}},Pn=e=>{let t=[],r=e.rawHeaders;for(let n=0;n<r.length;n+=2){let{[n]:o,[n+1]:s}=r;o.charCodeAt(0)!==58&&t.push([o,s])}return new Headers(t)},Tt=Symbol("wrapBodyStream"),An=(e,t,r,n,o)=>{let s={method:e,headers:r,signal:o.signal};if(e==="TRACE"){s.method="GET";let i=new ne(t,s);return Object.defineProperty(i,"method",{get(){return"TRACE"}}),i}if(!(e==="GET"||e==="HEAD"))if("rawBody"in n&&n.rawBody instanceof Buffer)s.body=new ReadableStream({start(i){i.enqueue(n.rawBody),i.close()}});else if(n[Tt]){let i;s.body=new ReadableStream({async pull(a){try{i||=At.toWeb(n).getReader();let{done:c,value:l}=await i.read();c?a.close():a.enqueue(l)}catch(c){a.error(c)}}})}else s.body=At.toWeb(n);return new ne(t,s)},Y=Symbol("getRequestCache"),_n=Symbol("requestCache"),fe=Symbol("incomingKey"),he=Symbol("urlKey"),Cn=Symbol("headersKey"),X=Symbol("abortControllerKey"),On=Symbol("getAbortController"),me={get method(){return this[fe].method||"GET"},get url(){return this[he]},get headers(){return this[Cn]||=Pn(this[fe])},[On](){return this[Y](),this[X]},[Y](){return this[X]||=new AbortController,this[_n]||=An(this.method,this[he],this.headers,this[fe],this[X])}};["body","bodyUsed","cache","credentials","destination","integrity","mode","redirect","referrer","referrerPolicy","signal","keepalive"].forEach(e=>{Object.defineProperty(me,e,{get(){return this[Y]()[e]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach(e=>{Object.defineProperty(me,e,{value:function(){return this[Y]()[e]()}})});Object.setPrototypeOf(me,ne.prototype);var Tn=(e,t)=>{let r=Object.create(me);r[fe]=e;let n=e.url||"";if(n[0]!=="/"&&(n.startsWith("http://")||n.startsWith("https://"))){if(e instanceof De)throw new F("Absolute URL for :path is not allowed in HTTP/2");try{let a=new URL(n);r[he]=a.href}catch(a){throw new F("Invalid absolute URL",{cause:a})}return r}let o=(e instanceof De?e.authority:e.headers.host)||t;if(!o)throw new F("Missing host header");let s;if(e instanceof De){if(s=e.scheme,!(s==="http"||s==="https"))throw new F("Unsupported scheme")}else s=e.socket&&e.socket.encrypted?"https":"http";let i=new URL(`${s}://${o}${n}`);if(i.hostname.length!==o.length&&i.hostname!==o.replace(/:\d+$/,""))throw new F("Invalid host header");return r[he]=i.href,r},_t=Symbol("responseCache"),G=Symbol("getResponseCache"),q=Symbol("cache"),He=global.Response,oe=class Lt{#t;#e;[G](){return delete this[q],this[_t]||=new He(this.#t,this.#e)}constructor(t,r){let n;if(this.#t=t,r instanceof Lt){let o=r[_t];if(o){this.#e=o,this[G]();return}else this.#e=r.#e,n=new Headers(r.#e.headers)}else this.#e=r;(typeof t=="string"||typeof t?.getReader<"u"||t instanceof Blob||t instanceof Uint8Array)&&(this[q]=[r?.status||200,t,n||r?.headers])}get headers(){let t=this[q];return t?(t[2]instanceof Headers||(t[2]=new Headers(t[2]||{"content-type":"text/plain; charset=UTF-8"})),t[2]):this[G]().headers}get status(){return this[q]?.[0]??this[G]().status}get ok(){let t=this.status;return t>=200&&t<300}};["body","bodyUsed","redirected","statusText","trailers","type","url"].forEach(e=>{Object.defineProperty(oe.prototype,e,{get(){return this[G]()[e]}})});["arrayBuffer","blob","clone","formData","json","text"].forEach(e=>{Object.defineProperty(oe.prototype,e,{value:function(){return this[G]()[e]()}})});Object.setPrototypeOf(oe,He);Object.setPrototypeOf(oe.prototype,He.prototype);async function Ln(e){return Promise.race([e,Promise.resolve().then(()=>Promise.resolve(void 0))])}function Mt(e,t,r){let n=a=>{e.cancel(a).catch(()=>{})};return t.on("close",n),t.on("error",n),(r??e.read()).then(i,o),e.closed.finally(()=>{t.off("close",n),t.off("error",n)});function o(a){a&&t.destroy(a)}function s(){e.read().then(i,o)}function i({done:a,value:c}){try{if(a)t.end();else if(!t.write(c))t.once("drain",s);else return e.read().then(i,o)}catch(l){o(l)}}}function Mn(e,t){if(e.locked)throw new TypeError("ReadableStream is locked.");return t.destroyed?void 0:Mt(e.getReader(),t)}var Ne=e=>{let t={};e instanceof Headers||(e=new Headers(e??void 0));let r=[];for(let[n,o]of e)n==="set-cookie"?r.push(o):t[n]=o;return r.length>0&&(t["set-cookie"]=r),t["content-type"]??="text/plain; charset=UTF-8",t},In="x-hono-already-sent";typeof global.crypto>"u"&&(global.crypto=kn);var Be=Symbol("outgoingEnded"),Ct=Symbol("incomingDraining"),Dn=500,Un=64*1024*1024,Ue=e=>{let t=e;if(e.destroyed||t[Ct])return;if(t[Ct]=!0,e instanceof Ot){try{e.stream?.close?.(Sn.NGHTTP2_NO_ERROR)}catch{}return}let r=0,n=()=>{clearTimeout(s),e.off("data",i),e.off("end",n),e.off("error",n)},o=()=>{n();let a=e.socket;a&&!a.destroyed&&a.destroySoon()},s=setTimeout(o,Dn);s.unref?.();let i=a=>{r+=a.length,r>Un&&o()};e.on("data",i),e.on("end",n),e.on("error",n),e.resume()},Nn=()=>new Response(null,{status:400}),It=e=>new Response(null,{status:e instanceof Error&&(e.name==="TimeoutError"||e.constructor.name==="TimeoutError")?504:500}),je=(e,t)=>{let r=e instanceof Error?e:new Error("unknown error",{cause:e});r.code==="ERR_STREAM_PREMATURE_CLOSE"?console.info("The user aborted a request."):(console.error(e),t.headersSent||t.writeHead(500,{"Content-Type":"text/plain"}),t.end(`Error: ${r.message}`),t.destroy(r))},kt=e=>{"flushHeaders"in e&&e.writable&&e.flushHeaders()},Dt=async(e,t)=>{let[r,n,o]=e[q],s=!1;if(!o)o={"content-type":"text/plain; charset=UTF-8"};else if(o instanceof Headers)s=o.has("content-length"),o=Ne(o);else if(Array.isArray(o)){let i=new Headers(o);s=i.has("content-length"),o=Ne(i)}else for(let i in o)if(i.length===14&&i.toLowerCase()==="content-length"){s=!0;break}s||(typeof n=="string"?o["Content-Length"]=Buffer.byteLength(n):n instanceof Uint8Array?o["Content-Length"]=n.byteLength:n instanceof Blob&&(o["Content-Length"]=n.size)),t.writeHead(r,o),typeof n=="string"||n instanceof Uint8Array?t.end(n):n instanceof Blob?t.end(new Uint8Array(await n.arrayBuffer())):(kt(t),await Mn(n,t)?.catch(i=>je(i,t))),t[Be]?.()},jn=e=>typeof e.then=="function",Hn=async(e,t,r={})=>{if(jn(e))if(r.errorHandler)try{e=await e}catch(o){let s=await r.errorHandler(o);if(!s)return;e=s}else e=await e.catch(It);if(q in e)return Dt(e,t);let n=Ne(e.headers);if(e.body){let o=e.body.getReader(),s=[],i=!1,a;if(n["transfer-encoding"]!=="chunked"){let c=2;for(let l=0;l<c;l++){a||=o.read();let u=await Ln(a).catch(d=>{console.error(d),i=!0});if(!u){if(l===1){await new Promise(d=>setTimeout(d)),c=3;continue}break}if(a=void 0,u.value&&s.push(u.value),u.done){i=!0;break}}i&&!("content-length"in n)&&(n["content-length"]=s.reduce((l,u)=>l+u.length,0))}t.writeHead(e.status,n),s.forEach(c=>{t.write(c)}),i?t.end():(s.length===0&&kt(t),await Mt(o,t,a))}else n[In]||(t.writeHead(e.status,n),t.end());t[Be]?.()},Bn=(e,t={})=>{let r=t.autoCleanupIncoming??!0;return t.overrideGlobalObjects!==!1&&global.Request!==ne&&(Object.defineProperty(global,"Request",{value:ne}),Object.defineProperty(global,"Response",{value:oe})),async(n,o)=>{let s,i;try{i=Tn(n,t.hostname);let a=!r||n.method==="GET"||n.method==="HEAD";if(a||(n[Tt]=!0,n.on("end",()=>{a=!0}),n instanceof Ot&&(o[Be]=()=>{a||setTimeout(()=>{a||setTimeout(()=>{Ue(n)})})}),o.on("finish",()=>{a||Ue(n)})),o.on("close",()=>{i[X]&&(n.errored?i[X].abort(n.errored.toString()):o.writableFinished||i[X].abort("Client connection prematurely closed.")),a||setTimeout(()=>{a||setTimeout(()=>{Ue(n)})})}),s=e(i,{incoming:n,outgoing:o}),q in s)return Dt(s,o)}catch(a){if(s)return je(a,o);if(t.errorHandler){if(s=await t.errorHandler(i?a:En(a)),!s)return}else i?s=It(a):s=Nn()}try{return await Hn(s,o,t)}catch(a){return je(a,o)}}},$n=e=>{let t=e.fetch,r=Bn(t,{hostname:e.hostname,overrideGlobalObjects:e.overrideGlobalObjects,autoCleanupIncoming:e.autoCleanupIncoming});return(e.createServer||xn)(e.serverOptions||{},r)},Ut=(e,t)=>{let r=$n(e);return r.listen(e?.port??3e3,e.hostname,()=>{let n=r.address();t&&t(n)}),r};var $e=(e,t,r)=>(n,o)=>{let s=-1;return i(0);async function i(a){if(a<=s)throw new Error("next() called multiple times");s=a;let c,l=!1,u;if(e[a]?(u=e[a][0][0],n.req.routeIndex=a):u=a===e.length&&o||void 0,u)try{c=await u(n,()=>i(a+1))}catch(d){if(d instanceof Error&&t)n.error=d,c=await t(d,n),l=!0;else throw d}else n.finalized===!1&&r&&(c=await r(n));return c&&(n.finalized===!1||l)&&(n.res=c),n}};var Nt=Symbol();var jt=async(e,t=Object.create(null))=>{let{all:r=!1,dot:n=!1}=t,s=(e instanceof ge?e.raw.headers:e.headers).get("Content-Type");return s?.startsWith("multipart/form-data")||s?.startsWith("application/x-www-form-urlencoded")?Fn(e,{all:r,dot:n}):{}};async function Fn(e,t){let r=await e.formData();return r?qn(r,t):{}}function qn(e,t){let r=Object.create(null);return e.forEach((n,o)=>{t.all||o.endsWith("[]")?zn(r,o,n):r[o]=n}),t.dot&&Object.entries(r).forEach(([n,o])=>{n.includes(".")&&(Wn(r,n,o),delete r[n])}),r}var zn=(e,t,r)=>{e[t]!==void 0?Array.isArray(e[t])?e[t].push(r):e[t]=[e[t],r]:t.endsWith("[]")?e[t]=[r]:e[t]=r},Wn=(e,t,r)=>{if(/(?:^|\.)__proto__\./.test(t))return;let n=e,o=t.split(".");o.forEach((s,i)=>{i===o.length-1?n[s]=r:((!n[s]||typeof n[s]!="object"||Array.isArray(n[s])||n[s]instanceof File)&&(n[s]=Object.create(null)),n=n[s])})};var qe=e=>{let t=e.split("/");return t[0]===""&&t.shift(),t},Ht=e=>{let{groups:t,path:r}=Kn(e),n=qe(r);return Vn(n,t)},Kn=e=>{let t=[];return e=e.replace(/\{[^}]+\}/g,(r,n)=>{let o=`@${n}`;return t.push([o,r]),o}),{groups:t,path:e}},Vn=(e,t)=>{for(let r=t.length-1;r>=0;r--){let[n]=t[r];for(let o=e.length-1;o>=0;o--)if(e[o].includes(n)){e[o]=e[o].replace(n,t[r][1]);break}}return e},we={},Bt=(e,t)=>{if(e==="*")return"*";let r=e.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/);if(r){let n=`${e}#${t}`;return we[n]||(r[2]?we[n]=t&&t[0]!==":"&&t[0]!=="*"?[n,r[1],new RegExp(`^${r[2]}(?=/${t})`)]:[e,r[1],new RegExp(`^${r[2]}$`)]:we[n]=[e,r[1],!0]),we[n]}return null},ye=(e,t)=>{try{return t(e)}catch{return e.replace(/(?:%[0-9A-Fa-f]{2})+/g,r=>{try{return t(r)}catch{return r}})}},Gn=e=>ye(e,decodeURI),ze=e=>{let t=e.url,r=t.indexOf("/",t.indexOf(":")+4),n=r;for(;n<t.length;n++){let o=t.charCodeAt(n);if(o===37){let s=t.indexOf("?",n),i=t.indexOf("#",n),a=s===-1?i===-1?void 0:i:i===-1?s:Math.min(s,i),c=t.slice(r,a);return Gn(c.includes("%25")?c.replace(/%25/g,"%2525"):c)}else if(o===63||o===35)break}return t.slice(r,n)};var $t=e=>{let t=ze(e);return t.length>1&&t.at(-1)==="/"?t.slice(0,-1):t},N=(e,t,...r)=>(r.length&&(t=N(t,...r)),`${e?.[0]==="/"?"":"/"}${e}${t==="/"?"":`${e?.at(-1)==="/"?"":"/"}${t?.[0]==="/"?t.slice(1):t}`}`),be=e=>{if(e.charCodeAt(e.length-1)!==63||!e.includes(":"))return null;let t=e.split("/"),r=[],n="";return t.forEach(o=>{if(o!==""&&!/\:/.test(o))n+="/"+o;else if(/\:/.test(o))if(/\?/.test(o)){r.length===0&&n===""?r.push("/"):r.push(n);let s=o.replace("?","");n+="/"+s,r.push(n)}else n+="/"+o}),r.filter((o,s,i)=>i.indexOf(o)===s)},Fe=e=>/[%+]/.test(e)?(e.indexOf("+")!==-1&&(e=e.replace(/\+/g," ")),e.indexOf("%")!==-1?ye(e,We):e):e,Ft=(e,t,r)=>{let n;if(!r&&t&&!/[%+]/.test(t)){let i=e.indexOf("?",8);if(i===-1)return;for(e.startsWith(t,i+1)||(i=e.indexOf(`&${t}`,i+1));i!==-1;){let a=e.charCodeAt(i+t.length+1);if(a===61){let c=i+t.length+2,l=e.indexOf("&",c);return Fe(e.slice(c,l===-1?void 0:l))}else if(a==38||isNaN(a))return"";i=e.indexOf(`&${t}`,i+1)}if(n=/[%+]/.test(e),!n)return}let o={};n??=/[%+]/.test(e);let s=e.indexOf("?",8);for(;s!==-1;){let i=e.indexOf("&",s+1),a=e.indexOf("=",s);a>i&&i!==-1&&(a=-1);let c=e.slice(s+1,a===-1?i===-1?void 0:i:a);if(n&&(c=Fe(c)),s=i,c==="")continue;let l;a===-1?l="":(l=e.slice(a+1,i===-1?void 0:i),n&&(l=Fe(l))),r?(o[c]&&Array.isArray(o[c])||(o[c]=[]),o[c].push(l)):o[c]??=l}return t?o[t]:o},qt=Ft,zt=(e,t)=>Ft(e,t,!0),We=decodeURIComponent;var Wt=e=>ye(e,We),ge=class{raw;#t;#e;routeIndex=0;path;bodyCache={};constructor(e,t="/",r=[[]]){this.raw=e,this.path=t,this.#e=r,this.#t={}}param(e){return e?this.#r(e):this.#s()}#r(e){let t=this.#e[0][this.routeIndex][1][e],r=this.#o(t);return r&&/\%/.test(r)?Wt(r):r}#s(){let e={},t=Object.keys(this.#e[0][this.routeIndex][1]);for(let r of t){let n=this.#o(this.#e[0][this.routeIndex][1][r]);n!==void 0&&(e[r]=/\%/.test(n)?Wt(n):n)}return e}#o(e){return this.#e[1]?this.#e[1][e]:e}query(e){return qt(this.url,e)}queries(e){return zt(this.url,e)}header(e){if(e)return this.raw.headers.get(e)??void 0;let t={};return this.raw.headers.forEach((r,n)=>{t[n]=r}),t}async parseBody(e){return jt(this,e)}#n=e=>{let{bodyCache:t,raw:r}=this,n=t[e];if(n)return n;let o=Object.keys(t)[0];return o?t[o].then(s=>(o==="json"&&(s=JSON.stringify(s)),new Response(s)[e]())):t[e]=r[e]()};json(){return this.#n("text").then(e=>JSON.parse(e))}text(){return this.#n("text")}arrayBuffer(){return this.#n("arrayBuffer")}bytes(){return this.#n("arrayBuffer").then(e=>new Uint8Array(e))}blob(){return this.#n("blob")}formData(){return this.#n("formData")}addValidatedData(e,t){this.#t[e]=t}valid(e){return this.#t[e]}get url(){return this.raw.url}get method(){return this.raw.method}get[Nt](){return this.#e}get matchedRoutes(){return this.#e[0].map(([[,e]])=>e)}get routePath(){return this.#e[0].map(([[,e]])=>e)[this.routeIndex].path}};var Kt={Stringify:1,BeforeStream:2,Stream:3},Xn=(e,t)=>{let r=new String(e);return r.isEscaped=!0,r.callbacks=t,r};var Ke=async(e,t,r,n,o)=>{typeof e=="object"&&!(e instanceof String)&&(e instanceof Promise||(e=e.toString()),e instanceof Promise&&(e=await e));let s=e.callbacks;if(!s?.length)return Promise.resolve(e);o?o[0]+=e:o=[e];let i=Promise.all(s.map(a=>a({phase:t,buffer:o,context:n}))).then(a=>Promise.all(a.filter(Boolean).map(c=>Ke(c,t,!1,n,o))).then(()=>o[0]));return r?Xn(await i,s):i};var Yn="text/plain; charset=UTF-8",Ve=(e,t)=>({"Content-Type":e,...t}),se=(e,t)=>new Response(e,t),Ge=class{#t;#e;env={};#r;finalized=!1;error;#s;#o;#n;#u;#c;#l;#a;#d;#p;constructor(e,t){this.#t=e,t&&(this.#o=t.executionCtx,this.env=t.env,this.#l=t.notFoundHandler,this.#p=t.path,this.#d=t.matchResult)}get req(){return this.#e??=new ge(this.#t,this.#p,this.#d),this.#e}get event(){if(this.#o&&"respondWith"in this.#o)return this.#o;throw Error("This context has no FetchEvent")}get executionCtx(){if(this.#o)return this.#o;throw Error("This context has no ExecutionContext")}get res(){return this.#n||=se(null,{headers:this.#a??=new Headers})}set res(e){if(this.#n&&e){e=se(e.body,e);for(let[t,r]of this.#n.headers.entries())if(t!=="content-type")if(t==="set-cookie"){let n=this.#n.headers.getSetCookie();e.headers.delete("set-cookie");for(let o of n)e.headers.append("set-cookie",o)}else e.headers.set(t,r)}this.#n=e,this.finalized=!0}render=(...e)=>(this.#c??=t=>this.html(t),this.#c(...e));setLayout=e=>this.#u=e;getLayout=()=>this.#u;setRenderer=e=>{this.#c=e};header=(e,t,r)=>{this.finalized&&(this.#n=se(this.#n.body,this.#n));let n=this.#n?this.#n.headers:this.#a??=new Headers;t===void 0?n.delete(e):r?.append?n.append(e,t):n.set(e,t)};status=e=>{this.#s=e};set=(e,t)=>{this.#r??=new Map,this.#r.set(e,t)};get=e=>this.#r?this.#r.get(e):void 0;get var(){return this.#r?Object.fromEntries(this.#r):{}}#i(e,t,r){let n=this.#n?new Headers(this.#n.headers):this.#a??new Headers;if(typeof t=="object"&&"headers"in t){let s=t.headers instanceof Headers?t.headers:new Headers(t.headers);for(let[i,a]of s)i.toLowerCase()==="set-cookie"?n.append(i,a):n.set(i,a)}if(r)for(let[s,i]of Object.entries(r))if(typeof i=="string")n.set(s,i);else{n.delete(s);for(let a of i)n.append(s,a)}let o=typeof t=="number"?t:t?.status??this.#s;return se(e,{status:o,headers:n})}newResponse=(...e)=>this.#i(...e);body=(e,t,r)=>this.#i(e,t,r);text=(e,t,r)=>!this.#a&&!this.#s&&!t&&!r&&!this.finalized?new Response(e):this.#i(e,t,Ve(Yn,r));json=(e,t,r)=>this.#i(JSON.stringify(e),t,Ve("application/json",r));html=(e,t,r)=>{let n=o=>this.#i(o,t,Ve("text/html; charset=UTF-8",r));return typeof e=="object"?Ke(e,Kt.Stringify,!1,{}).then(n):n(e)};redirect=(e,t)=>{let r=String(e);return this.header("Location",/[^\x00-\xFF]/.test(r)?encodeURI(r):r),this.newResponse(null,t??302)};notFound=()=>(this.#l??=()=>se(),this.#l(this))};var x="ALL",Vt="all",Gt=["get","post","put","delete","options","patch"],ve="Can not add a route since the matcher is already built.",xe=class extends Error{};var Xt="__COMPOSED_HANDLER";var Jn=e=>e.text("404 Not Found",404),Yt=(e,t)=>{if("getResponse"in e){let r=e.getResponse();return t.newResponse(r.body,r)}return console.error(e),t.text("Internal Server Error",500)},Jt=class Qt{get;post;put;delete;options;patch;all;on;use;router;getPath;_basePath="/";#t="/";routes=[];constructor(t={}){[...Gt,Vt].forEach(s=>{this[s]=(i,...a)=>(typeof i=="string"?this.#t=i:this.#s(s,this.#t,i),a.forEach(c=>{this.#s(s,this.#t,c)}),this)}),this.on=(s,i,...a)=>{for(let c of[i].flat()){this.#t=c;for(let l of[s].flat())a.map(u=>{this.#s(l.toUpperCase(),this.#t,u)})}return this},this.use=(s,...i)=>(typeof s=="string"?this.#t=s:(this.#t="*",i.unshift(s)),i.forEach(a=>{this.#s(x,this.#t,a)}),this);let{strict:n,...o}=t;Object.assign(this,o),this.getPath=n??!0?t.getPath??ze:$t}#e(){let t=new Qt({router:this.router,getPath:this.getPath});return t.errorHandler=this.errorHandler,t.#r=this.#r,t.routes=this.routes,t}#r=Jn;errorHandler=Yt;route(t,r){let n=this.basePath(t);return r.routes.map(o=>{let s;r.errorHandler===Yt?s=o.handler:(s=async(i,a)=>(await $e([],r.errorHandler)(i,()=>o.handler(i,a))).res,s[Xt]=o.handler),n.#s(o.method,o.path,s,o.basePath)}),this}basePath(t){let r=this.#e();return r._basePath=N(this._basePath,t),r}onError=t=>(this.errorHandler=t,this);notFound=t=>(this.#r=t,this);mount(t,r,n){let o,s;n&&(typeof n=="function"?s=n:(s=n.optionHandler,n.replaceRequest===!1?o=c=>c:o=n.replaceRequest));let i=s?c=>{let l=s(c);return Array.isArray(l)?l:[l]}:c=>{let l;try{l=c.executionCtx}catch{}return[c.env,l]};o||=(()=>{let c=N(this._basePath,t),l=c==="/"?0:c.length;return u=>{let d=new URL(u.url);return d.pathname=this.getPath(u).slice(l)||"/",new Request(d,u)}})();let a=async(c,l)=>{let u=await r(o(c.req.raw),...i(c));if(u)return u;await l()};return this.#s(x,N(t,"*"),a),this}#s(t,r,n,o){t=t.toUpperCase(),r=N(this._basePath,r);let s={basePath:o!==void 0?N(this._basePath,o):this._basePath,path:r,method:t,handler:n};this.router.add(t,r,[n,s]),this.routes.push(s)}#o(t,r){if(t instanceof Error)return this.errorHandler(t,r);throw t}#n(t,r,n,o){if(o==="HEAD")return(async()=>new Response(null,await this.#n(t,r,n,"GET")))();let s=this.getPath(t,{env:n}),i=this.router.match(o,s),a=new Ge(t,{path:s,matchResult:i,env:n,executionCtx:r,notFoundHandler:this.#r});if(i[0].length===1){let l;try{l=i[0][0][0][0](a,async()=>{a.res=await this.#r(a)})}catch(u){return this.#o(u,a)}return l instanceof Promise?l.then(u=>u||(a.finalized?a.res:this.#r(a))).catch(u=>this.#o(u,a)):l??this.#r(a)}let c=$e(i[0],this.errorHandler,this.#r);return(async()=>{try{let l=await c(a);if(!l.finalized)throw new Error("Context is not finalized. Did you forget to return a Response object or `await next()`?");return l.res}catch(l){return this.#o(l,a)}})()}fetch=(t,...r)=>this.#n(t,r[1],r[0],t.method);request=(t,r,n,o)=>t instanceof Request?this.fetch(r?new Request(t,r):t,n,o):(t=t.toString(),this.fetch(new Request(/^https?:\/\//.test(t)?t:`http://localhost${N("/",t)}`,r),n,o));fire=()=>{addEventListener("fetch",t=>{t.respondWith(this.#n(t.request,t,void 0,t.request.method))})}};var Se=[];function Xe(e,t){let r=this.buildAllMatchers(),n=((o,s)=>{let i=r[o]||r[x],a=i[2][s];if(a)return a;let c=s.match(i[0]);if(!c)return[[],Se];let l=c.indexOf("",1);return[i[1][l],c]});return this.match=n,n(e,t)}var Ee="[^/]+",ie=".*",ae="(?:|/.*)",z=Symbol(),Qn=new Set(".\\+*[^]$()");function Zn(e,t){return e.length===1?t.length===1?e<t?-1:1:-1:t.length===1||e===ie||e===ae?1:t===ie||t===ae?-1:e===Ee?1:t===Ee?-1:e.length===t.length?e<t?-1:1:t.length-e.length}var Zt=class Ye{#t;#e;#r=Object.create(null);insert(t,r,n,o,s){if(t.length===0){if(this.#t!==void 0)throw z;if(s)return;this.#t=r;return}let[i,...a]=t,c=i==="*"?a.length===0?["","",ie]:["","",Ee]:i==="/*"?["","",ae]:i.match(/^\:([^\{\}]+)(?:\{(.+)\})?$/),l;if(c){let u=c[1],d=c[2]||Ee;if(u&&c[2]&&(d===".*"||(d=d.replace(/^\((?!\?:)(?=[^)]+\)$)/,"(?:"),/\((?!\?:)/.test(d))))throw z;if(l=this.#r[d],!l){if(Object.keys(this.#r).some(f=>f!==ie&&f!==ae))throw z;if(s)return;l=this.#r[d]=new Ye,u!==""&&(l.#e=o.varIndex++)}!s&&u!==""&&n.push([u,l.#e])}else if(l=this.#r[i],!l){if(Object.keys(this.#r).some(u=>u.length>1&&u!==ie&&u!==ae))throw z;if(s)return;l=this.#r[i]=new Ye}l.insert(a,r,n,o,s)}buildRegExpStr(){let r=Object.keys(this.#r).sort(Zn).map(n=>{let o=this.#r[n];return(typeof o.#e=="number"?`(${n})@${o.#e}`:Qn.has(n)?`\\${n}`:n)+o.buildRegExpStr()});return typeof this.#t=="number"&&r.unshift(`#${this.#t}`),r.length===0?"":r.length===1?r[0]:"(?:"+r.join("|")+")"}};var er=class{#t={varIndex:0};#e=new Zt;insert(e,t,r){let n=[],o=[];for(let i=0;;){let a=!1;if(e=e.replace(/\{[^}]+\}/g,c=>{let l=`@\\${i}`;return o[i]=[l,c],i++,a=!0,l}),!a)break}let s=e.match(/(?::[^\/]+)|(?:\/\*$)|./g)||[];for(let i=o.length-1;i>=0;i--){let[a]=o[i];for(let c=s.length-1;c>=0;c--)if(s[c].indexOf(a)!==-1){s[c]=s[c].replace(a,o[i][1]);break}}return this.#e.insert(s,t,n,this.#t,r),n}buildRegExp(){let e=this.#e.buildRegExpStr();if(e==="")return[/^$/,[],[]];let t=0,r=[],n=[];return e=e.replace(/#(\d+)|@(\d+)|\.\*\$/g,(o,s,i)=>s!==void 0?(r[++t]=Number(s),"$()"):(i!==void 0&&(n[Number(i)]=++t),"")),[new RegExp(`^${e}`),r,n]}};var eo=[/^$/,[],Object.create(null)],tr=Object.create(null);function rr(e){return tr[e]??=new RegExp(e==="*"?"":`^${e.replace(/\/\*$|([.\\+*[^\]$()])/g,(t,r)=>r?`\\${r}`:"(?:|/.*)")}$`)}function to(){tr=Object.create(null)}function ro(e){let t=new er,r=[];if(e.length===0)return eo;let n=e.map(l=>[!/\*|\/:/.test(l[0]),...l]).sort(([l,u],[d,f])=>l?1:d?-1:u.length-f.length),o=Object.create(null);for(let l=0,u=-1,d=n.length;l<d;l++){let[f,h,w]=n[l];f?o[h]=[w.map(([g])=>[g,Object.create(null)]),Se]:u++;let y;try{y=t.insert(h,u,f)}catch(g){throw g===z?new xe(h):g}f||(r[u]=w.map(([g,p])=>{let m=Object.create(null);for(p-=1;p>=0;p--){let[v,T]=y[p];m[v]=T}return[g,m]}))}let[s,i,a]=t.buildRegExp();for(let l=0,u=r.length;l<u;l++)for(let d=0,f=r[l].length;d<f;d++){let h=r[l][d]?.[1];if(!h)continue;let w=Object.keys(h);for(let y=0,g=w.length;y<g;y++)h[w[y]]=a[h[w[y]]]}let c=[];for(let l in i)c[l]=r[i[l]];return[s,c,o]}function J(e,t){if(e){for(let r of Object.keys(e).sort((n,o)=>o.length-n.length))if(rr(r).test(t))return[...e[r]]}}var Re=class{name="RegExpRouter";#t;#e;constructor(){this.#t={[x]:Object.create(null)},this.#e={[x]:Object.create(null)}}add(e,t,r){let n=this.#t,o=this.#e;if(!n||!o)throw new Error(ve);n[e]||[n,o].forEach(a=>{a[e]=Object.create(null),Object.keys(a[x]).forEach(c=>{a[e][c]=[...a[x][c]]})}),t==="/*"&&(t="*");let s=(t.match(/\/:/g)||[]).length;if(/\*$/.test(t)){let a=rr(t);e===x?Object.keys(n).forEach(c=>{n[c][t]||=J(n[c],t)||J(n[x],t)||[]}):n[e][t]||=J(n[e],t)||J(n[x],t)||[],Object.keys(n).forEach(c=>{(e===x||e===c)&&Object.keys(n[c]).forEach(l=>{a.test(l)&&n[c][l].push([r,s])})}),Object.keys(o).forEach(c=>{(e===x||e===c)&&Object.keys(o[c]).forEach(l=>a.test(l)&&o[c][l].push([r,s]))});return}let i=be(t)||[t];for(let a=0,c=i.length;a<c;a++){let l=i[a];Object.keys(o).forEach(u=>{(e===x||e===u)&&(o[u][l]||=[...J(n[u],l)||J(n[x],l)||[]],o[u][l].push([r,s-c+a+1]))})}}match=Xe;buildAllMatchers(){let e=Object.create(null);return Object.keys(this.#e).concat(Object.keys(this.#t)).forEach(t=>{e[t]||=this.#r(t)}),this.#t=this.#e=void 0,to(),e}#r(e){let t=[],r=e===x;return[this.#t,this.#e].forEach(n=>{let o=n[e]?Object.keys(n[e]).map(s=>[s,n[e][s]]):[];o.length!==0?(r||=!0,t.push(...o)):e!==x&&t.push(...Object.keys(n[x]).map(s=>[s,n[x][s]]))}),r?ro(t):null}};var Je=class{name="SmartRouter";#t=[];#e=[];constructor(e){this.#t=e.routers}add(e,t,r){if(!this.#e)throw new Error(ve);this.#e.push([e,t,r])}match(e,t){if(!this.#e)throw new Error("Fatal error");let r=this.#t,n=this.#e,o=r.length,s=0,i;for(;s<o;s++){let a=r[s];try{for(let c=0,l=n.length;c<l;c++)a.add(...n[c]);i=a.match(e,t)}catch(c){if(c instanceof xe)continue;throw c}this.match=a.match.bind(a),this.#t=[a],this.#e=void 0;break}if(s===o)throw new Error("Fatal error");return this.name=`SmartRouter + ${this.activeRouter.name}`,i}get activeRouter(){if(this.#e||this.#t.length!==1)throw new Error("No active router has been determined yet.");return this.#t[0]}};var ce=Object.create(null),no=e=>{for(let t in e)return!0;return!1},nr=class or{#t;#e;#r;#s=0;#o=ce;constructor(t,r,n){if(this.#e=n||Object.create(null),this.#t=[],t&&r){let o=Object.create(null);o[t]={handler:r,possibleKeys:[],score:0},this.#t=[o]}this.#r=[]}insert(t,r,n){this.#s=++this.#s;let o=this,s=Ht(r),i=[];for(let a=0,c=s.length;a<c;a++){let l=s[a],u=s[a+1],d=Bt(l,u),f=Array.isArray(d)?d[0]:l;if(f in o.#e){o=o.#e[f],d&&i.push(d[1]);continue}o.#e[f]=new or,d&&(o.#r.push(d),i.push(d[1])),o=o.#e[f]}return o.#t.push({[t]:{handler:n,possibleKeys:i.filter((a,c,l)=>l.indexOf(a)===c),score:this.#s}}),o}#n(t,r,n,o,s){for(let i=0,a=r.#t.length;i<a;i++){let c=r.#t[i],l=c[n]||c[x],u={};if(l!==void 0&&(l.params=Object.create(null),t.push(l),o!==ce||s&&s!==ce))for(let d=0,f=l.possibleKeys.length;d<f;d++){let h=l.possibleKeys[d],w=u[l.score];l.params[h]=s?.[h]&&!w?s[h]:o[h]??s?.[h],u[l.score]=!0}}}search(t,r){let n=[];this.#o=ce;let s=[this],i=qe(r),a=[],c=i.length,l=null;for(let u=0;u<c;u++){let d=i[u],f=u===c-1,h=[];for(let y=0,g=s.length;y<g;y++){let p=s[y],m=p.#e[d];m&&(m.#o=p.#o,f?(m.#e["*"]&&this.#n(n,m.#e["*"],t,p.#o),this.#n(n,m,t,p.#o)):h.push(m));for(let v=0,T=p.#r.length;v<T;v++){let L=p.#r[v],E=p.#o===ce?{}:{...p.#o};if(L==="*"){let P=p.#e["*"];P&&(this.#n(n,P,t,p.#o),P.#o=E,h.push(P));continue}let[R,A,S]=L;if(!d&&!(S instanceof RegExp))continue;let b=p.#e[R];if(S instanceof RegExp){if(l===null){l=new Array(c);let H=r[0]==="/"?1:0;for(let B=0;B<c;B++)l[B]=H,H+=i[B].length+1}let P=r.substring(l[u]),M=S.exec(P);if(M){if(E[A]=M[0],this.#n(n,b,t,p.#o,E),no(b.#e)){b.#o=E;let H=M[0].match(/\//)?.length??0;(a[H]||=[]).push(b)}continue}}(S===!0||S.test(d))&&(E[A]=d,f?(this.#n(n,b,t,E,p.#o),b.#e["*"]&&this.#n(n,b.#e["*"],t,E,p.#o)):(b.#o=E,h.push(b)))}}let w=a.shift();s=w?h.concat(w):h}return n.length>1&&n.sort((u,d)=>u.score-d.score),[n.map(({handler:u,params:d})=>[u,d])]}};var Qe=class{name="TrieRouter";#t;constructor(){this.#t=new nr}add(e,t,r){let n=be(t);if(n){for(let o=0,s=n.length;o<s;o++)this.#t.insert(e,n[o],r);return}this.#t.insert(e,t,r)}match(e,t){return this.#t.search(e,t)}};var Ze=class extends Jt{constructor(e={}){super(e),this.router=e.router??new Je({routers:[new Re,new Qe]})}};var Pe=e=>{let t={origin:"*",allowMethods:["GET","HEAD","PUT","POST","DELETE","PATCH"],allowHeaders:[],exposeHeaders:[],...e},r=(o=>typeof o=="string"?o==="*"?()=>o:s=>o===s?s:null:typeof o=="function"?o:s=>o.includes(s)?s:null)(t.origin),n=(o=>typeof o=="function"?o:Array.isArray(o)?()=>o:()=>[])(t.allowMethods);return async function(s,i){function a(l,u){s.res.headers.set(l,u)}let c=await r(s.req.header("origin")||"",s);if(c&&a("Access-Control-Allow-Origin",c),t.credentials&&a("Access-Control-Allow-Credentials","true"),t.exposeHeaders?.length&&a("Access-Control-Expose-Headers",t.exposeHeaders.join(",")),s.req.method==="OPTIONS"){t.origin!=="*"&&a("Vary","Origin"),t.maxAge!=null&&a("Access-Control-Max-Age",t.maxAge.toString());let l=await n(s.req.header("origin")||"",s);l.length&&a("Access-Control-Allow-Methods",l.join(","));let u=t.allowHeaders;if(!u?.length){let d=s.req.header("Access-Control-Request-Headers");d&&(u=d.split(/\s*,\s*/))}return u?.length&&(a("Access-Control-Allow-Headers",u.join(",")),s.res.headers.append("Vary","Access-Control-Request-Headers")),s.res.headers.delete("Content-Length"),s.res.headers.delete("Content-Type"),new Response(null,{headers:s.res.headers,status:204,statusText:"No Content"})}await i(),t.origin!=="*"&&s.header("Vary","Origin",{append:!0})}};import xr from"process";import Sr from"path";import{fileURLToPath as Uo}from"url";import No from"child_process";import jo,{constants as Ho}from"fs/promises";import{promisify as mo}from"util";import go from"child_process";import ot,{constants as dr}from"fs/promises";import ar from"process";import co from"os";import lo from"fs";import io from"fs";import sr from"fs";var et;function oo(){try{return sr.statSync("/.dockerenv"),!0}catch{return!1}}function so(){try{return sr.readFileSync("/proc/self/cgroup","utf8").includes("docker")}catch{return!1}}function tt(){return et===void 0&&(et=oo()||so()),et}var rt,ao=()=>{try{return io.statSync("/run/.containerenv"),!0}catch{return!1}};function Q(){return rt===void 0&&(rt=ao()||tt()),rt}var ir=()=>{if(ar.platform!=="linux")return!1;if(co.release().toLowerCase().includes("microsoft"))return!Q();try{return lo.readFileSync("/proc/version","utf8").toLowerCase().includes("microsoft")?!Q():!1}catch{return!1}},k=ar.env.__IS_WSL_TEST__?ir:ir();import cr from"process";import{Buffer as uo}from"buffer";import{promisify as po}from"util";import fo from"child_process";import Sa,{constants as Ea}from"fs/promises";var ho=po(fo.execFile),nt=()=>`${cr.env.SYSTEMROOT||cr.env.windir||String.raw`C:\Windows`}\\System32\\WindowsPowerShell\\v1.0\\powershell.exe`;var O=async(e,t={})=>{let{powerShellPath:r,...n}=t,o=O.encodeCommand(e);return ho(r??nt(),[...O.argumentsPrefix,o],{encoding:"utf8",...n})};O.argumentsPrefix=["-NoProfile","-NonInteractive","-ExecutionPolicy","Bypass","-EncodedCommand"];O.encodeCommand=e=>uo.from(e,"utf16le").toString("base64");O.escapeArgument=e=>`'${String(e).replaceAll("'","''")}'`;function lr(e){for(let t of e.split(`
|
|
3
|
+
`)){if(/^\s*#/.test(t))continue;let r=/^\s*root\s*=\s*(?<mountPoint>"[^"]*"|'[^']*'|[^#]*)/.exec(t);if(r)return r.groups.mountPoint.trim().replaceAll(/^["']|["']$/g,"")}}var wo=mo(go.execFile),yo=(()=>{let e="/mnt/",t;return async function(){if(t)return t;let r="/etc/wsl.conf",n=!1;try{await ot.access(r,dr.F_OK),n=!0}catch{}if(!n)return e;let o=await ot.readFile(r,{encoding:"utf8"}),s=lr(o);return s===void 0?e:(t=s,t=t.endsWith("/")?t:`${t}/`,t)}})(),bo=async()=>`${await yo()}c/Windows/System32/WindowsPowerShell/v1.0/powershell.exe`,Ae=k?bo:nt,ur,pr=async()=>(ur??=(async()=>{try{let e=await Ae();return await ot.access(e,dr.X_OK),!0}catch{return!1}})(),ur),fr=async()=>{let e=await Ae(),t=String.raw`(Get-ItemProperty -Path "HKCU:\Software\Microsoft\Windows\Shell\Associations\UrlAssociations\http\UserChoice").ProgId`,{stdout:r}=await O(t,{powerShellPath:e});return r.trim()},hr=async e=>{if(/^[a-z]+:\/\//i.test(e))return e;try{let{stdout:t}=await wo("wslpath",["-aw",e],{encoding:"utf8"});return t.trim()}catch{return e}};function W(e,t,r){let n=o=>Object.defineProperty(e,t,{value:o,enumerable:!0,writable:!0});return Object.defineProperty(e,t,{configurable:!0,enumerable:!0,get(){let o=r();return n(o),o},set(o){n(o)}}),e}import{promisify as Lo}from"util";import ut from"process";import{execFile as Mo}from"child_process";import{promisify as vo}from"util";import xo from"process";import{execFile as So}from"child_process";var Eo=vo(So);async function st(){if(xo.platform!=="darwin")throw new Error("macOS only");let{stdout:e}=await Eo("defaults",["read","com.apple.LaunchServices/com.apple.launchservices.secure","LSHandlers"]),r=/LSHandlerRoleAll = "(?!-)(?<id>[^"]+?)";\s+?LSHandlerURLScheme = (?:http|https);/.exec(e)?.groups.id??"com.apple.Safari";return r==="com.apple.safari"?"com.apple.Safari":r}import Ro from"process";import{promisify as Po}from"util";import{execFile as Ao,execFileSync as Fa}from"child_process";var _o=Po(Ao);async function mr(e,{humanReadableOutput:t=!0,signal:r}={}){if(Ro.platform!=="darwin")throw new Error("macOS only");let n=t?[]:["-ss"],o={};r&&(o.signal=r);let{stdout:s}=await _o("osascript",["-e",e,n],o);return s.trim()}async function it(e){return mr(`tell application "Finder" to set app_path to application file id "${e}" as string
|
|
4
|
+
tell application "System Events" to get value of property list item "CFBundleName" of property list file (app_path & ":Contents:Info.plist")`)}import{promisify as Co}from"util";import{execFile as Oo}from"child_process";var To=Co(Oo),_e={MSEdgeHTM:{name:"Edge",id:"com.microsoft.edge"},MSEdgeBHTML:{name:"Edge Beta",id:"com.microsoft.edge.beta"},MSEdgeDHTML:{name:"Edge Dev",id:"com.microsoft.edge.dev"},AppXq0fevzme2pys62n3e0fbqa7peapykr8v:{name:"Edge",id:"com.microsoft.edge.old"},ChromeHTML:{name:"Chrome",id:"com.google.chrome"},ChromeBHTML:{name:"Chrome Beta",id:"com.google.chrome.beta"},ChromeDHTML:{name:"Chrome Dev",id:"com.google.chrome.dev"},ChromiumHTM:{name:"Chromium",id:"org.chromium.Chromium"},BraveHTML:{name:"Brave",id:"com.brave.Browser"},BraveBHTML:{name:"Brave Beta",id:"com.brave.Browser.beta"},BraveDHTML:{name:"Brave Dev",id:"com.brave.Browser.dev"},BraveSSHTM:{name:"Brave Nightly",id:"com.brave.Browser.nightly"},FirefoxURL:{name:"Firefox",id:"org.mozilla.firefox"},OperaStable:{name:"Opera",id:"com.operasoftware.Opera"},VivaldiHTM:{name:"Vivaldi",id:"com.vivaldi.Vivaldi"},"IE.HTTP":{name:"Internet Explorer",id:"com.microsoft.ie"}},ct=new Map(Object.entries(_e)),at=class extends Error{};async function lt(e=To){let{stdout:t}=await e("reg",["QUERY"," HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\Shell\\Associations\\UrlAssociations\\http\\UserChoice","/v","ProgId"]),r=/ProgId\s*REG_SZ\s*(?<id>\S+)/.exec(t);if(!r)throw new at(`Cannot find Windows browser in stdout: ${JSON.stringify(t)}`);let{id:n}=r.groups,o=n.lastIndexOf("."),s=n.lastIndexOf("-"),i=o===-1?void 0:n.slice(0,o),a=s===-1?void 0:n.slice(0,s);return _e[n]??_e[i]??_e[a]??{name:n,id:n}}var Io=Lo(Mo),ko=e=>e.toLowerCase().replaceAll(/(?:^|\s|-)\S/g,t=>t.toUpperCase());async function dt(){if(ut.platform==="darwin"){let e=await st();return{name:await it(e),id:e}}if(ut.platform==="linux"){let{stdout:e}=await Io("xdg-mime",["query","default","x-scheme-handler/http"]),t=e.trim();return{name:ko(t.replace(/.desktop$/,"").replace("-"," ")),id:t}}if(ut.platform==="win32")return lt();throw new Error("Only macOS, Linux, and Windows are supported")}import pt from"process";var Do=!!(pt.env.SSH_CONNECTION||pt.env.SSH_CLIENT||pt.env.SSH_TTY),gr=Do;var Ce=Symbol("fallbackAttempt"),ft=import.meta.url?Sr.dirname(Uo(import.meta.url)):"",wr=Sr.join(ft,"xdg-open"),{platform:Z,arch:yr}=xr,br=async(e,t)=>{if(e.length===0)return;let r=[];for(let n of e)try{return await t(n)}catch(o){r.push(o)}throw new AggregateError(r,"Failed to open in all supported apps")},Oe=async e=>{e={wait:!1,background:!1,newInstance:!1,allowNonzeroExitCode:!1,...e};let t=e[Ce]===!0;if(delete e[Ce],Array.isArray(e.app))return br(e.app,l=>Oe({...e,app:l,[Ce]:!0}));let{name:r,arguments:n=[]}=e.app??{};if(n=[...n],Array.isArray(r))return br(r,l=>Oe({...e,app:{name:l,arguments:n},[Ce]:!0}));if(r==="browser"||r==="browserPrivate"){let l={"com.google.chrome":"chrome","google-chrome.desktop":"chrome","com.brave.browser":"brave","org.mozilla.firefox":"firefox","firefox.desktop":"firefox","com.microsoft.msedge":"edge","com.microsoft.edge":"edge","com.microsoft.edgemac":"edge","microsoft-edge.desktop":"edge","com.apple.safari":"safari"},u={chrome:"--incognito",brave:"--incognito",firefox:"--private-window",edge:"--inPrivate"},d;if(k){let f=await fr();d=ct.get(f)??{}}else d=await dt();if(d.id in l){let f=l[d.id.toLowerCase()];if(r==="browserPrivate"){if(f==="safari")throw new Error("Safari doesn't support opening in private mode via command line");n.push(u[f])}return Oe({...e,app:{name:ee[f],arguments:n}})}throw new Error(`${d.name} is not supported as a default browser`)}let o,s=[],i={},a=!1;if(k&&!Q()&&!gr&&!r&&(a=await pr()),Z==="darwin")o="open",e.wait&&s.push("--wait-apps"),e.background&&s.push("--background"),e.newInstance&&s.push("--new"),r&&s.push("-a",r);else if(Z==="win32"||a){o=await Ae(),s.push(...O.argumentsPrefix),k||(i.windowsVerbatimArguments=!0),k&&e.target&&(e.target=await hr(e.target));let l=["$ProgressPreference = 'SilentlyContinue';","Start"];e.wait&&l.push("-Wait"),r?(l.push(O.escapeArgument(r)),e.target&&n.push(e.target)):e.target&&l.push(O.escapeArgument(e.target)),n.length>0&&(n=n.map(u=>O.escapeArgument(u)),l.push("-ArgumentList",n.join(","))),e.target=O.encodeCommand(l.join(" ")),e.wait||(i.stdio="ignore")}else{if(r)o=r;else{let l=!ft||ft==="/",u=!1;try{await jo.access(wr,Ho.X_OK),u=!0}catch{}o=xr.versions.electron??(Z==="android"||l||!u)?"xdg-open":wr}n.length>0&&s.push(...n),e.wait||(i.stdio="ignore",i.detached=!0)}Z==="darwin"&&n.length>0&&s.push("--args",...n),e.target&&s.push(e.target);let c=No.spawn(o,s,i);return e.wait?new Promise((l,u)=>{c.once("error",u),c.once("close",d=>{if(!e.allowNonzeroExitCode&&d!==0){u(new Error(`Exited with code ${d}`));return}l(c)})}):t?new Promise((l,u)=>{c.once("error",u),c.once("spawn",()=>{c.once("close",d=>{if(c.off("error",u),d!==0){u(new Error(`Exited with code ${d}`));return}c.unref(),l(c)})})}):(c.unref(),new Promise((l,u)=>{c.once("error",u),c.once("spawn",()=>{c.off("error",u),l(c)})}))},Bo=(e,t)=>{if(typeof e!="string")throw new TypeError("Expected a `target`");return Oe({...t,target:e})};function vr(e){if(typeof e=="string"||Array.isArray(e))return e;let{[yr]:t}=e;if(!t)throw new Error(`${yr} is not supported`);return t}function le({[Z]:e},{wsl:t}={}){if(t&&k)return vr(t);if(!e)throw new Error(`${Z} is not supported`);return vr(e)}var ee={browser:"browser",browserPrivate:"browserPrivate"};W(ee,"chrome",()=>le({darwin:"google chrome",win32:"chrome",linux:["google-chrome","google-chrome-stable","chromium","chromium-browser"]},{wsl:{ia32:"/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe",x64:["/mnt/c/Program Files/Google/Chrome/Application/chrome.exe","/mnt/c/Program Files (x86)/Google/Chrome/Application/chrome.exe"]}}));W(ee,"brave",()=>le({darwin:"brave browser",win32:"brave",linux:["brave-browser","brave"]},{wsl:{ia32:"/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe",x64:["/mnt/c/Program Files/BraveSoftware/Brave-Browser/Application/brave.exe","/mnt/c/Program Files (x86)/BraveSoftware/Brave-Browser/Application/brave.exe"]}}));W(ee,"firefox",()=>le({darwin:"firefox",win32:String.raw`C:\Program Files\Mozilla Firefox\firefox.exe`,linux:"firefox"},{wsl:"/mnt/c/Program Files/Mozilla Firefox/firefox.exe"}));W(ee,"edge",()=>le({darwin:"microsoft edge",win32:"msedge",linux:["microsoft-edge","microsoft-edge-dev"]},{wsl:"/mnt/c/Program Files (x86)/Microsoft/Edge/Application/msedge.exe"}));W(ee,"safari",()=>le({darwin:"Safari"}));var Er=Bo;function Rr(e=""){return`<link rel="icon" type="image/svg+xml" href="${`${e.replace(/\/$/,"")}/favicon-black.svg?v=4`}" />`}import{existsSync as Ur,readFileSync as Wo}from"fs";import U from"path";import{fileURLToPath as Ko}from"url";import{gunzipSync as Vo}from"zlib";var D=vn(Dr(),1);function te(e,t){return e.header("Retry-After",String(qo(t))),e.json({error:"Too Many Requests"},429)}function qo(e){return e&&typeof e=="object"&&"msBeforeNext"in e&&typeof e.msBeforeNext=="number"&&Number.isFinite(e.msBeforeNext)?Math.max(1,Math.ceil(e.msBeforeNext/1e3)):60}var Go={".js":"application/javascript",".css":"text/css",".svg":"image/svg+xml",".png":"image/png",".ico":"image/x-icon",".webmanifest":"application/manifest+json"};function Xo(){let e=U.dirname(Ko(import.meta.url));for(let t of[U.resolve(e,"app"),U.resolve(e,"../app"),U.resolve(e,"../../dist/app")])if(Ur(U.join(t,"inspector.js.gz")))return t;throw new Error("Inspector bundle not found (expected dist/app/inspector.js.gz)")}function Nr(e,t="/inspector/assets"){let r=Xo(),n=new Map,o=new D.default({points:600,duration:60}),s=async(i,a)=>{try{await o.consume(i.req)}catch(c){return te(i,c)}return a()};e.use(`${t}/*`,s),e.get(`${t}/*`,async i=>{let a=i.req.path.slice(t.length),c=a.startsWith("/")?a.slice(1):a;if(!c||c.includes(".."))return i.notFound();let l=c==="inspector.js"||c==="inspector.css"?`${c}.gz`:c,u=U.resolve(r,l),d=r.endsWith(U.sep)?r:`${r}${U.sep}`;if(!u.startsWith(d)||!Ur(u))return i.notFound();let f=U.extname(c),h=l.endsWith(".gz"),w=/(?:^|,)\s*gzip\s*(?:,|$)/i.test(i.req.header("accept-encoding")??""),y=Wo(u),g=h&&!w?n.get(u)??Yo(n,u,y):y,p=g.buffer.slice(g.byteOffset,g.byteOffset+g.byteLength);return i.body(p,200,{"Content-Type":Go[f]??"application/octet-stream",...h&&w?{"Content-Encoding":"gzip"}:{},...h?{Vary:"Accept-Encoding"}:{},"Cache-Control":"no-cache"})})}function Yo(e,t,r){let n=Vo(r);return e.set(t,n),n}var jr={name:"@mcp-use/inspector",type:"module",version:"20.0.0-beta.50",description:"MCP Inspector - A tool for inspecting and debugging MCP servers",author:"",license:"MIT",homepage:"https://github.com/mcp-use/mcp-use#readme",repository:{type:"git",url:"git+https://github.com/mcp-use/mcp-use.git",directory:"libraries/typescript/packages/inspector"},bugs:{url:"https://github.com/mcp-use/mcp-use/issues"},keywords:["mcp","inspector","debug","tools"],exports:{".":{types:"./dist/server/index.d.ts",import:"./dist/server/index.js"},"./client":{types:"./dist/client/index.d.ts",import:"./dist/client/index.js"}},main:"./dist/server/index.js",types:"./dist/server/index.d.ts",bin:{"mcp-inspect":"./dist/cli.js"},files:["dist"],scripts:{dev:"rimraf node_modules/.vite && VITE_MANUFACT_CHAT_URL=${VITE_MANUFACT_CHAT_URL:-http://localhost:8000/api/v1/inspector/chat/stream} vite --strictPort","dev:client":"pnpm run dev","dev:server":"VITE_DEV=true tsx watch src/server/server.ts","dev:standalone":"tsx watch src/server/server.ts",clean:"rimraf dist",build:"npm run clean && npm run build:client-exports && npm run build:server && npm run build:app && npm run verify:package","build:app":"vite build --config vite.app.config.ts && node scripts/compress-app.mjs","watch:app":"vite build --watch --config vite.app.config.ts","preview:app":"vite preview --config vite.app.config.ts --host 127.0.0.1","serve:app":"pnpm build:app && pnpm preview:app","analyze:app":"ANALYZE=true vite build --config vite.app.config.ts","build:client-exports":"tsup --config tsup.client.ts","build:server":"tsup --config tsup.server.ts","verify:package":"node scripts/verify-package.mjs",prepublishOnly:"pnpm --filter @mcp-use/client build && pnpm build",start:"node dist/cli.js --port 3000",preview:"vite preview","type-check":"tsc --noEmit",lint:"eslint .","lint:fix":"eslint . --fix","test:e2e":"playwright test","test:e2e:ui":"playwright test --ui","test:e2e:debug":"playwright test --debug","test:e2e:builtin":"node tests/e2e/scripts/run-test-matrix.mjs builtin","test:e2e:prod":"node tests/e2e/scripts/run-test-matrix.mjs prod","test:e2e:mix":"node tests/e2e/scripts/run-test-matrix.mjs mix","test:e2e:prod:ui":"TEST_MODE=production playwright test --ui","test:e2e:codegen":"playwright codegen http://localhost:3000/inspector","test:e2e:report":"playwright show-report","test:e2e:python":"node tests/e2e/scripts/run-python-e2e.mjs","test:unit":"vitest run","test:unit:watch":"vitest","test:e2e:tunnel":"node tests/e2e/scripts/run-tunnel-test.mjs","install:pnpm":"pnpm install","install:npm":"npm install","lint:npm":"npm run lint:fix","lint:pnpm":"pnpm lint:fix"},engines:{node:">=22.22.2"},peerDependencies:{"@base-ui/react":"^1.6.0","@mcp-use/agent":"^2.0.0-alpha.0","@mcp-use/client":"^2.0.0-alpha.0","class-variance-authority":"^0.7.1",clsx:"^2.1.1",express:"^4.21.2 || ^5.0.0","lucide-react":"^0.562.0","markdown-to-jsx":"^9.7.4","mcp-use":"workspace:*",motion:"^12.34.2",react:"^18.0.0 || ^19.0.0","react-dom":"^18.0.0 || ^19.0.0","react-resizable-panels":"^4.6.4",sonner:"^2.0.7","tailwind-merge":"^3.5.0"},peerDependenciesMeta:{"@base-ui/react":{optional:!0},"@mcp-use/agent":{optional:!0},"@mcp-use/client":{optional:!0},"class-variance-authority":{optional:!0},clsx:{optional:!0},express:{optional:!0},"lucide-react":{optional:!0},"markdown-to-jsx":{optional:!0},motion:{optional:!0},react:{optional:!0},"react-dom":{optional:!0},"react-resizable-panels":{optional:!0},sonner:{optional:!0},"tailwind-merge":{optional:!0}},dependencies:{},publishConfig:{access:"public"},devDependencies:{"@base-ui/react":"^1.6.0","@hono/node-server":"^1.19.13","@mcp-use/agent":"workspace:*","@mcp-use/client":"workspace:*","@playwright/test":"^1.58.2","@tailwindcss/vite":"^4.2.0","@types/express":"^5.0.6","@vitejs/plugin-react":"^6.0.0","class-variance-authority":"^0.7.1",clsx:"^2.1.1",emulate:"0.5.0",eslint:"^9.39.2",express:"^5.2.1",hono:"^4.12.12","lucide-react":"^0.562.0","markdown-to-jsx":"^9.7.4",motion:"^12.34.2","oauth2-mock-server":"^8.2.2",open:"^11.0.0",react:"^19.2.3","react-dom":"^19.2.3","react-router":"^7.12.0","react-resizable-panels":"^4.6.4","rate-limiter-flexible":"^11.2.0","rollup-plugin-visualizer":"^6.0.3",sonner:"^2.0.7","tailwind-merge":"^3.5.0",tailwindcss:"^4.2.0",tsup:"^8.5.1",tsx:"^4.21.0","tw-animate-css":"^1.4.0",typescript:"^5.9.3",vite:"^8.0.16",vitest:"^4.1.0","wait-on":"^9.0.4",zod:"^4.2.0"}};var Qo=jr.version;function Te(){return Qo}var Zo=`<!doctype html>
|
|
5
|
+
<html>
|
|
6
|
+
<head>
|
|
7
|
+
<meta charset="utf-8" />
|
|
8
|
+
<meta
|
|
9
|
+
http-equiv="Content-Security-Policy"
|
|
10
|
+
content="default-src 'self'; img-src * data: blob: 'unsafe-inline'; media-src * blob: data:; font-src * blob: data:; script-src * 'wasm-unsafe-eval' 'unsafe-inline' 'unsafe-eval' blob: data:; style-src * blob: data: 'unsafe-inline'; connect-src * data: blob: about:; frame-src * blob: data: http://localhost:* https://localhost:* http://127.0.0.1:* https://127.0.0.1:*;"
|
|
11
|
+
/>
|
|
12
|
+
<title>MCP Apps Sandbox Proxy</title>
|
|
13
|
+
<style>
|
|
14
|
+
html, body { margin: 0; padding: 0; height: 100%; width: 100%; overflow: hidden; }
|
|
15
|
+
* { box-sizing: border-box; }
|
|
16
|
+
iframe { display: block; background-color: transparent; border: 0px none transparent; padding: 0px; width: 100%; height: 100%; }
|
|
17
|
+
</style>
|
|
18
|
+
</head>
|
|
19
|
+
<body>
|
|
20
|
+
<script>
|
|
21
|
+
function sanitizeDomain(domain) {
|
|
22
|
+
if (typeof domain !== "string") return "";
|
|
23
|
+
return domain.replace(/['"<>;]/g, "").trim();
|
|
24
|
+
}
|
|
2
25
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
26
|
+
function buildAllowAttribute(permissions) {
|
|
27
|
+
if (!permissions) return "";
|
|
28
|
+
const allowList = [];
|
|
29
|
+
if (permissions.camera) allowList.push("camera *");
|
|
30
|
+
if (permissions.microphone) allowList.push("microphone *");
|
|
31
|
+
if (permissions.geolocation) allowList.push("geolocation *");
|
|
32
|
+
if (permissions.clipboardWrite) allowList.push("clipboard-write *");
|
|
33
|
+
return allowList.join("; ");
|
|
34
|
+
}
|
|
9
35
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
const envUrl = process.env.INSPECTOR_ASSETS_URL ?? process.env.MCP_USE_INSPECTOR_ASSETS_URL;
|
|
26
|
-
if (envUrl) {
|
|
27
|
-
return {
|
|
28
|
-
jsUrl: envUrl,
|
|
29
|
-
cssUrl: inspectorStylesUrl(envUrl),
|
|
30
|
-
useLocal: false
|
|
31
|
-
};
|
|
32
|
-
}
|
|
33
|
-
const legacyBase = process.env.INSPECTOR_CDN_BASE;
|
|
34
|
-
if (legacyBase) {
|
|
35
|
-
const base = legacyBase.replace(/\/$/, "");
|
|
36
|
-
if (/\.js(?:$|[?#])/.test(base)) {
|
|
37
|
-
return {
|
|
38
|
-
jsUrl: base,
|
|
39
|
-
cssUrl: inspectorStylesUrl(base),
|
|
40
|
-
useLocal: false
|
|
41
|
-
};
|
|
42
|
-
}
|
|
43
|
-
return {
|
|
44
|
-
jsUrl: `${base}/inspector.js`,
|
|
45
|
-
cssUrl: `${base}/inspector.css`,
|
|
46
|
-
useLocal: false
|
|
47
|
-
};
|
|
48
|
-
}
|
|
49
|
-
if (inspectorMode2 === "standalone") {
|
|
50
|
-
const prefix = basePath;
|
|
51
|
-
return {
|
|
52
|
-
jsUrl: `${prefix}/dist/cdn/inspector.js`,
|
|
53
|
-
cssUrl: `${prefix}/dist/cdn/inspector.css`,
|
|
54
|
-
useLocal: true
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
|
-
const jsUrl = DEFAULT_REMOTE_ASSETS_URL;
|
|
58
|
-
return {
|
|
59
|
-
jsUrl,
|
|
60
|
-
cssUrl: inspectorStylesUrl(jsUrl),
|
|
61
|
-
useLocal: false
|
|
62
|
-
};
|
|
63
|
-
}
|
|
36
|
+
function buildCSP(csp) {
|
|
37
|
+
if (!csp) {
|
|
38
|
+
return [
|
|
39
|
+
"default-src 'none'",
|
|
40
|
+
"script-src 'unsafe-inline'",
|
|
41
|
+
"style-src 'unsafe-inline'",
|
|
42
|
+
"img-src data:",
|
|
43
|
+
"font-src data:",
|
|
44
|
+
"media-src data:",
|
|
45
|
+
"connect-src 'none'",
|
|
46
|
+
"frame-src 'none'",
|
|
47
|
+
"object-src 'none'",
|
|
48
|
+
"base-uri 'none'",
|
|
49
|
+
].join("; ");
|
|
50
|
+
}
|
|
64
51
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
"favicon.ico",
|
|
71
|
-
"apple-touch-icon.png",
|
|
72
|
-
"site.webmanifest",
|
|
73
|
-
"web-app-manifest-192x192.png",
|
|
74
|
-
"web-app-manifest-512x512.png",
|
|
75
|
-
"favicon-black.svg",
|
|
76
|
-
"favicon-white.svg"
|
|
77
|
-
];
|
|
78
|
-
function renderInspectorFaviconLinks(basePath = "") {
|
|
79
|
-
const prefix = basePath.replace(/\/$/, "");
|
|
80
|
-
const href = `${prefix}/favicon-black.svg?v=${FAVICON_CACHE_VERSION}`;
|
|
81
|
-
return `<link rel="icon" type="image/svg+xml" href="${href}" />`;
|
|
82
|
-
}
|
|
52
|
+
const connectDomains = (csp.connectDomains || []).map(sanitizeDomain).filter(Boolean);
|
|
53
|
+
const resourceDomains = (csp.resourceDomains || []).map(sanitizeDomain).filter(Boolean);
|
|
54
|
+
const frameDomains = (csp.frameDomains || []).map(sanitizeDomain).filter(Boolean);
|
|
55
|
+
const baseUriDomains = (csp.baseUriDomains || []).map(sanitizeDomain).filter(Boolean);
|
|
56
|
+
const scriptDirectives = (csp.scriptDirectives || []).filter(function(d) { return typeof d === "string" && d.length > 0; });
|
|
83
57
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
58
|
+
const connectSrc = connectDomains.length > 0 ? connectDomains.join(" ") : "'none'";
|
|
59
|
+
const resourceSrc = resourceDomains.length > 0 ? ["data:", "blob:", ...resourceDomains].join(" ") : "data: blob:";
|
|
60
|
+
const frameSrc = frameDomains.length > 0 ? frameDomains.join(" ") : "'none'";
|
|
61
|
+
const baseUri = baseUriDomains.length > 0 ? baseUriDomains.join(" ") : "'none'";
|
|
62
|
+
const scriptSrcParts = ["'unsafe-inline'", resourceSrc];
|
|
63
|
+
if (scriptDirectives.length > 0) scriptSrcParts.push(scriptDirectives.join(" "));
|
|
64
|
+
|
|
65
|
+
return [
|
|
66
|
+
"default-src 'none'",
|
|
67
|
+
"script-src " + scriptSrcParts.join(" "),
|
|
68
|
+
"style-src 'unsafe-inline' " + resourceSrc,
|
|
69
|
+
"img-src " + resourceSrc,
|
|
70
|
+
"font-src " + resourceSrc,
|
|
71
|
+
"media-src " + resourceSrc,
|
|
72
|
+
"connect-src " + connectSrc,
|
|
73
|
+
"frame-src " + frameSrc,
|
|
74
|
+
"object-src 'none'",
|
|
75
|
+
"base-uri " + baseUri,
|
|
76
|
+
].join("; ");
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
function buildViolationListenerScript() {
|
|
80
|
+
return \`<script>
|
|
81
|
+
document.addEventListener('securitypolicyviolation', function(e) {
|
|
82
|
+
var violation = {
|
|
83
|
+
type: 'mcp-apps:csp-violation',
|
|
84
|
+
directive: e.violatedDirective,
|
|
85
|
+
blockedUri: e.blockedURI,
|
|
86
|
+
sourceFile: e.sourceFile || null,
|
|
87
|
+
lineNumber: e.lineNumber || null,
|
|
88
|
+
columnNumber: e.columnNumber || null,
|
|
89
|
+
effectiveDirective: e.effectiveDirective,
|
|
90
|
+
originalPolicy: e.originalPolicy,
|
|
91
|
+
disposition: e.disposition,
|
|
92
|
+
timestamp: Date.now()
|
|
93
|
+
};
|
|
94
|
+
console.warn('[MCP Apps CSP Violation]', violation.directive, ':', violation.blockedUri);
|
|
95
|
+
window.parent.postMessage(violation, '*');
|
|
96
|
+
});
|
|
97
|
+
|
|
98
|
+
function serializeConsoleArgs(args) {
|
|
99
|
+
try {
|
|
100
|
+
return Array.from(args || []).map(function(arg) {
|
|
101
|
+
if (arg instanceof Error) {
|
|
102
|
+
return {
|
|
103
|
+
type: 'Error',
|
|
104
|
+
message: arg.message,
|
|
105
|
+
stack: arg.stack,
|
|
106
|
+
name: arg.name,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (typeof arg === 'object' && arg !== null) {
|
|
110
|
+
try {
|
|
111
|
+
return JSON.parse(JSON.stringify(arg));
|
|
112
|
+
} catch (e) {
|
|
113
|
+
return String(arg);
|
|
114
|
+
}
|
|
126
115
|
}
|
|
116
|
+
return arg;
|
|
127
117
|
});
|
|
118
|
+
} catch (e) {
|
|
119
|
+
return [String(args)];
|
|
128
120
|
}
|
|
129
121
|
}
|
|
130
122
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
".webmanifest": "application/manifest+json"
|
|
142
|
-
};
|
|
143
|
-
function resolveDistCdnDir() {
|
|
144
|
-
const here = path2.dirname(fileURLToPath2(import.meta.url));
|
|
145
|
-
for (const dir of [
|
|
146
|
-
path2.resolve(here, "cdn"),
|
|
147
|
-
// dist/cli.js (bundled)
|
|
148
|
-
path2.resolve(here, "../cdn")
|
|
149
|
-
// dist/server/*.js
|
|
150
|
-
]) {
|
|
151
|
-
if (existsSync2(path2.join(dir, "inspector.js"))) {
|
|
152
|
-
return dir;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
throw new Error(
|
|
156
|
-
"Inspector bundle not found (expected dist/cdn/inspector.js)"
|
|
157
|
-
);
|
|
158
|
-
}
|
|
159
|
-
function registerInspectorStaticAssets(app2, basePath = "") {
|
|
160
|
-
const cdnDir = resolveDistCdnDir();
|
|
161
|
-
const mountPath = `${basePath}/dist/cdn`;
|
|
162
|
-
app2.get(`${mountPath}/*`, (c) => {
|
|
163
|
-
const subPath = c.req.path.slice(mountPath.length);
|
|
164
|
-
const relative = subPath.startsWith("/") ? subPath.slice(1) : subPath;
|
|
165
|
-
if (!relative || relative.includes("..")) {
|
|
166
|
-
return c.notFound();
|
|
167
|
-
}
|
|
168
|
-
const file = path2.resolve(cdnDir, relative);
|
|
169
|
-
const root = cdnDir.endsWith(path2.sep) ? cdnDir : `${cdnDir}${path2.sep}`;
|
|
170
|
-
if (!file.startsWith(root) || !existsSync2(file)) {
|
|
171
|
-
return c.notFound();
|
|
172
|
-
}
|
|
173
|
-
const ext = path2.extname(file);
|
|
174
|
-
return c.body(readFileSync2(file), 200, {
|
|
175
|
-
"Content-Type": CONTENT_TYPES2[ext] ?? "application/octet-stream",
|
|
176
|
-
"Cache-Control": "public, max-age=3600"
|
|
177
|
-
});
|
|
178
|
-
});
|
|
123
|
+
function sendConsoleToParent(level, args) {
|
|
124
|
+
try {
|
|
125
|
+
window.parent.postMessage({
|
|
126
|
+
type: 'iframe-console-log',
|
|
127
|
+
level: level,
|
|
128
|
+
args: serializeConsoleArgs(args),
|
|
129
|
+
timestamp: new Date().toISOString(),
|
|
130
|
+
url: window.location.href,
|
|
131
|
+
}, '*');
|
|
132
|
+
} catch (e) {}
|
|
179
133
|
}
|
|
180
134
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
description: "MCP Inspector - A tool for inspecting and debugging MCP servers",
|
|
187
|
-
author: "",
|
|
188
|
-
license: "MIT",
|
|
189
|
-
homepage: "https://github.com/mcp-use/mcp-use#readme",
|
|
190
|
-
repository: {
|
|
191
|
-
type: "git",
|
|
192
|
-
url: "git+https://github.com/mcp-use/mcp-use.git",
|
|
193
|
-
directory: "libraries/typescript/packages/inspector"
|
|
194
|
-
},
|
|
195
|
-
bugs: {
|
|
196
|
-
url: "https://github.com/mcp-use/mcp-use/issues"
|
|
197
|
-
},
|
|
198
|
-
keywords: [
|
|
199
|
-
"mcp",
|
|
200
|
-
"inspector",
|
|
201
|
-
"debug",
|
|
202
|
-
"tools"
|
|
203
|
-
],
|
|
204
|
-
exports: {
|
|
205
|
-
".": {
|
|
206
|
-
types: "./dist/server/index.d.ts",
|
|
207
|
-
import: "./dist/server/index.js"
|
|
208
|
-
},
|
|
209
|
-
"./proxy": {
|
|
210
|
-
types: "./dist/server/proxy-routes.d.ts",
|
|
211
|
-
import: "./dist/server/proxy-routes.js"
|
|
212
|
-
},
|
|
213
|
-
"./client": {
|
|
214
|
-
types: "./dist/client/index.d.ts",
|
|
215
|
-
import: "./dist/client/index.js"
|
|
216
|
-
}
|
|
217
|
-
},
|
|
218
|
-
main: "./dist/server/index.js",
|
|
219
|
-
types: "./dist/server/index.d.ts",
|
|
220
|
-
bin: {
|
|
221
|
-
"mcp-inspect": "./dist/cli.js"
|
|
222
|
-
},
|
|
223
|
-
files: [
|
|
224
|
-
"dist"
|
|
225
|
-
],
|
|
226
|
-
scripts: {
|
|
227
|
-
dev: "rimraf node_modules/.vite && VITE_MANUFACT_CHAT_URL=${VITE_MANUFACT_CHAT_URL:-http://localhost:8000/api/v1/inspector/chat/stream} vite --strictPort",
|
|
228
|
-
"dev:client": "pnpm run dev",
|
|
229
|
-
"dev:server": "VITE_DEV=true tsx watch src/server/server.ts",
|
|
230
|
-
"dev:standalone": "tsx watch src/server/server.ts",
|
|
231
|
-
build: "npm run build:client && npm run build:client-exports && npm run build:server && npm run build:cli && npm run build:cdn",
|
|
232
|
-
"build:cdn": "vite build --config vite.cdn.config.ts",
|
|
233
|
-
"watch:cdn": "vite build --watch --config vite.cdn.config.ts",
|
|
234
|
-
"preview:cdn": "vite preview --config vite.cdn.config.ts --host 127.0.0.1",
|
|
235
|
-
"serve:cdn": "pnpm build:cdn && pnpm preview:cdn",
|
|
236
|
-
"analyze:cdn": "ANALYZE=true vite build --config vite.cdn.config.ts",
|
|
237
|
-
"build:client": "vite build",
|
|
238
|
-
"build:client-exports": "tsup --config tsup.client.ts && tsc -p tsconfig.client.json --emitDeclarationOnly --declaration",
|
|
239
|
-
"build:server": "tsup 'src/server/**/*.ts' --format esm --out-dir dist/server && tsc -p tsconfig.server.json --emitDeclarationOnly --declaration",
|
|
240
|
-
"build:cli": "tsup src/server/cli.ts --format esm --out-dir dist/",
|
|
241
|
-
prepublishOnly: "pnpm --filter @mcp-use/client build && pnpm build",
|
|
242
|
-
start: "node dist/cli.js --port 3000",
|
|
243
|
-
preview: "vite preview",
|
|
244
|
-
"type-check": "tsc --noEmit",
|
|
245
|
-
lint: "eslint .",
|
|
246
|
-
"lint:fix": "eslint . --fix",
|
|
247
|
-
"test:e2e": "playwright test",
|
|
248
|
-
"test:e2e:ui": "playwright test --ui",
|
|
249
|
-
"test:e2e:debug": "playwright test --debug",
|
|
250
|
-
"test:e2e:builtin": "node tests/e2e/scripts/run-test-matrix.mjs builtin",
|
|
251
|
-
"test:e2e:prod": "node tests/e2e/scripts/run-test-matrix.mjs prod",
|
|
252
|
-
"test:e2e:mix": "node tests/e2e/scripts/run-test-matrix.mjs mix",
|
|
253
|
-
"test:e2e:prod:ui": "TEST_MODE=production playwright test --ui",
|
|
254
|
-
"test:e2e:codegen": "playwright codegen http://localhost:3000/inspector",
|
|
255
|
-
"test:e2e:report": "playwright show-report",
|
|
256
|
-
"test:e2e:python": "node tests/e2e/scripts/run-python-e2e.mjs",
|
|
257
|
-
"test:unit": "vitest run",
|
|
258
|
-
"test:unit:watch": "vitest",
|
|
259
|
-
"test:e2e:tunnel": "node tests/e2e/scripts/run-tunnel-test.mjs",
|
|
260
|
-
"install:yarn": "yarn install",
|
|
261
|
-
"install:pnpm": "pnpm install",
|
|
262
|
-
"install:npm": "npm install",
|
|
263
|
-
"lint:yarn": "yarn eslint . --fix",
|
|
264
|
-
"lint:npm": "npm run lint:fix",
|
|
265
|
-
"lint:pnpm": "pnpm lint:fix"
|
|
266
|
-
},
|
|
267
|
-
engines: {
|
|
268
|
-
node: ">=22.22.2"
|
|
269
|
-
},
|
|
270
|
-
peerDependencies: {
|
|
271
|
-
"@mcp-use/client": "^2.0.0-alpha.0",
|
|
272
|
-
express: "^4.21.2 || ^5.0.0",
|
|
273
|
-
react: "^18.0.0 || ^19.0.0",
|
|
274
|
-
"react-dom": "^18.0.0 || ^19.0.0",
|
|
275
|
-
"react-router": "^7.12.0"
|
|
276
|
-
},
|
|
277
|
-
peerDependenciesMeta: {
|
|
278
|
-
express: {
|
|
279
|
-
optional: true
|
|
280
|
-
}
|
|
281
|
-
},
|
|
282
|
-
dependencies: {
|
|
283
|
-
"@base-ui/react": "^1.6.0",
|
|
284
|
-
"@hono/node-server": "^1.19.13",
|
|
285
|
-
"@mcp-use/agent": "workspace:*",
|
|
286
|
-
"@mcp-use/client": "workspace:*",
|
|
287
|
-
"class-variance-authority": "^0.7.1",
|
|
288
|
-
clsx: "^2.1.1",
|
|
289
|
-
hono: "^4.12.12",
|
|
290
|
-
"lucide-react": "^0.562.0",
|
|
291
|
-
"markdown-to-jsx": "^9.7.4",
|
|
292
|
-
motion: "^12.34.2",
|
|
293
|
-
open: "^11.0.0",
|
|
294
|
-
"react-resizable-panels": "^4.6.4",
|
|
295
|
-
sonner: "^2.0.7",
|
|
296
|
-
"tailwind-merge": "^3.5.0"
|
|
297
|
-
},
|
|
298
|
-
publishConfig: {
|
|
299
|
-
access: "public"
|
|
300
|
-
},
|
|
301
|
-
devDependencies: {
|
|
302
|
-
"@playwright/test": "^1.58.2",
|
|
303
|
-
"@tailwindcss/vite": "^4.2.0",
|
|
304
|
-
"@types/express": "^5.0.6",
|
|
305
|
-
"mcp-use": "workspace:*",
|
|
306
|
-
"@vitejs/plugin-react": "^6.0.0",
|
|
307
|
-
emulate: "0.5.0",
|
|
308
|
-
eslint: "^9.39.2",
|
|
309
|
-
express: "^5.2.1",
|
|
310
|
-
"oauth2-mock-server": "^8.2.2",
|
|
311
|
-
react: "^19.2.3",
|
|
312
|
-
"react-dom": "^19.2.3",
|
|
313
|
-
"react-router": "^7.12.0",
|
|
314
|
-
"rollup-plugin-visualizer": "^6.0.3",
|
|
315
|
-
tailwindcss: "^4.2.0",
|
|
316
|
-
tsup: "^8.5.1",
|
|
317
|
-
tsx: "^4.21.0",
|
|
318
|
-
"tw-animate-css": "^1.4.0",
|
|
319
|
-
typescript: "^5.9.3",
|
|
320
|
-
vite: "^8.0.16",
|
|
321
|
-
vitest: "^4.1.0",
|
|
322
|
-
"wait-on": "^9.0.4",
|
|
323
|
-
zod: "^4.2.0"
|
|
324
|
-
}
|
|
135
|
+
var originalConsoleError = console.error.bind(console);
|
|
136
|
+
console.error = function() {
|
|
137
|
+
var args = Array.from(arguments);
|
|
138
|
+
originalConsoleError.apply(console, args);
|
|
139
|
+
sendConsoleToParent('error', args);
|
|
325
140
|
};
|
|
326
141
|
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
142
|
+
window.addEventListener('error', function(event) {
|
|
143
|
+
sendConsoleToParent('error', [{
|
|
144
|
+
message: event.message,
|
|
145
|
+
filename: event.filename,
|
|
146
|
+
lineno: event.lineno,
|
|
147
|
+
colno: event.colno,
|
|
148
|
+
error: event.error ? {
|
|
149
|
+
message: event.error.message,
|
|
150
|
+
stack: event.error.stack,
|
|
151
|
+
name: event.error.name,
|
|
152
|
+
} : null,
|
|
153
|
+
}]);
|
|
154
|
+
});
|
|
155
|
+
|
|
156
|
+
window.addEventListener('unhandledrejection', function(event) {
|
|
157
|
+
sendConsoleToParent('error', [{
|
|
158
|
+
message: 'Unhandled Promise Rejection',
|
|
159
|
+
reason: event.reason ? String(event.reason) : 'Unknown',
|
|
160
|
+
error: event.reason instanceof Error ? {
|
|
161
|
+
message: event.reason.message,
|
|
162
|
+
stack: event.reason.stack,
|
|
163
|
+
name: event.reason.name,
|
|
164
|
+
} : null,
|
|
165
|
+
}]);
|
|
166
|
+
});
|
|
167
|
+
</\` + \`script>\`;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
function injectCSP(html, cspValue) {
|
|
171
|
+
const cspMeta = '<meta http-equiv="Content-Security-Policy" content="' + cspValue + '">';
|
|
172
|
+
const violationListener = buildViolationListenerScript();
|
|
173
|
+
const injection = cspMeta + violationListener;
|
|
174
|
+
|
|
175
|
+
if (html.includes("<head>")) {
|
|
176
|
+
return html.replace("<head>", "<head>" + injection);
|
|
177
|
+
} else if (html.includes("<HEAD>")) {
|
|
178
|
+
return html.replace("<HEAD>", "<HEAD>" + injection);
|
|
179
|
+
} else if (html.includes("<html>")) {
|
|
180
|
+
return html.replace("<html>", "<html><head>" + injection + "</head>");
|
|
181
|
+
} else if (html.includes("<HTML>")) {
|
|
182
|
+
return html.replace("<HTML>", "<HTML><head>" + injection + "</head>");
|
|
183
|
+
} else if (html.includes("<!DOCTYPE") || html.includes("<!doctype")) {
|
|
184
|
+
return html.replace(/(<!DOCTYPE[^>]*>|<!doctype[^>]*>)/i, "$1<head>" + injection + "</head>");
|
|
185
|
+
} else {
|
|
186
|
+
return injection + html;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// Query params from host (csp_mode, permissions, widget_csp). AppFrame only
|
|
191
|
+
// sends { html, csp } in sandbox-resource-ready; we carry the rest on the URL.
|
|
192
|
+
// Blob URLs cannot reliably carry search params, so the CDN shell injects
|
|
193
|
+
// window.__SANDBOX_SEARCH__ via buildSandboxProxyBlobHtml.
|
|
194
|
+
const query = new URLSearchParams(
|
|
195
|
+
typeof window.__SANDBOX_SEARCH__ === "string"
|
|
196
|
+
? window.__SANDBOX_SEARCH__
|
|
197
|
+
: location.search
|
|
198
|
+
);
|
|
199
|
+
const queryCspMode = query.get("csp_mode") || "permissive";
|
|
200
|
+
let queryPermissions = null;
|
|
201
|
+
let queryWidgetCsp = null;
|
|
202
|
+
try {
|
|
203
|
+
const rawPerm = query.get("permissions");
|
|
204
|
+
if (rawPerm) queryPermissions = JSON.parse(rawPerm);
|
|
205
|
+
} catch (e) {}
|
|
206
|
+
try {
|
|
207
|
+
const rawCsp = query.get("widget_csp");
|
|
208
|
+
if (rawCsp) queryWidgetCsp = JSON.parse(rawCsp);
|
|
209
|
+
} catch (e) {}
|
|
210
|
+
|
|
211
|
+
const inner = document.createElement("iframe");
|
|
212
|
+
inner.style = "width:100%; height:100%; border:none;";
|
|
213
|
+
inner.setAttribute("sandbox", "allow-scripts allow-same-origin allow-forms");
|
|
214
|
+
document.body.appendChild(inner);
|
|
332
215
|
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
216
|
+
window.addEventListener("message", async (event) => {
|
|
217
|
+
if (event.source === window.parent) {
|
|
218
|
+
if (event.data && event.data.method === "ui/notifications/sandbox-resource-ready") {
|
|
219
|
+
const params = event.data.params || {};
|
|
220
|
+
const html = params.html;
|
|
221
|
+
const sandbox = params.sandbox;
|
|
222
|
+
// Prefer message csp when present; fall back to URL widget_csp
|
|
223
|
+
const csp = params.csp != null ? params.csp : queryWidgetCsp;
|
|
224
|
+
const permissions = params.permissions != null ? params.permissions : queryPermissions;
|
|
225
|
+
const permissive =
|
|
226
|
+
typeof params.permissive === "boolean"
|
|
227
|
+
? params.permissive
|
|
228
|
+
: queryCspMode === "permissive";
|
|
229
|
+
if (typeof sandbox === "string") {
|
|
230
|
+
inner.setAttribute("sandbox", sandbox);
|
|
231
|
+
}
|
|
232
|
+
const allowAttribute = buildAllowAttribute(permissions);
|
|
233
|
+
if (allowAttribute) {
|
|
234
|
+
inner.setAttribute("allow", allowAttribute);
|
|
235
|
+
}
|
|
236
|
+
if (typeof html === "string") {
|
|
237
|
+
if (permissive) {
|
|
238
|
+
const permissiveCsp = [
|
|
239
|
+
"default-src * 'unsafe-inline' 'unsafe-eval' data: blob: filesystem: about:",
|
|
240
|
+
"script-src * 'unsafe-inline' 'unsafe-eval' data: blob:",
|
|
241
|
+
"style-src * 'unsafe-inline' data: blob:",
|
|
242
|
+
"img-src * data: blob: https: http:",
|
|
243
|
+
"media-src * data: blob: https: http:",
|
|
244
|
+
"font-src * data: blob: https: http:",
|
|
245
|
+
"connect-src * data: blob: https: http: ws: wss: about:",
|
|
246
|
+
"frame-src * data: blob: https: http: about:",
|
|
247
|
+
"object-src * data: blob:",
|
|
248
|
+
"base-uri *",
|
|
249
|
+
"form-action *",
|
|
250
|
+
].join("; ");
|
|
251
|
+
const processedHtml = injectCSP(html, permissiveCsp);
|
|
252
|
+
inner.srcdoc = processedHtml;
|
|
253
|
+
} else {
|
|
254
|
+
const cspValue = buildCSP(csp);
|
|
255
|
+
const processedHtml = injectCSP(html, cspValue);
|
|
256
|
+
inner.srcdoc = processedHtml;
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
} else {
|
|
260
|
+
if (inner && inner.contentWindow) {
|
|
261
|
+
inner.contentWindow.postMessage(event.data, "*");
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
} else if (event.source === inner.contentWindow) {
|
|
265
|
+
window.parent.postMessage(event.data, "*");
|
|
266
|
+
}
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
window.parent.postMessage({
|
|
270
|
+
jsonrpc: "2.0",
|
|
271
|
+
method: "ui/notifications/sandbox-proxy-ready",
|
|
272
|
+
params: {},
|
|
273
|
+
}, "*");
|
|
274
|
+
</script>
|
|
275
|
+
</body>
|
|
276
|
+
</html>`;function Hr(e){let r="<script>window.__SANDBOX_SEARCH__ = "+JSON.stringify(e).replace(/</g,"\\u003c")+";</script>";return Zo.replace("<body>","<body>"+r)}var Br=Te();function es(e){let t=e.hostname==="localhost"?"127.0.0.1":e.hostname==="127.0.0.1"||e.hostname==="::1"?"localhost":void 0;if(!t)return;let r=new URL(e.origin);return r.hostname=t,r.origin}var ts=`<!doctype html>
|
|
336
277
|
<html lang="en"><head><meta charset="utf-8"><title>Signed in</title><meta name="robots" content="noindex"><style>html,body{margin:0;height:100%;display:flex;align-items:center;justify-content:center;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",sans-serif;color:#4b5563;background:#fff}</style></head>
|
|
337
278
|
<body><div>Signed in. You can close this window.</div>
|
|
338
279
|
<script>try{if(window.opener&&!window.opener.closed)window.opener.postMessage({type:"manufact:oauth-complete"},"*")}catch(e){}try{window.close()}catch(e){}</script>
|
|
339
|
-
</body></html>`;
|
|
340
|
-
|
|
341
|
-
const scripts = [];
|
|
342
|
-
if (config?.basePath !== void 0) {
|
|
343
|
-
scripts.push(
|
|
344
|
-
`<script>window.__MCP_BASE_PATH__ = ${JSON.stringify(config.basePath)};</script>`
|
|
345
|
-
);
|
|
346
|
-
}
|
|
347
|
-
if (config?.devMode) {
|
|
348
|
-
scripts.push(`<script>window.__MCP_DEV_MODE__ = true;</script>`);
|
|
349
|
-
}
|
|
350
|
-
if (config?.sandboxOrigin) {
|
|
351
|
-
scripts.push(
|
|
352
|
-
`<script>window.__MCP_SANDBOX_ORIGIN__ = ${JSON.stringify(config.sandboxOrigin)};</script>`
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
if (config?.proxyUrl !== void 0) {
|
|
356
|
-
scripts.push(
|
|
357
|
-
`<script>window.__MCP_PROXY_URL__ = ${JSON.stringify(config.proxyUrl)};</script>`
|
|
358
|
-
);
|
|
359
|
-
}
|
|
360
|
-
if (config?.inspectorMode) {
|
|
361
|
-
scripts.push(
|
|
362
|
-
`<script>window.__MCP_INSPECTOR_MODE__ = ${JSON.stringify(config.inspectorMode)};</script>`
|
|
363
|
-
);
|
|
364
|
-
}
|
|
365
|
-
if (config?.manufactChatUrl) {
|
|
366
|
-
scripts.push(
|
|
367
|
-
`<script>window.__MANUFACT_CHAT_URL__ = ${JSON.stringify(config.manufactChatUrl)};</script>`
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
if (config?.disableTelemetry) {
|
|
371
|
-
scripts.push(
|
|
372
|
-
`<script>window.__MCP_USE_ANONYMIZED_TELEMETRY__ = false;try{localStorage.setItem("MCP_USE_ANONYMIZED_TELEMETRY","false");}catch(e){}</script>`
|
|
373
|
-
);
|
|
374
|
-
}
|
|
375
|
-
const runtimeScripts = scripts.join("\n ");
|
|
376
|
-
return `<!doctype html>
|
|
280
|
+
</body></html>`;function rs(e,t,r){let n=[];e?.basePath!==void 0&&n.push(`<script>window.__MCP_BASE_PATH__ = ${JSON.stringify(e.basePath)};</script>`),e?.devMode&&n.push("<script>window.__MCP_DEV_MODE__ = true;</script>"),e?.sandboxOrigin&&n.push(`<script>window.__MCP_SANDBOX_ORIGIN__ = ${JSON.stringify(e.sandboxOrigin)};</script>`),e?.proxyUrl!==void 0&&n.push(`<script>window.__MCP_PROXY_URL__ = ${JSON.stringify(e.proxyUrl)};</script>`),e?.inspectorMode&&n.push(`<script>window.__MCP_INSPECTOR_MODE__ = ${JSON.stringify(e.inspectorMode)};</script>`),e?.manufactChatUrl&&n.push(`<script>window.__MANUFACT_CHAT_URL__ = ${JSON.stringify(e.manufactChatUrl)};</script>`),e?.disableTelemetry&&n.push('<script>window.__MCP_USE_ANONYMIZED_TELEMETRY__ = false;try{localStorage.setItem("MCP_USE_ANONYMIZED_TELEMETRY","false");}catch(e){}</script>'),process.env.MCP_USE_DEV_CLI==="1"&&n.push("<script>window.__MCP_DEV_CLI__ = true;</script>");let o=n.join(`
|
|
281
|
+
`);return`<!doctype html>
|
|
377
282
|
<html lang="en">
|
|
378
283
|
<head>
|
|
379
284
|
<meta charset="UTF-8" />
|
|
380
|
-
${
|
|
285
|
+
${Rr(`${t}/inspector/assets`)}
|
|
381
286
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
382
287
|
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
383
288
|
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
384
289
|
<link href="https://fonts.googleapis.com/css2?family=Ubuntu:wght@400;500;700&display=swap" rel="stylesheet" />
|
|
385
|
-
<link rel="stylesheet" href="${
|
|
290
|
+
<link rel="stylesheet" href="${r.cssUrl}" />
|
|
386
291
|
<title>Inspector | mcp-use</title>
|
|
387
292
|
<meta name="description" content="Free, open-source MCP Inspector by mcp-use. Connect to any MCP server, test tools, prompts, and resources, inspect RPC logs, and debug MCP apps \u2014 all in your browser." />
|
|
388
|
-
<
|
|
389
|
-
|
|
293
|
+
<style>
|
|
294
|
+
:root { color-scheme: light dark; }
|
|
295
|
+
html, body { height: 100%; margin: 0; background-color: #f3f3f3; }
|
|
296
|
+
#root { height: 100%; }
|
|
297
|
+
.mcp-boot {
|
|
298
|
+
display: flex;
|
|
299
|
+
height: 100%;
|
|
300
|
+
align-items: center;
|
|
301
|
+
justify-content: center;
|
|
302
|
+
background-color: #f3f3f3;
|
|
303
|
+
}
|
|
304
|
+
.mcp-boot-inner {
|
|
305
|
+
display: flex;
|
|
306
|
+
flex-direction: column;
|
|
307
|
+
align-items: center;
|
|
308
|
+
gap: 16px;
|
|
309
|
+
}
|
|
310
|
+
.mcp-boot-spinner {
|
|
311
|
+
width: 32px;
|
|
312
|
+
height: 32px;
|
|
313
|
+
color: #52525b;
|
|
314
|
+
animation: mcp-boot-spin 1s linear infinite;
|
|
315
|
+
}
|
|
316
|
+
.mcp-boot-label {
|
|
317
|
+
margin: 0;
|
|
318
|
+
font-family: Ubuntu, sans-serif;
|
|
319
|
+
font-size: 0.875rem;
|
|
320
|
+
line-height: 1.25rem;
|
|
321
|
+
color: #52525b;
|
|
322
|
+
}
|
|
323
|
+
@keyframes mcp-boot-spin {
|
|
324
|
+
to { transform: rotate(360deg); }
|
|
325
|
+
}
|
|
326
|
+
@media (prefers-color-scheme: dark) {
|
|
327
|
+
html, body { background-color: #000; }
|
|
328
|
+
.mcp-boot { background-color: #000; }
|
|
329
|
+
.mcp-boot-spinner, .mcp-boot-label { color: #a1a1aa; }
|
|
330
|
+
}
|
|
331
|
+
</style>
|
|
332
|
+
<script>window.__INSPECTOR_VERSION__ = ${JSON.stringify(Br)};</script>
|
|
333
|
+
${o}
|
|
390
334
|
</head>
|
|
391
335
|
<body>
|
|
392
336
|
<script>
|
|
@@ -402,972 +346,32 @@ function generateCdnShellHtml(config, basePath, assets) {
|
|
|
402
346
|
};
|
|
403
347
|
}
|
|
404
348
|
</script>
|
|
405
|
-
<div id="root"
|
|
406
|
-
|
|
349
|
+
<div id="root">
|
|
350
|
+
<div class="mcp-boot">
|
|
351
|
+
<div class="mcp-boot-inner">
|
|
352
|
+
<svg
|
|
353
|
+
class="mcp-boot-spinner"
|
|
354
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
355
|
+
viewBox="0 0 24 24"
|
|
356
|
+
fill="none"
|
|
357
|
+
stroke="currentColor"
|
|
358
|
+
stroke-width="2"
|
|
359
|
+
stroke-linecap="round"
|
|
360
|
+
stroke-linejoin="round"
|
|
361
|
+
role="status"
|
|
362
|
+
aria-label="Loading"
|
|
363
|
+
>
|
|
364
|
+
<path d="M21 12a9 9 0 1 1-6.219-8.56" />
|
|
365
|
+
</svg>
|
|
366
|
+
<p class="mcp-boot-label">Connecting to MCP server...</p>
|
|
367
|
+
</div>
|
|
368
|
+
</div>
|
|
369
|
+
</div>
|
|
370
|
+
<script type="module" src="${r.jsUrl}"></script>
|
|
407
371
|
</body>
|
|
408
|
-
</html>`;
|
|
409
|
-
|
|
410
|
-
function
|
|
411
|
-
const assets = resolveInspectorAssetUrls(config?.inspectorMode, basePath);
|
|
412
|
-
const p = (suffix) => `${basePath}${suffix}`;
|
|
413
|
-
const effectiveConfig = {
|
|
414
|
-
...config,
|
|
415
|
-
basePath: config?.basePath ?? basePath,
|
|
416
|
-
proxyUrl: config?.proxyUrl !== void 0 ? config.proxyUrl : p("/inspector/api/proxy"),
|
|
417
|
-
disableTelemetry: config?.disableTelemetry ?? process.env.MCP_USE_ANONYMIZED_TELEMETRY === "false"
|
|
418
|
-
};
|
|
419
|
-
const serveShell = (c) => {
|
|
420
|
-
const base = resolveInspectorAssetUrls(config?.inspectorMode, basePath);
|
|
421
|
-
const jsUrl = withInspectorCacheBust(base.jsUrl);
|
|
422
|
-
return c.html(
|
|
423
|
-
generateCdnShellHtml(effectiveConfig, basePath, {
|
|
424
|
-
jsUrl,
|
|
425
|
-
cssUrl: inspectorStylesUrl(jsUrl)
|
|
426
|
-
})
|
|
427
|
-
);
|
|
428
|
-
};
|
|
429
|
-
registerInspectorFaviconStatic(app2, basePath);
|
|
430
|
-
app2.get(
|
|
431
|
-
p("/inspector/oauth-popup-closed.html"),
|
|
432
|
-
(c) => c.html(OAUTH_POPUP_CLOSED_HTML)
|
|
433
|
-
);
|
|
434
|
-
app2.get(p("/inspector"), serveShell);
|
|
435
|
-
app2.get(`${p("/inspector")}/`, serveShell);
|
|
436
|
-
const apiPrefix = p("/inspector/api/");
|
|
437
|
-
app2.get(p("/inspector/*"), (c) => {
|
|
438
|
-
if (c.req.path.startsWith(apiPrefix)) {
|
|
439
|
-
return c.notFound();
|
|
440
|
-
}
|
|
441
|
-
return serveShell(c);
|
|
442
|
-
});
|
|
443
|
-
app2.post(p("/inspector/*"), (c) => {
|
|
444
|
-
if (c.req.path.startsWith(apiPrefix)) {
|
|
445
|
-
return c.notFound();
|
|
446
|
-
}
|
|
447
|
-
return serveShell(c);
|
|
448
|
-
});
|
|
449
|
-
if (basePath === "") {
|
|
450
|
-
app2.get("/", (c) => {
|
|
451
|
-
const url = new URL(c.req.url);
|
|
452
|
-
return c.redirect(`${p("/inspector")}${url.search}`);
|
|
453
|
-
});
|
|
454
|
-
}
|
|
455
|
-
if (assets.useLocal) {
|
|
456
|
-
registerInspectorStaticAssets(app2, basePath);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
// src/server/proxy/mcp-proxy.ts
|
|
461
|
-
import { cors } from "hono/cors";
|
|
462
|
-
import { logger } from "hono/logger";
|
|
463
|
-
|
|
464
|
-
// src/server/proxy/oauth-proxy.ts
|
|
465
|
-
import { lookup } from "dns/promises";
|
|
466
|
-
import { isIP } from "net";
|
|
467
|
-
var SAFE_REQUEST_HEADERS = /* @__PURE__ */ new Set([
|
|
468
|
-
"accept",
|
|
469
|
-
"authorization",
|
|
470
|
-
"content-type",
|
|
471
|
-
"dpop"
|
|
472
|
-
]);
|
|
473
|
-
var SAFE_RESPONSE_HEADERS = /* @__PURE__ */ new Set([
|
|
474
|
-
"cache-control",
|
|
475
|
-
"content-type",
|
|
476
|
-
"dpop-nonce",
|
|
477
|
-
"expires",
|
|
478
|
-
"pragma",
|
|
479
|
-
"retry-after",
|
|
480
|
-
"www-authenticate"
|
|
481
|
-
]);
|
|
482
|
-
var ENDPOINT_FIELDS = [
|
|
483
|
-
["registration_endpoint", "registration"],
|
|
484
|
-
["token_endpoint", "token"],
|
|
485
|
-
["revocation_endpoint", "revocation"],
|
|
486
|
-
["introspection_endpoint", "introspection"]
|
|
487
|
-
];
|
|
488
|
-
var BINDING_TTL_MS = 10 * 60 * 1e3;
|
|
489
|
-
var MAX_BINDINGS = 100;
|
|
490
|
-
function mountOAuthProxy(app2, options = {}) {
|
|
491
|
-
const {
|
|
492
|
-
basePath = "/oauth",
|
|
493
|
-
allowedOrigins = [],
|
|
494
|
-
allowLoopback = false,
|
|
495
|
-
timeoutMs = 1e4,
|
|
496
|
-
maxRequestBodyBytes = 64 * 1024,
|
|
497
|
-
maxResponseBodyBytes = 1024 * 1024,
|
|
498
|
-
enableLogging = true,
|
|
499
|
-
authenticate,
|
|
500
|
-
validateServerUrl
|
|
501
|
-
} = options;
|
|
502
|
-
const origins = new Set(allowedOrigins.map(normalizeOrigin));
|
|
503
|
-
const bindings = /* @__PURE__ */ new Map();
|
|
504
|
-
app2.use(`${basePath}/*`, async (c, next) => {
|
|
505
|
-
const origin = c.req.header("Origin");
|
|
506
|
-
if (origin && !isAllowedOrigin(origin, c.req.url, origins)) {
|
|
507
|
-
return c.json({ error: "Origin not allowed" }, 403);
|
|
508
|
-
}
|
|
509
|
-
if (c.req.method === "OPTIONS") {
|
|
510
|
-
return corsResponse(origin);
|
|
511
|
-
}
|
|
512
|
-
await next();
|
|
513
|
-
if (origin) setCorsHeaders(c.res.headers, origin);
|
|
514
|
-
});
|
|
515
|
-
app2.get(`${basePath}/metadata`, async (c) => {
|
|
516
|
-
if (!await isAuthenticated(c, authenticate)) {
|
|
517
|
-
return c.json({ error: "Unauthorized" }, 401);
|
|
518
|
-
}
|
|
519
|
-
const serverUrlResult = await validateUrl(
|
|
520
|
-
c.req.query("serverUrl"),
|
|
521
|
-
allowLoopback
|
|
522
|
-
);
|
|
523
|
-
if ("error" in serverUrlResult) {
|
|
524
|
-
return c.json({ error: serverUrlResult.error }, 400);
|
|
525
|
-
}
|
|
526
|
-
const serverUrl = serverUrlResult.url;
|
|
527
|
-
if (validateServerUrl && !await validateServerUrl(serverUrl.toString(), c)) {
|
|
528
|
-
return c.json({ error: "MCP server URL not allowed" }, 403);
|
|
529
|
-
}
|
|
530
|
-
const targetResult = await validateUrl(c.req.query("url"), allowLoopback);
|
|
531
|
-
if ("error" in targetResult) {
|
|
532
|
-
return c.json({ error: targetResult.error }, 400);
|
|
533
|
-
}
|
|
534
|
-
const target = targetResult.url;
|
|
535
|
-
const key = canonicalUrl(serverUrl);
|
|
536
|
-
const binding = getBinding(bindings, key);
|
|
537
|
-
let metadataKind = classifyMetadataTarget(serverUrl, target, binding);
|
|
538
|
-
if (!metadataKind && binding.authorizationServers.size === 0) {
|
|
539
|
-
try {
|
|
540
|
-
await hydrateBinding(
|
|
541
|
-
serverUrl,
|
|
542
|
-
binding,
|
|
543
|
-
allowLoopback,
|
|
544
|
-
timeoutMs,
|
|
545
|
-
maxResponseBodyBytes
|
|
546
|
-
);
|
|
547
|
-
bindings.set(key, binding);
|
|
548
|
-
metadataKind = classifyMetadataTarget(serverUrl, target, binding);
|
|
549
|
-
} catch {
|
|
550
|
-
}
|
|
551
|
-
}
|
|
552
|
-
if (!metadataKind) {
|
|
553
|
-
return c.json(
|
|
554
|
-
{ error: "Metadata target is not bound to this MCP server" },
|
|
555
|
-
403
|
|
556
|
-
);
|
|
557
|
-
}
|
|
558
|
-
try {
|
|
559
|
-
log(enableLogging, `GET ${target}`);
|
|
560
|
-
const upstream = await safeFetch(target, {
|
|
561
|
-
method: "GET",
|
|
562
|
-
headers: { Accept: "application/json" },
|
|
563
|
-
redirect: "manual",
|
|
564
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
565
|
-
});
|
|
566
|
-
if (isRedirect(upstream.status)) {
|
|
567
|
-
return c.json(
|
|
568
|
-
{ error: "OAuth metadata redirects are not allowed" },
|
|
569
|
-
502
|
|
570
|
-
);
|
|
571
|
-
}
|
|
572
|
-
const raw = await readCapped(upstream, maxResponseBodyBytes);
|
|
573
|
-
if (!upstream.ok) {
|
|
574
|
-
return c.body(raw, upstream.status, {
|
|
575
|
-
"Content-Type": upstream.headers.get("content-type") ?? "application/json"
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
const metadata = parseObject(raw);
|
|
579
|
-
if (metadataKind.type === "protected-resource") {
|
|
580
|
-
await bindProtectedResource(
|
|
581
|
-
metadata,
|
|
582
|
-
serverUrl,
|
|
583
|
-
binding,
|
|
584
|
-
allowLoopback
|
|
585
|
-
);
|
|
586
|
-
} else {
|
|
587
|
-
await bindAuthorizationServer(
|
|
588
|
-
metadata,
|
|
589
|
-
metadataKind.issuer,
|
|
590
|
-
binding,
|
|
591
|
-
allowLoopback
|
|
592
|
-
);
|
|
593
|
-
}
|
|
594
|
-
binding.updatedAt = Date.now();
|
|
595
|
-
bindings.set(key, binding);
|
|
596
|
-
pruneBindings(bindings);
|
|
597
|
-
return c.body(raw, 200, {
|
|
598
|
-
"Content-Type": upstream.headers.get("content-type") ?? "application/json"
|
|
599
|
-
});
|
|
600
|
-
} catch (error) {
|
|
601
|
-
return proxyError(c, error, enableLogging);
|
|
602
|
-
}
|
|
603
|
-
});
|
|
604
|
-
app2.post(`${basePath}/proxy`, async (c) => {
|
|
605
|
-
if (!await isAuthenticated(c, authenticate)) {
|
|
606
|
-
return c.json({ error: "Unauthorized" }, 401);
|
|
607
|
-
}
|
|
608
|
-
let request;
|
|
609
|
-
try {
|
|
610
|
-
request = JSON.parse(
|
|
611
|
-
await readRequestCapped(c.req.raw, maxRequestBodyBytes)
|
|
612
|
-
);
|
|
613
|
-
} catch (error) {
|
|
614
|
-
return c.json(
|
|
615
|
-
{
|
|
616
|
-
error: error instanceof BodyTooLargeError ? "Request body too large" : "Invalid JSON request body"
|
|
617
|
-
},
|
|
618
|
-
error instanceof BodyTooLargeError ? 413 : 400
|
|
619
|
-
);
|
|
620
|
-
}
|
|
621
|
-
const serverUrlResult = await validateUrl(request.serverUrl, allowLoopback);
|
|
622
|
-
if ("error" in serverUrlResult) {
|
|
623
|
-
return c.json({ error: serverUrlResult.error }, 400);
|
|
624
|
-
}
|
|
625
|
-
const serverUrl = serverUrlResult.url;
|
|
626
|
-
if (validateServerUrl && !await validateServerUrl(serverUrl.toString(), c)) {
|
|
627
|
-
return c.json({ error: "MCP server URL not allowed" }, 403);
|
|
628
|
-
}
|
|
629
|
-
const targetResult = await validateUrl(request.url, allowLoopback);
|
|
630
|
-
if ("error" in targetResult) {
|
|
631
|
-
return c.json({ error: targetResult.error }, 400);
|
|
632
|
-
}
|
|
633
|
-
const target = targetResult.url;
|
|
634
|
-
if (request.method !== void 0 && request.method !== "POST") {
|
|
635
|
-
return c.json({ error: "Only OAuth endpoint POST is allowed" }, 405);
|
|
636
|
-
}
|
|
637
|
-
const bindingKey = canonicalUrl(serverUrl);
|
|
638
|
-
const binding = getBinding(bindings, bindingKey);
|
|
639
|
-
if (binding.endpoints.size === 0) {
|
|
640
|
-
try {
|
|
641
|
-
await hydrateBinding(
|
|
642
|
-
serverUrl,
|
|
643
|
-
binding,
|
|
644
|
-
allowLoopback,
|
|
645
|
-
timeoutMs,
|
|
646
|
-
maxResponseBodyBytes
|
|
647
|
-
);
|
|
648
|
-
bindings.set(bindingKey, binding);
|
|
649
|
-
pruneBindings(bindings);
|
|
650
|
-
} catch (error) {
|
|
651
|
-
return proxyError(c, error, enableLogging);
|
|
652
|
-
}
|
|
653
|
-
}
|
|
654
|
-
const endpointKind = binding.endpoints.get(canonicalUrl(target));
|
|
655
|
-
if (!endpointKind) {
|
|
656
|
-
return c.json(
|
|
657
|
-
{ error: "OAuth endpoint is not bound to this MCP server" },
|
|
658
|
-
403
|
|
659
|
-
);
|
|
660
|
-
}
|
|
661
|
-
try {
|
|
662
|
-
const headers = filterRequestHeaders(request.headers);
|
|
663
|
-
const body = serializeBody(request.body, headers);
|
|
664
|
-
if (new TextEncoder().encode(body ?? "").byteLength > maxRequestBodyBytes) {
|
|
665
|
-
return c.json({ error: "OAuth request body too large" }, 413);
|
|
666
|
-
}
|
|
667
|
-
log(enableLogging, `POST ${endpointKind} ${target}`);
|
|
668
|
-
const upstream = await safeFetch(target, {
|
|
669
|
-
method: "POST",
|
|
670
|
-
headers,
|
|
671
|
-
body,
|
|
672
|
-
redirect: "manual",
|
|
673
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
674
|
-
});
|
|
675
|
-
if (isRedirect(upstream.status)) {
|
|
676
|
-
return c.json(
|
|
677
|
-
{ error: "OAuth endpoint redirects are not allowed" },
|
|
678
|
-
502
|
|
679
|
-
);
|
|
680
|
-
}
|
|
681
|
-
const raw = await readCapped(upstream, maxResponseBodyBytes);
|
|
682
|
-
const responseHeaders = filterResponseHeaders(upstream.headers);
|
|
683
|
-
const contentType = upstream.headers.get("content-type") ?? "";
|
|
684
|
-
let responseBody = raw;
|
|
685
|
-
if (contentType.includes("json")) {
|
|
686
|
-
try {
|
|
687
|
-
responseBody = JSON.parse(raw);
|
|
688
|
-
} catch {
|
|
689
|
-
}
|
|
690
|
-
}
|
|
691
|
-
return c.json({
|
|
692
|
-
status: upstream.status,
|
|
693
|
-
statusText: upstream.statusText,
|
|
694
|
-
headers: responseHeaders,
|
|
695
|
-
body: responseBody
|
|
696
|
-
});
|
|
697
|
-
} catch (error) {
|
|
698
|
-
return proxyError(c, error, enableLogging);
|
|
699
|
-
}
|
|
700
|
-
});
|
|
701
|
-
log(enableLogging, `Mounted at ${basePath}/metadata and ${basePath}/proxy`);
|
|
702
|
-
}
|
|
703
|
-
async function validateUrl(value, allowLoopback) {
|
|
704
|
-
if (typeof value !== "string" || !value) {
|
|
705
|
-
return { error: "Missing or invalid URL" };
|
|
706
|
-
}
|
|
707
|
-
let url;
|
|
708
|
-
try {
|
|
709
|
-
url = new URL(value);
|
|
710
|
-
} catch {
|
|
711
|
-
return { error: "Invalid URL" };
|
|
712
|
-
}
|
|
713
|
-
if (url.username || url.password || url.hash) {
|
|
714
|
-
return { error: "URL credentials and fragments are not allowed" };
|
|
715
|
-
}
|
|
716
|
-
const loopback = isLoopbackHostname(url.hostname);
|
|
717
|
-
if (url.protocol !== "https:") {
|
|
718
|
-
if (!(allowLoopback && loopback && url.protocol === "http:")) {
|
|
719
|
-
return { error: "HTTPS is required" };
|
|
720
|
-
}
|
|
721
|
-
}
|
|
722
|
-
if (loopback) {
|
|
723
|
-
return allowLoopback ? { url } : { error: "Loopback URL not allowed" };
|
|
724
|
-
}
|
|
725
|
-
if (isLocalHostname(url.hostname)) {
|
|
726
|
-
return { error: "Local network URL not allowed" };
|
|
727
|
-
}
|
|
728
|
-
try {
|
|
729
|
-
const addresses = isIP(url.hostname) ? [url.hostname] : (await lookup(url.hostname, { all: true, verbatim: true })).map(
|
|
730
|
-
({ address }) => address
|
|
731
|
-
);
|
|
732
|
-
if (addresses.length === 0 || addresses.some((address) => !isPublicAddress(address))) {
|
|
733
|
-
return { error: "Private or non-routable URL not allowed" };
|
|
734
|
-
}
|
|
735
|
-
} catch {
|
|
736
|
-
return { error: "URL hostname could not be resolved" };
|
|
737
|
-
}
|
|
738
|
-
return { url };
|
|
739
|
-
}
|
|
740
|
-
async function isSafeProxyTarget(value, allowLoopback = false) {
|
|
741
|
-
return !("error" in await validateUrl(value, allowLoopback));
|
|
742
|
-
}
|
|
743
|
-
function classifyMetadataTarget(serverUrl, target, binding) {
|
|
744
|
-
const targetUrl = canonicalUrl(target);
|
|
745
|
-
if (protectedResourceMetadataUrls(serverUrl).some(
|
|
746
|
-
(candidate) => canonicalUrl(candidate) === targetUrl
|
|
747
|
-
)) {
|
|
748
|
-
return { type: "protected-resource" };
|
|
749
|
-
}
|
|
750
|
-
for (const issuer of binding.authorizationServers) {
|
|
751
|
-
if (authorizationServerMetadataUrls(new URL(issuer)).some(
|
|
752
|
-
(candidate) => canonicalUrl(candidate) === targetUrl
|
|
753
|
-
)) {
|
|
754
|
-
return { type: "authorization-server", issuer };
|
|
755
|
-
}
|
|
756
|
-
}
|
|
757
|
-
return void 0;
|
|
758
|
-
}
|
|
759
|
-
function protectedResourceMetadataUrls(serverUrl) {
|
|
760
|
-
const path3 = serverUrl.pathname === "/" ? "" : serverUrl.pathname;
|
|
761
|
-
return [
|
|
762
|
-
new URL(`/.well-known/oauth-protected-resource${path3}`, serverUrl.origin),
|
|
763
|
-
new URL("/.well-known/oauth-protected-resource", serverUrl.origin)
|
|
764
|
-
];
|
|
765
|
-
}
|
|
766
|
-
function authorizationServerMetadataUrls(issuer) {
|
|
767
|
-
const path3 = issuer.pathname === "/" ? "" : issuer.pathname;
|
|
768
|
-
return [
|
|
769
|
-
new URL(`/.well-known/oauth-authorization-server${path3}`, issuer.origin),
|
|
770
|
-
new URL(`/.well-known/openid-configuration${path3}`, issuer.origin),
|
|
771
|
-
new URL(`${path3 || ""}/.well-known/openid-configuration`, issuer.origin)
|
|
772
|
-
];
|
|
773
|
-
}
|
|
774
|
-
async function bindProtectedResource(metadata, serverUrl, binding, allowLoopback) {
|
|
775
|
-
if (typeof metadata.resource !== "string" || canonicalUrl(new URL(metadata.resource)) !== canonicalUrl(serverUrl)) {
|
|
776
|
-
throw new InvalidUpstreamError(
|
|
777
|
-
"Protected-resource metadata does not match serverUrl"
|
|
778
|
-
);
|
|
779
|
-
}
|
|
780
|
-
if (!Array.isArray(metadata.authorization_servers) || metadata.authorization_servers.length === 0) {
|
|
781
|
-
throw new InvalidUpstreamError(
|
|
782
|
-
"Protected-resource metadata has no authorization servers"
|
|
783
|
-
);
|
|
784
|
-
}
|
|
785
|
-
const issuers = /* @__PURE__ */ new Set();
|
|
786
|
-
for (const value of metadata.authorization_servers) {
|
|
787
|
-
const result = await validateUrl(value, allowLoopback);
|
|
788
|
-
if ("error" in result) {
|
|
789
|
-
throw new InvalidUpstreamError(
|
|
790
|
-
`Unsafe authorization server: ${result.error}`
|
|
791
|
-
);
|
|
792
|
-
}
|
|
793
|
-
issuers.add(canonicalUrl(result.url));
|
|
794
|
-
}
|
|
795
|
-
binding.authorizationServers = issuers;
|
|
796
|
-
binding.endpoints.clear();
|
|
797
|
-
}
|
|
798
|
-
async function bindAuthorizationServer(metadata, expectedIssuer, binding, allowLoopback) {
|
|
799
|
-
if (typeof metadata.issuer !== "string" || canonicalUrl(new URL(metadata.issuer)) !== expectedIssuer) {
|
|
800
|
-
throw new InvalidUpstreamError(
|
|
801
|
-
"Authorization-server metadata issuer mismatch"
|
|
802
|
-
);
|
|
803
|
-
}
|
|
804
|
-
binding.endpoints.clear();
|
|
805
|
-
for (const [field, kind] of ENDPOINT_FIELDS) {
|
|
806
|
-
const value = metadata[field];
|
|
807
|
-
if (value === void 0) continue;
|
|
808
|
-
const result = await validateUrl(value, allowLoopback);
|
|
809
|
-
if ("error" in result) {
|
|
810
|
-
throw new InvalidUpstreamError(`Unsafe ${field}: ${result.error}`);
|
|
811
|
-
}
|
|
812
|
-
binding.endpoints.set(canonicalUrl(result.url), kind);
|
|
813
|
-
}
|
|
814
|
-
}
|
|
815
|
-
async function hydrateBinding(serverUrl, binding, allowLoopback, timeoutMs, maxResponseBodyBytes) {
|
|
816
|
-
for (const metadataUrl of protectedResourceMetadataUrls(serverUrl)) {
|
|
817
|
-
const response = await safeFetch(metadataUrl, {
|
|
818
|
-
method: "GET",
|
|
819
|
-
headers: { Accept: "application/json" },
|
|
820
|
-
redirect: "manual",
|
|
821
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
822
|
-
});
|
|
823
|
-
if (isRedirect(response.status)) {
|
|
824
|
-
throw new InvalidUpstreamError(
|
|
825
|
-
"OAuth metadata redirects are not allowed"
|
|
826
|
-
);
|
|
827
|
-
}
|
|
828
|
-
if (!response.ok) continue;
|
|
829
|
-
await bindProtectedResource(
|
|
830
|
-
parseObject(await readCapped(response, maxResponseBodyBytes)),
|
|
831
|
-
serverUrl,
|
|
832
|
-
binding,
|
|
833
|
-
allowLoopback
|
|
834
|
-
);
|
|
835
|
-
break;
|
|
836
|
-
}
|
|
837
|
-
if (binding.authorizationServers.size === 0) {
|
|
838
|
-
throw new InvalidUpstreamError(
|
|
839
|
-
"Protected-resource metadata could not be discovered"
|
|
840
|
-
);
|
|
841
|
-
}
|
|
842
|
-
for (const issuer of binding.authorizationServers) {
|
|
843
|
-
let bound = false;
|
|
844
|
-
for (const metadataUrl of authorizationServerMetadataUrls(
|
|
845
|
-
new URL(issuer)
|
|
846
|
-
)) {
|
|
847
|
-
const response = await safeFetch(metadataUrl, {
|
|
848
|
-
method: "GET",
|
|
849
|
-
headers: { Accept: "application/json" },
|
|
850
|
-
redirect: "manual",
|
|
851
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
852
|
-
});
|
|
853
|
-
if (isRedirect(response.status)) {
|
|
854
|
-
throw new InvalidUpstreamError(
|
|
855
|
-
"OAuth metadata redirects are not allowed"
|
|
856
|
-
);
|
|
857
|
-
}
|
|
858
|
-
if (!response.ok) continue;
|
|
859
|
-
await bindAuthorizationServer(
|
|
860
|
-
parseObject(await readCapped(response, maxResponseBodyBytes)),
|
|
861
|
-
issuer,
|
|
862
|
-
binding,
|
|
863
|
-
allowLoopback
|
|
864
|
-
);
|
|
865
|
-
bound = true;
|
|
866
|
-
break;
|
|
867
|
-
}
|
|
868
|
-
if (bound) break;
|
|
869
|
-
}
|
|
870
|
-
if (binding.endpoints.size === 0) {
|
|
871
|
-
throw new InvalidUpstreamError(
|
|
872
|
-
"Authorization-server metadata could not be discovered"
|
|
873
|
-
);
|
|
874
|
-
}
|
|
875
|
-
binding.updatedAt = Date.now();
|
|
876
|
-
}
|
|
877
|
-
async function safeFetch(url, init) {
|
|
878
|
-
return fetch(url, init);
|
|
879
|
-
}
|
|
880
|
-
function filterRequestHeaders(value) {
|
|
881
|
-
const result = new Headers();
|
|
882
|
-
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
883
|
-
return result;
|
|
884
|
-
for (const [name, rawValue] of Object.entries(value)) {
|
|
885
|
-
const lower = name.toLowerCase();
|
|
886
|
-
if (SAFE_REQUEST_HEADERS.has(lower) && typeof rawValue === "string") {
|
|
887
|
-
result.set(lower, rawValue);
|
|
888
|
-
}
|
|
889
|
-
}
|
|
890
|
-
return result;
|
|
891
|
-
}
|
|
892
|
-
function filterResponseHeaders(headers) {
|
|
893
|
-
const result = {};
|
|
894
|
-
headers.forEach((value, name) => {
|
|
895
|
-
if (SAFE_RESPONSE_HEADERS.has(name.toLowerCase())) result[name] = value;
|
|
896
|
-
});
|
|
897
|
-
return result;
|
|
898
|
-
}
|
|
899
|
-
function serializeBody(body, headers) {
|
|
900
|
-
if (body === void 0 || body === null) return void 0;
|
|
901
|
-
if (typeof body === "string") return body;
|
|
902
|
-
const contentType = headers.get("content-type") ?? "";
|
|
903
|
-
if (contentType.includes("application/x-www-form-urlencoded") && typeof body === "object" && !Array.isArray(body)) {
|
|
904
|
-
const params = new URLSearchParams();
|
|
905
|
-
for (const [key, value] of Object.entries(
|
|
906
|
-
body
|
|
907
|
-
)) {
|
|
908
|
-
params.append(key, String(value));
|
|
909
|
-
}
|
|
910
|
-
return params.toString();
|
|
911
|
-
}
|
|
912
|
-
if (!headers.has("content-type")) {
|
|
913
|
-
headers.set("content-type", "application/json");
|
|
914
|
-
}
|
|
915
|
-
return JSON.stringify(body);
|
|
916
|
-
}
|
|
917
|
-
async function readRequestCapped(request, maxBytes) {
|
|
918
|
-
const declared = Number(request.headers.get("content-length"));
|
|
919
|
-
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
920
|
-
throw new BodyTooLargeError();
|
|
921
|
-
}
|
|
922
|
-
return readStreamCapped(request.body, maxBytes);
|
|
923
|
-
}
|
|
924
|
-
async function readCapped(response, maxBytes) {
|
|
925
|
-
const declared = Number(response.headers.get("content-length"));
|
|
926
|
-
if (Number.isFinite(declared) && declared > maxBytes) {
|
|
927
|
-
await response.body?.cancel();
|
|
928
|
-
throw new BodyTooLargeError();
|
|
929
|
-
}
|
|
930
|
-
return readStreamCapped(response.body, maxBytes);
|
|
931
|
-
}
|
|
932
|
-
async function readStreamCapped(stream, maxBytes) {
|
|
933
|
-
if (!stream) return "";
|
|
934
|
-
const reader = stream.getReader();
|
|
935
|
-
const chunks = [];
|
|
936
|
-
let size = 0;
|
|
937
|
-
while (true) {
|
|
938
|
-
const { done, value } = await reader.read();
|
|
939
|
-
if (done) break;
|
|
940
|
-
size += value.byteLength;
|
|
941
|
-
if (size > maxBytes) {
|
|
942
|
-
await reader.cancel();
|
|
943
|
-
throw new BodyTooLargeError();
|
|
944
|
-
}
|
|
945
|
-
chunks.push(value);
|
|
946
|
-
}
|
|
947
|
-
const bytes = new Uint8Array(size);
|
|
948
|
-
let offset = 0;
|
|
949
|
-
for (const chunk of chunks) {
|
|
950
|
-
bytes.set(chunk, offset);
|
|
951
|
-
offset += chunk.byteLength;
|
|
952
|
-
}
|
|
953
|
-
return new TextDecoder().decode(bytes);
|
|
954
|
-
}
|
|
955
|
-
function parseObject(value) {
|
|
956
|
-
let parsed;
|
|
957
|
-
try {
|
|
958
|
-
parsed = JSON.parse(value);
|
|
959
|
-
} catch {
|
|
960
|
-
throw new InvalidUpstreamError("OAuth metadata is not valid JSON");
|
|
961
|
-
}
|
|
962
|
-
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
963
|
-
throw new InvalidUpstreamError("OAuth metadata is not an object");
|
|
964
|
-
}
|
|
965
|
-
return parsed;
|
|
966
|
-
}
|
|
967
|
-
function getBinding(bindings, key) {
|
|
968
|
-
const existing = bindings.get(key);
|
|
969
|
-
if (existing && Date.now() - existing.updatedAt <= BINDING_TTL_MS) {
|
|
970
|
-
return existing;
|
|
971
|
-
}
|
|
972
|
-
bindings.delete(key);
|
|
973
|
-
return {
|
|
974
|
-
authorizationServers: /* @__PURE__ */ new Set(),
|
|
975
|
-
endpoints: /* @__PURE__ */ new Map(),
|
|
976
|
-
updatedAt: Date.now()
|
|
977
|
-
};
|
|
978
|
-
}
|
|
979
|
-
function pruneBindings(bindings) {
|
|
980
|
-
const now = Date.now();
|
|
981
|
-
for (const [key, binding] of bindings) {
|
|
982
|
-
if (now - binding.updatedAt > BINDING_TTL_MS) bindings.delete(key);
|
|
983
|
-
}
|
|
984
|
-
while (bindings.size > MAX_BINDINGS) {
|
|
985
|
-
const oldest = bindings.keys().next().value;
|
|
986
|
-
if (!oldest) break;
|
|
987
|
-
bindings.delete(oldest);
|
|
988
|
-
}
|
|
989
|
-
}
|
|
990
|
-
function canonicalUrl(url) {
|
|
991
|
-
const copy = new URL(url);
|
|
992
|
-
copy.hash = "";
|
|
993
|
-
if (copy.protocol === "https:" && copy.port === "443" || copy.protocol === "http:" && copy.port === "80") {
|
|
994
|
-
copy.port = "";
|
|
995
|
-
}
|
|
996
|
-
return copy.toString().replace(/\/$/, "");
|
|
997
|
-
}
|
|
998
|
-
function normalizeOrigin(origin) {
|
|
999
|
-
const url = new URL(origin);
|
|
1000
|
-
if (url.pathname !== "/" || url.search || url.hash) {
|
|
1001
|
-
throw new Error(`OAuth proxy allowed origin must be an origin: ${origin}`);
|
|
1002
|
-
}
|
|
1003
|
-
return url.origin;
|
|
1004
|
-
}
|
|
1005
|
-
function isAllowedOrigin(origin, requestUrl, allowed) {
|
|
1006
|
-
try {
|
|
1007
|
-
const normalized = normalizeOrigin(origin);
|
|
1008
|
-
return normalized === new URL(requestUrl).origin || allowed.has(normalized);
|
|
1009
|
-
} catch {
|
|
1010
|
-
return false;
|
|
1011
|
-
}
|
|
1012
|
-
}
|
|
1013
|
-
function corsResponse(origin) {
|
|
1014
|
-
const headers = new Headers();
|
|
1015
|
-
if (origin) setCorsHeaders(headers, origin);
|
|
1016
|
-
headers.set("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
|
|
1017
|
-
headers.set(
|
|
1018
|
-
"Access-Control-Allow-Headers",
|
|
1019
|
-
"Accept, Authorization, Content-Type"
|
|
1020
|
-
);
|
|
1021
|
-
headers.set("Access-Control-Max-Age", "600");
|
|
1022
|
-
return new Response(null, { status: 204, headers });
|
|
1023
|
-
}
|
|
1024
|
-
function setCorsHeaders(headers, origin) {
|
|
1025
|
-
headers.set("Access-Control-Allow-Origin", origin);
|
|
1026
|
-
headers.append("Vary", "Origin");
|
|
1027
|
-
}
|
|
1028
|
-
async function isAuthenticated(c, authenticate) {
|
|
1029
|
-
return authenticate ? authenticate(c) : true;
|
|
1030
|
-
}
|
|
1031
|
-
function isRedirect(status) {
|
|
1032
|
-
return status >= 300 && status < 400;
|
|
1033
|
-
}
|
|
1034
|
-
function isLoopbackHostname(hostname) {
|
|
1035
|
-
const normalized = hostname.toLowerCase().replace(/^\[|\]$/g, "");
|
|
1036
|
-
return normalized === "localhost" || normalized.endsWith(".localhost") || normalized === "::1" || normalized.startsWith("127.");
|
|
1037
|
-
}
|
|
1038
|
-
function isLocalHostname(hostname) {
|
|
1039
|
-
const normalized = hostname.toLowerCase();
|
|
1040
|
-
return normalized.endsWith(".local") || normalized.endsWith(".internal") || normalized.endsWith(".home.arpa");
|
|
1041
|
-
}
|
|
1042
|
-
function isPublicAddress(address) {
|
|
1043
|
-
if (address.includes(":")) {
|
|
1044
|
-
const lower = address.toLowerCase();
|
|
1045
|
-
if (lower.startsWith("::ffff:")) {
|
|
1046
|
-
return isPublicAddress(lower.slice(7));
|
|
1047
|
-
}
|
|
1048
|
-
return !(lower === "::" || lower === "::1" || lower.startsWith("fc") || lower.startsWith("fd") || /^fe[89ab]/.test(lower) || lower.startsWith("ff") || lower.startsWith("2001:db8:"));
|
|
1049
|
-
}
|
|
1050
|
-
const parts = address.split(".").map(Number);
|
|
1051
|
-
if (parts.length !== 4 || parts.some((part) => !Number.isInteger(part))) {
|
|
1052
|
-
return false;
|
|
1053
|
-
}
|
|
1054
|
-
const [a, b, c] = parts;
|
|
1055
|
-
return !(a === 0 || a === 10 || a === 127 || a === 100 && b >= 64 && b <= 127 || a === 169 && b === 254 || a === 172 && b >= 16 && b <= 31 || a === 192 && b === 0 && c === 0 || a === 192 && b === 0 && c === 2 || a === 192 && b === 168 || a === 198 && (b === 18 || b === 19) || a === 198 && b === 51 && c === 100 || a === 203 && b === 0 && c === 113 || a >= 224);
|
|
1056
|
-
}
|
|
1057
|
-
function log(enabled, message) {
|
|
1058
|
-
if (enabled) console.log(`[OAuth BFF] ${message}`);
|
|
1059
|
-
}
|
|
1060
|
-
function proxyError(c, error, logging) {
|
|
1061
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1062
|
-
if (logging) console.error("[OAuth BFF]", message);
|
|
1063
|
-
if (error instanceof BodyTooLargeError) {
|
|
1064
|
-
return c.json({ error: "Upstream response too large" }, 502);
|
|
1065
|
-
}
|
|
1066
|
-
if (error instanceof InvalidUpstreamError) {
|
|
1067
|
-
return c.json({ error: error.message }, 502);
|
|
1068
|
-
}
|
|
1069
|
-
if (error instanceof DOMException && error.name === "TimeoutError") {
|
|
1070
|
-
return c.json({ error: "OAuth upstream timed out" }, 504);
|
|
1071
|
-
}
|
|
1072
|
-
return c.json({ error: "OAuth upstream request failed" }, 502);
|
|
1073
|
-
}
|
|
1074
|
-
var BodyTooLargeError = class extends Error {
|
|
1075
|
-
};
|
|
1076
|
-
var InvalidUpstreamError = class extends Error {
|
|
1077
|
-
};
|
|
1078
|
-
|
|
1079
|
-
// src/server/proxy/mcp-proxy.ts
|
|
1080
|
-
function isOpenEndedSseResponse(contentType, contentLength) {
|
|
1081
|
-
return contentType.includes("text/event-stream") && !contentLength;
|
|
1082
|
-
}
|
|
1083
|
-
function mountMcpProxy(app2, options = {}) {
|
|
1084
|
-
const basePath = options.path || "/mcp/proxy";
|
|
1085
|
-
const enableLogging = options.enableLogging !== false;
|
|
1086
|
-
app2.use(
|
|
1087
|
-
`${basePath}/*`,
|
|
1088
|
-
cors({
|
|
1089
|
-
origin: "*",
|
|
1090
|
-
allowHeaders: [
|
|
1091
|
-
"Authorization",
|
|
1092
|
-
"Content-Type",
|
|
1093
|
-
"Accept",
|
|
1094
|
-
"X-Target-URL",
|
|
1095
|
-
"X-MCP-Target",
|
|
1096
|
-
"Mcp-Session-Id",
|
|
1097
|
-
"mcp-session-id",
|
|
1098
|
-
"mcp-protocol-version",
|
|
1099
|
-
"X-Server-Id",
|
|
1100
|
-
"X-Requested-With"
|
|
1101
|
-
],
|
|
1102
|
-
exposeHeaders: ["*"]
|
|
1103
|
-
})
|
|
1104
|
-
);
|
|
1105
|
-
if (enableLogging) {
|
|
1106
|
-
app2.use(`${basePath}/*`, logger());
|
|
1107
|
-
}
|
|
1108
|
-
app2.all(`${basePath}/*`, async (c) => {
|
|
1109
|
-
try {
|
|
1110
|
-
if (options.authenticate) {
|
|
1111
|
-
const isAuthenticated2 = await options.authenticate(c);
|
|
1112
|
-
if (!isAuthenticated2) {
|
|
1113
|
-
return c.json({ error: "Unauthorized" }, 401);
|
|
1114
|
-
}
|
|
1115
|
-
}
|
|
1116
|
-
const targetUrl = c.req.header("X-Target-URL");
|
|
1117
|
-
if (!targetUrl) {
|
|
1118
|
-
return c.json(
|
|
1119
|
-
{
|
|
1120
|
-
error: "X-Target-URL header is required",
|
|
1121
|
-
usage: "Set X-Target-URL header to the MCP server URL you want to proxy to"
|
|
1122
|
-
},
|
|
1123
|
-
400
|
|
1124
|
-
);
|
|
1125
|
-
}
|
|
1126
|
-
if (!await isSafeProxyTarget(targetUrl, options.allowLoopback ?? false)) {
|
|
1127
|
-
return c.json(
|
|
1128
|
-
{
|
|
1129
|
-
error: "Invalid target URL",
|
|
1130
|
-
details: "Target is not allowed by the proxy network policy"
|
|
1131
|
-
},
|
|
1132
|
-
403
|
|
1133
|
-
);
|
|
1134
|
-
}
|
|
1135
|
-
if (options.validateRequest) {
|
|
1136
|
-
const isValid = await options.validateRequest(targetUrl, c);
|
|
1137
|
-
if (!isValid) {
|
|
1138
|
-
return c.json(
|
|
1139
|
-
{
|
|
1140
|
-
error: "Invalid target URL",
|
|
1141
|
-
details: "The requested target URL is not allowed"
|
|
1142
|
-
},
|
|
1143
|
-
403
|
|
1144
|
-
);
|
|
1145
|
-
}
|
|
1146
|
-
}
|
|
1147
|
-
try {
|
|
1148
|
-
new URL(targetUrl);
|
|
1149
|
-
} catch {
|
|
1150
|
-
return c.json(
|
|
1151
|
-
{
|
|
1152
|
-
error: "Invalid target URL format",
|
|
1153
|
-
details: "The X-Target-URL must be a valid HTTP/HTTPS URL"
|
|
1154
|
-
},
|
|
1155
|
-
400
|
|
1156
|
-
);
|
|
1157
|
-
}
|
|
1158
|
-
const method = c.req.method;
|
|
1159
|
-
const headers = {};
|
|
1160
|
-
const requestHeaders = c.req.header();
|
|
1161
|
-
for (const [key, value] of Object.entries(requestHeaders)) {
|
|
1162
|
-
const lowerKey = key.toLowerCase();
|
|
1163
|
-
if (!lowerKey.startsWith("x-proxy-") && !lowerKey.startsWith("x-target-") && !lowerKey.startsWith("x-mcp-") && !lowerKey.startsWith("x-forwarded-") && !lowerKey.startsWith("cf-") && lowerKey !== "x-original-host" && lowerKey !== "host" && lowerKey !== "accept-encoding" && lowerKey !== "cdn-loop") {
|
|
1164
|
-
headers[key] = value;
|
|
1165
|
-
}
|
|
1166
|
-
}
|
|
1167
|
-
headers["Accept-Encoding"] = "identity";
|
|
1168
|
-
try {
|
|
1169
|
-
const targetUrlObj = new URL(targetUrl);
|
|
1170
|
-
headers.Host = targetUrlObj.host;
|
|
1171
|
-
} catch {
|
|
1172
|
-
return c.json({ error: "Invalid target URL" }, 400);
|
|
1173
|
-
}
|
|
1174
|
-
const body = method !== "GET" && method !== "HEAD" ? new Uint8Array(await c.req.arrayBuffer()).slice() : void 0;
|
|
1175
|
-
const response = await fetch(targetUrl, {
|
|
1176
|
-
method,
|
|
1177
|
-
headers,
|
|
1178
|
-
body,
|
|
1179
|
-
redirect: "manual"
|
|
1180
|
-
});
|
|
1181
|
-
if (response.status >= 300 && response.status < 400) {
|
|
1182
|
-
const location = response.headers.get("location");
|
|
1183
|
-
if (location) {
|
|
1184
|
-
const redirectUrl = new URL(location, targetUrl).toString();
|
|
1185
|
-
if (!await isSafeProxyTarget(
|
|
1186
|
-
redirectUrl,
|
|
1187
|
-
options.allowLoopback ?? false
|
|
1188
|
-
) || options.validateRequest && !await options.validateRequest(redirectUrl, c)) {
|
|
1189
|
-
return c.json({ error: "Redirect target is not allowed" }, 403);
|
|
1190
|
-
}
|
|
1191
|
-
const redirectResponse = await fetch(redirectUrl, {
|
|
1192
|
-
method,
|
|
1193
|
-
headers,
|
|
1194
|
-
body,
|
|
1195
|
-
redirect: "manual"
|
|
1196
|
-
});
|
|
1197
|
-
const redirectHeaders = {};
|
|
1198
|
-
redirectResponse.headers.forEach((value, key) => {
|
|
1199
|
-
const lowerKey = key.toLowerCase();
|
|
1200
|
-
if (lowerKey !== "content-encoding" && lowerKey !== "transfer-encoding" && lowerKey !== "content-length") {
|
|
1201
|
-
redirectHeaders[key] = value;
|
|
1202
|
-
}
|
|
1203
|
-
});
|
|
1204
|
-
return new Response(redirectResponse.body, {
|
|
1205
|
-
status: redirectResponse.status,
|
|
1206
|
-
statusText: redirectResponse.statusText,
|
|
1207
|
-
headers: redirectHeaders
|
|
1208
|
-
});
|
|
1209
|
-
}
|
|
1210
|
-
}
|
|
1211
|
-
const responseHeaders = {};
|
|
1212
|
-
response.headers.forEach((value, key) => {
|
|
1213
|
-
const lowerKey = key.toLowerCase();
|
|
1214
|
-
if (lowerKey !== "content-encoding" && lowerKey !== "transfer-encoding" && lowerKey !== "content-length") {
|
|
1215
|
-
responseHeaders[key] = value;
|
|
1216
|
-
}
|
|
1217
|
-
});
|
|
1218
|
-
const contentType = response.headers.get("content-type") || "";
|
|
1219
|
-
const upstreamContentLength = response.headers.get("content-length");
|
|
1220
|
-
const isTrueStream = isOpenEndedSseResponse(
|
|
1221
|
-
contentType,
|
|
1222
|
-
upstreamContentLength
|
|
1223
|
-
);
|
|
1224
|
-
if (isTrueStream) {
|
|
1225
|
-
return new Response(response.body, {
|
|
1226
|
-
status: response.status,
|
|
1227
|
-
statusText: response.statusText,
|
|
1228
|
-
headers: responseHeaders
|
|
1229
|
-
});
|
|
1230
|
-
}
|
|
1231
|
-
const bodyBuffer = await response.arrayBuffer();
|
|
1232
|
-
responseHeaders["Content-Length"] = String(bodyBuffer.byteLength);
|
|
1233
|
-
return new Response(bodyBuffer, {
|
|
1234
|
-
status: response.status,
|
|
1235
|
-
statusText: response.statusText,
|
|
1236
|
-
headers: responseHeaders
|
|
1237
|
-
});
|
|
1238
|
-
} catch (error) {
|
|
1239
|
-
const message = error instanceof Error ? error.message : "Unknown error";
|
|
1240
|
-
const targetUrl = c.req.header("X-Target-URL");
|
|
1241
|
-
const isConnectionRefused = error instanceof Error && (error.message.includes("ECONNREFUSED") || error.message.includes("fetch failed"));
|
|
1242
|
-
if (isConnectionRefused) {
|
|
1243
|
-
console.warn(
|
|
1244
|
-
`[MCP Proxy] Connection refused to ${targetUrl || "unknown target"} - server may not be running`
|
|
1245
|
-
);
|
|
1246
|
-
} else {
|
|
1247
|
-
console.error(
|
|
1248
|
-
"[MCP Proxy] Request failed:",
|
|
1249
|
-
message,
|
|
1250
|
-
"\nTarget URL:",
|
|
1251
|
-
targetUrl || "unknown",
|
|
1252
|
-
"\nError:",
|
|
1253
|
-
error
|
|
1254
|
-
);
|
|
1255
|
-
}
|
|
1256
|
-
return c.json(
|
|
1257
|
-
{
|
|
1258
|
-
error: "Proxy request failed",
|
|
1259
|
-
details: message,
|
|
1260
|
-
targetUrl: targetUrl || "unknown"
|
|
1261
|
-
},
|
|
1262
|
-
500
|
|
1263
|
-
);
|
|
1264
|
-
}
|
|
1265
|
-
});
|
|
1266
|
-
}
|
|
1267
|
-
|
|
1268
|
-
// src/server/proxy-routes.ts
|
|
1269
|
-
function registerInspectorProxyRoutes(app2, config, basePath = "") {
|
|
1270
|
-
const p = (suffix) => `${basePath}${suffix}`;
|
|
1271
|
-
const allowLoopback = config?.oauthProxyAllowLoopback ?? false;
|
|
1272
|
-
const mountOAuth = config?.oauth !== false;
|
|
1273
|
-
app2.get(p("/inspector/health"), (c) => {
|
|
1274
|
-
return c.json({
|
|
1275
|
-
status: "ok",
|
|
1276
|
-
protocol: "mcp-use-inspector-preview",
|
|
1277
|
-
version: 1,
|
|
1278
|
-
capabilities: ["view-preview"]
|
|
1279
|
-
});
|
|
1280
|
-
});
|
|
1281
|
-
mountMcpProxy(app2, {
|
|
1282
|
-
path: p("/inspector/api/proxy"),
|
|
1283
|
-
allowLoopback
|
|
1284
|
-
});
|
|
1285
|
-
if (mountOAuth) {
|
|
1286
|
-
mountOAuthProxy(app2, {
|
|
1287
|
-
basePath: p("/inspector/api/oauth"),
|
|
1288
|
-
enableLogging: true,
|
|
1289
|
-
allowedOrigins: config?.oauthProxyAllowedOrigins ?? [],
|
|
1290
|
-
allowLoopback
|
|
1291
|
-
});
|
|
1292
|
-
}
|
|
1293
|
-
if (config?.autoConnectUrl !== void 0) {
|
|
1294
|
-
const autoConnectUrl = config.autoConnectUrl;
|
|
1295
|
-
app2.get(p("/inspector/config.json"), (c) => {
|
|
1296
|
-
return c.json({ autoConnectUrl: autoConnectUrl ?? null });
|
|
1297
|
-
});
|
|
1298
|
-
}
|
|
1299
|
-
}
|
|
1300
|
-
|
|
1301
|
-
// src/server/utils.ts
|
|
1302
|
-
function isValidUrl(urlString) {
|
|
1303
|
-
try {
|
|
1304
|
-
const url = new URL(urlString);
|
|
1305
|
-
return url.protocol === "http:" || url.protocol === "https:";
|
|
1306
|
-
} catch {
|
|
1307
|
-
return false;
|
|
1308
|
-
}
|
|
1309
|
-
}
|
|
1310
|
-
async function findAvailablePort(startPort2 = 8080, maxAttempts = 100) {
|
|
1311
|
-
const net = await import("net");
|
|
1312
|
-
for (let port = startPort2; port < startPort2 + maxAttempts; port++) {
|
|
1313
|
-
try {
|
|
1314
|
-
await new Promise((resolve, reject) => {
|
|
1315
|
-
const server = net.createServer();
|
|
1316
|
-
server.listen(port, () => {
|
|
1317
|
-
server.close(() => resolve());
|
|
1318
|
-
});
|
|
1319
|
-
server.on("error", (err) => reject(err));
|
|
1320
|
-
});
|
|
1321
|
-
return port;
|
|
1322
|
-
} catch {
|
|
1323
|
-
continue;
|
|
1324
|
-
}
|
|
1325
|
-
}
|
|
1326
|
-
throw new Error(
|
|
1327
|
-
`No available port found after trying ${maxAttempts} ports starting from ${startPort2}`
|
|
1328
|
-
);
|
|
1329
|
-
}
|
|
1330
|
-
|
|
1331
|
-
// src/server/cli.ts
|
|
1332
|
-
var args = process.argv.slice(2);
|
|
1333
|
-
var mcpUrl;
|
|
1334
|
-
var startPort = 8080;
|
|
1335
|
-
var noOpen = false;
|
|
1336
|
-
for (let i = 0; i < args.length; i++) {
|
|
1337
|
-
if (args[i] === "--url") {
|
|
1338
|
-
if (i + 1 >= args.length || args[i + 1].startsWith("-")) {
|
|
1339
|
-
console.error("Error: --url requires a value");
|
|
1340
|
-
process.exit(1);
|
|
1341
|
-
}
|
|
1342
|
-
const url = args[i + 1];
|
|
1343
|
-
if (!isValidUrl(url)) {
|
|
1344
|
-
console.error(`Error: Invalid URL format: ${url}`);
|
|
1345
|
-
console.error("URL must start with http://, https://, ws://, or wss://");
|
|
1346
|
-
process.exit(1);
|
|
1347
|
-
}
|
|
1348
|
-
mcpUrl = url;
|
|
1349
|
-
i++;
|
|
1350
|
-
} else if (args[i] === "--port") {
|
|
1351
|
-
if (i + 1 >= args.length || args[i + 1].startsWith("-")) {
|
|
1352
|
-
console.error("Error: --port requires a value");
|
|
1353
|
-
process.exit(1);
|
|
1354
|
-
}
|
|
1355
|
-
const parsedPort = Number.parseInt(args[i + 1], 10);
|
|
1356
|
-
if (Number.isNaN(parsedPort) || parsedPort < 1 || parsedPort > 65535) {
|
|
1357
|
-
console.error(
|
|
1358
|
-
`Error: Port must be a number between 1 and 65535, got: ${args[i + 1]}`
|
|
1359
|
-
);
|
|
1360
|
-
process.exit(1);
|
|
1361
|
-
}
|
|
1362
|
-
startPort = parsedPort;
|
|
1363
|
-
i++;
|
|
1364
|
-
} else if (args[i] === "--no-open") {
|
|
1365
|
-
noOpen = true;
|
|
1366
|
-
} else if (args[i] === "--version" || args[i] === "-v") {
|
|
1367
|
-
console.log(getInspectorVersion());
|
|
1368
|
-
process.exit(0);
|
|
1369
|
-
} else if (args[i] === "--help" || args[i] === "-h") {
|
|
1370
|
-
console.log(`
|
|
372
|
+
</html>`}function $r(e,t,r=""){let n=`${r}/inspector/assets`,o=encodeURIComponent(Br),s={jsUrl:`${n}/inspector.js?v=${o}`,cssUrl:`${n}/inspector.css?v=${o}`},i=u=>`${r}${u}`,a={...t,basePath:t?.basePath??r,proxyUrl:t?.proxyUrl!==void 0?t.proxyUrl:i("/inspector/api/proxy"),disableTelemetry:t?.disableTelemetry??process.env.MCP_USE_ANONYMIZED_TELEMETRY==="false"},c=u=>{let d=new URL(u.req.url),f={...a,sandboxOrigin:a.sandboxOrigin??es(d)??null};return u.html(rs(f,r,s))};Nr(e,n),e.get(i("/inspector/oauth-popup-closed.html"),u=>u.html(ts)),e.get(i("/inspector/sandbox"),u=>u.html(Hr(new URL(u.req.url).search))),e.get(i("/inspector"),c),e.get(`${i("/inspector")}/`,c);let l=i("/inspector/api/");e.get(i("/inspector/*"),u=>u.req.path.startsWith(l)?u.notFound():c(u)),e.post(i("/inspector/*"),u=>u.req.path.startsWith(l)?u.notFound():c(u)),r===""&&t?.rootRedirect!==!1&&e.get("/",u=>{let d=new URL(u.req.url);return u.redirect(`${i("/inspector")}${d.search}`)})}function ns(){let{process:e,Deno:t}=globalThis;return!(typeof t?.noColor=="boolean"?t.noColor:e!==void 0?"NO_COLOR"in e?.env:!1)}async function Fr(){let{navigator:e}=globalThis,t="cloudflare:workers";return!(e!==void 0&&e.userAgent==="Cloudflare-Workers"?await(async()=>{try{return"NO_COLOR"in((await import(t)).env??{})}catch{return!1}})():!ns())}var os=e=>{let[t,r]=[",","."];return e.map(o=>o.replace(/(\d)(?=(\d\d\d)+(?!\d))/g,"$1"+t)).join(r)},ss=e=>{let t=Date.now()-e;return os([t<1e3?t+"ms":Math.round(t/1e3)+"s"])},is=async e=>{if(await Fr())switch(e/100|0){case 5:return`\x1B[31m${e}\x1B[0m`;case 4:return`\x1B[33m${e}\x1B[0m`;case 3:return`\x1B[36m${e}\x1B[0m`;case 2:return`\x1B[32m${e}\x1B[0m`}return`${e}`};async function qr(e,t,r,n,o=0,s){let i=t==="<--"?`${t} ${r} ${n}`:`${t} ${r} ${n} ${await is(o)} ${s}`;e(i)}var zr=(e=console.log)=>async function(r,n){let{method:o,url:s}=r.req,i=s.slice(s.indexOf("/",8));await qr(e,"<--",o,i);let a=Date.now();await n(),await qr(e,"-->",o,i,r.res.status,ss(a))};import{lookup as as}from"dns/promises";import{Buffer as cs}from"buffer";import{isIP as ls}from"net";var us=new Set(["accept","authorization","content-type","dpop"]),ds=new Set(["cache-control","content-type","dpop-nonce","expires","pragma","retry-after","www-authenticate"]),ps=[["registration_endpoint","registration"],["token_endpoint","token"],["revocation_endpoint","revocation"],["introspection_endpoint","introspection"]],Jr=600*1e3,fs=100,hs=1440*60*1e3,ms=500;function xt(e,t={}){let{basePath:r="/oauth",allowedOrigins:n=[],allowLoopback:o=!1,timeoutMs:s=1e4,maxRequestBodyBytes:i=64*1024,maxResponseBodyBytes:a=1024*1024,callbackPath:c="/oauth/callback",enableLogging:l=!0,authenticate:u,validateServerUrl:d,rateLimiter:f=new D.default({points:120,duration:60})}=t,h=new Set(n.map(vt)),w=new Map,y=new Map,g=async(p,m)=>{try{await f.consume(p.req)}catch(v){return te(p,v)}return m()};e.use(`${r}/*`,async(p,m)=>{let v=p.req.header("Origin");if(v&&!Rs(v,p,h))return p.json({error:"Origin not allowed"},403);if(p.req.method==="OPTIONS")return Ps(v);await m(),v&&on(p.res.headers,v)}),e.use(`${r}/*`,g),e.get(`${r}/metadata`,async p=>{if(!await Yr(p,u))return p.json({error:"Unauthorized"},401);let m=await V(p.req.query("serverUrl"),o);if("error"in m)return p.json({error:m.error},400);let v=m.url;if(d&&!await d(v.toString(),p))return p.json({error:"MCP server URL not allowed"},403);let T=await V(p.req.query("url"),o);if("error"in T)return p.json({error:T.error},400);let L=T.url,E=I(v),R=Gr(w,E),A=Wr(v,L,R);if(!A&&R.authorizationServers.size===0)try{await Kr(v,R,o,s,a),w.set(E,R),A=Wr(v,L,R)}catch{}if(!A)return p.json({error:"Metadata target is not bound to this MCP server"},403);try{wt(l,`GET ${L}`);let S=await Le(L,{method:"GET",headers:{Accept:"application/json"},redirect:"manual",signal:AbortSignal.timeout(s)});if(Ie(S.status))return p.json({error:"OAuth metadata redirects are not allowed"},502);let b=await Me(S,a);if(!S.ok)return p.body(b,S.status,{"Content-Type":S.headers.get("content-type")??"application/json"});let P=bt(b);return A.type==="protected-resource"?await en(P,v,R,o):await tn(P,A.issuer,R,o),R.updatedAt=Date.now(),w.set(E,R),Xr(w),p.body(b,200,{"Content-Type":S.headers.get("content-type")??"application/json"})}catch(S){return yt(p,S,l)}}),e.post(`${r}/proxy`,async p=>{if(!await Yr(p,u))return p.json({error:"Unauthorized"},401);let m;try{m=JSON.parse(await Ss(p.req.raw,i))}catch(b){return p.json({error:b instanceof j?"Request body too large":"Invalid JSON request body"},b instanceof j?413:400)}let v=await V(m.serverUrl,o);if("error"in v)return p.json({error:v.error},400);let T=v.url;if(d&&!await d(T.toString(),p))return p.json({error:"MCP server URL not allowed"},403);let L=await V(m.url,o);if("error"in L)return p.json({error:L.error},400);let E=L.url;if(m.method!==void 0&&m.method!=="POST")return p.json({error:"Only OAuth endpoint POST is allowed"},405);let R=I(T),A=Gr(w,R);if(A.endpoints.size===0)try{await Kr(T,A,o,s,a),w.set(R,A),Xr(w)}catch(b){return yt(p,b,l)}let S=A.endpoints.get(I(E));if(!S)return p.json({error:"OAuth endpoint is not bound to this MCP server"},403);try{let b=gs(m.headers),P=ys(m.body,b);if(S==="registration"){let fn=vt(p.req.header("Origin")??new URL(p.req.url).origin);P=Es(P,b,new URL(c,fn).toString())}else P=vs({body:P,headers:b,bindingKey:R,clients:y});if(new TextEncoder().encode(P??"").byteLength>i)return p.json({error:"OAuth request body too large"},413);wt(l,`POST ${S} ${E}`);let M=await Le(E,{method:"POST",headers:b,body:P,redirect:"manual",signal:AbortSignal.timeout(s)});if(Ie(M.status))return p.json({error:"OAuth endpoint redirects are not allowed"},502);let H=await Me(M,a),B=ws(M.headers),pn=M.headers.get("content-type")??"",$=H;if(pn.includes("json"))try{$=JSON.parse(H)}catch{}return S==="registration"&&M.ok&&$&&typeof $=="object"&&!Array.isArray($)&&($=bs({responseBody:$,binding:A,bindingKey:R,clients:y})),p.json({status:M.status,statusText:M.statusText,headers:B,body:$})}catch(b){return yt(p,b,l)}}),wt(l,`Mounted at ${r}/metadata and ${r}/proxy`)}async function V(e,t){if(typeof e!="string"||!e)return{error:"Missing or invalid URL"};let r;try{r=new URL(e)}catch{return{error:"Invalid URL"}}if(r.username||r.password||r.hash)return{error:"URL credentials and fragments are not allowed"};let n=As(r.hostname);if(r.protocol!=="https:"&&!(t&&n&&r.protocol==="http:"))return{error:"HTTPS is required"};if(n)return t?{url:r}:{error:"Loopback URL not allowed"};if(_s(r.hostname))return{error:"Local network URL not allowed"};try{let o=ls(r.hostname)?[r.hostname]:(await as(r.hostname,{all:!0,verbatim:!0})).map(({address:s})=>s);if(o.length===0||o.some(s=>!sn(s)))return{error:"Private or non-routable URL not allowed"}}catch{return{error:"URL hostname could not be resolved"}}return{url:r}}async function St(e,t=!1){return!("error"in await V(e,t))}function Wr(e,t,r){let n=I(t);if(Qr(e).some(o=>I(o)===n))return{type:"protected-resource"};for(let o of r.authorizationServers)if(Zr(new URL(o)).some(s=>I(s)===n))return{type:"authorization-server",issuer:o}}function Qr(e){let t=e.pathname==="/"?"":e.pathname;return[new URL(`/.well-known/oauth-protected-resource${t}`,e.origin),new URL("/.well-known/oauth-protected-resource",e.origin)]}function Zr(e){let t=e.pathname==="/"?"":e.pathname;return[new URL(`/.well-known/oauth-authorization-server${t}`,e.origin),new URL(`/.well-known/openid-configuration${t}`,e.origin),new URL(`${t||""}/.well-known/openid-configuration`,e.origin)]}async function en(e,t,r,n){if(typeof e.resource!="string"||I(new URL(e.resource))!==I(t))throw new _("Protected-resource metadata does not match serverUrl");if(!Array.isArray(e.authorization_servers)||e.authorization_servers.length===0)throw new _("Protected-resource metadata has no authorization servers");let o=new Set;for(let s of e.authorization_servers){let i=await V(s,n);if("error"in i)throw new _(`Unsafe authorization server: ${i.error}`);o.add(I(i.url))}r.authorizationServers=o,r.endpoints.clear(),r.tokenEndpointAuthMethods.clear()}async function tn(e,t,r,n){if(typeof e.issuer!="string"||I(new URL(e.issuer))!==t)throw new _("Authorization-server metadata issuer mismatch");r.endpoints.clear(),r.tokenEndpointAuthMethods=new Set(Array.isArray(e.token_endpoint_auth_methods_supported)?e.token_endpoint_auth_methods_supported.filter(o=>typeof o=="string"):[]);for(let[o,s]of ps){let i=e[o];if(i===void 0)continue;let a=await V(i,n);if("error"in a)throw new _(`Unsafe ${o}: ${a.error}`);r.endpoints.set(I(a.url),s)}}async function Kr(e,t,r,n,o){for(let s of Qr(e)){let i=await Le(s,{method:"GET",headers:{Accept:"application/json"},redirect:"manual",signal:AbortSignal.timeout(n)});if(Ie(i.status))throw new _("OAuth metadata redirects are not allowed");if(i.ok){await en(bt(await Me(i,o)),e,t,r);break}}if(t.authorizationServers.size===0)throw new _("Protected-resource metadata could not be discovered");for(let s of t.authorizationServers){let i=!1;for(let a of Zr(new URL(s))){let c=await Le(a,{method:"GET",headers:{Accept:"application/json"},redirect:"manual",signal:AbortSignal.timeout(n)});if(Ie(c.status))throw new _("OAuth metadata redirects are not allowed");if(c.ok){await tn(bt(await Me(c,o)),s,t,r),i=!0;break}}if(i)break}if(t.endpoints.size===0)throw new _("Authorization-server metadata could not be discovered");t.updatedAt=Date.now()}async function Le(e,t){return fetch(e,t)}function gs(e){let t=new Headers;if(!e||typeof e!="object"||Array.isArray(e))return t;for(let[r,n]of Object.entries(e)){let o=r.toLowerCase();us.has(o)&&typeof n=="string"&&t.set(o,n)}return t}function ws(e){let t={};return e.forEach((r,n)=>{ds.has(n.toLowerCase())&&(t[n]=r)}),t}function ys(e,t){if(e==null)return;if(typeof e=="string"){if(!t.has("content-type"))try{JSON.parse(e),t.set("content-type","application/json")}catch{t.set("content-type","application/x-www-form-urlencoded")}return e}if((t.get("content-type")??"").includes("application/x-www-form-urlencoded")&&typeof e=="object"&&!Array.isArray(e)){let n=new URLSearchParams;for(let[o,s]of Object.entries(e))n.append(o,String(s));return n.toString()}return t.has("content-type")||t.set("content-type","application/json"),JSON.stringify(e)}function rn(e,t){return`${e}\0${t}`}function bs(e){let{responseBody:t,binding:r,bindingKey:n,clients:o}=e,s=t.client_id,i=t.client_secret;if(typeof s!="string"||typeof i!="string")return t;let a=t.token_endpoint_auth_method,c=a==="client_secret_post"||a==="client_secret_basic"?a:r.tokenEndpointAuthMethods.has("client_secret_basic")?"client_secret_basic":"client_secret_post",l=t.client_secret_expires_at,u=l===0?Number.POSITIVE_INFINITY:typeof l=="number"&&l>0?l*1e3:Date.now()+hs;for(xs(o),o.set(rn(n,s),{clientSecret:i,authMethod:c,expiresAt:u});o.size>ms;){let f=o.keys().next().value;if(!f)break;o.delete(f)}let d={...t};return delete d.client_secret,delete d.client_secret_expires_at,d.token_endpoint_auth_method="none",d}function vs(e){let{body:t,headers:r,bindingKey:n,clients:o}=e;if(!t||!(r.get("content-type")??"").includes("application/x-www-form-urlencoded"))return t;let s=new URLSearchParams(t),i=s.get("client_id");if(!i)return t;let a=rn(n,i),c=o.get(a);if(!c)return t;if(c.expiresAt<=Date.now())return o.delete(a),t;if(s.delete("client_secret"),c.authMethod==="client_secret_basic"){let l=cs.from(`${Vr(i)}:${Vr(c.clientSecret)}`,"utf8").toString("base64");r.set("authorization",`Basic ${l}`)}else r.delete("authorization"),s.set("client_id",i),s.set("client_secret",c.clientSecret);return s.toString()}function Vr(e){return new URLSearchParams({value:e}).toString().slice(6)}function xs(e){let t=Date.now();for(let[r,n]of e)n.expiresAt<=t&&e.delete(r)}async function Ss(e,t){let r=Number(e.headers.get("content-length"));if(Number.isFinite(r)&&r>t)throw new j;return nn(e.body,t)}async function Me(e,t){let r=Number(e.headers.get("content-length"));if(Number.isFinite(r)&&r>t)throw await e.body?.cancel(),new j;return nn(e.body,t)}async function nn(e,t){if(!e)return"";let r=e.getReader(),n=[],o=0;for(;;){let{done:a,value:c}=await r.read();if(a)break;if(o+=c.byteLength,o>t)throw await r.cancel(),new j;n.push(c)}let s=new Uint8Array(o),i=0;for(let a of n)s.set(a,i),i+=a.byteLength;return new TextDecoder().decode(s)}function bt(e){let t;try{t=JSON.parse(e)}catch{throw new _("OAuth metadata is not valid JSON")}if(!t||typeof t!="object"||Array.isArray(t))throw new _("OAuth metadata is not an object");return t}function Gr(e,t){let r=e.get(t);return r&&Date.now()-r.updatedAt<=Jr?r:(e.delete(t),{authorizationServers:new Set,endpoints:new Map,tokenEndpointAuthMethods:new Set,updatedAt:Date.now()})}function Xr(e){let t=Date.now();for(let[r,n]of e)t-n.updatedAt>Jr&&e.delete(r);for(;e.size>fs;){let r=e.keys().next().value;if(!r)break;e.delete(r)}}function I(e){let t=new URL(e);return t.hash="",(t.protocol==="https:"&&t.port==="443"||t.protocol==="http:"&&t.port==="80")&&(t.port=""),t.toString().replace(/\/$/,"")}function Es(e,t,r){if(!e||!(t.get("content-type")??"").includes("json"))return e;try{let o=JSON.parse(e);return!o||typeof o!="object"||Array.isArray(o)?e:JSON.stringify({...o,redirect_uris:[r]})}catch{return e}}function vt(e){let t=new URL(e);if(t.pathname!=="/"||t.search||t.hash)throw new Error(`OAuth proxy allowed origin must be an origin: ${e}`);return t.origin}function Rs(e,t,r){try{let n=vt(e);if(n===new URL(t.req.url).origin||r.has(n))return!0;let o=new URL(n),i=t.req.header("x-forwarded-host")?.split(",")[0]?.trim()||t.req.header("host");if(!i||o.host!==i)return!1;let a=t.req.header("x-forwarded-proto")?.split(",")[0]?.trim();return!a||`${a}:`===o.protocol}catch{return!1}}function Ps(e){let t=new Headers;return e&&on(t,e),t.set("Access-Control-Allow-Methods","GET, POST, OPTIONS"),t.set("Access-Control-Allow-Headers","Accept, Authorization, Content-Type"),t.set("Access-Control-Max-Age","600"),new Response(null,{status:204,headers:t})}function on(e,t){e.set("Access-Control-Allow-Origin",t),e.append("Vary","Origin")}async function Yr(e,t){return t?t(e):!0}function Ie(e){return e>=300&&e<400}function As(e){let t=e.toLowerCase().replace(/^\[|\]$/g,"");return t==="localhost"||t.endsWith(".localhost")||t==="::1"||t.startsWith("127.")}function _s(e){let t=e.toLowerCase();return t.endsWith(".local")||t.endsWith(".internal")||t.endsWith(".home.arpa")}function sn(e){if(e.includes(":")){let s=e.toLowerCase();return s.startsWith("::ffff:")?sn(s.slice(7)):!(s==="::"||s==="::1"||s.startsWith("fc")||s.startsWith("fd")||/^fe[89ab]/.test(s)||s.startsWith("ff")||s.startsWith("2001:db8:"))}let t=e.split(".").map(Number);if(t.length!==4||t.some(s=>!Number.isInteger(s)))return!1;let[r,n,o]=t;return!(r===0||r===10||r===127||r===100&&n>=64&&n<=127||r===169&&n===254||r===172&&n>=16&&n<=31||r===192&&n===0&&o===0||r===192&&n===0&&o===2||r===192&&n===168||r===198&&(n===18||n===19)||r===198&&n===51&&o===100||r===203&&n===0&&o===113||r>=224)}function wt(e,t){e&&console.log(`[OAuth BFF] ${t}`)}function yt(e,t,r){let n=t instanceof Error?t.message:"Unknown error";return r&&console.error("[OAuth BFF]",n),t instanceof j?e.json({error:"Upstream response too large"},502):t instanceof _?e.json({error:t.message},502):t instanceof DOMException&&t.name==="TimeoutError"?e.json({error:"OAuth upstream timed out"},504):e.json({error:"OAuth upstream request failed"},502)}var j=class extends Error{},_=class extends Error{};var Cs=3;function Os(e,t){return e.includes("text/event-stream")&&!t}function Et(e,t={}){let r=t.path||"/mcp/proxy",n=t.enableLogging!==!1,o=t.rateLimiter??new D.default({points:120,duration:60}),s=async(i,a)=>{try{await o.consume(i.req)}catch(c){return te(i,c)}return a()};e.use(`${r}/*`,Pe({origin:"*",allowHeaders:["Authorization","Content-Type","Accept","X-Target-URL","X-MCP-Target","Mcp-Session-Id","mcp-session-id","mcp-protocol-version","X-Server-Id","X-Requested-With"],exposeHeaders:["*"]})),n&&e.use(`${r}/*`,zr()),e.use(`${r}/*`,s),e.all(`${r}/*`,async i=>{try{if(t.authenticate&&!await t.authenticate(i))return i.json({error:"Unauthorized"},401);let a=i.req.header("X-Target-URL");if(!a)return i.json({error:"X-Target-URL header is required",usage:"Set X-Target-URL header to the MCP server URL you want to proxy to"},400);if(!await St(a,t.allowLoopback??!1))return i.json({error:"Invalid target URL",details:"Target is not allowed by the proxy network policy"},403);if(t.validateRequest&&!await t.validateRequest(a,i))return i.json({error:"Invalid target URL",details:"The requested target URL is not allowed"},403);try{new URL(a)}catch{return i.json({error:"Invalid target URL format",details:"The X-Target-URL must be a valid HTTP/HTTPS URL"},400)}let c=i.req.method,l={},u=i.req.header();for(let[y,g]of Object.entries(u)){let p=y.toLowerCase();!p.startsWith("x-proxy-")&&!p.startsWith("x-target-")&&!p.startsWith("x-mcp-")&&!p.startsWith("x-forwarded-")&&!p.startsWith("cf-")&&p!=="x-original-host"&&p!=="host"&&p!=="origin"&&p!=="referer"&&p!=="cookie"&&p!=="proxy-authorization"&&p!=="accept-encoding"&&p!=="cdn-loop"&&!p.startsWith("sec-fetch-")&&(l[y]=g)}l["Accept-Encoding"]="identity";let d=c!=="GET"&&c!=="HEAD"?new Uint8Array(await i.req.arrayBuffer()).slice():void 0,f=a,h=c,w=d;for(let y=0;;y+=1){let g=await fetch(f,{method:h,headers:l,body:w,redirect:"manual"}),p=g.headers.get("location");if(!(g.status>=300&&g.status<400&&p))return Ts(g);if(y>=Cs)return i.json({error:"Too many upstream redirects"},502);let m=new URL(p,f);if(!await St(m.toString(),t.allowLoopback??!1)||t.validateRequest&&!await t.validateRequest(m.toString(),i))return i.json({error:"Redirect target is not allowed"},403);m.origin!==new URL(f).origin&&(ke(l,"authorization"),ke(l,"proxy-authorization")),(g.status===303||(g.status===301||g.status===302)&&h==="POST")&&(h="GET",w=void 0,ke(l,"content-type"),ke(l,"content-length")),f=m.toString()}}catch(a){let c=a instanceof Error?a.message:"Unknown error",l=i.req.header("X-Target-URL");return a instanceof Error&&(a.message.includes("ECONNREFUSED")||a.message.includes("fetch failed"))?console.warn(`[MCP Proxy] Connection refused to ${l||"unknown target"} - server may not be running`):console.error("[MCP Proxy] Request failed:",c,`
|
|
373
|
+
Target URL:`,l||"unknown",`
|
|
374
|
+
Error:`,a),i.json({error:"Proxy request failed",details:c,targetUrl:l||"unknown"},500)}})}function ke(e,t){for(let r of Object.keys(e))r.toLowerCase()===t&&delete e[r]}async function Ts(e){let t={};if(e.headers.forEach((o,s)=>{let i=s.toLowerCase();i!=="content-encoding"&&i!=="transfer-encoding"&&i!=="content-length"&&i!=="set-cookie"&&(t[s]=o)}),Os(e.headers.get("content-type")||"",e.headers.get("content-length")))return new Response(e.body,{status:e.status,statusText:e.statusText,headers:t});if([204,205,304].includes(e.status))return new Response(null,{status:e.status,statusText:e.statusText,headers:t});let n=await e.arrayBuffer();return t["Content-Length"]=String(n.byteLength),new Response(n,{status:e.status,statusText:e.statusText,headers:t})}function an(e,t,r=""){let n=a=>`${r}${a}`,o=t?.oauthProxyAllowLoopback??!1,s=t?.oauth!==!1,i=new D.default({points:120,duration:60});if(e.get(n("/inspector/health"),a=>a.json({status:"ok",protocol:"mcp-use-inspector-preview",version:1,capabilities:["view-preview"]})),Et(e,{path:n("/inspector/api/proxy"),allowLoopback:o,rateLimiter:i}),s&&xt(e,{basePath:n("/inspector/api/oauth"),callbackPath:n("/inspector/oauth/callback"),enableLogging:!0,allowedOrigins:t?.oauthProxyAllowedOrigins??[],allowLoopback:o,rateLimiter:i}),t?.autoConnectUrl!==void 0){let a=t.autoConnectUrl;e.get(n("/inspector/config.json"),c=>c.json({autoConnectUrl:a??null}))}}function cn(e){try{let t=new URL(e);return t.protocol==="http:"||t.protocol==="https:"}catch{return!1}}async function ln(e=8080,t=100){let r=await import("net");for(let n=e;n<e+t;n++)try{return await new Promise((o,s)=>{let i=r.createServer();i.listen(n,()=>{i.close(()=>o())}),i.on("error",a=>s(a))}),n}catch{continue}throw new Error(`No available port found after trying ${t} ports starting from ${e}`)}function Rt(e){if(!(e instanceof Error))return`UnknownError (${typeof e})`;let t=/^[A-Za-z][A-Za-z0-9_.-]{0,63}$/.test(e.name)?e.name:"Error",r=e.code,n=typeof r=="string"&&/^[A-Z][A-Z0-9_]{0,31}$/.test(r)?r:void 0;return n?`${t} (${n})`:t}var C=process.argv.slice(2),de,un=8080,dn=!1;for(let e=0;e<C.length;e++)if(C[e]==="--url"){(e+1>=C.length||C[e+1].startsWith("-"))&&(console.error("Error: --url requires a value"),process.exit(1));let t=C[e+1];cn(t)||(console.error("Error: Invalid URL format."),console.error("URL must start with http://, https://, ws://, or wss://"),process.exit(1)),de=t,e++}else if(C[e]==="--port"){(e+1>=C.length||C[e+1].startsWith("-"))&&(console.error("Error: --port requires a value"),process.exit(1));let t=Number.parseInt(C[e+1],10);(Number.isNaN(t)||t<1||t>65535)&&(console.error("Error: Port must be a number between 1 and 65535."),process.exit(1)),un=t,e++}else C[e]==="--no-open"?dn=!0:C[e]==="--version"||C[e]==="-v"?(console.log(Te()),process.exit(0)):C[e]==="--help"||C[e]==="-h"?(console.log(`
|
|
1371
375
|
MCP Inspector - Inspect and debug MCP servers
|
|
1372
376
|
|
|
1373
377
|
Usage:
|
|
@@ -1384,60 +388,4 @@ Examples:
|
|
|
1384
388
|
npx @mcp-use/inspector --url http://localhost:3000/mcp
|
|
1385
389
|
npx @mcp-use/inspector --url http://localhost:3000/mcp --port 9000
|
|
1386
390
|
npx @mcp-use/inspector
|
|
1387
|
-
`);
|
|
1388
|
-
process.exit(0);
|
|
1389
|
-
} else {
|
|
1390
|
-
console.error(`Error: Unknown option: ${args[i]}`);
|
|
1391
|
-
console.error("Run with --help to see available options.");
|
|
1392
|
-
process.exit(1);
|
|
1393
|
-
}
|
|
1394
|
-
}
|
|
1395
|
-
var app = new Hono();
|
|
1396
|
-
app.use(
|
|
1397
|
-
"*",
|
|
1398
|
-
cors2({
|
|
1399
|
-
origin: "*",
|
|
1400
|
-
exposeHeaders: ["*"]
|
|
1401
|
-
})
|
|
1402
|
-
);
|
|
1403
|
-
app.use("/inspector/api/proxy/*", logger2());
|
|
1404
|
-
var inspectorMode = process.env.MCP_INSPECTOR_MODE ?? (process.env.RAILWAY_ENVIRONMENT_NAME ? "cloud" : "standalone");
|
|
1405
|
-
registerInspectorProxyRoutes(app, {
|
|
1406
|
-
autoConnectUrl: mcpUrl,
|
|
1407
|
-
oauthProxyAllowedOrigins: [],
|
|
1408
|
-
oauthProxyAllowLoopback: inspectorMode === "standalone"
|
|
1409
|
-
});
|
|
1410
|
-
registerInspectorCdnShell(app, {
|
|
1411
|
-
inspectorMode,
|
|
1412
|
-
manufactChatUrl: process.env.MANUFACT_CHAT_URL
|
|
1413
|
-
});
|
|
1414
|
-
async function startServer() {
|
|
1415
|
-
try {
|
|
1416
|
-
const port = await findAvailablePort(startPort);
|
|
1417
|
-
serve({
|
|
1418
|
-
fetch: app.fetch,
|
|
1419
|
-
port
|
|
1420
|
-
});
|
|
1421
|
-
console.log(`\u{1F680} MCP Inspector running on http://localhost:${port}`);
|
|
1422
|
-
if (mcpUrl) {
|
|
1423
|
-
console.log(`\u{1F4E1} Auto-connecting to: ${mcpUrl}`);
|
|
1424
|
-
}
|
|
1425
|
-
if (!noOpen) {
|
|
1426
|
-
const openUrl = new URL(`http://localhost:${port}/inspector`);
|
|
1427
|
-
if (mcpUrl) {
|
|
1428
|
-
openUrl.searchParams.set("autoConnect", mcpUrl);
|
|
1429
|
-
}
|
|
1430
|
-
try {
|
|
1431
|
-
await open(openUrl.toString());
|
|
1432
|
-
console.log(`\u{1F310} Browser opened`);
|
|
1433
|
-
} catch {
|
|
1434
|
-
console.log(`\u{1F310} Please open ${openUrl} in your browser`);
|
|
1435
|
-
}
|
|
1436
|
-
}
|
|
1437
|
-
return { port, fetch: app.fetch };
|
|
1438
|
-
} catch (error) {
|
|
1439
|
-
console.error("Failed to start server:", error);
|
|
1440
|
-
process.exit(1);
|
|
1441
|
-
}
|
|
1442
|
-
}
|
|
1443
|
-
startServer();
|
|
391
|
+
`),process.exit(0)):(console.error("Error: Unknown option."),console.error("Run with --help to see available options."),process.exit(1));var pe=new Ze;pe.use("*",Pe({origin:"*",exposeHeaders:["*"]}));an(pe,{autoConnectUrl:de,oauthProxyAllowedOrigins:[],oauthProxyAllowLoopback:!0});$r(pe,{inspectorMode:"standalone",manufactChatUrl:process.env.MANUFACT_CHAT_URL});async function Ls(){try{let e=await ln(un);if(Ut({fetch:pe.fetch,port:e}),console.log(`MCP Inspector started at http://localhost:${e}/inspector`),de&&console.log("Auto-connect configured."),!dn){let t=new URL(`http://localhost:${e}/inspector`);de&&t.searchParams.set("autoConnect",de);try{await Er(t.toString()),console.log("Browser opened.")}catch(r){console.log(`Browser could not be opened automatically. Open ${t.toString()} manually.`),console.error(`Browser open error: ${Rt(r)}`)}}return{port:e,fetch:pe.fetch}}catch(e){console.error(`Failed to start server (StartupError): ${Rt(e)}`),process.exit(1)}}Ls();
|