How to Design Good MCP Tools
The hardest part of an MCP server is often not protocol code. It is deciding what capabilities to expose and how to shape them for reliable model use.
Use task-level names
Prefer names that describe intent. find_customer_by_email is clearer than query_db. Descriptions should explain when to use a tool, what it returns, and important limits.
Keep parameter sets small
Large schemas increase tool-selection and argument-generation errors. Separate genuinely different operations instead of creating a single “do_everything” tool with dozens of optional fields.
Design safe defaults
Read-only behavior should be easier to invoke than destructive behavior. For mutations, include explicit identifiers, avoid surprising cascades, and support dry-run or approval patterns when practical.
Idempotency
If network retries are possible, mutation tools should use idempotency keys or deterministic request identifiers where the downstream system supports them. Otherwise a retry can create duplicate tickets, payments, or deployments.
Return model-friendly results
Return enough structured information for the model to continue, but avoid dumping huge raw payloads. Include stable IDs that later tools can consume.