Skip to content

Commit 37acee9

Browse files
committed
Handle nullable arrays in tool inputSchemas
* In DynamicJsonForm.tsx - In debouncedUpdateParent, formatJson, and validateJson, - when trimming the JSON value, use ?.trim() in case the field is null * In jsonUtils.ts - in tryParseJson - use ?.trim() in case the field is null * In schemaUtils.ts - in normalizeUnionType - add condition to handle the case where there is an anyOf with array or null as options * In ToolsTab.tsx - for nullable fields, in null checkbox, in onCheckedChange handler - when not checked, if prop type is array, set to undefined (empty input field that can be edited rather than the word "null" as the default could provide Fixes #846
1 parent c7683b4 commit 37acee9

File tree

4 files changed

+28
-15
lines changed

4 files changed

+28
-15
lines changed

client/src/components/DynamicJsonForm.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,8 @@ const DynamicJsonForm = forwardRef<DynamicJsonFormRef, DynamicJsonFormProps>(
113113
setJsonError(errorMessage);
114114

115115
// Reset to default for clearly invalid JSON (not just incomplete typing)
116-
const trimmed = jsonString.trim();
117-
if (trimmed.length > 5 && !trimmed.match(/^[\s[{]/)) {
116+
const trimmed = jsonString?.trim();
117+
if (trimmed && trimmed.length > 5 && !trimmed.match(/^[\s[{]/)) {
118118
onChange(generateDefaultValue(schema));
119119
}
120120
}
@@ -155,7 +155,7 @@ const DynamicJsonForm = forwardRef<DynamicJsonFormRef, DynamicJsonFormProps>(
155155

156156
const formatJson = () => {
157157
try {
158-
const jsonStr = rawJsonValue.trim();
158+
const jsonStr = rawJsonValue?.trim();
159159
if (!jsonStr) {
160160
return;
161161
}
@@ -171,7 +171,7 @@ const DynamicJsonForm = forwardRef<DynamicJsonFormRef, DynamicJsonFormProps>(
171171
const validateJson = () => {
172172
if (!isJsonMode) return { isValid: true, error: null };
173173
try {
174-
const jsonStr = rawJsonValue.trim();
174+
const jsonStr = rawJsonValue?.trim();
175175
if (!jsonStr) return { isValid: true, error: null };
176176
const parsed = JSON.parse(jsonStr);
177177
// Clear any pending debounced update and immediately update parent

client/src/components/ToolsTab.tsx

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -181,16 +181,18 @@ const ToolsTab = ({
181181
...params,
182182
[key]: checked
183183
? null
184-
: prop.default !== null
185-
? prop.default
186-
: prop.type === "boolean"
187-
? false
188-
: prop.type === "string"
189-
? ""
190-
: prop.type === "number" ||
191-
prop.type === "integer"
192-
? undefined
193-
: undefined,
184+
: prop.type === "array"
185+
? undefined
186+
: prop.default !== null
187+
? prop.default
188+
: prop.type === "boolean"
189+
? false
190+
: prop.type === "string"
191+
? ""
192+
: prop.type === "number" ||
193+
prop.type === "integer"
194+
? undefined
195+
: undefined,
194196
})
195197
}
196198
/>

client/src/utils/jsonUtils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ export function tryParseJson(str: string): {
8484
success: boolean;
8585
data: JsonValue;
8686
} {
87-
const trimmed = str.trim();
87+
const trimmed = str?.trim();
8888
if (
89+
trimmed &&
8990
!(trimmed.startsWith("{") && trimmed.endsWith("}")) &&
9091
!(trimmed.startsWith("[") && trimmed.endsWith("]"))
9192
) {

client/src/utils/schemaUtils.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,16 @@ export function normalizeUnionType(schema: JsonSchemaType): JsonSchemaType {
191191
return { ...schema, type: "integer", anyOf: undefined, nullable: true };
192192
}
193193

194+
// Handle anyOf with exactly array and null (FastMCP pattern)
195+
if (
196+
schema.anyOf &&
197+
schema.anyOf.length === 2 &&
198+
schema.anyOf.some((t) => (t as JsonSchemaType).type === "array") &&
199+
schema.anyOf.some((t) => (t as JsonSchemaType).type === "null")
200+
) {
201+
return { ...schema, type: "array", anyOf: undefined, nullable: true };
202+
}
203+
194204
// Handle array type with exactly string and null
195205
if (
196206
Array.isArray(schema.type) &&

0 commit comments

Comments
 (0)