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

pawbrowse

v0.6.5

Published

Let Claude Code drive your real, logged-in Chrome. A zero-dependency MCP server + a Chrome MV3 extension that uses element-table perception over CDP. The calling agent is the policy: no second model, no API keys, page snapshots never leave for a third par

Readme

PawBrowse is a Chrome MV3 extension + a tiny zero-dependency MCP server that lets your local AI coding agent (like Claude Code) read and act on your actual, logged-in browser tabs — your profile, your sessions, your open pages — with no remote-debug port, no browser relaunch, and no separate AI model or API key.

It's the open, self-owned answer to "I wish my agent could just use my real browser": the same capability as the first-party Claude-in-Chrome extension, but yours, auditable, MCP-native, and faster per action (see the benchmark below).

Claude Code ──stdio (MCP)──▶ mcp/server.mjs ─┐
Cursor      ──stdio (MCP)──▶ mcp/server.mjs ─┼─IPC─▶ broker ──ws://127.0.0.1:10577──▶ Chrome extension ──CDP──▶ your real tabs
VS Code     ──stdio (MCP)──▶ mcp/server.mjs ─┘                                              │
                                                                    each session ⇒ its own 🐾 tab group

Run as many sessions as you want. The first one starts a shared broker that owns the port and the extension; every other session just connects to it. Each session gets its own tab group (named 🐾 PawBrowse, its own color) and drives only its own tab, so several editors/agents can automate the browser at once without fighting over a port or a tab. Close a session and its tabs are cleaned up; the broker reaps itself when the last session ends. Nothing to configure — no ports, no "already in use."


Getting started

Two one-time steps, about 30 seconds. PawBrowse is a Chrome extension (the hands + eyes in your browser) plus a tiny local server your AI client runs — both install with a click.

1 — Add the extension to Chrome

Add to Chrome

Live on the Chrome Web Store — one click, done.

2 — Connect your AI client (one time)

Claude Desktop — click the button above to download pawbrowse.mcpb, then double-click it (or drag it into Settings → Extensions) and click Install. No command, no config.

Claude Code — one line (the CLI has no click-to-install, so paste this):

claude mcp add --scope user pawbrowse -- npx -y pawbrowse@latest

Then fully restart your client and ask: "use pawbrowse: what's my browser status?" — you should see extension_connected: true, and the extension badge turns green ●.

Needs Node.js ≥ 18. Works with Claude Code, Cursor, VS Code, or any MCP client — the one button/line just tells your client to run npx -y pawbrowse@latest; nothing to clone or build.

Building from source or contributing? See CONTRIBUTING.md.

Using it

You don't call the tools yourself — you just ask Claude Code in plain language, and it uses PawBrowse to drive whatever tab you point it at. Some things to try:

  • "Open news.ycombinator.com and give me the top 5 story titles."
  • "On this tab, search for 'open source license' and open the first result."
  • "Fill the signup form on the current page with my name and email, but don't submit."
  • "Go to my GitHub notifications and tell me what's new."

Tips:

  • It acts on the tab you have open and are logged into — no separate window, no re-login.
  • Point it at a specific tab by name, or it uses the active tab.
  • It reads the page as a list of controls and clicks/types precisely — no screenshots needed.

Troubleshooting

| Symptom | Fix | | --- | --- | | Badge never turns green | The server isn't running — make sure you fully restarted Claude Code after claude mcp add (a /mcp reconnect alone won't relaunch it). | | "No extension connected" | Reload the extension at chrome://extensions, then re-run browser_status. | | "Another debugger is already attached" | That tab has DevTools open or another extension driving it — close DevTools or switch tabs. | | A chrome:// / Web Store page won't drive | Those are browser pages Chrome blocks from automation — use a normal web page. | | Changed the port | Set the same port in the extension's Options and in --env PAWBROWSE_PORT=…. |

Requires Node ≥ 18 (≥ 22 to run the test suite). Works on Chrome, Edge, and Brave.


