diff options
Diffstat (limited to 'packages/cli/src/ui/commands')
| -rw-r--r-- | packages/cli/src/ui/commands/mcpCommand.test.ts | 18 | ||||
| -rw-r--r-- | packages/cli/src/ui/commands/mcpCommand.ts | 65 | ||||
| -rw-r--r-- | packages/cli/src/ui/commands/types.ts | 1 |
3 files changed, 71 insertions, 13 deletions
diff --git a/packages/cli/src/ui/commands/mcpCommand.test.ts b/packages/cli/src/ui/commands/mcpCommand.test.ts index 2b8753a0..afa71ba5 100644 --- a/packages/cli/src/ui/commands/mcpCommand.test.ts +++ b/packages/cli/src/ui/commands/mcpCommand.test.ts @@ -71,6 +71,7 @@ describe('mcpCommand', () => { getToolRegistry: ReturnType<typeof vi.fn>; getMcpServers: ReturnType<typeof vi.fn>; getBlockedMcpServers: ReturnType<typeof vi.fn>; + getPromptRegistry: ReturnType<typeof vi.fn>; }; beforeEach(() => { @@ -92,6 +93,10 @@ describe('mcpCommand', () => { }), getMcpServers: vi.fn().mockReturnValue({}), getBlockedMcpServers: vi.fn().mockReturnValue([]), + getPromptRegistry: vi.fn().mockResolvedValue({ + getAllPrompts: vi.fn().mockReturnValue([]), + getPromptsByServer: vi.fn().mockReturnValue([]), + }), }; mockContext = createMockCommandContext({ @@ -223,7 +228,7 @@ describe('mcpCommand', () => { // Server 2 - Connected expect(message).toContain( - '🟢 \u001b[1mserver2\u001b[0m - Ready (1 tools)', + '🟢 \u001b[1mserver2\u001b[0m - Ready (1 tool)', ); expect(message).toContain('server2_tool1'); @@ -365,13 +370,13 @@ describe('mcpCommand', () => { if (isMessageAction(result)) { const message = result.content; expect(message).toContain( - '🟢 \u001b[1mserver1\u001b[0m - Ready (1 tools)', + '🟢 \u001b[1mserver1\u001b[0m - Ready (1 tool)', ); expect(message).toContain('\u001b[36mserver1_tool1\u001b[0m'); expect(message).toContain( '🔴 \u001b[1mserver2\u001b[0m - Disconnected (0 tools cached)', ); - expect(message).toContain('No tools available'); + expect(message).toContain('No tools or prompts available'); } }); @@ -421,10 +426,10 @@ describe('mcpCommand', () => { // Check server statuses expect(message).toContain( - '🟢 \u001b[1mserver1\u001b[0m - Ready (1 tools)', + '🟢 \u001b[1mserver1\u001b[0m - Ready (1 tool)', ); expect(message).toContain( - '🔄 \u001b[1mserver2\u001b[0m - Starting... (first startup may take longer) (tools will appear when ready)', + '🔄 \u001b[1mserver2\u001b[0m - Starting... (first startup may take longer) (tools and prompts will appear when ready)', ); } }); @@ -994,6 +999,9 @@ describe('mcpCommand', () => { getBlockedMcpServers: vi.fn().mockReturnValue([]), getToolRegistry: vi.fn().mockResolvedValue(mockToolRegistry), getGeminiClient: vi.fn().mockReturnValue(mockGeminiClient), + getPromptRegistry: vi.fn().mockResolvedValue({ + getPromptsByServer: vi.fn().mockReturnValue([]), + }), }, }, }); diff --git a/packages/cli/src/ui/commands/mcpCommand.ts b/packages/cli/src/ui/commands/mcpCommand.ts index 5467b994..709053b6 100644 --- a/packages/cli/src/ui/commands/mcpCommand.ts +++ b/packages/cli/src/ui/commands/mcpCommand.ts @@ -12,6 +12,7 @@ import { MessageActionReturn, } from './types.js'; import { + DiscoveredMCPPrompt, DiscoveredMCPTool, getMCPDiscoveryState, getMCPServerStatus, @@ -101,6 +102,8 @@ const getMcpStatus = async ( (tool) => tool instanceof DiscoveredMCPTool && tool.serverName === serverName, ) as DiscoveredMCPTool[]; + const promptRegistry = await config.getPromptRegistry(); + const serverPrompts = promptRegistry.getPromptsByServer(serverName) || []; const status = getMCPServerStatus(serverName); @@ -160,9 +163,26 @@ const getMcpStatus = async ( // Add tool count with conditional messaging if (status === MCPServerStatus.CONNECTED) { - message += ` (${serverTools.length} tools)`; + const parts = []; + if (serverTools.length > 0) { + parts.push( + `${serverTools.length} ${serverTools.length === 1 ? 'tool' : 'tools'}`, + ); + } + if (serverPrompts.length > 0) { + parts.push( + `${serverPrompts.length} ${ + serverPrompts.length === 1 ? 'prompt' : 'prompts' + }`, + ); + } + if (parts.length > 0) { + message += ` (${parts.join(', ')})`; + } else { + message += ` (0 tools)`; + } } else if (status === MCPServerStatus.CONNECTING) { - message += ` (tools will appear when ready)`; + message += ` (tools and prompts will appear when ready)`; } else { message += ` (${serverTools.length} tools cached)`; } @@ -186,6 +206,7 @@ const getMcpStatus = async ( message += RESET_COLOR; if (serverTools.length > 0) { + message += ` ${COLOR_CYAN}Tools:${RESET_COLOR}\n`; serverTools.forEach((tool) => { if (showDescriptions && tool.description) { // Format tool name in cyan using simple ANSI cyan color @@ -222,12 +243,41 @@ const getMcpStatus = async ( } } }); - } else { + } + if (serverPrompts.length > 0) { + if (serverTools.length > 0) { + message += '\n'; + } + message += ` ${COLOR_CYAN}Prompts:${RESET_COLOR}\n`; + serverPrompts.forEach((prompt: DiscoveredMCPPrompt) => { + if (showDescriptions && prompt.description) { + message += ` - ${COLOR_CYAN}${prompt.name}${RESET_COLOR}`; + const descLines = prompt.description.trim().split('\n'); + if (descLines) { + message += ':\n'; + for (const descLine of descLines) { + message += ` ${COLOR_GREEN}${descLine}${RESET_COLOR}\n`; + } + } else { + message += '\n'; + } + } else { + message += ` - ${COLOR_CYAN}${prompt.name}${RESET_COLOR}\n`; + } + }); + } + + if (serverTools.length === 0 && serverPrompts.length === 0) { + message += ' No tools or prompts available\n'; + } else if (serverTools.length === 0) { message += ' No tools available'; if (status === MCPServerStatus.DISCONNECTED && needsAuthHint) { message += ` ${COLOR_GREY}(type: "/mcp auth ${serverName}" to authenticate this server)${RESET_COLOR}`; } message += '\n'; + } else if (status === MCPServerStatus.DISCONNECTED && needsAuthHint) { + // This case is for when serverTools.length > 0 + message += ` ${COLOR_GREY}(type: "/mcp auth ${serverName}" to authenticate this server)${RESET_COLOR}\n`; } message += '\n'; } @@ -328,11 +378,10 @@ const authCommand: SlashCommand = { // Import dynamically to avoid circular dependencies const { MCPOAuthProvider } = await import('@google/gemini-cli-core'); - // Create OAuth config for authentication (will be discovered automatically) - const oauthConfig = server.oauth || { - authorizationUrl: '', // Will be discovered automatically - tokenUrl: '', // Will be discovered automatically - }; + let oauthConfig = server.oauth; + if (!oauthConfig) { + oauthConfig = { enabled: false }; + } // Pass the MCP server URL for OAuth discovery const mcpServerUrl = server.httpUrl || server.url; diff --git a/packages/cli/src/ui/commands/types.ts b/packages/cli/src/ui/commands/types.ts index 9a1088fd..1684677c 100644 --- a/packages/cli/src/ui/commands/types.ts +++ b/packages/cli/src/ui/commands/types.ts @@ -128,6 +128,7 @@ export type SlashCommandActionReturn = export enum CommandKind { BUILT_IN = 'built-in', FILE = 'file', + MCP_PROMPT = 'mcp-prompt', } // The standardized contract for any command in the system. |
