Debugging a black box: 36 renders against Claude, and the part where my own data was wrong An engineer built a probe server and ran 36 renders against claude.ai web to debug why MCP App widgets silently fail to render. The experiments showed that omitting the `_meta.ui.domain` field does not prevent rendering, but a wrong value is fatal, and that a static HTML marker is the key to distinguishing between a never-created iframe and a failed script. The findings invert common advice and highlight the importance of precise endpoint hashing. If you've built an MCP App — the HTML widget an MCP server hands a host to render inline — you may have hit this: the tool call succeeds, structuredContent comes back fine, the model announces that a widget rendered, and the user sees nothing. No error. No console output. Just a gap in the conversation. There's a long issue https://github.com/modelcontextprotocol/ext-apps/issues/671 full of people with this exact symptom, all of them me included posting variations of "my server is spec-correct and nothing renders." That's a hard thing to act on. So I built a probe server designed to answer one question at a time and ran it 36 times. This post is mostly about method — how you experiment on a host whose source you can't read and whose renderer you can't attach a debugger to. The MCP specifics are the worked example. The most useful part is at the end, where my measurements lied to me twice. Everything behavioural here was measured on 31 July 2026 against claude.ai web. Host behaviour changes; treat the numbers as a snapshot, not a spec. The most-upvoted lead in that thread says claude.ai silently refuses to place the iframe unless your resource declares meta.ui.domain , computed as sha256