What is EmbeddedResource?
EmbeddedResource is a content block that carries a resource's actual bytes inline within an MCP message rather than referring to the resource by URI. It wraps either a TextResourceContents (UTF-8 text with an optional mimeType) or a BlobResourceContents (base64-encoded binary with a required mimeType), and the discriminated union is resolved at runtime via the contents object's own structure. The mandatory type field is always the literal string "resource", which lets message parsers distinguish EmbeddedResource from its sibling PromptMessage content types without inspecting the nested payload. In the MCP message flow, EmbeddedResource appears most often inside tool call results and prompt message sequences where the server wants the LLM host to have the full resource bytes immediately available — no follow-up resources/read round-trip required. This is the key design trade-off: embedding trades network efficiency for latency and simplicity. A server that embeds a 200 KB PDF in every tool response will saturate the transport quickly, but a server that always returns links forces the host to issue a second request before the model can process the content. The optional annotations field mirrors the same Annotations object used across MCP primitives; it carries audience and priority hints that hosts can use to decide whether to surface the resource to the model at all. EmbeddedResource was present from the initial 2024-11-05 schema release and has not undergone breaking changes, though the annotations field was added in the 2025-03-26 revision alongside broader annotation support across the protocol.
When to use
Small resources that should always be included in the result.
When NOT to use
Large binary files — use ResourceLink and let the host fetch on demand.
Notes
Size limits are transport-dependent
MCP does not impose a protocol-level byte limit on EmbeddedResource payloads, but the underlying transport does. stdio transports buffer entire JSON lines in memory, so embedding large BlobResourceContents can exhaust process heap. HTTP/SSE transports have their own body-size limits. Establish a per-server convention — commonly 1 MB for blobs — and fall back to ResourceLink above that threshold.
Base64 overhead for binary content
BlobResourceContents stores binary data as a base64 string, which inflates the wire size by roughly 33% compared with raw bytes. This cost is unavoidable in JSON-framed transports. For images or PDFs that will be decoded client-side, factor in this overhead when setting your size threshold; a 750 KB file becomes approximately 1 MB on the wire.
Sibling type ResourceLink vs EmbeddedResource
ResourceLink and EmbeddedResource are the two content block types for resources in MCP. ResourceLink carries only a URI and metadata — the host must call resources/read to get bytes. EmbeddedResource carries the bytes directly. Choose EmbeddedResource when the bytes are cheap to compute or already in memory; choose ResourceLink when the resource is large, access is conditional, or you want the host to control fetch timing.
MIME type is required for blobs, optional for text
TextResourceContents allows an omitted mimeType, which defaults to text/plain in most SDK implementations. BlobResourceContents requires a non-empty mimeType because the host needs it to decode or render the binary payload. Omitting mimeType on a blob will cause schema validation errors in strict parsers and silent mishandling in lenient ones — always populate it.
Annotations are hints, not enforcement
The annotations field on EmbeddedResource carries audience (user, assistant) and priority (0.0–1.0) hints. Hosts are not required to act on them; they are advisory signals for context-window management and UI rendering. A priority of 0.0 signals that the content is background context the model does not need to reason about directly, which some hosts use to decide whether to omit the resource from the prompt entirely.
Fields
| Field | Type | Required | Purpose |
|---|---|---|---|
| type | 'resource' | yes | Discriminator for the content block. |
| resource | TextResourceContents | BlobResourceContents | yes | Inline contents. |
| annotations | Annotations? | no | Optional annotations. |
Examples
Embedded markdown
{
"type": "resource",
"resource": {
"uri": "memo://daily/notes",
"mimeType": "text/markdown",
"text": "# Daily notes\n- bullet 1"
}
}
Common mistakes
❌ Embedding huge files
✅ Use ResourceLink for anything large enough to fit in main memory but not the context window.