Show stderr output from mcp servers in debug mode (#4049)

This commit is contained in:
Billy Biggs 2025-07-14 06:42:22 +02:00 committed by GitHub
parent c7840966e2
commit bc4182b9d2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 39 additions and 1 deletions

View File

@ -166,6 +166,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(mockConfig.getMcpServers).toHaveBeenCalledTimes(1); expect(mockConfig.getMcpServers).toHaveBeenCalledTimes(1);
expect(mockConfig.getMcpServerCommand).toHaveBeenCalledTimes(1); expect(mockConfig.getMcpServerCommand).toHaveBeenCalledTimes(1);
@ -196,6 +197,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(parse).toHaveBeenCalledWith(commandString, process.env); expect(parse).toHaveBeenCalledWith(commandString, process.env);
@ -243,6 +245,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(StdioClientTransport).toHaveBeenCalledWith({ expect(StdioClientTransport).toHaveBeenCalledWith({
@ -282,6 +285,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(SSEClientTransport).toHaveBeenCalledWith( expect(SSEClientTransport).toHaveBeenCalledWith(
@ -325,6 +329,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
return { serverConfig }; return { serverConfig };
@ -388,6 +393,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(StreamableHTTPClientTransport).toHaveBeenCalledWith( expect(StreamableHTTPClientTransport).toHaveBeenCalledWith(
@ -431,6 +437,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
return { serverConfig }; return { serverConfig };
@ -542,6 +549,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(3); expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(3);
@ -610,6 +618,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(1); expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(1);
@ -644,6 +653,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
), ),
).rejects.toThrow('Parsing failed'); ).rejects.toThrow('Parsing failed');
expect(mockToolRegistry.registerTool).not.toHaveBeenCalled(); expect(mockToolRegistry.registerTool).not.toHaveBeenCalled();
@ -658,6 +668,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(console.error).toHaveBeenCalledWith( expect(console.error).toHaveBeenCalledWith(
@ -683,6 +694,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(console.error).toHaveBeenCalledWith( expect(console.error).toHaveBeenCalledWith(
@ -708,6 +720,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(console.error).toHaveBeenCalledWith( expect(console.error).toHaveBeenCalledWith(
@ -732,6 +745,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
const clientInstances = vi.mocked(Client).mock.results; const clientInstances = vi.mocked(Client).mock.results;
@ -782,6 +796,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(2); expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(2);
@ -809,6 +824,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(2); expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(2);
@ -835,6 +851,7 @@ describe('discoverMcpTools', () => {
mockConfig.getMcpServers() ?? {}, mockConfig.getMcpServers() ?? {},
mockConfig.getMcpServerCommand(), mockConfig.getMcpServerCommand(),
mockToolRegistry as any, mockToolRegistry as any,
false,
); );
expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(1); expect(mockToolRegistry.registerTool).toHaveBeenCalledTimes(1);

View File

@ -127,6 +127,7 @@ export async function discoverMcpTools(
mcpServers: Record<string, MCPServerConfig>, mcpServers: Record<string, MCPServerConfig>,
mcpServerCommand: string | undefined, mcpServerCommand: string | undefined,
toolRegistry: ToolRegistry, toolRegistry: ToolRegistry,
debugMode: boolean,
): Promise<void> { ): Promise<void> {
// Set discovery state to in progress // Set discovery state to in progress
mcpDiscoveryState = MCPDiscoveryState.IN_PROGRESS; mcpDiscoveryState = MCPDiscoveryState.IN_PROGRESS;
@ -147,7 +148,12 @@ export async function discoverMcpTools(
const discoveryPromises = Object.entries(mcpServers).map( const discoveryPromises = Object.entries(mcpServers).map(
([mcpServerName, mcpServerConfig]) => ([mcpServerName, mcpServerConfig]) =>
connectAndDiscover(mcpServerName, mcpServerConfig, toolRegistry), connectAndDiscover(
mcpServerName,
mcpServerConfig,
toolRegistry,
debugMode,
),
); );
await Promise.all(discoveryPromises); await Promise.all(discoveryPromises);
@ -174,6 +180,7 @@ async function connectAndDiscover(
mcpServerName: string, mcpServerName: string,
mcpServerConfig: MCPServerConfig, mcpServerConfig: MCPServerConfig,
toolRegistry: ToolRegistry, toolRegistry: ToolRegistry,
debugMode: boolean,
): Promise<void> { ): Promise<void> {
// Initialize the server status as connecting // Initialize the server status as connecting
updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTING); updateMCPServerStatus(mcpServerName, MCPServerStatus.CONNECTING);
@ -223,6 +230,17 @@ async function connectAndDiscover(
return; return;
} }
if (
debugMode &&
transport instanceof StdioClientTransport &&
transport.stderr
) {
transport.stderr.on('data', (data) => {
const stderrStr = data.toString().trim();
console.debug(`[DEBUG] [MCP STDERR (${mcpServerName})]: `, stderrStr);
});
}
const mcpClient = new Client({ const mcpClient = new Client({
name: 'gemini-cli-mcp-client', name: 'gemini-cli-mcp-client',
version: '0.0.1', version: '0.0.1',

View File

@ -297,6 +297,7 @@ describe('ToolRegistry', () => {
mcpServerConfigVal, mcpServerConfigVal,
undefined, undefined,
toolRegistry, toolRegistry,
false,
); );
}); });
@ -318,6 +319,7 @@ describe('ToolRegistry', () => {
mcpServerConfigVal, mcpServerConfigVal,
undefined, undefined,
toolRegistry, toolRegistry,
false,
); );
}); });
}); });

View File

@ -164,6 +164,7 @@ export class ToolRegistry {
this.config.getMcpServers() ?? {}, this.config.getMcpServers() ?? {},
this.config.getMcpServerCommand(), this.config.getMcpServerCommand(),
this, this,
this.config.getDebugMode(),
); );
} }