# Arc Control (macOS) [Health: Active]

**Category:** 📂 Browser Automation  
**Repository:** https://github.com/DB-25/arc-control-mcp  
**GitHub Stars:** 2  
**npm Downloads (last month):** 156  
**Views:** 4  
**Installs:** 0  
**Upvotes:** 0  
**Directory Page:** https://allmcps.com/mcp/arc-control-macos

## Description
macOS-only MCP server for the Arc browser: tabs, navigation, page reading, DOM, scripting

## Tools
Capabilities this server exposes over MCP:

- **list_tabs** — Every tab, or narrow with `scope: "own"`, `query`, `space`, `window_id`. Rows are flagged `mine` and `isActive`.
- **get_current_tab** — The tab a call with no `tab_id` would act on.
- **switch_to_tab** — Make a tab active in its window. `activate` also brings Arc to the front. Waits for you to stop typing.
- **close_tab** — Close one tab.
- **close_own_tabs** — Close every tab this agent opened, leaving the user's alone. `include_stale` also closes tabs leaked by a dead previous run of the same label.
- **arc_status** — Arc's version and whether it is the frontmost app, owned tabs, the agent window (id, placement, display, minimized), whether Accessibility is available, your current idle time, whether the agent space exists, what a call with no `tab_id` resolves to (reported separately for read-only and for changi…
- **open_url** — Open a URL in the agent window, launching Arc if needed. Waits for you to stop typing, and reports `focusRestored` and `waitedForUserMs`. Options for `new_tab`, target `space`, `little_arc`, `activate`, `wait_until_loaded`.
- **go_back** — Move a tab through its history, verified by checking the URL actually changed.
- **reload_tab** — Reload a tab.
- **wait_for_load** — Poll until the document is ready, optionally until the URL contains a substring. Also reads Arc's `loading` flag (see [Loading tabs](#loading-tabs-and-stop_loading)), so a hung page shows up as `ready: "loading"` instead of a stalled call.
- **stop_loading** — Press the stop button on a tab that will not finish loading, which also unblocks every page tool on it.
- **get_page_content** — Visible text, whole page or every element matching a selector, joined. Always reports `matched`, so a partial answer is never silent, and flags truncation.
- **get_html** — Markup for the page or one element, outer or inner. Reports how many matched and takes `nth` to pick another.
- **query_elements** — Structured details per element: text, value, href, visibility, attributes. Reports `total` alongside `returned`. The main way to see what is on a page before acting.
- **get_links** — Links with text and resolved href, filterable by substring.
- **get_page_info** — Title, URL, ready state, meta description, a headings outline, and counts of links, forms, inputs, buttons and iframes. A cheap first look at an unfamiliar page.
- **snapshot** — The page as a compact tree of roles, accessible names and `[ref=e12]` refs. Options: `interactive_only`, `scope`, `depth`, `max_chars` (a cut is always reported), `boxes`, `diff`. See [Snapshots and refs](#snapshots-and-refs).
- **click** — Scroll into view and dispatch a real pointer sequence, so framework handlers fire. `nth` picks among matches. Waits for the DOM to settle and reports `settledMs`.
- **fill** — Set an input, textarea or contenteditable through the native setter, firing `input` and `change`. `submit: true` presses Enter afterwards. Also settles.
- **select_option** — Choose an option by value or visible label. Also settles.
- **press_key** — Dispatch a key press to an element or the focused element. Also settles.
- **scroll** — Scroll the page by direction and amount, or scroll one element into view.
- **wait_for_selector** — Poll until an element is `present`, `visible` or `absent`.
- **wait_for_text** — Poll until any of several strings, or a regex, appears in or disappears from the page's visible text or a scope selector.
- **fill_form** — Fill up to 50 fields in one call, each through the same checks as `fill`. Reports every field, is `ok: false` when any failed, and names which. Values are not echoed.
- **hover** — Send `pointerover`, `pointerenter`, `mouseover`, `mouseenter`, `pointermove` and `mousemove` at an element's center. Reports `coveredBy` like `click`. CSS `:hover` styles do not change: that is browser state a script cannot set.
- **type** — Type one character at a time (`keydown`, `keypress`, `beforeinput`, a native-setter append, `input`, `keyup`), for widgets that react to per-character events. Verifies the field afterwards: `ok: false` when characters did not go in, and the final value is reported (only its length for a password).…
- **capture_start** — Start recording console output, uncaught errors, unhandled rejections, and `fetch` and `XMLHttpRequest` calls (method, url, status, duration; never bodies or headers). Fails with `ok: false` when the page's CSP blocks it. See [Console and network capture](#console-and-network-capture).
- **capture_read** — Return what was recorded, oldest first, optionally clearing what it returned. Fails when no recorder is running rather than returning an empty list.
- **network_entries** — The page's requests from the browser's own resource timing. No recorder, so it works under any CSP, with the limits listed below.
- **list_spaces** — Spaces in the front window with tab counts, which is active, and `topAppCount` for the sidebar favourites that belong to no space.
- **focus_space** — Switch the front window to a space. Rarely needed: unfocused tabs are fully scriptable. Waits for you to stop typing.
- **execute_javascript** — Run JavaScript in a tab and return the result. Takes a bare expression or a statement body, validated before injection.
- **batch** — Run several tools in order in one call. `continue_on_error` keeps going past a failure.
- **sidebar_tree** — Every space with pinned items (folders nested) and unpinned tabs, plus top apps. Each tab has `id` (the `tab_id` `list_tabs` reports), `title`, `url`, `lastActiveAt`. `space`, `max_items`, `include_urls`, and `match_live` to mark each tab open or not.
- **find_stale_tabs** — Tabs idle for `days` (default 7), oldest first, with space and `pinned` / `unpinned` / `topApp`. Also reports exact duplicate URLs across the sidebar.
- **search_archive** — Search archived and closed tabs by text, newest first. `reason` narrows to `auto` or `manual`, `since_days` to a window.
- **search_history** — Search browsing history by text and time window. **Off unless `ARC_MCP_ALLOW_HISTORY=1`.

## Claude Desktop Quick Installation
Install path detected from listing signals. Uses `npx` (confidence: high):

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

## Documentation

## What Arc Control (macOS) does

Arc Control (macOS) MCP server gives an MCP client control of the Arc browser installed on the same Mac. It can enumerate tabs, identify the current tab, open URLs, move through history, reload pages, and close tabs. Ownership information lets an agent distinguish tabs it opened from tabs belonging to the user, while cleanup can remove the agent's tabs without closing the user's browsing session.

The server also exposes page-level operations. An agent can read visible text, inspect HTML, query elements and attributes, collect links, view page metadata, create accessibility-style snapshots, fill controls, click elements, select options, send key presses, scroll, hover, and wait for page state or text changes. It can record selected console, error, and request events, or inspect resource-timing entries without starting a recorder.

## How it works

Communication with Arc uses Apple Events and Arc's scripting interface. The server is designed around Arc's tab identifiers, tab selection behavior, spaces, and window model rather than Chrome's incompatible scripting assumptions.

Calls with no `tab_id` use an agent-owned tab when one is available. Read-only operations can fall back to Arc's active tab, while operations that change a tab require an owned tab unless the caller supplies an explicit identifier. This default reduces accidental navigation or reloads of the user's current page. Explicit tab IDs can target any tab.

Inputs are checked against schemas before execution. Page interactions wait for the DOM to settle where applicable, and loading, matching, truncation, and partial-result conditions are reported instead of being silently hidden.

## Setup and configuration

The Arc Control (macOS) MCP server runs only on macOS with Arc installed and Node.js 20 or later. The published package can be registered through `npx` using `arc-control-mcp@latest`; there is no build step. A source checkout can instead start `src/index.js` with Node and an absolute path.

Two permissions are required. In macOS Privacy & Security settings, enable Arc under Automation for the application that launches the MCP server. In Arc's Advanced settings, enable JavaScript from Apple Events. Without the first permission, tools fail at the Apple Event layer. Without the second, tab and window operations may work while page-content and interaction tools fail.

Accessibility is optional. It supports moving the agent window between displays and restoring focus when Arc takes it, but the server remains usable without it. The package declares macOS as its supported operating system, so Linux and Windows installations stop with a platform error.

## Tools and capabilities

- List, inspect, switch, open, reload, and close Arc tabs.
- Remove all tabs owned by the current agent, with an option for stale tabs from a previous run.
- Read visible text, HTML, links, page metadata, element details, and compact page snapshots.
- Click, fill, type, select options, press keys, scroll, hover, and fill multiple form fields.
- Wait for loading, selectors, text, or URL conditions; stop a page that remains loading.
- Capture console and request activity, or inspect browser resource-timing entries.

## Limitations and notes

The Arc Control (macOS) MCP server is not cross-platform, cross-browser, headless, or container-ready. Apple Events cannot reach an Arc process across a Docker boundary, so the project does not provide a Docker deployment. JavaScript-driven page tools depend on Arc's JavaScript-from-Apple-Events setting, and CDP tools require Node.js 22 or newer because they use the built-in `WebSocket` implementation.

The server is not an ownership sandbox. Ownership is reported and used for unnamed-target defaults and cleanup, but an explicitly supplied tab ID is not rejected solely because another user opened it. Visible operations generally wait for the user to stop typing, and callers can opt into activation where supported.

_Full upstream README: https://allmcps.com/mcp/arc-control-macos/readme_

