@vybestack/llxprt-code-core 0.1.12 → 0.1.13-hotfix1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/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 +523 -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,149 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { promises as fs } from 'node:fs';
|
|
7
|
+
import * as path from 'node:path';
|
|
8
|
+
import * as os from 'node:os';
|
|
9
|
+
import { getErrorMessage } from '../utils/errors.js';
|
|
10
|
+
/**
|
|
11
|
+
* Class for managing MCP OAuth token storage and retrieval.
|
|
12
|
+
*/
|
|
13
|
+
export class MCPOAuthTokenStorage {
|
|
14
|
+
static TOKEN_FILE = 'mcp-oauth-tokens.json';
|
|
15
|
+
static CONFIG_DIR = '.gemini';
|
|
16
|
+
/**
|
|
17
|
+
* Get the path to the token storage file.
|
|
18
|
+
*
|
|
19
|
+
* @returns The full path to the token storage file
|
|
20
|
+
*/
|
|
21
|
+
static getTokenFilePath() {
|
|
22
|
+
const homeDir = os.homedir();
|
|
23
|
+
return path.join(homeDir, this.CONFIG_DIR, this.TOKEN_FILE);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Ensure the config directory exists.
|
|
27
|
+
*/
|
|
28
|
+
static async ensureConfigDir() {
|
|
29
|
+
const configDir = path.dirname(this.getTokenFilePath());
|
|
30
|
+
await fs.mkdir(configDir, { recursive: true });
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Load all stored MCP OAuth tokens.
|
|
34
|
+
*
|
|
35
|
+
* @returns A map of server names to credentials
|
|
36
|
+
*/
|
|
37
|
+
static async loadTokens() {
|
|
38
|
+
const tokenMap = new Map();
|
|
39
|
+
try {
|
|
40
|
+
const tokenFile = this.getTokenFilePath();
|
|
41
|
+
const data = await fs.readFile(tokenFile, 'utf-8');
|
|
42
|
+
const tokens = JSON.parse(data);
|
|
43
|
+
for (const credential of tokens) {
|
|
44
|
+
tokenMap.set(credential.serverName, credential);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch (error) {
|
|
48
|
+
// File doesn't exist or is invalid, return empty map
|
|
49
|
+
if (error.code !== 'ENOENT') {
|
|
50
|
+
console.error(`Failed to load MCP OAuth tokens: ${getErrorMessage(error)}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return tokenMap;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Save a token for a specific MCP server.
|
|
57
|
+
*
|
|
58
|
+
* @param serverName The name of the MCP server
|
|
59
|
+
* @param token The OAuth token to save
|
|
60
|
+
* @param clientId Optional client ID used for this token
|
|
61
|
+
* @param tokenUrl Optional token URL used for this token
|
|
62
|
+
*/
|
|
63
|
+
static async saveToken(serverName, token, clientId, tokenUrl) {
|
|
64
|
+
await this.ensureConfigDir();
|
|
65
|
+
const tokens = await this.loadTokens();
|
|
66
|
+
const credential = {
|
|
67
|
+
serverName,
|
|
68
|
+
token,
|
|
69
|
+
clientId,
|
|
70
|
+
tokenUrl,
|
|
71
|
+
updatedAt: Date.now(),
|
|
72
|
+
};
|
|
73
|
+
tokens.set(serverName, credential);
|
|
74
|
+
const tokenArray = Array.from(tokens.values());
|
|
75
|
+
const tokenFile = this.getTokenFilePath();
|
|
76
|
+
try {
|
|
77
|
+
await fs.writeFile(tokenFile, JSON.stringify(tokenArray, null, 2), { mode: 0o600 });
|
|
78
|
+
}
|
|
79
|
+
catch (error) {
|
|
80
|
+
console.error(`Failed to save MCP OAuth token: ${getErrorMessage(error)}`);
|
|
81
|
+
throw error;
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Get a token for a specific MCP server.
|
|
86
|
+
*
|
|
87
|
+
* @param serverName The name of the MCP server
|
|
88
|
+
* @returns The stored credentials or null if not found
|
|
89
|
+
*/
|
|
90
|
+
static async getToken(serverName) {
|
|
91
|
+
const tokens = await this.loadTokens();
|
|
92
|
+
return tokens.get(serverName) || null;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Remove a token for a specific MCP server.
|
|
96
|
+
*
|
|
97
|
+
* @param serverName The name of the MCP server
|
|
98
|
+
*/
|
|
99
|
+
static async removeToken(serverName) {
|
|
100
|
+
const tokens = await this.loadTokens();
|
|
101
|
+
if (tokens.delete(serverName)) {
|
|
102
|
+
const tokenArray = Array.from(tokens.values());
|
|
103
|
+
const tokenFile = this.getTokenFilePath();
|
|
104
|
+
try {
|
|
105
|
+
if (tokenArray.length === 0) {
|
|
106
|
+
// Remove file if no tokens left
|
|
107
|
+
await fs.unlink(tokenFile);
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
await fs.writeFile(tokenFile, JSON.stringify(tokenArray, null, 2), {
|
|
111
|
+
mode: 0o600,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
console.error(`Failed to remove MCP OAuth token: ${getErrorMessage(error)}`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* Check if a token is expired.
|
|
122
|
+
*
|
|
123
|
+
* @param token The token to check
|
|
124
|
+
* @returns True if the token is expired
|
|
125
|
+
*/
|
|
126
|
+
static isTokenExpired(token) {
|
|
127
|
+
if (!token.expiresAt) {
|
|
128
|
+
return false; // No expiry, assume valid
|
|
129
|
+
}
|
|
130
|
+
// Add a 5-minute buffer to account for clock skew
|
|
131
|
+
const bufferMs = 5 * 60 * 1000;
|
|
132
|
+
return Date.now() + bufferMs >= token.expiresAt;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Clear all stored MCP OAuth tokens.
|
|
136
|
+
*/
|
|
137
|
+
static async clearAllTokens() {
|
|
138
|
+
try {
|
|
139
|
+
const tokenFile = this.getTokenFilePath();
|
|
140
|
+
await fs.unlink(tokenFile);
|
|
141
|
+
}
|
|
142
|
+
catch (error) {
|
|
143
|
+
if (error.code !== 'ENOENT') {
|
|
144
|
+
console.error(`Failed to clear MCP OAuth tokens: ${getErrorMessage(error)}`);
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
//# sourceMappingURL=oauth-token-storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-token-storage.js","sourceRoot":"","sources":["../../../src/mcp/oauth-token-storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
7
|
+
import { promises as fs } from 'node:fs';
|
|
8
|
+
import * as path from 'node:path';
|
|
9
|
+
import { MCPOAuthTokenStorage, } from './oauth-token-storage.js';
|
|
10
|
+
// Mock file system operations
|
|
11
|
+
vi.mock('node:fs', () => ({
|
|
12
|
+
promises: {
|
|
13
|
+
readFile: vi.fn(),
|
|
14
|
+
writeFile: vi.fn(),
|
|
15
|
+
mkdir: vi.fn(),
|
|
16
|
+
unlink: vi.fn(),
|
|
17
|
+
},
|
|
18
|
+
}));
|
|
19
|
+
vi.mock('node:os', () => ({
|
|
20
|
+
homedir: vi.fn(() => '/mock/home'),
|
|
21
|
+
}));
|
|
22
|
+
describe('MCPOAuthTokenStorage', () => {
|
|
23
|
+
const mockToken = {
|
|
24
|
+
accessToken: 'access_token_123',
|
|
25
|
+
refreshToken: 'refresh_token_456',
|
|
26
|
+
tokenType: 'Bearer',
|
|
27
|
+
scope: 'read write',
|
|
28
|
+
expiresAt: Date.now() + 3600000, // 1 hour from now
|
|
29
|
+
};
|
|
30
|
+
const mockCredentials = {
|
|
31
|
+
serverName: 'test-server',
|
|
32
|
+
token: mockToken,
|
|
33
|
+
clientId: 'test-client-id',
|
|
34
|
+
tokenUrl: 'https://auth.example.com/token',
|
|
35
|
+
updatedAt: Date.now(),
|
|
36
|
+
};
|
|
37
|
+
beforeEach(() => {
|
|
38
|
+
vi.clearAllMocks();
|
|
39
|
+
vi.spyOn(console, 'error').mockImplementation(() => { });
|
|
40
|
+
});
|
|
41
|
+
afterEach(() => {
|
|
42
|
+
vi.restoreAllMocks();
|
|
43
|
+
});
|
|
44
|
+
describe('loadTokens', () => {
|
|
45
|
+
it('should return empty map when token file does not exist', async () => {
|
|
46
|
+
vi.mocked(fs.readFile).mockRejectedValue({ code: 'ENOENT' });
|
|
47
|
+
const tokens = await MCPOAuthTokenStorage.loadTokens();
|
|
48
|
+
expect(tokens.size).toBe(0);
|
|
49
|
+
expect(console.error).not.toHaveBeenCalled();
|
|
50
|
+
});
|
|
51
|
+
it('should load tokens from file successfully', async () => {
|
|
52
|
+
const tokensArray = [mockCredentials];
|
|
53
|
+
vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify(tokensArray));
|
|
54
|
+
const tokens = await MCPOAuthTokenStorage.loadTokens();
|
|
55
|
+
expect(tokens.size).toBe(1);
|
|
56
|
+
expect(tokens.get('test-server')).toEqual(mockCredentials);
|
|
57
|
+
expect(fs.readFile).toHaveBeenCalledWith(path.join('/mock/home', '.gemini', 'mcp-oauth-tokens.json'), 'utf-8');
|
|
58
|
+
});
|
|
59
|
+
it('should handle corrupted token file gracefully', async () => {
|
|
60
|
+
vi.mocked(fs.readFile).mockResolvedValue('invalid json');
|
|
61
|
+
const tokens = await MCPOAuthTokenStorage.loadTokens();
|
|
62
|
+
expect(tokens.size).toBe(0);
|
|
63
|
+
expect(console.error).toHaveBeenCalledWith(expect.stringContaining('Failed to load MCP OAuth tokens'));
|
|
64
|
+
});
|
|
65
|
+
it('should handle file read errors other than ENOENT', async () => {
|
|
66
|
+
const error = new Error('Permission denied');
|
|
67
|
+
vi.mocked(fs.readFile).mockRejectedValue(error);
|
|
68
|
+
const tokens = await MCPOAuthTokenStorage.loadTokens();
|
|
69
|
+
expect(tokens.size).toBe(0);
|
|
70
|
+
expect(console.error).toHaveBeenCalledWith(expect.stringContaining('Failed to load MCP OAuth tokens'));
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe('saveToken', () => {
|
|
74
|
+
it('should save token with restricted permissions', async () => {
|
|
75
|
+
vi.mocked(fs.readFile).mockRejectedValue({ code: 'ENOENT' });
|
|
76
|
+
vi.mocked(fs.mkdir).mockResolvedValue(undefined);
|
|
77
|
+
vi.mocked(fs.writeFile).mockResolvedValue(undefined);
|
|
78
|
+
await MCPOAuthTokenStorage.saveToken('test-server', mockToken, 'client-id', 'https://token.url');
|
|
79
|
+
expect(fs.mkdir).toHaveBeenCalledWith(path.join('/mock/home', '.gemini'), { recursive: true });
|
|
80
|
+
expect(fs.writeFile).toHaveBeenCalledWith(path.join('/mock/home', '.gemini', 'mcp-oauth-tokens.json'), expect.stringContaining('test-server'), { mode: 0o600 });
|
|
81
|
+
});
|
|
82
|
+
it('should update existing token for same server', async () => {
|
|
83
|
+
const existingCredentials = {
|
|
84
|
+
...mockCredentials,
|
|
85
|
+
serverName: 'existing-server',
|
|
86
|
+
};
|
|
87
|
+
vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify([existingCredentials]));
|
|
88
|
+
vi.mocked(fs.writeFile).mockResolvedValue(undefined);
|
|
89
|
+
const newToken = { ...mockToken, accessToken: 'new_access_token' };
|
|
90
|
+
await MCPOAuthTokenStorage.saveToken('existing-server', newToken);
|
|
91
|
+
const writeCall = vi.mocked(fs.writeFile).mock.calls[0];
|
|
92
|
+
const savedData = JSON.parse(writeCall[1]);
|
|
93
|
+
expect(savedData).toHaveLength(1);
|
|
94
|
+
expect(savedData[0].token.accessToken).toBe('new_access_token');
|
|
95
|
+
expect(savedData[0].serverName).toBe('existing-server');
|
|
96
|
+
});
|
|
97
|
+
it('should handle write errors gracefully', async () => {
|
|
98
|
+
vi.mocked(fs.readFile).mockRejectedValue({ code: 'ENOENT' });
|
|
99
|
+
vi.mocked(fs.mkdir).mockResolvedValue(undefined);
|
|
100
|
+
const writeError = new Error('Disk full');
|
|
101
|
+
vi.mocked(fs.writeFile).mockRejectedValue(writeError);
|
|
102
|
+
await expect(MCPOAuthTokenStorage.saveToken('test-server', mockToken)).rejects.toThrow('Disk full');
|
|
103
|
+
expect(console.error).toHaveBeenCalledWith(expect.stringContaining('Failed to save MCP OAuth token'));
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
describe('getToken', () => {
|
|
107
|
+
it('should return token for existing server', async () => {
|
|
108
|
+
vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify([mockCredentials]));
|
|
109
|
+
const result = await MCPOAuthTokenStorage.getToken('test-server');
|
|
110
|
+
expect(result).toEqual(mockCredentials);
|
|
111
|
+
});
|
|
112
|
+
it('should return null for non-existent server', async () => {
|
|
113
|
+
vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify([mockCredentials]));
|
|
114
|
+
const result = await MCPOAuthTokenStorage.getToken('non-existent');
|
|
115
|
+
expect(result).toBeNull();
|
|
116
|
+
});
|
|
117
|
+
it('should return null when no tokens file exists', async () => {
|
|
118
|
+
vi.mocked(fs.readFile).mockRejectedValue({ code: 'ENOENT' });
|
|
119
|
+
const result = await MCPOAuthTokenStorage.getToken('test-server');
|
|
120
|
+
expect(result).toBeNull();
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
describe('removeToken', () => {
|
|
124
|
+
it('should remove token for specific server', async () => {
|
|
125
|
+
const credentials1 = { ...mockCredentials, serverName: 'server1' };
|
|
126
|
+
const credentials2 = { ...mockCredentials, serverName: 'server2' };
|
|
127
|
+
vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify([credentials1, credentials2]));
|
|
128
|
+
vi.mocked(fs.writeFile).mockResolvedValue(undefined);
|
|
129
|
+
await MCPOAuthTokenStorage.removeToken('server1');
|
|
130
|
+
const writeCall = vi.mocked(fs.writeFile).mock.calls[0];
|
|
131
|
+
const savedData = JSON.parse(writeCall[1]);
|
|
132
|
+
expect(savedData).toHaveLength(1);
|
|
133
|
+
expect(savedData[0].serverName).toBe('server2');
|
|
134
|
+
});
|
|
135
|
+
it('should remove token file when no tokens remain', async () => {
|
|
136
|
+
vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify([mockCredentials]));
|
|
137
|
+
vi.mocked(fs.unlink).mockResolvedValue(undefined);
|
|
138
|
+
await MCPOAuthTokenStorage.removeToken('test-server');
|
|
139
|
+
expect(fs.unlink).toHaveBeenCalledWith(path.join('/mock/home', '.gemini', 'mcp-oauth-tokens.json'));
|
|
140
|
+
expect(fs.writeFile).not.toHaveBeenCalled();
|
|
141
|
+
});
|
|
142
|
+
it('should handle removal of non-existent token gracefully', async () => {
|
|
143
|
+
vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify([mockCredentials]));
|
|
144
|
+
await MCPOAuthTokenStorage.removeToken('non-existent');
|
|
145
|
+
expect(fs.writeFile).not.toHaveBeenCalled();
|
|
146
|
+
expect(fs.unlink).not.toHaveBeenCalled();
|
|
147
|
+
});
|
|
148
|
+
it('should handle file operation errors gracefully', async () => {
|
|
149
|
+
vi.mocked(fs.readFile).mockResolvedValue(JSON.stringify([mockCredentials]));
|
|
150
|
+
vi.mocked(fs.unlink).mockRejectedValue(new Error('Permission denied'));
|
|
151
|
+
await MCPOAuthTokenStorage.removeToken('test-server');
|
|
152
|
+
expect(console.error).toHaveBeenCalledWith(expect.stringContaining('Failed to remove MCP OAuth token'));
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
describe('isTokenExpired', () => {
|
|
156
|
+
it('should return false for token without expiry', () => {
|
|
157
|
+
const tokenWithoutExpiry = { ...mockToken };
|
|
158
|
+
delete tokenWithoutExpiry.expiresAt;
|
|
159
|
+
const result = MCPOAuthTokenStorage.isTokenExpired(tokenWithoutExpiry);
|
|
160
|
+
expect(result).toBe(false);
|
|
161
|
+
});
|
|
162
|
+
it('should return false for valid token', () => {
|
|
163
|
+
const futureToken = {
|
|
164
|
+
...mockToken,
|
|
165
|
+
expiresAt: Date.now() + 3600000, // 1 hour from now
|
|
166
|
+
};
|
|
167
|
+
const result = MCPOAuthTokenStorage.isTokenExpired(futureToken);
|
|
168
|
+
expect(result).toBe(false);
|
|
169
|
+
});
|
|
170
|
+
it('should return true for expired token', () => {
|
|
171
|
+
const expiredToken = {
|
|
172
|
+
...mockToken,
|
|
173
|
+
expiresAt: Date.now() - 3600000, // 1 hour ago
|
|
174
|
+
};
|
|
175
|
+
const result = MCPOAuthTokenStorage.isTokenExpired(expiredToken);
|
|
176
|
+
expect(result).toBe(true);
|
|
177
|
+
});
|
|
178
|
+
it('should return true for token expiring within buffer time', () => {
|
|
179
|
+
const soonToExpireToken = {
|
|
180
|
+
...mockToken,
|
|
181
|
+
expiresAt: Date.now() + 60000, // 1 minute from now (within 5-minute buffer)
|
|
182
|
+
};
|
|
183
|
+
const result = MCPOAuthTokenStorage.isTokenExpired(soonToExpireToken);
|
|
184
|
+
expect(result).toBe(true);
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
describe('clearAllTokens', () => {
|
|
188
|
+
it('should remove token file successfully', async () => {
|
|
189
|
+
vi.mocked(fs.unlink).mockResolvedValue(undefined);
|
|
190
|
+
await MCPOAuthTokenStorage.clearAllTokens();
|
|
191
|
+
expect(fs.unlink).toHaveBeenCalledWith(path.join('/mock/home', '.gemini', 'mcp-oauth-tokens.json'));
|
|
192
|
+
});
|
|
193
|
+
it('should handle non-existent file gracefully', async () => {
|
|
194
|
+
vi.mocked(fs.unlink).mockRejectedValue({ code: 'ENOENT' });
|
|
195
|
+
await MCPOAuthTokenStorage.clearAllTokens();
|
|
196
|
+
expect(console.error).not.toHaveBeenCalled();
|
|
197
|
+
});
|
|
198
|
+
it('should handle other file errors gracefully', async () => {
|
|
199
|
+
vi.mocked(fs.unlink).mockRejectedValue(new Error('Permission denied'));
|
|
200
|
+
await MCPOAuthTokenStorage.clearAllTokens();
|
|
201
|
+
expect(console.error).toHaveBeenCalledWith(expect.stringContaining('Failed to clear MCP OAuth tokens'));
|
|
202
|
+
});
|
|
203
|
+
});
|
|
204
|
+
});
|
|
205
|
+
//# sourceMappingURL=oauth-token-storage.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"oauth-token-storage.test.js","sourceRoot":"","sources":["../../../src/mcp/oauth-token-storage.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { MCPOAuthConfig } from './oauth-provider.js';
|
|
7
|
+
/**
|
|
8
|
+
* OAuth authorization server metadata as per RFC 8414.
|
|
9
|
+
*/
|
|
10
|
+
export interface OAuthAuthorizationServerMetadata {
|
|
11
|
+
issuer: string;
|
|
12
|
+
authorization_endpoint: string;
|
|
13
|
+
token_endpoint: string;
|
|
14
|
+
token_endpoint_auth_methods_supported?: string[];
|
|
15
|
+
revocation_endpoint?: string;
|
|
16
|
+
revocation_endpoint_auth_methods_supported?: string[];
|
|
17
|
+
registration_endpoint?: string;
|
|
18
|
+
response_types_supported?: string[];
|
|
19
|
+
grant_types_supported?: string[];
|
|
20
|
+
code_challenge_methods_supported?: string[];
|
|
21
|
+
scopes_supported?: string[];
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* OAuth protected resource metadata as per RFC 9728.
|
|
25
|
+
*/
|
|
26
|
+
export interface OAuthProtectedResourceMetadata {
|
|
27
|
+
resource: string;
|
|
28
|
+
authorization_servers?: string[];
|
|
29
|
+
bearer_methods_supported?: string[];
|
|
30
|
+
resource_documentation?: string;
|
|
31
|
+
resource_signing_alg_values_supported?: string[];
|
|
32
|
+
resource_encryption_alg_values_supported?: string[];
|
|
33
|
+
resource_encryption_enc_values_supported?: string[];
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Utility class for common OAuth operations.
|
|
37
|
+
*/
|
|
38
|
+
export declare class OAuthUtils {
|
|
39
|
+
/**
|
|
40
|
+
* Construct well-known OAuth endpoint URLs.
|
|
41
|
+
*/
|
|
42
|
+
static buildWellKnownUrls(baseUrl: string): {
|
|
43
|
+
protectedResource: string;
|
|
44
|
+
authorizationServer: string;
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* Fetch OAuth protected resource metadata.
|
|
48
|
+
*
|
|
49
|
+
* @param resourceMetadataUrl The protected resource metadata URL
|
|
50
|
+
* @returns The protected resource metadata or null if not available
|
|
51
|
+
*/
|
|
52
|
+
static fetchProtectedResourceMetadata(resourceMetadataUrl: string): Promise<OAuthProtectedResourceMetadata | null>;
|
|
53
|
+
/**
|
|
54
|
+
* Fetch OAuth authorization server metadata.
|
|
55
|
+
*
|
|
56
|
+
* @param authServerMetadataUrl The authorization server metadata URL
|
|
57
|
+
* @returns The authorization server metadata or null if not available
|
|
58
|
+
*/
|
|
59
|
+
static fetchAuthorizationServerMetadata(authServerMetadataUrl: string): Promise<OAuthAuthorizationServerMetadata | null>;
|
|
60
|
+
/**
|
|
61
|
+
* Convert authorization server metadata to OAuth configuration.
|
|
62
|
+
*
|
|
63
|
+
* @param metadata The authorization server metadata
|
|
64
|
+
* @returns The OAuth configuration
|
|
65
|
+
*/
|
|
66
|
+
static metadataToOAuthConfig(metadata: OAuthAuthorizationServerMetadata): MCPOAuthConfig;
|
|
67
|
+
/**
|
|
68
|
+
* Discover OAuth configuration using the standard well-known endpoints.
|
|
69
|
+
*
|
|
70
|
+
* @param serverUrl The base URL of the server
|
|
71
|
+
* @returns The discovered OAuth configuration or null if not available
|
|
72
|
+
*/
|
|
73
|
+
static discoverOAuthConfig(serverUrl: string): Promise<MCPOAuthConfig | null>;
|
|
74
|
+
/**
|
|
75
|
+
* Parse WWW-Authenticate header to extract OAuth information.
|
|
76
|
+
*
|
|
77
|
+
* @param header The WWW-Authenticate header value
|
|
78
|
+
* @returns The resource metadata URI if found
|
|
79
|
+
*/
|
|
80
|
+
static parseWWWAuthenticateHeader(header: string): string | null;
|
|
81
|
+
/**
|
|
82
|
+
* Discover OAuth configuration from WWW-Authenticate header.
|
|
83
|
+
*
|
|
84
|
+
* @param wwwAuthenticate The WWW-Authenticate header value
|
|
85
|
+
* @returns The discovered OAuth configuration or null if not available
|
|
86
|
+
*/
|
|
87
|
+
static discoverOAuthFromWWWAuthenticate(wwwAuthenticate: string): Promise<MCPOAuthConfig | null>;
|
|
88
|
+
/**
|
|
89
|
+
* Extract base URL from an MCP server URL.
|
|
90
|
+
*
|
|
91
|
+
* @param mcpServerUrl The MCP server URL
|
|
92
|
+
* @returns The base URL
|
|
93
|
+
*/
|
|
94
|
+
static extractBaseUrl(mcpServerUrl: string): string;
|
|
95
|
+
/**
|
|
96
|
+
* Check if a URL is an SSE endpoint.
|
|
97
|
+
*
|
|
98
|
+
* @param url The URL to check
|
|
99
|
+
* @returns True if the URL appears to be an SSE endpoint
|
|
100
|
+
*/
|
|
101
|
+
static isSSEEndpoint(url: string): boolean;
|
|
102
|
+
/**
|
|
103
|
+
* Build a resource parameter for OAuth requests.
|
|
104
|
+
*
|
|
105
|
+
* @param endpointUrl The endpoint URL
|
|
106
|
+
* @returns The resource parameter value
|
|
107
|
+
*/
|
|
108
|
+
static buildResourceParameter(endpointUrl: string): string;
|
|
109
|
+
}
|