{
  "markdown": "# mac-control-mcp\n\n[![CI](https://github.com/AdelElo13/mac-control-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/AdelElo13/mac-control-mcp/actions/workflows/ci.yml)\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](LICENSE)\n[![Platform](https://img.shields.io/badge/platform-macOS%2014%2B-blue.svg)](#install)\n[![Notarized](https://img.shields.io/badge/signed-Developer%20ID%20%2B%20Notarized-success.svg)](#install)\n[![MCP Registry](https://img.shields.io/badge/MCP%20Registry-io.github.AdelElo13%2Fmac--control--mcp-7B68EE.svg)](https://registry.modelcontextprotocol.io/)\n\nNative Swift MCP server for full macOS automation. 63 tools in one signed `.app` bundle — no Python, no Node runtime, no Electron.\n\n<p align=\"center\">\n  <img src=\"docs/demo.gif\" width=\"720\" alt=\"mac-control-mcp driving Safari: open tab, type query, capture window, OCR, Spotlight search — all via MCP stdio\">\n</p>\n\nGives any MCP-compatible client (Claude Desktop, Claude Code, Cursor, etc.) the ability to:\n\n- Read and mutate the Accessibility tree of any running app\n- Drive Safari and Chrome (tabs, navigation, JS eval)\n- Capture the screen, a display, or a specific window (ScreenCaptureKit)\n- OCR what's on screen\n- Click, type, scroll, drag, send key events\n- Control windows (move / resize / fullscreen / minimize / main)\n- Manage the clipboard\n- Launch / activate / quit apps\n- Search Spotlight's index (NSMetadataQuery) and launch results\n- Toggle dark mode, volume, list displays, inspect menus\n\n## Install\n\nRequires macOS 14.0+. Three options, in order of simplicity:\n\n### 1. One-click install (Claude Desktop, recommended)\n\nThe server is published as an [MCP Bundle](https://github.com/anthropics/mcpb) — a zip with a `manifest.json` that Claude Desktop reads directly:\n\n1. Download [**mac-control-mcp-v0.2.6.mcpb**](https://github.com/AdelElo13/mac-control-mcp/releases/download/v0.2.6/mac-control-mcp-v0.2.6.mcpb) from the release page.\n2. Double-click the `.mcpb` file. Claude Desktop opens an install dialog.\n3. Click Install. The server is registered under the name `mac-control-mcp` and available immediately in new chats.\n4. First tool call triggers the macOS TCC consent prompts (Screen Recording, Accessibility, Apple Events). Grant all three once — the bundle is Developer-ID signed and notarized, so grants persist across updates.\n\nIt's also listed on the [official MCP Registry](https://registry.modelcontextprotocol.io/) as `io.github.AdelElo13/mac-control-mcp`, so any MCP client that supports the registry will find it by searching for \"mac-control\".\n\n### 2. Download the prebuilt app\n\nIf you don't use Claude Desktop or want manual control:\n\n1. Download [**MacControlMCP-v0.2.6-macos-universal.tar.gz**](https://github.com/AdelElo13/mac-control-mcp/releases/download/v0.2.6/MacControlMCP-v0.2.6-macos-universal.tar.gz).\n2. Extract and move `MacControlMCP.app` to `~/Applications/`.\n3. Point your MCP client at the binary inside:\n\n```json\n{\n  \"mcpServers\": {\n    \"mac-control-mcp\": {\n      \"type\": \"stdio\",\n      \"command\": \"/Users/you/Applications/MacControlMCP.app/Contents/MacOS/MacControlMCP\"\n    }\n  }\n}\n```\n\nAdd that block to `~/Library/Application Support/Claude/claude_desktop_config.json` (Claude Desktop) or `~/.claude.json` → `mcpServers` (Claude Code).\n\nVerify the download with the published SHA-256:\n\n```bash\nshasum -a 256 MacControlMCP-v0.2.6-macos-universal.tar.gz\n# should match MacControlMCP-v0.2.6-macos-universal.sha256 on the release\n```\n\n### 3. Build from source\n\nFor contributors or if you want to tweak the code. Requires Swift 6 / Xcode 16+:\n\n```bash\ngit clone https://github.com/AdelElo13/mac-control-mcp.git\ncd mac-control-mcp\n./scripts/build-bundle.sh\n```\n\nProduces `~/Applications/MacControlMCP.app/Contents/MacOS/MacControlMCP`. Without a Developer ID cert in your keychain it'll fall back to ad-hoc signing (works for local use, TCC grants reset on every rebuild).\n\nTo re-sign + re-notarise an existing Apple Developer account:\n\n```bash\n# one-time: store notary credentials in keychain\nxcrun notarytool store-credentials \"mac-control-mcp\" \\\n    --apple-id \"you@example.com\" --team-id \"XXXXXXXXXX\"\n\n# subsequent builds:\nNOTARIZE_PROFILE=mac-control-mcp ./scripts/build-bundle.sh\n```\n\n## Tool surface\n\n| Category | Tools |\n|---|---|\n| Permissions | `permissions_status`, `request_permissions` |\n| Accessibility | `find_element(s)`, `query_elements`, `list_elements`, `get_ui_tree`, `get_element_attributes`, `set_element_attribute`, `read_value`, `perform_element_action`, `wait_for_element`, `scroll_to_element` |\n| App lifecycle | `list_apps`, `launch_app`, `activate_app`, `quit_app`, `force_quit_app`, `wait_for_app`, `focused_app` |\n| Windows | `list_windows`, `focus_window`, `move_window`, `resize_window`, `set_window_state`, `wait_for_window`, `move_window_to_display` |\n| Input | `click`, `mouse_event`, `drag_and_drop`, `scroll`, `type_text`, `press_key`, `press_key_sequence`, `key_down`, `key_up`, `convert_coordinates` |\n| Menus | `click_menu_path`, `list_menu_paths`, `list_menu_titles` |\n| Browser | `browser_list_tabs`, `browser_get_active_tab`, `browser_navigate`, `browser_new_tab`, `browser_close_tab`, `browser_eval_js` |\n| Screen | `capture_screen`, `capture_window`, `capture_display`, `ocr_screen` |\n| Clipboard | `clipboard_read`, `clipboard_write`, `clipboard_clear` |\n| Spotlight | `spotlight_search`, `spotlight_open_result` |\n| System | `set_volume`, `set_dark_mode`, `list_displays` |\n| File dialogs | `file_dialog_set_path`, `file_dialog_select_item`, `file_dialog_confirm`, `file_dialog_cancel`, `wait_for_file_dialog` |\n\nTotal: **63 tools**.\n\n## Security model\n\n- Tools that write files (`capture_*`, `ocr_screen`) validate `output_path` via a strict allow-list — only the user-scoped temp dir (`NSTemporaryDirectory()`) and `~/Desktop`, `~/Documents`, `~/Downloads`, `~/Pictures` are accepted. Symlinks at the target path are rejected to prevent redirection. `/tmp` is deliberately excluded because it's shared across users and opens a TOCTOU window.\n- AppleScript string interpolation for `browser_eval_js` wraps user code in `(0, eval)(…)` via `JSON.stringify`, so quotes/newlines/unicode can't break out of the wrapper.\n- No network calls. Everything is local system integration.\n\n## Status (verified in the current release)\n\n| Scope | State |\n|---|---|\n| Unit / integration test suite | 63 tests in 11 suites, all green locally and on CI (macos-15) |\n| Live tool probe | 43 of the 63 tools exercised end-to-end via real MCP stdio against the running binary, all pass |\n| Destructive tools (volume, dark mode, force_quit_app, drag_and_drop, file_dialog_*) | Verified live in a reversible way |\n| Code signing | Developer ID Application (A3W973JZ49) with hardened runtime |\n| Apple notarization | Accepted by Apple Notary Service, ticket stapled, `spctl` reports `source=Notarized Developer ID` |\n| Gatekeeper flow | Extracted + launched with the `com.apple.quarantine` xattr set; no right-click-open needed |\n| MCP Registry | Published as `io.github.AdelElo13/mac-control-mcp` v0.2.6 — distributed as an `.mcpb` bundle for one-click install |\n| Architectures | Universal binary (arm64 + x86_64). Intel slice compiles cleanly but has not been runtime-verified on actual Intel hardware |\n| `move_window_to_display` | Skipped — requires a 2+ display setup |\n\nIf you run into an untested path, please open an issue with the reproduction — happy to fix fast.\n\n## Caveats\n\n- **Cross-origin iframes** block `browser_eval_js` — same-origin policy, not a limitation of the tool. Use AX coords or synthetic CGEvents for content inside embedded iframes from other origins.\n- **First-run TCC prompts are unavoidable.** macOS requires the user to grant Screen Recording, Accessibility and Apple Events the first time. The usage-description strings in `Info.plist` make the consent dialogs show up with a clear reason, but you still need to click Allow in System Settings once.\n\n## Development\n\n```bash\n# Run the test suite (63 tests in 11 suites)\nswift test\n\n# Build without packaging\nswift build -c release\n\n# Live probe the running binary via MCP stdio\npython3 scripts/mcp-sweep.py  # if included\n```\n\n## License\n\nMIT — see [LICENSE](LICENSE).\n\n## Contributing\n\nIssues and pull requests welcome. Adversarial reviews especially — prior releases went through 11 rounds of external review before shipping.\n",
  "bytes": 8394,
  "sha": "3bb3c6a936c860fc7014d6f951bf9e9972e5bff090050755c3adfb962ece45c8",
  "repo_slug": "adelelo13/mac-control-mcp",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_adelelo13_mac_control_mcp_4960bf41/readme"
}