mac-mcp-server
Provides comprehensive tools for macOS automation, including system information retrieval, window and application management, input simulation, and UI element interaction via AppleScript and JXA.
Enables automation and control of the Safari web browser through macOS-level automation and accessibility frameworks.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@mac-mcp-server List all running apps and tell me my current battery level"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
mac-mcp-server
A macOS AppleScript MCP (Model Context Protocol) server that enables Claude Code and other AI assistants to automate macOS through AppleScript and JXA (JavaScript for Automation).
Overview
This MCP server provides 44 tools for comprehensive macOS automation, allowing AI assistants to:
Retrieve system information (hardware, battery, displays)
Manage applications (launch, quit, activate, list running apps)
Control windows (move, resize, focus, minimize)
Simulate keyboard and mouse input
Interact with UI elements via Accessibility APIs
Capture screenshots (auto-optimized for API compatibility)
Access clipboard and notifications
Control audio settings
Navigate menus and status bar items
The server communicates over stdio for seamless Claude Code integration and uses AppleScript/JXA for system automation.
Related MCP server: Automation MCP
Quick Start
Prerequisites
macOS 10.15 (Catalina) or later
Node.js 20.11.0 or later
Install from npm
npm install -g mac-mcp-serverConfigure Claude Code
Add the following to your Claude Code MCP configuration (~/.claude.json or Claude Desktop settings):
{
"mcpServers": {
"mac-mcp-server": {
"command": "npx",
"args": ["-y", "mac-mcp-server"]
}
}
}Restart Claude Code to load the MCP server.
Grant macOS Permissions
On first use, macOS will prompt you to grant required permissions. See the Permissions Guide below for details.
Tool Reference
System Information
Tool | Description |
| Retrieves macOS version, hardware model, processor, and memory |
| Gets battery percentage and charging status (MacBooks) |
| Lists connected displays with resolution information |
Audio Control
Tool | Description |
| Gets current system volume (0-100) |
| Sets system volume to specified percentage |
| Checks if system audio is muted |
| Mutes or unmutes system audio |
Clipboard and Notifications
Tool | Description |
| Reads current clipboard content (text, image, or files) |
| Sets clipboard to specified text |
| Displays a macOS notification with optional subtitle and sound |
Application Management
Tool | Description |
| Lists all running GUI applications with bundle IDs and PIDs |
| Launches an application by name |
| Gracefully quits an application |
| Brings an application to the foreground |
Finder Integration
Tool | Description |
| Opens Finder and selects the specified file or folder |
| Gets paths of currently selected files in Finder |
| Gets the path of the frontmost Finder window |
Window Management
Tool | Description |
| Lists all visible windows with position and size |
| Brings a specific window to the front |
| Moves a window to specified coordinates |
| Resizes a window to specified dimensions |
| Minimizes a window to the Dock |
Mouse Control
Tool | Description |
| Performs a mouse click (left, right, or middle button) |
| Performs a double-click |
| Moves the cursor without clicking |
| Performs a drag operation from start to end coordinates |
Keyboard Input
Tool | Description |
| Types text at the current cursor position |
| Presses a key by name (Enter, Tab, Escape, F1-F12, etc.) |
| Presses a focused-app/menu key combination (not guaranteed for OS-global hotkeys) |
Scroll and Navigation
Tool | Description |
| Scrolls in a specified direction (up, down, left, right) |
| Scrolls until a UI element becomes visible |
Screenshots
Tool | Description |
| Captures screen, display, window, or region as PNG/JPEG |
Screenshot Features:
Auto-resize: Screenshots are resized to max 1600px (configurable) for API compatibility
Auto-compress: File size limited to 1.8MB using JPEG compression when needed
Full resolution: Use
rawFile: truefor file output at full resolutionDisable processing: Set
maxDimension: 0andmaxFileSize: 0to disable all processing
UI Element Interaction
Tool | Description |
| Retrieves the UI element tree for an application |
| Clicks a UI element by path |
| Gets the value of a UI element |
| Sets the value of an editable UI element |
| Sets keyboard focus to a UI element |
Menu Bar Operations
Tool | Description |
| Gets the menu hierarchy for an application |
| Clicks a menu item by path (e.g., "File > Save") |
| Gets enabled/checked state of a menu item |
| Lists visible status bar items |
| Clicks a status bar item to open its menu |
| Clicks a menu item within a status bar menu |
| Gets complete menu bar hierarchy for a process |
macOS Permissions
This server requires specific macOS permissions to function. The first time you use certain tools, macOS will prompt you to grant access.
Required Permissions
1. Accessibility
Required for: Keyboard input, mouse control, UI element interaction, window management
Grant access:
Open System Settings > Privacy & Security > Accessibility
Click the + button and add your terminal app (Terminal, iTerm2, or Claude Code)
Toggle the switch to enable access
Restart your terminal after granting permission
Quick access:
open "x-apple.systempreferences:com.apple.preference.security?Privacy_Accessibility"2. Automation
Required for: Controlling other applications (Finder, Safari, etc.)
Grant access:
Open System Settings > Privacy & Security > Automation
Find your terminal app in the list
Enable checkboxes for target applications you want to control
If prompted during first use, click OK to allow
Quick access:
open "x-apple.systempreferences:com.apple.preference.security?Privacy_Automation"3. Screen Recording
Required for: Screenshots
Grant access:
Open System Settings > Privacy & Security > Screen Recording
Click the + button and add your terminal app
Toggle the switch to enable access
Restart your terminal after granting permission
Quick access:
open "x-apple.systempreferences:com.apple.preference.security?Privacy_ScreenCapture"Troubleshooting Permissions
Issue | Solution |
Permission added but not working | Restart your terminal app completely (Cmd+Q, then reopen) |
App not appearing in permission list | Run the operation once to trigger the permission dialog |
Permission still denied after granting | Remove the app from the list, restart, then re-add it |
All permission issues persist | Restart macOS |
"assistive access" error | Grant Accessibility permission specifically |
"-1743" error code | Grant Automation permission for the target app |
Screenshot returns black image | Grant Screen Recording permission and restart |
Permission Checklist
Before using mac-mcp-server, verify these permissions are granted:
Accessibility - Terminal/Claude Code added and enabled
Automation - Target apps enabled under your terminal
Screen Recording - Terminal/Claude Code added and enabled
App restarted after granting permissions
Usage Examples
System Information
// Get system info
await get_system_info({})
// Returns: { macOSVersion: "15.0", hardwareModel: "MacBook Pro", ... }
// Get battery status
await get_battery_status({})
// Returns: { percentage: 85, isCharging: true, isDesktop: false }Application Management
// List running applications
await list_running_apps({})
// Returns: [{ name: "Safari", bundleId: "com.apple.Safari", processId: 1234 }, ...]
// Launch an application
await launch_app({ name: 'Safari' })
// Quit an application
await quit_app({ name: 'Safari' })Window Management
// List all windows
await list_windows({})
// Focus a specific window
await focus_window({ appName: 'Finder', windowIndex: 1 })
// Move a window
await move_window({ appName: 'Finder', x: 100, y: 100 })
// Resize a window
await resize_window({ appName: 'Finder', width: 800, height: 600 })Keyboard and Mouse
// Type text
await type_text({ text: 'Hello, World!' })
// Press a key
await press_key({ key: 'enter' })
// Key combination (Cmd+C)
await key_combination({ modifiers: ['command'], key: 'c' })
// Note: key_combination uses AppleScript System Events. It is intended for
// focused-window shortcuts and app menu key equivalents, not OS-global hotkeys
// such as Electron globalShortcut/RegisterEventHotKey handlers. Prefer
// click_menu_item, click_status_bar_item, or an in-window shortcut for those.
// Click at coordinates
await click({ x: 500, y: 300 })
// Right-click
await click({ x: 500, y: 300, button: 'right' })
// Cmd+click
await click({ x: 500, y: 300, modifiers: ['command'] })Screenshots
// Capture full screen (auto-resized and compressed for API)
await take_screenshot({})
// Capture to file (also auto-processed by default)
await take_screenshot({ filePath: '/tmp/screenshot.png' })
// Capture at full resolution (no processing)
await take_screenshot({ filePath: '/tmp/full.png', rawFile: true })
// Capture specific region
await take_screenshot({
region: { x: 100, y: 100, width: 800, height: 600 },
})
// Custom compression settings
await take_screenshot({
maxDimension: 1920, // Max 1920px
maxFileSize: 1_000_000, // Max 1MB
quality: 70, // JPEG quality 70
})
// Disable all processing for base64 output
await take_screenshot({ maxDimension: 0, maxFileSize: 0 })UI Element Interaction
// Get UI element tree
await get_ui_elements({ appName: 'Safari', maxDepth: 3 })
// Click a button by path
await click_ui_element({
appName: 'Safari',
elementPath: 'window1/button1',
})
// Set text field value
await set_ui_element_value({
appName: 'TextEdit',
elementPath: 'window1/textfield1',
value: 'New text',
})Menu Operations
// List application menus
await list_menu_items({ appName: 'Finder' })
// Click a menu item
await click_menu_item({
appName: 'Finder',
menuPath: 'File > New Finder Window',
})
// Get menu item state
await get_menu_item_state({
appName: 'Finder',
menuPath: 'View > Show Path Bar',
})Installation from Source
For development or customization:
git clone https://github.com/laststance/mac-mcp-server.git
cd mac-mcp-server
pnpm install
pnpm buildThen configure Claude Code to use the local build:
{
"mcpServers": {
"mac-mcp-server": {
"command": "node",
"args": ["/path/to/mac-mcp-server/dist/index.js"]
}
}
}Development
Commands
Command | Description |
| Build for production |
| Development mode (watch) |
| Run tests |
| TypeScript type checking |
| Lint code |
| Lint and auto-fix |
| Format code with Prettier |
Project Structure
mac-mcp-server/
├── src/
│ ├── index.ts # Entry point, MCP server setup
│ ├── lib/
│ │ ├── server.ts # MCP server configuration
│ │ ├── executor.ts # AppleScript execution
│ │ ├── permission.ts # Permission checking and guidance
│ │ └── sanitizer.ts # Input sanitization
│ └── tools/
│ ├── system.ts # System information tools
│ ├── clipboard.ts # Clipboard management
│ ├── notification.ts # Notification display
│ ├── audio.ts # Audio control
│ ├── application.ts # Application lifecycle
│ ├── finder.ts # Finder integration
│ ├── window.ts # Window management
│ ├── mouse.ts # Mouse control
│ ├── keyboard.ts # Keyboard input
│ ├── scroll.ts # Scroll operations
│ ├── screenshot.ts # Screenshot capture
│ ├── ui-element.ts # UI element interaction
│ └── menu.ts # Menu bar operations
├── dist/ # Compiled output
├── package.json
└── tsconfig.jsonSecurity
This MCP server is designed with security in mind:
AppleScript-only execution: All automation is performed through AppleScript and JXA. No arbitrary shell commands are executed.
Input sanitization: All user inputs are sanitized before being included in AppleScript to prevent injection attacks.
No data persistence: The server does not store any user data or credentials.
Permission-gated access: All sensitive operations require explicit macOS permission grants.
Scoped automation: Each tool has a specific, limited purpose rather than providing general system access.
Requirements
Requirement | Version |
macOS | 10.15 (Catalina) or later |
Node.js | 20.11.0 or later |
pnpm | 10.28.0 (for development) |
License
MIT
Author
Contributing
Contributions are welcome. Please open an issue first to discuss what you would like to change.
Fork the repository
Create your feature branch (
git checkout -b feature/amazing-feature)Commit your changes (
git commit -m 'Add some amazing feature')Push to the branch (
git push origin feature/amazing-feature)Open a Pull Request
Available Tools
44 toolsactivate_appC
Brings an application to the foreground
Inputs: name (required).
clickB
Performs a mouse click at specified coordinates. Supports left, right, middle buttons and modifier keys
Inputs: x (required), y (required), button, modifiers.
click_status_bar_itemB
Clicks a status bar item to open its menu
Inputs: identifier (required).
click_ui_elementB
Clicks a UI element by path (e.g., "window1/button1")
Inputs: appName (required), elementPath (required).
double_clickB
Performs a double-click at specified coordinates
Inputs: x (required), y (required).
dragC
Performs a drag operation from start to end coordinates
Inputs: startX (required), startY (required), endX (required), endY (required).
focus_ui_elementB
Sets keyboard focus to a UI element
Inputs: appName (required), elementPath (required).
focus_windowB
Brings a specific window to the front by app name and optional window index
Inputs: appName (required), windowIndex, windowTitle.
get_battery_statusA
Gets battery percentage and charging status (MacBooks only, returns isDesktop: true for desktop Macs)
Inputs: no named parameters.
get_clipboardA
Reads current clipboard content (text, image paths, or file paths)
Inputs: no named parameters.
get_display_infoA
Lists connected displays with name, resolution, and main display indicator
Inputs: no named parameters.
get_finder_window_pathA
Gets the path of the frontmost Finder window
Inputs: no named parameters.
get_mute_statusA
Checks if system audio is currently muted
Inputs: no named parameters.
get_selected_filesA
Gets paths of files currently selected in Finder
Inputs: no named parameters.
get_system_infoA
Retrieves macOS system information including version, hardware model, processor, and memory
Inputs: no named parameters.
get_ui_elementsA
Retrieves the UI element tree for an application. Use maxDepth to limit tree depth
Inputs: appName (required), maxDepth.
get_ui_element_valueB
Gets the value of a UI element (text field content, checkbox state, etc.)
Inputs: appName (required), elementPath (required).
get_volumeA
Gets the current system volume as a percentage (0-100)
Inputs: no named parameters.
key_combinationA
Presses a focused-app or menu key combination with modifiers; OS-global hotkeys such as Electron globalShortcut are not guaranteed
Inputs: modifiers (required), key (required).
launch_appB
Launches an application by name (e.g., "Safari", "Finder")
Inputs: name (required).
list_running_appsA
Lists all running GUI applications with name, bundle ID, and process ID
Inputs: no named parameters.
list_status_bar_itemsB
Lists visible status bar (menu bar extras) items
Inputs: no named parameters.
list_windowsB
Lists all visible windows with app name, title, position, and size. Optional: filter by app name
Inputs: appName.
minimize_windowA
Minimizes a window to the Dock
Inputs: appName (required), windowIndex, windowTitle.
move_mouseA
Moves the mouse cursor to specified coordinates without clicking
Inputs: x (required), y (required).
move_windowB
Moves a window to specified x, y coordinates
Inputs: appName (required), x (required), y (required), windowIndex, +1 more.
press_keyB
Presses a key by name (Enter, Tab, Escape, F1-F12, Arrow keys, etc.)
Inputs: key (required), repeat.
quit_appA
Gracefully quits an application by name
Inputs: name (required).
resize_windowB
Resizes a window to specified width and height
Inputs: appName (required), width (required), height (required), windowIndex, +1 more.
reveal_in_finderB
Opens Finder and selects the specified file or folder
Inputs: path (required).
scrollA
Scrolls in a specified direction (up, down, left, right) at optional coordinates
Inputs: direction (required), amount, x, y.
scroll_to_elementC
Scrolls until a UI element with specified text or role becomes visible
Inputs: appName (required), elementPath (required).
send_notificationB
Displays a macOS notification with title, optional message, subtitle, and sound
Inputs: title (required), message (required), subtitle, sound.
set_clipboardB
Sets clipboard to specified text content
Inputs: text (required).
set_muteA
Mutes or unmutes system audio
Inputs: muted (required).
set_ui_element_valueB
Sets the value of an editable UI element (text fields, sliders, etc.)
Inputs: appName (required), elementPath (required), value (required).
set_volumeB
Sets the system volume to a specified percentage (0-100)
Inputs: value (required).
take_screenshotA
Captures a screenshot of the screen, display, window, or region. Auto-resized to max 1600px and compressed to max 1.8MB for API compatibility (both file and base64 output). Use rawFile: true to save at full resolution, or maxDimension/maxFileSize: 0 to disable processing
Inputs: display, windowId, region, format, +5 more.
type_textB
Types text at the current cursor position with optional delay between characters
Inputs: text (required), delay.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
Loading tool schema changelog…
TDQS
Scored across 44 tools
Most tools have distinct purposes, but the multiple click variants (click, click_menu_item, click_status_bar_item, etc.) and focus tools (focus_window, focus_ui_element) could cause slight confusion. Descriptions help differentiate them.
All tool names follow a consistent verb_noun pattern in snake_case, e.g., `launch_app`, `set_volume`, `take_screenshot`. No mixing of conventions.
44 tools is on the high side for a single server, covering a broad range of Mac automation tasks. While each tool serves a purpose, the count is borderline heavy and might benefit from consolidation.
The tool set covers core macOS automation areas: UI interaction, system info, app management, clipboard, notifications, and screenshots. Minor gaps exist (e.g., no AppleScript execution), but the surface is largely complete for its domain.
Maintenance
Related MCP Connectors
EXZA Remote — AI Computer Commander Your computer. Your control. Securely connect your own macOS, Windows or Linux computer to compatible AI clients, including ChatGPT and Claude. EXZA Remote provides 59 MCP tools for authorized file management, terminal operations, system monitoring, desktop automation and email workflows. GETTING STARTED 1. Create an EXZA Remote account. 2. Install the official computer connection client. 3. Pair your device using a temporary six-digit PIN. 4. Approve the connection on your computer. 5. Connect your preferred MCP client using EXZA OAuth. MCP ENDPOINT https://remote.exza.de/mcp TRANSPORT Streamable HTTP with OAuth 2.0 KEY FEATURES • 59 MCP tool interfaces • Secure computer and file access • Terminal commands and background jobs • File search, reading and editing • System monitoring and desktop automation • macOS, Windows and Linux support • Owner-controlled permissions and approvals COMPLETE INSTALLATION & DOCUMENTATION Detailed setup instructions, terminal installation commands, all 59 tools, troubleshooting and security information: https://github.com/exzade/EXZA-Remote/blob/main/docs/GLAMA_OVERVIEW.md Official website: https://remote.exza.de EXZA Remote is an independent, OAuth-protected service. Computer access requires individual account authorization and device-owner approval.
Connect AI assistants to your approved computer for files, commands, browser and desktop tasks.
- DNS-DATA RemoteDeprecatedcom.dns-data
Connect AI assistants to authorized Windows and macOS devices for files, commands, and management.
Use your Mac, Windows or Linux computer from ChatGPT, Claude or Codex: files, commands, documents.
Related MCP Servers
- AlicenseAqualityDmaintenanceProvides native macOS computer control tools including mouse and keyboard simulation, screenshot capture, and application management for MCP-compatible agents. It enables AI assistants to directly interact with the macOS operating system and installed apps through standard tool calls.2428 npm9MIT
- AlicenseNot gradedqualityDmaintenanceEnables AI assistants to automate macOS desktop tasks including mouse control, keyboard input, screenshots, window management, and UI interaction.10 npm415MIT
- FlicenseBqualityDmaintenanceEnables macOS automation through 45 AppleScript-powered tools for system control, app management, calendar, reminders, notifications, clipboard, and task scheduling.45-
- AlicenseAqualityDmaintenanceEnables AI agents to control macOS desktop apps via screenshots, mouse clicks, keyboard input, accessibility queries, and AppleScript.1112 npmMIT