vercel/ai · error · Error
Unsupported MCP App resource URI: ${uri}
Error message
Unsupported MCP App resource URI: ${uri} What it means
Thrown by readMCPAppResource when the given URI does not start with the 'ui://' scheme. Only ui:// URIs are treated as MCP App resources; anything else is rejected before a resources/read request is made.
Source
Thrown at packages/mcp/src/tool/mcp-apps.ts:278
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;
}): Promise<MCPAppResource> {
if (!uri.startsWith('ui://')) {
throw new Error(`Unsupported MCP App resource URI: ${uri}`);
}
return getMCPAppResourceFromReadResult({
uri,
resource: await client.readResource({ uri, options }),
});
}
View on GitHub (pinned to 69428b1f8b)
Solutions
- Only pass URIs extracted via getMCPAppResourceUris or from tool _meta ui resourceUri fields, which are ui:// by spec.
- Check the URI string for typos in the scheme (must be exactly 'ui://').
- If you need a non-app resource, use client.readResource directly instead of readMCPAppResource.
Example fix
// before
await readMCPAppResource({ client, uri: 'https://example.com/widget.html' });
// after
await readMCPAppResource({ client, uri: 'ui://widget/gauge.html' }); Defensive patterns
Strategy: validation
Validate before calling
if (!uri.startsWith('ui://')) {
throw new Error(`Expected ui:// MCP App resource URI, got: ${uri}`);
} Type guard
function isMCPAppUri(uri: string): boolean {
return uri.startsWith('ui://');
} Try / catch
try {
const app = await readMCPAppResource({ client, uri });
} catch (e) {
if (e instanceof Error && e.message.startsWith('Unsupported MCP App resource URI')) {
// fall back to client.readResource for non-app resources
} else throw e;
} Prevention
- Derive app URIs from getMCPAppResourceUris instead of hand-writing them
- Check the scheme with a helper before calling readMCPAppResource
- Don't confuse standard MCP resources with MCP App (ui://) resources
When it happens
Trigger: Passing a file://, https://, or other non-ui:// URI (e.g. a tool output resource URI or a typo like 'ui:/') to readMCPAppResource or resource().
Common situations: Developer accidentally reads a regular MCP resource as an app; a tool annotation returns an ordinary resource URI; typo in the scheme; mixing up MCP Apps resources with standard MCP resources.
Related errors
- Invalid MCP App resource URI: ${JSON.stringify(resourceUri)}
- MCP App resource not found in read result: ${uri}
- ACP MCP server ${JSON.stringify(name)} must be configured wi
- Cline MCP server ${JSON.stringify(input.serverName)} must de
- Pi MCP server ${JSON.stringify(name)} must be configured wit
AI-assisted analysis of vercel/ai@69428b1f8b (2026-08-30).
Data as JSON: /api/errors/d1b101be0e058e14.
Report an issue: GitHub.