MCP tool definition linter

Free, runs in your browser. Updated .

An agent chooses and calls an MCP tool from three things only: its name, its description and its input schema. If the name breaks a model API’s rules, the description is missing or vague, or the arguments are undocumented, the agent picks the wrong tool or fills it badly, and every definition costs context on every request. Paste a server’s tools/list response and the linter checks each tool against 15 rules drawn from the MCP specification and the limits of common model APIs, and says how many tokens each definition takes. Nothing you paste leaves your browser.

Copy it from the MCP Inspector's Tools tab or your client's debug log. It stays in this browser tab.

The 15 checks

Errors break the tool in some clients or leave the model unable to call it. Warnings make the tool harder to choose or fill, or more expensive to carry.

CheckLevelWhy it matters
Tool has a nameErrorThe name is how the model calls the tool. A tool without one cannot be called.
Names are uniqueErrorTwo tools with the same name make every call to that name ambiguous, and many clients drop one of them.
Name uses only letters, digits, _ - and .ErrorThe MCP specification limits tool names to these characters and 128 of them. Spaces and other symbols break clients that pass names through to the model.
Name fits the strictest model APIsWarningSeveral model APIs accept function names of at most 64 letters, digits, underscores and hyphens. Clients that forward names unchanged fail on dots or longer names.
Tool has a descriptionErrorWithout a description the model guesses what the tool does from its name, and often picks the wrong one or none.
Description says what the tool does and when to use itWarningA few words rarely tell the model when this tool fits better than a similar one. One or two sentences usually do.
Description stays under about 300 tokensWarningThe description is sent on every request. Long usage notes spend context every turn; keep what the model needs to choose and call the tool.
Tool has an inputSchemaErrorThe MCP specification requires an inputSchema on every tool, even one that takes no arguments.
inputSchema is a JSON Schema objectErrorMCP tool arguments are a JSON object, so the schema’s type must be "object". Other shapes are rejected by strict clients.
Every required argument is definedErrorA name in "required" that is not in "properties" asks the model for an argument it has no description or type for.
Arguments have descriptionsWarningThe model fills arguments from their names and descriptions. Undescribed arguments get guessed formats and values.
Arguments have a typeWarningAn argument with no type, enum, const or composition accepts anything, so the model has no guide to the value’s shape.
Enums stay shortWarningEvery enum value is sent on every request. Past about 50 values, take a free string and validate it on the server instead.
Schema nests no more than three objects deepWarningDeeply nested arguments are harder for models to fill correctly and cost more tokens. Flatten where you can.
Whole definition stays under 1,000 tokensWarningA definition this large takes a noticeable share of the context window on every request, whether or not the tool is called.

A tool definition that passes

The description says what the tool returns and when to use a different one. Each argument has a type and a description that gives its format, and the enum is short.

{
  "name": "search_issues",
  "description": "Search open and closed issues in one repository by keyword. Returns up to 20 issues with number, title, state and URL. Use get_issue for the full text of one issue.",
  "inputSchema": {
    "type": "object",
    "properties": {
      "repository": {
        "type": "string",
        "description": "owner/name, for example acme/website."
      },
      "query": {
        "type": "string",
        "description": "Words to match in the title or body."
      },
      "state": {
        "type": "string",
        "enum": [
          "open",
          "closed",
          "all"
        ],
        "description": "Which issues to include. Defaults to open."
      }
    },
    "required": [
      "repository",
      "query"
    ]
  }
}

Questions

What characters can an MCP tool name use?
The MCP specification allows letters, digits, underscores, hyphens and dots, from 1 to 128 characters. Several model APIs are stricter and accept function names of at most 64 letters, digits, underscores and hyphens, so a name that fits both, such as search_docs, works in the most clients.
How long should an MCP tool description be?
Long enough to say what the tool does, what it returns and when to use it instead of a similar tool: usually one to three sentences. The linter warns under five words and over about 300 tokens, because the description is sent with every request.
Does every MCP tool need an inputSchema?
Yes. The specification requires an inputSchema on every tool, and its type must be "object" because arguments are passed as a JSON object. A tool that takes no arguments can use {"type": "object"} with no properties.
Why describe each argument?
The model fills arguments from their names and descriptions. A description that gives the format, the unit or the allowed range ("ISO 8601 date", "1 to 20") prevents most malformed calls.
How do I get a server’s tools/list response?
Connect to the server with the MCP Inspector and open the Tools tab, or copy the tools/list result from your client’s debug log. Paste the whole JSON: the linter reads the JSON-RPC envelope, the result object or the bare tools array.
Is my tool list uploaded anywhere?
No. The linter parses and checks the JSON in this browser tab and keeps nothing after you leave the page.

Related