Feedback

Chat Icon

Practical MCP with FastMCP & LangChain

Engineering the Agentic Experience

Parameter Types, Tool Descriptions, and Additional Customization
44%

Better Control with Pydantic

So at this stage, we have a tool that accepts an integer age and returns an integer:

@mcp.tool
def dog_to_human_age(age: int) -> int:
    """Calculate the real age of a dog in human years."""
    return age * 7

Imagine if the age sent by the LLM is negative, for example -3 or if the age is unrealistically high, like 50. The tool would still return a result, but it wouldn't make sense in the real world.

To handle this, we can use the following approach:

from pydantic import Field
from typing import Annotated

@mcp.tool
def dog_to_human_age(
    age: Annotated[int, Field(ge=0, le=30)]
) -> int:
    """Calculate the real age of a dog in human years."""
    return age * 7

In Python, Annotated is a way to attach additional metadata to type hints to provide more information about the expected values. For example:

age: Annotated[int, "This is the age of the dog in years, which must be a non-negative integer and realistically should not exceed 30 years."]

Pydantic's Field is a function that lets you attach extra information to a type annotation, things like minimum and maximum values, a description, or a default. Instead of just declaring age: int, you can write age: Annotated[int, Field(ge=0, le=30, description="The dog's age in years")] to say: "this is an integer, it must be between 0 and 30 (inclusive), and here is what it means."

FastMCP reads these constraints when building the tool's input schema, so they are sent to the LLM as part of the tool definition. The LLM learns what values are valid before it calls the tool. Pydantic also enforces them server-side, if an invalid value arrives anyway, validation fails before your function runs, and FastMCP returns an error to the caller automatically.

The most commonly used Field parameters for tool arguments are:

  • gt / lt: greater than / less than (exclusive bounds)
  • ge / le: greater than or equal / less than or equal (inclusive bounds)
  • description: shown to the client in the tool schema
  • default: marks the parameter as optional with a fallback value

For our example, to enforce that the age must be between 0 and 30, we can use ge=0 and le=30 in the Field definition.

Here is an example:

from typing import Annotated
from pydantic import Field

Practical MCP with FastMCP & LangChain

Engineering the Agentic Experience

Enroll now to unlock current content and receive all future updates for free. Your purchase supports the author and fuels the creation of more exciting content. Act fast, as the price will rise as the course nears completion!