What are MCP Prompts?
Understand user-controlled prompt templates and how they differ from tools.
What You'll Build
In this lesson, you'll build prompts.py — a reusable prompts
registry module, plus prompts_example.py to demonstrate it. By the end, your server will:
- Define prompts with arguments for customization
- Handle
prompts/listto advertise available prompts - Handle
prompts/getto return expanded prompt messages - Include practical prompts: code review, summarize, explain code, git commit
Each step builds on the previous one, and you'll test your server with curl commands.
Introduction to MCP Prompts
Prompts are pre-defined templates that help users interact with your MCP server in structured ways. Unlike tools (which AI models call automatically), prompts are user-controlled — the user explicitly selects and invokes them.
Tools are for AI models to call autonomously.
Prompts are for users to invoke directly, providing a structured
starting point for conversations.
Why Use Prompts?
Prompts serve several important purposes:
- Consistency — Ensure users get well-structured interactions every time
- Discoverability — Help users find common workflows without memorizing commands
- Parameterization — Accept arguments to customize the prompt for specific use cases
- Context injection — Include relevant context, instructions, or constraints
Prompts vs Tools vs Resources
Understanding the three MCP primitives:
| Primitive | Controlled By | Purpose |
|---|---|---|
| Tools | AI Model | Execute actions (read files, call APIs, compute) |
| Resources | Application | Provide data context (files, database records) |
| Prompts | User | Define conversation templates with arguments |
Prompt Arguments
Prompts can accept arguments to customize their behavior. Arguments make prompts flexible and reusable across different scenarios.
{
"name": "code-review",
"description": "Review code for bugs, style, and best practices",
"arguments": [
{
"name": "language",
"description": "Programming language of the code",
"required": true
},
{
"name": "focus",
"description": "What to focus on (security, performance, style)",
"required": false
}
]
}
How Prompts Work
The prompt workflow follows these steps:
┌─────────────────────────────────────────────────────────────┐
│ PROMPT WORKFLOW │
├─────────────────────────────────────────────────────────────┤
│ │
│ 1. USER browses available prompts │
│ Client ──► prompts/list │
│ Server ◄── list of prompts with arguments │
│ │
│ 2. USER selects a prompt and provides arguments │
│ Client ──► prompts/get { name, arguments } │
│ Server ◄── expanded prompt messages │
│ │
│ 3. CLIENT uses the prompt messages to start conversation │
│ (Messages are sent to the AI model) │
│ │
└─────────────────────────────────────────────────────────────┘
Example: A Simple Prompt
Here's how a "summarize" prompt might work. The user provides text, and the prompt generates a structured request for summarization.
# Example prompt definition
PROMPTS = {
"summarize": {
"name": "summarize",
"description": "Summarize the provided text concisely",
"arguments": [
{
"name": "text",
"description": "The text to summarize",
"required": True
},
{
"name": "max_sentences",
"description": "Maximum number of sentences (default: 3)",
"required": False
}
]
}
}
def get_prompt(name, arguments):
"""Generate prompt messages with argument substitution."""
if name == "summarize":
text = arguments.get("text", "")
max_sentences = arguments.get("max_sentences", "3")
return {
"messages": [
{
"role": "user",
"content": {
"type": "text",
"text": f"Please summarize the following text in {max_sentences} sentences or fewer:\n\n{text}"
}
}
]
}
return None
Unlike tools (which return results), prompts return messages that can be used to populate the conversation. These messages typically include instructions and the user's input formatted appropriately.
What's Next?
In the next step, we'll explore the detailed structure of prompt definitions, including how to properly define arguments with their types and validation.