“ui.domain mismatch”
The view's ui.domain has Claude's form, but its hash is not the SHA-256 of the connector URL the user added, so Claude refuses it. The three common causes: (1) The server hashed a different spelling of the URL: with or without the /mcp path, or with a trailing slash. The hash covers the full URL as entered. To tell: The doctor fails at resource-domain-claude and names the spelling the value is the hash of, when it is one. (2) The server hashed the URL it sees behind a proxy or load balancer (an internal host or port) rather than the public one. To tell: The doctor's expected value for the public URL differs from the one served; the served value matches none of the public spellings. (3) Users add the connector at more than one URL (a custom domain and a platform domain), and the server serves one fixed value. To tell: Run the doctor against each URL users enter: it passes for one and fails for the other. One command shows which: npx --allow-git=root github:agentwares/mcp-apps-doctor https://your-server.example/mcp --host claude.
Check your server now
npx --allow-git=root github:agentwares/mcp-apps-doctor https://your-server.example/mcp --host claude
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
Claude (claude.ai and Claude Desktop), instead of rendering the view.
The three causes, and how to tell them apart
- Cause 1. The server hashed a different spelling of the URL: with or without the /mcp path, or with a trailing slash. The hash covers the full URL as entered.
The check flags it atresource-domain-claude. The doctor fails at resource-domain-claude and names the spelling the value is the hash of, when it is one. - Cause 2. The server hashed the URL it sees behind a proxy or load balancer (an internal host or port) rather than the public one.
The check flags it atresource-domain-claude. The doctor's expected value for the public URL differs from the one served; the served value matches none of the public spellings. - Cause 3. Users add the connector at more than one URL (a custom domain and a platform domain), and the server serves one fixed value.
The check flags it atresource-domain-claude. Run the doctor against each URL users enter: it passes for one and fails for the other.
Sources and public reports
- the first 32 hex characters of the SHA-256 of your server URL, followed by .claudemcpcontent.com [source: Claude, Set ui.domain for Claude, read 8 October 2026]
- the server hashed the URL with the /mcp path, the connector was added without it [observed in alpic-ai/skybridge#630, opened 30 March 2026]
Keep checking
Other messages
- “MCP App renders blank”
- “Resource not found: ui://”
- “Tool has no UI”
- “Invalid ui.domain format”
- “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