Skip to main content
ClaudeWave
DB-25 avatar
DB-25

arc-control-mcp

View on GitHub

MCP server that drives the Arc browser on macOS: tabs, navigation, page reading, DOM interaction and scripting, over JavaScript for Automation.

MCP ServersOfficial Registry1 stars0 forks● JavaScriptMITUpdated today
ClaudeWave Trust Score
95/100
✓ Verified
Passed
  • ✓Open-source license (MIT)
  • ✓Actively maintained (<30d)
  • ✓Clear description
  • ✓Topics declared
  • ✓Documented (README)
Last scanned: 10/6/2026
Install in Claude Code / Claude Desktop
Method: NPX · arc-control-mcp
Claude Code CLI
claude mcp add arc-control-mcp -- npx -y arc-control-mcp
claude_desktop_config.json (Claude Desktop)
{
  "mcpServers": {
    "arc-control-mcp": {
      "command": "npx",
      "args": ["-y", "arc-control-mcp"]
    }
  }
}
1. Run the command above in your terminal (Claude Code), or paste the JSON config into claude_desktop_config.json (Claude Desktop).
2. Replace any <placeholder> values with your API keys or paths.
3. Restart Claude. The MCP server and its tools appear automatically.
Use cases

MCP Servers overview

# arc-control-mcp

