Skip to content

Commit b567184

Browse files
committed
fix: allow any JSON Schema type for outputSchema
The MCP spec does not require outputSchema to have type: 'object' at the root level - it can be any valid JSON Schema. This allows tools to return arrays, primitives, or other structures for list/batch responses. inputSchema still correctly requires type: 'object' since tool inputs are always named parameters. Fixes #1149
1 parent 3c50d07 commit b567184

File tree

3 files changed

+6
-17
lines changed

3 files changed

+6
-17
lines changed

src/spec.types.ts

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1166,11 +1166,7 @@ export interface Tool extends BaseMetadata, Icons {
11661166
* An optional JSON Schema object defining the structure of the tool's output returned in
11671167
* the structuredContent field of a CallToolResult.
11681168
*/
1169-
outputSchema?: {
1170-
type: "object";
1171-
properties?: { [key: string]: object };
1172-
required?: string[];
1173-
};
1169+
outputSchema?: { [key: string]: unknown };
11741170

11751171
/**
11761172
* Optional additional tool information.

src/types.test.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -420,16 +420,17 @@ describe('Types', () => {
420420
expect(result.success).toBe(false);
421421
});
422422

423-
test('should still require type: object at root for outputSchema', () => {
423+
test('should accept outputSchema with type: array', () => {
424424
const tool = {
425425
name: 'test',
426426
inputSchema: { type: 'object' },
427427
outputSchema: {
428-
type: 'array'
428+
type: 'array',
429+
items: { type: 'string' }
429430
}
430431
};
431432
const result = ToolSchema.safeParse(tool);
432-
expect(result.success).toBe(false);
433+
expect(result.success).toBe(true);
433434
});
434435

435436
test('should accept simple minimal schema (backward compatibility)', () => {

src/types.ts

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1012,16 +1012,8 @@ export const ToolSchema = z.object({
10121012
/**
10131013
* An optional JSON Schema 2020-12 object defining the structure of the tool's output
10141014
* returned in the structuredContent field of a CallToolResult.
1015-
* Must have type: 'object' at the root level per MCP spec.
10161015
*/
1017-
outputSchema: z
1018-
.object({
1019-
type: z.literal('object'),
1020-
properties: z.record(z.string(), AssertObjectSchema).optional(),
1021-
required: z.array(z.string()).optional()
1022-
})
1023-
.catchall(z.unknown())
1024-
.optional(),
1016+
outputSchema: z.record(z.string(), z.unknown()).optional(),
10251017
/**
10261018
* Optional additional tool information.
10271019
*/

0 commit comments

Comments
 (0)