The problem
Every MCP (Model Context Protocol) tool declares an inputSchema: a description, in JSON (JavaScript Object Notation) Schema, of the arguments it accepts. A language model fills in the arguments, and it can get them wrong: a missing field, a number where a text is expected, a value that is not allowed. So the server must check the arguments before calling the tool, and, if they are wrong, tell the model what to fix. You will write the checker and the call.
The subset of JSON Schema
For an object schema:
"type": "object"at the top, with"properties"mapping names to{"type": ...}. The type is one of"string","number"(int or float),"integer"(int only),"boolean","array","object". A property may also have"enum": a list of allowed values."required": names that must be present."additionalProperties": false: no other names allowed (when absent, extra names are allowed).
Validation
validate(arguments, schema) returns a list of error strings, empty if valid, in this order:
"missing required property '<name>'"for each required name, inrequiredorder;- then, for each argument in its own order, one of:
"unexpected property '<name>'","property '<name>' must be <type>"or"property '<name>' must be one of <enum list>".
In JSON Schema true is not a number: a bool matches only "boolean" (in Python True is an int, so check for it).
Example. The schema: an object with
location(a string, required),days(an integer) andunits(a string, one of"c"and"f"), andadditionalPropertiesfalse.
{"days": 2.5, "units": "k", "x": 1}gives, in order:missing required property 'location',property 'days' must be integer,property 'units' must be one of ['c', 'f'],unexpected property 'x'.{"location": "Paris", "days": 2}gives[]: valid.{"location": "Paris", "days": True}givesproperty 'days' must be integer.
Calling a tool
call_tool(tools, request): tools maps names to (schema, fn) pairs; request is a tools/call request. Return the JSON-RPC response:
- an unknown tool is a protocol error:
{"jsonrpc": "2.0", "id": <id>, "error": {"code": -32602, "message": "Unknown tool: <name>"}}; - invalid arguments are a tool execution error: a result with
"isError": Trueand one text content"Invalid arguments: " + "; ".join(errors), so the model can read what to fix; - valid arguments: call
fn(**arguments)and return itsstr()as text with"isError": False.
Results carry "resultType": "complete" and the shape {"jsonrpc": "2.0", "id": ..., "result": {"resultType": "complete", "content": [{"type": "text", "text": ...}], "isError": ...}}.
Example. The tool
weatherwith the schema above, called with{"location": "Paris", "days": "two"}: the result hasisErrortrue and the textInvalid arguments: property 'days' must be integer. The tool function is not called.
What to implement
validate(arguments, schema)andcall_tool(tools, request).
Requirements
- Never call the tool with invalid arguments.