Your First MCP Tool

from mcp.server import MCPServer

mcp = MCPServer("Utility Server")

@mcp.tool()
def calculate_tax(amount: float, rate: float) -> dict:
    """Calculate tax for an amount using a decimal rate."""
    tax = amount * rate
    return {"amount": amount, "tax": tax, "total": amount + tax}

Type hints become the contract

The SDK uses your function signature to derive the input schema. The docstring is part of the tool description that a host or model can use to decide when the tool is appropriate.

Choose explicit types

Use enums or constrained models when the domain has a limited set of values. Avoid accepting arbitrary dictionaries when a structured model would make invalid calls impossible.

Keep descriptions operational

Explain what the tool does, when it should be used, and important side effects. For mutation tools, make the destructive or irreversible nature obvious.

Tool quality affects model quality. A technically valid tool with an ambiguous name or schema can still perform poorly.