Client feedback your coding agent can act on

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.

Works with Claude Code today Agents reply, but can’t edit what people wrote
staging.ambridge-physio.example
Password protected
TreatmentsPricesContact

Back to running, without the guesswork.

Sports injury clinic by Ambridge village green. Same-week appointments, evenings until 8pm.

Book an appointment
Claire Hughes Open

This wraps onto two lines on my phone and looks squashed.

button “Book an appointment”, 390×844, Safari 18, iOS 18.6
Sam Patel via claude.ai

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.
The clinic, people and code are made up. Tool names and result lines are the server’s own.

One thread, from the client’s click to the fix

Nobody copies a screenshot into a ticket or retypes the client’s words for the agent. Everyone works in the same thread.

  1. Client

    Pins a comment

    Clicks the element on staging or localhost and types a sentence. The screenshot, URL, viewport, browser and OS come with it.

  2. Agent

    Reads it

    list_annotations, get_annotation for the thread and CSS selector, get_screenshot to see the page.

  3. Agent

    Fixes the code

    In your repository, on your machine. How’s that? never sees your code.

  4. Agent

    Replies in the thread

    reply posts under your name, marked “via claude.ai”, where the client will see it.

  5. Client

    Checks and resolves

    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.

What the agent receives

The same details a developer would ask the client for, as structured JSON. This is a trimmed get_annotation result.

Where on the page
target_label, css_selector and the page URL, so the agent can find the component without guessing.
What the client saw
Viewport, browser and OS. get_screenshot returns the screenshot as a JPEG up to 1280px wide, with the element’s box marked in element_rect.
Who said what
The whole thread, oldest first. authored_via is human or the host of the app that posted, so an agent can tell its own replies from the client’s.
What’s untrusted
Anything a person wrote or a page supplied sits under an 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.

Connect your agent

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 Code

  1. Add the server:
    claude mcp add --transport http howsthat \
      https://app.howsthat.design/mcp
  2. In Claude Code, run /mcp, pick howsthat and authenticate. Your browser opens the How’s that? sign-in and consent screen.
  3. Choose which projects it may see and approve. Then ask for the open feedback on a project, or run the built-in prompt:
    /mcp__howsthat__triage_feedback ambridge-physio

Which apps can connect

Apps sign in with a Client ID Metadata Document, a newer part of the MCP sign-in standard. Support varies:

  • Claude Code, tested end to end
  • Claude desktop and web, ChatGPT, Codex, VS Code with GitHub Copilot, Zed and Goose support it
  • Cursor, Gemini CLI, Cline, Continue and Copilot Studio don’t support it yet

You decide what the agent can touch

Each agent gets its own grant: the scopes it asked for, the projects you picked and nothing else.

annotations:read
List projects and pages, list and read annotations and their threads.list_projects, list_pages, list_annotations, get_annotation
screenshots:read
Fetch a comment’s screenshot. Kept separate because screenshots can show staging data.get_screenshot
threads:triage
Reply to, resolve and reopen threads as you. Each reply shows “via” the app’s host.reply, resolve, reopen

Tools outside the granted scopes aren’t listed to the agent at all. Projects outside the grant behave as if they don’t exist.

What agents can’t do

  • Pin a new comment on a page. They can only reply to existing ones.
  • Edit or delete anyone’s comments
  • Change projects or users
  • Use their token anywhere but /mcp

Comments are data, not instructions

A 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.

Limits and retries

  • 120 calls a minute, 20 changes a minute and 500 a day for each grant
  • reply takes an idempotency_key, so a retried call returns the first reply instead of posting twice
  • Replies are capped at 4,096 bytes

Audit and revoke

Every 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.

Where it differs from free developer tools

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.

Clients comment without an account
You send a review link; the client clicks and types. The people whose feedback your agent reads don’t need to be developers, or even signed up.
Staging, localhost and VPN-only sites
The browser extension runs in the reviewer’s own browser, so it works on password-protected staging, Basic Auth, localhost and sites only reachable on a VPN. It only switches on for sites in a project.
Journeys
Record a walk through a localhost or VPN-only flow (Alt+Shift+R). Each step is a copy of the page that reviewers comment on like the live site, so someone who can’t reach it can still give feedback.
Captured in the reviewer’s browser
Comments come from Chrome and Edge through the extension, and from Safari or a phone through a review link. Each one records which browser, OS and viewport it came from, so the agent fixes the bug the client actually saw.

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.

Questions developers ask

Which agents work with it?

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.

Does How’s that? see my code?

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.

Will the agent post to my client without me knowing?

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.

What’s in the screenshot?

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.

Does agent access cost extra?

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.

Can agents create tickets or new comments?

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.

Your client points at the thing. Your agent fixes it.

No card needed.

Book online
Sam Patel via claude.ai

Shortened it to “Book online” so it fits on one line. How’s that?

Claire Hughes Resolved

Spot on, thanks.