Resources, Tools & Prompts
The three MCP primitives and when to use each.
MCP servers expose three kinds of capabilities. Choosing the right one makes your server intuitive.
Tools β actions
The model calls a tool to do something. Every call is a request/response.
@mcp.tool()
def create_issue(title: str, body: str) -> str:
"""Create a GitHub issue."""
...
Use tools when the model should change state: write a file, run a query, post a message.
Resources β data
Resources are readable data the model can pull into context, addressed by URI.
@mcp.resource("db://schema")
def schema() -> str:
"""The current database schema."""
return get_schema()
Use resources for things the model should read on demand: a schema, a style guide, a log file.
Prompts β templates
Servers can ship reusable prompt templates with arguments.
@mcp.prompt()
def review(code: str) -> str:
return f"Review this code for bugs:\n\n{code}"
Use prompts for repeatable workflows your team standardizes (code review, commit messages).
How the model sees it
From the model's perspective:
- Tools = "things I can call."
- Resources = "things I can read."
- Prompts = "templates I can expand."
A good server uses the right primitive:
| Want the model to⦠| Use | | --- | --- | | Query the database | tool | | Read the DB schema | resource | | Follow your team's PR checklist | prompt | | Send a Slack message | tool |
Rule of thumb: state changes β tools; facts β resources; recipes β prompts.