Skip to content

Commit 23b7d51

Browse files
committed
Fixes for PR review feedback
1 parent 87dcf14 commit 23b7d51

File tree

4 files changed

+30
-25
lines changed

4 files changed

+30
-25
lines changed

server/dist/codeql-development-mcp-server.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200683,13 +200683,14 @@ function resolveZodSchema(inputSchema) {
200683200683
}
200684200684
function patchValidateToolInput(server) {
200685200685
const instance = server;
200686+
const originalValidateToolInput = instance.validateToolInput.bind(instance);
200686200687
instance.validateToolInput = async function(tool, args, toolName) {
200687200688
if (!tool.inputSchema) {
200688200689
return void 0;
200689200690
}
200690200691
const schema2 = resolveZodSchema(tool.inputSchema);
200691200692
if (!schema2) {
200692-
return args;
200693+
return originalValidateToolInput(tool, args, toolName);
200693200694
}
200694200695
const parseResult = await schema2.safeParseAsync(args);
200695200696
if (!parseResult.success) {

server/dist/codeql-development-mcp-server.js.map

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

server/src/lib/tool-validation.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,11 +90,12 @@ function resolveZodSchema(inputSchema: unknown): z.ZodTypeAny | undefined {
9090
return undefined;
9191
}
9292

93-
// ─── Prototype patch ─────────────────────────────────────────────────────────
93+
// ─── Instance patch ─────────────────────────────────────────────────────────
9494

9595
/**
96-
* Patch `McpServer.prototype.validateToolInput` so that **all** validation
97-
* errors are reported in a single response instead of only the first one.
96+
* Patch `validateToolInput` on the given McpServer **instance** so that
97+
* **all** validation errors are reported in a single response instead of
98+
* only the first one.
9899
*
99100
* Call this once after constructing the McpServer and before connecting
100101
* any transport.
@@ -103,6 +104,9 @@ export function patchValidateToolInput(server: McpServer): void {
103104
// eslint-disable-next-line @typescript-eslint/no-explicit-any
104105
const instance = server as any;
105106

107+
// Capture the original so we can delegate for unrecognized schema types
108+
const originalValidateToolInput = instance.validateToolInput.bind(instance);
109+
106110
instance.validateToolInput = async function (
107111
tool: { inputSchema?: unknown },
108112
args: unknown,
@@ -114,8 +118,9 @@ export function patchValidateToolInput(server: McpServer): void {
114118

115119
const schema = resolveZodSchema(tool.inputSchema);
116120
if (!schema) {
117-
// Unrecognized schema type — fall back to no validation (same as SDK)
118-
return args;
121+
// Unrecognized schema type — delegate to the original SDK validation
122+
// so mis-registered tools don't accidentally bypass input validation.
123+
return originalValidateToolInput(tool, args, toolName);
119124
}
120125

121126
const parseResult = await schema.safeParseAsync(args);

server/test/src/lib/tool-validation.test.ts

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -102,17 +102,17 @@ describe('formatAllValidationErrors', () => {
102102
describe('patchValidateToolInput', () => {
103103
it('should override validateToolInput on the server instance', () => {
104104
const server = new McpServer({ name: 'test', version: '1.0.0' });
105-
105+
106106
const original = (server as any).validateToolInput;
107107
patchValidateToolInput(server);
108-
108+
109109
expect((server as any).validateToolInput).not.toBe(original);
110110
});
111111

112112
it('should return undefined when tool has no inputSchema', async () => {
113113
const server = new McpServer({ name: 'test', version: '1.0.0' });
114114
patchValidateToolInput(server);
115-
115+
116116
const result = await (server as any).validateToolInput({}, {}, 'test_tool');
117117
expect(result).toBeUndefined();
118118
});
@@ -123,7 +123,7 @@ describe('patchValidateToolInput', () => {
123123
const tool = {
124124
inputSchema: { owner: z.string(), repo: z.string() },
125125
};
126-
126+
127127
const result = await (server as any).validateToolInput(
128128
tool,
129129
{ owner: 'octocat', repo: 'hello-world' },
@@ -138,7 +138,7 @@ describe('patchValidateToolInput', () => {
138138
const tool = {
139139
inputSchema: z.object({ owner: z.string(), repo: z.string() }),
140140
};
141-
141+
142142
const result = await (server as any).validateToolInput(
143143
tool,
144144
{ owner: 'octocat', repo: 'hello-world' },
@@ -158,7 +158,7 @@ describe('patchValidateToolInput', () => {
158158
},
159159
};
160160
try {
161-
161+
162162
await (server as any).validateToolInput(tool, {}, 'audit_store_findings');
163163
expect.fail('Should have thrown');
164164
} catch (error: unknown) {
@@ -181,7 +181,7 @@ describe('patchValidateToolInput', () => {
181181
}),
182182
};
183183
try {
184-
184+
185185
await (server as any).validateToolInput(tool, {}, 'annotation_create');
186186
expect.fail('Should have thrown');
187187
} catch (error: unknown) {
@@ -200,7 +200,7 @@ describe('patchValidateToolInput', () => {
200200
inputSchema: { owner: z.string(), repo: z.string().optional() },
201201
};
202202
try {
203-
203+
204204
await (server as any).validateToolInput(tool, {}, 'test_tool');
205205
expect.fail('Should have thrown');
206206
} catch (error: unknown) {
@@ -220,7 +220,7 @@ describe('patchValidateToolInput', () => {
220220
},
221221
};
222222
try {
223-
223+
224224
await (server as any).validateToolInput(
225225
tool,
226226
{ count: 'not-a-number' },
@@ -234,17 +234,16 @@ describe('patchValidateToolInput', () => {
234234
}
235235
});
236236

237-
it('should pass through args for unrecognized schema types', async () => {
237+
it('should delegate to original validateToolInput for unrecognized schema types', async () => {
238238
const server = new McpServer({ name: 'test', version: '1.0.0' });
239239
patchValidateToolInput(server);
240240
const tool = { inputSchema: 'not-a-zod-schema' };
241-
242-
const result = await (server as any).validateToolInput(
243-
tool,
244-
{ foo: 'bar' },
245-
'test_tool',
246-
);
247-
expect(result).toEqual({ foo: 'bar' });
241+
242+
// The original SDK validateToolInput will attempt to parse and may
243+
// throw or return — either way, validation is not silently skipped.
244+
await expect(
245+
(server as any).validateToolInput(tool, { foo: 'bar' }, 'test_tool'),
246+
).rejects.toThrow();
248247
});
249248
});
250249

0 commit comments

Comments
 (0)