New to Claude Skills? Learn how to install them →

Claude Custom Tools: The Same Rule as Skill Descriptions

Anthropic's own guidance for defining custom tools on the Claude API and Claude Managed Agents comes down to four rules, and the first one is the same lever that makes or breaks an agent skill.

September 2, 2026
Get Claude Skills
7 min read

The description is still the whole game

Anthropic publishes near-identical "best practices" guidance in two places: the Messages API's tool-definition docs and the Claude Managed Agents tools reference. Both boil down to the same four rules, and the first one is stated almost word for word in both places: "Provide extremely detailed descriptions. This is by far the most important factor in tool performance."

That's worth sitting with. Not the schema. Not the parameter types. The plain-English description is what Anthropic itself calls the single biggest lever you have over whether Claude uses a tool correctly, uses it at the wrong time, or ignores it entirely. If that sentence sounds familiar, it should: it's the exact same claim this site makes about agent skill descriptions, the field that decides whether a skill ever activates. Custom tools and skills are different mechanisms, one is a function call, the other is a loaded procedure, but they share the same failure mode. Something an agent can't read a good description of is something it will use badly or not at all, however well the underlying code works.

The four rules, verbatim

Both documentation pages give the same four points. This is the Managed Agents wording; the Messages API version adds one line about input_examples, covered separately below.

  1. Provide extremely detailed descriptions. Explain what the tool does and when to use it, and when not to. Explain what each parameter means and how it affects behavior. Call out important caveats or limitations. Anthropic's stated target: three to four sentences per tool description, more if the tool is complex.
  2. Consolidate related operations into fewer tools. Rather than a separate tool for every action (create_pr, review_pr, merge_pr), group them into one tool with an action parameter. Fewer, more capable tools reduce selection ambiguity as your tool surface grows.
  3. Use meaningful namespacing in tool names. When tools span multiple services or resources, prefix names with the resource, for example db_query or storage_read on Managed Agents, or github_list_prs and slack_send_message in the Messages API's own example. This keeps selection unambiguous as the library grows, and the Messages API docs call it "especially important when using tool search."
  4. Design tool responses to return only high-signal information. Return semantic, stable identifiers, slugs or UUIDs rather than opaque internal references, and include only the fields Claude needs to decide its next step. A bloated response wastes context and makes it harder for Claude to extract what actually matters.

A worked comparison: bad description vs good description

Anthropic's Messages API docs include a direct before-and-after that's worth reproducing, because it shows exactly how little a "correct" schema buys you if the description is thin.

{
  "name": "get_stock_price",
  "description": "Gets the stock price for a ticker.",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker": { "type": "string" }
    }
  }
}

That's technically complete. Claude can parse the schema and knows there's a required ticker string. What it doesn't know: what "the stock price" means (current price? closing price? which currency?), what counts as a valid ticker, what happens if the symbol doesn't exist, or whether this tool returns anything besides a price. Compare it with Anthropic's recommended version:

{
  "name": "get_stock_price",
  "description": "Retrieves the current stock price for a given ticker symbol. The ticker symbol must be a valid symbol for a publicly traded company on a major US stock exchange like NYSE or NASDAQ. The tool will return the latest trade price in USD. It should be used when the user asks about the current or most recent price of a specific stock. It will not provide any other information about the stock or company.",
  "input_schema": {
    "type": "object",
    "properties": {
      "ticker": {
        "type": "string",
        "description": "The stock ticker symbol, e.g. AAPL for Apple Inc."
      }
    },
    "required": ["ticker"]
  }
}

Same tool, same schema shape, and every open question from the first version is closed: what it does, what a valid input looks like, what it returns, when to reach for it, and explicitly, what it won't tell you. That last part, stating what a tool doesn't do, is easy to skip and genuinely useful: it stops Claude from calling a tool speculatively on the chance it might return something adjacent to what's needed.

Where the two platforms diverge slightly

The core guidance matches, but there are real mechanical differences worth knowing if you're building for both.

