MCP in Practice

Lesson 19 of 36

Prompts

The one the user chooses

Prompts are the least-used primitive and the most under-rated. They are message templates a user invokes by name — a slash command, a menu item, a button — with arguments they fill in.

python
@mcp.prompt(title="Weekly utilisation review")
def weekly_utilisation_review(
    week_of: Annotated[str, Field(description="Monday of the week under review, YYYY-MM-DD.")],
) -> str:
    """Draft the Monday note on how the floor was used last week."""
    return (
        f"Read rooms://catalog, then summarise how the floor was used in the week of {week_of}. "
        "Give one line per room, name the busiest and quietest day, and call out any room under "
        "30% utilisation with a suggestion."
    )

Retrieving it:

python
result = await client.get_prompt("weekly_utilisation_review", {"week_of": "2026-09-14"})
print(result.messages)
text
[PromptMessage(role='user', content=TextContent(type='text', text='Read rooms://catalog, then summarise how the floor was used in the week of 2026-09-14. Give one line per room, name the busiest and quietest day, and call out any room under 30% utilisation with a suggestion.'))]

The function name is the prompt name, the docstring is its description, and parameters become arguments — required when they have no default.

The recipe on the packet

The manufacturer prints a recipe on the box because they know the ingredient better than you do. They are not taking the pan out of your hands; you can ignore it entirely. But they have seen what goes wrong, and the recipe is them telling you.

That is what a prompt is, and it explains why the primitive exists at all. For a beginner: the server author is offering their own best way to use the thing they built. For anyone who has maintained a library, it is the same instinct as shipping a good README example — you know which three of the forty possible calls people actually want, and saying so is worth more than another feature.

The utilisation prompt above encodes real knowledge. It tells the model to read the catalog first, because otherwise it invents room names. It asks for one line per room, because unbounded summaries drift. It names the 30% threshold, because the floor manager has a threshold and the model does not know it. A member typing "summarise last week" gets none of that.

A prompt carries the server author's own knowledge of how to drive the server well
A prompt carries the server author's own knowledge of how to drive the server well

Multi-message prompts

A prompt can return a conversation, not just a string:

python
from mcp.server.mcpserver.prompts.base import AssistantMessage, Message, UserMessage

@mcp.prompt(title="Apologise for a double booking")
def apology_for_double_booking(booking_id: str, room_name: str) -> list[Message]:
    """Draft an apology to a member whose room was double-booked."""
    return [
        UserMessage(f"Booking {booking_id} for {room_name} was double-booked. Draft an apology."),
        AssistantMessage(
            "I'll keep it short, take responsibility without excuses, and offer a specific "
            "alternative. What tone would you like?"
        ),
    ]

The pre-filled assistant turn is the interesting part. It steers the model's next reply without the user having to type the steering — the model is now committed to being brief, non-defensive and concrete, because it apparently already said it would be.

Use this where the shape of the answer matters more than its content. Overuse makes the assistant feel scripted, which it is.

Designing prompts people pick

A prompt only helps if somebody chooses it from a list, so it competes on its name and description.

  • Name it after the outcome, not the mechanism. "Weekly utilisation review" beats "Generate report".
  • Keep arguments few and obvious. Every required argument is a field somebody has to fill before getting anything. One is usually enough; three is a form.
  • Give arguments sensible defaults where you can. A week_of that defaults to last Monday is one fewer decision.
  • Write the description for the menu. It is one line in a picker, not documentation.

And the honest note: prompt support varies across hosts, much like resources. Where a host exposes them as slash commands they are excellent; where it does not, they are invisible. Check before investing heavily.

What to take into the next lesson

Prompts are user-invoked templates that let a server author ship their own best way to drive the server, encoding thresholds and sequences a user would not know to ask for; they return a string or a whole conversation, and a pre-filled assistant turn steers the reply that follows. Next: what a handler can reach while it runs.

← Previous