if a field is nullable, provide a means of specifying null

This commit is contained in:
Greg Saab 2025-10-08 12:22:47 -04:00
commit 3fd0feb75a
3 changed files with 42 additions and 17 deletions

View file

@ -151,15 +151,39 @@ const ToolsTab = ({
const required = isPropertyRequired(key, inputSchema); const required = isPropertyRequired(key, inputSchema);
return ( return (
<div key={key}> <div key={key}>
<Label <div className="flex justify-between">
htmlFor={key} <Label
className="block text-sm font-medium text-gray-700 dark:text-gray-300" htmlFor={key}
> className="block text-sm font-medium text-gray-700 dark:text-gray-300"
{key} >
{required && ( {key}
<span className="text-red-500 ml-1">*</span> {required && (
)} <span className="text-red-500 ml-1">*</span>
</Label> )}
</Label>
{prop.nullable ? (
<div className="flex items-center space-x-2">
<Checkbox
id={key}
name={key}
checked={params[key] === null}
onCheckedChange={(checked: boolean) =>
setParams({
...params,
[key]: checked ? null : prop.default,
})
}
/>
<label
htmlFor={key}
className="text-sm font-medium text-gray-700 dark:text-gray-300"
>
Null
</label>
</div>
) : null}
</div>
{prop.type === "boolean" ? ( {prop.type === "boolean" ? (
<div className="flex items-center space-x-2 mt-2"> <div className="flex items-center space-x-2 mt-2">
<Checkbox <Checkbox

View file

@ -41,6 +41,7 @@ export type JsonSchemaType = {
maximum?: number; maximum?: number;
minLength?: number; minLength?: number;
maxLength?: number; maxLength?: number;
nullable?: boolean;
pattern?: string; pattern?: string;
format?: string; format?: string;
enum?: string[]; enum?: string[];

View file

@ -158,7 +158,7 @@ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType {
schema.anyOf.some((t) => (t as JsonSchemaType).type === "string") && schema.anyOf.some((t) => (t as JsonSchemaType).type === "string") &&
schema.anyOf.some((t) => (t as JsonSchemaType).type === "null") schema.anyOf.some((t) => (t as JsonSchemaType).type === "null")
) { ) {
return { ...schema, type: "string", anyOf: undefined }; return { ...schema, type: "string", anyOf: undefined, nullable: true };
} }
// Handle anyOf with exactly boolean and null (FastMCP pattern) // Handle anyOf with exactly boolean and null (FastMCP pattern)
@ -168,7 +168,7 @@ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType {
schema.anyOf.some((t) => (t as JsonSchemaType).type === "boolean") && schema.anyOf.some((t) => (t as JsonSchemaType).type === "boolean") &&
schema.anyOf.some((t) => (t as JsonSchemaType).type === "null") schema.anyOf.some((t) => (t as JsonSchemaType).type === "null")
) { ) {
return { ...schema, type: "boolean", anyOf: undefined }; return { ...schema, type: "boolean", anyOf: undefined, nullable: true };
} }
// Handle anyOf with exactly number and null (FastMCP pattern) // Handle anyOf with exactly number and null (FastMCP pattern)
@ -178,7 +178,7 @@ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType {
schema.anyOf.some((t) => (t as JsonSchemaType).type === "number") && schema.anyOf.some((t) => (t as JsonSchemaType).type === "number") &&
schema.anyOf.some((t) => (t as JsonSchemaType).type === "null") schema.anyOf.some((t) => (t as JsonSchemaType).type === "null")
) { ) {
return { ...schema, type: "number", anyOf: undefined }; return { ...schema, type: "number", anyOf: undefined, nullable: true };
} }
// Handle anyOf with exactly integer and null (FastMCP pattern) // Handle anyOf with exactly integer and null (FastMCP pattern)
@ -188,7 +188,7 @@ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType {
schema.anyOf.some((t) => (t as JsonSchemaType).type === "integer") && schema.anyOf.some((t) => (t as JsonSchemaType).type === "integer") &&
schema.anyOf.some((t) => (t as JsonSchemaType).type === "null") schema.anyOf.some((t) => (t as JsonSchemaType).type === "null")
) { ) {
return { ...schema, type: "integer", anyOf: undefined }; return { ...schema, type: "integer", anyOf: undefined, nullable: true };
} }
// Handle array type with exactly string and null // Handle array type with exactly string and null
@ -198,7 +198,7 @@ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType {
schema.type.includes("string") && schema.type.includes("string") &&
schema.type.includes("null") schema.type.includes("null")
) { ) {
return { ...schema, type: "string" }; return { ...schema, type: "string", nullable: true };
} }
// Handle array type with exactly boolean and null // Handle array type with exactly boolean and null
@ -208,7 +208,7 @@ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType {
schema.type.includes("boolean") && schema.type.includes("boolean") &&
schema.type.includes("null") schema.type.includes("null")
) { ) {
return { ...schema, type: "boolean" }; return { ...schema, type: "boolean", nullable: true };
} }
// Handle array type with exactly number and null // Handle array type with exactly number and null
@ -218,7 +218,7 @@ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType {
schema.type.includes("number") && schema.type.includes("number") &&
schema.type.includes("null") schema.type.includes("null")
) { ) {
return { ...schema, type: "number" }; return { ...schema, type: "number", nullable: true };
} }
// Handle array type with exactly integer and null // Handle array type with exactly integer and null
@ -228,7 +228,7 @@ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType {
schema.type.includes("integer") && schema.type.includes("integer") &&
schema.type.includes("null") schema.type.includes("null")
) { ) {
return { ...schema, type: "integer" }; return { ...schema, type: "integer", nullable: true };
} }
return schema; return schema;