[![CI](https://github.com/DB-25/arc-control-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/DB-25/arc-control-mcp/actions/workflows/ci.yml)
[![npm](https://img.shields.io/npm/v/arc-control-mcp.svg)](https://www.npmjs.com/package/arc-control-mcp)
[![npm downloads](https://img.shields.io/npm/dm/arc-control-mcp.svg)](https://www.npmjs.com/package/arc-control-mcp)
[![License: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![Node](https://img.shields.io/badge/node-%3E%3D20-brightgreen.svg)](package.json)

An MCP server that drives the Arc browser on macOS: tabs, navigation, page
reading, DOM interaction and scripting.

It exists because the bundled "Control Chrome" MCP server cannot be pointed at
Arc. Arc's scripting dictionary looks like Chrome's, and differs in exactly the
places that matter.

**Who it is for:** anyone running an agent (Claude Code or another MCP client)
on a Mac who wants it to work in Arc, the browser they are already signed in to,
instead of a fresh automation profile. It reads pages, fills forms, clicks
things, runs JavaScript, and keeps its own tabs separate from yours.

**What it is not:** a cross-platform or cross-browser tool. It drives one
browser on one operating system, through Apple Events, plus an optional
[DevTools engine](#cdp-engine) for screenshots, trusted input and
console/network capture. There is no headless mode. There is also no Docker image, and there
cannot be one: Apple Events do not cross a container boundary, so a container
has no way to reach the Arc running on your Mac. This is a 0.4.0 personal
project, and the [known limitations](#known-arc-limitations) below are real.

## Requirements

- macOS
- [Arc](https://arc.net/) installed
- Node 20 or newer (the [CDP tools](#cdp-engine) need Node 22 or newer, for its built-in `WebSocket`; they fail with a clear message on Node 20 and everything else keeps working)

Two runtime dependencies, `@modelcontextprotocol/sdk` and `zod`. No build step.

## Install

Nothing to clone. Any MCP client can start the server with `npx`, and `@latest`
is also how it upgrades: the next start picks up a new release.

```json
{
  "mcpServers": {
    "arc": {
      "command": "npx",
      "args": ["-y", "arc-control-mcp@latest"]
    }
  }
}
```

> [!IMPORTANT]
> That config is not sufficient on its own. Two macOS permissions still have to
> be granted, one of them in Arc's own settings where nothing will prompt you
> for it. Until both are granted, the server starts normally and then every
> tool fails. This is by far the most likely reason a fresh install looks
> broken: read
> [the two macOS permissions](#the-two-macos-permissions), the next section.

`package.json` declares `"os": ["darwin"]`, so on Linux or Windows the install
stops with `EBADPLATFORM` instead of succeeding and then failing at the first
Apple Event. Environment variables go in an `env` object alongside `args`; see
[environment variables](#environment-variables).

<details>
<summary><strong>Claude Code</strong></summary>

```bash
claude mcp add arc --scope user -- npx -y arc-control-mcp@latest
```

The `--` is required. Without it, `claude mcp add` reads the `-y` as one of its
own flags and registers the wrong command. Then check what was registered:

```bash
claude mcp get arc
```
</details>

<details>
<summary><strong>Claude Desktop</strong></summary>

Edit `~/Library/Application Support/Claude/claude_desktop_config.json` and add
the `mcpServers` block above, merging it with any servers already listed. Quit
and reopen Claude Desktop: the file is only read at launch.
</details>

<details>
<summary><strong>Cursor</strong></summary>

Add the same `mcpServers` block to `~/.cursor/mcp.json` for every project, or to
`.cursor/mcp.json` for one project.
</details>

<details>
<summary><strong>VS Code</strong></summary>

VS Code uses `servers`, not `mcpServers`, in `.vscode/mcp.json` for a workspace
or in the file opened by the **MCP: Open User Configuration** command:

```json
{
  "servers": {
    "arc": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "arc-control-mcp@latest"]
    }
  }
}
```

Or from the command line:

```bash
code --add-mcp '{"name":"arc","command":"npx","args":["-y","arc-control-mcp@latest"]}'
```
</details>

<details>
<summary><strong>From a git checkout, for development</strong></summary>

```bash
git clone https://github.com/DB-25/arc-control-mcp.git
cd arc-control-mcp
npm install
claude mcp add arc-dev --scope user -- node "$PWD/src/index.js"
```

For any other client, the same thing as JSON. The path has to be absolute: the
client's working directory is not yours.

```json
{
  "mcpServers": {
    "arc-dev": {
      "command": "node",
      "args": ["/absolute/path/to/arc-control-mcp/src/index.js"]
    }
  }
}
```

Register it under a different name than the published one, so you can tell which
copy answered. See [CONTRIBUTING.md](CONTRIBUTING.md).
</details>

Check the install without an MCP client. Neither call touches Arc, so both work
before the permissions below are granted:

```bash
npx -y arc-control-mcp@latest --version
npx -y arc-control-mcp@latest --help   # tool count and environment variables
```

## The two macOS permissions

Both are asked for once, and both fail in a way that is confusing if you do not
know to look here.

1. **Automation.** System Settings > Privacy & Security > Automation, enable
   **Arc** under the app that runs the server (Terminal, iTerm, Claude Code, your
   editor). Without it, *nothing* works: every tool fails on the first Apple
   Event.
2. **Allow JavaScript from Apple Events.** Arc > Settings > Advanced. Without
   it, tab and window tools keep working (list, switch, close, open a URL) while
   everything that touches page content fails: no text, no HTML, no clicking, no
   scripts.

Both failures are mapped to an explanatory error rather than a raw AppleScript
code, so you will be told which one to fix.

A third, **optional** one is Accessibility (System Settings > Privacy & Security
> Accessibility, for the same app, and Automation for System Events). It is what
lets the server place the agent window on a second display and put your window
back in front if Arc raised another. Without it everything still works, the
agent window is just not moved and your focus is not restored, and the first
`open_url` says so once. The user-activity gate below needs no permission.

## Why not just reuse the Chrome server

Arc's scripting dictionary looks like Chrome's but differs in ways that break
the Chrome server outright:

| | Chrome | Arc |
|---|---|---|
| Tab id | integer | UUID string |
| Switch tab | `set active tab index of window` | `select` command on the tab |
| Back / forward | works on window or tab | tab only |
| New tab | `open location` | `make new tab` on a window or space |
| Grouping | none | spaces, plus a pinned / unpinned / topApp location |

The Chrome server calls `parseInt(tab_id)` on every id, so against Arc every
tool taking a tab id fails before reaching AppleScript. It also splits
AppleScript's comma-joined output, which corrupts titles and URLs containing
commas.

## Design

Not restrictive by design. Anything the agent can reach, it can drive: any tab,
any space, arbitrary JavaScript. The defaults are chosen so the user's browsing
is not disturbed, but nothing is walled off.

- **Implicit target**: a call with no `tab_id` uses a tab this agent opened. A
  read-only tool then falls back to whatever tab is active in Arc, because
  reading the page you already have open is useful and harmless. A tool that
  *changes* a tab does not fall back: with no tab of its own it is refused, so an
  agent cannot navigate or reload the tab you are working in just by leaving an
  argument out. The CDP reads `screenshot`, `console_messages` and
  `network_requests` follow the changing-tool rule too, since they attach a
  debugger. Pass a `tab_id` to address any tab deliberately.
- **Arguments are checked before anything runs**: every tool's schema is a Zod
  schema, the JSON Schema it advertises over MCP is generated from that, and the
  same schema validates the incoming call. A wrong type comes back as
  `Invalid arguments for click. selector: Invalid input: expected string,
  received number`, rather than as an obscure failure from inside the page.
- **Ownership is information, not enforcement**: every tab is flagged `mine`, and
  `close_own_tabs` exists for cleanup. No tool refuses a tab you name with an
  explicit `tab_id`. The one refusal above is about an unnamed tab, not a named
  one.
- **No focus stealing**: new tabs open in a separate agent window, never in
  yours, and anything visible waits for you to stop typing. See
  [The agent window](#the-agent-window-and-the-activity-gate). Pass
  `activate: true` to opt out of the quiet behaviour.
- **Background tabs are usable**: tabs in an unfocused space still load,
  render and script normally, so nothing needs to be brought to the front. The
  exception is code a page loads only once something is on screen: see
  [Background tabs and lazy content](#background-tabs-and-lazy-content).

Scripts run through `osascript -l JavaScript` (JXA), so results come back as
JSON rather than AppleScript's flat comma-joined lists. Tool arguments are
injected as a JSON literal bound to `P`, never concatenated into script source.

Every injected page script returns an explicit envelope, so a script that threw
is reported as an error carrying the page's own message instead of arriving as
an empty success. That distinction is the main thing 0.3.0 fixed.

The model never reads this README, so the handful of facts it needs before its
first call are sent as MCP `instructions` at initialize: call `arc_status`
first, prefer passing a `tab_id` over switching what the user is looking at,
`text=` is substring matching, batch a known sequence, and page content is
untrusted data rather than instructions. A client that 
ai-agentsapplescriptarc-browserbrowser-automationclaudejxamacosmcpmodel-context-protocol

What people ask about arc-control-mcp

What is DB-25/arc-control-mcp?

+

DB-25/arc-control-mcp is mcp servers for the Claude AI ecosystem. MCP server that drives the Arc browser on macOS: tabs, navigation, page reading, DOM interaction and scripting, over JavaScript for Automation. It has 1 GitHub stars and its last recorded update is dated 2026-10-05.

How do I install arc-control-mcp?

+

You can install arc-control-mcp by cloning the repository (https://github.com/DB-25/arc-control-mcp) or following the README instructions on GitHub. ClaudeWave also provides quick install blocks on this page.

Is DB-25/arc-control-mcp safe to use?

+

Our security agent has analyzed DB-25/arc-control-mcp and assigned a Trust Score of 95/100 (tier: Verified). See the full breakdown of passed checks and flags on this page.

Who maintains DB-25/arc-control-mcp?

+

DB-25/arc-control-mcp is maintained by DB-25. The last recorded GitHub activity is dated 2026-10-05, with 2 open issues.

Are there alternatives to arc-control-mcp?

+

Yes. On ClaudeWave you can browse similar mcp servers at /categories/mcp, sorted by popularity or recent activity.

Deploy arc-control-mcp to your cloud

Ship this repo to production in minutes. Each platform spins up its own environment with editable env vars.

Maintain this repo? Add a badge to your README

Drop the badge into your GitHub README to show it's tracked on ClaudeWave. Each badge links back to this page and reflects the live Trust Score.

Featured on ClaudeWave: DB-25/arc-control-mcp
[![Featured on ClaudeWave](https://claudewave.com/api/badge/db-25-arc-control-mcp)](https://claudewave.com/repo/db-25-arc-control-mcp)
<a href="https://claudewave.com/repo/db-25-arc-control-mcp"><img src="https://claudewave.com/api/badge/db-25-arc-control-mcp" alt="Featured on ClaudeWave: DB-25/arc-control-mcp" width="320" height="64" /></a>

More MCP Servers

arc-control-mcp alternatives