Skip to content

Quick Start

MCP Server (AI Agents)

The primary use case is connecting an AI agent to your Mac via MCP.

1. Build or Install

cargo install axterminator --features cli

2. Configure Your Agent

Add to your MCP config (Claude Code, OpenCode, Cursor):

{
  "mcpServers": {
    "axterminator": {
      "command": "axterminator",
      "args": ["mcp", "serve"]
    }
  }
}

3. Grant Permissions

Open System Settings > Privacy & Security > Accessibility and add your terminal app.

Your agent now has 19 core tools to control any macOS app.

CLI

# List apps
axterminator apps

# Find elements
axterminator find "Save" --app Safari

# Click elements
axterminator click "Save" --app Safari

# Element hierarchy
axterminator tree --app Finder

# Screenshots
axterminator screenshot --app Safari

# HTTP MCP transport
axterminator mcp serve --http 8080 --token secret

Python API

import axterminator as ax

# 1. Check permissions
if not ax.is_accessibility_enabled():
    print("Enable in System Settings > Privacy > Accessibility")
    exit(1)

# 2. Connect to an app
app = ax.app(name="Calculator")

# 3. Find and click elements (in BACKGROUND!)
app.find("7").click()
app.find("+").click()
app.find("3").click()
app.find("=").click()

# Result: 10

Background Testing

AXTerminator clicks in the background by default. Your active window stays focused while tests run!

Connection Methods

# By name
app = ax.app(name="Safari")

# By bundle ID (recommended for reliability)
app = ax.app(bundle_id="com.apple.Safari")

# By PID
app = ax.app(pid=12345)

Finding Elements

# By text/title
button = app.find("Save")

# With timeout
button = app.find("Save", timeout_ms=5000)

# By role
text_field = app.find("role:AXTextField")

# Combined
save_btn = app.find("role:AXButton title:Save")

Actions

# Background clicks (default)
element.click()
element.double_click()
element.right_click()

# Focus mode for text input
element.click(mode=ax.FOCUS)
element.type_text("Hello World!")

pytest Integration

import pytest

@pytest.mark.ax_requires_app("Calculator")
def test_addition(ax_app, ax_wait):
    app = ax_app("Calculator")
    app.find("7").click()
    app.find("+").click()
    app.find("3").click()
    app.find("=").click()
    ax_wait(0.1)

Available fixtures: ax_app, ax_wait, ax_calculator, ax_finder