Skip to main content
Glama
matthewdcage

macOS Automation MCP Server

by matthewdcage
README.md
# macOS Automation MCP Server

A comprehensive MCP (Model Context Protocol) server for macOS automation via AppleScript. This server provides **45 universal tools** for system control, application management, calendar, reminders, notifications, clipboard operations, and scheduled tasks.

Built with **FastMCP** and **Pydantic** for type-safe, production-ready operation.

## ✅ Verified Working

- macOS 26.1+ compatible
- All 45 tools registered and functional
- AppleScript execution engine tested
- Shell command safety validation active

## Features

### P0 - Essential Tools (12 System + 6 App + 3 Notification + 3 Clipboard = 24 tools)
- **System Control**: Volume, dark mode, display sleep, WiFi, text-to-speech, screenshots
- **Application Control**: Launch, quit, list, and manage running applications
- **Notifications**: Send notifications, alerts, and dialogs
- **Clipboard**: Read, write, and manage clipboard contents

### P1 - Extended Tools (6 Finder + 3 Calendar + 5 Reminders = 14 tools)
- **Finder Operations**: Create folders, move to trash, reveal files, search
- **Calendar Integration**: List, create, and manage calendar events
- **Reminders Integration**: List, create, complete, and manage reminders

### P2 - Advanced Tools (4 Script + 3 Scheduler = 7 tools)
- **Script Execution**: Run AppleScript and shell commands
- **Task Scheduler**: Create and manage launchd scheduled tasks

## Installation

