MCP Tools vs Resources vs Prompts: Choose the Primitive
Use an MCP tool for callable behavior or computed retrieval, a resource for addressable context the client can read and manage, and a prompt for a user-chosen interaction template. The primitive should reflect who controls invocation and whether the operation can create side effects.
Choose by control surface and consequence
| Primitive | Protocol control model | Use it for | Primary risk to test |
|---|---|---|---|
| Tool | Model-controlled | Queries, calculations, API operations, and state-changing actions | Wrong invocation, unsafe arguments, excessive agency |
| Resource | Application-controlled | Files, records, documentation, schemas, and other addressable context | Unauthorized reads, stale content, context injection |
| Prompt | User-controlled | Discoverable templates for recurring interaction patterns | Misleading instructions, unsafe arguments, hidden assumptions |
| Resource template | Application-controlled with parameterized URI | Families of addressable content such as project or record views | Identifier tampering and enumeration |
| Tool returning a resource link | Model requests action; client chooses follow-up read | Computed discovery that points to reusable context | Link target trust and authorization continuity |
| None | Host-owned feature | Behavior that does not need a server protocol boundary | Added complexity without interoperability value |
The MCP 2025-06-18 server overview describes prompts as user-controlled, resources as application-controlled, and tools as model-controlled. That control hierarchy is a design aid, not an authorization system.
Use tools for bounded executable behavior
A tool has a unique name, description, input schema, and optionally an output schema and annotations. The model may discover and request it, while the client and server decide whether and how execution occurs. Good tools expose one coherent capability with explicit inputs, outputs, side effects, errors, idempotency behavior, and permission checks.
The official MCP tools specification distinguishes protocol errors from execution errors and allows structured content. It also requires servers to validate inputs and implement access controls, while clients should support confirmation for sensitive operations, validate results, use timeouts, and log tool use. Treat annotations as untrusted unless the server is trusted.
A read operation can still be a tool when it performs a parameterized query, computation, or external action. The decision is not “read versus write” alone; it is whether model-requested execution is the appropriate interaction.
Use resources for addressable context
A resource represents content with a URI and descriptive metadata. The client can list, read, attach, cache, subscribe to, or render it according to supported capabilities and product policy. This is a better fit for documentation, file content, database views, schemas, or history that should remain identifiable outside one model turn.
Resources do not become safe merely because they are “context.” Retrieved text can contain untrusted instructions, sensitive data, or stale facts. The host must enforce read authorization, decide what reaches the model, separate data from instructions, bound content size, and preserve origin and revision. Parameterized resource templates also need strict input validation and enumeration controls.
Use prompts for user-invoked interaction templates
An MCP prompt exposes a named template with a description and optional arguments. It is suitable for workflows users intentionally choose, such as reviewing a document, drafting a release note from selected context, or beginning a guided analysis. The client determines how prompts appear in menus, commands, or other interfaces.
Prompt templates should state their purpose, required arguments, context assumptions, output expectation, and limits. They must not smuggle tool authority or bypass host policy. A prompt can recommend an action, but any tool call that follows still passes through normal validation, authorization, confirmation, and execution controls.
The host composes primitives and enforces policy
The host may attach resources to a conversation, let the user select a prompt, and expose a curated group of tools to the model. It should show users which server and capability are involved, keep server connections isolated, and avoid giving every server the full conversation. Primitive choice helps clarify control, but the host remains responsible for context disclosure and consent.
Keep provenance when capabilities interact. If a tool returns a resource link, retain the server identity and reauthorize the resource read. If a prompt refers to a resource, resolve it under the current user. If resource content causes a tool proposal, treat the content as untrusted data and evaluate the tool request independently.
Primitive-choice failure cases
- Everything is a tool: static context becomes model-controlled execution, increasing calls and authority. Prefer resources for addressable content.
- Mutating operation as a resource: reading a URI secretly changes state. Reads should not hide side effects.
- Prompt as policy bypass: a template tells the model to skip approval. Host policy outranks template instructions.
- Resource content as instruction: a document tells the model to call a dangerous tool. Preserve the data boundary and reauthorize every action.
- Tool metadata as truth: a malicious description understates side effects. Curate trusted servers and enforce server-side contracts.
- URI authorization gap: a user changes a template parameter to read another tenant. Bind identity server-side and deny enumeration.
- Capability drift: cached discovery no longer matches the server. Handle change notifications and reconnect validation.
A primitive-first implementation sequence
- Name the user interaction. Identify who initiates it, what information crosses the boundary, and whether external state can change.
- Choose the control model. Use a prompt for explicit user selection, a resource for client-managed context, or a tool for model-requested execution.
- Write the primitive contract. Define identifiers, arguments, schemas, content types, errors, revisions, permissions, limits, and side effects.
- Declare only implemented capabilities. Make discovery accurate, stable, paginated where required, and version-aware.
- Apply policy at every transition. Authenticate servers, authorize reads and actions, validate arguments and URIs, and confirm consequential effects.
- Test primitive-specific failures. Cover malformed calls, stale resources, prompt argument gaps, untrusted content, changed discovery, and denied users.
- Observe composition. Trace which prompt, resource, tool, server, user decision, and policy outcome produced the final behavior.
Decision summary
Expose executable behavior as tools, addressable context as resources, and user-invoked interaction templates as prompts. Let the host compose them, keep authorization outside descriptive metadata, and split mixed primitives when their consequences or trust boundaries differ.
Primary and official sources
- MCP 2025-06-18 server features overview — official primitive definitions and control hierarchy.
- MCP 2025-06-18 tools specification — official schemas, results, errors, interaction, and security considerations.