Skip to content

Commit 9937fb2

Browse files
authored
Use lenient MCP output schema validator (#13521)
1 parent 8e531dc commit 9937fb2

File tree

8 files changed

+57
-13
lines changed

8 files changed

+57
-13
lines changed

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ jobs:
108108
- name: 'Link Checker'
109109
uses: 'lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2' # ratchet: lycheeverse/[email protected]
110110
with:
111-
args: '--verbose ./**/*.md'
111+
args: '--verbose --accept 200,503 ./**/*.md'
112112
fail: true
113113
test_linux:
114114
name: 'Test (Linux)'

.github/workflows/links.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,4 +20,4 @@ jobs:
2020
id: 'lychee'
2121
uses: 'lycheeverse/lychee-action@885c65f3dc543b57c898c8099f4e08c8afd178a2' # ratchet: lycheeverse/[email protected]
2222
with:
23-
args: '--verbose --no-progress ./**/*.md'
23+
args: '--verbose --no-progress --accept 200,503 ./**/*.md'

package-lock.json

Lines changed: 3 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/cli/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"@google/gemini-cli-core": "file:../core",
3232
"@google/genai": "1.30.0",
3333
"@iarna/toml": "^2.2.5",
34-
"@modelcontextprotocol/sdk": "^1.15.1",
34+
"@modelcontextprotocol/sdk": "^1.22.0",
3535
"@types/update-notifier": "^6.0.8",
3636
"ansi-regex": "^6.2.2",
3737
"clipboardy": "^5.0.0",

packages/cli/src/commands/extensions/examples/mcp-server/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"@types/node": "^20.11.25"
1313
},
1414
"dependencies": {
15-
"@modelcontextprotocol/sdk": "^1.11.0",
15+
"@modelcontextprotocol/sdk": "^1.22.0",
1616
"zod": "^3.22.4"
1717
}
1818
}

packages/core/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"@google/genai": "1.30.0",
2727
"@iarna/toml": "^2.2.5",
2828
"@joshua.litt/get-ripgrep": "^0.0.3",
29-
"@modelcontextprotocol/sdk": "^1.11.0",
29+
"@modelcontextprotocol/sdk": "^1.22.0",
3030
"@opentelemetry/api": "^1.9.0",
3131
"@opentelemetry/exporter-logs-otlp-grpc": "^0.203.0",
3232
"@opentelemetry/exporter-logs-otlp-http": "^0.203.0",

packages/core/src/tools/mcp-client.ts

Lines changed: 48 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,12 @@
55
*/
66

77
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
8+
import { AjvJsonSchemaValidator } from '@modelcontextprotocol/sdk/validation/ajv';
9+
import type {
10+
jsonSchemaValidator,
11+
JsonSchemaType,
12+
JsonSchemaValidator,
13+
} from '@modelcontextprotocol/sdk/validation/types.js';
814
import type { SSEClientTransportOptions } from '@modelcontextprotocol/sdk/client/sse.js';
915
import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js';
1016
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
@@ -533,6 +539,38 @@ export async function discoverMcpTools(
533539
}
534540
}
535541

542+
/**
543+
* A tolerant JSON Schema validator for MCP tool output schemas.
544+
*
545+
* Some MCP servers (e.g. third‑party extensions) return complex schemas that
546+
* include `$defs` / `$ref` chains which can occasionally trip AJV's resolver,
547+
* causing discovery to fail. This wrapper keeps the default AJV validator for
548+
* normal operation but falls back to a no‑op validator any time schema
549+
* compilation throws, so we can still list and use the tool while emitting a
550+
* debug log.
551+
*/
552+
class LenientJsonSchemaValidator implements jsonSchemaValidator {
553+
private readonly ajvValidator = new AjvJsonSchemaValidator();
554+
555+
getValidator<T>(schema: JsonSchemaType): JsonSchemaValidator<T> {
556+
try {
557+
return this.ajvValidator.getValidator<T>(schema);
558+
} catch (error) {
559+
debugLogger.warn(
560+
`Failed to compile MCP tool output schema (${
561+
(schema as Record<string, unknown>)?.['$id'] ?? '<no $id>'
562+
}): ${error instanceof Error ? error.message : String(error)}. ` +
563+
'Skipping output validation for this tool.',
564+
);
565+
return (input: unknown) => ({
566+
valid: true as const,
567+
data: input as T,
568+
errorMessage: undefined,
569+
});
570+
}
571+
}
572+
}
573+
536574
/** Visible for Testing */
537575
export function populateMcpServerCommand(
538576
mcpServers: Record<string, MCPServerConfig>,
@@ -892,10 +930,16 @@ export async function connectToMcpServer(
892930
debugMode: boolean,
893931
workspaceContext: WorkspaceContext,
894932
): Promise<Client> {
895-
const mcpClient = new Client({
896-
name: 'gemini-cli-mcp-client',
897-
version: '0.0.1',
898-
});
933+
const mcpClient = new Client(
934+
{
935+
name: 'gemini-cli-mcp-client',
936+
version: '0.0.1',
937+
},
938+
{
939+
// Use a tolerant validator so bad output schemas don't block discovery.
940+
jsonSchemaValidator: new LenientJsonSchemaValidator(),
941+
},
942+
);
899943

900944
mcpClient.registerCapabilities({
901945
roots: {

packages/vscode-ide-companion/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@
137137
"vitest": "^3.2.4"
138138
},
139139
"dependencies": {
140-
"@modelcontextprotocol/sdk": "^1.15.1",
140+
"@modelcontextprotocol/sdk": "^1.22.0",
141141
"cors": "^2.8.5",
142142
"express": "^5.1.0",
143143
"zod": "^3.25.76"

0 commit comments

Comments
 (0)