Skip to main content
Pre-release

This release is a pre-release and may not be stable for production use.

AXPilot

The MCP server for macOS. AXPilot lets any AI agent see and operate the apps on your Mac, through the macOS Accessibility API first and screenshots second, with safety controls that are on by default.

CI Status: alpha PyPI Python 3.11+ macOS 14+ License: Apache-2.0

Claude Code uses AXPilot to type a checklist in TextEdit, make its title bold and centred from the Format menu, and turn the other lines into a bulleted list

A real recording on macOS 26: Claude Code (left) drives TextEdit (right) through AXPilot. Sped up in places; the speed is shown on screen.

Project status: alpha. The first alpha, 0.1.0a1, is on PyPI: uv tool install axpilot, then three commands to connect it. It is verified on macOS 26 on Apple silicon; macOS 14 and 15 and Intel Macs are not tested yet. Expect breaking changes until 1.0. See the roadmap.

Why AXPilot

  • Sees the UI the way macOS does. A compact text snapshot of the accessibility tree gives every button, field, list and menu a short ref (e1, e2, …), so agents act on elements instead of guessing pixels. Text-only and local models work; vision is optional.
  • Acts reliably. Each action tries the most robust strategy first (an Accessibility action), falls back to synthetic mouse and keyboard events, and returns a diff of what changed.
  • Scripts that outlive the session. Ask for a script and locate turns the elements an agent used into stable locators (the AXIdentifier first, then role and name), each checked to match exactly one element, plus a ready-to-run Python script.
  • Safe by default. Scripting is off, destructive actions need your confirmation, password managers and the Privacy & Security settings are off limits, secure fields are never read, and there is no telemetry.
  • Works with any MCP client or agent framework. Standard MCP over stdio or Streamable HTTP: Claude Desktop, Claude Code, Cursor, VS Code, Codex CLI, Gemini CLI, OpenAI Agents SDK, LangGraph, Pydantic AI and more.
  • Permissions that just work. A tiny frozen AXPilot.app launcher holds the macOS permissions, so you grant Accessibility once, to AXPilot, and every client can use it, across updates.

Electron apps too: VS Code

A Python script built from AXPilot locators sets up a fresh VS Code in real time: light theme, Auto Save, a new hello.py and an extension search, while each locator it uses lights up and a clock counts 18 seconds

A real recording on macOS 26 with AXPilot 0.1.0a1. Claude Code first drove a throwaway VS Code through AXPilot (light theme, Auto Save, a new file, an extension search); here a script built from AXPilot's locators replays that setup on a fresh VS Code, in real time.

Features

The feature set planned for 1.0. Every tool below is implemented and tested against the simulated desktop. On a real Mac (macOS 26), the perception and input tools are verified, including dropdowns, menus and dialogs; the app, system, scripting and browser tools, the kill switch and the on-screen indicator are not yet. The tool reference documents each one.

Area What you get
Perception Accessibility snapshots with refs, element search, element inspection, stable locators for automation scripts, diffs after every action, screenshots with a screenshot_id for coordinate mapping, Vision OCR, app/window/display lists
Actions Click, type (layout-independent), keyboard shortcuts (layout-aware), scroll, drag, set values, raw AX actions, menu-bar commands by path, forms, apps, windows, opening files and URLs
Safety Profiles and toolsets, app and window deny-lists, Terminal rule, secure-field protection, confirmations, rate limit, audit log, yield-to-user, kill switch, client pairing
Integrations Any MCP client; tested framework examples; an Agent Skill; a computer profile for vision-first loops; a Windows-MCP naming profile

How it works

 MCP clients and agent frameworks
 (Claude, Cursor, VS Code, Codex, OpenAI Agents SDK, LangGraph, …)
        │ spawn `axpilot stdio`                │ Streamable HTTP (`axpilot http`)
        ▼                                      │ 127.0.0.1 + bearer token
 ┌────────────────┐   Unix socket (0600)       │
 │ axpilot bridge │──────────────┐             │
 │ (no perms)     │              ▼             ▼
 └────────────────┘   ┌──────────────────────────────────────────┐
                      │ AXPilot.app: tiny frozen launcher        │
                      │   └─ Python host (child process)         │
                      │       ├ MCP server: tools and schemas    │
                      │       ├ Policy and safety layer          │
                      │       └ Engine: Accessibility, input,    │
                      │         ScreenCaptureKit, Vision OCR     │
                      └──────────────────────────────────────────┘
        macOS permissions (Accessibility, Screen Recording) → AXPilot.app

Spike S1 confirmed this design on macOS 26 (Apple silicon): the permission prompts name AXPilot, and one grant covers every client. Direct mode (axpilot stdio --direct) runs everything in one process instead; macOS then attributes permissions to whichever app started the server (your terminal, Claude, Cursor, …).

Install

Requirements: macOS 14 Sonoma or later, Apple silicon or Intel.

From PyPI (alpha)

You need uv (or pipx).

