Skip to content

07 · Prompts: Reusable Prompt Templates

What a prompt template actually is

A prompt in MCP is a reusable, parameterized piece of prompt text that a server offers — think of it as a saved, fill-in-the-blanks request. Where a tool is something the model decides to call mid-conversation, a prompt is something the user typically invokes explicitly, the way you'd pick a saved template from a menu rather than describe what you want from scratch every time.

Hosts commonly surface prompts as quick-actions or slash-commands in their UI — the user sees a list of available prompts by name and picks one, rather than the model silently choosing to use one.

Defining a prompt

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("demo-server")

@mcp.prompt()
def code_review(language: str, focus: str = "general code quality") -> str:
    """Generate a code review request for a given language and focus area."""
    return (
        f"Please review the following {language} code, focusing on "
        f"{focus}. Point out specific issues with line references, and "
        f"suggest concrete fixes rather than general advice."
    )

@mcp.prompt() works the same way @mcp.tool() does: the function's type hints become the prompt's argument schema, and the docstring becomes its description. language is required (no default), focus is optional (it has a default value). A client calling prompts/get with {"language": "Python"} gets back the fully-rendered prompt text with focus filled in from its default.

Arguments with defaults vs. without

@mcp.prompt()
def summarize(text: str, max_sentences: int = 3) -> str:
    """Summarize a block of text in a target number of sentences."""
    return f"Summarize the following text in at most {max_sentences} sentences:\n\n{text}"

Here text must be supplied every time; max_sentences falls back to 3 when the caller doesn't specify it. This is exactly how optional tool arguments behave too — the same Python defaults mechanism drives both.

Prompt or tool — which one?

Ask: is this something the user explicitly chooses to trigger, with a roughly fixed shape each time ("review this code," "summarize this text," "write a commit message for this diff")? That's a prompt. Is it something the model should decide to reach for on its own, based on reasoning about what the user's actual request needs? That's a tool.

A "generate a weekly status report" request the user runs the same way every Friday is a good prompt — it's a known, repeatable shape of request. A "look up this customer's order history" request that the model should trigger automatically whenever it's relevant to the conversation is a tool — the model needs to decide when it applies, not the user.

Exercise

Write a prompt explain_error(error_message: str, language: str = "Python") that returns a request asking for a plain-English explanation of the given error message and, if applicable, a likely fix, in the context of the given language. Confirm in the Inspector that prompts/get with just an error_message argument still works correctly, falling back to the language default.