@google/gemini-cli-core 0.1.13 → 0.1.15-nightly.250731.0c6f7884

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.
Files changed (304) hide show
  1. package/README.md +50 -1
  2. package/dist/google-gemini-cli-core-0.1.15.tgz +0 -0
  3. package/dist/src/code_assist/codeAssist.js +2 -2
  4. package/dist/src/code_assist/codeAssist.js.map +1 -1
  5. package/dist/src/code_assist/oauth2.js +9 -2
  6. package/dist/src/code_assist/oauth2.js.map +1 -1
  7. package/dist/src/code_assist/oauth2.test.js +99 -7
  8. package/dist/src/code_assist/oauth2.test.js.map +1 -1
  9. package/dist/src/code_assist/server.d.ts +4 -6
  10. package/dist/src/code_assist/server.js +4 -69
  11. package/dist/src/code_assist/server.js.map +1 -1
  12. package/dist/src/code_assist/setup.d.ts +6 -1
  13. package/dist/src/code_assist/setup.js +4 -1
  14. package/dist/src/code_assist/setup.js.map +1 -1
  15. package/dist/src/code_assist/setup.test.js +4 -1
  16. package/dist/src/code_assist/setup.test.js.map +1 -1
  17. package/dist/src/code_assist/types.d.ts +2 -2
  18. package/dist/src/config/config.d.ts +43 -11
  19. package/dist/src/config/config.js +79 -27
  20. package/dist/src/config/config.js.map +1 -1
  21. package/dist/src/config/config.test.js +34 -23
  22. package/dist/src/config/config.test.js.map +1 -1
  23. package/dist/src/config/flashFallback.test.js +24 -48
  24. package/dist/src/config/flashFallback.test.js.map +1 -1
  25. package/dist/src/config/models.d.ts +1 -0
  26. package/dist/src/config/models.js +1 -0
  27. package/dist/src/config/models.js.map +1 -1
  28. package/dist/src/core/client.d.ts +5 -2
  29. package/dist/src/core/client.js +64 -22
  30. package/dist/src/core/client.js.map +1 -1
  31. package/dist/src/core/client.test.js +199 -2
  32. package/dist/src/core/client.test.js.map +1 -1
  33. package/dist/src/core/contentGenerator.d.ts +1 -1
  34. package/dist/src/core/contentGenerator.js +1 -1
  35. package/dist/src/core/contentGenerator.js.map +1 -1
  36. package/dist/src/core/coreToolScheduler.d.ts +1 -3
  37. package/dist/src/core/coreToolScheduler.js +1 -3
  38. package/dist/src/core/coreToolScheduler.js.map +1 -1
  39. package/dist/src/core/coreToolScheduler.test.js +76 -1
  40. package/dist/src/core/coreToolScheduler.test.js.map +1 -1
  41. package/dist/src/core/geminiChat.d.ts +4 -3
  42. package/dist/src/core/geminiChat.js +9 -11
  43. package/dist/src/core/geminiChat.js.map +1 -1
  44. package/dist/src/core/geminiRequest.js +2 -37
  45. package/dist/src/core/geminiRequest.js.map +1 -1
  46. package/dist/src/core/logger.d.ts +1 -0
  47. package/dist/src/core/logger.js +24 -4
  48. package/dist/src/core/logger.js.map +1 -1
  49. package/dist/src/core/logger.test.js +61 -10
  50. package/dist/src/core/logger.test.js.map +1 -1
  51. package/dist/src/core/nonInteractiveToolExecutor.test.js +5 -5
  52. package/dist/src/core/prompts.js +43 -19
  53. package/dist/src/core/prompts.js.map +1 -1
  54. package/dist/src/core/prompts.test.js +121 -4
  55. package/dist/src/core/prompts.test.js.map +1 -1
  56. package/dist/src/core/tokenLimits.js +1 -0
  57. package/dist/src/core/tokenLimits.js.map +1 -1
  58. package/dist/src/core/turn.d.ts +7 -2
  59. package/dist/src/core/turn.js +9 -0
  60. package/dist/src/core/turn.js.map +1 -1
  61. package/dist/src/core/turn.test.js +129 -0
  62. package/dist/src/core/turn.test.js.map +1 -1
  63. package/dist/src/ide/detect-ide.d.ts +10 -0
  64. package/dist/src/ide/detect-ide.js +24 -0
  65. package/dist/src/ide/detect-ide.js.map +1 -0
  66. package/dist/src/ide/ide-client.d.ts +40 -0
  67. package/dist/src/ide/ide-client.js +152 -0
  68. package/dist/src/ide/ide-client.js.map +1 -0
  69. package/dist/src/ide/ide-installer.d.ts +15 -0
  70. package/dist/src/ide/ide-installer.js +111 -0
  71. package/dist/src/ide/ide-installer.js.map +1 -0
  72. package/dist/src/ide/ide-installer.test.js +78 -0
  73. package/dist/src/ide/ide-installer.test.js.map +1 -0
  74. package/dist/src/ide/ideContext.d.ts +279 -0
  75. package/dist/src/ide/ideContext.js +102 -0
  76. package/dist/src/ide/ideContext.js.map +1 -0
  77. package/dist/src/ide/ideContext.test.js +265 -0
  78. package/dist/src/ide/ideContext.test.js.map +1 -0
  79. package/dist/src/index.d.ts +11 -1
  80. package/dist/src/index.js +14 -1
  81. package/dist/src/index.js.map +1 -1
  82. package/dist/src/mcp/google-auth-provider.d.ts +23 -0
  83. package/dist/src/mcp/google-auth-provider.js +63 -0
  84. package/dist/src/mcp/google-auth-provider.js.map +1 -0
  85. package/dist/src/mcp/google-auth-provider.test.d.ts +6 -0
  86. package/dist/src/mcp/google-auth-provider.test.js +54 -0
  87. package/dist/src/mcp/google-auth-provider.test.js.map +1 -0
  88. package/dist/src/mcp/oauth-provider.d.ts +5 -1
  89. package/dist/src/mcp/oauth-provider.js +36 -11
  90. package/dist/src/mcp/oauth-provider.js.map +1 -1
  91. package/dist/src/mcp/oauth-provider.test.js +2 -2
  92. package/dist/src/mcp/oauth-provider.test.js.map +1 -1
  93. package/dist/src/mcp/oauth-token-storage.d.ts +3 -1
  94. package/dist/src/mcp/oauth-token-storage.js +3 -1
  95. package/dist/src/mcp/oauth-token-storage.js.map +1 -1
  96. package/dist/src/mcp/oauth-utils.js +2 -2
  97. package/dist/src/mcp/oauth-utils.js.map +1 -1
  98. package/dist/src/mcp/oauth-utils.test.js +1 -1
  99. package/dist/src/mcp/oauth-utils.test.js.map +1 -1
  100. package/dist/src/prompts/mcp-prompts.d.ts +8 -0
  101. package/dist/src/prompts/mcp-prompts.js +13 -0
  102. package/dist/src/prompts/mcp-prompts.js.map +1 -0
  103. package/dist/src/prompts/prompt-registry.d.ts +26 -0
  104. package/dist/src/prompts/prompt-registry.js +47 -0
  105. package/dist/src/prompts/prompt-registry.js.map +1 -0
  106. package/dist/src/services/fileDiscoveryService.test.js +101 -60
  107. package/dist/src/services/fileDiscoveryService.test.js.map +1 -1
  108. package/dist/src/services/gitService.test.js +67 -86
  109. package/dist/src/services/gitService.test.js.map +1 -1
  110. package/dist/src/services/loopDetectionService.d.ts +51 -5
  111. package/dist/src/services/loopDetectionService.js +140 -36
  112. package/dist/src/services/loopDetectionService.js.map +1 -1
  113. package/dist/src/services/loopDetectionService.test.js +105 -99
  114. package/dist/src/services/loopDetectionService.test.js.map +1 -1
  115. package/dist/src/services/shellExecutionService.d.ts +70 -0
  116. package/dist/src/services/shellExecutionService.js +152 -0
  117. package/dist/src/services/shellExecutionService.js.map +1 -0
  118. package/dist/src/services/shellExecutionService.test.d.ts +6 -0
  119. package/dist/src/services/shellExecutionService.test.js +258 -0
  120. package/dist/src/services/shellExecutionService.test.js.map +1 -0
  121. package/dist/src/telemetry/clearcut-logger/clearcut-logger.d.ts +3 -1
  122. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js +75 -33
  123. package/dist/src/telemetry/clearcut-logger/clearcut-logger.js.map +1 -1
  124. package/dist/src/telemetry/clearcut-logger/event-metadata-key.d.ts +3 -1
  125. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js +7 -0
  126. package/dist/src/telemetry/clearcut-logger/event-metadata-key.js.map +1 -1
  127. package/dist/src/telemetry/constants.d.ts +2 -0
  128. package/dist/src/telemetry/constants.js +2 -0
  129. package/dist/src/telemetry/constants.js.map +1 -1
  130. package/dist/src/telemetry/file-exporters.d.ts +28 -0
  131. package/dist/src/telemetry/file-exporters.js +62 -0
  132. package/dist/src/telemetry/file-exporters.js.map +1 -0
  133. package/dist/src/telemetry/index.d.ts +2 -2
  134. package/dist/src/telemetry/index.js +2 -2
  135. package/dist/src/telemetry/index.js.map +1 -1
  136. package/dist/src/telemetry/loggers.d.ts +3 -1
  137. package/dist/src/telemetry/loggers.js +33 -1
  138. package/dist/src/telemetry/loggers.js.map +1 -1
  139. package/dist/src/telemetry/sdk.js +17 -6
  140. package/dist/src/telemetry/sdk.js.map +1 -1
  141. package/dist/src/telemetry/telemetry.test.js +2 -0
  142. package/dist/src/telemetry/telemetry.test.js.map +1 -1
  143. package/dist/src/telemetry/types.d.ts +16 -2
  144. package/dist/src/telemetry/types.js +25 -1
  145. package/dist/src/telemetry/types.js.map +1 -1
  146. package/dist/src/test-utils/mockWorkspaceContext.d.ts +13 -0
  147. package/dist/src/test-utils/mockWorkspaceContext.js +24 -0
  148. package/dist/src/test-utils/mockWorkspaceContext.js.map +1 -0
  149. package/dist/src/tools/edit.js +14 -7
  150. package/dist/src/tools/edit.js.map +1 -1
  151. package/dist/src/tools/edit.test.js +37 -1
  152. package/dist/src/tools/edit.test.js.map +1 -1
  153. package/dist/src/tools/glob.js +53 -17
  154. package/dist/src/tools/glob.js.map +1 -1
  155. package/dist/src/tools/glob.test.js +32 -6
  156. package/dist/src/tools/glob.test.js.map +1 -1
  157. package/dist/src/tools/grep.d.ts +1 -1
  158. package/dist/src/tools/grep.js +81 -29
  159. package/dist/src/tools/grep.js.map +1 -1
  160. package/dist/src/tools/grep.test.js +77 -10
  161. package/dist/src/tools/grep.test.js.map +1 -1
  162. package/dist/src/tools/ls.d.ts +5 -2
  163. package/dist/src/tools/ls.js +43 -13
  164. package/dist/src/tools/ls.js.map +1 -1
  165. package/dist/src/tools/ls.test.d.ts +6 -0
  166. package/dist/src/tools/ls.test.js +356 -0
  167. package/dist/src/tools/ls.test.js.map +1 -0
  168. package/dist/src/tools/mcp-client.d.ts +31 -3
  169. package/dist/src/tools/mcp-client.js +467 -38
  170. package/dist/src/tools/mcp-client.js.map +1 -1
  171. package/dist/src/tools/mcp-client.test.js +99 -7
  172. package/dist/src/tools/mcp-client.test.js.map +1 -1
  173. package/dist/src/tools/mcp-tool.js +1 -1
  174. package/dist/src/tools/mcp-tool.js.map +1 -1
  175. package/dist/src/tools/mcp-tool.test.js +34 -0
  176. package/dist/src/tools/mcp-tool.test.js.map +1 -1
  177. package/dist/src/tools/memoryTool.d.ts +17 -2
  178. package/dist/src/tools/memoryTool.js +130 -13
  179. package/dist/src/tools/memoryTool.js.map +1 -1
  180. package/dist/src/tools/memoryTool.test.js +88 -3
  181. package/dist/src/tools/memoryTool.test.js.map +1 -1
  182. package/dist/src/tools/modifiable-tool.test.js +51 -62
  183. package/dist/src/tools/modifiable-tool.test.js.map +1 -1
  184. package/dist/src/tools/read-file.js +8 -6
  185. package/dist/src/tools/read-file.js.map +1 -1
  186. package/dist/src/tools/read-file.test.js +125 -68
  187. package/dist/src/tools/read-file.test.js.map +1 -1
  188. package/dist/src/tools/read-many-files.d.ts +5 -3
  189. package/dist/src/tools/read-many-files.js +83 -33
  190. package/dist/src/tools/read-many-files.js.map +1 -1
  191. package/dist/src/tools/read-many-files.test.js +40 -4
  192. package/dist/src/tools/read-many-files.test.js.map +1 -1
  193. package/dist/src/tools/shell.d.ts +3 -23
  194. package/dist/src/tools/shell.js +173 -300
  195. package/dist/src/tools/shell.js.map +1 -1
  196. package/dist/src/tools/shell.test.js +278 -384
  197. package/dist/src/tools/shell.test.js.map +1 -1
  198. package/dist/src/tools/tool-registry.d.ts +13 -1
  199. package/dist/src/tools/tool-registry.js +46 -2
  200. package/dist/src/tools/tool-registry.js.map +1 -1
  201. package/dist/src/tools/tool-registry.test.js +13 -5
  202. package/dist/src/tools/tool-registry.test.js.map +1 -1
  203. package/dist/src/tools/write-file.js +5 -3
  204. package/dist/src/tools/write-file.js.map +1 -1
  205. package/dist/src/tools/write-file.test.js +36 -2
  206. package/dist/src/tools/write-file.test.js.map +1 -1
  207. package/dist/src/utils/bfsFileSearch.d.ts +2 -0
  208. package/dist/src/utils/bfsFileSearch.js +51 -24
  209. package/dist/src/utils/bfsFileSearch.js.map +1 -1
  210. package/dist/src/utils/bfsFileSearch.test.js +163 -103
  211. package/dist/src/utils/bfsFileSearch.test.js.map +1 -1
  212. package/dist/src/utils/editCorrector.js +4 -4
  213. package/dist/src/utils/editCorrector.js.map +1 -1
  214. package/dist/src/utils/editCorrector.test.js +1 -1
  215. package/dist/src/utils/editor.js +16 -10
  216. package/dist/src/utils/editor.js.map +1 -1
  217. package/dist/src/utils/editor.test.js +128 -28
  218. package/dist/src/utils/editor.test.js.map +1 -1
  219. package/dist/src/utils/errorReporting.d.ts +1 -1
  220. package/dist/src/utils/errorReporting.js +2 -2
  221. package/dist/src/utils/errorReporting.js.map +1 -1
  222. package/dist/src/utils/errorReporting.test.js +44 -38
  223. package/dist/src/utils/errorReporting.test.js.map +1 -1
  224. package/dist/src/utils/fileUtils.d.ts +4 -4
  225. package/dist/src/utils/fileUtils.js +31 -15
  226. package/dist/src/utils/fileUtils.js.map +1 -1
  227. package/dist/src/utils/fileUtils.test.js +37 -37
  228. package/dist/src/utils/fileUtils.test.js.map +1 -1
  229. package/dist/src/utils/flashFallback.integration.test.js +8 -0
  230. package/dist/src/utils/flashFallback.integration.test.js.map +1 -1
  231. package/dist/src/utils/formatters.d.ts +6 -0
  232. package/dist/src/utils/formatters.js +16 -0
  233. package/dist/src/utils/formatters.js.map +1 -0
  234. package/dist/src/utils/getFolderStructure.d.ts +3 -2
  235. package/dist/src/utils/getFolderStructure.js +27 -28
  236. package/dist/src/utils/getFolderStructure.js.map +1 -1
  237. package/dist/src/utils/getFolderStructure.test.js +169 -187
  238. package/dist/src/utils/getFolderStructure.test.js.map +1 -1
  239. package/dist/src/utils/gitIgnoreParser.js +4 -7
  240. package/dist/src/utils/gitIgnoreParser.js.map +1 -1
  241. package/dist/src/utils/gitIgnoreParser.test.js +70 -61
  242. package/dist/src/utils/gitIgnoreParser.test.js.map +1 -1
  243. package/dist/src/utils/memoryDiscovery.d.ts +2 -1
  244. package/dist/src/utils/memoryDiscovery.js +11 -5
  245. package/dist/src/utils/memoryDiscovery.js.map +1 -1
  246. package/dist/src/utils/memoryDiscovery.test.js +160 -371
  247. package/dist/src/utils/memoryDiscovery.test.js.map +1 -1
  248. package/dist/src/utils/nextSpeakerChecker.js +2 -2
  249. package/dist/src/utils/nextSpeakerChecker.js.map +1 -1
  250. package/dist/src/utils/nextSpeakerChecker.test.js +2 -2
  251. package/dist/src/utils/nextSpeakerChecker.test.js.map +1 -1
  252. package/dist/src/utils/partUtils.d.ts +14 -0
  253. package/dist/src/utils/partUtils.js +65 -0
  254. package/dist/src/utils/partUtils.js.map +1 -0
  255. package/dist/src/utils/partUtils.test.d.ts +6 -0
  256. package/dist/src/utils/partUtils.test.js +130 -0
  257. package/dist/src/utils/partUtils.test.js.map +1 -0
  258. package/dist/src/utils/paths.d.ts +11 -0
  259. package/dist/src/utils/paths.js +17 -1
  260. package/dist/src/utils/paths.js.map +1 -1
  261. package/dist/src/utils/quotaErrorDetection.js +0 -2
  262. package/dist/src/utils/quotaErrorDetection.js.map +1 -1
  263. package/dist/src/utils/retry.d.ts +3 -0
  264. package/dist/src/utils/retry.js +1 -1
  265. package/dist/src/utils/retry.js.map +1 -1
  266. package/dist/src/utils/retry.test.js.map +1 -1
  267. package/dist/src/utils/schemaValidator.d.ts +1 -1
  268. package/dist/src/utils/schemaValidator.js +6 -3
  269. package/dist/src/utils/schemaValidator.js.map +1 -1
  270. package/dist/src/utils/shell-utils.d.ts +78 -0
  271. package/dist/src/utils/shell-utils.js +306 -0
  272. package/dist/src/utils/shell-utils.js.map +1 -0
  273. package/dist/src/utils/shell-utils.test.d.ts +6 -0
  274. package/dist/src/utils/shell-utils.test.js +200 -0
  275. package/dist/src/utils/shell-utils.test.js.map +1 -0
  276. package/dist/src/utils/summarizer.js +1 -30
  277. package/dist/src/utils/summarizer.js.map +1 -1
  278. package/dist/src/utils/systemEncoding.d.ts +40 -0
  279. package/dist/src/utils/systemEncoding.js +149 -0
  280. package/dist/src/utils/systemEncoding.js.map +1 -0
  281. package/dist/src/utils/systemEncoding.test.d.ts +6 -0
  282. package/dist/src/utils/systemEncoding.test.js +368 -0
  283. package/dist/src/utils/systemEncoding.test.js.map +1 -0
  284. package/dist/src/utils/textUtils.d.ts +13 -0
  285. package/dist/src/utils/textUtils.js +28 -0
  286. package/dist/src/utils/textUtils.js.map +1 -0
  287. package/dist/src/utils/workspaceContext.d.ts +47 -0
  288. package/dist/src/utils/workspaceContext.js +106 -0
  289. package/dist/src/utils/workspaceContext.js.map +1 -0
  290. package/dist/src/utils/workspaceContext.test.d.ts +6 -0
  291. package/dist/src/utils/workspaceContext.test.js +209 -0
  292. package/dist/src/utils/workspaceContext.test.js.map +1 -0
  293. package/dist/tsconfig.tsbuildinfo +1 -1
  294. package/package.json +2 -1
  295. package/dist/google-gemini-cli-core-0.1.12.tgz +0 -0
  296. package/dist/src/core/geminiRequest.test.js +0 -72
  297. package/dist/src/core/geminiRequest.test.js.map +0 -1
  298. package/dist/src/services/ideContext.d.ts +0 -126
  299. package/dist/src/services/ideContext.js +0 -98
  300. package/dist/src/services/ideContext.js.map +0 -1
  301. package/dist/src/services/ideContext.test.js +0 -111
  302. package/dist/src/services/ideContext.test.js.map +0 -1
  303. /package/dist/src/{core/geminiRequest.test.d.ts → ide/ide-installer.test.d.ts} +0 -0
  304. /package/dist/src/{services → ide}/ideContext.test.d.ts +0 -0