uv tool install axpilot          # or: pipx install axpilot
axpilot setup                    # installs ~/Applications/AXPilot.app and its runtime
axpilot connect claude-desktop   # or claude-code, cursor, vscode, … (see --list)
axpilot doctor                   # checks the installation

Restart your MCP client, then ask it to use AXPilot ("take a snapshot of Finder"):

  1. The first time a client connects, AXPilot asks you whether to allow it. Allow it.
  2. The first tool call makes macOS ask whether AXPilot may control your computer. Open System Settings, switch on AXPilot under Accessibility, and ask again; no restart is needed.
  3. Screenshots and OCR also need Screen Recording for AXPilot. macOS applies that grant only after AXPilot restarts: run killall AXPilot, then restart your MCP client.

Details and other channels: docs/install.md. Permissions explained: docs/permissions.md.

From source (contributors)

You need uv and the Xcode Command Line Tools (xcode-select --install), which build the launcher.

git clone https://github.com/vansh3503/Mac-Mcp.git axpilot
cd axpilot
uv sync
launcher/build.sh                      # builds launcher/build/AXPilot.app
uv run axpilot setup --dev-source .    # installs ~/Applications/AXPilot.app and its runtime
uv run axpilot connect claude-desktop  # or claude-code, cursor, vscode, … (see --list)
uv run axpilot doctor                  # checks the installation

A launcher you build yourself has a different code signature from the published one, so macOS asks for the permissions again when you switch between the two.

Other ways to run it, without the launcher:

uv run axpilot stdio --engine fake   # the simulated desktop (any OS, no permissions needed)
uv run axpilot stdio --direct        # direct mode: grant Accessibility to the app that starts it

axpilot stdio speaks MCP on stdin/stdout, so it waits for a client. To poke at it by hand, use the MCP Inspector: npx @modelcontextprotocol/inspector uv run axpilot stdio --engine fake.

Connect a client

Installed from PyPI

axpilot connect <client> writes the config for you (with a backup). The snippets it writes:

Claude Desktop, Cursor (~/.cursor/mcp.json) and most other clients:

{ "mcpServers": { "axpilot": { "command": "axpilot", "args": ["stdio"] } } }

(Claude Desktop needs the absolute path of axpilot, e.g. /Users/you/.local/bin/axpilot.)

Claude Code:

claude mcp add axpilot -- axpilot stdio

VS Code (.vscode/mcp.json in a workspace, or your user mcp.json):

{ "servers": { "axpilot": { "type": "stdio", "command": "axpilot", "args": ["stdio"] } } }

More clients (Windsurf, Zed, Codex CLI, Gemini CLI, LM Studio, Goose, Cline, Continue): docs/clients.md.

From a source checkout

In the clone, uv run axpilot connect <client> writes the client's config for you (with a backup), pointing it at the checkout's axpilot by absolute path. Restart the client afterwards. For direct mode, or to write the config by hand, see docs/clients.md.

Use it from an agent framework

Anything that speaks MCP works. Two examples (APIs as of writing; one for each of eleven frameworks is in examples/frameworks/):

OpenAI Agents SDK

from agents import Agent, Runner
from agents.mcp import MCPServerStdio

async with MCPServerStdio(params={"command": "axpilot", "args": ["stdio"]}, cache_tools_list=True) as mac:
    agent = Agent(
        name="Mac operator",
        instructions="Call snapshot before acting, act on element refs, and verify the result.",
        mcp_servers=[mac],
    )
    result = await Runner.run(agent, "Open Notes and create a note titled 'Groceries'")

LangChain / LangGraph

from langchain.agents import create_agent
from langchain_mcp_adapters.client import MultiServerMCPClient

client = MultiServerMCPClient({"axpilot": {"command": "axpilot", "args": ["stdio"], "transport": "stdio"}})
agent = create_agent("<your-model>", await client.get_tools())

More frameworks: docs/frameworks.md.

Tools

The 1.0 tool surface, implemented. Profiles pick a starting set: minimal (10 tools, for small or local models), standard (default), full, and computer (one vision-first computer tool). A windows-mcp naming exposes the same tools under Windows-MCP's names and parameters.

Toolset Tools Default
observe snapshot, screenshot, find, explore, read, inspect, locate, ocr, list_apps, list_windows, list_displays, wait_for, status on (read-only)
input click, type_text, press_keys, scroll, drag, move_mouse, set_value, select_option, perform_action, select_menu, fill_form, handle_dialog on
apps app, window, open on
system clipboard, notify, spotlight_search, system_info, system_control, processes clipboard on
scripting shell, applescript, shortcuts, defaults off
browser browser_tabs, browser_read, browser_eval_js off
computer computer computer profile only

Every tool has an input and output schema, MCP annotations (readOnlyHint, destructiveHint, …) and stable error codes such as STALE_REF, BLOCKED_BY_POLICY or USER_ACTIVE. Full reference, generated from the code: docs/tools.md.

Safety defaults

