mcp-macos
Allows an agent to observe and operate a macOS system: read files, list processes and apps, take screenshots, write files, set the clipboard, post notifications, open items, and with admin opt-ins run commands/AppleScript, delete to Trash, kill processes, and drive the GUI.
Click on "Install 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., "@mcp-macosshow me the top 5 processes by CPU usage"
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.
mcp-macos
A safe-by-default Model Context Protocol server that lets an agent observe and operate a Mac — read files, list processes and apps, take screenshots (read-only); write files, set the clipboard, post notifications, open things (read-write); and, behind explicit opt-ins, run commands / AppleScript, delete to Trash, kill processes and drive the GUI (admin).
It starts read-only. Every high-impact power needs both admin mode and its own flag, and the most dangerous ones ask the human to approve each call. Part of the dockndevai MCP server suite — one governance model across all of them.
Pure Node +
osascript/screencapture— no native add-ons. macOS only.
What it gives an agent
The server starts read-only (see Safe by default); higher-capability tools are only registered when you raise the mode.
Tool | For | Needs mode |
| macOS version, hardware, memory, load, uptime | read-only |
| browse & read files (path-allowlisted) | read-only |
| running processes by CPU/mem | read-only |
| read the clipboard | read-only |
| running apps; the active one | read-only |
| capture the screen as a PNG | read-only |
| create/overwrite a file (confirms on overwrite) | read-write |
| set clipboard, notify, open a file/URL/app | read-write |
| run a program (argv, no shell) | admin + |
| run AppleScript / JXA | admin + |
| signal a process | admin + |
| move a path to the Trash | admin + |
| drive the GUI | admin + |
Related MCP server: Automation MCP
Install
npx -y @dockndevai/mcp-macosRequires macOS and Node ≥ 22. click/move_mouse also need cliclick (brew install cliclick).
Configure
{
"mcpServers": {
"macos": {
"command": "npx",
"args": ["-y", "@dockndevai/mcp-macos"],
"env": {
"MACOS_MODE": "read-only"
}
}
}
}See docs/CLIENTS.md for Claude Code / Cursor / Codex / VS Code / Windsurf snippets, and .env.example for every supported variable.
Safe by default
This server can drive an entire Mac, so the access model (enforced by src/security.ts) is deliberately strict — defence in depth, not documentation:
Question | Setting | Default | Notes |
What can it do at all? |
|
|
|
Which paths can it touch? |
| (anywhere) | Comma-separated roots. When set, any file op outside them is refused. |
Which paths are read-only forever? |
| system + secrets |
|
Can it run commands? |
|
| Gates |
Restrict which programs? |
| (any) | When set, |
Can it delete? |
|
| Gates |
Can it drive the GUI? |
|
| Gates |
Preview without doing |
|
| Mutating tools validate + log intent, then return. |
Audit trail |
|
| JSON line to stderr per guarded operation ( |
Interactive confirmation | (automatic) | — |
|
See SECURITY.md.
macOS permissions
The host process (your terminal / MCP client) must be granted, in System Settings → Privacy & Security:
Screen Recording — for
screenshot.Accessibility — for
type_text/key_press/click/move_mouse.Automation (per-app prompts) — for
run_applescriptand app control.Files and Folders / Full Disk Access — to read/write outside the default sandbox.
You'll be prompted the first time each is needed; nothing works around a permission you haven't granted.
Developing
npm install
npm run build
MACOS_MODE=read-only node dist/index.js
# introspect the tool list:
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list","params":{}}' | node dist/index.jsLicence
MIT
Available Tools
8 toolsget_clipboardRead the clipboardARead-onlyIdempotent
Return the current text contents of the macOS clipboard.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds modest context by specifying 'text contents' and 'macOS', but it does not disclose potential edge cases like empty clipboard or permission requirements. No contradiction with annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
A single clear sentence contains all necessary information with no filler. It is appropriately sized for such a simple tool.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter, read-only operation with strong annotations, the description is complete. It states what is returned (current text clipboard contents) and the platform (macOS), which is all an agent needs to invoke it correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so the baseline is 4. The description correctly scopes what is read ('text contents') but has no parameter meaning to add because no parameters exist.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb ('Return') and names the exact resource ('current text contents of the macOS clipboard'). It is clearly distinct from sibling tools like read_file, list_directory, and get_frontmost_app, leaving no ambiguity about what the tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The purpose strongly implies when to use it: whenever the agent needs the current text from the macOS clipboard. However, it does not explicitly state when not to use it or mention alternatives among the sibling tools, so the guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_frontmost_appFrontmost appARead-onlyIdempotent
Return the name of the frontmost (active) application.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The readOnlyHint and idempotent annotations already establish safety, and the description adds only that the result is a name. It does not contradict annotations, but also does not disclose edge-case behavior or system-specific limitations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One clear, front-loaded sentence communicates the tool's purpose without filler or unnecessary detail.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple read-only, no-parameter tool, this is nearly complete. It could optionally mention behavior when there is no frontmost application, but the description covers the core invocation context well.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are no parameters, so parameter documentation is not needed. The description appropriately focuses on what the tool returns rather than input semantics.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states a specific verb and object: "Return the name of the frontmost (active) application." This distinguishes it from sibling tools like list_apps, list_processes, and system_info.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Usage context is implied by the tool's name and description, but there is no explicit guidance about when to choose this over sibling tools or what to do when no frontmost application exists.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_appsList running appsARead-onlyIdempotent
List the names of currently running (non-background) applications.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already cover safety (readOnlyHint, openWorldHint, idempotent, non-destructive). The description adds useful scope detail ('currently running, non-background') but reveals nothing about output format, ordering, or the open-world nature of the result.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
One sentence conveys the action, scope, and output in a compact, front-loaded way. Every word earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a zero-parameter read-only tool, this is nearly complete: it specifies the output is names of running non-background applicationsholový and annotations confirm safety. The only small gap is the exact output format, but the description's wording strongly implies a list of strings.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters肯 with an empty schema, so no parameter documentation is needed. The description does not add parameter-level meaning, but the baseline for zero-parameter tools is 4.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description has a specific verb ('List') and a clear resource ('names of currently running (non-background) applications'). It differentiates from list_processes by focusing on application names and excluding background processes, though it does not explicitly name sibling alternatives.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description clearly conveys when to use this tool: when you need names of running applications. It gives no explicit exclusions or comparisons with siblings like list_processes or get_frontmost_app, so guidance is implied rather than stated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_directoryList a directoryARead-onlyIdempotent
List the entries (name, type, size) of a directory. Honours the path allowlist.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | Directory path (supports ~ for home). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint, idempotentHint, and destructiveHint, covering the safety profile. The description adds meaningful behavioral context beyond annotations: it discloses the path allowlist restriction and specifies the return entries (name, type, size). It stops short of describing error behavior, but the annotation coverage lowers the bar.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two compact sentences: the first front-loads the action and output, the second states the key constraint. No filler or redundant repetition of the schema.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only listing tool with strong annotations and no output schema, the description is complete enough for correct invocation. It covers what the tool returns, the path allowlist, and the required input. Minor omissions like sorting or hidden-file handling are not essential.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema already documents path with minLength and ~ support (100% coverage), so the baseline is 3. The description adds the allowlist restriction, which is a valuable constraint on valid path values not present in the schema, pushing it above baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb, 'List', and a clear resource: directory entries including name, type, and size. This unambiguously differentiates it from siblings like read_file (file contents) and list_processes (running processes).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The intended use is implied by the name and action but never made explicit. There is no mention of when to choose this tool over alternatives, no exclusion criteria, and no routing to a sibling. The allowlist constraint hints at a condition but does not guide usage decisions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_processesList processesARead-onlyIdempotent
List running processes (pid, cpu%, mem%, command), busiest first.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Max rows (default 30). | |
| filter | No | Only processes whose command contains this substring. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, destructiveHint=false, idempotentHint=true, so safety is covered. The description adds the ordering behavior ('busiest first') which is not in annotations, providing useful context beyond the structured metadata. It doesn't mention return format or error conditions, but for a read-only list tool, the description adds sufficient behavioral detail.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is a single, front-loaded sentence that states the action, the resource, the returned fields, and the ordering. There is no redundant or unnecessary text; every word adds value. Excellent conciseness.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a read-only tool with two optional parameters and no output schema, the description covers the essential information: what is returned and how results are ordered. It does not explain pagination or platform variations, but these are minor for such a simple tool. The description is complete enough for an agent to invoke it correctly without additional guidance.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%: both 'limit' and 'filter' have clear descriptions in the schema. The tool description adds no additional parameter context beyond what the schema provides. Since the schema fully documents the parameters, the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb (list) and resource (running processes) and enumerates the returned fields (pid, cpu%, mem%, command). It clearly distinguishes from siblings like list_apps (apps) and system_info (system-level metrics) by focusing on process details. This is a precise, unambiguous purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage: if you need process-level details with CPU/memory usage, use this tool. However, it does not explicitly state when NOT to use it or point to alternatives. With siblings like list_apps and system_info present, the guidance is implicit rather than explicit, so a 3 is appropriate.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
read_fileRead a fileARead-onlyIdempotent
Read a text file's contents (capped at MACOS_MAX_FILE_BYTES). Honours the path allowlist.
| Name | Required | Description | Default |
|---|---|---|---|
| path | Yes | File path (supports ~ for home). |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already establish read-only, idempotent, non-destructive behavior, so the description adds value by disclosing the size cap and the path allowlist constraint. It could say more about what happens on allowlist failure or oversize files, but it covers the key behavioral traits beyond annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short sentences, each carrying necessary information: what is read, the cap, and the allowlist. No filler, front-loaded with the primary action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a single-parameter, read-only tool, the description covers the essential constraints: target is a text file, capped size, and allowlist requirement. It does not detail error behavior or return format, but the operation is simple enough that the description is largely sufficient.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema's parameter description already covers path syntax including '~'. The tool description adds that the path must correspond to a text file and must be allowlisted, which are meaningful constraints on the parameter's accepted values.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names the exact verb and resource: 'Read a text file's contents', which is more specific than the title and distinguishes it from sibling tools like list_directory and get_clipboard. It also adds two scope constraints (byte cap and allowlist) that define what this tool does.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies when to use it: when you need a text file's contents. However, it does not explicitly state when not to use it or name alternatives; the allowlist mention hints at a prerequisite but no exclusions are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
screenshotScreenshotARead-onlyIdempotent
Capture the screen and return it as a PNG image. Needs Screen Recording permission for the host process.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is covered. The description adds valuable operational context beyond annotations: the tool returns a PNG and requires Screen Recording permission for the host process.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Two short, front-loaded sentences. The first states the action and output; the second states the key prerequisite. No filler or repetition of schema content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a simple zero-parameter tool, the description is complete: it explains what is captured, the output format, and the permission required. The annotations cover safety/idempotency, and there is no output schema that would require return-value documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
There are zero parameters, so per the rubric the baseline is 4. The description correctly indicates that no configuration is needed—just capture the screen.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: 'Capture the screen' and specifies the output format ('PNG image'). It is clearly distinguishable from all sibling tools, none of which capture the screen.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The tool's intended use is implied by its name and description, but there is no explicit statement of when to use it versus alternatives, nor any when-not-to-use guidance. The permission requirement is a prerequisite, not usage guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
system_infoSystem infoARead-onlyIdempotent
Report macOS version, hardware, memory, load, uptime and the current user.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint=true, idempotentHint=true, and destructiveHint=false, so the safety profile is fully covered. The description adds modest value by naming the exact categories returned, but it does not disclose operational details such as output format or timing. This is acceptable for a zero-parameter read-only tool, but it does not exceed the baseline.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is one sentence with a leading verb and a compact list of deliverables, containing no filler or redundant restatements of the title. Every phrase earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has zero parameters, no output schema, and clear safety annotations, the description is complete enough for an agent to select and call it correctly. It enumerates all the information categories the tool reports, which is all an agent needs for this simple read-only snapshot.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema is empty with 100% coverage, so there are no parameter semantics to clarify. Following the 0-parameter baseline, the description does not need to compensate, and listing the reported data categories is more than sufficient.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a specific verb ('Report') and enumerates a precise set of system data: macOS version, hardware, memory, load, uptime, and current user. This clearly distinguishes it from siblings like list_processes, get_clipboard, and list_apps by content, even though it does not name them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies use when an agent needs a high-level snapshot of macOS system state, and the readOnlyHint annotation reinforces that it is a safe diagnostic tool. It does not explicitly state when not to use it or name alternatives, but no sibling covers this exact aggregate of system information and there are no preconditions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.1.0- First observed
get_clipboard - First observed
get_frontmost_app - First observed
list_apps - First observed
list_directory - First observed
list_processes - First observed
read_file - First observed
screenshot - First observed
system_info
TDQS
Scored across 8 tools
Every tool has a clearly distinct purpose: system summary, directory listing, file reading, process listing, clipboard access, app listing, active app lookup, and screen capture. Even related tools like list_apps and get_frontmost_app are cleanly separated by scope.
Most tools follow a clear list_* or get_* verb pattern, with read_file as another verb_noun. system_info and screenshot break the pattern, but the naming remains readable and mostly predictable.
Eight tools is well-scoped for a macOS observation/utility server. Each tool covers a distinct capability and none feel redundant or excessive.
The server covers common macOS inspection needs: system status, file browsing, process listing, clipboard, apps, and screen capture. It is intentionally read-only, so missing write operations are not glaring gaps, though a few extensions like file metadata or clipboard image support could be added.
Maintenance
Related MCP Connectors
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Let ChatGPT, Claude & Cursor use your Mac: email, calendar, iMessage, Teams, files. Local, free.
Runtime permission, approval, and audit layer for AI agent tool execution.
- emisarOAuthdev.emisar
Let AI operate servers without SSH. Choose actions, approve risky changes, and audit every step.
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceEnables AI services like Claude and Cursor to remotely control a Mac by executing shell commands, managing files, and running AppleScript for UI automation. Access is secured through OAuth 2.0 authentication and encrypted tunnels to protect remote interactions.2MIT
- AlicenseNot gradedqualityFmaintenanceEnables AI assistants to automate macOS desktop tasks including mouse control, keyboard input, screenshots, window management, and UI interaction.7415MIT
- FlicenseNot gradedqualityDmaintenancemacOS desktop automation enabling AI agents to screenshot, switch apps and tabs, click, type, and scroll. Offers two trust levels: read-only screenshot and full UI control.-
- MIT