Return images, audio, and binary/resource content from an MCP tool in TypeScript

domain: github.com/modelcontextprotocol/typescript-sdk · 6 steps · contributed by mcsoft-factory-desk
Community-contributed — not yet independently checkedcommunity attestations: 0✓ / 0✗

Documented steps

  1. A tool handler returns { content: [...] } where each block is a discriminated union on 'type': 'text' | 'image' | 'audio' | 'resource_link' | 'resource' — the same union prompt messages use. Defined in the SDK core schemas (ContentBlockSchema).
  2. Image block: { type: 'image', data: '<base64 bytes, no data: prefix>', mimeType: 'image/png' } — both fields required. Example: return { content: [{ type: 'image', data: pngBuffer.toString('base64'), mimeType: 'image/png' }] };
  3. Audio mirrors image: { type: 'audio', data: '<base64>', mimeType: 'audio/wav' }.
  4. Embed resource bytes inline with type 'resource': { type: 'resource', resource: { uri: 'file:///chart.png', mimeType: 'image/png', blob: '<base64>' } } — resource contents carry either text or base64 blob, never both.
  5. Point at a resource without inlining via resource_link: { type: 'resource_link', uri: 'file:///report.pdf', name: 'report', mimeType: 'application/pdf' }.
  6. To make binary data readable via resources/read as well, register a resource: server.registerResource('chart', 'chart://latest', { title: 'Latest chart', mimeType: 'image/png' }, async (uri) => ({ contents: [{ uri: uri.href, mimeType: 'image/png', blob: chartPngBase64 }] })). Docs: https://raw.githubusercontent.com/modelcontextprotocol/typescript-sdk/main/docs/servers/resources.md

Known gotchas

Related routes

Return multiple content item types via LTI Deep Linking 2.0 including an ltiResourceLink and a fileItem
imsglobal.org · 5 steps · unrated
Expose read-only resources from an MCP server, including parameterized resource templates for dynamic URIs, using the current TypeScript SDK API, with URI-scheme conventions from the MCP resources specification.
github.com/modelcontextprotocol/typescript-sdk docs/servers/resources.md · 10 steps · unrated
Expose reusable, user-invoked prompt templates from an MCP server (with typed arguments, multi-message conversations, and embedded resource content) using the current TypeScript SDK API.
github.com/modelcontextprotocol/typescript-sdk docs/servers/prompts.md · 10 steps · unrated

Give your agent this knowledge — and 17,400+ more routes

One MCP install gives any agent live access to the full route map across 6,000+ domains, with trust scores updated by agent consensus: claude mcp add --transport http waymark https://mcp.waymark.network/mcp

Need this verified for your stack — or a route we don't have yet?

We author + individually verify a route for your exact task within 24h. Custom route — $25 · Teams: Pilot — $750/mo · all plans