npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

shadowmark-mcp

v2.0.0-alpha.5

Published

MCP server for Shadowmark — screen recording + annotations bridge for AI agents (SQLite-backed, dual stdio/HTTP-SSE transport)

Readme

🎯 shadowmark-mcp

Give your AI agent eyes, console, network & DOM — straight from the browser.

Record any web session locally; your agent reads the screen frames, console errors, network traffic, storage and DOM snapshots through MCP. No screenshots. No copy-paste. No cloud.

npm downloads node license: MIT MCP native

Quick startConnect & recordMCP toolsHTTP APIPrivacy

Turn any browser session into rich, actionable context for AI agents — local-first, MCP-native.

shadowmark-mcp is the local server half of Shadowmark. It captures what the user records in the Chrome extension — screen frames, console errors, network traffic, storage state, and DOM snapshots — into a local SQLite database, then exposes it to Claude Code / Cursor / any MCP client through 12 well-designed tools.

┌─────────────────────────────────────────────────────────────────────┐
│ Chrome Extension       HTTP                         MCP (stdio/SSE) │
│ ─────────────────  ─────────────►  shadowmark-mcp  ◄───────────────  Claude Code │
│ • Frame capture (2 FPS JPEG)       :3141                            │
│ • Console / network via CDP        SQLite + JPEGs                   │
│ • Annotations + DOM snapshots      ~/.shadowmark/                   │
│ • localStorage / sessionStorage                                     │
└─────────────────────────────────────────────────────────────────────┘

All data stays on the user's machine. The server never opens an outbound connection. Sensitive headers (Authorization, Cookie, x-api-key) are auto-redacted before storage.


Why this matters — productivity in numbers

Based on the typical bug-reporting workflow when working with an AI coding agent:

| Step | Manual workflow (today) | With Shadowmark | Speedup | |---|---|---|---| | Take screenshot of the issue | 10 s | auto (every 500ms) | — | | Copy console error → paste | 20 s | auto | — | | Find related network request, copy headers + body | 60 s | auto | — | | Type selector / framework info | 60 s | auto via DOM snapshot | — | | Write description, paste into Claude | 30 s | "what's in my latest recording" | — | | Total per bug context | ~3 minutes | ~15 seconds | ~12× |

| Dimension | Manual | Shadowmark | Δ | |---|---|---|---| | Context density | ~2 KB (selector + note + 1 error line) | ~50–200 KB structured (frames, full HTML, full network trace) | 25–100× richer | | Iteration speed (bug → fix attempt) | 3–5 min round-trip | ~30 s | ~6–10× | | Frames captured per minute of session | 0–2 manual screenshots | 120 (2 FPS) | 60–120× | | Network capture | manual copy of 1–2 requests | every request + response body (≤100 KB each) | 30×+ |

For a developer who logs 5 AI-assisted debugging cycles per day:

  • ~12 minutes saved per session × 5 sessions = 60 minutes saved per day.
  • Across a 5-day work week that's ~5 hours of pure context-gathering reclaimed.
  • Across a year, ~250 hours — roughly 6 working weeks.

These are estimates from typical workflows, not benchmarked claims. Your mileage depends on how often you hand context to an AI agent and how thoroughly you describe it today.


Client-side context — what gets captured

Per recording, Shadowmark captures and structures the following on the user's local machine:

~/.shadowmark/shadowmark.db               (SQLite WAL)
├── recordings                            session metadata
├── frames                                1 row per JPEG, with trigger reason
├── annotations  ← dom_snapshot column    user notes + serialized DOM
├── console_logs                          every console.* call + uncaught exceptions
├── network_requests  ← body columns      method/url/status/headers + req/res bodies
└── storage_snapshots                     localStorage + sessionStorage start & end