Highlights

  • Your real browser. Uses Chrome's built-in chrome.debugger (CDP) on tabs you already have open and logged into — no --remote-debugging-port, no relaunch, no separate profile.
  • The agent is the policy. No second model, no TYPESAFE_API_KEY, no OpenRouter — you (Claude) decide every action. Page content flows to your agent as normal tool results and never leaves for any third-party server.
  • Reads pages as an element table, not screenshots. A compact, numbered list of the actionable controls in view — cheap in tokens, fast to reason over, precise to act on.
  • Fast. Stable element refs let it act in one round trip — ~2.2× faster per action than the closed alternative in testing.
  • Zero dependencies, MIT, extensible. The whole server is one auditable .mjs file; the extension is plain JS. Add a tool or an op in minutes.

Benchmark

| | PawBrowse | Claude in Chrome | | --- | --- | --- | | Wall-clock (incl. the agent's thinking) | 102.5 s | 112.9 s | | Tool calls | 8 (12 actions) | 11 (19 actions) | | Screenshots needed to check state | 0 — every call returns the page's fresh element table | 3 | | Surprises handled | sign-in popup reported ("element is disabled") and dismissed; new tab followed automatically | a filter click that silently didn't apply, caught from a screenshot and retried |

Honest caveats: most of the time on both sides is the agent thinking between calls, so the wall-clock gap is modest. The structural signal is fewer calls and no screenshots — PawBrowse returns the page's state with every action, so the agent never has to "look again". Run 2 (Claude in Chrome) also started with Booking remembering run 1's destination and dates. One run each; treat it as an illustration, not a statistic. Reproduce: scripts/demo/peek-record.mjs films a tab, scripts/demo/render_compare.py renders the comparison.

How it compares

| | Claude-in-Chrome | PawBrowse | | --- | --- | --- | | Drives your real, logged-in Chrome | ✅ | ✅ (chrome.debugger, no port) | | Decision model | Claude | Claude — no second model, no key | | Perception | screenshots + a11y tree | compact element table | | Round trips per action | 2 (perceive → act) | 1 (stable refs) | | Page data to a third party | no | no | | Per-site permission gate | yes (allowlist) | no | | Open source / self-owned | ❌ | ✅ MIT, zero-dep | | Works with any MCP client | ❌ | ✅ |

The element table

Every observation returns a compact, numbered table of the in-viewport, actionable controls — with proper accessible names, current values, and state flags — instead of a screenshot:

Web browser - Wikipedia  —  https://en.wikipedia.org/wiki/Web_browser
scroll 0/6361  ·  83 controls
e2   fill    "Search Wikipedia"
e6   click   "Log in"
e10  click   "2 History"
e13  click ▾ "Toggle Browser market subsection"
e9   click✓  "Remember me"
e3   select  "Country"  opts{US | UK | ...}

Flags after the kind: ✓/· checked/unchecked · ▾/▸ expanded/collapsed (open vs closed menu, combobox, accordion) · ◉ selected (active tab/option). Refs like e10 derive from a stable node identity, so the agent can act on a control by ref in one round trip.

Tools

| Tool | Purpose | | --- | --- | | browser_status | Connection + attached-tab diagnostics. Call first if anything's off. | | browser_tabs | List open tabs (id, title, url, active). | | browser_navigate | { url, tabId? } → element table after load. | | browser_observe | { tabId? } → the element table. | | browser_read | { tabId?, max_chars? } → the page's readable prose (articles, docs, rules). | | browser_act | { ops: [...], tabId? } → runs ops in order, returns a fresh table + a "page changed?" signal. | | browser_assert | { contains? \| url_includes? \| ref_visible?, tabId? } → prove an outcome (pass/fail). |

Ops for browser_act: {op:"click",ref:"e12"} · {op:"click_text",text:"..."} (for custom widgets/menus not in the table) · {op:"type",ref:"e7",text:"..."} · {op:"select",ref:"e8",value:"..."} · {op:"key",key:"Enter"} · {op:"scroll",dy:600} · {op:"wait",ms:500}.

Reliability & safety engineering

PawBrowse was hardened through two multi-agent code audits and live testing on real sites:

  • Hit-tested clicks. Before every click it re-resolves the element live and verifies the center isn't covered (elementFromPoint), so it never clicks a stale, moved, or occluded target.
  • Semantic freshness guard. An element's role + accessible name is fingerprinted at observe time and re-checked before acting — a silently relabeled target is rejected ("observe again") instead of mis-clicked.
  • Robust fill. Select-all + insertText, which works with React/controlled inputs; typed comboboxes wait for their autocomplete options to actually render.
  • Background-tab safe. Uses Emulation.setFocusEmulationEnabled and setTimeout-based waits (never requestAnimationFrame, which Chrome pauses in background tabs) so driving a tab you aren't looking at doesn't hang.
  • No double-execution. If a post-action read fails because the page is navigating, the ops are reported as executed ("call observe next") rather than surfaced as a failure to retry.
  • Serialized, unwedgeable command queue — overlapping calls can't race the debugger, and one hung command can't block the rest.

Security & privacy

  • No data leaves your machine. There's no model and no API key; page content goes only to the agent you run locally. password, file, and hidden inputs are excluded and never exposed. (Other visible fields — e.g. text inputs — are part of the element table, so treat what's on screen as visible to your agent.)
  • Local-only bridge. The WebSocket binds to 127.0.0.1, rejects non-chrome-extension:// origins (so a web page can't connect), trusts only the current extension socket, caps inbound frame size, and rejects malformed/oversized frames. Trust model: the bridge trusts any local process on 127.0.0.1 (there's no shared token yet), so it assumes other software on your machine is trusted — the same assumption as most localhost dev tools. A per-pair token is planned hardening.
  • One powerful permission, no host permissions. The extension declares debugger (plus tabs, storage, alarms) and no host permissions — chrome.debugger doesn't need them. That's the same capability class as any real-browser agent; use it deliberately.
  • Fully auditable. The server is one zero-dependency file; the extension is plain JS.

