vercel/ai · error · Error
Invalid MCP App resource URI: ${JSON.stringify(resourceUri)}
Error message
Invalid MCP App resource URI: ${JSON.stringify(resourceUri)} What it means
Thrown by getMCPAppToolMeta when an MCP App tool declares a resourceUri (via ui metadata or the legacy _meta key) that is not a string or does not start with the required 'ui://' scheme. MCP Apps must point their UI resource at a ui:// URI, so the SDK validates the shape eagerly when reading tool metadata.
Source
Thrown at packages/mcp/src/tool/mcp-apps.ts:150
(v): v is MCPAppToolVisibility => v === 'model' || v === 'app',
)
: undefined;
}
/**
* Reads and validates MCP Apps metadata from a tool definition.
*/
export function getMCPAppToolMeta(
tool: MCPAppToolLike,
): MCPAppToolMeta | undefined {
const uiMeta = getToolUiMeta(tool._meta);
const resourceUri =
uiMeta?.resourceUri ?? tool._meta?.[MCP_APP_LEGACY_RESOURCE_URI_META_KEY];
const visibility = parseVisibility(uiMeta?.visibility);
if (resourceUri !== undefined) {
if (typeof resourceUri !== 'string' || !resourceUri.startsWith('ui://')) {
throw new Error(
`Invalid MCP App resource URI: ${JSON.stringify(resourceUri)}`,
);
}
} else if (uiMeta == null) {
return undefined;
}
return {
...uiMeta,
...(resourceUri != null ? { resourceUri } : {}),
...(visibility != null ? { visibility } : {}),
};
}
/**
* Returns the `ui://` app resource URI attached to a tool, if present.
*/
export function getMCPAppResourceUri(tool: MCPAppToolLike): string | undefined {View on GitHub (pinned to 69428b1f8b)
Solutions
- Change the tool's ui.resourceUri to a string beginning with 'ui://'.
- Serve the app HTML via the MCP server's resources/read (registered under the matching ui:// URI) rather than a plain HTTP URL.
- Remove resourceUri entirely if the tool has no MCP App UI, so metadata is treated as undefined.
- Update the MCP server to the current MCP Apps spec naming (ui metadata) and re-verify the emitted _meta.
Example fix
// before
{ _meta: { ui: { resourceUri: 'https://example.com/app.html' } } }
// after
{ _meta: { ui: { resourceUri: 'ui://my-server/app.html' } } } Defensive patterns
Strategy: validation
Validate before calling
function isValidAppResourceUri(uri) {
return typeof uri === 'string' && uri.startsWith('ui://');
}
const uiMeta = tool._meta?.ui;
const resourceUri = uiMeta?.resourceUri;
if (resourceUri !== undefined && !isValidAppResourceUri(resourceUri)) {
throw new Error(`Fix tool manifest: resourceUri must be a 'ui://' string, got ${JSON.stringify(resourceUri)}`);
} Type guard
function isValidAppResourceUri(uri: unknown): uri is string {
return typeof uri === 'string' && uri.startsWith('ui://');
} Try / catch
let meta;
try {
meta = getMCPAppToolMeta(tool);
} catch (e) {
if (e instanceof Error && e.message.startsWith('Invalid MCP App resource URI')) {
console.error('Tool manifest violates MCP Apps spec:', e.message);
meta = undefined; // treat as non-app tool or surface a config error
} else { throw e; }
} Prevention
- Always use 'ui://'-scheme resource URIs in MCP App tool metadata.
- Serve app HTML through MCP resources/read, not plain https:// links.
- Validate tool manifests with a schema check when building MCP servers.
- Migrate legacy _meta keys to the current ui metadata naming.
When it happens
Trigger: Registering/reading an MCP tool whose ui.resourceUri (or legacy _meta uiResourceUri) is a non-string value, an http(s):// URL, or a malformed URI without the ui:// prefix; servers built against older or hand-rolled MCP App conventions.
Common situations: MCP servers migrated from pre-standard drafts that used different resource URI schemes; hand-written tool manifests with copy-pasted https:// links to HTML files; JSON configs where resourceUri is accidentally an object (hence JSON.stringify in the message).
Related errors
- Unsupported MCP App resource URI: ${uri}
- 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/1585d23570a8d032.
Report an issue: GitHub.