Skip to main content
HomeTools

MCP Tool Schema Checker

Free

Paste an MCP tools/list response, a single MCP tool, or an OpenAI or Anthropic function definition. The checker applies rules from the MCP 2026-07-28 specification and the OpenAI and Claude tool-use docs: name rules per provider, required fields that do not exist, invented types, coded enums, dates with no format, x-mcp-header values that get a tool dropped, strict-mode incompatibilities, and annotation contradictions. It can also check a tools/call result against the tool's outputSchema. Everything runs in your browser.

#mcp#json-schema#ai-agents#tool-calling#linting

Check tool definitions

MCP 2026-07-28 · OpenAI · Claude

Runs in your browser. The checker is deterministic rules, not an LLM. Your tool definitions are never uploaded or stored.

Findings
3 errors
5 warnings
3 info

MCP tools/list JSON-RPC response · 3 tools

  • Error: orders.searchrequired names "customer_id", which is not in properties

    result.tools[0].inputSchema.required

    The model is never told the key exists or what type it takes, so it rarely sends it, and validation fails the call. This is usually a renamed property whose required entry was left behind.

    Fix: Add the property with a type and description, or remove it from required.

    required-unknown · JSON Schema

  • Error: get_orderx-mcp-header "Order Id" is not an HTTP token

    result.tools[1].inputSchema.properties.orderId["x-mcp-header"]

    The value must match RFC 9110 field-name syntax, so spaces, colons and control characters are not allowed. Streamable HTTP clients MUST reject a tool with an invalid x-mcp-header and leave it out of tools/list, so the model never sees this tool.

    Fix: Use letters, digits and hyphens.

    mcp-header-invalid · MCP 2026-07-28

  • Error: cancel_order"float" is not a JSON Schema type

    result.tools[2].inputSchema.properties.refundAmount.type

    Validators reject the schema, and models that do read it treat the type as unknown. Names like int, float, str and dict usually come from a Python or TypeScript type leaking into the schema.

    Fix: Use "number".

    type-invalid · JSON Schema

  • Warning: orders.searchCoded enum has no description

    result.tools[0].inputSchema.properties.status.enum

    The model sees "P", "S", "X" but not what each means, so it picks by position or by guess.

    Fix: Add a description that maps each value to its meaning.

    enum-undescribed · Tool design

  • Warning: orders.search"createdAfter" looks like a date or time but its format is not stated

    result.tools[0].inputSchema.properties.createdAfter

    The model may send "2026-10-16", "16/10/2026" or "next Friday". The schema accepts them all, and the handler parses whichever arrived.

    Fix: Add `"format": "date"` or `"date-time"`, and an example in the description.

    date-format-unstated · Tool design

  • Warning: cancel_orderDescription is 3 words

    result.tools[2].description

    A one-line description leaves the model to infer when to call the tool and what the arguments mean, so it calls it for near-miss requests or fills arguments with plausible guesses.

    Fix: Add when to use it, when not to, what it returns, and one concrete example value.

    description-thin · Tool design

  • Warning: cancel_ordernullable is OpenAPI 3.0, not JSON Schema

    result.tools[2].inputSchema.properties.reason.nullable

    JSON Schema validators ignore nullable, so a null from the model fails validation even though the schema looks like it allows one.

    Fix: Use a type array such as `"type": ["string", "null"]`.

    openapi-nullable · JSON Schema

  • Warning: cancel_orderName suggests a destructive action, destructiveHint is false

    result.tools[2].annotations.destructiveHint

    false tells an honest host the tool only adds things. It may drop the confirmation step for a delete or reset.

    Fix: Remove destructiveHint (it defaults to true) or set it to true, and require confirmation outside the model.

    annotations-destructive-false · MCP 2026-07-28

  • Info: orders.searchUnknown arguments are accepted

    result.tools[0].inputSchema

    Without `additionalProperties: false` a misspelt or invented argument (userID for userId) passes validation. Zod's default object then strips it, and the call succeeds without the value the model thought it sent.

    Fix: Add `"additionalProperties": false` (z.strictObject in Zod) so the model gets a validation error it can correct.

    extra-keys-accepted · JSON Schema

  • Info: cancel_orderUnknown arguments are accepted

    result.tools[2].inputSchema

    Without `additionalProperties: false` a misspelt or invented argument (userID for userId) passes validation. Zod's default object then strips it, and the call succeeds without the value the model thought it sent.

    Fix: Add `"additionalProperties": false` (z.strictObject in Zod) so the model gets a validation error it can correct.

    extra-keys-accepted · JSON Schema

  • Info: cancel_order3 parameters have no description: orderId, refundAmount, reason

    result.tools[2].inputSchema.properties

    The model fills parameters from their names alone. Names like id, query or type rarely say which id, what syntax, or which type.

    Fix: Give each parameter a description with its meaning, format and an example value.

    params-undescribed · Tool design

Check a tools/call result against outputSchema

Paste one result for a tool from the list above. The sample shows a result that drifted from get_order's schema.

Paste a result to check it.

What the checker can and cannot tell you(click to expand)

Why is a dotted name fine for MCP but an error for OpenAI?

MCP allows letters, digits, underscore, hyphen and dot, up to 128 characters. OpenAI function names allow letters, digits, underscore and dash up to 64; Claude allows the same set up to 128. A host that forwards MCP tools to a model API has to rename orders.search, so pick Check against for the models your agent uses.

What does strict mode change?

OpenAI strict mode and Claude strict tool use accept a subset of JSON Schema. OpenAI requires additionalProperties: false on every object and every property in required. Claude requires the same additionalProperties, rejects numeric and length constraints, and caps optional and union-typed parameters across the whole request. Tools that set strict: true are always checked this way.

What will it miss?

The rules read the schema, not the server. They cannot see whether the handler enforces what the schema promises, whether a model actually calls the tool correctly, or whether annotations tell the truth. Treat a clean report as a well-formed contract, and test the calls themselves. Heuristic rules such as thin descriptions and date-like names say so in their explanation.