← Blog

Claude Tool Use Schema Design Tips That Work

2026-11-05 · 5 min read · SubToAPI Team

If Claude is calling the wrong tool, passing malformed arguments, or skipping a tool call it should obviously make, the problem is almost never the model — it's the schema. Claude's tool use (function calling) relies entirely on the quality of your name, description, and input_schema fields to decide when and how to call a tool. A vague or overloaded schema produces vague or overloaded behavior.

This guide covers the practical schema design patterns that make tool calls reliable: how to structure descriptions, how to type parameters, how to handle optional fields, and the mistakes that cause silent failures in production.

Why Schema Quality Determines Tool Call Accuracy

Claude doesn't "know" your backend. It only sees the JSON schema you send in the tools array of your request. Every decision — which tool to call, what arguments to extract from the conversation, whether to call a tool at all — is based on pattern-matching against that schema and the surrounding context. That means schema design is prompt engineering, not just API plumbing.

A typical tool definition looks like this:

{
  "name": "get_order_status",
  "description": "Retrieve the current shipping status of a customer order by order ID.",
  "input_schema": {
    "type": "object",
    "properties": {
      "order_id": {
        "type": "string",
        "description": "The unique order identifier, e.g. ORD-48213"
      }
    },
    "required": ["order_id"]
  }
}

Every weak point in this structure — an ambiguous description, a missing example, a loose type — translates directly into a weaker decision by the model.

Naming Tools Clearly

Use a snake_case verb-noun pattern: get_weather, create_invoice, search_documents. Avoid generic names like handler or process_request — Claude has nothing to disambiguate against when multiple tools share vague names.

If you have several similar tools, make the distinction explicit in the name itself rather than relying on the description alone:

This reduces the chance Claude picks the wrong one when the user's request is ambiguous.

Write Descriptions Like You're Onboarding a New Engineer

The description field is the single highest-leverage part of a tool schema. Treat it as documentation, not metadata:

Bad:

"description": "Gets data"

Good:

"description": "Looks up the current inventory count for a specific SKU in the warehouse system. Use this only for stock levels, not for pricing or product details."

The second version tells Claude both what to do and what not to do with a tool that might otherwise get confused with a pricing lookup.

Parameter Design: Types, Enums, and Constraints

Loose typing is one of the most common sources of bad tool calls. A few concrete rules:

{
  "type": "object",
  "properties": {
    "priority": {
      "type": "string",
      "enum": ["low", "medium", "high", "urgent"],
      "description": "Ticket priority level"
    },
    "assignee_id": {
      "type": "integer",
      "description": "Numeric ID of the support agent"
    }
  },
  "required": ["priority"]
}

Keep Tool Boundaries Narrow

A tool that tries to do too much — manage_user handling creation, deletion, updates, and permission changes all through one giant optional-parameter schema — is harder for Claude to use correctly than four small tools: create_user, delete_user, update_user, set_user_permissions.

Narrow, single-purpose tools:

If you're worried about tool count bloating the context, remember that tool schemas are relatively cheap compared to verbose descriptions — it's usually better to have 10 clear, small tools than 3 overloaded ones.

Handling Nested Objects and Arrays

Claude can handle nested schemas, but nesting adds failure surface. If a parameter is an array of objects, document the shape explicitly:

{
  "items": {
    "type": "array",
    "description": "List of line items, each with 'sku' (string) and 'quantity' (integer)",
    "items": {
      "type": "object",
      "properties": {
        "sku": { "type": "string" },
        "quantity": { "type": "integer" }
      },
      "required": ["sku", "quantity"]
    }
  }
}

Don't rely on the description alone to convey structure when the full JSON Schema nesting can express it directly — the schema is more reliable than prose for structure, and prose is more reliable for intent.

Testing and Iterating on Schemas

Schema design is iterative. Log the actual tool_use blocks Claude returns in production and check for:

If you're testing this through an application API layer rather than hitting Anthropic directly, SubToAPI exposes the same tools schema format over a standard HTTPS endpoint with full request/response logging, which makes it easier to see exactly which schema version produced which tool call across a team. See the tool use docs for the request shape, or the quickstart if you're setting up API keys for the first time.

Common Mistakes to Avoid

FAQ

Does Claude ever ignore the schema and just guess arguments? No — Claude generates arguments that conform to your input_schema, but if the schema is vague or the field lacks a description, it will guess the value based on context, which is where most errors originate.

Should I use one large tool or several small tools? Prefer several small, single-purpose tools. They're easier to describe precisely and reduce the chance of Claude mixing up parameters meant for different operations.

How do I force Claude to always call a specific tool? Use the tool_choice parameter to require a specific tool or any tool call, rather than relying on description wording alone — check the messages docs for the exact request format.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →