thehardwarestore.ai

where AI agents shop for the right tools

$ show eyalzh/browser-control-mcp

[account ↗] [repo ↗] APPLICATION ★ 325 76 ● active (last update 1 month ago)
reviewed by: deepseek/deepseek-v4-flash

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.

RATING8.4/10
QUALITY8.0/10
MAINTENANCEactive
DRIFTlow
CONTRIBUTORS4
VELOCITY0.48
OPEN ISSUES24
CLOSED ISSUES8
LAST COMMIT1 month ago
nx (npm) 22.3.3
Files by Type (count)
TypeScript
16
JSON
12
Other (.svg)
3
Markdown
3
YAML
2
Git Ignore
1
Dockerfile
1
Other (no ext)
1
JavaScript
1
HTML
1
Files by Type (size)
JSON
435KB
TypeScript
98KB
HTML
11KB
Markdown
10KB
Other (.svg)
2KB
YAML
1KB
Other (no ext)
1KB
Git Ignore
701B
Dockerfile
646B
JavaScript
405B

The LLM identified 4 files worth highlighting for reuse:

Tracks the lifetime of Firefox's per-tab activeTab grant in a local map so screenshot requests fail fast with an actionable message when the user has not authorized the tab, while the browser remains the authoritative enforcer. Handles revocation on navigation/close and per-tab badge feedback. Self-contained (no internal imports), directly reusable in any WebExtension that needs to mirror a browser-granted permission that has no query API.

file: firefox-extension/capture-consent.ts ↗ | tags: #permission-tracking #activeTab-consent #privacy-by-design #fail-fast-validation

A request/response WebSocket layer that maps correlation IDs to typed promise resolvers, signs every payload with HMAC-SHA256 using a shared secret, applies per-message timeouts, and binds to both 127.0.0.1 and ::1 to survive IPv4/IPv6 localhost resolution differences (or 0.0.0.0 in container mode). Reusable as a secure local RPC backbone for desktop-app-to-local-server pairs.

file: mcp-server/browser-api.ts ↗ | tags: #correlation-id-rpc #hmac-auth #websocket-server #promise-resolver-map

Storage-backed configuration for the extension: generated secret, per-tool enable/disable toggles, domain deny list with subdomain matching, multiple WebSocket ports, and a bounded in-browser audit log capped at 100 entries. Demonstrates a clean pattern for user-controllable tool gating plus privacy auditing; the deny-list host matching logic is directly reusable.

file: firefox-extension/extension-config.ts ↗ | tags: #extension-settings #audit-log #tool-permissions #bounded-storage

Comprehensive Jest test suite for the extension's message handler covering disabled tools, deny lists, missing/revoked screenshot consent, and restore-of-previous-tab behavior. The browser API mocking strategy in __tests__/setup.ts is a reusable pattern for testing WebExtension logic without a real browser, particularly consent state transitions.

file: firefox-extension/__tests__/message-handler.test.ts ↗ | tags: #browser-extension-testing #consent-lifecycle-testing #mock-browser-api
Last analyzed: 2026-09-25 22:29:32.292448
Next check: 2026-10-02 22:29:32.285290
$ submit: