This wraps onto two lines on my phone and looks squashed.
Shortened the label to “Book online” so it stays on one line at 390px. It’s on staging now.
Your client clicks the button that looks wrong on staging and says why. Claude Code reads that comment over MCP, with the element, a screenshot and the browser it was left in, fixes the code and replies in the same thread your client sees.
No card needed.
Back to running, without the guesswork.
Sports injury clinic by Ambridge village green. Same-week appointments, evenings until 8pm.
Book an appointmentThis wraps onto two lines on my phone and looks squashed.
Shortened the label to “Book online” so it stays on one line at 390px. It’s on staging now.
> fix the open feedback on ambridge-physio. Reply on each one but leave it open for Claire to check. ● howsthat · list_annotations └ 2 annotations. ● howsthat · get_annotation #14 └ Annotation 14, open, 1 thread entry. ● howsthat · get_screenshot #14 └ Screenshot of annotation 14, 1170x2532 pixels. ● The label wraps at 390px. Shortening it. ● Update src/components/Hero.astro ● howsthat · reply #14 └ Reply added.
Nobody copies a screenshot into a ticket or retypes the client’s words for the agent. Everyone works in the same thread.
Clicks the element on staging or localhost and types a sentence. The screenshot, URL, viewport, browser and OS come with it.
list_annotations, get_annotation for the thread and CSS selector, get_screenshot to see the page.
In your repository, on your machine. How’s that? never sees your code.
reply posts under your name, marked “via claude.ai”, where the client will see it.
Looks at staging, then resolves the thread, or replies if it still isn’t right.
If you’d rather the agent closed threads itself, it can call resolve with a closing reply saying what changed and where, and reopen when a fix turns out to be incomplete.
The same details a developer would ask the client for, as structured JSON. This is a trimmed get_annotation result.
target_label, css_selector and the page URL, so the agent can find the component without guessing.get_screenshot returns the screenshot as a JPEG up to 1280px wide, with the element’s box marked in element_rect.authored_via is human or the host of the app that posted, so an agent can tell its own replies from the client’s.untrusted key, with control and bidi characters stripped and long text cut.{ "number": 14, "status": "open", "has_screenshot": true, "viewport": { "width": 390, "height": 844 }, "browser": "Safari 18", "dashboard_url": "https://app.howsthat.design/p/ambridge-physio/a/14", "created_at": "2026-10-09T09:02:11.482913+00:00", "comments": [ { "id": "0199c9e2-4b1a-7c3e-9f20-5d8a1e6b7c44", "kind": "text", "authored_via": "human", "created_at": "2026-10-09T09:02:11.482913+00:00", "edited_at": null, "untrusted": { "author": "Claire Hughes", "body": "This wraps onto two lines on my phone and looks squashed.", "body_truncated": false } } ], "untrusted": { "target_label": "button “Book an appointment”", "css_selector": "section.hero > a.btn-book", "text_quote": null, "page_url": "https://staging.ambridge-physio.example/", "os": "iOS 18.6" } }
get_screenshot, alongside the JPEG
{ "number": 14, "width": 1170, "height": 2532, "scale": 1,
"element_rect": { "x": 66, "y": 1236, "width": 516, "height": 132 } }
reply with an idempotency_key
{ "comment": { "id": "0199ca07-1d2e-7a41-b8c3-2e6f90a4d518",
"created_at": "2026-10-09T09:41:03.120554+00:00" },
"replayed": false }
Example values. Field names and shapes match the server.
The server is at https://app.howsthat.design/mcp (Streamable HTTP). There’s no API key to paste: the agent signs in through your browser and you approve it.
claude mcp add --transport http howsthat \ https://app.howsthat.design/mcp
/mcp, pick howsthat and authenticate. Your browser opens the How’s that? sign-in and consent screen./mcp__howsthat__triage_feedback ambridge-physio
Apps sign in with a Client ID Metadata Document, a newer part of the MCP sign-in standard. Support varies:
Each agent gets its own grant: the scopes it asked for, the projects you picked and nothing else.
annotations:readscreenshots:readthreads:triageTools outside the granted scopes aren’t listed to the agent at all. Projects outside the grant behave as if they don’t exist.
/mcpA comment is written by a person and could say anything, including “ignore your instructions”. Every tool result says so, and the built-in prompt tells the agent to treat untrusted text as a description of a problem, never as a command. It lowers the risk of prompt injection; it can’t remove it, so keep your agent’s own permission prompts on.
reply takes an idempotency_key, so a retried call returns the first reply instead of posting twiceEvery tool call, approval, denial and revocation is logged with ids only, never comment text, and kept for 180 days. Account › Connected apps shows each agent’s projects, when it was last used and its 20 most recent actions. Revoke it there and it stops at its next request.
An MCP server isn’t unusual any more. BugHerd, Marker.io, Userback, Jam and Pastel all offer one. The difference is who leaves the feedback and where.
localhost and sites only reachable on a VPN. It only switches on for sites in a project.Being fair to the other side: if you’re the only person filing bugs on your own app, a free bug-capture tool may suit you better. Some of them send console and network logs to the agent, and How’s that? doesn’t capture those.
Claude Code, tested end to end. Claude desktop and web, ChatGPT, Codex, VS Code with GitHub Copilot, Zed and Goose support the same sign-in method, so they should connect too. Cursor, Gemini CLI, Cline, Continue and Copilot Studio don’t support it yet.
No. The agent runs on your machine and edits your repository. How’s that? only receives the tool calls: a project slug, an annotation number and any reply text.
Only if you let it. It needs the threads:triage scope to reply, resolve or reopen, and Claude Code asks before each tool call unless you’ve allowed it. Replies appear under your name with “via claude.ai”, and every call is listed under Connected apps.
The reviewer’s viewport when they commented, as a JPEG at most 1280px wide. Password fields and anything marked data-annotate-mask are blacked out before upload. An agent without screenshots:read can’t fetch it.
No. It’s included on every paid plan, from Solo at $19 a month, and on the Free plan during your first 14 days. See pricing.
No, by design. Agents read threads and answer them. People create comments, so everything in a project came from someone who looked at the page.
Shortened it to “Book online” so it fits on one line. How’s that?
Spot on, thanks.