Feedback

Chat Icon

Practical MCP with FastMCP & LangChain

Engineering the Agentic Experience

User Elicitation
62%

Implementing Elicitation

To put in work the elicitation system, we are going to add the necessary code that will do the following:

  • Perform a fuzzy search for the breed name provided by the user.
  • Return the best match depending on the similarity score.
  • If the fuzzy search returns a close match, we will proceed with the elicitation.

We're going to use get_close_matches from the difflib standard library module to perform the fuzzy search. This function takes a query string and a list of possible matches, and returns the closest matches based on string similarity.

Example:

from difflib import get_close_matches

[...]

BREED_MULTIPLIERS = {
    "labrador": 7,
    "chihuahua": 5,
    "german shepherd": 8,
    "bulldog": 6,
}

def get_breed_multiplier(breed: str) -> int | None:
    """Fetch the age multiplier for a given dog breed."""
    return BREED_MULTIPLIERS.get(breed.lower())

@mcp.tool
async def dog_to_human_age(
    age: Annotated[int, Field(ge=0, le=30, description="The dog's age in years")],
    breed: Annotated[str, Field(description="The dog's breed")],
    ctx: Context,
) -> int:
    """Calculate the real age of a dog in human years based on its breed."""

    # Let the client know what we're doing
    await ctx.info(f"Looking up breed multiplier for '{breed}'")

    multiplier = get_breed_multiplier(breed)

    if multiplier is None:
        # Look for 1 similar breed name
        suggestions = get_close_matches(
            breed.lower(), BREED_MULTIPLIERS.keys(), n=1, cutoff=0.6
        )
        if suggestions:
            # Elicit the user with the best match
[...]            

Here is the full code that implements elicitation:

cat > $HOME/workspace/puppy_guide/server/main.py << EOF
import os
from difflib import get_close_matches
from typing import Annotated

from dotenv import load_dotenv
from pydantic import Field

from fastmcp import Context
from fastmcp import FastMCP
from fastmcp.exceptions import ToolError

load_dotenv()

mcp = FastMCP(
    name=os.getenv("MCP_NAME"),
    instructions=os.getenv("MCP_INSTRUCTIONS"),
)


BREED_MULTIPLIERS = {
    "labrador": 7,
    "chihuahua": 5,
    "german shepherd": 8,
    "bulldog": 6,
}


def get_breed_multiplier(breed: str) -> int | None:
    """Fetch the age multiplier for a given dog breed."""
    return BREED_MULTIPLIERS.get(breed.lower())


@mcp.tool
async def dog_to_human_age(
    age: Annotated[int, Field(ge=0, le=30, description="The dog's age in years")],
    breed: Annotated[str, Field(description="The dog's breed")],
    ctx: Context,
) -> int:
    """Calculate the real age of a dog in human years based on its breed."""

    # Let the client know what we're doing
    await ctx.info(f"Looking up breed multiplier for '{breed}

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!