input_examples is Messages API only. For tools with complex inputs, nested objects, or format-sensitive parameters, the Messages API lets you attach an input_examples array of schema-validated example inputs directly to the tool definition, alongside the description. Anthropic frames this as a secondary lever behind the description itself ("Prioritize descriptions, but consider using input_examples for complex tools"), not a replacement for one. It costs roughly 20 to 50 tokens per simple example and 100 to 200 for complex nested ones, and it isn't available on server-side tools or client toolsets like computer use, only on user-defined tools. Claude Managed Agents' current custom tool schema (name, description, input_schema) doesn't expose an equivalent field.

Forced tool use behaves differently by model. On the Messages API, tool_choice of type any or tool works on most current models, but not on manual extended thinking (thinking: {type: "enabled"}) and not at all on Claude Fable 5.1 or Claude Mythos 5.1, where it returns a 400 error regardless of thinking mode. The recommended substitute is the same in both cases: tool_choice: {"type": "auto"} paired with strict: true (strict tool use) to guarantee schema-valid output, or structured outputs when you need a fixed JSON shape.

Managed Agents auto-handles large outputs. When a built-in Managed Agents tool's output exceeds 100,000 characters (roughly 25,000 tokens), it's automatically written to a file in the sandbox and the model receives a truncated preview with the file path, reading the rest on demand. That's a platform-level safeguard sitting on top of the "design lean responses" rule above, not a replacement for writing a tool that doesn't return bloat in the first place.

Applying rule 2: consolidating actions in practice

Rule 2, fewer tools with an action parameter, is the one most likely to get skipped because it feels like premature abstraction early on. It stops feeling that way once a tool library grows past a handful of entries. A worked example:

{
  "name": "pr_manager",
  "description": "Manage GitHub pull requests: create a new PR, post a review, or merge an approved PR. Use action \"create\" to open a new PR from a branch, \"review\" to post a review comment or approval, and \"merge\" to merge a PR that has passing checks and required approvals. Will not merge a PR that fails checks or lacks required approvals; that failure is returned as an error, not silently retried.",
  "input_schema": {
    "type": "object",
    "properties": {
      "action": {
        "type": "string",
        "enum": ["create", "review", "merge"],
        "description": "Which PR operation to perform."
      },
      "pr_number": {
        "type": "integer",
        "description": "The pull request number. Required for review and merge; omitted for create."
      },
      "branch": {
        "type": "string",
        "description": "The source branch to open a PR from. Required for create."
      }
    },
    "required": ["action"]
  }
}

One tool, one clear name, three enumerated actions instead of create_pr, review_pr, and merge_pr as three separate entries Claude has to distinguish between at selection time. The description still does the heavy lifting: it says what each action means, and, following the "state what it won't do" pattern from the worked example above, it states the merge failure behavior explicitly rather than leaving Claude to guess whether a blocked merge retries or errors.

Why this reads like skill-writing advice, because it is

This site's established editorial position is that the description field is the single highest-leverage thing in the agent skills ecosystem, and the most common reason a skill silently never fires. Anthropic's own tool-use documentation, written for a completely different mechanism, arrives at the identical conclusion using nearly identical language. That's not a coincidence. A custom tool description and a skill's description field solve the same problem for the same reason: an agent has to decide, from a short piece of text and nothing else, whether this capability is the right one for the task in front of it. Whether that capability is a function it can call or a folder of instructions it can load doesn't change what makes the decision go well or badly.

If you're writing custom tools for a Claude Managed Agent that also loads agent skills, the same discipline applies to both: write the description like the reader has never seen the tool or skill before, because from the model's perspective, it hasn't.

Where to go next

For the mechanics of defining and configuring custom tools on Claude Managed Agents specifically, including the built-in toolset and domain restrictions on web_search and web_fetch, see Claude Managed Agents Explained and Restricting Claude Managed Agents' Web Search and Web Fetch to Specific Domains. For the equivalent discovery mechanic on the skills side, see How AI Agents Discover and Activate Skills and How to Write Your Own Agent Skill. If you're deciding whether a given capability should be a custom tool, an MCP server, or a skill in the first place, Agent Skills vs MCP covers that boundary directly. Browse the current skill catalog at getclaudeskills.com/skills.

Frequently asked questions