What are MCP's core primitives, and who controls each one?
Quick Answer
MCP defines three primitives on the server side — Tools (executable functions, model-controlled: the LLM decides when to call them), Resources (readable data like files or query results, application-controlled: the host decides what to expose and when), and Prompts (reusable templated messages, user-controlled: a person explicitly picks one, often from a slash-command-style menu). On the client side, MCP defines Sampling (a server can ask the client's LLM to generate a completion), Roots (the client tells a server which directories/URIs it's allowed to operate within), and Elicitation (a server can ask the user, via the client, for extra structured input mid-operation). Keeping each primitive's control model distinct is what lets hosts build sane permission and UX models around them.
Detailed Answer
MCP's design leans on one idea: different kinds of context need different kinds of control. That's why it splits functionality into distinct primitives instead of one generic "capability" bucket.
Server-side primitives
| Primitive | Who decides to use it | Typical shape |
|---|---|---|
| Tools | The model — the LLM picks a tool and arguments based on the conversation | A function with a name, description, and JSON Schema input, e.g. send_email(to, subject, body) |
| Resources | The application/host — it decides what context to attach, often without the model asking | A URI-addressable piece of data, e.g. file:///project/README.md or postgres://db/customers/42 |
| Prompts | The user — explicitly selected, often surfaced as a slash command or menu item | A parameterized message template, e.g. /summarize-pr number=482 |
Client-side primitives
| Primitive | Direction | Purpose |
|---|---|---|
| Sampling | Server asks client | Lets a server request an LLM completion through the client's model, instead of needing its own API key or model access |
| Roots | Client tells server | Scopes a server's filesystem/URI access to specific directories the user has exposed |
| Elicitation | Server asks client (asks user) | Lets a server pause mid-task and request extra structured input from the user, e.g. a missing parameter |
Why the distinction matters
If everything were "just a tool," a host would have no principled way to tell these apart: a destructive action that needs explicit user approval, background context that can be attached silently, or a workflow that only runs when a human deliberately invokes it. By baking the control model into the primitive itself, MCP pushes hosts toward safer defaults. It doesn't leave permissioning entirely up to each app author's judgment.