A visual canvas for coding agents: your agent shows interactive HTML artifacts in your browser, and your clicks flow back into the conversation. MCP server.
Six tools with clear verb-noun naming and well-structured schemas. Descriptions are detailed (100-300 chars) and explain WHAT, WHEN, and consequences. All tools have complete input schemas with typed parameters and descriptions. However, output schemas are not explicitly documented in the visible code, and error handling guidance is minimal. Tool composition is strong, each tool has a single responsibility and chains naturally (create_artifact → await_interaction → get_interactions). No security issues detected (no credentials in params). Naming is consistent and unambiguous.
Wait for the user to interact with an artifact (or for an external webhook POST). Returns the oldest matching unconsumed interaction immediately if one is queued; otherwise blocks up to timeout_seconds. Pass artifact_id to only accept interactions from that artifact (recommended after showing choices, so stale clicks elsewhere are not misread as the answer). On timeout it returns status=no_response — call it again to keep waiting; the user may need more time. If you have other work to do while waiting, use the background GET /api/wait watcher from the server instructions instead of this tool.
Show a new HTML artifact on the visual canvas in the user's browser. Provide a complete, self-contained HTML document (inline CSS/JS; the iframe is sandboxed, so no external network access or storage). A `claude.send(payload)` helper is auto-injected: call it from buttons/forms so the user's interaction is sent back. After creating an artifact that expects a response, call await_interaction with its artifact_id. Opens the browser automatically if no canvas tab is connected yet. Returns the artifact id and URL.
Drain all queued interactions without blocking. Use to check whether the user clicked something while you were doing other work.
List artifacts currently on the canvas (id, title, timestamps).
Output schemas not documented. Tool descriptions explain what is returned (e.g., 'Returns the artifact id and URL'), but formal output schema definitions are not visible in the source code. LLMs cannot reliably extract fields from undocumented responses.
Error handling lacks recovery guidance. Descriptions mention timeout behavior (await_interaction: 'returns status=no_response'), but no guidance on what the LLM should do next (retry? ask user? call alternative tool?). No error classification (retryable vs. fatal).
get_interactions has minimal description (75 chars). Lacks context on when to use it vs. await_interaction, and does not explain the interaction queue structure or field names.
| Scored | Grade | Overall | Spec posture | Rubric |
|---|---|---|---|---|
| 2026-09-23 | B | 71 | 2026-07-28+ | v2 |
Remove an artifact from the canvas.
Replace the HTML (and optionally the title) of an existing artifact. Connected canvas tabs reload it live. Use this to iterate on an artifact after user feedback instead of creating a new one.
list_artifacts description is generic (70 chars). Does not explain when to call it (e.g., 'Call before creating a new artifact to check for duplicates') or what the returned timestamps represent.
No tool annotations (readOnlyHint, destructiveHint, idempotentHint). Risk classification is inferred from tool names (remove_artifact is destructive) but not formally declared in the schema.