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 ExperienceEnroll 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!
