MCP

MCP Tools👨‍💻

Tools are the most commonly used MCP primitive. They represent actions that an AI model can invoke -- querying a database, sending an email, creating a file, calling an API. Each tool has a name, a description that helps the model understand when to use it, and an input schema that defines the arguments it accepts. When the model decides to use a tool, the client sends a tools/call request to the server with the tool name and arguments. The server validates the input, executes the tool logic, and returns a structured result. Tools can return text, images, or references to resources. Unlike resources, tools are expected to have side effects -- they do things in the world rather than just exposing data.

Key Takeaways

  • 1Every tool has three required components: a unique name, a human-readable description that guides the model's tool selection, and an inputSchema defined as JSON Schema (or Zod in TypeScript / type hints in Python) that specifies accepted arguments.
  • 2Tool handlers are async functions that receive validated arguments and return a CallToolResult containing a content array. Content items can be text (type: 'text'), images (type: 'image' with base64 data), or embedded resource references.
  • 3The MCP SDKs automatically validate incoming tool arguments against the input schema before calling your handler. If validation fails, the SDK returns a JSON-RPC error response without executing the tool, preventing malformed inputs from reaching your logic.
  • 4Tools can indicate errors in two ways: by throwing an exception (which becomes a JSON-RPC error) or by returning a result with isError: true in the content (which is a soft error the model can reason about and retry).
  • 5Tool descriptions are critical for AI tool selection. The model reads the description to decide whether a tool is appropriate for the current task. Vague descriptions like 'do stuff' lead to poor selection; specific descriptions like 'Search the PostgreSQL database for orders by customer email' lead to accurate selection.
  • 6Tools support progress reporting and cancellation via the context object. Long-running tools can report progress updates to the client, and the client can send a cancellation request if the user aborts the operation.

Examples

Defining tools with Zod schemas in TypeScript

typescript

Zod schemas provide rich validation and self-documenting inputs. The .describe() method on each field generates descriptions in the JSON Schema that help the model understand what values to provide. Optional fields, enums, and defaults give the model flexibility while constraining inputs to valid values.

Defining tools with decorators in Python

python

The Python SDK infers the input schema from type annotations and the docstring. Union types with None create optional fields, Enum types create enum constraints, and default values are included in the schema. The docstring Args section generates field descriptions. This approach keeps the schema definition close to the implementation.

Returning different content types from a tool

typescript

Tools can return multiple content items of different types in a single response. Text content is the most common, but image content (base64-encoded) is useful for charts, screenshots, and diagrams. The content array lets you combine text analysis with visual output in one tool call, giving the model richer context.

Handling tool errors gracefully

python

There are two error strategies: soft errors (returning an error message as text content) and hard errors (raising an exception). Soft errors let the model reason about the problem and try again with different inputs -- for example, trying a different user ID. Hard errors indicate unrecoverable failures like network issues. Choose soft errors for user-correctable problems and hard errors for infrastructure failures.

Tool with progress reporting in TypeScript

typescript

Long-running tools should report progress so the client can display status updates to the user. The context object (ctx) provides a reportProgress method that sends progress notifications to the client. This is especially important for batch operations, file processing, or API calls that may take several seconds.

Common Mistakes

Mistake:

Writing vague tool descriptions like 'handles data' or 'does operations', which cause the AI model to select the wrong tool or pass incorrect arguments.

Fix:

Write specific, action-oriented descriptions: 'Search the orders database by customer email, date range, or order status. Returns up to 100 matching orders with their details.' Include what the tool does, what inputs it expects, and what it returns.

Mistake:

Not validating tool inputs beyond the schema, trusting that schema validation alone prevents all bad inputs (e.g., path traversal in file paths, SQL injection in query parameters).

Fix:

Schema validation checks types and formats but not security constraints. Add business logic validation inside the handler: sanitize file paths, parameterize database queries, and validate that IDs reference existing records.

Mistake:

Returning raw error stack traces to the client when a tool throws an unhandled exception, exposing internal implementation details.

Fix:

Catch exceptions in your handler and return user-friendly error messages. Log the full stack trace server-side for debugging, but send only a descriptive message to the client: 'Database connection failed' rather than the full connection string and stack.

Mistake:

Defining too many tools on a single server (50+), which overwhelms the model's tool selection and degrades accuracy.

Fix:

Keep each server focused with 5-15 well-defined tools. If you need more capabilities, split them across multiple servers by domain (one for database operations, one for file management, one for API calls).

Mistake:

Making tool handlers synchronous and blocking, which prevents the server from handling other requests while a long-running tool executes.

Fix:

Always use async handlers. For CPU-intensive work, offload to a worker thread or subprocess. For I/O-bound work (API calls, database queries), use async/await to keep the event loop free.

Best Practices

  • Write tool descriptions from the perspective of the AI model. Explain what the tool does, when to use it, what it returns, and any constraints. The description is the model's primary guide for tool selection.
  • Use the most specific schema types available. Instead of z.string() for a date, use z.string().date(). Instead of z.string() for an email, use z.string().email(). Specific types improve validation and help the model provide correct values.
  • Return structured JSON for complex tool results. The model can parse and reason about structured data more accurately than unformatted text. Use json_response=True in Python or JSON.stringify in TypeScript.
  • Implement idempotency for tools that modify state. If the client retries a failed tool call, the second execution should not create duplicate records or perform the action twice.
  • Group related tools logically. If you have create-order, get-order, update-order, and cancel-order, they should all be on the same server so the model can discover and use them together.
  • Add rate limiting and timeouts to tools that call external APIs. A tool that makes unlimited API calls can exhaust quotas or hang indefinitely. Set reasonable timeouts and implement backoff strategies.

Summary

MCP tools are the action primitives of the protocol -- they let AI models invoke functions, query databases, call APIs, and modify state. Each tool is defined with a name, description, and input schema. The SDKs handle input validation, JSON-RPC serialization, and error formatting. In TypeScript, use registerTool with Zod schemas; in Python, use the @mcp.tool() decorator with type hints. Write specific descriptions to guide model selection, validate inputs beyond the schema for security, return structured content, and use async handlers for all I/O operations.

Practice MCP with hands-on challenges

Learn mcp tools hands-on in your IDE

Interactive lessons and challenges on Stanza, practice in VS Code, Cursor, or the web.

Related Concepts

Related Cheatsheets

Master MCP with Stanza

Interactive lessons and challenges, right in your code editor.

Check the free courses. No credit card.