mac-pilot-mcp
Interacts with Discord using Electron fallback with Chrome DevTools Protocol for UI automation.
Provides optional Chrome DevTools Protocol fallback for deeper UI inspection of Electron apps (e.g., VSCode, Slack, Discord).
Automates Figma actions such as exporting frames as PNG via UI automation and AppleScript.
Automates macOS system tasks including AppleScript, JXA, shell commands, window management, clipboard, notifications, and more.
Retrieves current URL and title, and performs other browser automation tasks.
Interacts with Slack using Electron fallback with Chrome DevTools Protocol for UI automation.
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., "@mac-pilot-mcptoggle dark mode"
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.
The Problem
There are 7+ macOS automation MCP servers. None of them remember anything. Every session starts from zero — same trial and error, same failures, same wasted tokens.
Related MCP server: openowl
The Solution
Mac-Pilot is different. It learns from every interaction:
Success? The pattern is auto-saved as app-specific knowledge
Failure? The error is recorded so it won't repeat the same mistake
Multi-step workflow? Save it as a recipe — replay it in one call next time
Ships with 21 built-in recipes so you're productive from the first run.
Quick Start
Install
npm install -g mac-pilot-mcpConnect to your AI client
claude mcp add mac-pilot -- mac-pilot-mcpOr manually add to ~/.claude.json:
{
"mcpServers": {
"mac-pilot": {
"command": "mac-pilot-mcp"
}
}
}Add to claude_desktop_config.json:
{
"mcpServers": {
"mac-pilot": {
"command": "npx",
"args": ["-y", "mac-pilot-mcp"]
}
}
}Add to your MCP settings (.cursor/mcp.json):
{
"mcpServers": {
"mac-pilot": {
"command": "npx",
"args": ["-y", "mac-pilot-mcp"]
}
}
}Add to your MCP config:
{
"mcpServers": {
"mac-pilot": {
"command": "npx",
"args": ["-y", "mac-pilot-mcp"]
}
}
}Grant Permissions
Mac-Pilot needs Accessibility access for UI automation:
System Settings → Privacy & Security → Accessibility
Toggle ON for your terminal app (Terminal, iTerm2, VS Code, Cursor, etc.)
Restart the terminal
How It Works
You: "Export the current Figma frame as PNG"
┌─ First time ─────────────────────────────────────────┐
│ │
│ 1. mac_recipe_search("Figma export") → No matches │
│ 2. mac_state() → Figma is frontmost │
│ 3. mac_run(applescript) → File > Export > PNG │
│ 4. mac_recipe_save("export-figma-png", steps=[...]) │
│ │
│ ✓ Worked! Pattern saved automatically. │
└───────────────────────────────────────────────────────┘
┌─ Next time ───────────────────────────────────────────┐
│ │
│ 1. mac_recipe_search("Figma export") │
│ → Found: export-figma-png (100% success rate) │
│ 2. mac_recipe_run("export-figma-png") │
│ → Done instantly │
│ │
│ ⚡ 4 steps → 2 steps. No trial and error. │
└───────────────────────────────────────────────────────┘Tools
Tool | What it does |
| Execute AppleScript, JXA, shell commands, open apps/URLs, click, type, keypress |
| Query system state — frontmost app, windows, clipboard, running apps |
| Find UI elements via Accessibility API (buttons, fields, menus) |
| Capture screen/window/region as base64 PNG |
| Save a working action sequence as a reusable recipe |
| Replay a saved recipe with parameter substitution |
| Full-text search across recipes and action history |
Built-in Recipes
21 recipes ship out of the box — no setup needed:
Category | Recipes | Example |
System |
|
|
Finder |
|
|
Safari |
|
|
Clipboard |
|
|
Notifications |
|
|
Terminal |
|
|
Windows |
|
|
Music |
|
|
Examples
AppleScript
{ "actionType": "applescript", "script": "tell application \"Finder\" to get name of every window" }JXA (JavaScript for Automation)
{ "actionType": "jxa", "script": "Application('Safari').documents[0].url()" }Shell command
{ "actionType": "shell", "command": "ls -la ~/Desktop" }Open an app or URL
{ "actionType": "open", "target": "Safari" }
{ "actionType": "open", "target": "https://github.com" }Type text
{ "actionType": "type", "text": "Hello World" }Keyboard shortcut
{ "actionType": "keypress", "text": "cmd+c" }
{ "actionType": "keypress", "text": "cmd+shift+4" }Find UI elements
mac_find_ui { "app": "Safari", "role": "AXButton" }
mac_find_ui { "app": "Finder", "searchText": "Downloads" }Electron apps (VSCode / Cursor / Slack / Discord) — macOS Accessibility
exposes a thin tree for Electron, so Mac-Pilot can optionally fall back to
Chrome DevTools Protocol when the app is launched with
--remote-debugging-port=<PORT>. See docs/ELECTRON-SUPPORT.md.
mac_find_ui {
"app": "Visual Studio Code",
"searchText": "Run Test",
"useElectronFallback": "auto"
}Take a screenshot
mac_screenshot { "target": "screen", "scale": 0.3 }
mac_screenshot { "target": "window", "windowName": "Safari" }Save a custom recipe
mac_recipe_save {
"name": "open-project",
"description": "Open VS Code at project directory",
"steps": [
{ "actionType": "shell", "params": { "command": "code {{path}}" }, "description": "Open VS Code" }
],
"parameters": [
{ "name": "path", "description": "Project directory path" }
],
"tags": ["dev", "vscode"]
}Security
Mac-Pilot blocks dangerous operations before they execute:
Layer | Protection |
Hard block |
|
Risk classification | Every action is rated |
Audit log | All actions (including blocked ones) are logged to SQLite |
Dry run | Test any action with |
Auto-cleanup | Action logs older than 30 days are pruned automatically |
Architecture
~/.mac-pilot/pilot.db (SQLite, WAL mode)
├── action_log — Every action executed, with timing + success/failure
├── action_log_fts — Full-text search index over action history
├── recipes — Saved automation sequences
├── recipes_fts — Full-text search index over recipes
├── app_knowledge — Per-app quirks, selectors, workarounds (auto-learned)
└── security_log — Blocked command audit trailBuilt-in recipes are auto-loaded on first run. Your custom recipes and learned knowledge persist across sessions.
Comparison
Feature | mac-pilot-mcp | Other MCP servers |
Self-learning (auto-saves knowledge) | Yes | No |
Reusable recipes with parameters | Yes | No |
Built-in recipe library | 21 | 0 |
JXA + AppleScript | Both | Usually one |
Full-text search (recipes + history) | Yes | No |
Security audit log | Yes | Rare |
Risk classification (4 levels) | Yes | No |
Dry run mode | Yes | Rare |
Action log auto-cleanup | Yes | No |
Troubleshooting
Your terminal needs Accessibility permission:
System Settings → Privacy & Security → Accessibility
Toggle ON for your terminal
Restart the terminal app completely
The target app must be running. Open it first:
mac_run { "actionType": "open", "target": "AppName" }Reduce the scale (default is 0.5):
mac_screenshot { "target": "screen", "scale": 0.3 }Recipe names are case-sensitive. Search first:
mac_recipe_search { "query": "your keyword" }Use dry run to check the risk classification:
mac_run { "actionType": "shell", "command": "your-command", "dryRun": true }Requirements
macOS (darwin only)
Node.js >= 18
Accessibility permission for UI automation
Contributing
Issues and PRs welcome at github.com/leesgit/mac-pilot-mcp.
git clone https://github.com/leesgit/mac-pilot-mcp.git
cd mac-pilot-mcp
npm install
npm run build
npm test # 144 testsLicense
MIT - Byeongchang Lee
Available Tools
11 toolsmac_clipboardA
Read / write / clear the macOS clipboard (text only, via pbpaste/pbcopy).
Examples:
Read text: { action: "read" }
Write text: { action: "write", text: "hello" }
Clear: { action: "clear" }
Limitations:
Text only. Images/files in the clipboard appear as their typed name.
No clipboard history — only the current value.
| Name | Required | Description | Default |
|---|---|---|---|
| text | No | Text to write (required when action = "write") | |
| action | Yes | Clipboard operation |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It transparently notes that only text is supported, images/files appear as names, and there is no clipboard history. It also mentions the underlying pbpaste/pbcopy mechanism, adding useful context beyond the basic operation.
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 concise and well-structured with clear sections for examples and limitations. Every sentence adds value, and the formatting makes it easy to scan. No unnecessary words or redundancy.
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 two-parameter tool with no output schema, the description is complete. It covers all actions, example usage, and key limitations. It does not explicitly describe return values or error cases, but those are simple enough not to require explanation. A slight gap is the absence of permission requirements, but this is not critical.
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 already fully describes both parameters (action with enum, text with conditional requirement). The description adds examples showing correct usage but does not provide additional semantic meaning beyond what the schema already states, so the baseline of 3 is appropriate.
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 the tool's function with specific actions (read/write/clear) on the macOS clipboard, and the text-only constraint distinguishes it from any potential clipboard-related tools. Sibling tools like mac_run and mac_screenshot are unrelated, so there is no ambiguity.
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 provides clear context on when to use the tool via examples and limitations (text-only, no history). It implicitly communicates when not to use it (e.g., for images or clipboard history), though it does not explicitly name alternative tools or provide exclusionary guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mac_find_uiA
Find UI elements (role, title, position, size) in an app via Accessibility, with optional Electron CDP fallback.
Examples:
All buttons in Safari: { app: "Safari", role: "AXButton" }
Element by title: { app: "Mail", title: "Send" }
Fuzzy search: { app: "Finder", searchText: "Documents" }
Electron AX (VSCode with --remote-debugging-port=9222): { app: "Visual Studio Code", useElectronFallback: true }
Auto-fallback for known Electron apps: { app: "Cursor", useElectronFallback: "auto" }
Limitations:
Requires Accessibility permission for the client app.
Electron apps (VSCode, Cursor, Slack, Discord) expose a thin AX tree; use useElectronFallback when AX returns empty.
CDP fallback needs the user to relaunch the app with --remote-debugging-port=.
| Name | Required | Description | Default |
|---|---|---|---|
| app | Yes | Application name | |
| role | No | AX role filter (e.g., AXButton, AXTextField) | |
| title | No | Exact element title to search for | |
| maxResults | No | Max results (1-50, default: 10) | |
| searchText | No | Fuzzy text search across all visible elements | |
| electronCdpPort | No | Explicit CDP port (skips auto-detect). Range 1-65535. | |
| useElectronFallback | No | Use Chrome DevTools Protocol fallback for Electron apps. `true` = always try; `"auto"` = only for known Electron apps when AX returns empty. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden. It discloses required permissions ('Requires Accessibility permission for the client app'), the behavior for Electron apps ('expose a thin AX tree'), and the prerequisite for CDP fallback ('needs the user to relaunch the app with --remote-debugging-port=<PORT>'). These are valuable behavioral traits beyond the schema. It does not detail return structure or error handling, which is a minor gap.
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 well-structured: a one-sentence summary, five illustrative examples, and three bullet-point limitations. Every sentence contributes information about usage or constraints. There is no fluff or repetition, and the front-loaded summary quickly establishes the tool's purpose.
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 tool with 7 parameters and no output schema, the description covers purpose, usage examples, and key limitations. It implies the return contains role, title, position, and size but does not explicitly state the return format (array, JSON). Error behavior for missing permissions or app not running is also absent. Given the complexity, this is a solid but not perfect level of completeness.
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 coverage is 100%, so the baseline is 3. The description adds value through examples that illustrate parameter combinations (e.g., { app: 'Cursor', useElectronFallback: 'auto' }) and clarifies when to use 'auto' vs boolean for useElectronFallback. This goes beyond the schema's descriptions by showing practical usage patterns.
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 clear verb and resource: 'Find UI elements (role, title, position, size) in an app via Accessibility.' This distinguishes it from sibling tools like mac_run (execute commands) and mac_state (inspect state). It also mentions the optional Electron CDP fallback, further specifying scope.
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 provides concrete examples for different use cases (all buttons, exact title, fuzzy search, Electron fallback) and notes a key limitation: 'use useElectronFallback when AX returns empty.' It gives clear context on when to use the tool, though it does not explicitly name alternatives or exclusions. The examples and limitations serve as implicit guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mac_permissionsA
Check macOS Privacy permissions (Automation/Accessibility/Screen Recording) + deep-link to grant.
Examples:
{ check: "all" } → return state of all 3 permissions
{ check: "accessibility" } → only Accessibility
Limitations:
macOS doesn't expose TCC state to ordinary processes. We probe by attempting a known-safe operation and observing the error class.
"Screen Recording" cannot be detected reliably without invoking a screenshot; we report "unknown" instead of guessing.
| Name | Required | Description | Default |
|---|---|---|---|
| check | No | Which permission to check (default: all) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It transparently discloses that macOS does not expose TCC state to ordinary processes, that the tool probes via a known-safe operation, and that Screen Recording cannot be detected reliably without invoking a screenshot, reporting 'unknown' instead of guessing. This is excellent behavioral disclosure beyond basic purpose.
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 well-structured with an opening purpose line, a concise examples block, and a clearly separated limitations section. Every sentence serves a purpose: purpose, usage example, and critical behavioral caveats. It is appropriately sized and front-loaded.
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 that there is no output schema and no annotations, the description does a good job of explaining the tool's behavior, including return state summaries, limitations, and probing method. It slightly lacks detail on the exact structure of the returned state (e.g., granted/denied values) and the specifics of the deep-link action, but overall it is sufficiently complete for an agent to use the tool 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?
Schema coverage is 100% with an enum and description, so the baseline is 3. The description adds value by providing concrete examples of the parameter values and their effects on the return state (e.g., 'check: all' returns all 3 permissions, 'check: accessibility' only returns that one). This clarifies the semantic output of each enum value beyond the schema.
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 and resource: 'Check macOS Privacy permissions (Automation/Accessibility/Screen Recording) + deep-link to grant.' It also mentions a deep-link capability, which further distinguishes this tool from the sibling tools (mac_run, mac_screenshot, etc.) that do not handle permission checks.
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 provides clear context on what the tool does and includes concrete examples for the check parameter. The 'Limitations' section adds important guidance about when results may be unreliable (especially Screen Recording), but it does not explicitly mention alternative tools or exclusive 'when to use' conditions. Overall, usage context is clear but exclusions are not fully spelled out.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mac_recipe_exportA
Export user-saved recipes as a portable .mac-recipe.json bundle (built-ins excluded by default).
Examples:
Export one recipe inline: { name: "open-url-in-private" }
Export all user recipes to a file: { outputPath: "~/recipes/backup.json" }
Include built-ins: { outputPath: "~/recipes/full.json", includeBuiltins: true }
Format: mac-recipe-bundle/v1 (versioned for forward compatibility).
Limitations: outputPath must resolve under $HOME and end with .json.
| Name | Required | Description | Default |
|---|---|---|---|
| name | No | Single recipe name to export (omit = export all user recipes) | |
| outputPath | No | Path to write bundle (must be under $HOME and end with .json). Omit to return inline. | |
| includeBuiltins | No | Include the 118 built-in recipes (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full transparency burden. It discloses the output format, versioning rationale, default behavior (built-ins excluded), and path/extension constraints. It does not address overwrite behavior or error handling, but it offers meaningful behavioral context beyond a bare operation description.
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 concise and well-structured: a one-sentence summary followed by three illustrative examples, then format and limitations. Every sentence serves a purpose, and the content is front-loaded with the core purpose. No redundancy or filler.
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 tool with 3 params, no output schema, and no annotations, the description covers the essential context: what it exports, how to invoke it, the output format, and constraints. It hints at inline return via examples but does not explicitly define the return structure, which is a minor gap.
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 already has 100% coverage with highly descriptive comments for each parameter (e.g., 'omit = export all user recipes', 'Omit to return inline'). The description adds examples and format context but does not introduce new parameter semantics beyond the schema. Baseline 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 opens with a specific verb and resource: 'Export user-saved recipes as a portable .mac-recipe.json bundle'. It clearly differentiates from siblings like import, search, and run by focusing on export and the bundle format. The default exclusion of built-ins is also stated, making the tool's scope unambiguous.
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 provides three concrete usage examples covering inline export, full export to file, and including built-ins. It also states limitations (path constraints). However, it does not explicitly name alternatives like mac_recipe_import for import use cases, so some 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.
mac_recipe_importA
Import a .mac-recipe.json bundle (inline or file path). Conflict policy: skip | rename | replace.
Examples:
From file: { inputPath: "~/recipes/team-bundle.json" }
From file with replace policy: { inputPath: "~/recipes/team.json", onConflict: "replace" }
Inline bundle: { bundle: { format: "mac-recipe-bundle/v1", exportedAt: "...", recipes: [...] } }
Conflict policy:
"skip" (default): keep existing recipe
"rename": append "-imported-N" until name is unique
"replace": delete existing first
Limitations:
Provide exactly one of
bundleorinputPath.Bundle format major version is enforced — v2 bundles rejected.
| Name | Required | Description | Default |
|---|---|---|---|
| bundle | No | Inline bundle object (format: mac-recipe-bundle/v1) | |
| inputPath | No | Path to bundle file (must be under $HOME and end with .json) | |
| onConflict | No | How to handle existing recipes with the same name (default: skip) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosing behavior. It thoroughly explains the conflict policy (skip, rename, replace) including the fact that 'replace' deletes the existing recipe first, and discloses limitations such as requiring exactly one of `bundle` or `inputPath` and enforced major version validation. This goes beyond basic description.
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 well-organized into sections (Examples, Conflict policy, Limitations), with each sentence providing useful information. It avoids fluff and is appropriately sized for the tool's complexity, making it easy to parse.
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?
The description covers all key aspects: what it does, how to invoke it, conflict policies, and limitations. However, since there is no output schema, the description does not mention what the tool returns, which would be helpful for a complete picture. Overall, it is comprehensive but slightly lacking in return-value clarity.
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?
Although the schema covers 100% of parameters, the description enriches them with concrete examples and detailed explanations. For instance, it illustrates how to use `onConflict` with the 'rename' policy and clarifies that `bundle` must be the inline object while `inputPath` must be a file path, adding meaning beyond the schema.
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 explicitly states 'Import a .mac-recipe.json bundle (inline or file path)', which is a specific verb+resource. It clearly distinguishes this tool from siblings like export, save, run, and search by focusing on the import action.
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 provides clear usage examples (from file, from file with replace, inline bundle) and explains the conflict policy options. While it doesn't explicitly state when to use this tool versus alternatives, the examples implicitly define its purpose, making the usage clear enough.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mac_recipe_runA
Run a saved recipe by name with parameter values.
Examples:
{ name: "toggle-dark-mode" }
{ name: "open-url-in-private", params: { url: "https://example.com" } }
Dry run (preview steps): { name: "send-email", params: { ... }, dryRun: true }
Limitations:
Stops on the first failed step (no partial rollback).
Each step inherits the recipe's app as appContext for self-learning.
| Name | Required | Description | Default |
|---|---|---|---|
| name | Yes | Recipe name | |
| dryRun | No | Preview steps without executing | |
| params | No | Parameter values (keys matching recipe parameter names) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are present, so the description carries the transparency burden. It explicitly notes that execution stops on the first failed step (no partial rollback) and that steps inherit the recipe's app context. These are useful behavioral disclosures beyond the raw action.
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 front-loaded with the core purpose, then gives three concise examples, then lists two limitations. It is compact and well-structured without unnecessary fluff.
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?
While it covers purpose, usage, and limitations, there is no mention of what the tool returns or what happens after execution. Since there is no output schema, the agent is left guessing about the result format.
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 already describes all parameters (100% coverage), so the baseline is 3. The description adds value with concrete examples showing how to pass params as an object and how dryRun previews steps, which helps clarify parameter intent.
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 'Run a saved recipe by name with parameter values,' a specific verb-and-resource statement. It clearly differentiates from sibling tools like mac_recipe_save and mac_recipe_search by focusing on execution.
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 provides concrete examples (toggle-dark-mode, open-url-with-params, dryRun) but does not explicitly discuss when to prefer this tool over siblings like mac_run. The usage context is implied rather than stated as a rule.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mac_recipe_saveA
Save a multi-step automation as a named recipe. {{param}} placeholders are JSON-safe substituted.
Example: { name: "open-url-in-private", description: "Open a URL in Safari private window", app: "Safari", steps: [ { actionType: "open", params: { target: "Safari" }, description: "Launch Safari" }, { actionType: "keypress", params: { text: "cmd+shift+n" }, description: "Open private window" }, { actionType: "keypress", params: { text: "cmd+l" }, description: "Focus address bar" }, { actionType: "type", params: { text: "{{url}}" }, description: "Enter URL" }, { actionType: "keypress", params: { text: "return" }, description: "Navigate" } ], parameters: [{ name: "url", description: "URL to open" }], tags: ["safari", "browser", "private"] }
Limitations:
Recipe names are unique. Re-saving the same name fails — delete or rename.
Each step's params goes through the security sandbox at run time.
| Name | Required | Description | Default |
|---|---|---|---|
| app | No | Primary target app | |
| name | Yes | Unique recipe name (max 100 chars) | |
| tags | No | Tags for searchability | |
| steps | Yes | Ordered list of steps | |
| parameters | No | Recipe parameters referenced in steps as {{paramName}} | |
| description | Yes | What this recipe does |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It does disclose useful behaviors: JSON-safe placeholder substitution, unique-name failure on re-save, and runtime security sandboxing. However, it omits any success-return behavior or post-save side effects, so coverage is partial.
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 front-loaded with a clear purpose statement and uses a compact bulleted 'Limitations' section. The long JSON example is justified because it demonstrates the complex nested object structure and parameter binding. It could be tighter but the length is earned.
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?
The description is fairly complete for a save tool: it covers the purpose, provides a full example of a valid recipe, and notes key constraints. No output schema exists, so a brief statement about return values or success confirmation would improve completeness, but the current description covers most operational needs.
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 provides 100% description coverage, so the baseline is 3. The description adds value beyond the schema by showing a concrete example of how the 'parameters' array connects to '{{param}}' placeholders in steps, and explains JSON-safe substitution, making parameter usage clearer.
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 opening sentence 'Save a multi-step automation as a named recipe' uses a specific verb and object, clearly distinguishing this from sibling recipe tools (run, export, import, search). The example further reinforces the purpose by showing a complete recipe structure.
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 for creating/saving named recipes and gives an illustrative example, but does not explicitly state when to use this tool versus alternatives, nor does it provide exclusion guidance. It mentions limitations (unique names, sandboxing) but no when-not-to-use criteria.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mac_recipe_searchA
Search 118 built-in + saved recipes by natural-language query. Call this BEFORE writing new AppleScript.
Examples:
{ query: "dark mode" } → matches toggle-dark-mode, get-dark-mode
{ query: "screenshot", app: "Finder" }
{ query: "send email", includeHistory: true }
Limitations:
FTS5 tokenizer is English-biased. For Korean/CJK, supplement with the
appfilter.
| Name | Required | Description | Default |
|---|---|---|---|
| app | No | Filter by target app name | |
| query | Yes | Natural language search query | |
| includeHistory | No | Also search raw action history (default: false) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the transparency burden. It discloses the FTS5 English-biased tokenizer limitation, shows example match behavior for queries, and mentions includeHistory semantics. It does not describe return format or pagination, but for a search tool the examples and limitations provide meaningful behavioral context.
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 concise, well-structured, and front-loaded with the core purpose. Examples are useful and the limitation is stated in one line. Every sentence earns its place without redundant fluff.
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 moderately simple search tool with no output schema, the description provides enough to get started: purpose, examples, and a key limitation. It does not disclose what the result payload looks like or how matches are ranked, but the examples and explicit 'before writing AppleScript' context make this acceptable for the tool's complexity.
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 coverage is 100%, but the description enriches parameter understanding with concrete examples: query is natural-language text, app is a filter that also helps with CJK tokenization, and includeHistory expands search to raw action history. This adds value beyond the terse schema descriptions, though the schema already documents the basics.
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 the tool searches 118 built-in and saved recipes using natural language, which is a specific verb+resource pairing. It also differentiates from siblings by emphasizing this is a search step before writing new AppleScript, distinguishing it from mac_recipe_save, mac_recipe_run, and import/export tools.
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 gives a direct usage directive: 'Call this BEFORE writing new AppleScript,' which establishes when to use it. Examples show useful variations with app filtering and includeHistory, and the limitation note advises using the app filter for Korean/CJK. It does not explicitly name alternative sibling tools for when not to use it, but the context is fairly clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mac_runA
Run an AppleScript/JXA/shell command or send click/type/keypress to macOS.
Supported actionTypes: applescript, jxa, shell, open, click, type, keypress.
Examples:
Open Safari: { actionType: "open", target: "Safari" }
Type text: { actionType: "type", text: "hello world" }
Cmd+C: { actionType: "keypress", text: "cmd+c" }
Run AppleScript: { actionType: "applescript", script: 'tell application "Finder" to activate', appContext: "Finder" }
List files: { actionType: "shell", command: "ls -la ~/Documents" }
Limitations:
Requires Accessibility + Automation permissions for click/type/keypress and AS targeting other apps.
Cannot bypass the lock screen.
Dangerous shell patterns (rm -rf /, curl|sh, sudo, etc.) are blocked by the sandbox.
Set appContext for the best self-learning: errors get classified per-app and reliable hints are auto-prepended on subsequent calls.
| Name | Required | Description | Default |
|---|---|---|---|
| x | No | X coordinate (required for click) | |
| y | No | Y coordinate (required for click) | |
| text | No | Text to type or key combo like "cmd+c" (required for type/keypress) | |
| dryRun | No | Validate without executing | |
| script | No | AppleScript or JXA code (required for applescript/jxa) | |
| target | No | App name, URL, or file path (required for open) | |
| command | No | Shell command (required for shell) | |
| timeout | No | Timeout in ms (100-30000, default: 10000) | |
| actionType | Yes | Type of action to execute | |
| appContext | No | Target application name for context |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of disclosing behavioral traits. It clearly mentions permission requirements, security exclusions, and the self-learning behavior of appContext. It lacks details on return values or error handling, which could be useful, but the description is notably transparent for a command execution tool.
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 well-organized and appropriately sized for a tool with 10 parameters and 7 action types. It starts with a clear summary, lists supported actions, provides 5 diverse examples, and ends with a concise bullet list of limitations. Every sentence serves a purpose, and the structure aids scannability.
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?
The description covers the tool's capabilities, limitations, and usage patterns comprehensively. It does not describe the output/return format, but since there is no output schema, this is a minor gap. Overall, it provides enough context for an agent to select and invoke the tool correctly for most cases.
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 already provides 100% description coverage for all 10 parameters. The description adds value via concrete examples that map actionType to required params, and it explains the appContext param's role in self-learning, which goes beyond the schema description. This enriches the semantics of the parameters.
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 the tool's purpose: 'Run an AppleScript/JXA/shell command or send click/type/keypress to macOS.' It enumerates all supported action types, distinguishing this as a general execution tool. The examples and limitations further clarify its scope, making it distinct from sibling tools like mac_state or mac_find_ui.
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 provides clear context on when to use the tool by listing action types and showing examples. It also highlights important prerequisites (Accessibility/Automation permissions) and limitations (cannot bypass lock screen, dangerous shell patterns blocked). However, it does not explicitly compare against alternative sibling tools or state when not to use this tool in favor of another.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mac_screenshotA
Capture screen, window, or region as base64 PNG.
Examples:
Full screen: { target: "screen" }
Specific app window: { target: "window", windowName: "Safari" }
Region (x,y from top-left): { target: "region", region: { x: 0, y: 0, width: 800, height: 600 } }
High-fidelity capture: { target: "screen", scale: 1.0 } (warning: larger token cost)
Limitations:
Requires Screen Recording permission (System Settings → Privacy & Security → Screen Recording).
Default scale is 0.5 to keep token cost reasonable; bump for OCR-quality captures.
Cursor is not included in the capture.
| Name | Required | Description | Default |
|---|---|---|---|
| scale | No | Scale factor 0.1-1.0 (default: 0.5 for token efficiency) | |
| region | No | Region coordinates for region capture | |
| target | Yes | What to capture | |
| windowName | No | App name for window capture |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully discloses key behaviors: output format (base64 PNG), permission requirements (Screen Recording), default scale (0.5) for token efficiency, and cursor exclusion. It also warns about token cost for high-fidelity captures, providing valuable operational context.
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 front-loaded with a clear one-sentence summary, followed by well-organized examples and limitations. Every sentence provides useful information with no redundancy, balancing detail with brevity.
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 4 parameters, one nested object, and no output schema, the description covers all necessary aspects: capture modes, parameter behavior, permissions, output format, and caveats. It is sufficiently complete for an agent to correctly select and invoke this tool without ambiguity.
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?
Although the schema already describes parameters, the description adds meaningful semantics: coordinate origin for region capture, the meaning of windowName (app name), and scale's impact on token cost. The examples directly illustrate parameter combinations, adding value beyond the schema.
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?
Opening sentence 'Capture screen, window, or region as base64 PNG' uses a specific verb and resource, clearly defining the tool's function. It also distinguishes itself from sibling tools like mac_run and mac_state, which focus on execution and system state rather than screen capture.
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 provides concrete use cases with examples for each target type (screen, window, region), giving clear context for when to use each mode. It does not explicitly name alternative tools or state when not to use the tool, but the examples and limitations effectively guide usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
mac_stateA
Read current macOS state: frontmost app, windows, Finder selection, running apps.
Examples:
All state: {} (returns everything)
Window list only: { include: ["windows"] }
Frontmost app: { include: ["frontmost_app"] }
Limitations:
Window list requires Accessibility for the apps you want to see.
"clipboard" still works but
mac_clipboardis preferred (lighter + write support).
| Name | Required | Description | Default |
|---|---|---|---|
| include | No | What state to query (default: all) |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description responsibly discloses key behaviors: empty input returns all state, window listing depends on Accessibility, and clipboard functionality is supported but deprecated in favor of a sibling tool. It does not describe the output format or potential side effects, but for a read-only state tool that is acceptable.
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 compact, well-organized into overview, examples, and limitations. Each sentence serves a distinct purpose: defining scope, demonstrating usage, and flagging caveats. There is no fluff or redundancy.
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?
The tool is simple (one optional parameter) and the description covers all enum values, usage, and limitations. However, with no output schema, it would be stronger to hint at the structure of the returned state. Still, for its complexity, it is sufficiently complete.
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 the 'include' parameter with enum values and a default, giving baseline coverage. The description adds value by showing exactly how to pass values in examples and clarifying that omitting include returns everything, which enriches the schema's meaning.
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 and resource: 'Read current macOS state,' and enumerates the exact aspects (frontmost app, windows, Finder selection, running apps). It distinguishes itself from siblings by explicitly noting that the clipboard is better served by mac_clipboard, making the tool's scope clear.
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 provides concrete usage examples for all state, window-only, and frontmost-app queries. It also gives clear exclusions: the clipboard works but mac_clipboard is preferred, and window listing requires Accessibility permissions. This gives an agent explicit guidance on when and how to invoke the tool.
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. Dates show when Glama detected each change.
11 tool updates
v0.4.1- First observed
mac_clipboard - First observed
mac_find_ui - First observed
mac_permissions - First observed
mac_recipe_export - First observed
mac_recipe_import - First observed
mac_recipe_run - First observed
mac_recipe_save - First observed
mac_recipe_search - First observed
mac_run - First observed
mac_screenshot - First observed
mac_state
TDQS
Each tool targets a distinct aspect of macOS automation: mac_run executes commands, mac_state reads system state, mac_clipboard manages the clipboard, mac_find_ui inspects UI elements, mac_screenshot captures the screen, and the recipe* tools cover the full recipe lifecycle. There is no meaningful overlap; even mac_run and mac_recipe_run are clearly separated by ad-hoc vs saved workflows.
All tools share the mac_ prefix and use snake_case, but the verb/noun order varies: mac_run and mac_find_ui are verb-first, while mac_state and mac_permissions are noun-first, and recipe tools use recipe_verb (e.g., mac_recipe_export). This is a minor deviation from a fully consistent verb_noun pattern but remains predictable and readable.
With 11 tools, the server is well-scoped for macOS automation. It covers command execution, state inspection, clipboard, UI inspection, screenshots, permissions, and a complete recipe subsystem without bloating. The count sits comfortably in the ideal 3-15 range and each tool earns its place.
The tool surface covers core automation actions (run, state, UI, screenshot, clipboard) and a full recipe lifecycle (save, run, search, export, import). Minor gaps exist, such as no explicit recipe deletion or a dedicated list-all tool, but these can be worked around via search or export, so agent workflows are not severely hindered.
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Related MCP Connectors
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
Automate 1,000+ services from any MCP-compatible AI agent: build Applets, run actions and queries.
Melaya is a remote MCP server. It gives an assistant hands on your own Android phone and browser: it reads the screen through the accessibility tree, then taps, types and navigates inside the apps and sites you allow-list, with no per-app API. It also builds, schedules and runs agent pipelines across 6k+ connected tools. OAuth 2.1, nothing to install.
MCP connector that lets ChatGPT list, search, and run your Apple Shortcuts via a local Mac agent
Related MCP Servers
- AlicenseNot gradedqualityDmaintenanceAn MCP server for macOS that enables AI agents to control the desktop GUI through keyboard input, mouse actions, and screen captures. It provides stable low-level primitives for UI automation and agent-driven desktop workflows.MIT
- AlicenseNot gradedqualityBmaintenanceAn MCP server that gives any AI assistant eyes and hands on your desktop — screenshots, clicking, typing, OCR, window management, accessibility-tree queries, workflow recording.5Apache 2.0
- AlicenseNot gradedqualityCmaintenanceStandalone MCP server that gives AI agents full GUI control over macOS — screenshots, mouse, keyboard, apps, clipboard, and multi-display — with zero private dependencies.18MIT
- AlicenseNot gradedqualityDmaintenanceMCP server that enables AI to fully control macOS — mouse, keyboard, terminal, screenshots, window management, UI element detection, and provides AI-optimized information reporting.20MIT
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/leesgit/mac-pilot-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server