browser-bridge-mcp 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Mukesh Bishnoi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,144 @@
1
+ # browser-bridge-mcp
2
+
3
+ Give [Claude Code](https://docs.anthropic.com/en/docs/claude-code) direct access to your browser — console logs, network requests, JS errors, storage, DOM, and more.
4
+
5
+ ## How it works
6
+
7
+ ```
8
+ Browser <──WebSocket──> MCP Server <──stdio──> Claude Code
9
+ ```
10
+
11
+ A small client script runs in your browser tab, hooks into console, fetch, XHR, and error events, and streams everything to an MCP server that Claude Code can query.
12
+
13
+ ## Quick Start
14
+
15
+ ### 1. Install
16
+
17
+ ```bash
18
+ npm install -D browser-bridge-mcp
19
+ ```
20
+
21
+ ### 2. Register with Claude Code
22
+
23
+ ```bash
24
+ # User scope (just you)
25
+ npx browser-bridge-mcp setup
26
+
27
+ # Project scope (whole team via .mcp.json)
28
+ npx browser-bridge-mcp setup --scope project
29
+ ```
30
+
31
+ ### 3. Connect your app (pick one)
32
+
33
+ **Next.js** — add to `next.config.mjs` (or `.ts`):
34
+
35
+ ```js
36
+ import { withBrowserBridge } from 'browser-bridge-mcp/next';
37
+
38
+ // Wrap your config — no-op in production
39
+ export default withBrowserBridge(nextConfig);
40
+ ```
41
+
42
+ **Vite** — add to `vite.config.js`:
43
+
44
+ ```js
45
+ import { browserBridge } from 'browser-bridge-mcp/vite';
46
+
47
+ export default defineConfig({
48
+ plugins: [browserBridge()],
49
+ });
50
+ ```
51
+
52
+ **Any page** (bookmarklet / console paste):
53
+
54
+ ```bash
55
+ npx browser-bridge-mcp bookmarklet # generates clickable bookmarklet HTML
56
+ npx browser-bridge-mcp snippet # prints client.js to stdout
57
+ ```
58
+
59
+ ### 4. Use it
60
+
61
+ Restart Claude Code, run your dev server, done. Claude can now see everything in your browser.
62
+
63
+ ## What Claude Can See
64
+
65
+ | Tool | Description |
66
+ |------|-------------|
67
+ | `browser_get_console_logs` | Console output (log, warn, error, info, debug) |
68
+ | `browser_get_network_requests` | Fetch/XHR with status, timing, headers, body |
69
+ | `browser_get_errors` | JS errors and unhandled promise rejections |
70
+ | `browser_get_local_storage` | Read localStorage |
71
+ | `browser_get_session_storage` | Read sessionStorage |
72
+ | `browser_get_cookies` | Read cookies |
73
+ | `browser_get_page_info` | URL, title, viewport, scroll position |
74
+ | `browser_execute_js` | Run arbitrary JS in the page |
75
+ | `browser_get_redux_state` | Redux store state |
76
+ | `browser_get_react_query_cache` | React Query cache |
77
+ | `browser_get_performance` | Page load timing, memory, resources |
78
+ | `browser_get_dom_snapshot` | DOM tree snapshot (CSS selector targeted) |
79
+ | `browser_list_connections` | List connected tabs |
80
+ | `browser_focus_tab` | Focus a specific tab for queries |
81
+ | `browser_clear_all` | Clear all event buffers |
82
+
83
+ ## Multi-Tab Support
84
+
85
+ Connect multiple browser tabs simultaneously. Use `browser_focus_tab` to switch which tab Claude is actively querying. The focused tab gets a blue badge; other connected tabs get a gray badge.
86
+
87
+ ## Configuration
88
+
89
+ Environment variables:
90
+
91
+ | Variable | Default | Description |
92
+ |----------|---------|-------------|
93
+ | `BROWSER_BRIDGE_PORT` | `8089` | WebSocket server port |
94
+ | `BROWSER_BRIDGE_HTTP_PORT` | `8090` | HTTP server port (serves client.js) |
95
+
96
+ Browser-side (set before client.js loads):
97
+
98
+ ```js
99
+ window.__BRIDGE_PORT = 8089; // WebSocket port
100
+ window.__BRIDGE_LABEL = "my-tab"; // Custom tab label
101
+ window.__BRIDGE_CAPTURE_BODIES = true; // Capture request/response bodies
102
+ window.__BRIDGE_MAX_BODY_SIZE = 10000; // Max body size in chars
103
+ ```
104
+
105
+ ## Framework Plugins
106
+
107
+ All plugins are **dev-only** and **no-op in production**.
108
+
109
+ ### Next.js
110
+
111
+ ```js
112
+ import { withBrowserBridge } from 'browser-bridge-mcp/next';
113
+ export default withBrowserBridge(nextConfig);
114
+ // Composes with other wrappers:
115
+ // export default withSentryConfig(withBrowserBridge(nextConfig), sentryOptions);
116
+ ```
117
+
118
+ ### Vite
119
+
120
+ ```js
121
+ import { browserBridge } from 'browser-bridge-mcp/vite';
122
+ export default defineConfig({ plugins: [browserBridge()] });
123
+ ```
124
+
125
+ ### Express / Connect
126
+
127
+ ```js
128
+ import { browserBridgeMiddleware } from 'browser-bridge-mcp/middleware';
129
+ app.use(browserBridgeMiddleware());
130
+ ```
131
+
132
+ ## CLI Commands
133
+
134
+ | Command | Description |
135
+ |---------|-------------|
136
+ | `npx browser-bridge-mcp setup` | Register MCP server with Claude Code |
137
+ | `npx browser-bridge-mcp setup --scope project` | Add to `.mcp.json` (team-wide) |
138
+ | `npx browser-bridge-mcp bookmarklet` | Generate bookmarklet HTML file |
139
+ | `npx browser-bridge-mcp snippet` | Print client.js to stdout |
140
+ | `npx browser-bridge-mcp serve` | Start server manually (debugging) |
141
+
142
+ ## License
143
+
144
+ MIT
package/bin/cli.mjs ADDED
@@ -0,0 +1,153 @@
1
+ #!/usr/bin/env node
2
+
3
+ /**
4
+ * Browser Bridge MCP — CLI
5
+ *
6
+ * Commands:
7
+ * setup Register MCP server with Claude Code (user scope)
8
+ * setup --scope project Register in .mcp.json (project scope, git-committed)
9
+ * bookmarklet Generate bookmarklet.html and open it
10
+ * snippet Print client.js to stdout for console paste
11
+ * serve Start the MCP server manually (for debugging)
12
+ * (default) Start MCP server via stdio (used by Claude Code)
13
+ */
14
+
15
+ import { execSync } from "child_process";
16
+ import { readFileSync, writeFileSync } from "fs";
17
+ import { fileURLToPath } from "url";
18
+ import { dirname, join } from "path";
19
+
20
+ const __dirname = dirname(fileURLToPath(import.meta.url));
21
+ const ROOT = join(__dirname, "..");
22
+ const CLIENT_PATH = join(ROOT, "src", "client.js");
23
+
24
+ const command = process.argv[2];
25
+
26
+ switch (command) {
27
+ case "setup":
28
+ setup();
29
+ break;
30
+ case "bookmarklet":
31
+ bookmarklet();
32
+ break;
33
+ case "snippet":
34
+ snippet();
35
+ break;
36
+ case "serve":
37
+ serve();
38
+ break;
39
+ default:
40
+ // Default: start the MCP server (this is what Claude Code invokes via stdio)
41
+ await import("../src/server.mjs");
42
+ break;
43
+ }
44
+
45
+ // ---------------------------------------------------------------------------
46
+ // Commands
47
+ // ---------------------------------------------------------------------------
48
+
49
+ function setup() {
50
+ const scopeFlag = process.argv.includes("--scope") && process.argv[process.argv.indexOf("--scope") + 1] === "project";
51
+
52
+ if (scopeFlag) {
53
+ // Project-scope: write .mcp.json
54
+ const mcpConfig = {
55
+ mcpServers: {
56
+ "browser-bridge": {
57
+ command: "npx",
58
+ args: ["-y", "browser-bridge-mcp"],
59
+ },
60
+ },
61
+ };
62
+
63
+ const mcpPath = join(process.cwd(), ".mcp.json");
64
+ let existing = {};
65
+ try {
66
+ existing = JSON.parse(readFileSync(mcpPath, "utf-8"));
67
+ } catch {
68
+ // File doesn't exist yet
69
+ }
70
+
71
+ existing.mcpServers = existing.mcpServers || {};
72
+ existing.mcpServers["browser-bridge"] = mcpConfig.mcpServers["browser-bridge"];
73
+
74
+ writeFileSync(mcpPath, JSON.stringify(existing, null, 2) + "\n");
75
+ console.log("✓ Added browser-bridge to .mcp.json (project scope)");
76
+ console.log(" Commit .mcp.json so your team gets it automatically.");
77
+ } else {
78
+ // User-scope: use claude mcp add
79
+ try {
80
+ execSync(
81
+ 'claude mcp add browser-bridge --transport stdio -- npx -y browser-bridge-mcp',
82
+ { stdio: "inherit" }
83
+ );
84
+ console.log("\n✓ Browser Bridge MCP registered with Claude Code");
85
+ console.log(" Restart Claude Code to activate.");
86
+ } catch (err) {
87
+ console.error("Failed to register MCP server. Is Claude Code CLI installed?");
88
+ console.error(" Try: npx browser-bridge-mcp setup --scope project");
89
+ process.exit(1);
90
+ }
91
+ }
92
+ }
93
+
94
+ function bookmarklet() {
95
+ const clientJs = readFileSync(CLIENT_PATH, "utf-8");
96
+
97
+ // Basic minification: remove comments and extra whitespace
98
+ const minified = clientJs
99
+ .replace(/\/\*[\s\S]*?\*\//g, "") // block comments
100
+ .replace(/\/\/.*$/gm, "") // line comments
101
+ .replace(/\n\s*\n/g, "\n") // empty lines
102
+ .replace(/^\s+/gm, "") // leading whitespace
103
+ .trim();
104
+
105
+ const bookmarkletUrl = `javascript:${encodeURIComponent(minified)}`;
106
+
107
+ const html = `<!DOCTYPE html>
108
+ <html><head><title>Browser Bridge Bookmarklet</title></head>
109
+ <body style="font-family:system-ui;max-width:600px;margin:40px auto;padding:20px;">
110
+ <h1>Browser Bridge</h1>
111
+ <p>Drag this link to your bookmarks bar:</p>
112
+ <p style="font-size:24px;padding:20px;background:#f0f0f0;border-radius:8px;text-align:center;">
113
+ <a href="${bookmarkletUrl}" style="color:#059669;text-decoration:none;font-weight:bold;">
114
+ Connect to Claude
115
+ </a>
116
+ </p>
117
+ <p style="color:#666;">Click it on any page to connect that tab to Claude Code's Browser Bridge.</p>
118
+ <h2>Or paste in console:</h2>
119
+ <pre style="background:#1e1e1e;color:#d4d4d4;padding:16px;border-radius:8px;overflow-x:auto;font-size:12px;max-height:300px;overflow-y:auto;">${clientJs.replace(/</g, "&lt;").replace(/>/g, "&gt;")}</pre>
120
+ </body></html>`;
121
+
122
+ const outPath = join(process.cwd(), "bookmarklet.html");
123
+ writeFileSync(outPath, html);
124
+ console.log(`✓ Bookmarklet written to ${outPath}`);
125
+ console.log(` (${bookmarkletUrl.length} characters)`);
126
+
127
+ // Try to open in browser
128
+ try {
129
+ const platform = process.platform;
130
+ if (platform === "darwin") {
131
+ execSync(`open "${outPath}"`);
132
+ } else if (platform === "linux") {
133
+ execSync(`xdg-open "${outPath}"`);
134
+ } else if (platform === "win32") {
135
+ execSync(`start "${outPath}"`);
136
+ }
137
+ } catch {
138
+ console.log(" Open bookmarklet.html in your browser to use it.");
139
+ }
140
+ }
141
+
142
+ function snippet() {
143
+ const clientJs = readFileSync(CLIENT_PATH, "utf-8");
144
+ process.stdout.write(clientJs);
145
+ }
146
+
147
+ async function serve() {
148
+ console.log("Starting Browser Bridge MCP server...");
149
+ console.log(" WebSocket: ws://127.0.0.1:8089");
150
+ console.log(" HTTP (client.js): http://127.0.0.1:8090/client.js");
151
+ console.log(" Press Ctrl+C to stop.\n");
152
+ await import("../src/server.mjs");
153
+ }
package/middleware.mjs ADDED
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Express/Connect middleware: browserBridgeMiddleware()
3
+ * Injects the browser bridge client script into HTML responses.
4
+ * For non-Next/Vite frameworks (Express, Fastify, etc.).
5
+ */
6
+ export function browserBridgeMiddleware(options = {}) {
7
+ const httpPort = options.httpPort || 8090;
8
+ return (req, res, next) => {
9
+ const originalEnd = res.end;
10
+ res.end = function (chunk, ...args) {
11
+ if (res.getHeader("content-type")?.includes("text/html") && chunk) {
12
+ const html = chunk.toString();
13
+ chunk = html.replace(
14
+ "</body>",
15
+ `<script src="http://127.0.0.1:${httpPort}/client.js" async></script></body>`
16
+ );
17
+ }
18
+ originalEnd.call(this, chunk, ...args);
19
+ };
20
+ next();
21
+ };
22
+ }
package/next.mjs ADDED
@@ -0,0 +1,40 @@
1
+ /**
2
+ * Next.js plugin: withBrowserBridge(nextConfig)
3
+ * Auto-injects the browser bridge client script in development mode.
4
+ * Complete no-op in production.
5
+ */
6
+ export function withBrowserBridge(nextConfig = {}, options = {}) {
7
+ if (process.env.NODE_ENV !== "development") return nextConfig;
8
+
9
+ const httpPort = options.httpPort || 8090;
10
+
11
+ return {
12
+ ...nextConfig,
13
+ webpack(config, ctx) {
14
+ // Only inject on client-side build
15
+ if (!ctx.isServer) {
16
+ const { BannerPlugin } = ctx.webpack;
17
+ config.plugins.push(
18
+ new BannerPlugin({
19
+ banner: `
20
+ if (typeof window !== 'undefined' && !window.__browserBridge) {
21
+ var s = document.createElement('script');
22
+ s.src = 'http://127.0.0.1:${httpPort}/client.js';
23
+ s.async = true;
24
+ s.onerror = function() { console.debug('[BrowserBridge] MCP server not running'); };
25
+ document.head.appendChild(s);
26
+ }
27
+ `,
28
+ raw: true,
29
+ entryOnly: true,
30
+ })
31
+ );
32
+ }
33
+ // Chain with user's webpack config if present
34
+ if (typeof nextConfig.webpack === "function") {
35
+ return nextConfig.webpack(config, ctx);
36
+ }
37
+ return config;
38
+ },
39
+ };
40
+ }
package/package.json ADDED
@@ -0,0 +1,52 @@
1
+ {
2
+ "name": "browser-bridge-mcp",
3
+ "version": "0.1.0",
4
+ "type": "module",
5
+ "description": "Give Claude Code direct access to your browser - console, network, errors, storage, DOM and more",
6
+ "author": "Mukesh Bishnoi <mukeshb.work@gmail.com>",
7
+ "bin": {
8
+ "browser-bridge-mcp": "./bin/cli.mjs"
9
+ },
10
+ "main": "./src/server.mjs",
11
+ "exports": {
12
+ ".": "./src/server.mjs",
13
+ "./next": "./next.mjs",
14
+ "./vite": "./vite.mjs",
15
+ "./middleware": "./middleware.mjs",
16
+ "./client": "./src/client.js"
17
+ },
18
+ "files": [
19
+ "bin/",
20
+ "src/",
21
+ "next.mjs",
22
+ "vite.mjs",
23
+ "middleware.mjs"
24
+ ],
25
+ "dependencies": {
26
+ "@modelcontextprotocol/sdk": "^1.12.1",
27
+ "ws": "^8.18.0",
28
+ "zod": "^3.24.0"
29
+ },
30
+ "keywords": [
31
+ "mcp",
32
+ "claude",
33
+ "claude-code",
34
+ "browser",
35
+ "devtools",
36
+ "debugging",
37
+ "console",
38
+ "network"
39
+ ],
40
+ "license": "MIT",
41
+ "engines": {
42
+ "node": ">=18"
43
+ },
44
+ "repository": {
45
+ "type": "git",
46
+ "url": "git+https://github.com/mukeshblackhat/browser-bridge-mcp.git"
47
+ },
48
+ "homepage": "https://github.com/mukeshblackhat/browser-bridge-mcp#readme",
49
+ "bugs": {
50
+ "url": "https://github.com/mukeshblackhat/browser-bridge-mcp/issues"
51
+ }
52
+ }