Check the protocol contract
Connect with an MCP Apps-capable client and check these operations in order:
The tool and resource contract has the fields to inspect. If one operation fails, fix that boundary before debugging the iframe.
Render the View
Start an inspector connected to your MCP server:--server "python server.py". Select the UI tool and call it with representative arguments. In the rendered View, check that:
- The HTML loads and
app.connect()completes theui/initializehandshake. - The View receives its tool input and result, including an error result when the tool returns
isError: true. - Buttons that call the server use tools whose visibility includes
"app". - External scripts, images, and requests load under the resource’s declared CSP.
- The View remains usable in each host mode, theme, and display mode your app supports.
Automate the check with Playwright
Thesunpeak/test fixtures can test any MCP server, including one written outside sunpeak. Configure the server as shown in testing setup, then add a test for a real UI tool:
renderTool() calls the real server. Without input, the fixture may use a saved simulation, which is useful for repeatable UI states but does not verify the live handler. The fixture’s readResource() returns HTML text, so inspect the raw MCP resources/read response separately when you need to assert its MIME type or _meta.ui security fields.
Run npx sunpeak test --e2e to execute these tests in the configured host projects. Add a test for an app-only helper and one for a tool error if your View depends on those paths. For host behavior that a local runtime cannot reproduce, use live tests against the real host.
See MCP Apps lifecycle for the message sequence and E2E testing for more fixture options.