arc-cdp-mcp
# arc-cdp-mcp
An MCP server that gives [Claude Code](https://claude.com/claude-code) control of
**[Arc](https://arc.net)** — navigate, click, fill forms, screenshot, read console and
network traffic. It exists because the official "Claude in Chrome" extension does not
work in Arc.
It talks to Arc over the Chrome DevTools Protocol, skipping the extension layer entirely.
## Why the official extension fails in Arc
If you installed the Claude extension in Arc and nothing happens, here is what is actually
going on. The extension *is* installed and its native-messaging channel to Claude Code
*does* work — commands reach Arc. Two things break after that:
**1. The side panel.** The service worker checks for `chrome.sidePanel` and falls back to
a notification whose text is right there in the bundle:
> Claude requires the Chrome Side Panel API, which isn't available in this browser.
> Use Google Chrome, Microsoft Edge, or Brave.
Arc has the API schema compiled in, but its side panel is a custom implementation
(`ArcBrowserSidePanel`) that is not exposed to extensions.
**2. New tabs.** Arc's new tab is `chrome://start-page/<uuid>`, which isn't navigable from
an extension context — it fails with `ERR_INVALID_URL`. The tab-group handshake then hangs
waiting for a page that will never be ready.
Since Claude Code runs in the terminal, the side panel isn't the part you need — the
automation is. So this server drops the extension and speaks CDP to Arc directly.
## Requirements
macOS, Arc, Node 18+, and Claude Code.
## Install
```sh
git clone https://github.com/chmodami/arc-cdp-mcp
cd arc-cdp-mcp
npm install
claude mcp add arc-cdp --scope user -- node "$PWD/src/server.js"
```
Restart Claude Code — MCP servers load at session start.
## Running
Arc has to be launched with a debugging port. It must be **fully quit** first; the flag
only applies to a new process.
```sh
./arc-start.sh
```
The script quits Arc, relaunches it with `--remote-debugging-port=9222`, and waits for CDP
to answer. Opening Arc from the Dock afterwards won't carry the flag.
For a different port: `./arc-start.sh 9333`, and set `ARC_CDP_URL=http://127.0.0.1:9333`.
## Tools
| Tool | What it does |
| --- | --- |
| `arc_tabs` | List tabs with id, title, URL and `owned` |
| `arc_navigate` | Open a URL (reuse the active tab or open a new one) |
| `arc_close_tab` | Close a tab this server opened |
| `arc_screenshot` | PNG of the viewport or the full page |
| `arc_read_page` | Visible text plus every interactive element, each with a `ref` |
| `arc_click` | Click by `ref`, CSS selector, or visible text |
| `arc_type` | Fill a field, optionally pressing Enter |
| `arc_press` | Send a key |
| `arc_eval` | Run JS in the page |
| `arc_console` | Console output and page errors, regex-filterable |
| `arc_network` | HTTP responses, regex-filterable, `onlyErrors` for status >= 400 |
The intended loop is `arc_read_page` → take a `ref` → `arc_click`/`arc_type`, rather than
guessing CSS selectors. Refs are reassigned on every read, so read again after anything
that changes the DOM.
## Your tabs vs. the server's tabs
CDP can see **every** Arc tab, including your bank and your email. To keep an implicit
call from ever landing on one:
- Tabs this server opened are `owned: true`; tabs that already existed are `owned: false`.
- The active tab — used when `tabId` is omitted — is **always** an owned one.
- Targeting one of your tabs requires passing its `tabId` explicitly.
- `arc_close_tab` refuses to close a tab it doesn't own.
Be clear about what this is: a convention inside the server, not a sandbox. An explicit
`tabId` still reaches any tab. **CDP has no per-site permission model** — the official
extension's site-by-site approval is a real protection you give up here. Decide whether
that trade is right for you before installing.
## Teaching your agent to use it
The tools show up on their own, but Claude Code still sees the `mcp__claude-in-chrome__*`
tools and may reach for those first — they connect, accept commands, and then time out.
`skill/arc-browser.md` is a skill that tells the agent to use `arc_*` instead, along with
the read-then-act loop and the tab rules. Install it with:
```sh
mkdir -p ~/.claude/skills/arc-browser
sed "s|<REPO_PATH>|$PWD|g" skill/arc-browser.md > ~/.claude/skills/arc-browser/SKILL.md
```
## Limitations
- Arc must be launched with the flag. Without it, every tool returns an error telling you
how to relaunch.
- Tabs Arc has suspended have no renderer and stay invisible until they load.
- No side panel: this is automation only, not Claude chat inside the browser.
- macOS only, because `arc-start.sh` uses `open` and `osascript`.
## Prior art
[`arc-browser-mcp`](https://www.npmjs.com/package/arc-browser-mcp) also drives Arc, with an
AppleScript engine alongside CDP. Worth a look — it may fit you better.
## License
MIT
TDQS
Scored across 11 tools
Each tool has a clear, distinct purpose with no overlap: click, type, press, eval, console, network, read_page, tabs, navigate, close_tab, and screenshot cover separate actions. The names unambiguously indicate their functions.
All tools follow a uniform prefix 'arc_' with lowercase and underscores. While some are verbs (click, type, navigate) and some are nouns (console, network, tabs), the consistent format and clear action-oriented names make the set highly coherent.
With 11 tools, the set is well-scoped for browser automation. Each tool serves a necessary function, and the count falls comfortably within the ideal 3-15 range without feeling bloated or sparse.
The toolkit covers the core browser automation lifecycle: navigation, interaction (click, type, press), reading content (read_page, screenshot), debugging (console, network, eval), and tab management (tabs, close_tab). Missing features like refresh/back are minor and do not detract from overall completeness.