Homework Solutions
Lesson 06 · MCP Servers
Solution to Task 1 — Search resource template
Reuse pkb.tools.search with its default limit, then JSON-encode the result so FastMCP can
serialize it. Drop this into pkb/resources.py and register it with the server the same way
you registered get_note in the lab:
import json
from pkb.tools import SearchArgs, search as _search
@mcp.resource("pkb://search/{query}")
def search_resource(query: str) -> str:
"""Search results as a JSON-encoded list of titles."""
return json.dumps(_search(SearchArgs(query=query)))
Common mistake
Returning the raw list[str] — FastMCP resources expect a string (or bytes).
JSON-encode the list with json.dumps(...).
Solution to Task 2 — Multi-message prompt
A prompt that returns list[PromptMessage] is FastMCP’s way of seeding a multi-turn
conversation. Each entry carries a role and a typed content payload:
from mcp.types import PromptMessage, TextContent
@mcp.prompt()
def summarize_prompt(topic: str) -> list[PromptMessage]:
"""Walk the LLM through summarizing notes on TOPIC."""
return [
PromptMessage(role="user", content=TextContent(type="text", text=f"Please summarize my notes on {topic}.")),
PromptMessage(role="assistant", content=TextContent(type="text", text="Of course — let me search.")),
PromptMessage(role="user", content=TextContent(type="text", text=f"Use pkb.search with query={topic}, then synthesize.")),
]
Common mistake
Returning a plain string from a multi-message prompt — FastMCP only sees one message. Use
list[PromptMessage] for multi-turn.
Solution to Task 3 — Pick the primitive
| Feature | Primitive | Why |
|---|---|---|
| Get the current weather for a city | Tool | Takes input (city) and returns a time-varying result; can’t be discovered via resources/list. |
| Contents of the user’s most recent note | Resource | Read-only, discoverable; the LLM should see it in resources/list automatically. |
| Email template for follow-up after a meeting | Prompt | Reusable template the user invokes; produces text for the LLM to expand. |
| Delete all notes older than 30 days | Tool | Mutates state; the act of calling it is the point. |
Looking ahead
Module 3 (Plan C) introduces sampling — server-initiated calls back to the LLM — and the full multi-tool PKB server.