@cyanheads/macos-mcp-server
Control macOS system settings, apps, windows, audio, displays, screenshots, and Focus mode via MCP. STDIO or Streamable HTTP.
13 Tools • 3 Resources
macOS-only. This server controls the local macOS system — it requires the host machine to be running macOS. HTTP transport is supported for completeness, but the practical use case is stdio: run it locally and point your MCP client at it.
Overview
Control your Mac from an agent: launch, quit, and arrange apps and windows, switch audio and display devices, capture screenshots, work with Finder, send notifications, and toggle Focus mode.
Tools
| Tool | Description |
|---|
macos_get_info | System snapshot: battery level and charging status, power source, Wi-Fi association and network name, hostname, macOS version, uptime, and display count; a failed probe leaves its field null and named in unavailable |
macos_check_permissions | Reports Accessibility, Screen Recording, and Automation > Finder status for the calling process from Apple's prompt-free checks — null with a reason when a check can't tell |
macos_manage_apps | List running apps, get the frontmost app, launch, quit, force-quit, hide, or show applications |
macos_manage_windows | List, focus, move, resize, move_resize, minimize, fullscreen, or close windows across all visible apps |
macos_control_volume | Get or set system output volume (0–100) and mute state |
macos_control_audio | List audio devices, get current defaults, or switch the default input/output device |
macos_control_appearance | Get or set dark/light mode |
macos_control_system | Lock the screen or put the display to sleep |
macos_take_screenshot | Capture the main display, one display by display_index, a named app window, or a pixel region; saves a PNG without replacing existing files unless overwrite is true, optional JPEG preview |
macos_manage_displays | List connected displays (with each one's index) and the configured layout names, and apply a named display layout preset |
macos_send_notification | Post a notification to macOS Notification Center |
macos_manage_focus | Get or set Do Not Disturb / Focus mode |
macos_manage_finder | Frontmost path, current selection, reveal, open with app, or move to Trash |
Resources
| Resource | Description |
|---|
macos://system/info | Current macOS system snapshot: battery, power source, Wi-Fi association and network name, hostname, version, uptime, display count; a failed probe leaves its field null and named in unavailable |
macos://audio/devices | All audio input and output devices, including which is the current default. Requires SwitchAudioSource CLI. |
macos://displays | Connected display inventory including persistent IDs, index (the display_index macos_take_screenshot and macos_manage_windows use), type, resolution, origin, rotation, scaling, and enabled state. Requires displayplacer CLI. |
Resource data is also accessible via macos_get_info, macos_control_audio (action=list), and macos_manage_displays (action=list).
Capability reference
macos_get_info tool
- Battery level (0–100), charging state, and power source (
AC, Battery, UPS); null on desktops with no battery. charging is false when the battery is held at a charge limit (AC attached; not charging) and true while finishing charge
- Wi-Fi association from the Wi-Fi device's link state; the network name is
null while connected when macOS withholds it (reading it requires Location Services access for the host app). The name renders in content[] as a code span, so markdown characters in it read back as the name
- Hostname and uptime (from Node's
os module), macOS version string (e.g. "15.1")
- Connected display count (
0 on a headless Mac)
- A probe that fails leaves its field
null and names it in unavailable; nothing is filled in. battery: null with battery absent from unavailable means the Mac has no battery
- No permissions required
macos_check_permissions tool
- Reports Accessibility (every
macos_manage_windows action, list included; macos_manage_apps hide and show, and the window_title frontmost reads; the ⌃⌘Q keystroke macos_control_system lock sends before it falls back to the screen saver), Screen Recording (window screenshots), and Automation > Finder (macos_manage_finder frontmost_path, get_selection, and trash) from Apple's prompt-free checks: AXIsProcessTrusted, CGPreflightScreenCaptureAccess, and AEDeterminePermissionToAutomateTarget with prompting off
- Each field is
true, false, or null when the check can't tell; unknown_reasons names why each null is unknown. Automation > Finder reads null until macOS has asked for consent and while Finder isn't running. Notifications is always null: macOS has no prompt-free check for it
- Returns the calling process name (e.g.
"ghostty", "node") so you know which process to grant permissions for
- Read-only — no check sends an Apple event to another app, captures the screen, or can show a permission prompt
- Run this first when debugging why another tool is failing
macos_manage_apps tool
list — running user-facing apps with name, bundle ID, PID, visible, and frontmost flags
frontmost — name, bundle ID, PID, and frontmost window title of the active app
launch — open or activate by app_name or bundle_id; hidden=true starts in the background
quit (graceful AppleScript quit) vs. force_quit (SIGKILL, no save prompt)
hide / show — toggle visibility; requires Accessibility
quit, force_quit, hide, and show first check that the app is running — resolved by application name the way tell application does ("Visual Studio Code" finds the Code process), without launching it — and return not_running when it isn't
- Typed errors:
app_not_found (launch of an app that isn't installed), no_frontmost_app (System Events reports no frontmost process), not_running, accessibility_required
macos_manage_windows tool