npm install @ferrow/tool-schema-validatorValidate LLM tool/function-call definitions and model-produced arguments — JSON-Schema subset checks, LLM-pitfall linting, path-precise argument errors, and a coercion mode for sloppy model output. Zero runtime dependencies, strict TypeScript.
import { validateToolDef, lintToolDef, validateArguments } from "tool-schema-validator";
const tool = {
name: "search_products",
description: "Search the product catalog by query and category.",
parameters: {
type: "object",
properties: {
query: { type: "string", description: "search text", minLength: 1 },
limit: { type: "integer", description: "max results", minimum: 1, maximum: 50 },
},
required: ["query"],
},
};
validateToolDef(tool); // => { valid: true, errors: [] }
lintToolDef(tool); // => [] (good name, has description, properties documented)
validateArguments(tool.parameters, { query: "mouse", limit: "10" });
// => { valid: false, errors: [{ path: "parameters.limit", message: "expected type integer, got string" }] }
validateArguments(tool.parameters, { query: "mouse", limit: "10" }, { coerce: true });
// => { valid: true, errors: [], coerced: { query: "mouse", limit: 10 } }Structural check: is tool.parameters a well-formed JSON-Schema subset
(valid type, properties shape, required string array, enum array,
recursive items)? Returns { valid, errors: ValidationError[] } with
path-precise errors.
Best-practice warnings for LLM tool-calling specifically (all structurally valid schemas can still fail this):
- missing
descriptionon the tool or on a property - ambiguous tool names (
do,run,execute,handle,process,go,action,call) - more than
options.maxProperties(default 12) top-level properties - a
requiredfield with no matching entry inproperties
Validates model-produced arguments against a JsonSchema. Errors are
path-precise (parameters.limit, parameters.items[2].id). With
options.coerce: true, attempts to coerce common sloppy-model mismatches
before failing: string "42" -> number 42, string "true"/"false"
-> boolean, number/boolean -> string. Returns coerced (the possibly-
coerced value) only when coerce is requested.
- Supports a subset of JSON Schema:
type,properties,required,enum,items,minimum/maximum,minLength/maxLength,description. No$ref,oneOf/anyOf/allOf,pattern, oradditionalPropertiesschema enforcement (the field is accepted but not enforced). - Coercion is intentionally narrow (numeric strings, boolean strings, primitive-to-string) — it will not coerce, say, a JSON string into an object.
- Linting is opinionated toward what makes tools easier for models to call correctly, not a general JSON-Schema style linter.
Part of the ferrow-toolkit collection · Sponsored by Ferrow