### Prerequisites
- macOS 10.15 or later
- Python 3.10 or later
- [uv](https://github.com/astral-sh/uv) (recommended) or pip

### Install with uv (Recommended)

```bash
cd /path/to/mcp-applescript-automation
uv sync
```

### Install with pip

```bash
cd /path/to/mcp-applescript-automation
pip install -e .
```

## Configuration

### Claude Desktop / Cursor

Add to your MCP configuration file:

```json
{
  "mcpServers": {
    "macos-automation": {
      "command": "uv",
      "args": ["run", "--directory", "/path/to/mcp-applescript-automation", "python", "main.py"],
      "env": {}
    }
  }
}
```

### Minerva Platform

Add to `config/mcp-servers.json`:

```json
"macos-automation-mcp": {
  "command": "uv",
  "args": ["run", "--directory", "/Volumes/dev-4tb/AA-GitHub/MCP/mcp-applescript-automation", "python", "main.py"],
  "env": {},
  "description": "macOS Automation MCP: System control, app management, calendar, reminders, notifications, scheduled tasks via AppleScript"
}
```

## Permissions

This server requires certain macOS permissions to function:

1. **Automation Permission** (Required)
   - System Preferences > Privacy & Security > Privacy > Automation
   - Grant permission to your terminal app (Terminal, iTerm2, Cursor, etc.)

2. **Accessibility Permission** (For some UI automation)
   - System Preferences > Privacy & Security > Privacy > Accessibility
   - Required for advanced UI interactions

3. **Calendar/Reminders Access** (For calendar/reminder tools)
   - System Preferences > Privacy & Security > Privacy > Calendars/Reminders
   - Required for calendar and reminder management

## Available Tools (45 Total)

### System Control (12 tools)

| Tool | Description |
|------|-------------|
| `get_system_info` | Get macOS version, hostname, user, and uptime |
| `set_volume` | Set system volume (0-100) |
| `get_volume` | Get current volume level |
| `toggle_mute` | Toggle audio mute |
| `toggle_dark_mode` | Toggle dark/light mode |
| `set_dark_mode` | Set dark mode explicitly |
| `is_dark_mode` | Check if dark mode is enabled |
| `sleep_display` | Put display to sleep |
| `say_text` | Speak text using TTS |
| `take_screenshot` | Capture screenshot |
| `get_wifi_network` | Get current WiFi network |
| `toggle_wifi` | Enable/disable WiFi |

### Application Control (6 tools)

| Tool | Description |
|------|-------------|
| `list_running_apps` | List all running applications |
| `get_frontmost_app` | Get active application info |
| `launch_app` | Launch an application |
| `quit_app` | Quit an application |
| `hide_app` | Hide an application |
| `is_app_running` | Check if app is running |

### Notifications (3 tools)

| Tool | Description |
|------|-------------|
| `send_notification` | Send macOS notification |
| `send_alert` | Show alert dialog |
| `choose_from_list` | Show selection dialog |

### Clipboard (3 tools)

| Tool | Description |
|------|-------------|
| `get_clipboard` | Get clipboard text |
| `set_clipboard` | Copy text to clipboard |
| `clear_clipboard` | Clear clipboard |

### Finder (6 tools)

| Tool | Description |
|------|-------------|
| `reveal_in_finder` | Reveal file in Finder |
| `create_folder` | Create new folder |
| `move_to_trash` | Move items to Trash |
| `empty_trash` | Empty Trash |
| `get_selected_files` | Get Finder selection |
| `search_files` | Search using Spotlight |

### Calendar (3 tools)

| Tool | Description |
|------|-------------|
| `list_calendars` | List all calendars |
| `list_calendar_events` | List upcoming events |
| `create_calendar_event` | Create new event |

### Reminders (5 tools)

| Tool | Description |
|------|-------------|
| `list_reminder_lists` | List reminder lists |
| `list_reminders` | List reminders |
| `create_reminder` | Create new reminder |
| `complete_reminder` | Mark reminder complete |
| `get_overdue_reminders` | Get overdue items |

### Scripts (4 tools)

| Tool | Description |
|------|-------------|
| `run_applescript` | Execute AppleScript code |
| `run_shell_command` | Execute shell command (with safety checks) |
| `open_url` | Open URL in browser |
| `open_file` | Open file with app |

### Task Scheduler (3 tools)

| Tool | Description |
|------|-------------|
| `create_scheduled_task` | Create launchd task |
| `list_scheduled_tasks` | List managed tasks |
| `remove_scheduled_task` | Remove a task |

### Complete Tool List (Alphabetical)

```
choose_from_list, clear_clipboard, complete_reminder, create_calendar_event,
create_folder, create_reminder, create_scheduled_task, empty_trash,
get_clipboard, get_frontmost_app, get_overdue_reminders, get_selected_files,
get_system_info, get_volume, get_wifi_network, hide_app, is_app_running,
is_dark_mode, launch_app, list_calendar_events, list_calendars,
list_reminder_lists, list_reminders, list_running_apps, list_scheduled_tasks,
move_to_trash, open_file, open_url, quit_app, remove_scheduled_task,
reveal_in_finder, run_applescript, run_shell_command, say_text, search_files,
send_alert, send_notification, set_clipboard, set_dark_mode, set_volume,
sleep_display, take_screenshot, toggle_dark_mode, toggle_mute, toggle_wifi
```

## Example Usage

### Via Claude/Cursor

```
"Set my system volume to 50%"
"What applications are currently running?"
"Send me a notification with title 'Reminder' and message 'Check email'"
"Create a calendar event for tomorrow at 2pm called 'Team Meeting'"
"What's on my clipboard?"
```

### Via MCP Tool Calls

```python
# Set volume
result = await callMCPTool('macos-automation__set_volume', {'level': 50})

# Send notification
result = await callMCPTool('macos-automation__send_notification', {
    'title': 'Hello',
    'message': 'World'
})

# List running apps
result = await callMCPTool('macos-automation__list_running_apps', {})
```

## Security

### Shell Command Safety

The `run_shell_command` tool includes safety checks that block dangerous commands. Only whitelisted commands are allowed:

- System info: `sw_vers`, `uname`, `hostname`, `whoami`, etc.
- File info: `ls`, `pwd`, `stat`, `file`, etc.
- Network info: `networksetup`, `ifconfig`, etc.
- macOS utilities: `defaults`, `launchctl`, `open`, etc.

Dangerous patterns like `rm -rf /`, `sudo rm`, fork bombs, etc. are blocked.

### AppleScript Sandboxing

AppleScript execution respects macOS sandboxing and permission systems. Scripts cannot access protected resources without proper permissions.

## Development

### Running Tests

```bash
uv run pytest tests/ -v
```

### Verification

```bash
# Verify server loads correctly
cd /Volumes/dev-4tb/AA-GitHub/MCP/mcp-applescript-automation
uv run python -c "from macos_automation_mcp import mcp; print(f'Server: {mcp.name}')"

# List all registered tools
uv run python -c "
from macos_automation_mcp.server import mcp
tools = list(mcp._tool_manager._tools.keys())
print(f'Registered {len(tools)} tools')
for t in sorted(tools): print(f'  - {t}')
"

# Test basic functionality
uv run python -c "
from macos_automation_mcp.domains import system
result = system.get_system_info()
print(f'macOS: {result.get(\"macos_version\")}')
print(f'Host: {result.get(\"hostname\")}')
"
```

### Project Structure

```
mcp-applescript-automation/
├── macos_automation_mcp/
│   ├── __init__.py
│   ├── server.py              # FastMCP server with 45 tool definitions
│   ├── core/
│   │   ├── __init__.py
│   │   ├── applescript.py     # AppleScript execution engine (osascript)
│   │   ├── shell.py           # Safe shell command execution
│   │   └── scheduler.py       # launchd task integration
│   ├── domains/
│   │   ├── __init__.py
│   │   ├── system.py          # System controls (12 tools)
│   │   ├── applications.py    # Application control (6 tools)
│   │   ├── finder.py          # Finder operations (6 tools)
│   │   ├── calendar.py        # Calendar.app integration (3 tools)
│   │   ├── reminders.py       # Reminders.app integration (5 tools)
│   │   ├── notifications.py   # Notification Center (3 tools)
│   │   ├── clipboard.py       # Clipboard operations (3 tools)
│   │   └── scripts.py         # Script execution (4 tools)
│   └── models/
│       ├── __init__.py
│       └── schemas.py         # Pydantic models for type safety
├── tests/
│   ├── __init__.py
│   └── test_applescript.py    # Unit tests
├── main.py                    # Entry point
├── pyproject.toml             # Dependencies: mcp[cli], pydantic
├── uv.lock                    # Locked dependencies
└── README.md
```

### Dependencies

- **mcp[cli]>=1.0.0** - FastMCP framework with CLI support
- **pydantic>=2.0.0** - Type-safe data validation

## License

MIT License

## Contributing

Contributions are welcome! Please feel free to submit issues and pull requests.

## Acknowledgments

- Built using [FastMCP](https://github.com/jlowin/fastmcp)
- Inspired by [applescript-mcp](https://github.com/joshrutkowski/applescript-mcp)
- Uses the [Model Context Protocol](https://modelcontextprotocol.io/)

TDQS

B3.4/5.0

Scored across 45 tools

Disambiguation4/5

Most tools have clearly distinct purposes, and the descriptions help differentiate them. A few pairs like toggle_mute and set_volume, or set_dark_mode and toggle_dark_mode, have some functional overlap but remain distinguishable. Overall, an agent can reliably select the correct tool.

Naming Consistency5/5

Tool names consistently follow a verb_noun pattern in snake_case, such as get_volume, set_volume, toggle_mute, and create_calendar_event. Prefixes like get_, set_, toggle_, list_, create_, and is_ are used predictably across domains. This makes the API easy to navigate.

Tool Count2/5

With 45 tools, the server is excessively large for a single coherent MCP server. While the macOS automation scope is broad, many tools (e.g., calendar and reminder management) could be separated into focused servers. This volume overwhelms an agent's ability to efficiently select among them.

Completeness4/5

The server covers a wide range of macOS automation tasks including system controls, app management, file operations, calendar, reminders, and scripting. Minor gaps exist such as lack of file read/write operations or direct control of display brightness, but the core workflows are well-supported. Overall, the surface is fairly complete for its domain.

Maintenance

ActivityInactive
ResponsivenessNo issues