Skip to main content
Glama
mac-mcp-server

mac-mcp-server

mac-mcp-server

npm version License: MIT Node.js Version macOS

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-server

Configure 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

get_system_info

Retrieves macOS version, hardware model, processor, and memory

get_battery_status

Gets battery percentage and charging status (MacBooks)

get_display_info

Lists connected displays with resolution information

Audio Control

Tool

Description

get_volume

Gets current system volume (0-100)

set_volume

Sets system volume to specified percentage

get_mute_status

Checks if system audio is muted

set_mute

Mutes or unmutes system audio

Clipboard and Notifications

Tool

Description

get_clipboard

Reads current clipboard content (text, image, or files)

set_clipboard

Sets clipboard to specified text

send_notification

Displays a macOS notification with optional subtitle and sound

Application Management

Tool

Description

list_running_apps

Lists all running GUI applications with bundle IDs and PIDs

launch_app

Launches an application by name

quit_app

Gracefully quits an application

activate_app

Brings an application to the foreground

Finder Integration

Tool

Description

reveal_in_finder

Opens Finder and selects the specified file or folder

get_selected_files

Gets paths of currently selected files in Finder

get_finder_window_path

Gets the path of the frontmost Finder window

Window Management

Tool

Description

list_windows

Lists all visible windows with position and size

focus_window

Brings a specific window to the front

move_window

Moves a window to specified coordinates

resize_window

Resizes a window to specified dimensions

minimize_window

Minimizes a window to the Dock

Mouse Control

Tool

Description

click

Performs a mouse click (left, right, or middle button)

double_click

Performs a double-click

move_mouse

Moves the cursor without clicking

drag

Performs a drag operation from start to end coordinates

Keyboard Input

Tool

Description

type_text

Types text at the current cursor position

press_key

Presses a key by name (Enter, Tab, Escape, F1-F12, etc.)

key_combination

Presses a focused-app/menu key combination (not guaranteed for OS-global hotkeys)

Scroll and Navigation

Tool

Description

scroll

Scrolls in a specified direction (up, down, left, right)

scroll_to_element

Scrolls until a UI element becomes visible

Screenshots

Tool

Description

take_screenshot

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: true for file output at full resolution

  • Disable processing: Set maxDimension: 0 and maxFileSize: 0 to disable all processing

UI Element Interaction

Tool

Description

get_ui_elements

Retrieves the UI element tree for an application

click_ui_element

Clicks a UI element by path

get_ui_element_value

Gets the value of a UI element

set_ui_element_value

Sets the value of an editable UI element

focus_ui_element

Sets keyboard focus to a UI element

Menu Bar Operations

Tool

Description

list_menu_items

Gets the menu hierarchy for an application

click_menu_item

Clicks a menu item by path (e.g., "File > Save")

get_menu_item_state

Gets enabled/checked state of a menu item

list_status_bar_items

Lists visible status bar items

click_status_bar_item

Clicks a status bar item to open its menu

click_status_bar_menu_item

Clicks a menu item within a status bar menu

get_menu_bar_structure

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:

  1. Open System Settings > Privacy & Security > Accessibility

  2. Click the + button and add your terminal app (Terminal, iTerm2, or Claude Code)

  3. Toggle the switch to enable access

  4. 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:

  1. Open System Settings > Privacy & Security > Automation

  2. Find your terminal app in the list

  3. Enable checkboxes for target applications you want to control

  4. 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:

  1. Open System Settings > Privacy & Security > Screen Recording

  2. Click the + button and add your terminal app

  3. Toggle the switch to enable access

  4. 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 build

Then 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

pnpm build

Build for production

pnpm dev

Development mode (watch)

pnpm test

Run tests

pnpm typecheck

TypeScript type checking

pnpm lint

Lint code

pnpm lint:fix

Lint and auto-fix

pnpm format

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.json

Security

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

Laststance.io

Contributing

Contributions are welcome. Please open an issue first to discuss what you would like to change.

  1. Fork the repository

  2. Create your feature branch (git checkout -b feature/amazing-feature)

  3. Commit your changes (git commit -m 'Add some amazing feature')

  4. Push to the branch (git push origin feature/amazing-feature)

  5. Open a Pull Request

Available Tools

44 tools
activate_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_menu_itemB

Clicks a menu item by path (e.g., "File > Save", "Edit > Copy")

Inputs: appName (required), menuPath (required).

click_status_bar_itemB

Clicks a status bar item to open its menu

Inputs: identifier (required).

click_status_bar_menu_itemB

Clicks a menu item within a status bar menu

Inputs: identifier (required), menuPath (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_menu_bar_structureC

Gets the complete menu bar hierarchy for a process by PID

Inputs: processName (required).

get_menu_item_stateB

Gets the enabled/checked state of a menu item

Inputs: appName (required), menuPath (required).

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_menu_itemsC

Gets the menu hierarchy for an application

Inputs: appName (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

    B3.4/5.0

    Scored across 44 tools

    Disambiguation4/5

    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.

    Naming Consistency5/5

    All tool names follow a consistent verb_noun pattern in snake_case, e.g., `launch_app`, `set_volume`, `take_screenshot`. No mixing of conventions.

    Tool Count3/5

    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.

    Completeness4/5

    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

    ActivityStale
    ResponsivenessNo recent community issues

    Related MCP Connectors

    Related MCP Servers

    • A
      license
      A
      quality
      D
      maintenance
      Provides 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.
      24
      28 npm
      9
      MIT
    • A
      license
      Not graded
      quality
      D
      maintenance
      Enables AI assistants to automate macOS desktop tasks including mouse control, keyboard input, screenshots, window management, and UI interaction.
      10 npm
      415
      MIT
    • A
      license
      A
      quality
      D
      maintenance
      Enables AI agents to control macOS desktop apps via screenshots, mouse clicks, keyboard input, accessibility queries, and AppleScript.
      11
      12 npm
      MIT

    Appeared in Searches