Content
# astra-browser
Chrome extension + MCP server for real browser automation in [Claude Code](https://docs.anthropic.com/en/docs/claude-code).
> I got tired of using the claude in chrome extension. It was bad: went through sanitsation, didn't do multi-agent tab handling well, gets caught easily. I (claude) could do better. So I did.
Real Chrome. Real cookies. Real sessions. No Playwright. No Puppeteer. No sanitization. Your AI agent drives the same browser you use, with full access to your logged-in sessions.
## What it does
astra-browser gives Claude Code 30+ browser automation tools through the [Model Context Protocol](https://modelcontextprotocol.io/). The Chrome extension uses the debugger API (CDP) for low-level control and the scripting API for DOM interaction. A Node.js MCP server bridges Claude Code's stdio transport to the extension over WebSocket.
**Key features:**
- Real Chrome session (not headless, not sandboxed)
- Multi-agent tab isolation (multiple Claude agents can work in parallel)
- Iframe-aware (cross-origin iframes handled transparently)
- Auto-screenshot on error (diagnostic images in error responses)
- Plugin system (extend with your own tools)
## Quick Start
### 1. Clone and install
```bash
git clone https://github.com/astraedus/astra-browser.git
cd astra-browser
npm install
```
### 2. Load the Chrome extension
1. Open `chrome://extensions` in Chrome
2. Enable **Developer mode** (toggle in top right)
3. Click **Load unpacked**
4. Select the `extension/` directory from this repo
### 3. Add to Claude Code
Add to your Claude Code settings (`~/.claude/settings.json` or project `.claude/settings.json`):
```json
{
"mcpServers": {
"astra-browser": {
"command": "node",
"args": ["/absolute/path/to/astra-browser/server/index.js"]
}
}
}
```
### 4. Verify
In Claude Code, ask: *"Take a screenshot of my current browser tab"*
## Tools
### Navigation
| Tool | Description |
|------|-------------|
| `navigate` | Navigate to a URL |
| `screenshot` | Take a screenshot, optionally save to disk |
| `navigate_and_screenshot` | Navigate + screenshot in one call |
### Interaction
| Tool | Description |
|------|-------------|
| `click` | Click at coordinates or on an element ref |
| `click_text` | Click on text content (smart element finding) |
| `click_and_wait` | Click then wait for text or selector |
| `click_and_screenshot` | Click then screenshot |
| `type` | Type text into the focused element |
| `key_press` | Press a key (Enter, Tab, etc.) |
| `scroll` | Scroll the page |
| `scroll_to` | Scroll to a specific element |
| `hover` | Hover over an element |
| `drag` | Drag from one point to another |
### Page Reading
| Tool | Description |
|------|-------------|
| `read_page` | Get the accessibility tree (element refs for clicking) |
| `get_page_text` | Get all visible text content |
| `javascript` | Execute JavaScript in the page context |
| `find_element` | Search the accessibility tree by type/text |
### Forms
| Tool | Description |
|------|-------------|
| `form_input` | Fill a single form field (text, select, checkbox) |
| `fill_form` | Fill multiple fields in one call |
| `form_fill_and_submit` | Fill a form and submit it |
| `select_option` | Select a dropdown option |
| `file_upload` | Upload a file to a file input |
| `upload_image` | Upload an image from disk |
### Tabs
| Tool | Description |
|------|-------------|
| `session_start` | Start a new browser session (creates a dedicated tab) |
| `tabs_list` | List all open tabs |
| `tabs_create` | Create a new tab |
| `tabs_close` | Close a tab |
| `tabs_describe` | Label a tab for identification |
### Debugging
| Tool | Description |
|------|-------------|
| `read_console` | Read browser console output |
| `read_network` | Read network requests/responses |
| `wait_for` | Wait for text to appear on page |
| `wait_for_element` | Wait for a CSS selector to appear/disappear |
| `handle_dialog` | Accept or dismiss browser dialogs |
| `resize_window` | Resize the browser window |
| `health` | Check extension connection status |
| `reload_extension` | Reload the extension (fixes stuck states) |
## Multi-Agent Support
Multiple Claude Code agents can use the browser simultaneously. Each agent calls `session_start` to get its own tab, then passes the `tabId` to every subsequent tool call. A per-tab mutex in the extension serializes operations on the same tab while allowing different tabs to run in parallel.
```
Agent A: session_start(label: "research") -> tabId: 100
Agent B: session_start(label: "testing") -> tabId: 101
Agent A: navigate(url: "...", tabId: 100) // runs in parallel
Agent B: navigate(url: "...", tabId: 101) // with this
```
## Configuration
| Environment Variable | Default | Description |
|---------------------|---------|-------------|
| `ASTRA_BROWSER_PORT` | `7865` | WebSocket port for extension communication |
| `ASTRA_TAB_CONTEXT_PATH` | *(none)* | Path to persist tab metadata JSON (for cross-agent visibility) |
| `ASTRA_SCREENSHOT_DIR` | `~/Pictures/screenshots` | Where `screenshot` saves files when `filename` is provided |
## Plugins
astra-browser has a plugin system for adding custom tools. Drop a `.js` file (or a directory with `index.js`) into `plugins/` and it auto-loads at startup.
### Plugin contract
```js
// plugins/my-plugin.js
module.exports = function register(server, bridge, utils) {
const { z, call, fs, path, os } = utils;
server.tool(
'my_custom_tool',
'Description of what this tool does',
{
url: z.string().describe('The URL to process')
},
async ({ url }) => {
// Use call() to invoke extension-side tools
const result = await call('navigate', { url });
return result;
}
);
};
```
### Available in `utils`
| Name | Description |
|------|-------------|
| `z` | Zod schema library (for tool argument validation) |
| `call` | Helper to invoke extension-side tools through the bridge |
| `fs` | Node.js `fs` module |
| `path` | Node.js `path` module |
| `os` | Node.js `os` module |
See `plugins/example.js` for a minimal working plugin.
## Architecture
```
Claude Code <--stdio--> MCP Server <--WebSocket--> Chrome Extension <--CDP--> Page
(Node.js) (Service Worker)
port 7865 chrome.debugger API
```
- **Extension** (`extension/`): Chrome MV3 extension using ES modules. Service worker assembles tools from `tools/*.js` modules. Uses `chrome.debugger` (CDP) for screenshots, mouse/keyboard, JS eval. Uses `chrome.scripting` for DOM reads, form fills, accessibility tree.
- **Server** (`server/`): Node.js MCP server using `@modelcontextprotocol/sdk`. Bridges Claude Code's stdio transport to the extension's WebSocket. Handles tab tracking, plugin loading, and composite tools.
- **Iframe handling**: Transparent. `lib/frames.js` detects when targets are inside iframes and routes operations to the correct frame. Agents don't need to know about iframes.
## Troubleshooting
**Extension not connecting**
- Check that Chrome is running with the extension loaded
- Verify the WebSocket port matches (default: 7865)
- Try reloading the extension at `chrome://extensions`
**Tools timing out**
- Call the `health` tool to check connection status
- Use `reload_extension` to reset the extension state
**Screenshots are blank**
- The extension needs to be "attached" to the tab via CDP
- Navigate to any page first, then screenshot
**Content script errors**
- Call `reload_extension`, then retry
- Check `chrome://extensions` for error logs
## License
MIT
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
MarkItDown-MCP is a lightweight server for converting URIs to Markdown.
cc-switch
All-in-One Assistant for Claude Code, Codex & Gemini CLI across platforms.
servers
Model Context Protocol Servers
servers
Model Context Protocol Servers
Time
A Model Context Protocol server for time and timezone conversions.