---
name: mcp-tool-design
description: Best practices for designing MCP server tools with clear names, descriptions, and schemas
---

## Instructions

When designing tools for an MCP server, follow these principles:

### Naming
- Use `snake_case` for tool names (e.g., `search_web`, `get_user_by_id`).
- Start with a verb: `get_`, `list_`, `create_`, `update_`, `delete_`, `search_`, `send_`.
- Be specific: `search_github_repos` not `search` — agents choose tools by name.

### Descriptions
- First sentence: what the tool does in plain English.
- Second sentence (optional): when to use it vs. similar tools.
- Include an example invocation if the input is non-obvious.
- Mention rate limits or cost if relevant.

### Input Schema (Zod)
- Every parameter needs `.describe("...")` — this is the agent's only guide.
- Mark optional params with `.optional()` and document their defaults.
- Use enums (`z.enum([...])`) instead of free-form strings when the value set is known.
- Keep required params to a minimum — prefer sensible defaults.

### Output
- Return structured JSON via `{ content: [{ type: "text", text: JSON.stringify(result) }] }`.
- Include a `summary` field for long results so the agent doesn't need to parse everything.
- On errors, return a clear error message — don't throw (the agent can't read stack traces).

### Security
- Never expose raw credentials in tool output.
- Validate and sanitize all inputs before passing to external APIs.
- Use `bearerToken: z.string().describe("Pass 'auto' for connection credentials")` for auth.