Skip to content

Commit 1583603

Browse files
authored
Merge pull request #67 from m-roberts/patch-1
fix: properly support required/optional tool input schema
2 parents 4f3fa17 + 26e0ff9 commit 1583603

File tree

1 file changed

+39
-17
lines changed

1 file changed

+39
-17
lines changed

src/tools/BaseTool.ts

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export interface ToolProtocol extends SDKTool {
3838
inputSchema: {
3939
type: "object";
4040
properties?: Record<string, unknown>;
41+
required?: string[];
4142
};
4243
};
4344
toolCall(request: {
@@ -54,19 +55,34 @@ export abstract class MCPTool<TInput extends Record<string, any> = {}>
5455
protected useStringify: boolean = true;
5556
[key: string]: unknown;
5657

57-
get inputSchema(): { type: "object"; properties?: Record<string, unknown> } {
58-
return {
59-
type: "object" as const,
60-
properties: Object.fromEntries(
61-
Object.entries(this.schema).map(([key, schema]) => [
62-
key,
63-
{
64-
type: this.getJsonSchemaType(schema.type),
65-
description: schema.description,
66-
},
67-
])
68-
),
58+
get inputSchema(): { type: "object"; properties?: Record<string, unknown>; required?: string[] } {
59+
const properties: Record<string, unknown> = {};
60+
const required: string[] = [];
61+
62+
Object.entries(this.schema).forEach(([key, schema]) => {
63+
// Determine the correct JSON schema type (unwrapping optional if necessary)
64+
const jsonType = this.getJsonSchemaType(schema.type);
65+
properties[key] = {
66+
type: jsonType,
67+
description: schema.description,
68+
};
69+
70+
// If the field is not an optional, add it to the required array.
71+
if (!(schema.type instanceof z.ZodOptional)) {
72+
required.push(key);
73+
}
74+
});
75+
76+
const inputSchema: { type: "object"; properties: Record<string, unknown>; required?: string[] } = {
77+
type: "object",
78+
properties,
6979
};
80+
81+
if (required.length > 0) {
82+
inputSchema.required = required;
83+
}
84+
85+
return inputSchema;
7086
}
7187

7288
get toolDefinition() {
@@ -103,11 +119,17 @@ export abstract class MCPTool<TInput extends Record<string, any> = {}>
103119
}
104120

105121
private getJsonSchemaType(zodType: z.ZodType<any>): string {
106-
if (zodType instanceof z.ZodString) return "string";
107-
if (zodType instanceof z.ZodNumber) return "number";
108-
if (zodType instanceof z.ZodBoolean) return "boolean";
109-
if (zodType instanceof z.ZodArray) return "array";
110-
if (zodType instanceof z.ZodObject) return "object";
122+
// Unwrap optional types to correctly determine the JSON schema type.
123+
let currentType = zodType;
124+
if (currentType instanceof z.ZodOptional) {
125+
currentType = currentType.unwrap();
126+
}
127+
128+
if (currentType instanceof z.ZodString) return "string";
129+
if (currentType instanceof z.ZodNumber) return "number";
130+
if (currentType instanceof z.ZodBoolean) return "boolean";
131+
if (currentType instanceof z.ZodArray) return "array";
132+
if (currentType instanceof z.ZodObject) return "object";
111133
return "string";
112134
}
113135

0 commit comments

Comments
 (0)