What is ResourceLink?
A ResourceLink (type: "resource_link") is a lightweight content block used to reference a server-managed resource by URI rather than embedding its raw bytes inline. Conceptually it acts as a pointer — the host receives the URI and can decide independently whether to fetch and surface the resource, cache it, or simply present a navigable reference to the end user. This separation of reference from retrieval is the core design intent: it keeps tool results and prompt messages lean while still giving the host enough information (name, optional title, optional mimeType) to render a meaningful affordance. Within the MCP message flow, ResourceLinks appear as items inside a content array — typically in tool result payloads or as parts of multi-part prompt messages returned by the server. They sit alongside sibling content types like TextContent, ImageContent, and EmbeddedResource. The difference from EmbeddedResource is intentional: EmbeddedResource carries the resource data inline, while ResourceLink delegates retrieval entirely to the host. Use ResourceLink when the data is large, already accessible via a known URI, or when you want the host to control access policy. The required fields are type, uri, and name; title and mimeType are optional but strongly encouraged in practice. Providing mimeType lets the host skip a separate content-negotiation round-trip, and a human-readable title improves display quality when the name alone is a machine-generated identifier. The interface was introduced alongside the unified content-block model in MCP and has remained stable; no breaking field changes have occurred across published spec revisions.
When to use
In tool/prompt results when you want to reference a resource by URI.
When NOT to use
When the resource is small and the host should always read it — embed it instead.
Notes
ResourceLink vs EmbeddedResource trade-off
ResourceLink defers data retrieval to the host; EmbeddedResource carries the bytes (as text or base64) inline inside the message. Prefer ResourceLink for large files, binary blobs, or anything the host already has access to — it avoids inflating message payloads and lets the host apply its own caching or access-control logic. Use EmbeddedResource only when you need the model to see the actual content in the same turn.
URI must match a declared resource
The spec does not require the URI to resolve to a resource that the server has explicitly listed in its resources/list response, but in practice most SDK implementations and validators warn or error when a ResourceLink URI has no corresponding registered resource. To avoid silent failures in production, ensure every URI you emit in a ResourceLink is either listed statically or covered by a resource template that the server has advertised. Mismatches surface at host render time rather than at schema validation, making them easy to miss in testing.
mimeType drives host rendering decisions
Omitting mimeType is valid per the schema but forces the host to either sniff the content type or render a generic link. For file-backed resources this is rarely a problem, but for dynamically generated resources (JSON reports, rendered PDFs) an absent mimeType often results in degraded UI in Claude Desktop and similar hosts. Treat mimeType as a de-facto required field even though the spec marks it optional.
name field is not a unique identifier
The name field is human-readable display text, not a stable identifier — two ResourceLinks can carry the same name pointing to different URIs. Do not use name for programmatic lookups or deduplication in client-side code. If you need a stable key, derive it from the URI. This is a common pitfall when building aggregation layers that group tool results by name.
Security: untrusted URIs in tool results
When a tool result contains a ResourceLink, the URI originates from server-side logic that may have processed untrusted input (user queries, external API responses). Hosts should treat ResourceLink URIs as untrusted and apply the same SSRF and redirect-following policies they would for any externally supplied URL. Servers should validate and sanitize URIs before placing them in ResourceLinks — never reflect a raw user-supplied string directly into the uri field.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| type | 'resource_link' | yes | Discriminator for the content block. |
| uri | string | yes | URI of the referenced resource. |
| name | string | yes | Programmatic identifier. |
| title | string? | no | Display name. |
| mimeType | string? | no | MIME type of the linked resource. |
Examples
Tool result with a ResourceLink
{
"type": "resource_link",
"uri": "file:///workspace/output.json",
"name": "result",
"mimeType": "application/json"
}
Common mistakes
❌ Forgetting 'type': 'resource_link'
✅ Without the discriminator the client cannot route the block.