The first example in dashhound’s README is a broken checkout.
14:02:11 tab 3 page http://localhost:3000/cart Your cart
14:02:15 tab 3 field Quantity = '0' on /cart
14:02:18 tab 3 field Promo code = 'SPRING' on /cart
14:02:19 tab 3 click 'Apply' (button) on /cart
14:02:19 tab 3 net POST 422 http://localhost:3000/api/cart/promo
14:02:20 tab 3 shot HTTP 422 POST /api/cart/promo -> ~/.local/share/dashhound/shots/20260930-140220-3.jpg
14:02:24 tab 3 click 'Checkout' (button) on /cart
14:02:24 tab 3 console uncaught: TypeError: Cannot read properties of undefined (reading 'total')
A screenshot lands a second after the promo call’s 422, and the TypeError comes with the Checkout click. Screenshots come after a save-type click, a form submit, a 4xx or 5xx response, or an error in the console, at most one every 4 s.
I built dashhound in September as a Manifest V3 extension plus one standard-library Python file, and it’s open source. Events stream over native messaging to that file, which serves them through a CLI, an HTML report and an MCP server.
Named for dogfooding, and for a dog. You find a bug in your own app, and when you try again it works fine. You weren’t screen recording, the reload cleared the console, and localhost has no Datadog to point at it. While a coding agent was helping me test a fix through a bridge into my browser, it kept asking what I’d clicked, and mostly I didn’t remember.
Before the bridge’s dashcam got its own repo, I looked for an existing tool. Agent browser tools see the browser as it is now, bug-report tools upload a recording when you file a bug, and screen recorders keep pixels and lose what they meant. None kept a plain record of what a person did. Dashhound does, much as visual regression shows what a change did.
Names a person would use
At first, the bridge’s dashcam logged CSS classes and clicks on invisible menu backdrops, and read like a crash dump. Now a click is named by its aria-label, title or visible text, and a field by its label, which is how the example gets 'Apply' (button) and Quantity = '0'.
The dashcam’s first real catch was a form that saved an empty record because of values the page had pre-filled. No retry from memory would have reproduced it, and the log had it in three lines and a screenshot.
Keeping the bodies
The first plan kept bodies only for failed calls, and only the request side in Chrome. I wanted all of them, in every browser, with the log capped by time or size.
Chrome’s Manifest V3 won’t give an extension a response body without attaching the debugger, which puts a banner on the tab. So page.js wraps the page’s fetch and XMLHttpRequest and reads a copy of each response, in Firefox and Chrome alike. Requests from web workers and service workers go unseen.
A login request carries a password, so values under keys like password or token are saved as [private], and headers are never recorded. Tested against a real login, dashhound hid the tokens and leaked one thing, a one-time sign-in code in a form body, fixed the same hour.
A day of calls could grow the log from kilobytes to gigabytes. By default each body is cut to 32 KB and the log loops at 24 hours or 500 MB. I never debug yesterday.
What the agent sees
Dashhound’s MCP server offers a coding agent two read-only tools, recent_activity and get_screenshot, the kind of short list my other agents run with.
claude mcp add dashhound -- dashhound mcp
dashhound log --since 10m --kind click,net,console
dashhound report --since 30m -o bug.html
The agent looks before it asks me what I clicked.
A bandana instead of a badge
Version 0.4.0 showed recording with a red REC badge on the toolbar icon, and the next release replaced it with Dash. The candidates for showing it on the dog himself were a red nose, a tally light and a red bandana, and I picked the bandana. He wears it on tabs being recorded and takes it off everywhere else. Above the article he’s putting it on and taking it off.
The bandana is 22 of the drawing’s 256 pixels, 20 of them empty space under his chin, so his face never changes. He’s stored as rows of letters, like Taquito, and the extension draws him at runtime in a dapple, cream or black coat, or in your own colors for the coat, muzzle, ears and bandana.
Where it stands
Version 0.5.1, released September 30, 2026, isn’t signed yet. It installs in Firefox Developer Edition or Nightly, or in Chrome with Developer mode, following the README. Bugs and ideas go to the issues.