Skip to main content
Glama
README.md
# mcp-mac-control

[![npm](https://img.shields.io/npm/v/@dockndevai/mcp-mac-control)](https://www.npmjs.com/package/@dockndevai/mcp-mac-control)
[![CI](https://github.com/dockndevai/mcp-mac-control/actions/workflows/ci.yml/badge.svg)](https://github.com/dockndevai/mcp-mac-control/actions/workflows/ci.yml)
[![licence](https://img.shields.io/badge/licence-MIT-blue)](LICENSE)

A [Model Context Protocol](https://modelcontextprotocol.io) server that gives an AI agent **full control of a Mac — like a person sitting at it**. Shell, AppleScript, files, processes, and **human-like GUI control**: move, click, double/right-click, **drag**, **scroll**, type, and press key combos — with a screenshot + window/screen-size perception loop.

> ⚠️ **This server is full-control by default.** It starts in `admin` mode with command execution, deletes, and GUI input all enabled. That is powerful and dangerous: anything the agent reads (a web page, an email, a file) could contain a prompt injection that then runs arbitrary code on your Mac. Only connect it to an agent and content you trust. Set **`MACCTL_SAFE_MODE=true`** to flip the whole thing to safe-by-default. If you want safe-by-default as the baseline, use the sibling [`@dockndevai/mcp-macos`](https://github.com/dockndevai/mcp-macos) instead.

Part of the [dockndevai MCP server suite](https://dockndevai.github.io/).

## What it gives an agent (26 tools)

**Perceive** — `screenshot`, `get_screen_size`, `list_windows`, `get_frontmost_app`, `list_apps`, `system_info`, `list_directory`, `read_file`, `list_processes`, `get_clipboard`

**Operate the desktop like a human** — `move_mouse`, `click` (left/right/double), `drag`, `scroll`, `type_text`, `key_press` (with ⌘/⌥/⌃/⇧), `activate_app`, `quit_app`, `open`, `set_clipboard`, `notify`, `write_file`

**Full power** — `run_command` (any program, no shell unless you ask for one), `run_applescript` (AppleScript/JXA — drive any scriptable app), `delete_path` (→ Trash), `kill_process`

The classic loop: `screenshot` → decide → `click`/`type`/`drag`/`scroll` → `screenshot` again.

## Install

```bash
npx -y @dockndevai/mcp-mac-control
```

macOS only. You'll need to grant the host app (Terminal, your IDE, Claude Desktop, …) macOS permissions the first time each capability is used:

- **Screen Recording** → for `screenshot`
- **Accessibility** → for GUI input (`click`, `type_text`, `drag`, `scroll`, `key_press`) and `list_windows`
- **Automation** → for AppleScript / app control
- Mouse control uses **cliclick**: `brew install cliclick`

## Configure (Claude Code)

```bash
claude mcp add mac-control -- npx -y @dockndevai/mcp-mac-control
```

That's it — it's full-control by default. To scope it down, add env flags (see below). See [docs/CLIENTS.md](docs/CLIENTS.md) for Claude Desktop / Cursor / Codex / VS Code / Windsurf, and [.env.example](.env.example) for every variable.

## Dialing the control up or down

Full control needs no configuration. Everything below is about **restricting** it:

| Variable | Default | Effect |
|---|---|---|
| `MACCTL_SAFE_MODE` | `false` | `true` → read-only, every power gated, confirmations on (safe-by-default) |
| `MACCTL_MODE` | `admin` | `read-only` / `read-write` / `admin` — caps which tools are registered |
| `MACCTL_ALLOW_EXEC` | `true` | shell / AppleScript / kill |
| `MACCTL_ALLOW_DELETE` | `true` | delete to Trash |
| `MACCTL_ALLOW_INPUT` | `true` | GUI input (mouse/keyboard) |
| `MACCTL_CONFIRM` | `false` | `true` → destructive ops pause for human approval via MCP elicitation |
| `MACCTL_PATH_ALLOWLIST` | (empty = anywhere) | confine file ops to these roots |
| `MACCTL_PROTECTED_PATHS` | (empty) | roots readable but never modified/deleted |
| `MACCTL_COMMAND_ALLOWLIST` | (empty = any) | restrict `run_command` to these programs |
| `MACCTL_DRY_RUN` | `false` | validate + log writes without executing |
| `MACCTL_AUDIT_LOG` | `true` | JSON audit line per guarded op, to stderr |

The policy engine ([`src/security.ts`](src/security.ts)) is the same graduated model as the rest of the suite — this server just ships it wide open by default. See [SECURITY.md](SECURITY.md).

## Developing

```bash
npm install
npm run build
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.js   # list tools
npm test
```

## Licence

MIT

TDQS

A4/5.0

Scored across 26 tools

Disambiguation5/5

Every tool targets a distinct action or resource: clipboard get/set, file read/write/delete, process list/kill, app management, UI input (click/drag/scroll/type/key), and system introspection. No two tools have overlapping purposes; even mouse actions are separated into move, click, drag, and scroll.

Naming Consistency4/5

Tool names uniformly use snake_case and mostly follow a verb_noun pattern (e.g., list_directory, read_file, activate_app). A few exceptions like system_info and screenshot are noun-like but still stylistically consistent and predictable.

Tool Count4/5

26 tools is on the higher end, but the server's broad purpose of controlling macOS justifies the count. The tool set covers file, process, app, UI, clipboard, and system domains without excessive redundancy, though it is heavier than typical servers.

Completeness4/5

The surface covers core macOS control operations: file lifecycle, process management, app control, clipboard, UI automation, and system info. Minor gaps like file rename/move or network configuration exist, but agents can work around them with run_command or AppleScript.

Maintenance

ActivityMaintained
ResponsivenessNo issues