@@ -7,10 +7,15 @@ 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
11
  import { parse } from 'shell-quote';
12
+ import { AuthProviderType } from '../config/config.js';
13
+ import { GoogleCredentialProvider } from '../mcp/google-auth-provider.js';
11
14
  import { DiscoveredMCPTool } from './mcp-tool.js';
12
15
  import { mcpToTool } from '@google/genai';
13
- import { ActiveFileNotificationSchema, IDE_SERVER_NAME, ideContext, } from '../services/ideContext.js';
16
+ import { MCPOAuthProvider } from '../mcp/oauth-provider.js';
17
+ import { OAuthUtils } from '../mcp/oauth-utils.js';
18
+ import { MCPOAuthTokenStorage } from '../mcp/oauth-token-storage.js';
14
19
  import { getErrorMessage } from '../utils/errors.js';
15
20
  export const MCP_DEFAULT_TIMEOUT_MSEC = 10 * 60 * 1000; // default to 10 minutes
16
21
  /**
@@ -40,11 +45,15 @@ export var MCPDiscoveryState;
40
45
  /**
41
46
  * Map to track the status of each MCP server within the core package
42
47
  */
43
- const mcpServerStatusesInternal = new Map();
48
+ const serverStatuses = new Map();
44
49
  /**
45
50
  * Track the overall MCP discovery state
46
51
  */
