← Back to Build

Tool Naming & Descriptions

Agents discover tools by reading names and descriptions. This is the single highest-leverage thing you can get right.

Why This Matters

When an LLM receives a list of tools, it reads every name and description to decide which one to call. Poor names create ambiguity. Vague descriptions cause the model to guess — or pick the wrong tool entirely. The tool metadata you write is literally the UI for an AI agent.

Key insight: Your tool's description field tells agents when to use it. Your inputSchema descriptions tell agents how to call it. Keep these concerns separate.

Tool Naming Rules

The MCP specification defines formal naming constraints. Follow these to ensure compatibility across all clients.

Spec Requirements

  • Names SHOULD be 1–128 characters
  • Allowed characters: A-Z, a-z, 0-9, underscore _, hyphen -, dot .
  • No spaces, commas, slashes, or other special characters
  • Names are case-sensitive and must be unique within your server

Community Conventions

Analysis of 500+ MCP servers shows strong community consensus:

  • snake_case is used by over 90% of servers — treat it as the standard
  • ~95% of tool names are multi-word (e.g., fetch_forecast, not forecast)
  • Less than 1% use camelCase, despite JavaScript/TypeScript dominance
  • Target 32 characters or fewer for UI readability

Naming Patterns That Work

Start With an Action Verb

Every tool name should begin with a verb that makes the action obvious:

PrefixUse ForExamples
get_Fetching a single resourceget_user, get_order_status
list_Retrieving multiple itemslist_repositories, list_open_issues
create_Creating a new resourcecreate_ticket, create_branch
update_Modifying an existing resourceupdate_profile, update_settings
delete_Removing a resourcedelete_comment, delete_webhook
search_Querying with filterssearch_documents, search_logs
run_Executing a processrun_query, run_migration

The Service-Action-Resource Pattern

For multi-service environments, prefix with the service name to prevent collisions:

  • github_create_issue instead of create_issue
  • slack_send_message instead of send_message
  • db_run_query instead of query

Dot Notation for Namespacing

The spec supports dots for hierarchical namespacing: admin.tools.list, user.profile.update. Use this when your server has clear domain boundaries.

Names to Avoid

Bad NameProblemBetter Name
do_stuffToo vagueprocess_payment
handleNo noun, no specificityhandle_webhook_event
dataNot a verb, not specificget_sales_data
executeActionOnResourcecamelCase, too genericupdate_resource
tool1Meaninglessvalidate_email

Writing Great Descriptions

The description field is the most important piece of metadata on your tool. It is what the LLM reads to decide whether to call your tool or a different one.

The Golden Rules

  1. 1–2 sentences max. Front-load the critical information.
  2. Lead with verb + resource. "Create a new Salesforce contact" not "This tool is used for creating contacts in Salesforce."
  3. Say when to use it, not just what it does. "Search customer orders by email. Use when a user asks about their order history." is better than "Searches orders."
  4. Don't duplicate schema info. Auth details, pagination, and rate limits belong in the inputSchema, not the description.
  5. Differentiate from sibling tools. If you have get_user and search_users, the descriptions must make the distinction obvious.

Good vs. Bad Descriptions

QualityExample
Good "Read the contents of multiple files simultaneously. More efficient than reading files individually when analyzing or comparing multiple files."
Bad "Reads files."
Good "Update shared drive settings including name, color, and restrictions. Requires drive admin permissions."
Bad "Updates a drive."

Parameter Descriptions

Every property in your inputSchema should have its own description. This is where you put the detail that helps the agent fill in arguments correctly.

  • State the type and constraints: "Customer email address (must be a valid email)"
  • Explain expected format: "ISO 8601 date string, e.g. 2026-03-01"
  • Clarify optional vs. required behavior: "If omitted, defaults to the last 30 days"
  • Use .describe() in Zod or Field(description=...) in Pydantic — don't skip it

Tool Annotations

Since spec version 2025-03-26, tools support behavioral annotations that help clients make safety decisions:

AnnotationDefaultWhat It Signals
readOnlyHintfalseTool does not modify the environment
destructiveHinttrueTool may perform destructive updates (delete, overwrite)
idempotentHintfalseRepeated calls with same args have no additional effect
openWorldHinttrueTool interacts with external entities (web, APIs)

These annotations affect real client behavior — ChatGPT, for example, renders tools without readOnlyHint: true as "write" tools that require user confirmation.

Avoiding Name Collisions

When users connect multiple MCP servers, duplicate tool names cause undefined behavior. Protect against this:

  • Prefix tools with your service/domain name: github_search_repos
  • Never use generic names like search, query, or run without a qualifier
  • Some frameworks auto-prefix with the server name (e.g., web1___search_web) but don't rely on it

Quick Checklist

  • Every tool has a snake_case name starting with a verb
  • Names are under 32 characters
  • Names use only allowed characters (letters, digits, _, -, .)
  • Description is 1–2 sentences, front-loaded with purpose
  • Description says when to use the tool, not just what it does
  • Every input parameter has its own description
  • Tool annotations are set accurately (readOnlyHint, destructiveHint)
  • No generic names that could collide with other servers
  • Sibling tools have clearly differentiated descriptions

Essential Resources

Official Specification

Spec Discussions & Proposals

SDKs & Frameworks

Guides & Best Practices

Deep Dives