Found a vulnerability? See SECURITY.md — please don't open a public issue.

Privacy policy

PawBrowse is built to collect nothing. Full policy: PRIVACY.md. In short:

  • Collection / use: PawBrowse has no AI model, no account, no API key, and no telemetry or analytics. Page content it reads (element tables, page text) is returned only to the local AI client you run, to fulfill your request.
  • Storage: the only thing stored is your bridge port number, in chrome.storage.local on your machine. Page content is not persisted by the extension beyond the current operation.
  • Sharing: nothing is sent to the developer or any third-party server. All traffic stays on 127.0.0.1 (localhost) between the extension and the server on your own computer.
  • Retention: none — there is no server-side data, so there is nothing to retain or delete.
  • Contact: questions or requests via GitHub issues.

Notes & limits

  • Attaching shows Chrome's "PawBrowse is debugging this browser" banner — expected.
  • One debugger client per tab: a tab with DevTools open (or driven by another extension) can't be attached — switch tabs or close DevTools.
  • chrome://, the Chrome Web Store, and other browser pages can't be driven.
  • One active client at a time. The bridge is a single localhost port, so PawBrowse can be driven by one client at a time (e.g. Claude Code or Claude Desktop). A second client reports the port is in use via browser_status rather than failing hard; set a different PAWBROWSE_PORT per client if you need both.
  • Shadow DOM and same-origin iframes are enumerated (v0.4.0): controls inside open shadow roots (web components) and same-origin iframes appear in the element table and are clickable/typable by ref. Not yet: cross-origin iframes (the browser blocks JS access to them), canvas, and file uploads.

Contributing

Contributions welcome — see CONTRIBUTING.md for dev setup, tests (npm test), and the PR process. By participating you agree to the Code of Conduct. Questions? SUPPORT.md.

Credits

Built with Claude Code. Some of the page-perception and action-execution techniques are adapted from browser-use/jev-ultrafast (MIT); this credit is kept as required by that project's license.

License

MIT © PawBrowse contributors.