Defining prompts
Users are bad at writing prompts. That sentence is not a criticism — it's a product opportunity. If your MCP server knows its domain well, you can ship pre-authored, carefully tested prompt templates that users can invoke by name instead of writing from scratch. A user typing convert report.pdf to markdown gets a decent result; a user invoking the server's format prompt with a document argument gets a reliable result, because you wrote that prompt, tested it, and know what it does. That's what MCP prompts are for.
What MCP prompts are
MCP prompts are parameterised message templates defined on the server and requested by clients. When a client asks for a prompt, the server returns a list of messages (already filled in with whatever arguments the client supplied) that can be sent straight to Claude.
Three important properties:
- Pre-authored. You write the prompt, tune it, test it. The user just selects it by name.
- Parameterised. Prompts take arguments — a document ID, a tone, a target audience — and interpolate them into the template.
- Domain-specific. Prompts should represent expertise in whatever your MCP server covers. A document-management server has format-and-clean-up prompts. A GitHub server has draft-release-notes prompts. A code-review server has review-this-PR prompts.
The best way to think about them: prompts are the server's opinion about how to do common things well. Users don't have to know the trick. They just ask for "format."
Why bother?
A user could type:
Reformat this document in markdown. Add headers and bullet points.
And it would work — ish. Claude would make reasonable choices, most of the time. The output might miss a table conversion, or leave inconsistent heading levels, or refuse to handle certain edge cases that your domain cares about.
A carefully tested prompt for the same task might:
- Specify exact markdown rules (ATX-style headers, no trailing whitespace, fenced code blocks with languages).
- Include concrete examples of good before/after pairs for the common cases.
- Handle edge cases explicitly (tables, nested lists, footnotes, images).
- Reference specific tools the server provides for applying the changes.
The result is consistent, reliable, and high-quality in ways that a user-written prompt usually isn't. The user doesn't have to learn any of that — they invoke format and get the expert version.
Defining a prompt with @mcp.prompt()
The FastMCP decorator for prompts mirrors the tool and resource decorators. The return type is a list of messages:
from mcp.server.fastmcp import FastMCP
from mcp.server.fastmcp.prompts import base
from pydantic import Field
@mcp.prompt(
name="format",
description="Rewrites the contents of the document in Markdown format.",
)
def format_document(
doc_id: str = Field(description="Id of the document to format"),
) -> list[base.Message]:
prompt = f"""
Your goal is to reformat a document to be written with markdown syntax.
The id of the document you need to reformat is:
<document_id>
{doc_id}
</document_id>
Add in headers, bullet points, tables, and any other markdown
formatting that improves readability. Be thorough — prefer richer
formatting over a plain conversion.
Use the 'edit_document' tool to apply the changes. After every
edit, verify the new content by re-reading the document with the
'read_doc_contents' tool. Do not stop until the formatting is
complete and consistent.
"""
return [base.UserMessage(prompt)]
Four things to notice:
@mcp.prompt(name=..., description=...)— same pattern as@mcp.tooland@mcp.resource. The description is what the client shows in its prompt picker.doc_id: str = Field(description=...)— the argument pattern is identical to tools. The SDK generates the expected-argument schema for the client.- The prompt body uses every Module 5 technique you know — clarity, specific instructions, XML tags for the document ID, a reference to the tools the model should use, explicit completion criteria. A good MCP prompt looks like a Module 5 prompt, because that's exactly what it is.
- Return
[base.UserMessage(prompt)]— a list of message objects. The SDK'sbasemodule providesUserMessageandAssistantMessageconstructors. You can return one message or several — a multi-turn starter conversation is perfectly valid if the task benefits from few-shot priming.
When a client requests format with doc_id="report.pdf", the SDK calls format_document(doc_id="report.pdf"), the prompt string gets interpolated, and the returned list of messages flows back to the client ready to be sent directly to Claude.
Testing in the inspector
The MCP Inspector (from the server inspector lesson) has a Prompts section alongside Tools and Resources. Navigate there and you'll see your format prompt listed.
- Click the prompt to see its arguments.
- Fill in
doc_idwith a valid document ID. - Invoke it to see the generated messages.
The inspector renders the final prompt text exactly as it would be delivered to Claude. This is where you iterate — tweak the template, re-invoke in the inspector, confirm the interpolation works, and validate the prose looks the way you want before any client ever consumes it.
Test the full path in the inspector before deploying. MCP prompts are meant to be "expert-grade" — if they're not better than what a user would write on their own, they don't justify existing.
Best practices
- Focus on tasks central to your server's purpose. Don't ship a random assortment; ship a handful of prompts that represent the operations your server was built to support.
- Write detailed, specific instructions — not vague requests. Apply every Module 5 technique.
- Test thoroughly with varied inputs. A prompt that works for one document but fails for the next isn't production-grade.
- Include clear descriptions so users can tell what each prompt does at a glance in the client UI.
- Design prompts to work with your server's tools and resources. A prompt that references tools only your server provides is exactly the kind of added value that makes the MCP server worth connecting to.
Prompts vs tools vs resources, in one sentence
- Tools — Claude decides when to call them, they perform actions.
- Resources — the client fetches them directly, they return data.
- Prompts — the client requests them as pre-authored message templates, and the messages go straight to Claude.
All three are parts of the same MCP server, and all three are ways the server adds value beyond what a client could achieve with direct API calls and hand-written prompts. In the next lesson you'll add list_prompts and get_prompt to your MCPClient wrapper so the CLI chatbot can surface prompts as slash commands.
Key Takeaways
- 1MCP prompts are pre-authored, parameterised message templates that let server authors ship expert-grade versions of common tasks in their domain.
- 2They represent the server's opinion about how to do common things well — users invoke them by name instead of writing prompts from scratch.
- 3Define prompts with @mcp.prompt(name=..., description=...); take arguments with Field(description=...); return a list of base.UserMessage (and optionally base.AssistantMessage) objects.
- 4A good MCP prompt applies every Module 5 prompt engineering technique — clarity, specificity, XML structure, explicit completion criteria, references to the server's own tools and resources.
- 5Test prompts in the MCP Inspector before deploying them; watch how the interpolation renders and validate the final prose matches what you intended.
- 6Focus on prompts central to your server's purpose and design them to work with your tools and resources for maximum added value.