@vybestack/llxprt-code-core 0.1.12 → 0.1.13
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/LICENSE +202 -0
- package/README.md +256 -0
- package/dist/src/adapters/IStreamAdapter.d.ts +18 -0
- package/dist/src/adapters/IStreamAdapter.js +7 -0
- package/dist/src/adapters/IStreamAdapter.js.map +1 -0
- package/dist/src/code_assist/oauth2.d.ts +1 -1
- package/dist/src/code_assist/oauth2.js +51 -29
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +36 -7
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/server.test.js +10 -2
- package/dist/src/code_assist/server.test.js.map +1 -1
- package/dist/src/config/config.d.ts +28 -5
- package/dist/src/config/config.js +29 -4
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +2 -3
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/core/client.d.ts +4 -2
- package/dist/src/core/client.js +68 -7
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +8 -0
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.d.ts +3 -2
- package/dist/src/core/contentGenerator.js +6 -8
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +12 -5
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +4 -2
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.js +50 -3
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/modelCheck.d.ts +1 -1
- package/dist/src/core/modelCheck.js +10 -3
- package/dist/src/core/modelCheck.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +3 -0
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.d.ts +1 -1
- package/dist/src/core/prompts.js +14 -2
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/turn.js +6 -0
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/index.d.ts +29 -1
- package/dist/src/index.js +33 -0
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/oauth-provider.d.ts +142 -0
- package/dist/src/mcp/oauth-provider.js +446 -0
- package/dist/src/mcp/oauth-provider.js.map +1 -0
- package/dist/src/mcp/oauth-provider.test.js +520 -0
- package/dist/src/mcp/oauth-provider.test.js.map +1 -0
- package/dist/src/mcp/oauth-token-storage.d.ts +81 -0
- package/dist/src/mcp/oauth-token-storage.js +149 -0
- package/dist/src/mcp/oauth-token-storage.js.map +1 -0
- package/dist/src/mcp/oauth-token-storage.test.d.ts +6 -0
- package/dist/src/mcp/oauth-token-storage.test.js +205 -0
- package/dist/src/mcp/oauth-token-storage.test.js.map +1 -0
- package/dist/src/mcp/oauth-utils.d.ts +109 -0
- package/dist/src/mcp/oauth-utils.js +183 -0
- package/dist/src/mcp/oauth-utils.js.map +1 -0
- package/dist/src/mcp/oauth-utils.test.d.ts +6 -0
- package/dist/src/mcp/oauth-utils.test.js +144 -0
- package/dist/src/mcp/oauth-utils.test.js.map +1 -0
- package/dist/src/parsers/TextToolCallParser.d.ts +35 -0
- package/dist/src/parsers/TextToolCallParser.js +248 -0
- package/dist/src/parsers/TextToolCallParser.js.map +1 -0
- package/dist/src/parsers/TextToolCallParser.test.d.ts +1 -0
- package/dist/src/parsers/TextToolCallParser.test.js +225 -0
- package/dist/src/parsers/TextToolCallParser.test.js.map +1 -0
- package/dist/src/providers/ContentGeneratorRole.d.ts +14 -0
- package/dist/src/providers/ContentGeneratorRole.js +16 -0
- package/dist/src/providers/ContentGeneratorRole.js.map +1 -0
- package/dist/src/providers/IMessage.d.ts +38 -0
- package/dist/src/providers/IMessage.js +17 -0
- package/dist/src/providers/IMessage.js.map +1 -0
- package/dist/src/providers/IModel.d.ts +23 -0
- package/dist/src/providers/IModel.js +17 -0
- package/dist/src/providers/IModel.js.map +1 -0
- package/dist/src/providers/IProvider.d.ts +36 -0
- package/dist/src/providers/IProvider.js +17 -0
- package/dist/src/providers/IProvider.js.map +1 -0
- package/dist/src/providers/IProviderConfig.d.ts +31 -0
- package/dist/src/providers/IProviderConfig.js +7 -0
- package/dist/src/providers/IProviderConfig.js.map +1 -0
- package/dist/src/providers/IProviderManager.d.ts +53 -0
- package/dist/src/providers/IProviderManager.js +7 -0
- package/dist/src/providers/IProviderManager.js.map +1 -0
- package/dist/src/providers/ITool.d.ts +23 -0
- package/dist/src/providers/ITool.js +17 -0
- package/dist/src/providers/ITool.js.map +1 -0
- package/dist/src/providers/ProviderContentGenerator.d.ts +1 -1
- package/dist/src/providers/ProviderManager.d.ts +24 -0
- package/dist/src/providers/ProviderManager.gemini-switch.test.d.ts +6 -0
- package/dist/src/providers/ProviderManager.gemini-switch.test.js +57 -0
- package/dist/src/providers/ProviderManager.gemini-switch.test.js.map +1 -0
- package/dist/src/providers/ProviderManager.js +116 -0
- package/dist/src/providers/ProviderManager.js.map +1 -0
- package/dist/src/providers/ProviderManager.test.d.ts +6 -0
- package/dist/src/providers/ProviderManager.test.js +284 -0
- package/dist/src/providers/ProviderManager.test.js.map +1 -0
- package/dist/src/providers/adapters/GeminiCompatibleWrapper.d.ts +2 -1
- package/dist/src/providers/adapters/GeminiCompatibleWrapper.js +15 -2
- package/dist/src/providers/adapters/GeminiCompatibleWrapper.js.map +1 -1
- package/dist/src/providers/adapters/GeminiCompatibleWrapper.test.js +20 -0
- package/dist/src/providers/adapters/GeminiCompatibleWrapper.test.js.map +1 -1
- package/dist/src/providers/anthropic/AnthropicProvider.d.ts +57 -0
- package/dist/src/providers/anthropic/AnthropicProvider.js +490 -0
- package/dist/src/providers/anthropic/AnthropicProvider.js.map +1 -0
- package/dist/src/providers/anthropic/AnthropicProvider.test.d.ts +1 -0
- package/dist/src/providers/anthropic/AnthropicProvider.test.js +486 -0
- package/dist/src/providers/anthropic/AnthropicProvider.test.js.map +1 -0
- package/dist/src/providers/errors.d.ts +13 -0
- package/dist/src/providers/errors.js +19 -0
- package/dist/src/providers/errors.js.map +1 -0
- package/dist/src/providers/gemini/GeminiProvider.d.ts +97 -0
- package/dist/src/providers/gemini/GeminiProvider.integration.test.d.ts +6 -0
- package/dist/src/providers/gemini/GeminiProvider.integration.test.js +90 -0
- package/dist/src/providers/gemini/GeminiProvider.integration.test.js.map +1 -0
- package/dist/src/providers/gemini/GeminiProvider.js +937 -0
- package/dist/src/providers/gemini/GeminiProvider.js.map +1 -0
- package/dist/src/providers/gemini/GeminiProvider.test.d.ts +6 -0
- package/dist/src/providers/gemini/GeminiProvider.test.js +136 -0
- package/dist/src/providers/gemini/GeminiProvider.test.js.map +1 -0
- package/dist/src/providers/integration/TEST_INSTRUCTIONS.md +197 -0
- package/dist/src/providers/integration/multi-provider.integration.test.d.ts +6 -0
- package/dist/src/providers/integration/multi-provider.integration.test.js +292 -0
- package/dist/src/providers/integration/multi-provider.integration.test.js.map +1 -0
- package/dist/src/providers/openai/ConversationCache.accumTokens.test.d.ts +1 -0
- package/dist/src/providers/openai/ConversationCache.accumTokens.test.js +97 -0
- package/dist/src/providers/openai/ConversationCache.accumTokens.test.js.map +1 -0
- package/dist/src/providers/openai/ConversationCache.d.ts +20 -0
- package/dist/src/providers/openai/ConversationCache.js +109 -0
- package/dist/src/providers/openai/ConversationCache.js.map +1 -0
- package/dist/src/providers/openai/ConversationCache.test.d.ts +1 -0
- package/dist/src/providers/openai/ConversationCache.test.js +113 -0
- package/dist/src/providers/openai/ConversationCache.test.js.map +1 -0
- package/dist/src/providers/openai/IChatGenerateParams.d.ts +11 -0
- package/dist/src/providers/openai/IChatGenerateParams.js +2 -0
- package/dist/src/providers/openai/IChatGenerateParams.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.callResponses.stateless.test.d.ts +1 -0
- package/dist/src/providers/openai/OpenAIProvider.callResponses.stateless.test.js +189 -0
- package/dist/src/providers/openai/OpenAIProvider.callResponses.stateless.test.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.d.ts +80 -0
- package/dist/src/providers/openai/OpenAIProvider.integration.test.d.ts +6 -0
- package/dist/src/providers/openai/OpenAIProvider.integration.test.js +125 -0
- package/dist/src/providers/openai/OpenAIProvider.integration.test.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.js +518 -0
- package/dist/src/providers/openai/OpenAIProvider.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.responses.test.d.ts +1 -0
- package/dist/src/providers/openai/OpenAIProvider.responses.test.js +326 -0
- package/dist/src/providers/openai/OpenAIProvider.responses.test.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.responsesIntegration.test.d.ts +1 -0
- package/dist/src/providers/openai/OpenAIProvider.responsesIntegration.test.js +213 -0
- package/dist/src/providers/openai/OpenAIProvider.responsesIntegration.test.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.shouldUseResponses.test.d.ts +1 -0
- package/dist/src/providers/openai/OpenAIProvider.shouldUseResponses.test.js +58 -0
- package/dist/src/providers/openai/OpenAIProvider.shouldUseResponses.test.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.stateful.integration.test.d.ts +6 -0
- package/dist/src/providers/openai/OpenAIProvider.stateful.integration.test.js +105 -0
- package/dist/src/providers/openai/OpenAIProvider.stateful.integration.test.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.switch.test.d.ts +1 -0
- package/dist/src/providers/openai/OpenAIProvider.switch.test.js +256 -0
- package/dist/src/providers/openai/OpenAIProvider.switch.test.js.map +1 -0
- package/dist/src/providers/openai/OpenAIProvider.test.d.ts +16 -0
- package/dist/src/providers/openai/OpenAIProvider.test.js +214 -0
- package/dist/src/providers/openai/OpenAIProvider.test.js.map +1 -0
- package/dist/src/providers/openai/RESPONSES_API_MODELS.d.ts +2 -0
- package/dist/src/providers/openai/RESPONSES_API_MODELS.js +14 -0
- package/dist/src/providers/openai/RESPONSES_API_MODELS.js.map +1 -0
- package/dist/src/providers/openai/ResponsesContextTrim.integration.test.d.ts +1 -0
- package/dist/src/providers/openai/ResponsesContextTrim.integration.test.js +210 -0
- package/dist/src/providers/openai/ResponsesContextTrim.integration.test.js.map +1 -0
- package/dist/src/providers/openai/__tests__/formatArrayResponse.test.d.ts +1 -0
- package/dist/src/providers/openai/__tests__/formatArrayResponse.test.js +65 -0
- package/dist/src/providers/openai/__tests__/formatArrayResponse.test.js.map +1 -0
- package/dist/src/providers/openai/buildResponsesRequest.d.ts +73 -0
- package/dist/src/providers/openai/buildResponsesRequest.js +165 -0
- package/dist/src/providers/openai/buildResponsesRequest.js.map +1 -0
- package/dist/src/providers/openai/buildResponsesRequest.stripToolCalls.test.d.ts +1 -0
- package/dist/src/providers/openai/buildResponsesRequest.stripToolCalls.test.js +129 -0
- package/dist/src/providers/openai/buildResponsesRequest.stripToolCalls.test.js.map +1 -0
- package/dist/src/providers/openai/buildResponsesRequest.test.d.ts +1 -0
- package/dist/src/providers/openai/buildResponsesRequest.test.js +406 -0
- package/dist/src/providers/openai/buildResponsesRequest.test.js.map +1 -0
- package/dist/src/providers/openai/buildResponsesRequest.undefined.test.d.ts +1 -0
- package/dist/src/providers/openai/buildResponsesRequest.undefined.test.js +50 -0
- package/dist/src/providers/openai/buildResponsesRequest.undefined.test.js.map +1 -0
- package/dist/src/providers/openai/docs/accessing-provider-info.md +172 -0
- package/dist/src/providers/openai/docs/params-mapping.md +91 -0
- package/dist/src/providers/openai/docs/responses-api-tool-calls.md +96 -0
- package/dist/src/providers/openai/estimateRemoteTokens.d.ts +26 -0
- package/dist/src/providers/openai/estimateRemoteTokens.js +75 -0
- package/dist/src/providers/openai/estimateRemoteTokens.js.map +1 -0
- package/dist/src/providers/openai/estimateRemoteTokens.test.d.ts +1 -0
- package/dist/src/providers/openai/estimateRemoteTokens.test.js +125 -0
- package/dist/src/providers/openai/estimateRemoteTokens.test.js.map +1 -0
- package/dist/src/providers/openai/getOpenAIProviderInfo.d.ts +46 -0
- package/dist/src/providers/openai/getOpenAIProviderInfo.js +75 -0
- package/dist/src/providers/openai/getOpenAIProviderInfo.js.map +1 -0
- package/dist/src/providers/openai/parseResponsesStream.d.ts +3 -0
- package/dist/src/providers/openai/parseResponsesStream.js +462 -0
- package/dist/src/providers/openai/parseResponsesStream.js.map +1 -0
- package/dist/src/providers/openai/parseResponsesStream.responsesToolCalls.test.d.ts +1 -0
- package/dist/src/providers/openai/parseResponsesStream.responsesToolCalls.test.js +192 -0
- package/dist/src/providers/openai/parseResponsesStream.responsesToolCalls.test.js.map +1 -0
- package/dist/src/providers/openai/parseResponsesStream.test.d.ts +1 -0
- package/dist/src/providers/openai/parseResponsesStream.test.js +151 -0
- package/dist/src/providers/openai/parseResponsesStream.test.js.map +1 -0
- package/dist/src/providers/tokenizers/AnthropicTokenizer.d.ts +19 -0
- package/dist/src/providers/tokenizers/AnthropicTokenizer.js +37 -0
- package/dist/src/providers/tokenizers/AnthropicTokenizer.js.map +1 -0
- package/dist/src/providers/tokenizers/ITokenizer.d.ts +18 -0
- package/dist/src/providers/tokenizers/ITokenizer.js +17 -0
- package/dist/src/providers/tokenizers/ITokenizer.js.map +1 -0
- package/dist/src/providers/tokenizers/OpenAITokenizer.d.ts +24 -0
- package/dist/src/providers/tokenizers/OpenAITokenizer.js +56 -0
- package/dist/src/providers/tokenizers/OpenAITokenizer.js.map +1 -0
- package/dist/src/providers/types/IProviderConfig.d.ts +102 -0
- package/dist/src/providers/types/IProviderConfig.js +17 -0
- package/dist/src/providers/types/IProviderConfig.js.map +1 -0
- package/dist/src/providers/types.d.ts +4 -69
- package/dist/src/services/ideContext.d.ts +2 -0
- package/dist/src/services/ideContext.js +8 -0
- package/dist/src/services/ideContext.js.map +1 -1
- package/dist/src/services/ideContext.test.js +10 -0
- package/dist/src/services/ideContext.test.js.map +1 -1
- package/dist/src/services/loopDetectionService.d.ts +17 -1
- package/dist/src/services/loopDetectionService.js +117 -2
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +109 -2
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +2 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +40 -2
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +2 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +4 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/sdk.js +0 -2
- package/dist/src/telemetry/sdk.js.map +1 -1
- package/dist/src/telemetry/types.d.ts +2 -1
- package/dist/src/telemetry/types.js +1 -0
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +1 -0
- package/dist/src/telemetry/uiTelemetry.js +7 -0
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.test.js +92 -0
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
- package/dist/src/tools/IToolFormatter.d.ts +40 -0
- package/dist/src/tools/IToolFormatter.js +17 -0
- package/dist/src/tools/IToolFormatter.js.map +1 -0
- package/dist/src/tools/ToolFormatter.d.ts +45 -0
- package/dist/src/tools/ToolFormatter.js +216 -0
- package/dist/src/tools/ToolFormatter.js.map +1 -0
- package/dist/src/tools/ToolFormatter.test.d.ts +16 -0
- package/dist/src/tools/ToolFormatter.test.js +349 -0
- package/dist/src/tools/ToolFormatter.test.js.map +1 -0
- package/dist/src/tools/ToolFormatter.toResponsesTool.test.d.ts +1 -0
- package/dist/src/tools/ToolFormatter.toResponsesTool.test.js +241 -0
- package/dist/src/tools/ToolFormatter.toResponsesTool.test.js.map +1 -0
- package/dist/src/tools/edit.d.ts +7 -1
- package/dist/src/tools/edit.js +19 -7
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/glob.js +2 -2
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/grep.js +2 -2
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/ls.js +2 -2
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/mcp-client.d.ts +0 -2
- package/dist/src/tools/mcp-client.js +8 -20
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +1 -72
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +11 -5
- package/dist/src/tools/mcp-tool.js +33 -9
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +40 -24
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/memoryTool.js +2 -2
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/read-file.d.ts +2 -1
- package/dist/src/tools/read-file.js +5 -2
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-many-files.js +2 -2
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/shell.js +2 -2
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/todo-read.js +2 -2
- package/dist/src/tools/todo-read.js.map +1 -1
- package/dist/src/tools/todo-write.js +2 -2
- package/dist/src/tools/todo-write.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +0 -1
- package/dist/src/tools/tool-registry.js +11 -8
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +36 -10
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +37 -2
- package/dist/src/tools/tools.js +25 -2
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/web-fetch.integration.test.d.ts +6 -0
- package/dist/src/tools/web-fetch.integration.test.js +532 -0
- package/dist/src/tools/web-fetch.integration.test.js.map +1 -0
- package/dist/src/tools/web-fetch.js +57 -50
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-search.js +34 -6
- package/dist/src/tools/web-search.js.map +1 -1
- package/dist/src/tools/web-search.test.d.ts +6 -0
- package/dist/src/tools/web-search.test.js +229 -0
- package/dist/src/tools/web-search.test.js.map +1 -0
- package/dist/src/tools/write-file.js +12 -5
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/utils/browser.d.ts +13 -0
- package/dist/src/utils/browser.js +49 -0
- package/dist/src/utils/browser.js.map +1 -0
- package/dist/src/utils/errors.js +4 -4
- package/dist/src/utils/errors.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.js +5 -1
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/quotaErrorDetection.js +0 -2
- package/dist/src/utils/quotaErrorDetection.js.map +1 -1
- package/dist/src/utils/retry.d.ts +6 -0
- package/dist/src/utils/retry.js +1 -1
- package/dist/src/utils/retry.js.map +1 -1
- package/dist/src/utils/user_account.js +6 -1
- package/dist/src/utils/user_account.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +6 -3
- package/dist/src/tools/web-fetch.test.js +0 -70
- package/dist/src/tools/web-fetch.test.js.map +0 -1
- package/dist/vybestack-llxprt-code-core-0.1.12.tgz +0 -0
- /package/dist/src/{tools/web-fetch.test.d.ts → mcp/oauth-provider.test.d.ts} +0 -0
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { MCPOAuthToken } from './oauth-token-storage.js';
|
|
7
|
+
/**
|
|
8
|
+
* OAuth configuration for an MCP server.
|
|
9
|
+
*/
|
|
10
|
+
export interface MCPOAuthConfig {
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
clientId?: string;
|
|
13
|
+
clientSecret?: string;
|
|
14
|
+
authorizationUrl?: string;
|
|
15
|
+
tokenUrl?: string;
|
|
16
|
+
scopes?: string[];
|
|
17
|
+
redirectUri?: string;
|
|
18
|
+
tokenParamName?: string;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* OAuth authorization response.
|
|
22
|
+
*/
|
|
23
|
+
export interface OAuthAuthorizationResponse {
|
|
24
|
+
code: string;
|
|
25
|
+
state: string;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* OAuth token response from the authorization server.
|
|
29
|
+
*/
|
|
30
|
+
export interface OAuthTokenResponse {
|
|
31
|
+
access_token: string;
|
|
32
|
+
token_type: string;
|
|
33
|
+
expires_in?: number;
|
|
34
|
+
refresh_token?: string;
|
|
35
|
+
scope?: string;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* Dynamic client registration request.
|
|
39
|
+
*/
|
|
40
|
+
export interface OAuthClientRegistrationRequest {
|
|
41
|
+
client_name: string;
|
|
42
|
+
redirect_uris: string[];
|
|
43
|
+
grant_types: string[];
|
|
44
|
+
response_types: string[];
|
|
45
|
+
token_endpoint_auth_method: string;
|
|
46
|
+
code_challenge_method?: string[];
|
|
47
|
+
scope?: string;
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Dynamic client registration response.
|
|
51
|
+
*/
|
|
52
|
+
export interface OAuthClientRegistrationResponse {
|
|
53
|
+
client_id: string;
|
|
54
|
+
client_secret?: string;
|
|
55
|
+
client_id_issued_at?: number;
|
|
56
|
+
client_secret_expires_at?: number;
|
|
57
|
+
redirect_uris: string[];
|
|
58
|
+
grant_types: string[];
|
|
59
|
+
response_types: string[];
|
|
60
|
+
token_endpoint_auth_method: string;
|
|
61
|
+
code_challenge_method?: string[];
|
|
62
|
+
scope?: string;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Provider for handling OAuth authentication for MCP servers.
|
|
66
|
+
*/
|
|
67
|
+
export declare class MCPOAuthProvider {
|
|
68
|
+
private static readonly REDIRECT_PORT;
|
|
69
|
+
private static readonly REDIRECT_PATH;
|
|
70
|
+
private static readonly HTTP_OK;
|
|
71
|
+
private static readonly HTTP_REDIRECT;
|
|
72
|
+
/**
|
|
73
|
+
* Register a client dynamically with the OAuth server.
|
|
74
|
+
*
|
|
75
|
+
* @param registrationUrl The client registration endpoint URL
|
|
76
|
+
* @param config OAuth configuration
|
|
77
|
+
* @returns The registered client information
|
|
78
|
+
*/
|
|
79
|
+
private static registerClient;
|
|
80
|
+
/**
|
|
81
|
+
* Discover OAuth configuration from an MCP server URL.
|
|
82
|
+
*
|
|
83
|
+
* @param mcpServerUrl The MCP server URL
|
|
84
|
+
* @returns OAuth configuration if discovered, null otherwise
|
|
85
|
+
*/
|
|
86
|
+
private static discoverOAuthFromMCPServer;
|
|
87
|
+
/**
|
|
88
|
+
* Generate PKCE parameters for OAuth flow.
|
|
89
|
+
*
|
|
90
|
+
* @returns PKCE parameters including code verifier, challenge, and state
|
|
91
|
+
*/
|
|
92
|
+
private static generatePKCEParams;
|
|
93
|
+
/**
|
|
94
|
+
* Start a local HTTP server to handle OAuth callback.
|
|
95
|
+
*
|
|
96
|
+
* @param expectedState The state parameter to validate
|
|
97
|
+
* @returns Promise that resolves with the authorization code
|
|
98
|
+
*/
|
|
99
|
+
private static startCallbackServer;
|
|
100
|
+
/**
|
|
101
|
+
* Build the authorization URL with PKCE parameters.
|
|
102
|
+
*
|
|
103
|
+
* @param config OAuth configuration
|
|
104
|
+
* @param pkceParams PKCE parameters
|
|
105
|
+
* @returns The authorization URL
|
|
106
|
+
*/
|
|
107
|
+
private static buildAuthorizationUrl;
|
|
108
|
+
/**
|
|
109
|
+
* Exchange authorization code for tokens.
|
|
110
|
+
*
|
|
111
|
+
* @param config OAuth configuration
|
|
112
|
+
* @param code Authorization code
|
|
113
|
+
* @param codeVerifier PKCE code verifier
|
|
114
|
+
* @returns The token response
|
|
115
|
+
*/
|
|
116
|
+
private static exchangeCodeForToken;
|
|
117
|
+
/**
|
|
118
|
+
* Refresh an access token using a refresh token.
|
|
119
|
+
*
|
|
120
|
+
* @param config OAuth configuration
|
|
121
|
+
* @param refreshToken The refresh token
|
|
122
|
+
* @returns The new token response
|
|
123
|
+
*/
|
|
124
|
+
static refreshAccessToken(config: MCPOAuthConfig, refreshToken: string, tokenUrl: string): Promise<OAuthTokenResponse>;
|
|
125
|
+
/**
|
|
126
|
+
* Perform the full OAuth authorization code flow with PKCE.
|
|
127
|
+
*
|
|
128
|
+
* @param serverName The name of the MCP server
|
|
129
|
+
* @param config OAuth configuration
|
|
130
|
+
* @param mcpServerUrl Optional MCP server URL for OAuth discovery
|
|
131
|
+
* @returns The obtained OAuth token
|
|
132
|
+
*/
|
|
133
|
+
static authenticate(serverName: string, config: MCPOAuthConfig, mcpServerUrl?: string): Promise<MCPOAuthToken>;
|
|
134
|
+
/**
|
|
135
|
+
* Get a valid access token for an MCP server, refreshing if necessary.
|
|
136
|
+
*
|
|
137
|
+
* @param serverName The name of the MCP server
|
|
138
|
+
* @param config OAuth configuration
|
|
139
|
+
* @returns A valid access token or null if not authenticated
|
|
140
|
+
*/
|
|
141
|
+
static getValidToken(serverName: string, config: MCPOAuthConfig): Promise<string | null>;
|
|
142
|
+
}
|
|
@@ -0,0 +1,446 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import * as http from 'node:http';
|
|
7
|
+
import * as crypto from 'node:crypto';
|
|
8
|
+
import { URL } from 'node:url';
|
|
9
|
+
import open from 'open';
|
|
10
|
+
import { MCPOAuthTokenStorage } from './oauth-token-storage.js';
|
|
11
|
+
import { getErrorMessage } from '../utils/errors.js';
|
|
12
|
+
import { OAuthUtils } from './oauth-utils.js';
|
|
13
|
+
/**
|
|
14
|
+
* Provider for handling OAuth authentication for MCP servers.
|
|
15
|
+
*/
|
|
16
|
+
export class MCPOAuthProvider {
|
|
17
|
+
static REDIRECT_PORT = 7777;
|
|
18
|
+
static REDIRECT_PATH = '/oauth/callback';
|
|
19
|
+
static HTTP_OK = 200;
|
|
20
|
+
static HTTP_REDIRECT = 302;
|
|
21
|
+
/**
|
|
22
|
+
* Register a client dynamically with the OAuth server.
|
|
23
|
+
*
|
|
24
|
+
* @param registrationUrl The client registration endpoint URL
|
|
25
|
+
* @param config OAuth configuration
|
|
26
|
+
* @returns The registered client information
|
|
27
|
+
*/
|
|
28
|
+
static async registerClient(registrationUrl, config) {
|
|
29
|
+
const redirectUri = config.redirectUri ||
|
|
30
|
+
`http://localhost:${this.REDIRECT_PORT}${this.REDIRECT_PATH}`;
|
|
31
|
+
const registrationRequest = {
|
|
32
|
+
client_name: 'Gemini CLI MCP Client',
|
|
33
|
+
redirect_uris: [redirectUri],
|
|
34
|
+
grant_types: ['authorization_code', 'refresh_token'],
|
|
35
|
+
response_types: ['code'],
|
|
36
|
+
token_endpoint_auth_method: 'none', // Public client
|
|
37
|
+
code_challenge_method: ['S256'],
|
|
38
|
+
scope: config.scopes?.join(' ') || '',
|
|
39
|
+
};
|
|
40
|
+
const response = await fetch(registrationUrl, {
|
|
41
|
+
method: 'POST',
|
|
42
|
+
headers: {
|
|
43
|
+
'Content-Type': 'application/json',
|
|
44
|
+
},
|
|
45
|
+
body: JSON.stringify(registrationRequest),
|
|
46
|
+
});
|
|
47
|
+
if (!response.ok) {
|
|
48
|
+
const errorText = await response.text();
|
|
49
|
+
throw new Error(`Client registration failed: ${response.status} ${response.statusText} - ${errorText}`);
|
|
50
|
+
}
|
|
51
|
+
return (await response.json());
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Discover OAuth configuration from an MCP server URL.
|
|
55
|
+
*
|
|
56
|
+
* @param mcpServerUrl The MCP server URL
|
|
57
|
+
* @returns OAuth configuration if discovered, null otherwise
|
|
58
|
+
*/
|
|
59
|
+
static async discoverOAuthFromMCPServer(mcpServerUrl) {
|
|
60
|
+
const baseUrl = OAuthUtils.extractBaseUrl(mcpServerUrl);
|
|
61
|
+
return OAuthUtils.discoverOAuthConfig(baseUrl);
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Generate PKCE parameters for OAuth flow.
|
|
65
|
+
*
|
|
66
|
+
* @returns PKCE parameters including code verifier, challenge, and state
|
|
67
|
+
*/
|
|
68
|
+
static generatePKCEParams() {
|
|
69
|
+
// Generate code verifier (43-128 characters)
|
|
70
|
+
const codeVerifier = crypto.randomBytes(32).toString('base64url');
|
|
71
|
+
// Generate code challenge using SHA256
|
|
72
|
+
const codeChallenge = crypto
|
|
73
|
+
.createHash('sha256')
|
|
74
|
+
.update(codeVerifier)
|
|
75
|
+
.digest('base64url');
|
|
76
|
+
// Generate state for CSRF protection
|
|
77
|
+
const state = crypto.randomBytes(16).toString('base64url');
|
|
78
|
+
return { codeVerifier, codeChallenge, state };
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Start a local HTTP server to handle OAuth callback.
|
|
82
|
+
*
|
|
83
|
+
* @param expectedState The state parameter to validate
|
|
84
|
+
* @returns Promise that resolves with the authorization code
|
|
85
|
+
*/
|
|
86
|
+
static async startCallbackServer(expectedState) {
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
const server = http.createServer(async (req, res) => {
|
|
89
|
+
try {
|
|
90
|
+
const url = new URL(req.url, `http://localhost:${this.REDIRECT_PORT}`);
|
|
91
|
+
if (url.pathname !== this.REDIRECT_PATH) {
|
|
92
|
+
res.writeHead(404);
|
|
93
|
+
res.end('Not found');
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const code = url.searchParams.get('code');
|
|
97
|
+
const state = url.searchParams.get('state');
|
|
98
|
+
const error = url.searchParams.get('error');
|
|
99
|
+
if (error) {
|
|
100
|
+
res.writeHead(this.HTTP_OK, { 'Content-Type': 'text/html' });
|
|
101
|
+
res.end(`
|
|
102
|
+
<html>
|
|
103
|
+
<body>
|
|
104
|
+
<h1>Authentication Failed</h1>
|
|
105
|
+
<p>Error: ${error.replace(/</g, '<').replace(/>/g, '>')}</p>
|
|
106
|
+
<p>${(url.searchParams.get('error_description') || '').replace(/</g, '<').replace(/>/g, '>')}</p>
|
|
107
|
+
<p>You can close this window.</p>
|
|
108
|
+
</body>
|
|
109
|
+
</html>
|
|
110
|
+
`);
|
|
111
|
+
server.close();
|
|
112
|
+
reject(new Error(`OAuth error: ${error}`));
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (!code || !state) {
|
|
116
|
+
res.writeHead(400);
|
|
117
|
+
res.end('Missing code or state parameter');
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
if (state !== expectedState) {
|
|
121
|
+
res.writeHead(400);
|
|
122
|
+
res.end('Invalid state parameter');
|
|
123
|
+
server.close();
|
|
124
|
+
reject(new Error('State mismatch - possible CSRF attack'));
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
127
|
+
// Send success response to browser
|
|
128
|
+
res.writeHead(this.HTTP_OK, { 'Content-Type': 'text/html' });
|
|
129
|
+
res.end(`
|
|
130
|
+
<html>
|
|
131
|
+
<body>
|
|
132
|
+
<h1>Authentication Successful!</h1>
|
|
133
|
+
<p>You can close this window and return to Gemini CLI.</p>
|
|
134
|
+
<script>window.close();</script>
|
|
135
|
+
</body>
|
|
136
|
+
</html>
|
|
137
|
+
`);
|
|
138
|
+
server.close();
|
|
139
|
+
resolve({ code, state });
|
|
140
|
+
}
|
|
141
|
+
catch (error) {
|
|
142
|
+
server.close();
|
|
143
|
+
reject(error);
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
server.on('error', reject);
|
|
147
|
+
server.listen(this.REDIRECT_PORT, () => {
|
|
148
|
+
console.log(`OAuth callback server listening on port ${this.REDIRECT_PORT}`);
|
|
149
|
+
});
|
|
150
|
+
// Timeout after 5 minutes
|
|
151
|
+
setTimeout(() => {
|
|
152
|
+
server.close();
|
|
153
|
+
reject(new Error('OAuth callback timeout'));
|
|
154
|
+
}, 5 * 60 * 1000);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Build the authorization URL with PKCE parameters.
|
|
159
|
+
*
|
|
160
|
+
* @param config OAuth configuration
|
|
161
|
+
* @param pkceParams PKCE parameters
|
|
162
|
+
* @returns The authorization URL
|
|
163
|
+
*/
|
|
164
|
+
static buildAuthorizationUrl(config, pkceParams) {
|
|
165
|
+
const redirectUri = config.redirectUri ||
|
|
166
|
+
`http://localhost:${this.REDIRECT_PORT}${this.REDIRECT_PATH}`;
|
|
167
|
+
const params = new URLSearchParams({
|
|
168
|
+
client_id: config.clientId,
|
|
169
|
+
response_type: 'code',
|
|
170
|
+
redirect_uri: redirectUri,
|
|
171
|
+
state: pkceParams.state,
|
|
172
|
+
code_challenge: pkceParams.codeChallenge,
|
|
173
|
+
code_challenge_method: 'S256',
|
|
174
|
+
});
|
|
175
|
+
if (config.scopes && config.scopes.length > 0) {
|
|
176
|
+
params.append('scope', config.scopes.join(' '));
|
|
177
|
+
}
|
|
178
|
+
// Add resource parameter for MCP OAuth spec compliance
|
|
179
|
+
params.append('resource', OAuthUtils.buildResourceParameter(config.authorizationUrl));
|
|
180
|
+
return `${config.authorizationUrl}?${params.toString()}`;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Exchange authorization code for tokens.
|
|
184
|
+
*
|
|
185
|
+
* @param config OAuth configuration
|
|
186
|
+
* @param code Authorization code
|
|
187
|
+
* @param codeVerifier PKCE code verifier
|
|
188
|
+
* @returns The token response
|
|
189
|
+
*/
|
|
190
|
+
static async exchangeCodeForToken(config, code, codeVerifier) {
|
|
191
|
+
const redirectUri = config.redirectUri ||
|
|
192
|
+
`http://localhost:${this.REDIRECT_PORT}${this.REDIRECT_PATH}`;
|
|
193
|
+
const params = new URLSearchParams({
|
|
194
|
+
grant_type: 'authorization_code',
|
|
195
|
+
code,
|
|
196
|
+
redirect_uri: redirectUri,
|
|
197
|
+
code_verifier: codeVerifier,
|
|
198
|
+
client_id: config.clientId,
|
|
199
|
+
});
|
|
200
|
+
if (config.clientSecret) {
|
|
201
|
+
params.append('client_secret', config.clientSecret);
|
|
202
|
+
}
|
|
203
|
+
// Add resource parameter for MCP OAuth spec compliance
|
|
204
|
+
params.append('resource', OAuthUtils.buildResourceParameter(config.tokenUrl));
|
|
205
|
+
const response = await fetch(config.tokenUrl, {
|
|
206
|
+
method: 'POST',
|
|
207
|
+
headers: {
|
|
208
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
209
|
+
},
|
|
210
|
+
body: params.toString(),
|
|
211
|
+
});
|
|
212
|
+
if (!response.ok) {
|
|
213
|
+
const errorText = await response.text();
|
|
214
|
+
throw new Error(`Token exchange failed: ${response.status} - ${errorText}`);
|
|
215
|
+
}
|
|
216
|
+
return (await response.json());
|
|
217
|
+
}
|
|
218
|
+
/**
|
|
219
|
+
* Refresh an access token using a refresh token.
|
|
220
|
+
*
|
|
221
|
+
* @param config OAuth configuration
|
|
222
|
+
* @param refreshToken The refresh token
|
|
223
|
+
* @returns The new token response
|
|
224
|
+
*/
|
|
225
|
+
static async refreshAccessToken(config, refreshToken, tokenUrl) {
|
|
226
|
+
const params = new URLSearchParams({
|
|
227
|
+
grant_type: 'refresh_token',
|
|
228
|
+
refresh_token: refreshToken,
|
|
229
|
+
client_id: config.clientId,
|
|
230
|
+
});
|
|
231
|
+
if (config.clientSecret) {
|
|
232
|
+
params.append('client_secret', config.clientSecret);
|
|
233
|
+
}
|
|
234
|
+
if (config.scopes && config.scopes.length > 0) {
|
|
235
|
+
params.append('scope', config.scopes.join(' '));
|
|
236
|
+
}
|
|
237
|
+
// Add resource parameter for MCP OAuth spec compliance
|
|
238
|
+
params.append('resource', OAuthUtils.buildResourceParameter(tokenUrl));
|
|
239
|
+
const response = await fetch(tokenUrl, {
|
|
240
|
+
method: 'POST',
|
|
241
|
+
headers: {
|
|
242
|
+
'Content-Type': 'application/x-www-form-urlencoded',
|
|
243
|
+
},
|
|
244
|
+
body: params.toString(),
|
|
245
|
+
});
|
|
246
|
+
if (!response.ok) {
|
|
247
|
+
const errorText = await response.text();
|
|
248
|
+
throw new Error(`Token refresh failed: ${response.status} - ${errorText}`);
|
|
249
|
+
}
|
|
250
|
+
return (await response.json());
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Perform the full OAuth authorization code flow with PKCE.
|
|
254
|
+
*
|
|
255
|
+
* @param serverName The name of the MCP server
|
|
256
|
+
* @param config OAuth configuration
|
|
257
|
+
* @param mcpServerUrl Optional MCP server URL for OAuth discovery
|
|
258
|
+
* @returns The obtained OAuth token
|
|
259
|
+
*/
|
|
260
|
+
static async authenticate(serverName, config, mcpServerUrl) {
|
|
261
|
+
// If no authorization URL is provided, try to discover OAuth configuration
|
|
262
|
+
if (!config.authorizationUrl && mcpServerUrl) {
|
|
263
|
+
console.log('No authorization URL provided, attempting OAuth discovery...');
|
|
264
|
+
// For SSE URLs, first check if authentication is required
|
|
265
|
+
if (OAuthUtils.isSSEEndpoint(mcpServerUrl)) {
|
|
266
|
+
try {
|
|
267
|
+
const response = await fetch(mcpServerUrl, {
|
|
268
|
+
method: 'HEAD',
|
|
269
|
+
headers: {
|
|
270
|
+
Accept: 'text/event-stream',
|
|
271
|
+
},
|
|
272
|
+
});
|
|
273
|
+
if (response.status === 401 || response.status === 307) {
|
|
274
|
+
const wwwAuthenticate = response.headers.get('www-authenticate');
|
|
275
|
+
if (wwwAuthenticate) {
|
|
276
|
+
const discoveredConfig = await OAuthUtils.discoverOAuthFromWWWAuthenticate(wwwAuthenticate);
|
|
277
|
+
if (discoveredConfig) {
|
|
278
|
+
config = {
|
|
279
|
+
...config,
|
|
280
|
+
...discoveredConfig,
|
|
281
|
+
scopes: discoveredConfig.scopes || config.scopes || [],
|
|
282
|
+
};
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
console.debug(`Failed to check SSE endpoint for authentication requirements: ${getErrorMessage(error)}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
// If we still don't have OAuth config, try the standard discovery
|
|
292
|
+
if (!config.authorizationUrl) {
|
|
293
|
+
const discoveredConfig = await this.discoverOAuthFromMCPServer(mcpServerUrl);
|
|
294
|
+
if (discoveredConfig) {
|
|
295
|
+
config = { ...config, ...discoveredConfig };
|
|
296
|
+
console.log('OAuth configuration discovered successfully');
|
|
297
|
+
}
|
|
298
|
+
else {
|
|
299
|
+
throw new Error('Failed to discover OAuth configuration from MCP server');
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// If no client ID is provided, try dynamic client registration
|
|
304
|
+
if (!config.clientId) {
|
|
305
|
+
// Extract server URL from authorization URL
|
|
306
|
+
if (!config.authorizationUrl) {
|
|
307
|
+
throw new Error('Cannot perform dynamic registration without authorization URL');
|
|
308
|
+
}
|
|
309
|
+
const authUrl = new URL(config.authorizationUrl);
|
|
310
|
+
const serverUrl = `${authUrl.protocol}//${authUrl.host}`;
|
|
311
|
+
console.log('No client ID provided, attempting dynamic client registration...');
|
|
312
|
+
// Get the authorization server metadata for registration
|
|
313
|
+
const authServerMetadataUrl = new URL('/.well-known/oauth-authorization-server', serverUrl).toString();
|
|
314
|
+
const authServerMetadata = await OAuthUtils.fetchAuthorizationServerMetadata(authServerMetadataUrl);
|
|
315
|
+
if (!authServerMetadata) {
|
|
316
|
+
throw new Error('Failed to fetch authorization server metadata for client registration');
|
|
317
|
+
}
|
|
318
|
+
// Register client if registration endpoint is available
|
|
319
|
+
if (authServerMetadata.registration_endpoint) {
|
|
320
|
+
const clientRegistration = await this.registerClient(authServerMetadata.registration_endpoint, config);
|
|
321
|
+
config.clientId = clientRegistration.client_id;
|
|
322
|
+
if (clientRegistration.client_secret) {
|
|
323
|
+
config.clientSecret = clientRegistration.client_secret;
|
|
324
|
+
}
|
|
325
|
+
console.log('Dynamic client registration successful');
|
|
326
|
+
}
|
|
327
|
+
else {
|
|
328
|
+
throw new Error('No client ID provided and dynamic registration not supported');
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
// Validate configuration
|
|
332
|
+
if (!config.clientId || !config.authorizationUrl || !config.tokenUrl) {
|
|
333
|
+
throw new Error('Missing required OAuth configuration after discovery and registration');
|
|
334
|
+
}
|
|
335
|
+
// Generate PKCE parameters
|
|
336
|
+
const pkceParams = this.generatePKCEParams();
|
|
337
|
+
// Build authorization URL
|
|
338
|
+
const authUrl = this.buildAuthorizationUrl(config, pkceParams);
|
|
339
|
+
console.log('\nOpening browser for OAuth authentication...');
|
|
340
|
+
console.log('If the browser does not open, please visit:');
|
|
341
|
+
console.log('');
|
|
342
|
+
// Get terminal width or default to 80
|
|
343
|
+
const terminalWidth = process.stdout.columns || 80;
|
|
344
|
+
const separatorLength = Math.min(terminalWidth - 2, 80);
|
|
345
|
+
const separator = '━'.repeat(separatorLength);
|
|
346
|
+
console.log(separator);
|
|
347
|
+
console.log('COPY THE ENTIRE URL BELOW (select all text between the lines):');
|
|
348
|
+
console.log(separator);
|
|
349
|
+
console.log(authUrl);
|
|
350
|
+
console.log(separator);
|
|
351
|
+
console.log('');
|
|
352
|
+
console.log('💡 TIP: Triple-click to select the entire URL, then copy and paste it into your browser.');
|
|
353
|
+
console.log('⚠️ Make sure to copy the COMPLETE URL - it may wrap across multiple lines.');
|
|
354
|
+
console.log('');
|
|
355
|
+
// Start callback server
|
|
356
|
+
const callbackPromise = this.startCallbackServer(pkceParams.state);
|
|
357
|
+
// Open browser
|
|
358
|
+
try {
|
|
359
|
+
await open(authUrl);
|
|
360
|
+
}
|
|
361
|
+
catch (error) {
|
|
362
|
+
console.warn('Failed to open browser automatically:', getErrorMessage(error));
|
|
363
|
+
}
|
|
364
|
+
// Wait for callback
|
|
365
|
+
const { code } = await callbackPromise;
|
|
366
|
+
console.log('\nAuthorization code received, exchanging for tokens...');
|
|
367
|
+
// Exchange code for tokens
|
|
368
|
+
const tokenResponse = await this.exchangeCodeForToken(config, code, pkceParams.codeVerifier);
|
|
369
|
+
// Convert to our token format
|
|
370
|
+
const token = {
|
|
371
|
+
accessToken: tokenResponse.access_token,
|
|
372
|
+
tokenType: tokenResponse.token_type,
|
|
373
|
+
refreshToken: tokenResponse.refresh_token,
|
|
374
|
+
scope: tokenResponse.scope,
|
|
375
|
+
};
|
|
376
|
+
if (tokenResponse.expires_in) {
|
|
377
|
+
token.expiresAt = Date.now() + tokenResponse.expires_in * 1000;
|
|
378
|
+
}
|
|
379
|
+
// Save token
|
|
380
|
+
try {
|
|
381
|
+
await MCPOAuthTokenStorage.saveToken(serverName, token, config.clientId, config.tokenUrl);
|
|
382
|
+
console.log('Authentication successful! Token saved.');
|
|
383
|
+
// Verify token was saved
|
|
384
|
+
const savedToken = await MCPOAuthTokenStorage.getToken(serverName);
|
|
385
|
+
if (savedToken) {
|
|
386
|
+
console.log(`Token verification successful: ${savedToken.token.accessToken.substring(0, 20)}...`);
|
|
387
|
+
}
|
|
388
|
+
else {
|
|
389
|
+
console.error('Token verification failed: token not found after save');
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
catch (saveError) {
|
|
393
|
+
console.error(`Failed to save token: ${getErrorMessage(saveError)}`);
|
|
394
|
+
throw saveError;
|
|
395
|
+
}
|
|
396
|
+
return token;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Get a valid access token for an MCP server, refreshing if necessary.
|
|
400
|
+
*
|
|
401
|
+
* @param serverName The name of the MCP server
|
|
402
|
+
* @param config OAuth configuration
|
|
403
|
+
* @returns A valid access token or null if not authenticated
|
|
404
|
+
*/
|
|
405
|
+
static async getValidToken(serverName, config) {
|
|
406
|
+
console.debug(`Getting valid token for server: ${serverName}`);
|
|
407
|
+
const credentials = await MCPOAuthTokenStorage.getToken(serverName);
|
|
408
|
+
if (!credentials) {
|
|
409
|
+
console.debug(`No credentials found for server: ${serverName}`);
|
|
410
|
+
return null;
|
|
411
|
+
}
|
|
412
|
+
const { token } = credentials;
|
|
413
|
+
console.debug(`Found token for server: ${serverName}, expired: ${MCPOAuthTokenStorage.isTokenExpired(token)}`);
|
|
414
|
+
// Check if token is expired
|
|
415
|
+
if (!MCPOAuthTokenStorage.isTokenExpired(token)) {
|
|
416
|
+
console.debug(`Returning valid token for server: ${serverName}`);
|
|
417
|
+
return token.accessToken;
|
|
418
|
+
}
|
|
419
|
+
// Try to refresh if we have a refresh token
|
|
420
|
+
if (token.refreshToken && config.clientId && credentials.tokenUrl) {
|
|
421
|
+
try {
|
|
422
|
+
console.log(`Refreshing expired token for MCP server: ${serverName}`);
|
|
423
|
+
const newTokenResponse = await this.refreshAccessToken(config, token.refreshToken, credentials.tokenUrl);
|
|
424
|
+
// Update stored token
|
|
425
|
+
const newToken = {
|
|
426
|
+
accessToken: newTokenResponse.access_token,
|
|
427
|
+
tokenType: newTokenResponse.token_type,
|
|
428
|
+
refreshToken: newTokenResponse.refresh_token || token.refreshToken,
|
|
429
|
+
scope: newTokenResponse.scope || token.scope,
|
|
430
|
+
};
|
|
431
|
+
if (newTokenResponse.expires_in) {
|
|
432
|
+
newToken.expiresAt = Date.now() + newTokenResponse.expires_in * 1000;
|
|
433
|
+
}
|
|
434
|
+
await MCPOAuthTokenStorage.saveToken(serverName, newToken, config.clientId, credentials.tokenUrl);
|
|
435
|
+
return newToken.accessToken;
|
|
436
|
+
}
|
|
437
|
+
catch (error) {
|
|
438
|
+
console.error(`Failed to refresh token: ${getErrorMessage(error)}`);
|
|
439
|
+
// Remove invalid token
|
|
440
|
+
await MCPOAuthTokenStorage.removeToken(serverName);
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
return null;
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
//# sourceMappingURL=oauth-provider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-provider.js","sourceRoot":"","sources":["../../../src/mcp/oauth-provider.ts"],"names":[],"mappings":"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"}
|