Prompts: workflows the user invokes

The third primitive is the one most developers ignore, which is a quiet mistake: prompts are the cheapest leverage in MCP. A prompt is a named, parameterised message template the server ships and the user explicitly invokes — expertise about how to use a system, delivered by the system itself.

A real prompt

Paper Trail's Monday ritual, encoded:

python
@mcp.prompt
def weekly_summary(week: str) -> str:
    """Template for the Monday operations summary."""
    return (f"Write the Paper Trail operations summary for week {week}. "
            "Sections: orders shipped, orders delayed, refunds issued, one risk. "
            "Keep it under 200 words and never invent a number.")

Discovery, then a prompts/get with the argument filled — captured:

text
== prompts ==
  weekly_summary: Template for the Monday operations summary.  args=['week']
== prompts/get weekly_summary ==
  role: user
  text: Write the Paper Trail operations summary for week 2026-W31. Sections: orders shipped, orde…

The server returns messages, not effects: here one user-role message, ready to drop into the conversation. A prompt may also return a multi-turn sequence — a user/assistant exchange that sets up a working pattern before the real conversation begins.

User-controlled, and where that surfaces

Prompts complete the control triangle: tools the model invokes, resources the application loads, prompts the user runs — typically surfaced as slash commands (Claude Code and Claude Desktop both render them that way; type / and connected servers' prompts appear by name). The model never triggers a prompt; a person reaches for one.

That placement is what makes them valuable. The person who built the order system knows the questions worth asking of it — the report structure that catches delayed orders, the caveats ("never invent a number") that keep a summary honest. Without prompts, that knowledge lives in a wiki nobody reads or gets re-typed badly by every user. As a prompt, it ships inside the integration, versioned with the server, one keystroke from use. The test for a good one: it encodes how the tools compose and what a good result looks like — not merely "please do X", which the user could type themselves.

The trifecta, assembled

One workflow, all three primitives, each in its lane: the user attaches policy://returns (their call — the model now sees the actual policy, not a memory of one) and invokes /weekly_summary 2026-W31 (their call — the expert-written template enters as their message). The template's instructions send the model to order_status and the refund log (its call, per tool, behind the host's gate). The model writes the summary — grounded by a resource the human chose, structured by a prompt the human invoked, fed by tools it chose itself. Doing, knowing, thinking; model, application, user. When you design a server, you are not writing three feature lists — you are deciding, capability by capability, who should be in charge of it.

One workflow using all three primitives, each under its own controller
One workflow using all three primitives, each under its own controller

Try this: take a task you personally perform with an AI assistant against some system, and write the prompt template a server should ship for it — arguments and all. If nothing in your template needed expertise, it was not a prompt worth shipping; sharpen it until it teaches.

← Previous