“Resource not found: ui://”
A tool links a view by _meta.ui.resourceUri, the host asked for exactly that URI with resources/read, and the server has no resource registered under it. The three common causes: (1) The URI in the tool and the URI the resource is registered at differ: a typo, a version suffix (ui://board/v2.html), a trailing slash, or a scheme other than ui://. To tell: The doctor fails at resource-read and names the URI the tool links; compare it with the registered one character by character. (2) The resource is registered only for some sessions: behind a capability check the host did not pass, or on a per-request server that registers tools but not resources. To tell: The doctor (which declares MCP Apps support) reads it, but the failing host does not; or it fails only after the first request in a stateless deploy. (3) A deploy renamed the view while a host still holds the old tool definition: ChatGPT keeps a published tool's previous definition until the update passes review, and may cache resource contents for up to an hour. To tell: The doctor passes against the new deploy; the failing URI is the old one. OpenAI asks you to keep each published UI resource URI working. One command shows which: npx --allow-git=root github:agentwares/mcp-apps-doctor https://your-server.example/mcp.
Check your server now
npx --allow-git=root github:agentwares/mcp-apps-doctor https://your-server.example/mcp
Discovery only: no credential, no tool called. It prints the first broken step, whose it is, and the fix with its source, and shows the view in a sandboxed preview.
Who prints it
The server's MCP SDK, in its answer to the host's resources/read (`Resource not found: ui://…` in the TypeScript SDK, `Resource ui://… not found` in its 1.x line), shown in a host's logs or MCP Inspector.
The three causes, and how to tell them apart
- Cause 1. The URI in the tool and the URI the resource is registered at differ: a typo, a version suffix (ui://board/v2.html), a trailing slash, or a scheme other than ui://.
The check flags it atresource-read. The doctor fails at resource-read and names the URI the tool links; compare it with the registered one character by character. - Cause 2. The resource is registered only for some sessions: behind a capability check the host did not pass, or on a per-request server that registers tools but not resources.
The check cannot see this one from outside: it happens inside the host or the portal. The doctor (which declares MCP Apps support) reads it, but the failing host does not; or it fails only after the first request in a stateless deploy. - Cause 3. A deploy renamed the view while a host still holds the old tool definition: ChatGPT keeps a published tool's previous definition until the update passes review, and may cache resource contents for up to an hour.
The check cannot see this one from outside: it happens inside the host or the portal. The doctor passes against the new deploy; the failing URI is the old one. OpenAI asks you to keep each published UI resource URI working.
Sources and public reports
- "Resource MUST exist on the server"; "Host MUST use resources/read to fetch the referenced resource URI" [source: MCP Apps spec 2026-01-26, Resource Discovery, read 8 October 2026]
- keep existing input schemas and each published UI resource URI working while an update is held [source: OpenAI remote MCP server review requirements, read 8 October 2026]
Keep checking
Other messages
- “MCP App renders blank”
- “Tool has no UI”
- “Invalid ui.domain format”
- “ui.domain mismatch”
- “Refused to load the script”
- “annotations_required”
- “domain_verification_required”
- “frame_domain_explanation_required”
- “screenshots_not_allowed”
- “Failed to fetch template”
Written 8 October 2026 from the sources above. The MCP Apps check · MCP Liveness · Terms · Privacy