MCP Primitives: Tools, Resources, Prompts
The three MCP primitives, who invokes each one, and how to pick the right primitive for a given capability.
MCP servers expose capabilities through three distinct primitive types: Tools, Resources, and Prompts. These are not interchangeable — each is invoked by a different party in the system, and picking the wrong primitive for a capability produces an awkward or broken integration even if the underlying code works fine.
Tools: model-invoked actions
Tools are actions the model itself decides to invoke, the same way it would call any other tool_use-based function. A "create_ticket" or "run_query" capability belongs here. The model reads the tool's description and schema (exactly as covered in tool schema design) and autonomously decides, based on the conversation, whether and when to call it. Tools are for anything where the decision of "should this run right now" should be made by the model reasoning about the user's request.
Resources: contextual data the app reads
Resources are data the host application can read and attach as context — a file's contents, a database schema, a log excerpt, a configuration document. Critically, resources are typically surfaced and selected by the user or the host application, not autonomously invoked by the model the way tools are. A user might browse available resources in a UI and attach one to a conversation, or the host might attach a resource automatically based on the current working context (like the currently open file). The model then reads the resource's content as part of its context, but the model does not "call" a resource the way it calls a tool.
Prompts: reusable templates
Prompts are reusable, parameterized templates that a server exposes for constructing a well-formed conversation starter or a common workflow — for example a "review_pull_request" prompt that expands into a structured instruction set when a user selects it. Like resources, prompts are invoked by the user or the host's UI (often surfaced as a slash-command-like menu), not autonomously by the model. They exist to standardize a recurring interaction pattern the server author has already figured out is useful.
Choosing the right primitive
The deciding question is: who should decide when this capability activates? If the answer is "the model, reasoning in-context about what the user needs" — that's a tool. If the answer is "the user, browsing and picking what to attach" — that's a resource. If the answer is "the user, invoking a known named workflow" — that's a prompt.
Overlap and combinations
A single server commonly exposes more than one primitive type, and a capability that starts as one primitive can reasonably grow a second form as usage patterns become clear. A wiki server might begin with just a Tool for search-and-fetch, then later add specific Resources for a handful of documents that are attached in nearly every conversation, since forcing the model to search for the same onboarding page every single session is wasted latency and tokens compared to letting a user attach it once as a Resource. Similarly, a workflow that starts as informal instructions typed into chat each time is a good candidate to formalize into a Prompt once a team notices they're retyping the same structure repeatedly.
The three primitives also differ in how much they rely on the model's judgment versus the host's UI. Tools depend entirely on description quality, exactly as covered for API-level tool schemas, because the model has no other signal for when to call them. Resources and Prompts depend more on how the host chooses to surface them — a host with a poor resource-browsing UI will make even well-designed Resources hard for users to find and attach, which is a host-side failure rather than a server-design failure.
Scenario: an MCP server for an internal wiki exposes the wiki's search-and-fetch-page capability as a Tool (the model decides when a question needs a wiki lookup), exposes a specific onboarding document as a Resource a new employee can manually attach to their first chat, and exposes a "draft_incident_report" Prompt that a user explicitly invokes to get a pre-structured template. Three different primitives, three different invokers, same server.
Try it
Pick any MCP server you have configured (or a public one's documentation) and list every capability it exposes, sorting each into Tools, Resources, or Prompts. For at least one Tool, explain in a sentence why it makes sense for the model to decide when to invoke it rather than the user; for at least one Resource or Prompt, explain why user selection is the better fit than model autonomy.