47
52
  let mcpDiscoveryState = MCPDiscoveryState.NOT_STARTED;
53
+ /**
54
+ * Map to track which MCP servers have been discovered to require OAuth
55
+ */
56
+ export const mcpServerRequiresOAuth = new Map();
48
57
  const statusChangeListeners = [];
49
58
  /**
50
59
  * Add a listener for MCP server status changes
@@ -65,7 +74,7 @@ export function removeMCPStatusChangeListener(listener) {
65
74
  * Update the status of an MCP server
66
75
  */
67
76
  function updateMCPServerStatus(serverName, status) {
68
- mcpServerStatusesInternal.set(serverName, status);
77
+ serverStatuses.set(serverName, status);
69
78
  // Notify all listeners
70
79
  for (const listener of statusChangeListeners) {
71
80
  listener(serverName, status);
@@ -75,13 +84,13 @@ function updateMCPServerStatus(serverName, status) {
75
84
  * Get the current status of an MCP server
76
85
  */
77
86
  export function getMCPServerStatus(serverName) {
78
- return (mcpServerStatusesInternal.get(serverName) || MCPServerStatus.DISCONNECTED);
87
+ return serverStatuses.get(serverName) || MCPServerStatus.DISCONNECTED;
79
88
  }
80
89
  /**
81
90
  * Get all MCP server statuses
82
91
  */
83
92
  export function getAllMCPServerStatuses() {
84
- return new Map(mcpServerStatusesInternal);
93
+ return new Map(serverStatuses);
85
94
  }
86
95
  /**
87
96
  * Get the current MCP discovery state
@@ -89,6 +98,121 @@ export function getAllMCPServerStatuses() {
89
98
  export function getMCPDiscoveryState() {
90
99
  return mcpDiscoveryState;
91
100
  }
101
+ /**
102
+ * Extract WWW-Authenticate header from error message string.
103
+ * This is a more robust approach than regex matching.
104
+ *
105
+ * @param errorString The error message string
106
+ * @returns The www-authenticate header value if found, null otherwise
107
+ */
108
+ function extractWWWAuthenticateHeader(errorString) {
109
+ // Try multiple patterns to extract the header
110
+ const patterns = [
111
+ /www-authenticate:\s*([^\n\r]+)/i,
112
+ /WWW-Authenticate:\s*([^\n\r]+)/i,
113
+ /"www-authenticate":\s*"([^"]+)"/i,
114
+ /'www-authenticate':\s*'([^']+)'/i,
115
+ ];
116
+ for (const pattern of patterns) {
117
+ const match = errorString.match(pattern);
118
+ if (match) {
119
+ return match[1].trim();
120
+ }
121
+ }
122
+ return null;
123
+ }
124
+ /**
125
+ * Handle automatic OAuth discovery and authentication for a server.
126
+ *
127
+ * @param mcpServerName The name of the MCP server
128
+ * @param mcpServerConfig The MCP server configuration
129
+ * @param wwwAuthenticate The www-authenticate header value
130
+ * @returns True if OAuth was successfully configured and authenticated, false otherwise
131
+ */
132
+ async function handleAutomaticOAuth(mcpServerName, mcpServerConfig, wwwAuthenticate) {
133
+ try {
134
+ console.log(`🔐 '${mcpServerName}' requires OAuth authentication`);
135
+ // Always try to parse the resource metadata URI from the www-authenticate header
136
+ let oauthConfig;
137
+ const resourceMetadataUri = OAuthUtils.parseWWWAuthenticateHeader(wwwAuthenticate);
138
+ if (resourceMetadataUri) {
139
+ oauthConfig = await OAuthUtils.discoverOAuthConfig(resourceMetadataUri);
140
+ }
141
+ else if (mcpServerConfig.url) {
142
+ // Fallback: try to discover OAuth config from the base URL for SSE
143
+ const sseUrl = new URL(mcpServerConfig.url);
144
+ const baseUrl = `${sseUrl.protocol}//${sseUrl.host}`;
145
+ oauthConfig = await OAuthUtils.discoverOAuthConfig(baseUrl);
146
+ }
147
+ else if (mcpServerConfig.httpUrl) {
148
+ // Fallback: try to discover OAuth config from the base URL for HTTP
149
+ const httpUrl = new URL(mcpServerConfig.httpUrl);
150
+ const baseUrl = `${httpUrl.protocol}//${httpUrl.host}`;
151
+ oauthConfig = await OAuthUtils.discoverOAuthConfig(baseUrl);
152
+ }
153
+ if (!oauthConfig) {
154
+ console.error(`❌ Could not configure OAuth for '${mcpServerName}' - please authenticate manually with /mcp auth ${mcpServerName}`);
155
+ return false;
156
+ }
157
+ // OAuth configuration discovered - proceed with authentication
158
+ // Create OAuth configuration for authentication
159
+ const oauthAuthConfig = {
160
+ enabled: true,
161
+ authorizationUrl: oauthConfig.authorizationUrl,
162
+ tokenUrl: oauthConfig.tokenUrl,
163
+ scopes: oauthConfig.scopes || [],
164
+ };
165
+ // Perform OAuth authentication
166
+ console.log(`Starting OAuth authentication for server '${mcpServerName}'...`);
167
+ await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig);
168
+ console.log(`OAuth authentication successful for server '${mcpServerName}'`);
169
+ return true;
170
+ }
171
+ catch (error) {
172
+ console.error(`Failed to handle automatic OAuth for server '${mcpServerName}': ${getErrorMessage(error)}`);
173
+ return false;
174
+ }
175
+ }
176
+ /**
177
+ * Create a transport with OAuth token for the given server configuration.
178
+ *
179
+ * @param mcpServerName The name of the MCP server
180
+ * @param mcpServerConfig The MCP server configuration
181
+ * @param accessToken The OAuth access token
182
+ * @returns The transport with OAuth token, or null if creation fails
183
+ */
184
+ async function createTransportWithOAuth(mcpServerName, mcpServerConfig, accessToken) {
185
+ try {
186
+ if (mcpServerConfig.httpUrl) {
187
+ // Create HTTP transport with OAuth token
188
+ const oauthTransportOptions = {
189
+ requestInit: {
190
+ headers: {
191
+ ...mcpServerConfig.headers,
192
+ Authorization: `Bearer ${accessToken}`,
193
+ },
194
+ },
195
+ };
196
+ return new StreamableHTTPClientTransport(new URL(mcpServerConfig.httpUrl), oauthTransportOptions);
197
+ }
198
+ else if (mcpServerConfig.url) {
199
+ // Create SSE transport with OAuth token in Authorization header
200
+ return new SSEClientTransport(new URL(mcpServerConfig.url), {
201
+ requestInit: {
202
+ headers: {
203
+ ...mcpServerConfig.headers,
204
+ Authorization: `Bearer ${accessToken}`,
205
+ },
206
+ },
207
+ });
208
+ }
209
+ return null;
210
+ }
211
+ catch (error) {
212
+ console.error(`Failed to create OAuth transport for server '${mcpServerName}': ${getErrorMessage(error)}`);
213
+ return null;
214
+ }
215
+ }
92
216
  /**
93
217
  * Discovers tools from all configured MCP servers and registers them with the tool registry.
94
218
  * It orchestrates the connection and discovery process for each server defined in the
@@ -99,11 +223,11 @@ export function getMCPDiscoveryState() {
99
223
  * @param toolRegistry The central registry where discovered tools will be registered.
100
224
  * @returns A promise that resolves when the discovery process has been attempted for all servers.
101
225
  */