~/.shadowmark/recordings/<id>/frames/*.jpg   raw screen frames at 1920×1080

| Source | Captured via | Cap | Notes | |---|---|---|---| | Screen frame | chrome.tabCapture + canvas → JPEG q=82 | 2 FPS · ~140 KB/frame | Auto-stop at 60 s | | Console + uncaught errors | CDP Runtime.consoleAPICalled + Runtime.exceptionThrown | unbounded rows, 4 KB / message | Levels: log/info/warn/error/debug | | Network request | CDP Network.requestWillBeSent | unbounded rows | Headers redacted | | Network response | CDP Network.responseReceived + Network.loadingFinishedNetwork.getResponseBody | 100 KB / body, text-only | Binary (images/fonts) skipped | | Storage | chrome.scripting.executeScript snapshot of window.localStorage + sessionStorage | start + end of recording | 4 KB per key | | DOM snapshot | content script — target outerHTML, ancestor chain, surrounding HTML | 100 KB total per annotation | Captured only when the user annotates during recording | | Annotation note | user types into the toolbar | 4 KB plain text | Linked to a specific frame |

Every row links back to its recording_id, so the MCP tools can join across sources to build a merged timeline.


Which Chrome extension to use

shadowmark-mcp is the server. It does nothing without the companion Shadowmark Chrome extension.

| Component | Where | Distribution | |---|---|---| | Chrome extension | shadowmark.in | Chrome Web Store | | MCP server (this package) | npm: shadowmark-mcp | This README |

Install the extension

Add it from the Chrome Web Store, or click Add to Chrome on shadowmark.in. That's the whole install — no cloning, no developer mode.


Quick start

1. Install + auto-configure

npm install -g shadowmark-mcp
shadowmark-mcp install        # writes the MCP entry to Claude Desktop AND Claude Code config

The install command auto-detects which Claude clients you have and registers shadowmark in their MCP config. It's idempotent — safe to re-run.

2. Restart your Claude client

  • Claude Code: exit the CLI and relaunch from the directory you want to work in.
  • Claude Desktop: quit + reopen the app.

Connect & record (the full flow)

 npm i -g shadowmark-mcp
        │
        ▼
 connect to Claude Code ──┐
   (auto via stdio, or    │   server reachable on :3141
    SSE — see below)      ├─────────────────────────────►  extension shows  ● Record
        │                 │   (a Claude Code session OR
 run a recording          │    `shadowmark-mcp --http`)
        │
        ▼
 "what's in my latest Shadowmark recording? suggest a fix."
        │
        ▼
 agent calls shadowmark_get_context → sees frames + console + network + DOM → edits the code

Two roles, often one process

| Role | Who serves it | |---|---| | MCP reads — Claude sees your recordings | stdio: Claude Code / Claude Desktop spawn it automatically | | Recording ingest — the extension saves frames/console/network to :3141 | the --http listener (see below) |

As of v2.0.0-alpha.3, the stdio server also opens the ingest listener on 127.0.0.1:3141 automatically while your Claude Code session is open — so recording "just works" with no extra step. The extension's Record button only appears when it can reach :3141; if it's hidden, either open a Claude Code session or start the standalone daemon.

A. Connect to Claude Code

Stdio (simplest — Claude Code launches the server):

shadowmark-mcp install                          # writes the config for you
# or, manually:
claude mcp add shadowmark -s user -- shadowmark-mcp --stdio

SSE (one daemon serves both the extension and Claude Code):

shadowmark-mcp --http                            # keep running (own terminal / background)
claude mcp add shadowmark -s user --transport sse http://127.0.0.1:3141/mcp

Verify with claude mcp list, then start a new Claude Code session.

B. Record + ask

  1. Open any http(s) site in Chrome.
  2. When the Shadowmark toolbar shows ● Record (server reachable), click it.
  3. Reproduce the issue. Optionally click elements to drop annotations — the agent gets the exact DOM for those moments. Recording auto-stops at 60 s.
  4. Stop (or let it auto-stop).
  5. In Claude Code / Claude Desktop, ask:

    "What's in my latest Shadowmark recording? Suggest a fix."

Claude calls shadowmark_get_context → sees the merged timeline + key frames → reads your annotation's DOM snapshot → proposes a specific edit.

Want recording without a terminal at all?

Run it once as a background daemon so :3141 is always up:

shadowmark-mcp --http

(A future release will let the extension launch the helper itself via Native Messaging — no daemon, no terminal.)


MCP tools

| Tool | Purpose | |---|---| | shadowmark_list_recordings | List recent recordings with ids, timestamps, frame counts | | shadowmark_get_context | Start here — merged timeline + 4 key frames inline as images | | shadowmark_get_annotations | User-flagged moments with frame_id + optional DOM snapshot | | shadowmark_get_frames | Up to 8 frames inline; filter by trigger or center on a timestamp | | shadowmark_get_console_logs | Console output (filter by level) | | shadowmark_get_network_requests | HTTP traffic; failed_only, url_contains, include_bodies filters | | shadowmark_get_storage | localStorage + sessionStorage snapshots |

Plus the preserved v1 annotation-task tools: get_pending_tasks, get_task, complete_task, get_page_context, clear_all_tasks.

MCP prompt

  • shadowmark-workflow — one-time prompt that teaches the agent how to interpret recordings and act on them. Invoke once at the start of a session for the most useful behavior.

HTTP API

The server exposes a local-only HTTP API on 127.0.0.1:3141:

| Endpoint | Method | Purpose | |---|---|---| | /health | GET | Liveness check (used by the Chrome extension) | | /ingest/start | POST | Begin a recording | | /ingest/frame | POST | Send one JPEG frame (base64) | | /ingest/console | POST | Log a console event | | /ingest/network | POST | Insert or upsert a network request | | /ingest/storage | POST | Snapshot localStorage / sessionStorage | | /ingest/annotation | POST | Save a mid-recording annotation + DOM snapshot | | /ingest/finalize | POST | Mark the recording complete | | /tasks | GET/POST/DELETE | Annotation-task queue (v1 surface, preserved) | | /recordings | GET | List recordings | | /recordings/:id | GET / DELETE | Detail or cascading delete | | /recordings/:id/player | GET | Standalone HTML slideshow viewer | | /recordings/:id/frames/:ts.jpg | GET | Serve a single frame | | /recordings/:id/events.json | GET | Player data payload | | /mcp | GET (SSE) | MCP transport for HTTP clients | | /mcp/messages?sessionId=… | POST | MCP JSON-RPC body for SSE clients |


Configuration

| Env var | Default | Effect | |---|---|---| | SHADOWMARK_DB_PATH | ~/.shadowmark/shadowmark.db | Override SQLite location | | SHADOWMARK_RECORDINGS_DIR | ~/.shadowmark/recordings/ | Override frame storage location | | SHADOWMARK_STORE_PATH | ~/.shadowmark/tasks.json | Override annotation-task queue file. Pass none to disable persistence (tests use this). | | SHADOWMARK_MCP_CONFIG_PATH | (auto-detected) | Override target for install subcommand (testing only). |


Privacy & security

  • Local-only. The server binds to 127.0.0.1 and makes no outbound calls.
  • Header redaction. Authorization, Cookie, Set-Cookie, X-Api-Key, X-Auth-Token, X-Token, X-Session are replaced with [REDACTED] before storage.
  • Body capture is text-only. Binary content (images/fonts/video) is skipped — the agent can't use raw bytes anyway, and they would inflate storage.
  • Size-bounded. Per-body cap 100 KB. Frame cap 60 s. Disk usage is finite per recording.
  • User-controlled deletion. The extension popup has a delete button per recording. Server cascades the DB rows and removes the JPEGs from disk.

How it differs from session-replay tools

| | LogRocket / Replay.io / Sentry Session Replay | Shadowmark | |---|---|---| | Where data lives | Vendor cloud | User's machine (~/.shadowmark/) | | Captured for | Product analytics, ops triage | AI-assisted development | | Format | Proprietary playback in vendor UI | SQLite + JPEGs (open) + MCP tools | | Per-event price | Yes (tens to thousands per month) | Free | | Works for AI agents | No native integration | Built for it (12 MCP tools, single workflow prompt) | | Network body capture | Optional, paid tier | On by default, 100 KB cap, text-only | | DOM context for AI | None | Per-annotation snapshot with ancestor chain | | Frame format | WebRTC video / DOM replay | Per-second JPEGs (model-vision friendly) |

Shadowmark is intentionally narrow: it builds context for AI agents, not for humans watching playback. The player UI exists so you can review your own sessions, but the primary consumer is your agent.


Development

git clone https://github.com/Shrikant-satpute/shadowmark-mcp
cd shadowmark-mcp
npm install
npm run build       # clears dist/ and compiles
npm test            # 25 tests
npm start           # boot the HTTP server locally

To regenerate the install CLI behavior:

SHADOWMARK_MCP_CONFIG_PATH=/tmp/test-mcp.json npm run start -- install --dry-run

To smoke-test the M3 tools against your real database:

node scripts/m3-smoke.mjs                # uses the latest recording
node scripts/m3-smoke.mjs <recording_id> # specific one

Roadmap

  • [x] Chrome Web Store listing live — shadowmark.in (v1.2.0 recording update in review)
  • [ ] Cookie + IndexedDB capture (beyond localStorage)
  • [ ] WebSocket frame capture
  • [ ] Voice annotations via Web Speech API
  • [ ] Source-map-aware stack traces
  • [ ] Frame deduplication / skip-if-unchanged
  • [ ] Cloud-sync option (opt-in)
  • [ ] Team workspaces

Issues & feature requests: file at the GitHub repo.


License

MIT — see LICENSE.


Contact

Built by shrikant-satpute.