summaryrefslogtreecommitdiff
path: root/packages/cli/src/ui
diff options
context:
space:
mode:
Diffstat (limited to 'packages/cli/src/ui')
-rw-r--r--packages/cli/src/ui/commands/mcpCommand.test.ts80
-rw-r--r--packages/cli/src/ui/commands/mcpCommand.ts47
2 files changed, 126 insertions, 1 deletions
diff --git a/packages/cli/src/ui/commands/mcpCommand.test.ts b/packages/cli/src/ui/commands/mcpCommand.test.ts
index e52cb9df..2b8753a0 100644
--- a/packages/cli/src/ui/commands/mcpCommand.test.ts
+++ b/packages/cli/src/ui/commands/mcpCommand.test.ts
@@ -976,4 +976,84 @@ describe('mcpCommand', () => {
}
});
});
+
+ describe('refresh subcommand', () => {
+ it('should refresh the list of tools and display the status', async () => {
+ const mockToolRegistry = {
+ discoverMcpTools: vi.fn(),
+ getAllTools: vi.fn().mockReturnValue([]),
+ };
+ const mockGeminiClient = {
+ setTools: vi.fn(),
+ };
+
+ const context = createMockCommandContext({
+ services: {
+ config: {
+ getMcpServers: vi.fn().mockReturnValue({ server1: {} }),
+ getBlockedMcpServers: vi.fn().mockReturnValue([]),
+ getToolRegistry: vi.fn().mockResolvedValue(mockToolRegistry),
+ getGeminiClient: vi.fn().mockReturnValue(mockGeminiClient),
+ },
+ },
+ });
+
+ const refreshCommand = mcpCommand.subCommands?.find(
+ (cmd) => cmd.name === 'refresh',
+ );
+ expect(refreshCommand).toBeDefined();
+
+ const result = await refreshCommand!.action!(context, '');
+
+ expect(context.ui.addItem).toHaveBeenCalledWith(
+ {
+ type: 'info',
+ text: 'Refreshing MCP servers and tools...',
+ },
+ expect.any(Number),
+ );
+ expect(mockToolRegistry.discoverMcpTools).toHaveBeenCalled();
+ expect(mockGeminiClient.setTools).toHaveBeenCalled();
+
+ expect(isMessageAction(result)).toBe(true);
+ if (isMessageAction(result)) {
+ expect(result.messageType).toBe('info');
+ expect(result.content).toContain('Configured MCP servers:');
+ }
+ });
+
+ it('should show an error if config is not available', async () => {
+ const contextWithoutConfig = createMockCommandContext({
+ services: {
+ config: null,
+ },
+ });
+
+ const refreshCommand = mcpCommand.subCommands?.find(
+ (cmd) => cmd.name === 'refresh',
+ );
+ const result = await refreshCommand!.action!(contextWithoutConfig, '');
+
+ expect(result).toEqual({
+ type: 'message',
+ messageType: 'error',
+ content: 'Config not loaded.',
+ });
+ });
+
+ it('should show an error if tool registry is not available', async () => {
+ mockConfig.getToolRegistry = vi.fn().mockResolvedValue(undefined);
+
+ const refreshCommand = mcpCommand.subCommands?.find(
+ (cmd) => cmd.name === 'refresh',
+ );
+ const result = await refreshCommand!.action!(mockContext, '');
+
+ expect(result).toEqual({
+ type: 'message',
+ messageType: 'error',
+ content: 'Could not retrieve tool registry.',
+ });
+ });
+ });
});
diff --git a/packages/cli/src/ui/commands/mcpCommand.ts b/packages/cli/src/ui/commands/mcpCommand.ts
index c33a25d1..5467b994 100644
--- a/packages/cli/src/ui/commands/mcpCommand.ts
+++ b/packages/cli/src/ui/commands/mcpCommand.ts
@@ -417,12 +417,57 @@ const listCommand: SlashCommand = {
},
};
+const refreshCommand: SlashCommand = {
+ name: 'refresh',
+ description: 'Refresh the list of MCP servers and tools',
+ kind: CommandKind.BUILT_IN,
+ action: async (
+ context: CommandContext,
+ ): Promise<SlashCommandActionReturn> => {
+ const { config } = context.services;
+ if (!config) {
+ return {
+ type: 'message',
+ messageType: 'error',
+ content: 'Config not loaded.',
+ };
+ }
+
+ const toolRegistry = await config.getToolRegistry();
+ if (!toolRegistry) {
+ return {
+ type: 'message',
+ messageType: 'error',
+ content: 'Could not retrieve tool registry.',
+ };
+ }
+
+ context.ui.addItem(
+ {
+ type: 'info',
+ text: 'Refreshing MCP servers and tools...',
+ },
+ Date.now(),
+ );
+
+ await toolRegistry.discoverMcpTools();
+
+ // Update the client with the new tools
+ const geminiClient = config.getGeminiClient();
+ if (geminiClient) {
+ await geminiClient.setTools();
+ }
+
+ return getMcpStatus(context, false, false, false);
+ },
+};
+
export const mcpCommand: SlashCommand = {
name: 'mcp',
description:
'list configured MCP servers and tools, or authenticate with OAuth-enabled servers',
kind: CommandKind.BUILT_IN,
- subCommands: [listCommand, authCommand],
+ subCommands: [listCommand, authCommand, refreshCommand],
// Default action when no subcommand is provided
action: async (context: CommandContext, args: string) =>
// If no subcommand, run the list command