102
- export async function discoverMcpTools(mcpServers, mcpServerCommand, toolRegistry, debugMode) {
226
+ export async function discoverMcpTools(mcpServers, mcpServerCommand, toolRegistry, promptRegistry, debugMode) {
103
227
  mcpDiscoveryState = MCPDiscoveryState.IN_PROGRESS;
104
228
  try {
105
229
  mcpServers = populateMcpServerCommand(mcpServers, mcpServerCommand);
106
- const discoveryPromises = Object.entries(mcpServers).map(([mcpServerName, mcpServerConfig]) => connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, debugMode));
230
+ const discoveryPromises = Object.entries(mcpServers).map(([mcpServerName, mcpServerConfig]) => connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode));
107
231
  await Promise.all(discoveryPromises);
108
232
  }
109
233
  finally {
@@ -136,7 +260,7 @@ export function populateMcpServerCommand(mcpServers, mcpServerCommand) {
136
260
  * @param toolRegistry The registry to register discovered tools with
137
261
  * @returns Promise that resolves when discovery is complete
138
262
  */
139
- export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, debugMode) {
263
+ export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry, promptRegistry, debugMode) {
140
264
  updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTING);
141
265
  try {
142
266
  const mcpClient = await connectToMcpServer(mcpServerName, mcpServerConfig, debugMode);
@@ -145,15 +269,8 @@ export async function connectAndDiscover(mcpServerName, mcpServerConfig, toolReg
145
269
  mcpClient.onerror = (error) => {
146
270
  console.error(`MCP ERROR (${mcpServerName}):`, error.toString());
147
271
  updateMCPServerStatus(mcpServerName, MCPServerStatus.DISCONNECTED);
148
- if (mcpServerName === IDE_SERVER_NAME) {
149
- ideContext.clearActiveFileContext();
150
- }
151
272
  };
152
- if (mcpServerName === IDE_SERVER_NAME) {
153
- mcpClient.setNotificationHandler(ActiveFileNotificationSchema, (notification) => {
154
- ideContext.setActiveFileContext(notification.params);
155
- });
156
- }
273
+ await discoverPrompts(mcpServerName, mcpClient, promptRegistry);
157
274
  const tools = await discoverTools(mcpServerName, mcpServerConfig, mcpClient);
158
275
  for (const tool of tools) {
159
276
  toolRegistry.registerTool(tool);
@@ -194,15 +311,67 @@ export async function discoverTools(mcpServerName, mcpServerConfig, mcpClient) {
194
311
  }
195
312
  discoveredTools.push(new DiscoveredMCPTool(mcpCallableTool, mcpServerName, funcDecl.name, funcDecl.description ?? '', funcDecl.parametersJsonSchema ?? { type: 'object', properties: {} }, mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC, mcpServerConfig.trust));
196
313
  }
197
- if (discoveredTools.length === 0) {
198
- throw Error('No enabled tools found');
199
- }
200
314
  return discoveredTools;
201
315
  }
202
316
  catch (error) {
203
317
  throw new Error(`Error discovering tools: ${error}`);
204
318
  }
205
319
  }
320
+ /**
321
+ * Discovers and logs prompts from a connected MCP client.
322
+ * It retrieves prompt declarations from the client and logs their names.
323
+ *
324
+ * @param mcpServerName The name of the MCP server.
325
+ * @param mcpClient The active MCP client instance.
326
+ */
327
+ export async function discoverPrompts(mcpServerName, mcpClient, promptRegistry) {
328
+ try {
329
+ const response = await mcpClient.request({ method: 'prompts/list', params: {} }, ListPromptsResultSchema);
330
+ for (const prompt of response.prompts) {
331
+ promptRegistry.registerPrompt({
332
+ ...prompt,
333
+ serverName: mcpServerName,
334
+ invoke: (params) => invokeMcpPrompt(mcpServerName, mcpClient, prompt.name, params),
335
+ });
336
+ }
337
+ }
338
+ catch (error) {
339
+ // It's okay if this fails, not all servers will have prompts.
340
+ // Don't log an error if the method is not found, which is a common case.
341
+ if (error instanceof Error &&
342
+ !error.message?.includes('Method not found')) {
343
+ console.error(`Error discovering prompts from ${mcpServerName}: ${getErrorMessage(error)}`);
344
+ }
345
+ }
346
+ }
347
+ /**
348
+ * Invokes a prompt on a connected MCP client.
349
+ *
350
+ * @param mcpServerName The name of the MCP server.
351
+ * @param mcpClient The active MCP client instance.
352
+ * @param promptName The name of the prompt to invoke.
353
+ * @param promptParams The parameters to pass to the prompt.
354
+ * @returns A promise that resolves to the result of the prompt invocation.
355
+ */
356
+ export async function invokeMcpPrompt(mcpServerName, mcpClient, promptName, promptParams) {
357
+ try {
358
+ const response = await mcpClient.request({
359
+ method: 'prompts/get',
360
+ params: {
361
+ name: promptName,
362
+ arguments: promptParams,
363
+ },
364
+ }, GetPromptResultSchema);
365
+ return response;
366
+ }
367
+ catch (error) {
368
+ if (error instanceof Error &&
369
+ !error.message?.includes('Method not found')) {
370
+ console.error(`Error invoking prompt '${promptName}' from ${mcpServerName} ${promptParams}: ${getErrorMessage(error)}`);
371
+ }
372
+ throw error;
373
+ }
374
+ }
206
375
  /**
207
376
  * Creates and connects an MCP client to a server based on the provided configuration.
208
377
  * It determines the appropriate transport (Stdio, SSE, or Streamable HTTP) and
@@ -230,7 +399,7 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
230
399
  };
231
400
  }
232
401
  try {
233
- const transport = createTransport(mcpServerName, mcpServerConfig, debugMode);
402
+ const transport = await createTransport(mcpServerName, mcpServerConfig, debugMode);
234
403
  try {
235
404
  await mcpClient.connect(transport, {
236
405
  timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC,
@@ -243,29 +412,280 @@ export async function connectToMcpServer(mcpServerName, mcpServerConfig, debugMo
243
412
  }
244
413
  }
245
414
  catch (error) {
246
- // Create a safe config object that excludes sensitive information
247
- const safeConfig = {
248
- command: mcpServerConfig.command,
249
- url: mcpServerConfig.url,
250
- httpUrl: mcpServerConfig.httpUrl,
251
- cwd: mcpServerConfig.cwd,
252
- timeout: mcpServerConfig.timeout,
253
- trust: mcpServerConfig.trust,
254
- // Exclude args, env, and headers which may contain sensitive data
255
- };
256
- let errorString = `failed to start or connect to MCP server '${mcpServerName}' ` +
257
- `${JSON.stringify(safeConfig)}; \n${error}`;
258
- if (process.env.SANDBOX) {
259
- errorString += `\nMake sure it is available in the sandbox`;
415
+ // Check if this is a 401 error that might indicate OAuth is required
416
+ const errorString = String(error);
417
+ if (errorString.includes('401') &&
418
+ (mcpServerConfig.httpUrl || mcpServerConfig.url)) {
419
+ mcpServerRequiresOAuth.set(mcpServerName, true);
420
+ // Only trigger automatic OAuth discovery for HTTP servers or when OAuth is explicitly configured
421
+ // For SSE servers, we should not trigger new OAuth flows automatically
422
+ const shouldTriggerOAuth = mcpServerConfig.httpUrl || mcpServerConfig.oauth?.enabled;
423
+ if (!shouldTriggerOAuth) {
424
+ // For SSE servers without explicit OAuth config, if a token was found but rejected, report it accurately.
425
+ const credentials = await MCPOAuthTokenStorage.getToken(mcpServerName);
426
+ if (credentials) {
427
+ const hasStoredTokens = await MCPOAuthProvider.getValidToken(mcpServerName, {
428
+ // Pass client ID if available
429
+ clientId: credentials.clientId,
430
+ });
431
+ if (hasStoredTokens) {
432
+ console.log(`Stored OAuth token for SSE server '${mcpServerName}' was rejected. ` +
433
+ `Please re-authenticate using: /mcp auth ${mcpServerName}`);
434
+ }
435
+ else {
436
+ console.log(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
437
+ `Please authenticate using: /mcp auth ${mcpServerName}`);
438
+ }
439
+ }
440
+ throw new Error(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
441
+ `Please authenticate using: /mcp auth ${mcpServerName}`);
442
+ }
443
+ // Try to extract www-authenticate header from the error
444
+ let wwwAuthenticate = extractWWWAuthenticateHeader(errorString);
445
+ // If we didn't get the header from the error string, try to get it from the server
446
+ if (!wwwAuthenticate && mcpServerConfig.url) {
447
+ console.log(`No www-authenticate header in error, trying to fetch it from server...`);
448
+ try {
449
+ const response = await fetch(mcpServerConfig.url, {
450
+ method: 'HEAD',
451
+ headers: {
452
+ Accept: 'text/event-stream',
453
+ },
454
+ signal: AbortSignal.timeout(5000),
455
+ });
456
+ if (response.status === 401) {
457
+ wwwAuthenticate = response.headers.get('www-authenticate');
458
+ if (wwwAuthenticate) {
459
+ console.log(`Found www-authenticate header from server: ${wwwAuthenticate}`);
460
+ }
461
+ }
462
+ }
463
+ catch (fetchError) {
464
+ console.debug(`Failed to fetch www-authenticate header: ${getErrorMessage(fetchError)}`);
465
+ }
466
+ }
467
+ if (wwwAuthenticate) {
468
+ console.log(`Received 401 with www-authenticate header: ${wwwAuthenticate}`);
469
+ // Try automatic OAuth discovery and authentication
470
+ const oauthSuccess = await handleAutomaticOAuth(mcpServerName, mcpServerConfig, wwwAuthenticate);
471
+ if (oauthSuccess) {
472
+ // Retry connection with OAuth token
473
+ console.log(`Retrying connection to '${mcpServerName}' with OAuth token...`);
474
+ // Get the valid token - we need to create a proper OAuth config
475
+ // The token should already be available from the authentication process
476
+ const credentials = await MCPOAuthTokenStorage.getToken(mcpServerName);
477
+ if (credentials) {
478
+ const accessToken = await MCPOAuthProvider.getValidToken(mcpServerName, {
479
+ // Pass client ID if available
480
+ clientId: credentials.clientId,
481
+ });
482
+ if (accessToken) {
483
+ // Create transport with OAuth token
484
+ const oauthTransport = await createTransportWithOAuth(mcpServerName, mcpServerConfig, accessToken);
485
+ if (oauthTransport) {
486
+ try {
487
+ await mcpClient.connect(oauthTransport, {
488
+ timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC,
489
+ });
490
+ // Connection successful with OAuth
491
+ return mcpClient;
492
+ }
493
+ catch (retryError) {
494
+ console.error(`Failed to connect with OAuth token: ${getErrorMessage(retryError)}`);
495
+ throw retryError;
496
+ }
497
+ }
498
+ else {
499
+ console.error(`Failed to create OAuth transport for server '${mcpServerName}'`);
500
+ throw new Error(`Failed to create OAuth transport for server '${mcpServerName}'`);
501
+ }
502
+ }
503
+ else {
504
+ console.error(`Failed to get OAuth token for server '${mcpServerName}'`);
505
+ throw new Error(`Failed to get OAuth token for server '${mcpServerName}'`);
506
+ }
507
+ }
508
+ else {
509
+ console.error(`Failed to get credentials for server '${mcpServerName}' after successful OAuth authentication`);
510
+ throw new Error(`Failed to get credentials for server '${mcpServerName}' after successful OAuth authentication`);
511
+ }
512
+ }
513
+ else {
514
+ console.error(`Failed to handle automatic OAuth for server '${mcpServerName}'`);
515
+ throw new Error(`Failed to handle automatic OAuth for server '${mcpServerName}'`);
516
+ }
517
+ }
518
+ else {
519
+ // No www-authenticate header found, but we got a 401
520
+ // Only try OAuth discovery for HTTP servers or when OAuth is explicitly configured
521
+ // For SSE servers, we should not trigger new OAuth flows automatically
522
+ const shouldTryDiscovery = mcpServerConfig.httpUrl || mcpServerConfig.oauth?.enabled;
523
+ if (!shouldTryDiscovery) {
524
+ const credentials = await MCPOAuthTokenStorage.getToken(mcpServerName);
525
+ if (credentials) {
526
+ const hasStoredTokens = await MCPOAuthProvider.getValidToken(mcpServerName, {
527
+ // Pass client ID if available
528
+ clientId: credentials.clientId,
529
+ });
530
+ if (hasStoredTokens) {
531
+ console.log(`Stored OAuth token for SSE server '${mcpServerName}' was rejected. ` +
532
+ `Please re-authenticate using: /mcp auth ${mcpServerName}`);
533
+ }
534
+ else {
535
+ console.log(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
536
+ `Please authenticate using: /mcp auth ${mcpServerName}`);
537
+ }
538
+ }
539
+ throw new Error(`401 error received for SSE server '${mcpServerName}' without OAuth configuration. ` +
540
+ `Please authenticate using: /mcp auth ${mcpServerName}`);
541
+ }
542
+ // For SSE servers, try to discover OAuth configuration from the base URL
543
+ console.log(`🔍 Attempting OAuth discovery for '${mcpServerName}'...`);
544
+ if (mcpServerConfig.url) {
545
+ const sseUrl = new URL(mcpServerConfig.url);
546
+ const baseUrl = `${sseUrl.protocol}//${sseUrl.host}`;
547
+ try {
548
+ // Try to discover OAuth configuration from the base URL
549
+ const oauthConfig = await OAuthUtils.discoverOAuthConfig(baseUrl);
550
+ if (oauthConfig) {
551
+ console.log(`Discovered OAuth configuration from base URL for server '${mcpServerName}'`);
552
+ // Create OAuth configuration for authentication
553
+ const oauthAuthConfig = {
554
+ enabled: true,
555
+ authorizationUrl: oauthConfig.authorizationUrl,
556
+ tokenUrl: oauthConfig.tokenUrl,
557
+ scopes: oauthConfig.scopes || [],
558
+ };
559
+ // Perform OAuth authentication
560
+ console.log(`Starting OAuth authentication for server '${mcpServerName}'...`);
561
+ await MCPOAuthProvider.authenticate(mcpServerName, oauthAuthConfig);
562
+ // Retry connection with OAuth token
563
+ const credentials = await MCPOAuthTokenStorage.getToken(mcpServerName);
564
+ if (credentials) {
565
+ const accessToken = await MCPOAuthProvider.getValidToken(mcpServerName, {
566
+ // Pass client ID if available
567
+ clientId: credentials.clientId,
568
+ });
569
+ if (accessToken) {
570
+ // Create transport with OAuth token
571
+ const oauthTransport = await createTransportWithOAuth(mcpServerName, mcpServerConfig, accessToken);
572
+ if (oauthTransport) {
573
+ try {
574
+ await mcpClient.connect(oauthTransport, {
575
+ timeout: mcpServerConfig.timeout ?? MCP_DEFAULT_TIMEOUT_MSEC,
576
+ });
577
+ // Connection successful with OAuth
578
+ return mcpClient;
579
+ }
580
+ catch (retryError) {
581
+ console.error(`Failed to connect with OAuth token: ${getErrorMessage(retryError)}`);
582
+ throw retryError;
583
+ }
584
+ }
585
+ else {
586
+ console.error(`Failed to create OAuth transport for server '${mcpServerName}'`);
587
+ throw new Error(`Failed to create OAuth transport for server '${mcpServerName}'`);
588
+ }
589
+ }
590
+ else {
591
+ console.error(`Failed to get OAuth token for server '${mcpServerName}'`);
592
+ throw new Error(`Failed to get OAuth token for server '${mcpServerName}'`);
593
+ }
594
+ }
595
+ else {
596
+ console.error(`Failed to get stored credentials for server '${mcpServerName}'`);
597
+ throw new Error(`Failed to get stored credentials for server '${mcpServerName}'`);
598
+ }
599
+ }
600
+ else {
601
+ console.error(`❌ Could not configure OAuth for '${mcpServerName}' - please authenticate manually with /mcp auth ${mcpServerName}`);
602
+ throw new Error(`OAuth configuration failed for '${mcpServerName}'. Please authenticate manually with /mcp auth ${mcpServerName}`);
603
+ }
604
+ }
605
+ catch (discoveryError) {
606
+ console.error(`❌ OAuth discovery failed for '${mcpServerName}' - please authenticate manually with /mcp auth ${mcpServerName}`);
607
+ throw discoveryError;
608
+ }
609
+ }
610
+ else {
611
+ console.error(`❌ '${mcpServerName}' requires authentication but no OAuth configuration found`);
612
+ throw new Error(`MCP server '${mcpServerName}' requires authentication. Please configure OAuth or check server settings.`);
613
+ }
614
+ }
615
+ }
616
+ else {
617
+ // Handle other connection errors
618
+ // Create a concise error message
619
+ const errorMessage = error.message || String(error);
620
+ const isNetworkError = errorMessage.includes('ENOTFOUND') ||
621
+ errorMessage.includes('ECONNREFUSED');
622
+ let conciseError;
623
+ if (isNetworkError) {
624
+ conciseError = `Cannot connect to '${mcpServerName}' - server may be down or URL incorrect`;
625
+ }
626
+ else {
627
+ conciseError = `Connection failed for '${mcpServerName}': ${errorMessage}`;
628
+ }
629
+ if (process.env.SANDBOX) {
630
+ conciseError += ` (check sandbox availability)`;
631
+ }
632
+ throw new Error(conciseError);
260
633
  }
261
- throw new Error(errorString);
262
634
  }
263
635
  }
264
636
  /** Visible for Testing */
265
- export function createTransport(mcpServerName, mcpServerConfig, debugMode) {
637
+ export async function createTransport(mcpServerName, mcpServerConfig, debugMode) {
638
+ if (mcpServerConfig.authProviderType === AuthProviderType.GOOGLE_CREDENTIALS) {
639
+ const provider = new GoogleCredentialProvider(mcpServerConfig);
640
+ const transportOptions = {
641
+ authProvider: provider,
642
+ };
643
+ if (mcpServerConfig.httpUrl) {
644
+ return new StreamableHTTPClientTransport(new URL(mcpServerConfig.httpUrl), transportOptions);
645
+ }
646
+ else if (mcpServerConfig.url) {
647
+ return new SSEClientTransport(new URL(mcpServerConfig.url), transportOptions);
648
+ }
649
+ throw new Error('No URL configured for Google Credentials MCP server');
650
+ }
651
+ // Check if we have OAuth configuration or stored tokens
652
+ let accessToken = null;
653
+ let hasOAuthConfig = mcpServerConfig.oauth?.enabled;
654
+ if (hasOAuthConfig && mcpServerConfig.oauth) {
655
+ accessToken = await MCPOAuthProvider.getValidToken(mcpServerName, mcpServerConfig.oauth);
656
+ if (!accessToken) {
657
+ console.error(`MCP server '${mcpServerName}' requires OAuth authentication. ` +
658
+ `Please authenticate using the /mcp auth command.`);
659
+ throw new Error(`MCP server '${mcpServerName}' requires OAuth authentication. ` +
660
+ `Please authenticate using the /mcp auth command.`);
661
+ }
662
+ }
663
+ else {
664
+ // Check if we have stored OAuth tokens for this server (from previous authentication)
665
+ const credentials = await MCPOAuthTokenStorage.getToken(mcpServerName);
666
+ if (credentials) {
667
+ accessToken = await MCPOAuthProvider.getValidToken(mcpServerName, {
668
+ // Pass client ID if available
669
+ clientId: credentials.clientId,
670
+ });
671
+ if (accessToken) {
672
+ hasOAuthConfig = true;
673
+ console.log(`Found stored OAuth token for server '${mcpServerName}'`);
674
+ }
675
+ }
676
+ }
266
677
  if (mcpServerConfig.httpUrl) {
267
678
  const transportOptions = {};
268
- if (mcpServerConfig.headers) {
679
+ // Set up headers with OAuth token if available
680
+ if (hasOAuthConfig && accessToken) {
681
+ transportOptions.requestInit = {
682
+ headers: {
683
+ ...mcpServerConfig.headers,
684
+ Authorization: `Bearer ${accessToken}`,
685
+ },
686
+ };
687
+ }
688
+ else if (mcpServerConfig.headers) {
269
689
  transportOptions.requestInit = {
270
690
  headers: mcpServerConfig.headers,
271
691
  };
@@ -274,7 +694,16 @@ export function createTransport(mcpServerName, mcpServerConfig, debugMode) {
274
694
  }
275
695
  if (mcpServerConfig.url) {
276
696
  const transportOptions = {};
277
- if (mcpServerConfig.headers) {
697
+ // Set up headers with OAuth token if available
698
+ if (hasOAuthConfig && accessToken) {
699
+ transportOptions.requestInit = {
700
+ headers: {
701
+ ...mcpServerConfig.headers,
702
+ Authorization: `Bearer ${accessToken}`,
703
+ },
704
+ };
705
+ }
706
+ else if (mcpServerConfig.headers) {
278
707
  transportOptions.requestInit = {
279
708
  headers: mcpServerConfig.headers,
280
709
  };