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.

By Mario AlexandreMCP & Agent Engineering

Choose by control surface and consequence

Primitive choice based on control model, contract, and primary risk.
PrimitiveProtocol control modelUse it forPrimary risk to test
ToolModel-controlledQueries, calculations, API operations, and state-changing actionsWrong invocation, unsafe arguments, excessive agency
ResourceApplication-controlledFiles, records, documentation, schemas, and other addressable contextUnauthorized reads, stale content, context injection
PromptUser-controlledDiscoverable templates for recurring interaction patternsMisleading instructions, unsafe arguments, hidden assumptions
Resource templateApplication-controlled with parameterized URIFamilies of addressable content such as project or record viewsIdentifier tampering and enumeration
Tool returning a resource linkModel requests action; client chooses follow-up readComputed discovery that points to reusable contextLink target trust and authorization continuity
NoneHost-owned featureBehavior that does not need a server protocol boundaryAdded 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

  1. Name the user interaction. Identify who initiates it, what information crosses the boundary, and whether external state can change.
  2. Choose the control model. Use a prompt for explicit user selection, a resource for client-managed context, or a tool for model-requested execution.
  3. Write the primitive contract. Define identifiers, arguments, schemas, content types, errors, revisions, permissions, limits, and side effects.
  4. Declare only implemented capabilities. Make discovery accurate, stable, paginated where required, and version-aware.
  5. Apply policy at every transition. Authenticate servers, authorize reads and actions, validate arguments and URIs, and confirm consequential effects.
  6. Test primitive-specific failures. Cover malformed calls, stale resources, prompt argument gaps, untrusted content, changed discovery, and denied users.
  7. 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

  1. MCP 2025-06-18 server features overview — official primitive definitions and control hierarchy.
  2. MCP 2025-06-18 tools specification — official schemas, results, errors, interaction, and security considerations.