@machina.ai/cell-cli-core 1.0.17-rc1 → 1.0.21-rc2
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/index.d.ts +3 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- package/dist/package.json +9 -2
- package/dist/src/code_assist/converter.d.ts +4 -2
- package/dist/src/code_assist/converter.js +2 -1
- package/dist/src/code_assist/converter.js.map +1 -1
- package/dist/src/code_assist/converter.test.js +48 -1
- package/dist/src/code_assist/converter.test.js.map +1 -1
- package/dist/src/code_assist/oauth2.d.ts +1 -0
- package/dist/src/code_assist/oauth2.js +38 -21
- package/dist/src/code_assist/oauth2.js.map +1 -1
- package/dist/src/code_assist/oauth2.test.js +51 -8
- package/dist/src/code_assist/oauth2.test.js.map +1 -1
- package/dist/src/code_assist/server.js +1 -1
- package/dist/src/code_assist/server.js.map +1 -1
- package/dist/src/code_assist/server.test.js +4 -1
- package/dist/src/code_assist/server.test.js.map +1 -1
- package/dist/src/code_assist/setup.js +48 -17
- package/dist/src/code_assist/setup.js.map +1 -1
- package/dist/src/code_assist/setup.test.js +114 -8
- package/dist/src/code_assist/setup.test.js.map +1 -1
- package/dist/src/config/config.d.ts +41 -11
- package/dist/src/config/config.js +85 -27
- package/dist/src/config/config.js.map +1 -1
- package/dist/src/config/config.test.js +117 -3
- package/dist/src/config/config.test.js.map +1 -1
- package/dist/src/config/flashFallback.test.js +0 -4
- package/dist/src/config/flashFallback.test.js.map +1 -1
- package/dist/src/core/client.d.ts +12 -16
- package/dist/src/core/client.js +218 -135
- package/dist/src/core/client.js.map +1 -1
- package/dist/src/core/client.test.js +636 -37
- package/dist/src/core/client.test.js.map +1 -1
- package/dist/src/core/contentGenerator.js +23 -21
- package/dist/src/core/contentGenerator.js.map +1 -1
- package/dist/src/core/contentGenerator.test.js +30 -126
- package/dist/src/core/contentGenerator.test.js.map +1 -1
- package/dist/src/core/coreToolScheduler.d.ts +23 -8
- package/dist/src/core/coreToolScheduler.js +179 -64
- package/dist/src/core/coreToolScheduler.js.map +1 -1
- package/dist/src/core/coreToolScheduler.test.js +250 -97
- package/dist/src/core/coreToolScheduler.test.js.map +1 -1
- package/dist/src/core/geminiChat.d.ts +7 -6
- package/dist/src/core/geminiChat.js +43 -43
- package/dist/src/core/geminiChat.js.map +1 -1
- package/dist/src/core/logger.d.ts +23 -1
- package/dist/src/core/logger.js +115 -11
- package/dist/src/core/logger.js.map +1 -1
- package/dist/src/core/logger.test.js +112 -17
- package/dist/src/core/logger.test.js.map +1 -1
- package/dist/src/core/loggingContentGenerator.d.ts +25 -0
- package/dist/src/core/loggingContentGenerator.js +95 -0
- package/dist/src/core/loggingContentGenerator.js.map +1 -0
- package/dist/src/core/nonInteractiveToolExecutor.js +28 -1
- package/dist/src/core/nonInteractiveToolExecutor.js.map +1 -1
- package/dist/src/core/nonInteractiveToolExecutor.test.js +85 -62
- package/dist/src/core/nonInteractiveToolExecutor.test.js.map +1 -1
- package/dist/src/core/prompts.js +4 -4
- package/dist/src/core/prompts.js.map +1 -1
- package/dist/src/core/subagent.d.ts +230 -0
- package/dist/src/core/subagent.js +447 -0
- package/dist/src/core/subagent.js.map +1 -0
- package/dist/src/core/subagent.test.d.ts +6 -0
- package/dist/src/core/subagent.test.js +515 -0
- package/dist/src/core/subagent.test.js.map +1 -0
- package/dist/src/core/turn.js +1 -0
- package/dist/src/core/turn.js.map +1 -1
- package/dist/src/core/turn.test.js +4 -0
- package/dist/src/core/turn.test.js.map +1 -1
- package/dist/src/generated/git-commit.d.ts +7 -0
- package/dist/src/generated/git-commit.js +10 -0
- package/dist/src/generated/git-commit.js.map +1 -0
- package/dist/src/ide/constants.d.ts +6 -0
- package/dist/src/ide/constants.js +7 -0
- package/dist/src/ide/constants.js.map +1 -0
- package/dist/src/ide/detect-ide.d.ts +12 -2
- package/dist/src/ide/detect-ide.js +64 -5
- package/dist/src/ide/detect-ide.js.map +1 -1
- package/dist/src/ide/detect-ide.test.d.ts +6 -0
- package/dist/src/ide/detect-ide.test.js +65 -0
- package/dist/src/ide/detect-ide.test.js.map +1 -0
- package/dist/src/ide/ide-client.d.ts +34 -11
- package/dist/src/ide/ide-client.js +230 -62
- package/dist/src/ide/ide-client.js.map +1 -1
- package/dist/src/ide/ide-client.test.d.ts +6 -0
- package/dist/src/ide/ide-client.test.js +43 -0
- package/dist/src/ide/ide-client.test.js.map +1 -0
- package/dist/src/ide/ide-installer.js +23 -34
- package/dist/src/ide/ide-installer.js.map +1 -1
- package/dist/src/ide/ide-installer.test.js +6 -8
- package/dist/src/ide/ide-installer.test.js.map +1 -1
- package/dist/src/ide/ideContext.d.ts +97 -2
- package/dist/src/ide/ideContext.js +45 -0
- package/dist/src/ide/ideContext.js.map +1 -1
- package/dist/src/ide/process-utils.d.ts +14 -0
- package/dist/src/ide/process-utils.js +57 -0
- package/dist/src/ide/process-utils.js.map +1 -0
- package/dist/src/index.d.ts +7 -1
- package/dist/src/index.js +7 -1
- package/dist/src/index.js.map +1 -1
- package/dist/src/mcp/google-auth-provider.js +9 -0
- package/dist/src/mcp/google-auth-provider.js.map +1 -1
- package/dist/src/mcp/google-auth-provider.test.js +45 -10
- package/dist/src/mcp/google-auth-provider.test.js.map +1 -1
- package/dist/src/mcp/oauth-provider.d.ts +1 -1
- package/dist/src/mcp/oauth-provider.js +185 -59
- package/dist/src/mcp/oauth-provider.js.map +1 -1
- package/dist/src/mcp/oauth-provider.test.js +134 -62
- package/dist/src/mcp/oauth-provider.test.js.map +1 -1
- package/dist/src/mcp/oauth-utils.d.ts +3 -1
- package/dist/src/mcp/oauth-utils.js +50 -12
- package/dist/src/mcp/oauth-utils.js.map +1 -1
- package/dist/src/mcp/oauth-utils.test.js +17 -2
- package/dist/src/mcp/oauth-utils.test.js.map +1 -1
- package/dist/src/mocks/msw.d.ts +6 -0
- package/dist/src/mocks/msw.js +8 -0
- package/dist/src/mocks/msw.js.map +1 -0
- package/dist/src/prompts/prompt-registry.d.ts +8 -0
- package/dist/src/prompts/prompt-registry.js +16 -0
- package/dist/src/prompts/prompt-registry.js.map +1 -1
- package/dist/src/services/chatRecordingService.d.ts +150 -0
- package/dist/src/services/chatRecordingService.js +318 -0
- package/dist/src/services/chatRecordingService.js.map +1 -0
- package/dist/src/services/chatRecordingService.test.d.ts +6 -0
- package/dist/src/services/chatRecordingService.test.js +288 -0
- package/dist/src/services/chatRecordingService.test.js.map +1 -0
- package/dist/src/services/fileSystemService.d.ts +31 -0
- package/dist/src/services/fileSystemService.js +18 -0
- package/dist/src/services/fileSystemService.js.map +1 -0
- package/dist/src/services/fileSystemService.test.d.ts +6 -0
- package/dist/src/services/fileSystemService.test.js +41 -0
- package/dist/src/services/fileSystemService.test.js.map +1 -0
- package/dist/src/services/loopDetectionService.js +19 -16
- package/dist/src/services/loopDetectionService.js.map +1 -1
- package/dist/src/services/loopDetectionService.test.js +191 -0
- package/dist/src/services/loopDetectionService.test.js.map +1 -1
- package/dist/src/services/shellExecutionService.js +29 -9
- package/dist/src/services/shellExecutionService.js.map +1 -1
- package/dist/src/services/shellExecutionService.test.js +21 -3
- package/dist/src/services/shellExecutionService.test.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +78 -9
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +316 -205
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.d.ts +17 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js +342 -0
- package/dist/src/telemetry/clearcut-logger/clearcut-logger.test.js.map +1 -0
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +14 -2
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +32 -9
- package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
- package/dist/src/telemetry/constants.d.ts +2 -0
- package/dist/src/telemetry/constants.js +2 -0
- package/dist/src/telemetry/constants.js.map +1 -1
- package/dist/src/telemetry/index.d.ts +2 -2
- package/dist/src/telemetry/index.js +2 -2
- package/dist/src/telemetry/index.js.map +1 -1
- package/dist/src/telemetry/integration.test.circular.js +1 -0
- package/dist/src/telemetry/integration.test.circular.js.map +1 -1
- package/dist/src/telemetry/loggers.d.ts +4 -1
- package/dist/src/telemetry/loggers.js +55 -6
- package/dist/src/telemetry/loggers.js.map +1 -1
- package/dist/src/telemetry/loggers.test.circular.js +7 -2
- package/dist/src/telemetry/loggers.test.circular.js.map +1 -1
- package/dist/src/telemetry/loggers.test.js +43 -8
- package/dist/src/telemetry/loggers.test.js.map +1 -1
- package/dist/src/telemetry/metrics.d.ts +7 -2
- package/dist/src/telemetry/metrics.js +26 -6
- package/dist/src/telemetry/metrics.js.map +1 -1
- package/dist/src/telemetry/metrics.test.js +81 -1
- package/dist/src/telemetry/metrics.test.js.map +1 -1
- package/dist/src/telemetry/sdk.d.ts +1 -1
- package/dist/src/telemetry/sdk.js +77 -41
- package/dist/src/telemetry/sdk.js.map +1 -1
- package/dist/src/telemetry/sdk.test.d.ts +6 -0
- package/dist/src/telemetry/sdk.test.js +82 -0
- package/dist/src/telemetry/sdk.test.js.map +1 -0
- package/dist/src/telemetry/telemetry.test.js +2 -4
- package/dist/src/telemetry/telemetry.test.js.map +1 -1
- package/dist/src/telemetry/tool-call-decision.d.ts +13 -0
- package/dist/src/telemetry/tool-call-decision.js +29 -0
- package/dist/src/telemetry/tool-call-decision.js.map +1 -0
- package/dist/src/telemetry/types.d.ts +55 -21
- package/dist/src/telemetry/types.js +83 -43
- package/dist/src/telemetry/types.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.d.ts +8 -1
- package/dist/src/telemetry/uiTelemetry.js +17 -2
- package/dist/src/telemetry/uiTelemetry.js.map +1 -1
- package/dist/src/telemetry/uiTelemetry.test.js +57 -10
- package/dist/src/telemetry/uiTelemetry.test.js.map +1 -1
- package/dist/src/test-utils/config.d.ts +16 -0
- package/dist/src/test-utils/config.js +32 -0
- package/dist/src/test-utils/config.js.map +1 -0
- package/dist/src/test-utils/tools.d.ts +44 -0
- package/dist/src/test-utils/tools.js +105 -0
- package/dist/src/test-utils/tools.js.map +1 -0
- package/dist/src/tools/diffOptions.d.ts +2 -0
- package/dist/src/tools/diffOptions.js +28 -0
- package/dist/src/tools/diffOptions.js.map +1 -1
- package/dist/src/tools/diffOptions.test.d.ts +6 -0
- package/dist/src/tools/diffOptions.test.js +119 -0
- package/dist/src/tools/diffOptions.test.js.map +1 -0
- package/dist/src/tools/edit.d.ts +10 -34
- package/dist/src/tools/edit.js +152 -136
- package/dist/src/tools/edit.js.map +1 -1
- package/dist/src/tools/edit.test.js +125 -51
- package/dist/src/tools/edit.test.js.map +1 -1
- package/dist/src/tools/glob.d.ts +4 -11
- package/dist/src/tools/glob.js +87 -91
- package/dist/src/tools/glob.js.map +1 -1
- package/dist/src/tools/glob.test.js +42 -12
- package/dist/src/tools/glob.test.js.map +1 -1
- package/dist/src/tools/grep.d.ts +4 -36
- package/dist/src/tools/grep.js +107 -84
- package/dist/src/tools/grep.js.map +1 -1
- package/dist/src/tools/grep.test.js +40 -23
- package/dist/src/tools/grep.test.js.map +1 -1
- package/dist/src/tools/ls.d.ts +4 -23
- package/dist/src/tools/ls.js +77 -79
- package/dist/src/tools/ls.js.map +1 -1
- package/dist/src/tools/ls.test.js +62 -34
- package/dist/src/tools/ls.test.js.map +1 -1
- package/dist/src/tools/mcp-client-manager.d.ts +38 -0
- package/dist/src/tools/mcp-client-manager.js +74 -0
- package/dist/src/tools/mcp-client-manager.js.map +1 -0
- package/dist/src/tools/mcp-client-manager.test.d.ts +6 -0
- package/dist/src/tools/mcp-client-manager.test.js +39 -0
- package/dist/src/tools/mcp-client-manager.test.js.map +1 -0
- package/dist/src/tools/mcp-client.d.ts +57 -3
- package/dist/src/tools/mcp-client.js +235 -10
- package/dist/src/tools/mcp-client.js.map +1 -1
- package/dist/src/tools/mcp-client.test.js +234 -87
- package/dist/src/tools/mcp-client.test.js.map +1 -1
- package/dist/src/tools/mcp-tool.d.ts +6 -13
- package/dist/src/tools/mcp-tool.js +62 -34
- package/dist/src/tools/mcp-tool.js.map +1 -1
- package/dist/src/tools/mcp-tool.test.js +118 -59
- package/dist/src/tools/mcp-tool.test.js.map +1 -1
- package/dist/src/tools/memoryTool.d.ts +10 -14
- package/dist/src/tools/memoryTool.js +123 -121
- package/dist/src/tools/memoryTool.js.map +1 -1
- package/dist/src/tools/memoryTool.test.js +38 -18
- package/dist/src/tools/memoryTool.test.js.map +1 -1
- package/dist/src/tools/modifiable-tool.d.ts +9 -6
- package/dist/src/tools/modifiable-tool.js +6 -3
- package/dist/src/tools/modifiable-tool.js.map +1 -1
- package/dist/src/tools/modifiable-tool.test.js +12 -12
- package/dist/src/tools/modifiable-tool.test.js.map +1 -1
- package/dist/src/tools/read-file.d.ts +4 -6
- package/dist/src/tools/read-file.js +95 -50
- package/dist/src/tools/read-file.js.map +1 -1
- package/dist/src/tools/read-file.test.js +199 -129
- package/dist/src/tools/read-file.test.js.map +1 -1
- package/dist/src/tools/read-many-files.d.ts +3 -5
- package/dist/src/tools/read-many-files.js +204 -138
- package/dist/src/tools/read-many-files.js.map +1 -1
- package/dist/src/tools/read-many-files.test.js +197 -33
- package/dist/src/tools/read-many-files.test.js.map +1 -1
- package/dist/src/tools/shell.d.ts +4 -6
- package/dist/src/tools/shell.js +112 -102
- package/dist/src/tools/shell.js.map +1 -1
- package/dist/src/tools/shell.test.js +55 -28
- package/dist/src/tools/shell.test.js.map +1 -1
- package/dist/src/tools/tool-error.d.ts +5 -0
- package/dist/src/tools/tool-error.js +5 -0
- package/dist/src/tools/tool-error.js.map +1 -1
- package/dist/src/tools/tool-registry.d.ts +25 -22
- package/dist/src/tools/tool-registry.js +100 -116
- package/dist/src/tools/tool-registry.js.map +1 -1
- package/dist/src/tools/tool-registry.test.js +29 -212
- package/dist/src/tools/tool-registry.test.js.map +1 -1
- package/dist/src/tools/tools.d.ts +137 -92
- package/dist/src/tools/tools.js +188 -61
- package/dist/src/tools/tools.js.map +1 -1
- package/dist/src/tools/tools.test.d.ts +6 -0
- package/dist/src/tools/tools.test.js +206 -0
- package/dist/src/tools/tools.test.js.map +1 -0
- package/dist/src/tools/web-fetch.d.ts +4 -7
- package/dist/src/tools/web-fetch.js +58 -64
- package/dist/src/tools/web-fetch.js.map +1 -1
- package/dist/src/tools/web-fetch.test.js +8 -4
- package/dist/src/tools/web-fetch.test.js.map +1 -1
- package/dist/src/tools/web-search.d.ts +4 -5
- package/dist/src/tools/web-search.js +47 -51
- 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 +139 -0
- package/dist/src/tools/web-search.test.js.map +1 -0
- package/dist/src/tools/write-file.d.ts +20 -11
- package/dist/src/tools/write-file.js +197 -142
- package/dist/src/tools/write-file.js.map +1 -1
- package/dist/src/tools/write-file.test.js +156 -96
- package/dist/src/tools/write-file.test.js.map +1 -1
- package/dist/src/utils/bfsFileSearch.test.js +28 -56
- package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
- package/dist/src/utils/browser.js +4 -3
- package/dist/src/utils/browser.js.map +1 -1
- package/dist/src/utils/editCorrector.js +21 -22
- package/dist/src/utils/editCorrector.js.map +1 -1
- package/dist/src/utils/editor.d.ts +1 -1
- package/dist/src/utils/editor.js +14 -6
- package/dist/src/utils/editor.js.map +1 -1
- package/dist/src/utils/editor.test.js +48 -16
- package/dist/src/utils/editor.test.js.map +1 -1
- package/dist/src/utils/environmentContext.d.ts +21 -0
- package/dist/src/utils/environmentContext.js +90 -0
- package/dist/src/utils/environmentContext.js.map +1 -0
- package/dist/src/utils/environmentContext.test.d.ts +6 -0
- package/dist/src/utils/environmentContext.test.js +140 -0
- package/dist/src/utils/environmentContext.test.js.map +1 -0
- package/dist/src/utils/errorParsing.d.ts +8 -0
- package/dist/src/utils/errorParsing.js +93 -0
- package/dist/src/utils/errorParsing.js.map +1 -0
- package/dist/src/utils/errorParsing.test.d.ts +6 -0
- package/dist/src/utils/errorParsing.test.js +172 -0
- package/dist/src/utils/errorParsing.test.js.map +1 -0
- package/dist/src/utils/fileUtils.d.ts +9 -1
- package/dist/src/utils/fileUtils.js +18 -15
- package/dist/src/utils/fileUtils.js.map +1 -1
- package/dist/src/utils/fileUtils.test.js +24 -22
- package/dist/src/utils/fileUtils.test.js.map +1 -1
- package/dist/src/utils/filesearch/crawlCache.d.ts +25 -0
- package/dist/src/utils/filesearch/crawlCache.js +57 -0
- package/dist/src/utils/filesearch/crawlCache.js.map +1 -0
- package/dist/src/utils/filesearch/crawlCache.test.d.ts +6 -0
- package/dist/src/utils/filesearch/crawlCache.test.js +103 -0
- package/dist/src/utils/filesearch/crawlCache.test.js.map +1 -0
- package/dist/src/utils/filesearch/crawler.d.ts +15 -0
- package/dist/src/utils/filesearch/crawler.js +50 -0
- package/dist/src/utils/filesearch/crawler.js.map +1 -0
- package/dist/src/utils/filesearch/crawler.test.d.ts +6 -0
- package/dist/src/utils/filesearch/crawler.test.js +468 -0
- package/dist/src/utils/filesearch/crawler.test.js.map +1 -0
- package/dist/src/utils/filesearch/fileSearch.d.ts +37 -0
- package/dist/src/utils/filesearch/fileSearch.js +186 -0
- package/dist/src/utils/filesearch/fileSearch.js.map +1 -0
- package/dist/src/utils/filesearch/fileSearch.test.d.ts +6 -0
- package/dist/src/utils/filesearch/fileSearch.test.js +552 -0
- package/dist/src/utils/filesearch/fileSearch.test.js.map +1 -0
- package/dist/src/utils/filesearch/ignore.d.ts +42 -0
- package/dist/src/utils/filesearch/ignore.js +106 -0
- package/dist/src/utils/filesearch/ignore.js.map +1 -0
- package/dist/src/utils/filesearch/ignore.test.d.ts +6 -0
- package/dist/src/utils/filesearch/ignore.test.js +144 -0
- package/dist/src/utils/filesearch/ignore.test.js.map +1 -0
- package/dist/src/utils/filesearch/result-cache.d.ts +33 -0
- package/dist/src/utils/filesearch/result-cache.js +59 -0
- package/dist/src/utils/filesearch/result-cache.js.map +1 -0
- package/dist/src/utils/filesearch/result-cache.test.d.ts +6 -0
- package/dist/src/utils/filesearch/result-cache.test.js +46 -0
- package/dist/src/utils/filesearch/result-cache.test.js.map +1 -0
- package/dist/src/utils/flashFallback.integration.test.js +0 -2
- package/dist/src/utils/flashFallback.integration.test.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.js +7 -4
- package/dist/src/utils/memoryDiscovery.js.map +1 -1
- package/dist/src/utils/memoryDiscovery.test.js +3 -2
- package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.js +3 -7
- package/dist/src/utils/memoryImportProcessor.js.map +1 -1
- package/dist/src/utils/memoryImportProcessor.test.js +17 -20
- package/dist/src/utils/memoryImportProcessor.test.js.map +1 -1
- package/dist/src/utils/nextSpeakerChecker.js +5 -6
- package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
- package/dist/src/utils/nextSpeakerChecker.test.js +2 -2
- package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
- package/dist/src/utils/paths.d.ts +7 -0
- package/dist/src/utils/paths.js +15 -0
- package/dist/src/utils/paths.js.map +1 -1
- package/dist/src/utils/paths.test.js +74 -2
- package/dist/src/utils/paths.test.js.map +1 -1
- package/dist/src/utils/quotaErrorDetection.d.ts +1 -5
- package/dist/src/utils/quotaErrorDetection.js.map +1 -1
- package/dist/src/utils/schemaValidator.d.ts +1 -8
- package/dist/src/utils/schemaValidator.js +1 -32
- package/dist/src/utils/schemaValidator.js.map +1 -1
- package/dist/src/utils/secure-browser-launcher.js +4 -3
- package/dist/src/utils/secure-browser-launcher.js.map +1 -1
- package/dist/src/utils/shell-utils.d.ts +39 -0
- package/dist/src/utils/shell-utils.js +72 -2
- package/dist/src/utils/shell-utils.js.map +1 -1
- package/dist/src/utils/shell-utils.test.js +132 -4
- package/dist/src/utils/shell-utils.test.js.map +1 -1
- package/dist/src/utils/systemEncoding.js +1 -1
- package/dist/src/utils/systemEncoding.js.map +1 -1
- package/dist/src/utils/systemEncoding.test.js +23 -23
- package/dist/src/utils/systemEncoding.test.js.map +1 -1
- package/dist/src/utils/user_account.js +58 -48
- package/dist/src/utils/user_account.js.map +1 -1
- package/dist/src/utils/user_account.test.js +76 -9
- package/dist/src/utils/user_account.test.js.map +1 -1
- package/dist/src/utils/workspaceContext.d.ts +22 -7
- package/dist/src/utils/workspaceContext.js +81 -55
- package/dist/src/utils/workspaceContext.js.map +1 -1
- package/dist/src/utils/workspaceContext.test.js +221 -137
- package/dist/src/utils/workspaceContext.test.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/package.json +11 -2
- package/dist/src/core/modelCheck.d.ts +0 -14
- package/dist/src/core/modelCheck.js +0 -62
- package/dist/src/core/modelCheck.js.map +0 -1
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { McpClient, MCPDiscoveryState, populateMcpServerCommand, } from './mcp-client.js';
|
|
7
|
+
import { getErrorMessage } from '../utils/errors.js';
|
|
8
|
+
/**
|
|
9
|
+
* Manages the lifecycle of multiple MCP clients, including local child processes.
|
|
10
|
+
* This class is responsible for starting, stopping, and discovering tools from
|
|
11
|
+
* a collection of MCP servers defined in the configuration.
|
|
12
|
+
*/
|
|
13
|
+
export class McpClientManager {
|
|
14
|
+
clients = new Map();
|
|
15
|
+
mcpServers;
|
|
16
|
+
mcpServerCommand;
|
|
17
|
+
toolRegistry;
|
|
18
|
+
promptRegistry;
|
|
19
|
+
debugMode;
|
|
20
|
+
workspaceContext;
|
|
21
|
+
discoveryState = MCPDiscoveryState.NOT_STARTED;
|
|
22
|
+
constructor(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode, workspaceContext) {
|
|
23
|
+
this.mcpServers = mcpServers;
|
|
24
|
+
this.mcpServerCommand = mcpServerCommand;
|
|
25
|
+
this.toolRegistry = toolRegistry;
|
|
26
|
+
this.promptRegistry = promptRegistry;
|
|
27
|
+
this.debugMode = debugMode;
|
|
28
|
+
this.workspaceContext = workspaceContext;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Initiates the tool discovery process for all configured MCP servers.
|
|
32
|
+
* It connects to each server, discovers its available tools, and registers
|
|
33
|
+
* them with the `ToolRegistry`.
|
|
34
|
+
*/
|
|
35
|
+
async discoverAllMcpTools() {
|
|
36
|
+
await this.stop();
|
|
37
|
+
this.discoveryState = MCPDiscoveryState.IN_PROGRESS;
|
|
38
|
+
const servers = populateMcpServerCommand(this.mcpServers, this.mcpServerCommand);
|
|
39
|
+
const discoveryPromises = Object.entries(servers).map(async ([name, config]) => {
|
|
40
|
+
const client = new McpClient(name, config, this.toolRegistry, this.promptRegistry, this.workspaceContext, this.debugMode);
|
|
41
|
+
this.clients.set(name, client);
|
|
42
|
+
try {
|
|
43
|
+
await client.connect();
|
|
44
|
+
await client.discover();
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
// Log the error but don't let a single failed server stop the others
|
|
48
|
+
console.error(`Error during discovery for server '${name}': ${getErrorMessage(error)}`);
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
await Promise.all(discoveryPromises);
|
|
52
|
+
this.discoveryState = MCPDiscoveryState.COMPLETED;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Stops all running local MCP servers and closes all client connections.
|
|
56
|
+
* This is the cleanup method to be called on application exit.
|
|
57
|
+
*/
|
|
58
|
+
async stop() {
|
|
59
|
+
const disconnectionPromises = Array.from(this.clients.entries()).map(async ([name, client]) => {
|
|
60
|
+
try {
|
|
61
|
+
await client.disconnect();
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
console.error(`Error stopping client '${name}': ${getErrorMessage(error)}`);
|
|
65
|
+
}
|
|
66
|
+
});
|
|
67
|
+
await Promise.all(disconnectionPromises);
|
|
68
|
+
this.clients.clear();
|
|
69
|
+
}
|
|
70
|
+
getDiscoveryState() {
|
|
71
|
+
return this.discoveryState;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=mcp-client-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client-manager.js","sourceRoot":"","sources":["../../../src/tools/mcp-client-manager.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH,OAAO,EACL,SAAS,EACT,iBAAiB,EACjB,wBAAwB,GACzB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGrD;;;;GAIG;AACH,MAAM,OAAO,gBAAgB;IACnB,OAAO,GAA2B,IAAI,GAAG,EAAE,CAAC;IACnC,UAAU,CAAkC;IAC5C,gBAAgB,CAAqB;IACrC,YAAY,CAAe;IAC3B,cAAc,CAAiB;IAC/B,SAAS,CAAU;IACnB,gBAAgB,CAAmB;IAC5C,cAAc,GAAsB,iBAAiB,CAAC,WAAW,CAAC;IAE1E,YACE,UAA2C,EAC3C,gBAAoC,EACpC,YAA0B,EAC1B,cAA8B,EAC9B,SAAkB,EAClB,gBAAkC;QAElC,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;QAC7B,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;QACzC,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;QACjC,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,gBAAgB,GAAG,gBAAgB,CAAC;IAC3C,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,mBAAmB;QACvB,MAAM,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC,WAAW,CAAC;QACpD,MAAM,OAAO,GAAG,wBAAwB,CACtC,IAAI,CAAC,UAAU,EACf,IAAI,CAAC,gBAAgB,CACtB,CAAC;QAEF,MAAM,iBAAiB,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,GAAG,CACnD,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;YACvB,MAAM,MAAM,GAAG,IAAI,SAAS,CAC1B,IAAI,EACJ,MAAM,EACN,IAAI,CAAC,YAAY,EACjB,IAAI,CAAC,cAAc,EACnB,IAAI,CAAC,gBAAgB,EACrB,IAAI,CAAC,SAAS,CACf,CAAC;YACF,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YAC/B,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC;gBACvB,MAAM,MAAM,CAAC,QAAQ,EAAE,CAAC;YAC1B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,qEAAqE;gBACrE,OAAO,CAAC,KAAK,CACX,sCAAsC,IAAI,MAAM,eAAe,CAC7D,KAAK,CACN,EAAE,CACJ,CAAC;YACJ,CAAC;QACH,CAAC,CACF,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;QACrC,IAAI,CAAC,cAAc,GAAG,iBAAiB,CAAC,SAAS,CAAC;IACpD,CAAC;IAED;;;OAGG;IACH,KAAK,CAAC,IAAI;QACR,MAAM,qBAAqB,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC,GAAG,CAClE,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE,EAAE;YACvB,IAAI,CAAC;gBACH,MAAM,MAAM,CAAC,UAAU,EAAE,CAAC;YAC5B,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CACX,0BAA0B,IAAI,MAAM,eAAe,CAAC,KAAK,CAAC,EAAE,CAC7D,CAAC;YACJ,CAAC;QACH,CAAC,CACF,CAAC;QAEF,MAAM,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;QACzC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;IACvB,CAAC;IAED,iBAAiB;QACf,OAAO,IAAI,CAAC,cAAc,CAAC;IAC7B,CAAC;CACF"}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright 2025 Google LLC
|
|
4
|
+
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
+
*/
|
|
6
|
+
import { afterEach, describe, expect, it, vi } from 'vitest';
|
|
7
|
+
import { McpClientManager } from './mcp-client-manager.js';
|
|
8
|
+
import { McpClient } from './mcp-client.js';
|
|
9
|
+
vi.mock('./mcp-client.js', async () => {
|
|
10
|
+
const originalModule = await vi.importActual('./mcp-client.js');
|
|
11
|
+
return {
|
|
12
|
+
...originalModule,
|
|
13
|
+
McpClient: vi.fn(),
|
|
14
|
+
populateMcpServerCommand: vi.fn(() => ({
|
|
15
|
+
'test-server': {},
|
|
16
|
+
})),
|
|
17
|
+
};
|
|
18
|
+
});
|
|
19
|
+
describe('McpClientManager', () => {
|
|
20
|
+
afterEach(() => {
|
|
21
|
+
vi.restoreAllMocks();
|
|
22
|
+
});
|
|
23
|
+
it('should discover tools from all servers', async () => {
|
|
24
|
+
const mockedMcpClient = {
|
|
25
|
+
connect: vi.fn(),
|
|
26
|
+
discover: vi.fn(),
|
|
27
|
+
disconnect: vi.fn(),
|
|
28
|
+
getStatus: vi.fn(),
|
|
29
|
+
};
|
|
30
|
+
vi.mocked(McpClient).mockReturnValue(mockedMcpClient);
|
|
31
|
+
const manager = new McpClientManager({
|
|
32
|
+
'test-server': {},
|
|
33
|
+
}, '', {}, {}, false, {});
|
|
34
|
+
await manager.discoverAllMcpTools();
|
|
35
|
+
expect(mockedMcpClient.connect).toHaveBeenCalledOnce();
|
|
36
|
+
expect(mockedMcpClient.discover).toHaveBeenCalledOnce();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
39
|
+
//# sourceMappingURL=mcp-client-manager.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mcp-client-manager.test.js","sourceRoot":"","sources":["../../../src/tools/mcp-client-manager.test.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC7D,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAK5C,EAAE,CAAC,IAAI,CAAC,iBAAiB,EAAE,KAAK,IAAI,EAAE;IACpC,MAAM,cAAc,GAAG,MAAM,EAAE,CAAC,YAAY,CAAC,iBAAiB,CAAC,CAAC;IAChE,OAAO;QACL,GAAG,cAAc;QACjB,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;QAClB,wBAAwB,EAAE,EAAE,CAAC,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;YACrC,aAAa,EAAE,EAAE;SAClB,CAAC,CAAC;KACJ,CAAC;AACJ,CAAC,CAAC,CAAC;AAEH,QAAQ,CAAC,kBAAkB,EAAE,GAAG,EAAE;IAChC,SAAS,CAAC,GAAG,EAAE;QACb,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,wCAAwC,EAAE,KAAK,IAAI,EAAE;QACtD,MAAM,eAAe,GAAG;YACtB,OAAO,EAAE,EAAE,CAAC,EAAE,EAAE;YAChB,QAAQ,EAAE,EAAE,CAAC,EAAE,EAAE;YACjB,UAAU,EAAE,EAAE,CAAC,EAAE,EAAE;YACnB,SAAS,EAAE,EAAE,CAAC,EAAE,EAAE;SACnB,CAAC;QACF,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,eAAe,CAClC,eAAuC,CACxC,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,gBAAgB,CAClC;YACE,aAAa,EAAE,EAAE;SAClB,EACD,EAAE,EACF,EAAkB,EAClB,EAAoB,EACpB,KAAK,EACL,EAAsB,CACvB,CAAC;QACF,MAAM,OAAO,CAAC,mBAAmB,EAAE,CAAC;QACpC,MAAM,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,oBAAoB,EAAE,CAAC;QACvD,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,oBAAoB,EAAE,CAAC;IAC1D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -11,6 +11,7 @@ import { DiscoveredMCPTool } from './mcp-tool.js';
|
|
|
11
11
|
import { FunctionDeclaration } from '@google/genai';
|
|
12
12
|
import { ToolRegistry } from './tool-registry.js';
|
|
13
13
|
import { PromptRegistry } from '../prompts/prompt-registry.js';
|
|
14
|
+
import { WorkspaceContext } from '../utils/workspaceContext.js';
|
|
14
15
|
export declare const MCP_DEFAULT_TIMEOUT_MSEC: number;
|
|
15
16
|
export type DiscoveredMCPPrompt = Prompt & {
|
|
16
17
|
serverName: string;
|
|
@@ -38,6 +39,45 @@ export declare enum MCPDiscoveryState {
|
|
|
38
39
|
/** Discovery has completed (with or without errors) */
|
|
39
40
|
COMPLETED = "completed"
|
|
40
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* A client for a single MCP server.
|
|
44
|
+
*
|
|
45
|
+
* This class is responsible for connecting to, discovering tools from, and
|
|
46
|
+
* managing the state of a single MCP server.
|
|
47
|
+
*/
|
|
48
|
+
export declare class McpClient {
|
|
49
|
+
private readonly serverName;
|
|
50
|
+
private readonly serverConfig;
|
|
51
|
+
private readonly toolRegistry;
|
|
52
|
+
private readonly promptRegistry;
|
|
53
|
+
private readonly workspaceContext;
|
|
54
|
+
private readonly debugMode;
|
|
55
|
+
private client;
|
|
56
|
+
private transport;
|
|
57
|
+
private status;
|
|
58
|
+
private isDisconnecting;
|
|
59
|
+
constructor(serverName: string, serverConfig: MCPServerConfig, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, workspaceContext: WorkspaceContext, debugMode: boolean);
|
|
60
|
+
/**
|
|
61
|
+
* Connects to the MCP server.
|
|
62
|
+
*/
|
|
63
|
+
connect(): Promise<void>;
|
|
64
|
+
/**
|
|
65
|
+
* Discovers tools and prompts from the MCP server.
|
|
66
|
+
*/
|
|
67
|
+
discover(): Promise<void>;
|
|
68
|
+
/**
|
|
69
|
+
* Disconnects from the MCP server.
|
|
70
|
+
*/
|
|
71
|
+
disconnect(): Promise<void>;
|
|
72
|
+
/**
|
|
73
|
+
* Returns the current status of the client.
|
|
74
|
+
*/
|
|
75
|
+
getStatus(): MCPServerStatus;
|
|
76
|
+
private updateStatus;
|
|
77
|
+
private createTransport;
|
|
78
|
+
private discoverTools;
|
|
79
|
+
private discoverPrompts;
|
|
80
|
+
}
|
|
41
81
|
/**
|
|
42
82
|
* Map to track which MCP servers have been discovered to require OAuth
|
|
43
83
|
*/
|
|
@@ -54,6 +94,10 @@ export declare function addMCPStatusChangeListener(listener: StatusChangeListene
|
|
|
54
94
|
* Remove a listener for MCP server status changes
|
|
55
95
|
*/
|
|
56
96
|
export declare function removeMCPStatusChangeListener(listener: StatusChangeListener): void;
|
|
97
|
+
/**
|
|
98
|
+
* Update the status of an MCP server
|
|
99
|
+
*/
|
|
100
|
+
export declare function updateMCPServerStatus(serverName: string, status: MCPServerStatus): void;
|
|
57
101
|
/**
|
|
58
102
|
* Get the current status of an MCP server
|
|
59
103
|
*/
|
|
@@ -76,7 +120,7 @@ export declare function getMCPDiscoveryState(): MCPDiscoveryState;
|
|
|
76
120
|
* @param toolRegistry The central registry where discovered tools will be registered.
|
|
77
121
|
* @returns A promise that resolves when the discovery process has been attempted for all servers.
|
|
78
122
|
*/
|
|
79
|
-
export declare function discoverMcpTools(mcpServers: Record<string, MCPServerConfig>, mcpServerCommand: string | undefined, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, debugMode: boolean): Promise<void>;
|
|
123
|
+
export declare function discoverMcpTools(mcpServers: Record<string, MCPServerConfig>, mcpServerCommand: string | undefined, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, debugMode: boolean, workspaceContext: WorkspaceContext): Promise<void>;
|
|
80
124
|
/** Visible for Testing */
|
|
81
125
|
export declare function populateMcpServerCommand(mcpServers: Record<string, MCPServerConfig>, mcpServerCommand: string | undefined): Record<string, MCPServerConfig>;
|
|
82
126
|
/**
|
|
@@ -89,7 +133,17 @@ export declare function populateMcpServerCommand(mcpServers: Record<string, MCPS
|
|
|
89
133
|
* @param toolRegistry The registry to register discovered tools with
|
|
90
134
|
* @returns Promise that resolves when discovery is complete
|
|
91
135
|
*/
|
|
92
|
-
export declare function connectAndDiscover(mcpServerName: string, mcpServerConfig: MCPServerConfig, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, debugMode: boolean): Promise<void>;
|
|
136
|
+
export declare function connectAndDiscover(mcpServerName: string, mcpServerConfig: MCPServerConfig, toolRegistry: ToolRegistry, promptRegistry: PromptRegistry, debugMode: boolean, workspaceContext: WorkspaceContext): Promise<void>;
|
|
137
|
+
/**
|
|
138
|
+
* Recursively validates that a JSON schema and all its nested properties and
|
|
139
|
+
* items have a `type` defined.
|
|
140
|
+
*
|
|
141
|
+
* @param schema The JSON schema to validate.
|
|
142
|
+
* @returns `true` if the schema is valid, `false` otherwise.
|
|
143
|
+
*
|
|
144
|
+
* @visiblefortesting
|
|
145
|
+
*/
|
|
146
|
+
export declare function hasValidTypes(schema: unknown): boolean;
|
|
93
147
|
/**
|
|
94
148
|
* Discovers and sanitizes tools from a connected MCP client.
|
|
95
149
|
* It retrieves function declarations from the client, filters out disabled tools,
|
|
@@ -130,7 +184,7 @@ export declare function invokeMcpPrompt(mcpServerName: string, mcpClient: Client
|
|
|
130
184
|
* @returns A promise that resolves to a connected MCP `Client` instance.
|
|
131
185
|
* @throws An error if the connection fails or the configuration is invalid.
|
|
132
186
|
*/
|
|
133
|
-
export declare function connectToMcpServer(mcpServerName: string, mcpServerConfig: MCPServerConfig, debugMode: boolean): Promise<Client>;
|
|
187
|
+
export declare function connectToMcpServer(mcpServerName: string, mcpServerConfig: MCPServerConfig, debugMode: boolean, workspaceContext: WorkspaceContext): Promise<Client>;
|
|
134
188
|
/** Visible for Testing */
|
|
135
189
|
export declare function createTransport(mcpServerName: string, mcpServerConfig: MCPServerConfig, debugMode: boolean): Promise<Transport>;
|
|
136
190
|
/** Visible for testing */
|
|
@@ -7,7 +7,7 @@ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
|
|
|
7
7
|
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
|
|
8
8
|
import { SSEClientTransport, } from '@modelcontextprotocol/sdk/client/sse.js';
|
|
9
9
|
import { StreamableHTTPClientTransport, } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
|
|
10
|
-
import { ListPromptsResultSchema, GetPromptResultSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
10
|
+
import { ListPromptsResultSchema, GetPromptResultSchema, ListRootsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
11
11
|
import { parse } from 'shell-quote';
|
|
12
12
|
import { AuthProviderType } from '../config/config.js';
|
|
13
13
|
import { GoogleCredentialProvider } from '../mcp/google-auth-provider.js';
|
|
@@ -17,6 +17,8 @@ import { MCPOAuthProvider } from '../mcp/oauth-provider.js';
|
|
|
17
17
|
import { OAuthUtils } from '../mcp/oauth-utils.js';
|
|
18
18
|
import { MCPOAuthTokenStorage } from '../mcp/oauth-token-storage.js';
|
|
19
19
|
import { getErrorMessage } from '../utils/errors.js';
|
|
20
|
+
import { basename } from 'node:path';
|
|
21
|
+
import { pathToFileURL } from 'node:url';
|
|
20
22
|
export const MCP_DEFAULT_TIMEOUT_MSEC = 10 * 60 * 1000; // default to 10 minutes
|
|
21
23
|
/**
|
|
22
24
|
* Enum representing the connection status of an MCP server
|
|
@@ -42,6 +44,122 @@ export var MCPDiscoveryState;
|
|
|
42
44
|
/** Discovery has completed (with or without errors) */
|
|
43
45
|
MCPDiscoveryState["COMPLETED"] = "completed";
|
|
44
46
|
})(MCPDiscoveryState || (MCPDiscoveryState = {}));
|
|
47
|
+
/**
|
|
48
|
+
* A client for a single MCP server.
|
|
49
|
+
*
|
|
50
|
+
* This class is responsible for connecting to, discovering tools from, and
|
|
51
|
+
* managing the state of a single MCP server.
|
|
52
|
+
*/
|
|
53
|
+
export class McpClient {
|
|
54
|
+
serverName;
|
|
55
|
+
serverConfig;
|
|
56
|
+
toolRegistry;
|
|
57
|
+
promptRegistry;
|
|
58
|
+
workspaceContext;
|
|
59
|
+
debugMode;
|
|
60
|
+
client;
|
|
61
|
+
transport;
|
|
62
|
+
status = MCPServerStatus.DISCONNECTED;
|
|
63
|
+
isDisconnecting = false;
|
|
64
|
+
constructor(serverName, serverConfig, toolRegistry, promptRegistry, workspaceContext, debugMode) {
|
|
65
|
+
this.serverName = serverName;
|
|
66
|
+
this.serverConfig = serverConfig;
|
|
67
|
+
this.toolRegistry = toolRegistry;
|
|
68
|
+
this.promptRegistry = promptRegistry;
|
|
69
|
+
this.workspaceContext = workspaceContext;
|
|
70
|
+
this.debugMode = debugMode;
|
|
71
|
+
this.client = new Client({
|
|
72
|
+
name: `gemini-cli-mcp-client-${this.serverName}`,
|
|
73
|
+
version: '0.0.1',
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Connects to the MCP server.
|
|
78
|
+
*/
|
|
79
|
+
async connect() {
|
|
80
|
+
this.isDisconnecting = false;
|
|
81
|
+
this.updateStatus(MCPServerStatus.CONNECTING);
|
|
82
|
+
try {
|
|
83
|
+
this.transport = await this.createTransport();
|
|
84
|
+
this.client.onerror = (error) => {
|
|
85
|
+
if (this.isDisconnecting) {
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
console.error(`MCP ERROR (${this.serverName}):`, error.toString());
|
|
89
|
+
this.updateStatus(MCPServerStatus.DISCONNECTED);
|
|
90
|
+
};
|
|
91
|
+
this.client.registerCapabilities({
|
|
92
|
+
roots: {},
|
|
93
|
+
});
|
|
94
|
+
this.client.setRequestHandler(ListRootsRequestSchema, async () => {
|
|
95
|
+
const roots = [];
|
|
96
|
+
for (const dir of this.workspaceContext.getDirectories()) {
|
|
97
|
+
roots.push({
|
|
98
|
+
uri: pathToFileURL(dir).toString(),
|
|
99
|
+
name: basename(dir),
|
|
100
|
+
});
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
roots,
|
|
104
|
+
};
|
|
105
|
+
});
|
|
106
|
+
await this.client.connect(this.transport, {
|
|
107
|
+
timeout: this.serverConfig.timeout,
|
|
108
|
+
});
|
|
109
|
+
this.updateStatus(MCPServerStatus.CONNECTED);
|
|
110
|
+
}
|
|
111
|
+
catch (error) {
|
|
112
|
+
this.updateStatus(MCPServerStatus.DISCONNECTED);
|
|
113
|
+
throw error;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Discovers tools and prompts from the MCP server.
|
|
118
|
+
*/
|
|
119
|
+
async discover() {
|
|
120
|
+
if (this.status !== MCPServerStatus.CONNECTED) {
|
|
121
|
+
throw new Error('Client is not connected.');
|
|
122
|
+
}
|
|
123
|
+
const prompts = await this.discoverPrompts();
|
|
124
|
+
const tools = await this.discoverTools();
|
|
125
|
+
if (prompts.length === 0 && tools.length === 0) {
|
|
126
|
+
throw new Error('No prompts or tools found on the server.');
|
|
127
|
+
}
|
|
128
|
+
for (const tool of tools) {
|
|
129
|
+
this.toolRegistry.registerTool(tool);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Disconnects from the MCP server.
|
|
134
|
+
*/
|
|
135
|
+
async disconnect() {
|
|
136
|
+
this.isDisconnecting = true;
|
|
137
|
+
if (this.transport) {
|
|
138
|
+
await this.transport.close();
|
|
139
|
+
}
|
|
140
|
+
this.client.close();
|
|
141
|
+
this.updateStatus(MCPServerStatus.DISCONNECTED);
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* Returns the current status of the client.
|
|
145
|
+
*/
|
|
146
|
+
getStatus() {
|
|
147
|
+
return this.status;
|
|
148
|
+
}
|
|
149
|
+
updateStatus(status) {
|
|
150
|
+
this.status = status;
|
|
151
|
+
updateMCPServerStatus(this.serverName, status);
|
|
152
|
+
}
|
|
153
|
+
async createTransport() {
|
|
154
|
+
return createTransport(this.serverName, this.serverConfig, this.debugMode);
|
|
155
|
+
}
|
|
156
|
+
async discoverTools() {
|
|
157
|
+
return discoverTools(this.serverName, this.serverConfig, this.client);
|
|
158
|
+
}
|
|
159
|
+
async discoverPrompts() {
|
|
160
|
+
return discoverPrompts(this.serverName, this.client, this.promptRegistry);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
45
163
|
/**
|
|
46
164
|
* Map to track the status of each MCP server within the core package
|
|
47
165
|
*/
|
|
@@ -73,7 +191,7 @@ export function removeMCPStatusChangeListener(listener) {
|
|
|
73
191
|
/**
|
|
74
192
|
* Update the status of an MCP server
|
|
75
193
|
*/
|
|
76
|
-
function updateMCPServerStatus(serverName, status) {
|
|
194
|
+
export function updateMCPServerStatus(serverName, status) {
|
|
77
195
|
serverStatuses.set(serverName, status);
|
|
78
196
|
// Notify all listeners
|
|
79
197
|
for (const listener of statusChangeListeners) {
|
|
@@ -163,8 +281,10 @@ async function handleAutomaticOAuth(mcpServerName, mcpServerConfig, wwwAuthentic
|
|
|
163
281
|
scopes: oauthConfig.scopes || [],
|
|
164
282
|
};
|
|
165
283
|
// Perform OAuth authentication
|
|
284
|
+
// Pass the server URL for proper discovery
|
|
285
|
+
const serverUrl = mcpServerConfig.httpUrl || mcpServerConfig.url;
|
|
166
286
|
console.log(`Starting OAuth authentication for server '${mcpServerName}'...`);
|
|
167
|
-
await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig);
|
|
287
|
+
await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig, serverUrl);
|
|
168
288
|
console.log(`OAuth authentication successful for server '${mcpServerName}'`);
|
|
169
289
|
return true;
|
|
170
290
|
}
|
|
@@ -223,11 +343,11 @@ async function createTransportWithOAuth(mcpServerName, mcpServerConfig, accessTo
|
|
|
223
343
|
* @param toolRegistry The central registry where discovered tools will be registered.
|
|
224
344
|
* @returns A promise that resolves when the discovery process has been attempted for all servers.
|
|
225
345
|
*/
|
|
226
|
-
export async function discoverMcpTools(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode) {
|
|
346
|
+
export async function discoverMcpTools(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode, workspaceContext) {
|
|
227
347
|
mcpDiscoveryState = MCPDiscoveryState.IN_PROGRESS;
|
|
228
348
|
try {
|
|
229
349
|
mcpServers = populateMcpServerCommand(mcpServers, mcpServerCommand);
|
|
230
|
-
const discoveryPromises = Object.entries(mcpServers).map(([mcpServerName, mcpServerConfig]) => connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode));
|
|
350
|
+
const discoveryPromises = Object.entries(mcpServers).map(([mcpServerName, mcpServerConfig]) => connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode, workspaceContext));
|
|
231
351
|
await Promise.all(discoveryPromises);
|
|
232
352
|
}
|
|
233
353
|
finally {
|
|
@@ -260,11 +380,11 @@ export function populateMcpServerCommand(mcpServers, mcpServerCommand) {
|
|
|
260
380
|
* @param toolRegistry The registry to register discovered tools with
|
|
261
381
|
* @returns Promise that resolves when discovery is complete
|
|
262
382
|
*/
|
|
263
|
-
export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode) {
|
|
383
|
+
export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode, workspaceContext) {
|
|
264
384
|
updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTING);
|
|
265
385
|
let mcpClient;
|
|
266
386
|
try {
|
|
267
|
-
mcpClient = await connectToMcpServer(mcpServerName, mcpServerConfig, debugMode);
|
|
387
|
+
mcpClient = await connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext);
|
|
268
388
|
mcpClient.onerror = (error) => {
|
|
269
389
|
console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
|
|
270
390
|
updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
|
|
@@ -291,6 +411,59 @@ export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolReg
|
|
|
291
411
|
updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
|
|
292
412
|
}
|
|
293
413
|
}
|
|
414
|
+
/**
|
|
415
|
+
* Recursively validates that a JSON schema and all its nested properties and
|
|
416
|
+
* items have a `type` defined.
|
|
417
|
+
*
|
|
418
|
+
* @param schema The JSON schema to validate.
|
|
419
|
+
* @returns `true` if the schema is valid, `false` otherwise.
|
|
420
|
+
*
|
|
421
|
+
* @visiblefortesting
|
|
422
|
+
*/
|
|
423
|
+
export function hasValidTypes(schema) {
|
|
424
|
+
if (typeof schema !== 'object' || schema === null) {
|
|
425
|
+
// Not a schema object we can validate, or not a schema at all.
|
|
426
|
+
// Treat as valid as it has no properties to be invalid.
|
|
427
|
+
return true;
|
|
428
|
+
}
|
|
429
|
+
const s = schema;
|
|
430
|
+
if (!s['type']) {
|
|
431
|
+
// These keywords contain an array of schemas that should be validated.
|
|
432
|
+
//
|
|
433
|
+
// If no top level type was given, then they must each have a type.
|
|
434
|
+
let hasSubSchema = false;
|
|
435
|
+
const schemaArrayKeywords = ['anyOf', 'allOf', 'oneOf'];
|
|
436
|
+
for (const keyword of schemaArrayKeywords) {
|
|
437
|
+
const subSchemas = s[keyword];
|
|
438
|
+
if (Array.isArray(subSchemas)) {
|
|
439
|
+
hasSubSchema = true;
|
|
440
|
+
for (const subSchema of subSchemas) {
|
|
441
|
+
if (!hasValidTypes(subSchema)) {
|
|
442
|
+
return false;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
// If the node itself is missing a type and had no subschemas, then it isn't valid.
|
|
448
|
+
if (!hasSubSchema)
|
|
449
|
+
return false;
|
|
450
|
+
}
|
|
451
|
+
if (s['type'] === 'object' && s['properties']) {
|
|
452
|
+
if (typeof s['properties'] === 'object' && s['properties'] !== null) {
|
|
453
|
+
for (const prop of Object.values(s['properties'])) {
|
|
454
|
+
if (!hasValidTypes(prop)) {
|
|
455
|
+
return false;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
if (s['type'] === 'array' && s['items']) {
|
|
461
|
+
if (!hasValidTypes(s['items'])) {
|
|
462
|
+
return false;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
return true;
|
|
466
|
+
}
|
|
294
467
|
/**
|
|
295
468
|
* Discovers and sanitizes tools from a connected MCP client.
|
|
296
469
|
* It retrieves function declarations from the client, filters out disabled tools,
|
|
@@ -316,6 +489,12 @@ export async function discoverTools(mcpServerName, mcpServerConfig, mcpClient) {
|
|
|
316
489
|
if (!isEnabled(funcDecl, mcpServerName, mcpServerConfig)) {
|
|
317
490
|
continue;
|
|
318
491
|
}
|
|
492
|
+
if (!hasValidTypes(funcDecl.parametersJsonSchema)) {
|
|
493
|
+
console.warn(`Skipping tool '${funcDecl.name}' from MCP server '${mcpServerName}' ` +
|
|
494
|
+
`because it has missing types in its parameter schema. Please file an ` +
|
|
495
|
+
`issue with the owner of the MCP server.`);
|
|
496
|
+
continue;
|
|
497
|
+
}
|
|
319
498
|
discoveredTools.push(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, funcDecl.name, funcDecl.description ?? '', funcDecl.parametersJsonSchema ?? { type: 'object', properties: {} }, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
|
|
320
499
|
}
|
|
321
500
|
catch (error) {
|
|
@@ -341,6 +520,9 @@ export async function discoverTools(mcpServerName, mcpServerConfig, mcpClient) {
|
|
|
341
520
|
*/
|
|
342
521
|
export async function discoverPrompts(mcpServerName, mcpClient, promptRegistry) {
|
|
343
522
|
try {
|
|
523
|
+
// Only request prompts if the server supports them.
|
|
524
|
+
if (mcpClient.getServerCapabilities()?.prompts == null)
|
|
525
|
+
return [];
|
|
344
526
|
const response = await mcpClient.request({ method: 'prompts/list', params: {} }, ListPromptsResultSchema);
|
|
345
527
|
for (const prompt of response.prompts) {
|
|
346
528
|
promptRegistry.registerPrompt({
|
|
@@ -399,11 +581,52 @@ export async function invokeMcpPrompt(mcpServerName, mcpClient, promptName, prom
|
|
|
399
581
|
* @returns A promise that resolves to a connected MCP `Client` instance.
|
|
400
582
|
* @throws An error if the connection fails or the configuration is invalid.
|
|
401
583
|
*/
|
|
402
|
-
export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode) {
|
|
584
|
+
export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMode, workspaceContext) {
|
|
403
585
|
const mcpClient = new Client({
|
|
404
586
|
name: 'gemini-cli-mcp-client',
|
|
405
587
|
version: '0.0.1',
|
|
406
588
|
});
|
|
589
|
+
mcpClient.registerCapabilities({
|
|
590
|
+
roots: {
|
|
591
|
+
listChanged: true,
|
|
592
|
+
},
|
|
593
|
+
});
|
|
594
|
+
mcpClient.setRequestHandler(ListRootsRequestSchema, async () => {
|
|
595
|
+
const roots = [];
|
|
596
|
+
for (const dir of workspaceContext.getDirectories()) {
|
|
597
|
+
roots.push({
|
|
598
|
+
uri: pathToFileURL(dir).toString(),
|
|
599
|
+
name: basename(dir),
|
|
600
|
+
});
|
|
601
|
+
}
|
|
602
|
+
return {
|
|
603
|
+
roots,
|
|
604
|
+
};
|
|
605
|
+
});
|
|
606
|
+
let unlistenDirectories = workspaceContext.onDirectoriesChanged(async () => {
|
|
607
|
+
try {
|
|
608
|
+
await mcpClient.notification({
|
|
609
|
+
method: 'notifications/roots/list_changed',
|
|
610
|
+
});
|
|
611
|
+
}
|
|
612
|
+
catch (_) {
|
|
613
|
+
// If this fails, its almost certainly because the connection was closed
|
|
614
|
+
// and we should just stop listening for future directory changes.
|
|
615
|
+
unlistenDirectories?.();
|
|
616
|
+
unlistenDirectories = undefined;
|
|
617
|
+
}
|
|
618
|
+
});
|
|
619
|
+
// Attempt to pro-actively unsubscribe if the mcp client closes. This API is
|
|
620
|
+
// very brittle though so we don't have any guarantees, hence the try/catch
|
|
621
|
+
// above as well.
|
|
622
|
+
//
|
|
623
|
+
// Be a good steward and don't just bash over onclose.
|
|
624
|
+
const oldOnClose = mcpClient.onclose;
|
|
625
|
+
mcpClient.onclose = () => {
|
|
626
|
+
oldOnClose?.();
|
|
627
|
+
unlistenDirectories?.();
|
|
628
|
+
unlistenDirectories = undefined;
|
|
629
|
+
};
|
|
407
630
|
// patch Client.callTool to use request timeout as genai McpCallTool.callTool does not do it
|
|
408
631
|
// TODO: remove this hack once GenAI SDK does callTool with request options
|
|
409
632
|
if ('callTool' in mcpClient) {
|
|
@@ -574,8 +797,10 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
|
|
|
574
797
|
scopes: oauthConfig.scopes || [],
|
|
575
798
|
};
|
|
576
799
|
// Perform OAuth authentication
|
|
800
|
+
// Pass the server URL for proper discovery
|
|
801
|
+
const serverUrl = mcpServerConfig.httpUrl || mcpServerConfig.url;
|
|
577
802
|
console.log(`Starting OAuth authentication for server '${mcpServerName}'...`);
|
|
578
|
-
await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig);
|
|
803
|
+
await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig, serverUrl);
|
|
579
804
|
// Retry connection with OAuth token
|
|
580
805
|
const credentials = await MCPOAuthTokenStorage.getToken(mcpServerName);
|
|
581
806
|
if (credentials) {
|
|
@@ -643,7 +868,7 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
|
|
|
643
868
|
else {
|
|
644
869
|
conciseError = `Connection failed for '${mcpServerName}': ${errorMessage}`;
|
|
645
870
|
}
|
|
646
|
-
if (process.env
|
|
871
|
+
if (process.env['SANDBOX']) {
|
|
647
872
|
conciseError += ` (check sandbox availability)`;
|
|
648
873
|
}
|
|
649
874
|
throw new Error(conciseError);
|