What is Resource?
A Resource is the MCP primitive for exposing read-only contextual data from a server to the host application. Conceptually it maps to any addressable piece of data your server owns — a file on disk, a database row, a live API response, a git commit, or a configuration blob. The host (not the client LLM) decides which resources to attach to a conversation, making resources application-controlled rather than model-initiated; this is the key distinction from tool results, which are produced on demand during inference. In the MCP message flow, a server advertises its resources via resources/list and clients fetch individual content via resources/read, receiving either text or blob payloads. The uri field is the stable identifier — servers must treat it as opaque from the client's perspective and ensure it remains dereferenceable across sessions. The mimeType hint lets hosts render or summarize content appropriately before injection. The optional size field enables a host to make prefetch decisions without fetching the full payload. The annotations field carries audience and priority metadata (introduced alongside the broader Annotations type) that allows servers to signal whether a resource is intended for the model, the user, or both, and how urgently it should be surfaced. title was added as a display-friendly label separate from name to decouple machine identifiers from human-readable presentation — name is used in tool/prompt references while title appears in UI.
When to use
For static or polled contextual data the LLM should be able to read.
When NOT to use
For dynamic actions — use Tools. For input templates — use Prompts.
Notes
URI scheme is not validated by spec
MCP does not mandate a specific URI scheme; file://, https://, and custom schemes like db:// or git:// are all valid. Servers must ensure URIs are globally unique within their namespace and remain stable across reconnects. Clients that cache resources by URI will break silently if a server reuses a URI for different content across sessions.
size is advisory, not enforced
The size field is an optional byte-count hint; the spec does not require it to be exact or even present. Hosts use it to decide whether to pre-fetch or lazy-load content. In production, mismatched size values (e.g., from compressed storage) can cause hosts to truncate or skip large resources unexpectedly — always provide an accurate value or omit the field entirely.
mimeType drives host-side summarization
When a host injects resource content into the context window it may summarize, truncate, or convert the payload based on mimeType. Binary mimes like application/octet-stream are often dropped or base64-encoded, consuming significant token budget. Prefer text/plain or a structured type like application/json where possible to maximize the chance the content is faithfully included.
name vs title naming contract
name is a stable machine identifier used in cross-references from prompts and tools — changing it is a breaking change for any client that references the resource by name. title is purely cosmetic and safe to update at any time. Omitting title causes most SDK-generated UIs to fall back to name, which is acceptable but often user-unfriendly for paths or slugs.
Resource templates extend this type
The spec also defines ResourceTemplate, which shares the same mimeType and annotations fields but replaces uri with a uriTemplate (RFC 6570). Servers that expose parameterized resources (e.g., file://{path} or db://tables/{table}/rows/{id}) should use ResourceTemplate in resources/list rather than enumerating every concrete Resource — this is a common performance pitfall when serving large filesystems or databases.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| uri | string | yes | Unique identifier for the resource (e.g., file:///path). |
| name | string | yes | Programmatic identifier. |
| title | string? | no | Display name. |
| description | string? | no | What this resource contains. |
| mimeType | string? | no | MIME type — text/plain, image/png, application/json. |
| size | number? | no | Size in bytes. |
| annotations | Annotations? | no | audience, priority, lastModified. |
Examples
A file resource
{
"uri": "file:///workspace/README.md",
"name": "readme",
"title": "Project README",
"mimeType": "text/markdown",
"size": 4096
}
Common mistakes
❌ Mutating data via Resources
✅ Resources are read-only — write paths belong in Tools.
❌ Using fragile URIs that change every connection
✅ URIs should be stable identifiers.