# io.github.cyanheads/macos-mcp-server (npm · @cyanheads/macos-mcp-server)

Control macOS system settings, apps, windows, audio, displays, screenshots, and Focus mode via MCP.

- Trust score: 66/100 (medium)
- Change this week: +60
- Registry status: active
- Liveness: live
- Owner verified: no
- Last scored: 2026-08-07

## Components

- npm · `@cyanheads/macos-mcp-server`: 66/100 (this document), [markdown](https://verifymcp.io/servers/cyanheads-macos-mcp-server/cyanheads-macos-mcp-server.md), [page](https://verifymcp.io/servers/cyanheads-macos-mcp-server/cyanheads-macos-mcp-server)

## Channel facts

- Registry: `npm`
- Package: `@cyanheads/macos-mcp-server`
- Version: `0.1.4`
- Transport: `stdio`

## Trust breakdown

How this component scores in each security and reliability category. Every signal is checked automatically from public evidence about the published package, including repeated runs of it in an isolated sandbox, and we only credit what we can confirm. Scores are 0–100 per category. Scoring method: https://verifymcp.io/docs/scoring (what has changed: https://verifymcp.io/docs/scoring/changelog)

Scored 2026-08-07.

- **Supply Chain Security**: 86/100
  - No malware found by supply-chain analysis.
  - Known CVEs were checked across the 125 of 132 dependencies we could resolve, so this covers what we could see, not the whole tree.
  - No install/post-install scripts declared.
  - Dependency health was assessed across the 125 of 132 dependencies we could resolve, so this covers what we could see, not the whole tree.
- **Provenance & Transparency**: 45/100
  - Source repository is publicly reachable at the declared URL.
  - Provenance check failed: no build-provenance attestation is published.
  - Clear OSI-approved license (Apache-2.0).
  - Actively maintained (last published 55 days ago).
  - Disclosure check failed: no security disclosure policy was found in the source repository.
- **Schema Quality & AI Usability**: 82/100
  - 100% of prompts and resources have a non-trivial description (not blank, and not just the item's name).
  - AI-judged instruction clarity (excellent).
  - Context-footprint check failed: tool/resource definitions use about 2153 tokens (~134/item across 16 items; 13 tools + 3 resources), over budget; trim descriptions and params.
  - Usage-examples check failed: none of the tools include examples.
- **Stability & Change Management**: 0/100
  - Stability not yet verified: not enough scan history yet (needs a 30-day window).
- **Tool Coverage**: 100/100
  - 100% of tools have a non-trivial description (not blank, and not just the tool's name).
  - 100% of tool parameters carry a description.
  - Structured output schemas are declared (100% of tools); any adoption earns full credit.
- **Capabilities**: 100/100
  - Implements a supported MCP spec version (2025-11-25); the latest is 2026-07-28.

**Unverified: 1 category.** A category scored 0 because we could not verify it: a data source with nothing on this package, evidence we could not reach, or a check we could not run. We only credit what we can confirm.

## Install

### Claude

```bash
claude mcp add cyanheads-macos-mcp-server -- npx -y @cyanheads/macos-mcp-server
```

### Codex

```bash
codex mcp add cyanheads-macos-mcp-server -- npx -y @cyanheads/macos-mcp-server
```

### opencode

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "cyanheads-macos-mcp-server": {
      "type": "local",
      "command": [
        "npx",
        "-y",
        "@cyanheads/macos-mcp-server"
      ],
      "enabled": true
    }
  }
}
```

### OpenClaw

```bash
openclaw mcp add cyanheads-macos-mcp-server --command npx --arg -y --arg @cyanheads/macos-mcp-server
```

### Hermes

```yaml
mcp_servers:
  cyanheads-macos-mcp-server:
    command: "npx"
    args: ["-y", "@cyanheads/macos-mcp-server"]
```

### Other

```json
{
  "mcpServers": {
    "cyanheads-macos-mcp-server": {
      "command": "npx",
      "args": [
        "-y",
        "@cyanheads/macos-mcp-server"
      ]
    }
  }
}
```

## Changelog

Every change recorded for this component, newest first. Days that predate change tracking, or that we cannot explain, say so: "we were watching and nothing happened" and "we were not watching" are different claims.

### 2026-08-07 (score 66, 0)

- [functional regression] Security disclosure: unverified → fail

### 2026-08-06 (score 66, 0)

- [functional regression] Security disclosure: fail → unverified

### 2026-08-05 (score 66, +31)

- [security] Stability: Stability not yet verified: not enough scan history yet (needs a 30-day window).
- [functional improvement] Schema quality: unverified → 100
- [functional improvement] MCP protocol: unverified → pass
- [functional improvement] Tool coverage: unverified → 100
- [functional] First check of Tool coverage: 100
- [functional] First check of Tool coverage: 100
- [functional] First check of Schema quality: fail
- [functional] First check of Schema quality: excellent
- [functional] First check of Schema quality: fail

### 2026-08-03 (score 35, +30)

- [security regression] Provenance: unverified → fail
- [security improvement] Malware scan: unverified → pass
- [security improvement] Install scripts: unverified → pass
- [security improvement] Known CVEs: unverified → partial
- [security] Stability: Stability not yet verified: our sandbox run of this package did not complete, so we have no schema to compare.
- [functional improvement] Maintenance: unverified → pass
- [functional improvement] License: unverified → pass
- [functional improvement] Dependency health: unverified → partial
- [functional] Schema quality: Schema quality not yet verified: our sandbox run of this package did not complete, so we have no schema to assess.
- [functional] Capabilities: Protocol version not yet verified: our sandbox run of this package did not complete, so we never saw its MCP handshake.
- [functional] Tool coverage: Tool coverage not yet verified: our sandbox run of this package did not complete, so we have no tool definitions to assess.
- [functional] Licence: Apache-2.0

### 2026-08-02 (score 5, −15)

- [security regression] Malware scan: pass → unverified
- [security] Stability: Stability not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet.
- [functional] Tool coverage: Tool coverage not yet verified: we do not have a sandbox capture of the tool definitions this version of the package serves yet.
- [functional] Schema quality: Schema quality not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet.
- [functional] Capabilities: Protocol version not yet verified: we do not have a sandbox capture of the MCP handshake this version of the package performs yet.

### 2026-08-01 (score 20, +14)

- [functional] We updated how we score, so this day's move reflects our rubric, not a change to the server

### 2026-07-31 (score 6, −19)

- [security regression] Malware scan: pass → unverified
- [functional regression] Security disclosure: unverified → fail
- [functional regression] Dependency health: partial → unverified
- [functional] Tool coverage: Tool coverage not yet verified: our sandbox run of this package did not complete, so we have no tool definitions to assess.
- [functional] Schema quality: Schema quality not yet verified: our sandbox run of this package did not complete, so we have no schema to assess.

### 2026-07-29 (score 25, +1)

- [functional regression] Security disclosure: fail → unverified
- [functional improvement] Dependency health: unverified → partial
- [functional] Tool coverage: Tool coverage not yet verified: we do not have a sandbox capture of the tool definitions this version of the package serves yet.
- [functional] Schema quality: Schema quality not yet verified: we do not have a sandbox capture of the MCP schema this version of the package serves yet.

## MCP tools (13)

### `macos_get_info` (~67 tokens)

Get macOS System Info

Returns a snapshot of the current macOS system state: battery level and charging status, power source (AC/Battery), Wi-Fi SSID, hostname, macOS version, uptime in seconds, and connected display count. All fields reflect live system state at the time of the call.

Output parameters:

- `battery`: Battery info, or null on desktops with no battery.
- `display_count` (number): Number of currently connected displays.
- `hostname` (string): Machine hostname.
- `macos_version` (string): macOS product version string, e.g. "15.1.0".
- `uptime_seconds` (number): Seconds since last boot.
- `wifi` (object): Wi-Fi connection status.

### `macos_check_permissions` (~78 tokens)

Check macOS Permissions

Reports which macOS permissions relevant to this server are currently granted for the calling process: Accessibility (required for window manipulation, app hide/show), Screen Recording (required for window screenshots), Automation > Finder (required for Finder selection), and Notifications. Use this tool before attempting operations that require elevated permissions to confirm prerequisites without triggering an OS permission prompt.

Output parameters:

- `accessibility` (boolean): True when Accessibility permission is granted.
- `automation_finder` (boolean): True when Automation > Finder permission is granted.
- `calling_process` (string): Name of the process that launched this server (e.g. "ghostty", "node").
- `notifications` (boolean): True when notifications can be posted via osascript.
- `screen_recording` (boolean): True when Screen Recording permission is granted.

### `macos_manage_apps` (~189 tokens)

Manage macOS Apps

Manage application lifecycle: list all running user-facing apps, get the frontmost app, launch or activate an app, gracefully quit or force-quit a process, or hide/show an app. Launch activates the app if already running; use hidden=true to start in the background without bringing it forward. Force-quit terminates immediately (SIGKILL) without saving. Hide and show require Accessibility permission.

Input parameters:

- `action` (string, required): Operation to perform on the application.
- `app_name` (string): Application name, e.g. "Safari", "Visual Studio Code". Required for launch, quit, force_quit, hide, show.
- `bundle_id` (string): Bundle identifier, e.g. "com.apple.Safari". Alternative to app_name for launch.
- `hidden` (boolean): launch only: when true, start the app in the background without bringing it to the foreground.

Output parameters:

- `action` (string): The action that was performed.
- `app` (object): Frontmost application details. Present for action=frontmost.
- `app_name` (string): The application acted upon. Present for write actions.
- `apps` (array): Running user-facing applications. Present for action=list.
- `success` (boolean): True when the operation completed successfully. Present for write actions.

### `macos_control_volume` (~146 tokens)

Control macOS Volume

Get or set the system output volume level (0–100) and mute state. The get action returns the current level and mute state. The set action accepts level (0–100), muted (true/false), or both. Setting level=0 does not mute — use muted=true for explicit muting.

Input parameters:

- `action` (string, required): get returns current state; set applies provided level and/or muted values.
- `level` (number): Output volume level from 0 (silent) to 100 (maximum). Only used with action=set.
- `muted` (boolean): Mute state. true=mute output, false=unmute. Only used with action=set.

Output parameters:

- `level` (number): Current output volume level (0–100).
- `muted` (boolean): True when the output is currently muted.

### `macos_send_notification` (~130 tokens)

Send macOS Notification

Post a notification to macOS Notification Center via osascript. The notification appears immediately and uses the calling process's notification settings. Title is required; body, subtitle, and sound are optional. Each call creates a new notification (not idempotent). Do Not Disturb does not suppress notifications sent via osascript.

Input parameters:

- `body` (string): Notification body text.
- `sound` (boolean): When true, plays the default notification sound. Defaults to false.
- `subtitle` (string): Notification subtitle (appears below the title).
- `title` (string, required): Notification title (required).

Output parameters:

- `success` (boolean): True when the notification was posted successfully.

### `macos_control_appearance` (~111 tokens)

Control macOS Appearance

Get or set the system appearance (dark mode or light mode). The get action returns the current mode. The set action accepts mode="dark", "light", or "toggle". Setting "dark" or "light" is idempotent — calling twice produces the same state. "toggle" flips the current mode on each call.

Input parameters:

- `action` (string, required): get returns the current appearance; set applies the specified mode.
- `mode` (string): Target appearance mode. Required for action=set.

Output parameters:

- `dark_mode` (boolean): True when dark mode is currently active.

### `macos_control_system` (~86 tokens)

Control macOS System

System-level power controls: lock the screen (⌃⌘Q shortcut via Accessibility; falls back to ScreenSaverEngine binary if Accessibility is not granted) or put the display to sleep immediately. Both operations are immediate and user-reversible (wake/unlock with any input).

Input parameters:

- `action` (string, required): lock — lock the screen immediately. sleep_display — turn off all displays.

Output parameters:

- `action` (string): The action that was performed.
- `success` (boolean): True when the operation completed.

### `macos_manage_windows` (~232 tokens)

Manage macOS Windows

Window operations across all visible apps: list all windows with their bounds, focus an app window, move or resize a window, minimize/restore, toggle fullscreen, or close. List and focus do not require Accessibility; all other operations do. When app_name and window_title are both given, window_title takes precedence.

Input parameters:

- `action` (string, required): Operation to perform.
- `app_name` (string): Target application name. Targets the frontmost window of this app.
- `fullscreen` (boolean): For fullscreen: true=enter fullscreen, false=exit fullscreen.
- `height` (number): Window height in pixels for resize/move_resize.
- `minimized` (boolean): For minimize: true=minimize, false=restore from Dock.
- `width` (number): Window width in pixels for resize/move_resize.
- `window_title` (string): Exact window title. Takes precedence over app_name when both are provided.
- `x` (number): Left edge x-coordinate for move/move_resize. Screen coordinates.
- `y` (number): Top edge y-coordinate for move/move_resize. Screen coordinates.

Output parameters:

- `action` (string): The action that was performed.
- `success` (boolean): True when the operation completed. Present for write actions.
- `window` (object): Window state after the operation. Present for write actions.
- `windows` (array): All visible windows across all apps. Present for action=list.

### `macos_control_audio` (~158 tokens)

Control macOS Audio Routing

Manage audio device routing: list all input and output devices, get the current default input and output devices, or switch the default input or output device. Device names support case-insensitive partial matching — "MacBook" matches "MacBook Pro Microphone". Volume level control is separate (use macos_control_volume). Requires SwitchAudioSource CLI (brew install switchaudio-osx).

Input parameters:

- `action` (string, required): list — all devices; current — default input and output; switch_output/switch_input — change the default device.
- `device` (string): Partial or full device name for switch_output/switch_input. Case-insensitive substring match.
- `type` (string): Filter by device type for action=list. Defaults to "all".

Output parameters:

- `action` (string): The action that was performed.
- `device` (object): The device that is now the default. Present for switch actions.
- `devices` (array): All audio devices matching the type filter. Present for action=list.
- `input` (object): Current default input device. Present for action=current.
- `output` (object): Current default output device. Present for action=current.
- `success` (boolean): True when the switch completed. Present for switch actions.

### `macos_manage_displays` (~155 tokens)

Manage macOS Displays

List connected displays with their current layout (resolution, position, rotation, scaling) and optionally apply a pre-configured display layout by name. Requires displayplacer CLI (brew install jakehilborn/jakehilborn/displayplacer). Layouts are pre-configured in the MACOS_DISPLAY_LAYOUTS environment variable as a JSON object mapping names to displayplacer argument strings. Layout application only accepts named presets — raw displayplacer args are never accepted from the user.

Input parameters:

- `action` (string, required): list — enumerate connected displays; apply_layout — activate a saved layout.
- `layout_name` (string): Name of the display layout to apply. Must match a key in MACOS_DISPLAY_LAYOUTS. Required for action=apply_layout.

Output parameters:

- `action` (string): The action that was performed.
- `current_config` (string): The current displayplacer command that would reproduce the active arrangement. Present for action=list.
- `displays` (array): Connected display inventory. Present for action=list.
- `layout_name` (string): Name of the layout that was applied. Present for action=apply_layout.
- `success` (boolean): True when the layout was applied. Present for action=apply_layout.

### `macos_take_screenshot` (~276 tokens)

Take macOS Screenshot

Capture a screenshot of the full screen, a specific display (by 0-based index), a named app window, or a pixel region. Always saves a full-resolution PNG to disk (defaulting to ~/Desktop). Optionally returns a downscaled JPEG preview (max 1024px wide) as base64 for agent visual analysis — keeping response size manageable. Window capture requires Screen Recording permission; all other targets do not.

Input parameters:

- `app_name` (string): App name for target=window, e.g. "Safari". App must be running and not minimized.
- `display_index` (number): 0-based display index for target=display. 0 is the primary display.
- `include_data` (boolean): When true, returns a downscaled JPEG preview as base64 in the response for agent visual analysis. Defaults to false.
- `path` (string): Absolute path for the output PNG. Defaults to MACOS_SCREENSHOT_DIR/<timestamp>.png (~/Desktop if not configured). Must be within ~/Desktop, /tmp, or the home directory.
- `region` (object): Pixel region to capture. Required for target=region.
- `target` (string, required): screen — full screen; window — a named app window (requires Screen Recording); display — a specific connected display; region — a pixel rectangle.

Output parameters:

- `height` (number): Full-resolution image height in pixels.
- `path` (string): Absolute path to the full-resolution PNG written to disk.
- `preview` (string): Base64-encoded JPEG preview (max 1024px wide, ~70% quality). Present only when include_data=true.
- `preview_height` (number): Preview image height in pixels. Present when include_data=true.
- `preview_width` (number): Preview image width in pixels. Present when include_data=true.
- `width` (number): Full-resolution image width in pixels.

### `macos_manage_finder` (~179 tokens)

Manage macOS Finder

Finder integration: get the path of the frontmost Finder window, get the current Finder selection, reveal a file or folder in Finder, open a path with a specific app, or move a path to the Trash (recoverable — goes to Trash, not rm). Frontmost path and reveal work without any special permissions. get_selection requires Automation > Finder permission. trash moves files to Trash, not permanent deletion.

Input parameters:

- `action` (string, required): frontmost_path — path of the Finder window in focus; get_selection — selected items; reveal — show path in Finder; open_with — open path using a named app; trash — move path to Trash.
- `app_name` (string): Application name for open_with, e.g. "TextEdit".
- `path` (string): Absolute path for reveal, open_with, and trash actions.

Output parameters:

- `action` (string): The action that was performed.
- `count` (number): Number of selected items. Present for action=get_selection.
- `path`: POSIX path of the frontmost Finder window, or null when no window is open. Present for frontmost_path and write actions.
- `paths` (array): POSIX paths of selected items in Finder. Present for action=get_selection.
- `success` (boolean): True when the operation completed. Present for write actions.

### `macos_manage_focus` (~188 tokens)

Manage macOS Focus Mode

Get or set Do Not Disturb / Focus mode. The get action is best-effort — macOS 13+ protects the Focus state database and the returned status may be "unknown" on some configurations. The set action requires the built-in "Set Focus" shortcut to exist in the Shortcuts app (present on macOS 12+). Mode names must exactly match configured Focus profiles (e.g. "Do Not Disturb", "Work", "Personal").

Input parameters:

- `action` (string, required): get — query current Focus status (best-effort); set — enable or disable a Focus mode.
- `enabled` (boolean): For action=set: true=enable the mode, false=disable it. Defaults to true.
- `mode` (string): Focus mode name for action=set, e.g. "Do Not Disturb", "Work". Must match a configured Focus profile exactly.

Output parameters:

- `action` (string): The action that was performed.
- `mode`: Active Focus mode name, or null when inactive or unknown. Present for action=get and action=set.
- `reason` (string): Explanation when status is "unknown". Present for action=get.
- `status` (string): Current Focus status. Present for action=get. "unknown" when macOS cannot be queried without entitlements.
- `success` (boolean): True when the Focus mode was applied. Present for action=set.

## Diagnostics

Captured diagnostic sections: Provenance, Dependencies. The full working is on the page: https://verifymcp.io/servers/cyanheads-macos-mcp-server/cyanheads-macos-mcp-server#diagnostics

## Score history

- 2026-08-07: 66
- 2026-08-06: 66
- 2026-08-05: 66
- 2026-08-04: 35
- 2026-08-03: 35
- 2026-08-02: 5
- 2026-08-01: 20
- 2026-07-31: 6
- 2026-07-29: 25
- 2026-07-28: 24
- 2026-07-27: 24

## Links

- npm package: https://www.npmjs.com/package/@cyanheads/macos-mcp-server
- Socket report: https://socket.dev/npm/package/@cyanheads/macos-mcp-server
- Repository: https://github.com/cyanheads/macos-mcp-server
- Changelog RSS feed: https://verifymcp.io/servers/cyanheads-macos-mcp-server/cyanheads-macos-mcp-server.xml
- Changelog JSON feed: https://verifymcp.io/servers/cyanheads-macos-mcp-server/cyanheads-macos-mcp-server.json
- HTML version of this page: https://verifymcp.io/servers/cyanheads-macos-mcp-server/cyanheads-macos-mcp-server
