loading…
Search for a command to run...
loading…
Enables AI agents to control the Google Chrome browser through a Node.js WebSocket bridge and a dedicated browser extension. It provides tools for capturing scr
Enables AI agents to control the Google Chrome browser through a Node.js WebSocket bridge and a dedicated browser extension. It provides tools for capturing screenshots, executing JavaScript, managing tabs, and extracting page content via the MCP protocol.
AI Agent controls Chrome browser via MCP protocol + Chrome Extension + WebSocket bridge
[AI Agent]
⇅ (MCP Tools via stdio)
[Node.js App — MCP Server + WebSocket Server]
⇅ (WebSocket on port 7890)
[Chrome Extension (Manifest V3)]
⇅ (chrome.* APIs)
[Browser Tabs]
capture_screenshot, execute_js) via the MCP protocol (stdio transport)requestId, and sends a JSON command over WebSocket to the Chrome ExtensionrequestId/chrome-extension-mcp
├── extension/ # Chrome Extension (Manifest V3)
│ ├── manifest.json # Extension manifest
│ ├── background.js # Service worker — WS client + action handlers
│ └── content.js # Content script (placeholder)
├── server/ # Node.js backend
│ ├── index.js # Entry point — starts WS + MCP servers
│ ├── wsServer.js # WebSocket server — client management + command dispatch
│ ├── mcpServer.js # MCP server — tool registration via @modelcontextprotocol/sdk
│ ├── cli.js # CLI tool for testing commands
│ ├── tools/ # MCP tool definitions
│ │ ├── captureScreenshot.js
│ │ ├── getHtml.js
│ │ ├── executeJs.js
│ │ ├── openTab.js
│ │ ├── listTabs.js
│ │ └── closeTab.js
│ └── package.json # Server dependencies
├── package.json # Root scripts
└── README.md # This file
| Tool | Description | Input |
|---|---|---|
capture_screenshot |
Capture a tab screenshot as base64 PNG | { tabId?, title? } |
get_html |
Get full HTML source of a page | { tabId? } |
execute_js |
Execute JavaScript in page context | { tabId?, script } |
open_tab |
Open a new browser tab | { url } |
list_tabs |
List all open tabs | {} |
close_tab |
Close a tab by ID | { tabId } |
| Action | Description | Payload |
|---|---|---|
focus_tab |
Focus/activate a tab | { tabId } |
get_text |
Extract visible text from a page | { tabId? } |
get_element |
Get element by CSS selector | { tabId?, selector } |
{
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"action": "capture_screenshot",
"payload": {
"tabId": 123
}
}
{
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"success": true,
"data": {
"tabId": 123,
"format": "png",
"base64": "iVBORw0KGgo..."
},
"error": null
}
{
"requestId": "550e8400-e29b-41d4-a716-446655440000",
"success": false,
"data": null,
"error": "No active tab found"
}
cd server
npm install
Or from the project root:
npm run install:server
The server runs two components simultaneously:
7890 (configurable via WS_PORT env var)cd server
node index.js
Or from the project root:
npm start
You should see:
[WS] WebSocket server attached to HTTP server
[Server] HTTP + WebSocket server listening on port 7890
[MCP] Server started on stdio transport
chrome://extensions/extension/ folder from this projectYou can verify the connection:
[MCP Extension] Connected to servercurl http://localhost:7890/health
Expected response:
{
"status": "ok",
"connectedClients": 1,
"clients": ["<client-uuid>"]
}
The CLI tool connects directly to the WebSocket server and sends commands to the extension.
# List all open tabs
cd server
node cli.js list_tabs
# Open a new tab
node cli.js open_tab '{"url":"https://www.google.com"}'
# Capture screenshot of active tab
node cli.js capture_screenshot
# Capture screenshot by tab title
node cli.js capture_screenshot '{"title":"Google"}'
# Get HTML of active tab
node cli.js get_html
# Execute JavaScript
node cli.js execute_js '{"script":"return document.title"}'
# Close a tab (use tabId from list_tabs)
node cli.js close_tab '{"tabId":123}'
# Get visible text
node cli.js get_text
# Get element by selector
node cli.js get_element '{"selector":"h1"}'
cd server
node cli.js
This starts a REPL where you can type commands:
mcp> list_tabs
mcp> open_tab {"url":"https://github.com"}
mcp> capture_screenshot {"title":"GitHub"}
mcp> execute_js {"script":"return document.title"}
mcp> exit
Configure your MCP client (e.g., Claude Desktop, Cursor, etc.) to use this server:
Add to your claude_desktop_config.json:
{
"mcpServers": {
"chrome-browser": {
"command": "node",
"args": ["/absolute/path/to/chrome-extension-mcp/server/index.js"],
"env": {
"WS_PORT": "7890"
}
}
}
}
Add to your .cursor/mcp.json:
{
"mcpServers": {
"chrome-browser": {
"command": "node",
"args": ["/absolute/path/to/chrome-extension-mcp/server/index.js"],
"env": {
"WS_PORT": "7890"
}
}
}
}
After configuration, the AI Agent will have access to all 6 MCP tools to control your Chrome browser.
| Variable | Default | Description |
|---|---|---|
WS_PORT |
7890 |
WebSocket + HTTP server port |
WS_URL |
ws://localhost:7890 |
WebSocket URL (CLI only) |
The WebSocket URL is hardcoded in extension/background.js:
const WS_URL = 'ws://localhost:7890';
Change this if your server runs on a different host/port.
localhost. The extension only connects to localhost.execute_js tool requires an explicit script parameter — the extension won't execute code without a proper request.requestId (UUID v4) to prevent response spoofing.clientId on connection.execute_js to a whitelist of allowed scripts"No Chrome extension clients connected""Request timed out after 30000ms""Failed to send command: ...""Unknown action: <action>""Missing required field: <field>""No tab found matching title: <title>"chrome://extensions/[MCP Extension]All server logs go to stderr (so they don't interfere with MCP stdio communication):
[WS] — WebSocket server events[MCP] — MCP server events[Server] — General server eventsserver/tools/ following the existing patternwsServer and returns { name, description, inputSchema, handler }server/mcpServer.jsextension/background.js| Problem | Solution |
|---|---|
| Extension won't connect | Make sure the server is running first (node server/index.js) |
| "No Chrome extension clients connected" | Check that the extension is loaded and the service worker is active |
| Screenshot returns error | Some pages (chrome://, file://) don't allow screenshots |
| execute_js fails | Some pages have CSP restrictions that block injected scripts |
| Service worker goes inactive | Chrome may suspend idle service workers; the auto-reconnect handles this |
| Port 7890 already in use | Change WS_PORT environment variable or kill the existing process |
MIT
Добавь это в claude_desktop_config.json и перезапусти Claude Desktop.
{
"mcpServers": {
"chrome-extension-mcp-bridge": {
"command": "npx",
"args": []
}
}
}