The MCP Python SDK offers two advanced features for building more sophisticated servers: Sampling and Completions.
Sampling: Dynamic LLM Interactions
Sampling allows your tools to call the LLM during execution. Instead of just returning data from the database, a tool can ask the LLM that powers the Agent to transform, explain, or enhance that data.
For example, a tool could retrieve movie information from Neo4j and then ask the LLM to convert the strctured data into a natural language description:
@mcp.tool()
async def explain_movie_data(movie_title: str, ctx: Context) -> str:
"""Get a natural language explanation of movie data."""
# Get movie data from Neo4j
movie_data = await get_movie_details(movie_title, ctx)
# Ask LLM to explain the data
result = await ctx.session.create_message(
messages=[
SamplingMessage(
role="user",
content=TextContent(
text=f"Describe {movie_data['title']} ({movie_data['released']}) " +
f"starring {', '.join(movie_data['actors'])}. " +
"Write 2-3 engaging sentences."
)
)
],
max_tokens=200
)
return result.content.text if result.content.type == "text" else str(result.content)Use sampling when you need:
-
Natural language generation from structured data
-
Dynamic summaries based on query results
-
Content that adapts to the specific data retrieved
-
Recommendations or insights derived from data
Sampling requires client support and adds processing overhead. The client must support the sampling capability for this feature to work.
Completions: Smart Parameter Suggestions
Completions provide autocomplete suggestions when users are filling in tool parameters or resource URIs. This helps users discover valid values without memorizing them.
For example, when a user starts typing a genre name, completions can suggest matching options from the database:
@server.complete()
async def handle_completion(
ref: types.PromptReference | types.ResourceReference,
argument: types.CompleteArgument
) -> CompleteResult:
"""Provide genre completions."""
if argument.name == "genre":
records, _, _ = await driver.execute_query(
"""
MATCH (g:Genre)
WHERE g.name STARTS WITH $prefix
RETURN g.name AS name
ORDER BY name ASC LIMIT 10
""",
prefix=argument.value
)
return CompleteResult(
completion=Completion(
values=[record["label"] for record in records]
)
)
return CompleteResult(completion=Completion(values=[]))Use completions when:
-
Users need to discover valid parameter values
-
Your tools accept specific values from a dataset
-
You want to improve user experience with suggestions
-
Form-based interfaces benefit from autocomplete
Completions require using the low-level Server API instead of FastMCP’s decorator-based approach.
Choosing Advanced Features
Both features are optional and add complexity. Consider them when:
-
Building user-facing tools where experience matters
-
The benefit justifies the implementation cost
-
Your client supports these capabilities
Always check client support before using advanced features:
if ctx.session.client_params.capabilities.sampling:
# Use sampling
else:
# Provide simpler alternativeSummary
Advanced MCP features can enhance your server’s capabilities:
-
Sampling - Dynamic content generation through LLM interactions
-
Completions - Smart parameter suggestions for better UX
-
Implementation Notes - Check client support and consider performance impact
In the next lesson, you’ll review what you’ve learned and explore next steps.