mcp-screen
mcp-screen is an MCP server that gives terminal coding agents a local interactive canvas to display visual widgets, read human selections and annotations, ask visual questions, and post standup reports.
place_widget: display markdown, text, tables, bar/line charts, metrics, key-value, status lists, and live architecture maps (livemap) with optional size, stable ID, and live source (command/URL/MCP) with refresh interval.update_widget: modify an existing widget's data (shallow merge by default), title, or size.read_widget: read a widget's data plus the human's selection (clicked table row/chart bar), annotations, and livemap unmapped files.read_canvas: list every widget with its ID, kind, title, live status, and current selection.remove_widget: delete one widget and stop its live refresh.clear_canvas: remove all widgets, with optional undo.ask_user: show 2–8 clickable choice cards and block until the human answers or times out, returning their choice.post_report: post a standup card with summary, test results, changed files, branch/worktree, and risks.Create live, self-refreshing widgets from commands, URLs, or MCP tools after human approval, running server-side without an LLM.
Supports Amp as a terminal agent client, registered via amp mcp add screen -- npx mcp-screen or the amp.mcpServers entry in ~/.config/amp/settings.json, so the agent's tool calls can place widgets, ask visual questions and post reports to the shared canvas.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mcp-screenchart last quarter's revenue, then ask me which region to focus on"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
Your terminal agent can finally show you things, and you can point back.
An infinite canvas next to your terminal. Your agent puts charts, diffs, flows, logs, plans and maps on it. You circle the bar that looks wrong and type "why?", and the agent reads exactly what you pointed at. Local, one command, no API keys.
claude mcp add screen -- npx mcp-screenThe agent in this clip is scripted (labelled on screen): no model is running. Everything else is real. Each widget comes from a real MCP tool call to a real mcp-screen process, the circle is drawn with real mouse input, and the caption quotes what read_canvas actually returned (scripts/record-hero.mjs, also as hero.mp4). The older demo of ask_user and the agent theatre is demo.gif.
Why · Features · Install · Tools · Security · Contributing
Why
Claude Code, Codex, opencode, Amp, Cursor CLI and Gemini CLI live in a terminal, and a terminal can't show a chart, a table, or the UIs that MCP servers now ship as MCP Apps. Those UIs reach a terminal agent as a wall of JSON, and when the agent needs a decision you get a numbered list to type back into.
mcp-screen opens a browser tab next to your terminal and gives the agent somewhere to put things, and gives you something to click. It runs entirely on your machine (127.0.0.1, token-protected, nothing uploaded).
First time? Run npx mcp-screen serve, then click Try a sample canvas to play with it before wiring up an agent. Press ? for shortcuts. It stays smooth with 100+ widgets (off-screen cards are culled; measured budgets in QA.md).
Related MCP server: relay-inspect
Features
One canvas, 17 widget kinds. The yellow circle ("why?") has the agent's reply threaded under it; the sticky note on the diff is still waiting. Circled data points stay attached when you scroll the card. Screenshot from scripts/e2e.mjs.
Canvas
place_widget charts, tables, metrics, markdown and status lists. Clicks flow back: the agent can read_widget and see the bar or row you picked.
Visual questions
ask_user puts choice cards on screen and blocks until you click one. The agent gets your choice back.
Agent theatre As agents read, edit and create files, their orbs glide across a live architecture map, files fly in and modules glow.
Standup board
Claude Code Stop/SubagentStop hooks turn each finished run into a card: files changed, tests, summary, risks.
MCP Apps for terminal agents
mcp-screen wrap -- <server> renders every ui:// result in a null-origin sandbox.
Live widgets
A widget can carry a command/URL/tool source that refreshes with no LLM in the loop, after you approve it.
Plus Share (PNG/HTML of the whole canvas, filename includes the project; Copy link opens that named canvas on localhost; Notifications can mute a canvas or set quiet hours), named canvases (git root by default, header switcher), and Clear (confirm + undo). Circle a bar or long-press / Alt+click a row to leave a note; the agent answers in a thread (reply_annotation). With install-hooks, every prompt injects “N notes waiting on the canvas” when you left questions unanswered.
Install
The canvas opens at http://127.0.0.1:4747. Several agent sessions share one canvas: the first one starts it and the others attach.
claude mcp add screen -- npx mcp-screen
npx mcp-screen install-hooks --write # optional: standup, theatre, and “notes waiting” on each promptcodex mcp add screen -- npx mcp-screen, or ~/.codex/config.toml:
[mcp_servers.screen]
command = "npx"
args = ["mcp-screen"]opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": { "screen": { "type": "local", "command": ["npx", "mcp-screen"] } }
}amp mcp add screen -- npx mcp-screen, or ~/.config/amp/settings.json:
{ "amp.mcpServers": { "screen": { "command": "npx", "args": ["mcp-screen"] } } }~/.cursor/mcp.json, or .cursor/mcp.json in a project:
{ "mcpServers": { "screen": { "type": "stdio", "command": "npx", "args": ["mcp-screen"] } } }Check it with cursor-agent mcp list. A project-level server may show as needing approval; run cursor-agent mcp enable screen.
gemini mcp add -s user screen npx mcp-screen # writes mcpServers to ~/.gemini/settings.jsonGemini CLI disables MCP servers in folders you haven't trusted, so trust the project folder when it asks. gemini mcp list should show screen as Connected.
How these were checked (Oct 2026): opencode ran end to end with a free model. For Amp, Cursor CLI and Gemini CLI, the configs above were written (via amp mcp add and gemini mcp add for those two); Cursor (cursor-agent mcp list-tools screen) and Gemini (gemini mcp list → Connected) started the server and saw its tools. Prompting a model through Claude Code, Codex, Amp, Cursor and Gemini needs an account login, which we didn't do here.
Tools
Tool | What it does |
| Put a widget on the canvas (kinds below). Optional |
| Change a widget; shallow-merges |
| Read a widget, including your |
| List every widget (with |
| List named canvases (one per project) and switch the browser to one. Default name = git root folder, or |
| Answer (or follow up on) a human's note/circle. The reply appears as a thread bubble next to their mark. |
| One-click: answer the oldest unanswered note (optional |
With npx mcp-screen install-hooks --write, Claude Code also gets a UserPromptSubmit / SessionStart hook: when notes are waiting, each prompt injects them as additionalContext so the agent can call reply_annotation without being asked again.
| remove_widget | Remove one widget. |
| clear_canvas | Remove everything (undo: true brings it back). |
| ask_user | Show 2–8 choice cards and wait for your click; returns the choice, or answered: false with a reason. |
| ask_form | Show a small form (text, textarea, number, slider, select, checkbox) and wait for Submit; values are validated before the agent gets them. |
| tidy_canvas | Re-pack all widgets into a neat grid (same as the Tidy up button). |
| post_report | Add a card to the standup board. |
kind | data |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| created by |
The canvas and your annotations
The canvas is infinite. Pan by dragging the background or scrolling, zoom with Ctrl/⌘+scroll or +/−, F fits everything, and Tidy up re-packs the grid. Drag a card by its header to move it; positions are kept by the hub and show up in read_canvas. The minimap (bottom right) jumps anywhere.
The left toolbar lets you talk back with ink: arrow (A), circle (O), highlighter (H) and sticky note (N), in five colours. Each mark is attached to the widget it lands on, plus the data points under it (bars, rows, log lines, diagram nodes, map markers, diff lines…), so the agent sees for example {kind:"circle", text:"why?", target:{widgetId:"ci-chart", dataPoints:[{label:"10/09", value:9}]}}. Select a mark and press Delete to remove it. It's deliberately not a whiteboard: marks exist to point the agent at things.
ask_user
ask_user { "question": "Which pricing layout should I build?",
"choices": [ { "id": "tiers", "label": "Three tiers", "description": "Good / better / best", "preview": "- Free · Pro · Team" },
{ "id": "slider", "label": "Usage slider" } ],
"timeoutSeconds": 180 }
// → { "answered": true, "choice": { "id": "tiers", "label": "Three tiers" }, "widgetId": "question-…" }2 to 8 choices, each with an optional description and markdown preview. The call blocks (sending MCP progress notifications every 10 s) until you click, the timeout passes (default 3 min, max 15), the card is removed, or the agent cancels the call. It then returns answered: false with the reason.
Agent theatre (livemap)
Ask: "draw a livemap of this repo with place_widget, one box per module, with globs". Once the hooks are installed, every Read, Write and Edit plays out live: the agent's orb moves to the module, the file chip flies in and lands with a ripple, the box glows (blue for reads, warm for edits, a NEW badge for created files), and a caption says who is doing what. Theatre mode hides the side panel for a full-screen view. If you installed hooks before this version, re-run install-hooks --write so the PostToolUse matcher includes Read. read_widget on the map returns unmappedFiles, the edited files no box covers, so the agent knows when to redraw.
MCP Apps (wrap)
claude mcp add flaky -- npx mcp-screen wrap -- node examples/demo-app-server.mjsThe agent sees the wrapped server's tools unchanged, plus the screen tools. When a tool declares _meta.ui.resourceUri, mcp-screen fetches the ui:// resource and renders it on the canvas. The bridge handles ui/initialize, tool-input and tool-result notifications, tools/call and resources/read proxied back to the server, ui/open-link, ui/message and ui/update-model-context. Whatever the app reports becomes the widget's selection, so the agent can read it.
Live widgets
place_widget { "kind": "status-list", "title": "Pipelines", "data": { "items": [] },
"source": { "type": "command", "argv": ["gh", "run", "list", "--json", "..."], "parse": "json" },
"intervalMs": 30000 }The widget appears with an Approve button that shows the exact command. Nothing runs until you click it. Approved sources are saved to ~/.mcp-screen/allowlist.json. Commands run without a shell, with a timeout and an output cap. Stop revokes the approval. See SECURITY.md.
Standup hooks
npx mcp-screen install-hooks --write # merges Stop / SubagentStop / PostToolUse hooks into ./.claude/settings.json
# (--local points them at a local checkout instead of npx)When an agent or subagent stops, the hook reads git diff --numstat (plus untracked files) in its worktree. The summary and risks come from Claude Code's last_assistant_message. Subagent cards are named by agent_type, and the internal agents Claude Code runs (with an empty agent_type) are skipped. The hook also reads the transcript for the last test command and its result (vitest, jest, pytest, go and cargo output are parsed), falling back to the transcript for the summary if needed. These become a card. Agents can also call post_report themselves.
CLI
mcp-screen stdio MCP server + canvas
mcp-screen wrap -- <cmd...> proxy an MCP server and render its MCP Apps
mcp-screen serve canvas only
mcp-screen hook hook entry point (reads the hook JSON on stdin)
mcp-screen install-hooks [--write]
--port <n> (default 4747) --no-openDevelop
npm install
npm run build
npm test # vitest unit tests, one file per part
npm run screenshots # end-to-end: real stdio MCP client, hooks, Playwright screenshots + GIF
npm run demo # records the ask_user + theatre demo: screenshots/demo.gif + demo.mp4
node scripts/record-hero.mjs # records the README hero: screenshots/hero.gif + hero.mp4 + hero.png
npm run ux # first-timer checks at 4 viewport sizes (screenshots/ux/)
npm run soak # 25 clear/undo/re-place cycles through the UI; DOM + heap must stay flat
npm run perf # performance budgets with 120 widgets (see QA.md)
npm run interop # renders the official ext-apps basic-server-vanillajs example through wrapThe design reuses pieces of opencanvas: the fan-out event bus, the widget-registry idea (kind → schema → renderer) and the null-origin plugin sandbox. It leaves out tldraw for a lighter grid canvas and a zero-build browser client.
See CONTRIBUTING.md. The design reuses pieces of opencanvas: the fan-out event bus, the widget-registry idea (kind → schema → renderer) and the null-origin plugin sandbox. It leaves out tldraw for a lighter grid canvas and a zero-build browser client.
The UI uses the Inter variable font (SIL OFL 1.1, public/fonts/LICENSE-Inter.txt), bundled locally so nothing loads from the network.
Status
v0.1, early. Named canvases live under ~/.mcp-screen/canvases/<id>.json (legacy canvas.json is migrated) and come back after a restart (MCP_SCREEN_NO_PERSIST=1 turns that off). Known gaps: diagrams cover Mermaid flowcharts only; maps are an offline world outline (no tiles, no zoom inside the map); PNG export of an embedded MCP App shows a placeholder, because the sandboxed frame can't be captured; MCP-tool live sources and app tools/call only work in the session that runs wrap and owns the canvas; no single-binary build yet.
Security
mcp-screen binds to 127.0.0.1, needs a per-run token, sandboxes MCP Apps in a null origin, and never runs a live source until you approve it. Details and known limits: SECURITY.md.
If mcp-screen helps your agent show its work, give it a star so other people can find it.
MIT © Krunal Ashar
Available Tools
8 toolsask_userA
Ask the human a visual question: places clickable choice cards on the canvas and BLOCKS until they click one (or the timeout passes). Use it for decisions that are easier to make by looking: layouts, copy options, which bug to fix first. Returns {answered, choice:{id,label}} or {answered:false, reason}.
| Name | Required | Description | Default |
|---|---|---|---|
| detail | No | Optional context shown under the question. | |
| choices | Yes | ||
| question | Yes | ||
| timeoutSeconds | No | How long to wait, default 180, max 900. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well on the most non-obvious trait: it BLOCKS until a click or timeout, and it discloses the return shape including the {answered:false, reason} unanswerable case. It omits failure/error semantics and any timeout-visibility caveats, but the blocking disclosure is the crucial one and it is front-loaded.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three dense sentences with zero waste; the blocking behavior and return format are front-loaded where an agent needs them before committing to a call. No filler or restatement of the name.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a blocking interactive tool with no annotations and no output schema, the description supplies the essentials: what happens on the canvas, that the call blocks, and the exact return shape. It could say more about timeout expiry consequences, but nothing critical for correct invocation is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 50% (question and the choices container lack descriptions). The description adds conceptual meaning (cards are clickable, choices yield {id,label}) but does not document the choices min/max constraints, the id/label contract, or the timeout default beyond what the schema already states. Baseline 3 is appropriate at partial coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Ask the human a visual question') and describes the mechanism (clickable choice cards on the canvas). It is clearly distinguishable from canvas-manipulation siblings like place_widget or read_canvas, since it is a blocking human-in-the-loop prompt rather than a widget operation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly gives when-to-use context: 'decisions that are easier to make by looking: layouts, copy options, which bug to fix first.' This is clear situational guidance, but it does not name alternatives or state when NOT to use it (e.g., when a plain text question would suffice).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
clear_canvasA
Remove every widget from the canvas (standup cards stay). The human can undo it from the canvas, or you can call clear_canvas with undo:true right after.
| Name | Required | Description | Default |
|---|---|---|---|
| undo | No | Restore the widgets removed by the last clear. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden and does well: it discloses destruction scope (all widgets), what is preserved (standup cards), and reversibility via two distinct undo routes. It omits permission/auth requirements and any effect on other collaborators, leaving modest gaps for a destructive operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences, zero waste, with the destructive scope and its exception front-loaded before the recovery guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, no-output-schema tool this is nearly complete: it covers scope, exception, and reversibility. It does not mention what the call returns (e.g., count of removed widgets) or failure modes, which are the only remaining gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3, but the description adds real value beyond the schema: it clarifies that undo should be invoked 'right after' the clear, a temporal coupling the schema's 'last clear' wording only implies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Remove every widget from the canvas') plus an explicit scope exception ('standup cards stay'). This is distinguishable from the sibling remove_widget, which acts on a single widget, without opening either schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The bulk-clear use case is clear, and the description routes the agent to the recovery path (human undo or re-invoking with undo:true). It does not explicitly say when to prefer the sibling remove_widget for a single widget, so it stops short of full when-not guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
place_widgetA
Show something to the human on their mcp-screen canvas (a browser tab next to the terminal). Returns the widget id. Widget kinds and their data:
markdown {markdown}
text {text} (monospace log/output)
table {columns: string[], rows: cell[][]} (sortable; row clicks become the widget selection)
chart {type: "bar"|"line", labels: string[], values: number[], unit?, linkTo?: tableId} (bar clicks become the selection and filter the linked table)
metric {value, label?, delta?}
kv {items: {key: value}}
status-list {items: [{label, status: "ok"|"fail"|"pending"|"unknown", detail?}]}
livemap {root?, nodes: [{id, label, globs: string[], layer?, description?}], edges: [{from, to, label?}]} (architecture diagram; file edits matching a node's globs light it up live)
| Name | Required | Description | Default |
|---|---|---|---|
| h | No | Height in grid rows, 1-4. | |
| w | No | Width in grid columns, 1-4. | |
| id | No | Optional stable id, e.g. "ci-failures". | |
| data | Yes | Payload matching the kind (see description). | |
| kind | Yes | ||
| title | Yes | ||
| source | No | Optional live source, re-run server-side every intervalMs with no LLM. {type:"command", argv:[...], cwd?, parse?:"json"|"text"} (no shell) | {type:"url", url, parse?} | {type:"mcp", tool, arguments?} (wrap mode only). NOTHING runs until the human clicks Approve on the canvas; approved sources go on a persistent allow-list. Output must match the widget data shape (or be text for markdown/text/metric). | |
| intervalMs | No | Refresh interval for a live source, min 2000, default 30000. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral burden and does so well: it discloses that live sources re-run server-side with no LLM, that 'NOTHING runs until the human clicks Approve on the canvas,' that approved sources go on a persistent allow-list, that livemap nodes light up on matching file edits, and that source output must match the widget data shape. These are non-obvious, high-consequence behaviors the schema does not express.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Purpose and return value are front-loaded in one sentence, then a tight bulleted payload catalogue follows. It is long, but nearly every line is load-bearing for an 8-kind polymorphic tool; only the parentheticals (e.g. 'sortable', 'monospace log/output') shade into extra detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a complex, nested, no-annotation tool this covers the essentials: kinds, payload shapes, live-source gating, refresh interval, and the returned id. It omits secondary behavior an agent might need — default layout/size handling for h/w/w, whether an existing id collides or updates, and any widget-count limits — but nothing that blocks a correct call.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema's `data` field is a bare 'Payload matching the kind (see description)' pointer, so the description is the only place the per-kind payload contracts are defined (table columns/rows, chart type/labels/values/linkTo, metric, kv, status-list statuses, livemap nodes/globs/edges). At 75% coverage with 8 params and deep nesting, this compensates fully for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Show something to the human on their mcp-screen canvas') and the return value ('Returns the widget id'), which clearly frames this as the creation/display tool. The eight-item widget-kind list reinforces that this is the create path. It never explicitly names or contrasts with update_widget or read_widget, so sibling differentiation is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied rather than stated: the widget-kind catalogue tells the agent what it can render, and the first sentence implies 'use this when you want the human to see something.' There is no explicit statement of when to prefer place_widget over update_widget, post_report, or ask_user, and no stated exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
post_reportB
Post a standup card when you finish a task: what you changed, test results, a short summary and risks. Cards are grouped by worktree and agent on the Standup board.
| Name | Required | Description | Default |
|---|---|---|---|
| agent | No | Your name/role, e.g. "claude-main" or "test-writer". | |
| risks | No | ||
| tests | No | ||
| branch | No | ||
| summary | Yes | ||
| worktree | No | Worktree or repo name. | |
| filesChanged | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full behavioral burden. It discloses only that cards are 'grouped by worktree and agent on the Standup board'; it says nothing about permissions, whether posts are append-only or overwritable, side effects, or return behavior for a mutation tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences with the trigger and action front-loaded and no filler. Efficient, though it spends its second sentence on grouping metadata rather than on parameter guidance.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 7-parameter mutation tool with nested objects (tests, filesChanged), no annotations, and no output schema, the description leaves significant gaps: the 'branch' param is unaddressed, nested required fields are unexplained, and posting behavior/auth requirements are undisclosed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is low at 29%, so the description must compensate. It does map several params to intended content — 'what you changed' (filesChanged), 'test results' (tests), 'a short summary' (summary), 'risks' (risks), and grouping by worktree/agent — but omits 'branch' and gives no format details for the nested tests/filesChanged structures.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Post a standup card') plus the trigger ('when you finish a task'). It is clear what the tool does, but it never distinguishes itself from the widget/canvas siblings (place_widget, update_widget, read_canvas, etc.), leaving the agent to infer that this is a separate standup-board concept.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Gives a clear when-to-use trigger: 'when you finish a task.' However, it names no alternatives and states no when-not-to-use condition, so routing versus the sibling widget tools is left to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_canvasA
List every widget on the canvas with its id, kind, title, live status and current selection.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. 'List' and 'live status' imply a non-mutating read and disclose the shape of the returned data, which is genuinely useful. However, it says nothing about ordering, pagination, or whether 'live status' reflects real-time state or a cached snapshot.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single sentence that front-loads the verb and scope and wastes no words while still enumerating the returned fields.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read tool with no annotations and no output schema, the description covers the essential behavior and even lists the returned fields. It stops short of describing ordering or scale limits, which would matter for a canvas with many widgets.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool takes zero parameters, so there is no parameter semantics to explain; the baseline of 4 applies. The description correctly implies the call is unfiltered, returning everything on the canvas.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (List) and resource (every widget on the canvas) and enumerates the returned fields (id, kind, title, live status, selection). It implicitly distinguishes itself from the sibling read_widget by scoping to 'every widget', though it never names that alternative.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is only implied: 'every widget' suggests a bulk/inventory read as opposed to the single-item read_widget, but the description never states when to prefer this over read_widget or any other sibling. No exclusions or preconditions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_widgetB
Read a widget back, including selection: what the human clicked (table row, chart bar) or what an MCP App reported. For livemaps, unmappedFiles lists edited files no node covers (time to update the map).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the full burden, and it does disclose part of the return surface: `selection` and the livemap-specific `unmappedFiles`. However, it says nothing about error behavior (unknown id), side effects, or freshness, and no output schema exists to fill that gap.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two tight sentences, front-loaded with the core action before the return-value details. The livemap aside is niche but short and actionable, though the backtick-heavy phrasing is slightly dense.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter read tool with no output schema and no annotations, the description partially compensates by naming key return fields. It still leaves the id semantics and failure modes undocumented, so an agent can call it but not fully anticipate the result.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single required `id` parameter has 0% schema description coverage, and the description never explains what the id refers to or its format. Since the parameter count is low the baseline is generous, but the description adds essentially no meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb+resource ('Read a widget back') that clearly contrasts with the write-oriented siblings place_widget, update_widget and remove_widget. It never names a sibling explicitly, so differentiation is inferred from read-vs-write semantics rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the return-content framing ('what the human clicked'), which tells the agent this is how you learn about user interaction, but there is no explicit when-to-use versus read_canvas or when-not-to-use guidance. An agent must infer the routing from the verb.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
remove_widgetB
Remove a widget (and stop its live refresh).
| Name | Required | Description | Default |
|---|---|---|---|
| id | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It does disclose a genuine behavioral trait beyond the schema: removal also stops the widget's live refresh. It does not state reversibility, whether the call errors on an unknown id, or whether it takes effect immediately, so a meaningful gap remains for a destructive operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single front-loaded sentence with zero filler; the action is stated first and the secondary behavioral note is parenthesized. Nothing could be trimmed without losing information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a one-parameter tool with no output schema and no annotations, the description covers the action and one side effect, which is close to sufficient. Missing details about error behavior and reversibility are minor given the low complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% – the lone parameter is documented only as type string with no description. The tool text adds nothing about what the id refers to or its format, so it fails to compensate for the low coverage as required. Only the parameter's self-evident name keeps this from scoring lower.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Specific verb+resource ("Remove a widget") makes the action unambiguous. It also adds a side-effect clause about stopping live refresh, which the sibling names (place_widget, update_widget) do not. However, it never explicitly contrasts itself with update_widget or clear_canvas, so sibling differentiation is left implicit.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage is implied by the name and the parenthetical note about live refresh, so an agent can reasonably infer when to call it. But there is no explicit when-to-use guidance, no mention of prerequisites, and no routing to alternatives like update_widget (modify) or clear_canvas (remove all).
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
update_widgetA
Update an existing widget. data is shallow-merged into the current data by default (send only the keys you change, e.g. {edges} on a livemap); pass merge:false to replace it entirely.
| Name | Required | Description | Default |
|---|---|---|---|
| h | No | ||
| w | No | ||
| id | Yes | ||
| data | No | ||
| merge | No | ||
| title | No |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It does disclose a genuinely important behavioral trait — that `data` is shallow-merged by default and fully replaced with merge:false — which is exactly the kind of semantics an agent needs. However it says nothing about permissions, error behavior for a missing id, or whether omitted geometry fields (h/w/title) are preserved.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two sentences with no filler, and the default behavior (shallow merge) is front-loaded ahead of the override. The {edges} example is compact and earns its place by making the merge semantics concrete.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
No annotations and no output schema, so the description is the only behavioral source. It covers the highest-risk ambiguity (merge vs replace) well, but leaves permission requirements and the outcome of updating a non-existent widget unexplained for a mutation tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0% across 6 parameters, so the description must compensate. It does well on the two non-obvious params, explaining `data` merge semantics with a concrete {edges} example and clarifying `merge:false`; id/title/h/w are left to self-evident naming and get no explanation.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Update an existing widget'), which cleanly separates it from place_widget and remove_widget in the sibling list. It does not explicitly name place_widget as the create-side alternative, so sibling differentiation is implicit rather than stated.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description frames the tool as updating an *existing* widget, which implies it should be used only after the widget exists, but it never says when to prefer place_widget or what to do if the id is unknown. Usage is implied by the verb and the merge discussion, not stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
ask_user - First observed
clear_canvas - First observed
place_widget - First observed
post_report - First observed
read_canvas - First observed
read_widget - First observed
remove_widget - First observed
update_widget
TDQS
Scored across 8 tools
Each tool has a clearly distinct purpose: place/update/read/remove widgets, read/clear the canvas, ask the user, and post reports. There is no overlapping functionality; the only potential confusion is between read_widget and read_canvas, but they operate at different scopes (single widget vs. entire canvas).
All tool names follow a consistent snake_case verb_noun pattern (place_widget, update_widget, read_widget, read_canvas, remove_widget, clear_canvas, ask_user, post_report). No deviations or mixed conventions.
With 8 tools, the set is well-scoped for a canvas UI management server. Each tool earns its place, covering creation, updates, reads, removals, bulk clearing, user interaction, and reporting without redundancy.
The surface provides full CRUD for widgets (create, read, update, delete, list), bulk clear, plus user interaction and reporting. No obvious gaps for the stated purpose; minor operations like reordering or renaming titles are not essential and can be inferred as part of widget data or skipped.
Maintenance
Related MCP Connectors
Deploy AI-generated HTML/CSS/JS to instant public HTTPS URLs from any MCP-compatible agent.
Live browser debugging for AI assistants — DOM, console, network via MCP.
Generate images, GIFs, videos, and PDFs from HTML, URLs, or templates — from your AI agent.
Remote MCP server exposing your Node Command fleet (files, shell, processes, browser) to AI hosts.
Related MCP Servers
- FlicenseNot gradedqualityAmaintenanceThe terminal AI agents can drive: a cross-platform desktop terminal (macOS/Linux/Windows, MIT) that runs a local MCP server. Spawn tabs/panes, run commands with structured output, read screens and full scrollback, take scrolling screenshots, record sessions with secret redaction, switch identity profiles. Auto-registers with Claude Code / Codex / Gemini CLI on install.14-
- AlicenseAqualityDmaintenanceProvides AI coding agents real-time browser access to console logs, network requests, DOM elements, and screenshots via MCP, enabling tight edit-reload-verify feedback loops.157 npm2MIT
- FlicenseNot gradedqualityDmaintenanceEnables agents to render shadcn-styled dashboards, forms, charts, and comparisons in a local browser via MCP tools.6 npm2-

orchords-web-pilotofficial
FlicenseAqualityCmaintenanceEnables coding agents to drive a real Playwright-backed browser session, navigating, observing, interacting, and capturing proof on web pages via MCP tools across stdio and Streamable HTTP transports.152-