fix(core): handle non-compliant mcpbridge responses from Xcode 26.3 (#18376)

This commit is contained in:
Peter Friese
2026-02-05 18:03:32 +01:00
committed by GitHub
parent ee58e1e3c1
commit 1cae5ab158
3 changed files with 254 additions and 8 deletions
+33 -8
View File
@@ -42,6 +42,7 @@ import { AuthProviderType } from '../config/config.js';
import { GoogleCredentialProvider } from '../mcp/google-auth-provider.js';
import { ServiceAccountImpersonationProvider } from '../mcp/sa-impersonation-provider.js';
import { DiscoveredMCPTool } from './mcp-tool.js';
import { XcodeMcpBridgeFixTransport } from './xcode-mcp-fix-transport.js';
import type { CallableTool, FunctionCall, Part, Tool } from '@google/genai';
import { basename } from 'node:path';
@@ -1905,7 +1906,7 @@ export async function createTransport(
}
if (mcpServerConfig.command) {
const transport = new StdioClientTransport({
let transport: Transport = new StdioClientTransport({
command: mcpServerConfig.command,
args: mcpServerConfig.args || [],
env: sanitizeEnvironment(
@@ -1928,14 +1929,38 @@ export async function createTransport(
cwd: mcpServerConfig.cwd,
stderr: 'pipe',
});
// Fix for Xcode 26.3 mcpbridge non-compliant responses
// It returns JSON in `content` instead of `structuredContent`
if (
mcpServerConfig.command === 'xcrun' &&
mcpServerConfig.args?.includes('mcpbridge')
) {
transport = new XcodeMcpBridgeFixTransport(transport);
}
if (debugMode) {
transport.stderr!.on('data', (data) => {
const stderrStr = data.toString().trim();
debugLogger.debug(
`[DEBUG] [MCP STDERR (${mcpServerName})]: `,
stderrStr,
);
});
// The `XcodeMcpBridgeFixTransport` wrapper hides the underlying `StdioClientTransport`,
// which exposes `stderr` for debug logging. We need to unwrap it to attach the listener.
const underlyingTransport =
transport instanceof XcodeMcpBridgeFixTransport
? // eslint-disable-next-line @typescript-eslint/no-explicit-any
(transport as any).transport
: transport;
if (
underlyingTransport instanceof StdioClientTransport &&
underlyingTransport.stderr
) {
underlyingTransport.stderr.on('data', (data) => {
const stderrStr = data.toString().trim();
debugLogger.debug(
`[DEBUG] [MCP STDERR (${mcpServerName})]: `,
stderrStr,
);
});
}
}
return transport;
}