vercel/ai · error · Error
Unsupported MCP App resource content format: ${uri}
Error message
Unsupported MCP App resource content format: ${uri} What it means
Thrown by getMCPAppResourceFromReadResult when the content entry has the correct MCP App MIME type but contains neither a 'text' string nor a 'blob' base64 string, so no HTML can be extracted. The library requires renderable HTML payload from the resource.
Source
Thrown at packages/mcp/src/tool/mcp-apps.ts:257
if (content == null) {
throw new Error(`MCP App resource not found in read result: ${uri}`);
}
if (content.mimeType !== MCP_APP_MIME_TYPE) {
throw new Error(
`Unsupported MCP App resource MIME type: ${content.mimeType}`,
);
}
const html =
'text' in content && typeof content.text === 'string'
? content.text
: 'blob' in content && typeof content.blob === 'string'
? new TextDecoder().decode(convertBase64ToUint8Array(content.blob))
: undefined;
if (html == null) {
throw new Error(`Unsupported MCP App resource content format: ${uri}`);
}
const meta = getResourceUiMeta(content._meta);
return { uri, mimeType: MCP_APP_MIME_TYPE, html, meta };
}
/**
* Reads a `ui://` resource from an MCP server and normalizes it for rendering.
*/
export async function readMCPAppResource({
client,
uri,
options,
}: {
client: Pick<MCPClient, 'readResource'>;
uri: string;
options?: RequestOptions;View on GitHub (pinned to 69428b1f8b)
Solutions
- Fix the MCP server to include the HTML in content.text (or base64 in content.blob) for the ui:// resource.
- Log the full read result to inspect what the server actually returned.
- Update the MCP server implementation/SDK version so the resource body is serialized correctly.
- If the payload is large, ensure the transport (e.g. SSE/HTTP) is not truncating or dropping the content.
Example fix
// before (server response missing body)
{ uri: 'ui://widget/gauge', mimeType: 'text/html;profile=mcp-app' }
// after
{ uri: 'ui://widget/gauge', mimeType: 'text/html;profile=mcp-app', text: '<html>...</html>' } Defensive patterns
Strategy: validation
Validate before calling
function hasRenderableBody(c: { text?: unknown; blob?: unknown }) {
return typeof c.text === 'string' || typeof c.blob === 'string';
} Type guard
function hasHtmlPayload(c: unknown): c is { text: string } | { blob: string } {
return !!c && typeof c === 'object' && (('text' in c && typeof (c as any).text === 'string') || ('blob' in c && typeof (c as any).blob === 'string'));
} Try / catch
try {
const app = await readMCPAppResource({ client, uri });
} catch (e) {
if (e instanceof Error && e.message.startsWith('Unsupported MCP App resource content format')) {
// treat as empty/missing app, use placeholder UI
} else throw e;
} Prevention
- Log the raw readResource result when integrating a new server
- Add a server-side test asserting the ui:// resource includes text or blob
- Keep server SDK versions current so bodies serialize correctly
When it happens
Trigger: A read result content matches the requested uri and has mimeType MCP_APP_MIME_TYPE, but is missing both the text and blob fields (or they are of the wrong type), leaving html === undefined.
Common situations: A buggy or partially-implemented MCP server returns an empty resource entry; a proxy strips the text field; the server sends binary content with malformed base64 encoding fields omitted; serialization drops the body.
Related errors
- Unsupported MCP App resource MIME type: ${content.mimeType}
- Invalid MCP App resource URI: ${JSON.stringify(resourceUri)}
- MCP App resource not found in read result: ${uri}
- Unsupported MCP App resource URI: ${uri}
- ACP MCP server name "ai-sdk-harness-tools" is reserved for H
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/24d614f76137433e.
Report an issue: GitHub.