Three primitives, not one
MCP exposes three primitives — Tools, Resources, and Prompts — because hosts render each as a different UI affordance. Treat them as interchangeable and you lose the leverage.
Tools
- Side-effectful actions: create, update, delete, query.
- Typed input schema, structured output.
- Surfaced as buttons, auto-invoked by the model, or both.
Resources
- Read-only context the host can fetch and cache.
- URI-addressed:
file://,db://, custom schemes. - Rendered in a resource picker; the user attaches them to a turn.
Prompts
- Parameterized templates the host surfaces as slash commands.
- Server returns the messages to send; the model never sees the template directly.
- Good for sharing "ways of asking" across a team.
Heuristic
If it mutates, it's a tool. If it can be cached and re-attached, it's a resource. If it's a template the user picks, it's a prompt.
FAQ
- When should I use a Tool vs a Resource?
- Tools when the model needs to *do* something (mutate state, run a query, call an API). Resources when the model needs to *read* something the host can fetch once and reuse — files, documents, schemas. The split matters because resources can be cached and surfaced in the host UI; tools cannot.
- What are Prompts actually for?
- Shareable, parameterized templates the host can offer the user as a slash command. Think 'summarize this PR' or 'draft a changelog entry'. They are not for system instructions to your model — keep those server-side.
- Can one MCP server expose all three?
- Yes, and most production servers do. A GitHub server exposes tools (create_issue), resources (repo file tree), and prompts (review_pr). Hosts pick what to surface based on UX.
- Why does this split exist at all?
- So hosts can render the right UI affordance for each. A resource picker, a tool button, a slash menu — they're different surfaces. Collapsing them into 'just functions' loses UX leverage.