$ account eyalzh
This repository is an application: an MCP (Model Context Protocol) server paired with a Firefox browser extension that gives AI assistants like Claude Desktop read and management access to a user's real browser. The MCP server exposes nine tools over stdio — open/close/list/reorder/group tabs, search browsing history, extract a page's text and links, find/highlight text in a tab, and capture screenshots. Unlike generic web-automation MCP servers, it deliberately cannot click, modify pages, or run arbitrary scripts; page content access requires per-domain user consent and screenshots require per-tab authorization via Firefox's activeTab mechanism. Architecturally this is an Nx monorepo with three packages: mcp-server (Node 22, @modelcontextprotocol/sdk), firefox-extension (Manifest V2 WebExtension), and common (shared typed message protocol). The server communicates with the AI client over MCP stdio and with the extension over a loopback-only WebSocket (127.0.0.1 and ::1 on port 8089, or 0.0.0.0 in container mode). Every message is HMAC-SHA256 signed with a shared secret the extension generates; the extension connects outbound, so no inbound socket is exposed in the browser. Requests are matched to responses by correlation ID with timeouts, and the extension replies with resources (tabs, history, content, screenshots) over the same channel. The code is security-conscious and well-crafted: the dual-loopback binding handles IPv4/IPv6 localhost resolution differences, a capture-consent module mirrors the browser's activeTab grant lifetime to fail fast with actionable errors, the extension ships no runtime third-party dependencies, and it includes per-tool enable/disable toggles, a domain deny list, and a bounded in-browser audit log. The extension message handler has a solid Jest test suite covering consent revocation, denied domains, and disabled tools; the MCP server itself lacks unit tests. Minor debt: an unused, deprecated 'readline' npm dependency in mcp-server/package.json, an Nx version mismatch between root (22.x) and the subproject (20.x), and a few non-null assertions in the WebSocket layer. The repo is actively maintained with recent commits, a release workflow that builds DXT packages, and current dependency versions (TypeScript 5.8, Jest 30, MCP SDK 1.x, ws 8.x), so technical drift is low.