On this page
MCP Resources vs Tools: What's the Difference and When to Use Each (Oct 2026)

In MCP, tools are actions the model chooses to call, and resources are data the application or user attaches as context. A tool can query, write, send or delete. A resource is something to read: a file, a schema, a record. That difference decides what needs your approval and what a server should expose.

The difference in one table

The MCP spec sorts a server's three building blocks by who controls them. This table is quoted from the server overview in the current (2026-07-28) spec.

Primitive Control Description Example
Prompts User-controlled Interactive templates invoked by user choice Slash commands, menu options
Resources Application-controlled Contextual data attached and managed by the client File contents, git history
Tools Model-controlled Functions exposed to the LLM to take actions API POST requests, file writing

So the short version: the model picks tools, the app (or you) picks resources, and you pick prompts.

Tools: actions the model decides to take

The spec defines tools as functions that let models "interact with external systems, such as querying databases, calling APIs, or performing computations." They are "model-controlled, meaning that the language model can discover and invoke tools automatically based on its contextual understanding and the user's prompts" (tools spec).

  • The client lists them with tools/list and runs one with tools/call.
  • Each tool has a name, a description and a JSON Schema for its inputs.
  • A tool can return text, images, audio, structured data, or links to resources.

Because the model decides when to call them, the spec asks for a person in the loop: "there SHOULD always be a human in the loop with the ability to deny tool invocations." Clients should show which tools are exposed, flag when one runs, and ask before sensitive operations.

Resources: data the app attaches as context

Resources "allow servers to share data that provides context to language models, such as files, database schemas, or application-specific information." Each one has a URI, like file:///project/src/main.rs, and they are "application-driven, with host applications determining how to incorporate context based on their needs" (resources spec).

  • The client lists them with resources/list and fetches one with resources/read.
  • Resource templates cover parameterized data, like file:///{path}.
  • Clients can subscribe to a resource and get a notification when it changes.

The spec lets apps choose how to surface them: a picker the user browses, search and filter, or automatic inclusion "based on heuristics or the AI model's selection." The protocol only defines reading a resource, not acting on it: a resource is there to bring content into the conversation.

How Claude Code uses each

In Claude Code, the two show up in different places:

  • Tools are offered to Claude, which calls them as it works. Your permission settings decide which ones run without asking.
  • Resources appear when you type @, alongside your files. You reference one as @server:protocol://resource/path, for example @github:issue://123, and Claude Code fetches it and attaches it to your message. Claude Code also gives Claude tools to list and read resources when a server supports them.
  • Prompts become commands: /mcp__servername__promptname.

Which is riskier?

Tools carry the action risk. A tool can write, delete, send or spend money, and the model decides when to call it. That's why approval prompts, read-only modes and tool annotations all focus on tools.

Resources carry the content risk. A resource can't take an action, but its text goes straight into the model's context. A README, an issue or a web page can contain instructions written to steer the model (prompt injection), and whatever tools are connected can then act on them. The spec puts the duty on servers: they "MUST validate all resource URIs" and "Access controls SHOULD be implemented for sensitive resources."

In practice:

  1. Keep approval on for tools that write, delete or reach outside services.
  2. Treat every resource as untrusted input, especially anything that comes from outside your team: public repos, tickets, scraped pages.
  3. Be most careful when one session mixes untrusted resources with powerful tools. That combination is where injected instructions turn into actions.

If you build an MCP server: resource or tool?

Expose it as a resource when it's data the user or app should choose to include: files, schemas, documentation, a specific record. It's read-only by design, the user stays in control of what goes in, and it doesn't add another action the model can take.

Expose it as a tool when the model needs to decide on its own to fetch or change something, or when the request needs parameters the model fills in: run a query, search, create an issue, send a message.

Some servers do both: a tool to search, which returns resource_link items the client can read or subscribe to. The spec allows this, and notes that resource links a tool returns aren't guaranteed to appear in resources/list.

Every tool you add also costs context, because its name, description and schema are loaded up front. See why MCP servers eat your context window.

Frequently asked questions

What is an MCP resource?

A piece of data a server shares as context, identified by a URI: a file, a database schema, a document. The client lists resources with resources/list and reads one with resources/read. The app or user decides when to include it.

What is an MCP tool?

A function the server exposes for the model to call, with a name, a description and an input schema. The model decides when to call it with tools/call. Tools can read or change things in outside systems.

Can an MCP resource change data?

Not by design. The protocol only defines listing, reading and subscribing to resources; changes go through tools. The content of a resource can still try to talk the model into calling a tool, so treat it as untrusted.

Do Claude Code and Cursor support MCP resources?

Claude Code does: type @ to see resources from connected servers, and reference them as @server:protocol://path. Support varies between clients, and the spec doesn't require any particular interface, so check your client's documentation.

Should I approve resources the way I approve tools?

Approval matters most for tools, because they act. For resources, the question is where the content comes from. Content from people outside your team can carry prompt injection, so limit which tools are connected in that session.

More: MCP security best practices · Is this MCP server safe to install? · MCP tool annotations explained