Control Default
Profile standard; scripting and browser toolsets off
Confirmations Required for destructive actions (shell, AppleScript, JS eval, running a shortcut, force quit, defaults write, process kill), showing the exact command
App deny-list Keychain Access, Passwords, 1Password, Bitwarden, LastPass, Dashlane, KeePassXC
Window deny-list The Privacy & Security pane of System Settings
Terminal rule Typing into Terminal, iTerm2, Ghostty, Warp and similar apps is blocked unless the shell tool is enabled
Secure fields Values never returned; typing refused unless allow_secure_fields = true
Rate limit 120 input actions per minute
Yield to user On: input pauses while you are using the mouse or keyboard
Audit log ~/Library/Logs/AXPilot/audit.jsonl, arguments redacted
Client pairing The host asks once per client app before it may connect
Kill switch, indicator ⌃⌥⌘P stops the agent (press again to resume); a frame and pill show while it acts (checked on macOS 26 in direct mode)
Telemetry None

Screen content is untrusted input for an agent. Read the security model before enabling scripting or browser. To report a vulnerability, see SECURITY.md.

How AXPilot compares

AXPilot is the macOS counterpart of Windows-MCP, with a tool surface (and an optional naming profile) that lets Windows-MCP prompts carry over. Other good projects in this space include MacOS-MCP (Python + PyObjC, the closest peer), Peekaboo (Swift), mcp-server-macos-use (Swift) and cua-driver. AXPilot's focus:

  1. Permissions that survive updates: a frozen launcher holds the grant for every client.
  2. Safety and privacy as the headline: no telemetry, pairing, kill switch, confirmations, audit.
  3. Spec-first MCP: schemas, annotations, structured output, deterministic tool order, stateless handles.
  4. Integration kit and evals: framework examples tested in CI, an Agent Skill, published eval results.

Roadmap

About 12 weeks to 1.0: v0.1 alpha (engine and core tools in direct mode; 0.1.0a1 is out), v0.2 beta (launcher, host app, safety), v0.3 public preview (one-line installer, connect for 12 clients, MCP Registry), v0.9 (full toolsets, OCR, frameworks, evals), then v1.0. Details and the open questions are in the project plan; decisions are recorded as ADRs.

Contributing

Contributions are welcome, and most of the code (server, policy, perception) runs and is tested on Linux. Start with CONTRIBUTING.md; AI coding agents should read AGENTS.md. Please follow the Code of Conduct.

License

Apache-2.0.

Acknowledgements

AXPilot is inspired by Windows-MCP by CursorTouch, whose tool design and install experience set the bar for desktop MCP servers. Thanks also to the authors of PyObjC, the MCP Python SDK and the projects listed above.

Thanks to Zeel Thakkar, who helped ship the 0.1.0a1 release to PyPI and is working on automating Electron apps with AXPilot, starting with the VS Code demo above.

"Mac" and "macOS" are trademarks of Apple Inc. Claude and Claude Code are trademarks of Anthropic. Other product and framework names mentioned here (such as Cursor, VS Code, LangChain and CrewAI) are trademarks of their respective owners and are used only to describe compatibility. AXPilot is an independent project and is not affiliated with or endorsed by any of them.

The demo video's voiceover was made with ElevenLabs and its music comes from the HeyGen audio library.

Metadata

Release files for axpilot 0.1.0a3

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for axpilot 0.1.0a3
File Size Uploaded Provenance Actions
axpilot-0.1.0a3.tar.gz 996.0 kB With provenance Details for axpilot-0.1.0a3.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for axpilot 0.1.0a3
File Interpreter ABI Platform Actions
axpilot-0.1.0a3-py3-none-macosx_14_0_universal2.whl Python 3 none macOS 14.0+ universal2 (ARM64, x86-64) Details for axpilot-0.1.0a3-py3-none-macosx_14_0_universal2.whl

Total release size: 1.7 MB

Release files / axpilot-0.1.0a3.tar.gz

Download URL axpilot-0.1.0a3.tar.gz
Size 996.0 kB
Tags Source
SHA-256 checksum
How to use checksums
44f81a72dc3f4b4868b3a9018b6693fc107e0027e464fb910abb28f920b0fa80
BLAKE2b-256 checksum
How to use checksums
331671d0ada9a71280b6953b3a56e2f7a94ebcc867640684f122cd4af9426201
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Release files / axpilot-0.1.0a3-py3-none-macosx_14_0_universal2.whl

Download URL axpilot-0.1.0a3-py3-none-macosx_14_0_universal2.whl
Size 727.3 kB
Tags Python 3 macOS 14.0+ universal2 (ARM64, x86-64)
SHA-256 checksum
How to use checksums
c391156f8ae60e36c052936083c3ffd579d1b5c56608d7e3a2038e9aa5f25836
BLAKE2b-256 checksum
How to use checksums
0c9befd15c8622acc991f7d8ae4c8f245d857069adc597e6f2fc1ac146a6f01b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

Security for axpilot 0.1.0a3

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for axpilot-0.1.0a3.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 24, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page