
This page is part of our MCP specification reference, a plain-English guide to the Model Context Protocol spec (version 2026-07-28), within The MCP Guide. Building a server? See MCP development.
An MCP resource is a piece of data a server shares as context for an AI model, such as a file, a database schema or a customer record. Each resource has a unique URI, like file:///project/src/main.rs. The client reads it with resources/read and decides how to use it.
Status in the 2026-07-28 spec: core. Resources are one of the three server features, with tools and prompts. A server opts in by declaring the resources capability.
The key difference from tools: resources are for reading context, and the host app decides when to use them. This page is based on the 2026-07-28 Resources page, checked on 28 October 2026.
Key Takeaways
- Resources are data identified by a URI that a server exposes as context, such as files, schemas or app records.
- Resources are "application-driven": the host app decides how to include them, unlike model-controlled tools.
- Clients list resources with
resources/list, read them withresources/read, and find parameterized ones withresources/templates/list. - In 2026-07-28, a missing resource returns error
-32602, not-32002, and an emptycontentsarray is not allowed for it. - List and read results now carry caching hints (
ttlMsandcacheScope), so clients can avoid re-fetching. - Change notifications moved to
subscriptions/listen; the oldresources/subscribecall is gone.
What a resource is
The spec says resources "allow servers to share data that provides context to language models, such as files, database schemas, or application-specific information." Each one is "uniquely identified by a URI."
A resource definition has these fields:
uri: the unique identifier.name: the resource name.title: an optional display name.description: optional text.mimeType: the optional content type, such astext/markdown.size: optional size in bytes.icons: optional images for the interface.
Contents are either text (a text field) or binary (a base64 blob field).
Why resources exist
Tools let a model act. Resources let an app give the model the right background. A coding assistant might attach a project's README. A support app might attach a customer's account record.
The spec calls resources application-driven. The host app decides how to use them. It might show a picker where users choose files, let users search and filter, or include context automatically based on heuristics or the model's choice. The spec does not require any specific interface.
If you are new to the three building blocks, read how MCP works and compare with MCP tools explained.
How it works
Listing resources
The client sends resources/list and gets back a page of resources, with caching hints:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"resultType": "complete",
"resources": [
{
"uri": "file:///project/src/main.rs",
"name": "main.rs",
"title": "Rust Software Application Main File",
"description": "Primary application entry point",
"mimeType": "text/x-rust"
}
],
"nextCursor": "next-page-cursor",
"ttlMs": 300000,
"cacheScope": "public"
}
}
The list supports pagination through cursor and nextCursor. The ttlMs field says how many milliseconds the client may treat the result as fresh. The cacheScope says whether shared caches may store it (public) or only the same authorization context (private), per the caching page.
Reading a resource
The client sends resources/read with a URI. The server returns a contents array, which may hold several items. For example, reading a directory resource could return several files. A server may also return an input_required result if it needs user input first, following the multi-round-trip request pattern.
Templates and subscriptions
Parameterized resources, like file:///{path}, are listed through resources/templates/list. See MCP resource templates. Clients that want to know when a resource changes use subscriptions/listen. See MCP resource subscriptions.
Annotations
Resources, templates and content blocks can carry three optional annotations:
audience:user,assistantor both.priority: 0.0 to 1.0, where 1 means effectively required.lastModified: an ISO 8601 timestamp.
Clients can use them to filter, prioritize or sort what goes into context.
URI schemes
The spec names a few standard schemes and allows custom ones that follow RFC 3986:
| Scheme | Use |
|---|---|
https:// | Only when the client can fetch the resource from the web directly, without the server |
file:// | Resources that behave like a filesystem, even if not a real disk |
git:// | Git version control integration |
| Custom | Any scheme that follows RFC 3986 |
The https:// rule surprises people. If the client would still need the server to fetch the content, the spec says the server SHOULD use another scheme or a custom one.
What changed across spec versions
| Version | Change |
|---|---|
| 2024-11-05 | Resources, templates, list-changed and resources/subscribe defined; not-found code -32002 (2024-11-05 Resources) |
| 2025-06-18 | title field added; tools can return resource links |
| 2025-11-25 | Icons added for resources and templates (changelog) |
| 2026-07-28 | Lists must not vary per connection; caching hints; input_required on read; subscriptions/listen replaces subscribe; not-found code becomes -32602 (changelog) |
The error change is easy to miss. In 2026-07-28, a missing resource MUST return -32602 (Invalid Params). Clients SHOULD still accept -32002 from older servers. And servers MUST NOT return an empty contents array for a resource that does not exist, because that is ambiguous.
Common mistakes
- Using resources for actions. Reading should not change anything. If it writes, sends or deletes, make it a tool.
- Skipping path checks. Servers MUST sanitize file paths to prevent directory traversal on
file://resources. A request for../../etc/passwdshould fail. - Returning an empty array for a missing resource. Return the
-32602error. - Using
https://for content only the server can reach. Use a custom scheme instead. - Assuming every client shows resources. Support varies by app. Our guide to AI apps that support MCP covers what each client offers.
The spec's security list also says servers must validate all resource URIs and should check permissions before operations. See the MCP security center.
Next step
Most real servers expose more than a fixed list of files. Read MCP resource templates next, or return to the MCP specification reference.
Frequently asked questions
What is the difference between MCP resources and tools?
Resources are data the host app reads as context, identified by URI. Tools are actions the model chooses to call, which may change things. The spec calls resources application-driven and tools model-controlled.
Can an MCP resource be binary, like an image or PDF?
Yes. Resource contents can be text or binary. Binary data goes in a base64-encoded blob field with a MIME type.
What error does MCP return for a resource that does not exist?
In the 2026-07-28 spec, the server must return JSON-RPC error -32602 (Invalid Params). Older versions used -32002, and clients should still accept it.
Do resources need a resources capability?
Yes. Servers that support resources must declare the resources capability. It can include listChanged and subscribe flags, or neither.
Can a tool return a resource?
Yes. A tool result can include a resource link or an embedded resource. The spec notes that resource links from tools are not guaranteed to appear in resources/list.











