dashhound mcp
Supports recording browser activity and screenshots from Brave via the dashhound extension, enabling MCP clients to review recent page, click, field, network, console, and screenshot events.
Supports recording browser activity and screenshots from Firefox via the dashhound extension and native messaging, enabling MCP clients to review recent page, click, field, network, console, and screenshot events.
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., "@dashhound mcpwhat did I just do on localhost, and what failed?"
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.
dashhound
A dashcam for your dev browser. Named for dogfooding (and for a dog).
You're using your own app and something breaks. You try again and it works fine. You weren't screen recording, the reload cleared the console, and localhost has no Datadog to point at it. dashhound is the dashcam that was already rolling: a local log of what happened on the sites you choose (pages, clicks, what you typed, API calls with what they sent and got back, errors) and a screenshot when something goes wrong. When the bug shows up, you, or your coding agent, look back instead of trying to reproduce it.
The story behind it, and Dash the pixel hound: carlosaguirre.workers.dev/work/dashhound
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')Local only. Everything is written to
~/.local/share/dashhoundby a small local program. No account, no server, no upload.Only the sites you list. Default:
http://localhost/*andhttp://127.0.0.1/*. Add your staging or QA hosts in the extension's settings. dashhound's scripts are only injected there; other sites never run them.Private by default. Password and card fields, anything matching your private selectors, values under keys like
password,token,secret,authorization,apiKey,sessionorcookie, any extra body keys you list in settings (one per line: a plain word matches a whole key name ignoring case,/regex/for patterns), and anything that passes a card-number checksum are stored as[private]. Request headers are never recorded.Loop recording. Like a dashcam: the oldest recording is deleted when either limit is hit, 24 hours or 500 MB by default (both configurable). It is a dashcam, not an archive.
Readable by agents.
dashhound mcpis an MCP server, so Claude Code, Cursor or any MCP client can ask "what did the user just do, and what failed?" before asking you.
What it records
Kind | When | What |
| the URL changes (single-page app routes included) | URL and title |
| you click | the words on the button or link (aria-label / title / text), or |
| a field changes and loses focus, or a select/checkbox changes |
|
| a form is submitted | the form's name |
| a | method, status (or error), URL, time, and the request and response bodies (text only, redacted, 32 KB each by default) |
|
| the message |
| after a save-type click (save, add, confirm, delete, submit, pay…), a form submit, HTTP ≥ 400, or a console error | a JPEG of the tab, at most one every 4 s, only of the tab on screen |
Shadow DOM is fine: clicks and fields inside open shadow roots are named from the real element.
Related MCP server: peek
Install
Needs Python 3.8+ (standard library only).
With pipx, no clone:
pipx install git+https://github.com/Lucer9/dashhound
dashhound install # registers the local host with Firefox
dashhound pack # builds ./dist/dashhound.xpi in the current folderOr from a clone (the commands below are written for this way; with pipx drop the ./):
git clone https://github.com/Lucer9/dashhound ~/dashhound && cd ~/dashhound
./dashhound install # registers the local host with Firefox
./dashhound pack # builds dist/dashhound.xpiEither way, install writes a small launcher, ~/.local/share/dashhound/dashhound-host, that runs dashhound with
the Python it was installed for, and registers that with the browser. Run install again if you move the clone or
reinstall with a different Python. Unpacked Chrome loading needs a folder: with pipx the extension is at
<pipx venv>/share/dashhound/extension, or unzip the .xpi.
Firefox: until dashhound is signed on addons.mozilla.org, load it in Firefox Developer Edition or Nightly with
xpinstall.signatures.required = false (about:config), then Install Add-on From File → dist/dashhound.xpi.
Or, for a session, about:debugging → Load Temporary Add-on → extension/manifest.json.
Chrome / Edge / Brave: chrome://extensions → Developer mode → Load unpacked → extension/. Copy the id it
shows, then ./dashhound install --chrome-id <id>.
Then open the extension's settings to choose which sites to record.
The toolbar button
The toolbar icon is Dash, a pixel dachshund. He wears a red bandana on tabs that are being recorded and takes it off everywhere else, so there is no badge. Click him for the menu:
the site, and whether it is Recording, Paused or Not recorded;
one action that fits: Record this site (adds
<scheme>://<host>/*, any port, then offers to reload, since the scripts only reach pages loaded after the site is listed), Pause or Resume recording (stops everything without touching the list; kept across restarts);what just happened in this tab: the last 5 events with their time, failed calls and errors in red (never field values or bodies; kept in memory for the browser session only);
the coat: dapple (default), cream, black (hard to see on dark toolbars), or your own colours for coat, muzzle, ears and bandana;
Copy log command (
dashhound log --since 10m, to paste for your agent) and Settings.
The dog was drawn in art/icon.json (16×16, one letter per colour). python3 art/export.py writes the store icons
and extension/dog.js, which the extension uses to draw him in any colours at runtime.
Reading it
./dashhound log # last hour
./dashhound log --since 10m --kind click,net,console
./dashhound log --grep checkout --since 2h
./dashhound log --kind net --bodies # what each API call sent and got back
./dashhound log --grep expired # searches bodies too
./dashhound log --json # raw events
./dashhound shots # screenshots with their reason
./dashhound status # data folder, size vs. the MB cap, oldest/newest event, last hour, browser connected
./dashhound report --since 30m -o bug.html # one HTML file to attach to a bug reportreport takes the same --since, --grep and --kind as log and prints the path it wrote (default
dashhound-report.html). The file has no external assets and opens offline: the timeline, screenshots inline, and
each API call's bodies in a collapsible block. The bodies are already redacted, but read the file before you share it.
Deleting recordings
If something sensitive got recorded by mistake:
./dashhound clear --since 10m # deletes the last 10 minutes of events and screenshots
./dashhound clear # deletes everything
./dashhound clear --yes # no confirmation promptclear asks for confirmation unless you pass --yes. Screenshots are matched by the time they were taken. A browser
that is recording right now keeps writing new events after the clear.
status shows "connected" when a dashhound host process is running, which means a browser with the extension is
open. The MB cap shown is the one the extension last sent; until then it shows the 500 MB default.
For coding agents (MCP)
claude mcp add dashhound -- dashhound mcp # Claude Code, installed with pipx
claude mcp add dashhound -- ~/dashhound/dashhound mcp # Claude Code, from a cloneAny MCP client works the same way: command dashhound (or ~/dashhound/dashhound), argument mcp. Tools:
recent_activity(since?, grep?, kinds?, bodies?): the timeline as text, newest last;bodiesadds what each API call sent and got back.get_screenshot(file): one of the screenshots listed in the timeline, as an image.
How it works
extension/ is a Manifest V3 extension (Firefox 140+, Chrome, Edge, Brave). The background registers two scripts,
only on the sites you list: page.js runs in the page itself and wraps fetch and XMLHttpRequest (reading a copy
of each response, so the page's own reading is untouched) and catches console errors; content.js names clicks and
field changes. background.js redacts bodies (redact.js), adds page loads, takes screenshots, and streams
everything over native messaging to dashhound, which appends one JSON Lines file per hour and runs the loop.
Capturing in the page rather than through the browser's network API is what makes bodies work the same in every browser: Chrome's Manifest V3 cannot read response bodies from an extension without attaching the debugger.
Checks: ./dashhound selftest (writer, loop limits, reader, report, MCP) and node test/redact.test.js (redaction).
Limits
Screenshots need the tab to be the visible one in its window (browser rule).
Requests made by web workers and service workers are not seen (only the page's own
fetch/XHR).Tabs that were open before a site was added to the list start recording after a reload.
statusfinds the running host withps, so on systems without it (Windows) it reports the browser as "unknown".Pausing stops what is recorded, not the page scripts: they stay injected on listed sites and simply have their events dropped.
Safari is not supported yet (its extensions package and talk to native apps differently).
Values typed into fields are recorded unless private: keep the site list to development and test environments.
License
MIT
Available Tools
2 toolsget_screenshotB
A screenshot dashhound took (the path comes from a 'shot' line in recent_activity).
| Name | Required | Description | Default |
|---|---|---|---|
| file | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description must carry the full behavioral burden. It does not disclose whether the operation is read-only, what it returns, error behavior, or any side effects; it only gives a brief contextual note about the screenshot's source.
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?
The description is a single short sentence with no wasted words. It is front-loaded with the resource identity and follows with the source context, though the parenthetical placement is slightly awkward.
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 simple one-parameter getter with no output schema, the description gives basic context but leaves gaps around return format and exact behavior. It is minimally adequate but not complete enough to fully guide invocation without inference.
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% for the single `file` parameter, so the description must compensate. It does so by explaining that the path comes from a 'shot' line in recent_activity, adding substantial meaning beyond the bare string 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?
The description identifies the resource as a screenshot taken by dashhound and connects it to recent_activity, but it does not explicitly state the action (retrieve/fetch) or distinguish the tool's purpose from its sibling beyond the path source. The tool name supplies the verb, so the purpose is inferable but not fully articulated.
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?
It implies that the `file` argument should come from a 'shot' line in recent_activity, which is useful workflow context. However, it does not explicitly state when to use this tool versus alternatives or what conditions make it the right choice.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
recent_activityA
What the user did in their browser recently, oldest first: pages opened, clicks (by the words on the button/link), field changes (name = value; private fields hidden), API calls with status and, on request, their bodies, console errors, and screenshots taken at key moments. Use it before asking the user what they did or what went wrong.
| Name | Required | Description | Default |
|---|---|---|---|
| grep | No | Only lines containing this text (case-insensitive). | |
| kinds | No | Only these kinds of events. | |
| since | No | How far back: 90s, 30m, 2h, 1d. Default 30m. | |
| bodies | No | Include what each API call sent and got back (secrets already hidden, cut to 2000 chars). Useful with grep or kinds=['net']. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It discloses useful behavioral traits: chronological ordering ('oldest first'), privacy handling ('private fields hidden'), and conditional behavior ('on request, their bodies'). However, it does not mention authentication requirements, rate limits, retention bounds, or the response format, leaving significant gaps for a tool with zero annotation coverage.
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?
The description is a single dense sentence followed by a short usage directive, front-loading the tool's purpose and event enumeration. Every clause appears to earn its place by specifying content or format. The length is justified by the breadth of the tool's output, though it could be slightly more scannable.
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?
Given no annotations and no output schema, the description must carry the full burden. It adequately describes what the tool returns and its ordering, but omits how results are returned (format, pagination, size limits), authentication needs, and how far back history is actually available (the since param defaults to 30m but no maximum is stated).
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 100%, so the schema already documents all four parameters fully. The description adds context about what the event types look like (click format, field-change format), which helps interpret the kinds enum and pick grep patterns, but it does not directly clarify the grep, since, or bodies parameters beyond what the schema states. Baseline 3 is appropriate.
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 clear verb+resource ('What the user did in their browser recently') and enumerates the specific event types returned. It is specific and distinguishable, but does not differentiate from the sibling get_screenshot tool, and its mention of screenshots as an event type could create some ambiguity with that sibling.
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?
Provides explicit usage context: 'Use it before asking the user what they did or what went wrong.' This tells the agent when to reach for the tool proactively. However, it offers no exclusions, prerequisites, or comparison to the get_screenshot alternative.
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.
2 tool updates
v0.5.1- First observed
get_screenshot - First observed
recent_activity
TDQS
Scored across 2 tools
recent_activity retrieves a chronological activity log, while get_screenshot retrieves a specific image by path. Their purposes and inputs are clearly distinct, so an agent can easily choose between them.
Both names use snake_case and are readable, but patterns differ slightly: get_screenshot follows verb_noun while recent_activity is a noun phrase without an explicit verb. This is a minor deviation in an otherwise consistent two-tool set.
Two tools is thin for a server whose domain involves browser session inspection; the set feels borderline rather than well-scoped. It may be sufficient for a narrowly focused recorder, but there is little room for filtering or session management.
The core observational workflow is covered: recent_activity exposes pages, clicks, field changes, API calls, console errors, and screenshot references, and get_screenshot retrieves those images. Minor gaps exist around querying or filtering activities or managing multiple sessions, but agents can work around them.
Maintenance
Related MCP Connectors
One searchable history across every AI coding tool, with secret scanning and a shared task board.
Live browser debugging for AI assistants — DOM, console, network via MCP.
Give agents eyes on any web page: structured context, and changes explained in plain language.
- SuperlogOAuthsh.superlog
Open-source agent that observes and fixes your application. Query logs, traces, metrics, incidents.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables Claude to remember and search everything that appeared on your screen using local OCR and embeddings. Provides tools for semantic search, activity timeline, and code change tracking.MIT
- AlicenseAqualityDmaintenanceRecords masked browser sessions (rrweb DOM + console + network) to a local SQLite store and exposes them to AI coding agents via stdio MCP. Fully local, no SaaS, no telemetry.107Apache 2.0
- AlicenseNot gradedqualityBmaintenanceEnables AI coding agents to capture screen and voice recordings, extract timestamped frames, and receive structured Markdown reports with context for bug fixing and UI feedback.22 npm18MIT
- AlicenseNot gradedqualityAmaintenanceGives AI coding agents eyes into running applications by recording browser activity and providing session investigation tools for debugging.8 npm3MIT