macOS Automator MCP Server
The macOS Automator MCP Server enables remote execution of AppleScript and JavaScript for Automation (JXA) scripts on macOS, facilitating control of applications and system functions through:
Script execution methods: Run scripts inline, from file paths, or via pre-defined knowledge base entries with support for arguments and placeholder substitution
Application control: Automate Safari, Chrome, Finder, Mail, Calendar, Music and other macOS applications
System operations: Manage files/folders, clipboard, notifications, Terminal commands, system settings (dark mode, volume)
Discovery tools: Use
get_scripting_tipsto find pre-built automation solutions by keywords or categoriesCustomization options: Set execution parameters (timeout, language, output formatting), add debugging information, and extend automation capabilities with local scripts
Integration potential: Incorporate macOS automation into larger AI-driven workflows
Supports JavaScript for Automation (JXA) to automate macOS applications and system tasks, with ability to execute scripts directly or reference them from a knowledge base.
Enables execution of AppleScript and JavaScript for Automation (JXA) to control macOS applications and system functions, with capabilities for file operations, terminal automation, system settings control, clipboard management, and application-specific integrations.
Returns formatted Markdown content for scripting tips and examples from the knowledge base, making documentation accessible through the get_scripting_tips tool.
Allows control of Safari browser, including retrieving tab URLs, navigating to websites, executing JavaScript in the browser context, and extracting page content.
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., "@macOS Automator MCP Serverextract all URLs from my current Safari tabs and save them to a text file"
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.
macOS Automator MCP 🤖 — Give your agent a Mac to operate

macOS Automator MCP is a Model Context Protocol server that lets MCP clients discover and run AppleScript or JavaScript for Automation (JXA). It is for agents that need to control macOS applications, inspect the system, or reuse scripts from a bundled knowledge base.
Install
You need macOS and Node.js 24 or newer. Add the server to your MCP client's configuration; npx downloads the current npm release when the client starts it.
{
"mcpServers": {
"macos_automator": {
"command": "npx",
"args": ["-y", "--package", "@steipete/macos-automator-mcp", "macos-automator-mcp"]
}
}
}If your client has a separate package field, use @steipete/macos-automator-mcp without @latest.
Related MCP server: Keynote-MCP
Quick start
Restart your MCP client after adding the configuration. First, ask it to call get_scripting_tips with a small search:
{
"search_term": "Safari front tab URL",
"limit": 3
}Then verify script execution with a read-only inline script through execute_script:
{
"script_content": "return \"Hello from macOS Automator\""
}The result is Hello from macOS Automator. Calls that control applications or the user interface may prompt for macOS permissions.
Tools
Tool | Purpose |
| List knowledge-base categories or search for AppleScript and JXA tips. |
| Run one inline script, script file, or knowledge-base script ID. |
Use get_scripting_tips before writing a script from scratch. A returned runnable ID can be passed to execute_script as kb_script_id; scripts with placeholders accept named input_data or positional arguments.
execute_script runs with the privileges of the process hosting the MCP server. Only run scripts you trust, and inspect generated scripts before allowing destructive actions. See the tool reference for every input and response option.
Permissions
The application that launches the MCP server—such as Terminal, an editor, or a desktop MCP client—owns its macOS privacy permissions:
Grant Automation access when scripts control Finder, Safari, Mail, or another application.
Grant Accessibility access when scripts use System Events for clicks, keystrokes, menus, or other UI scripting.
macOS may show a first-use prompt for each target application. The server cannot grant these permissions itself. See configuration and permissions for setup and common error codes.
Knowledge base
The package includes hundreds of AppleScript and JXA tips covering system tasks, files, browsers, terminals, productivity apps, developer tools, and UI automation. Search by keyword or category, then execute a result by its runnable ID.
A local knowledge base can add or override bundled tips without changing the package. It defaults to ~/.macos-automator/knowledge_base; see configuration and permissions for its layout and override rules.
Configuration
Variable | Values | Default |
|
|
|
|
|
|
| Absolute path to a custom knowledge base |
|
lazy loads the knowledge base on first use; eager loads it at server startup. More detail is in configuration and permissions.
Troubleshooting
Permission errors such as
-1743or-10004usually mean the host application needs Automation or Accessibility access.Script syntax errors are easiest to isolate with
include_executed_script_in_outputandinclude_substitution_logs, then reproduce in Script Editor.Use an absolute POSIX path with
script_path, and raisetimeout_secondsfor scripts that legitimately need more than 60 seconds.JXA normally works best with
output_format_mode: "direct"; the defaultautomode selects it for JXA.
See Debugging AppleScript and JXA for a longer diagnostic guide.
Development
pnpm install
pnpm run build
pnpm test
pnpm run lint
pnpm run validateThe repository uses pnpm 11 and Node.js 24. The development guide covers local server setup and knowledge-base contributions.
Community
Report bugs and propose scripts in GitHub Issues.
License
Available Tools
2 toolsexecute_scriptADestructive
Automate macOS tasks using AppleScript or JXA (JavaScript for Automation) to control applications like Terminal, Chrome, Safari, Finder, etc.
1. Script Source (Choose one):
kb_script_id(string): Preferred. Executes a pre-defined script from the knowledge base by its ID. Useget_scripting_tipsto find IDs and inputs. Supports placeholder substitution viainput_dataorarguments. Ex:kb_script_id: "safari_get_front_tab_url".script_content(string): Executes raw AppleScript/JXA code. Good for simple or dynamic scripts. Ex:script_content: "tell application \"Finder\" to empty trash".script_path(string): Executes a script from an absolute POSIX path on the server. Ex:/Users/user/myscripts/myscript.applescript.
2. Script Inputs (Optional):
input_data(JSON object): Forkb_script_id, provides named inputs (e.g.,--MCP_INPUT:keyName). Values (string, number, boolean, simple array/object) are auto-converted. Ex:input_data: { "folder_name": "New Docs" }.arguments(array of strings): Forscript_path(passes toon run argv/run(argv)). Forkb_script_id, used for positional args (e.g.,--MCP_ARG_1).
3. Execution Options (Optional):
language('applescript' | 'javascript'): Specify forscript_content/script_path(default: 'applescript'). Inferred forkb_script_id.timeout_seconds(integer, optional, default: 60): Sets the maximum time (in seconds) the script is allowed to run. Increase for potentially long-running operations.output_format_mode(enum, optional, default: 'auto'): Controlsosascriptoutput formatting.'auto': Smart default - resolves to'human_readable'for AppleScript and'direct'for JXA.'human_readable': For AppleScript, uses-s hflag.'structured_error': For AppleScript, uses-s sflag (structured errors).'structured_output_and_error': For AppleScript, uses-s ssflag (structured output & errors).'direct': No special output flags (recommended for JXA).
include_executed_script_in_output(boolean, optional, default: false): Iftrue, the final script content (after any placeholder substitutions) or script path that was executed will be included in the response. This is useful for debugging and understanding exactly what was run. Defaults to false.include_substitution_logs(boolean, default: false): Forkb_script_id, includes detailed placeholder substitution logs.report_execution_time(boolean, optional, default: false): Iftrue, an additional message with the formatted script execution time will be included in the response. Defaults to false.
| Name | Required | Description | Default |
|---|---|---|---|
| language | No | Specifies the scripting language. Crucial for `script_content` and `script_path` if not 'applescript'. Defaults to 'applescript'. Inferred if using `kb_script_id`. | |
| arguments | No | Optional arguments to pass to the script. For AppleScript, these are passed to the main `run` handler. For JXA, these are passed to the `run` function. | |
| input_data | No | Optional JSON object to provide named inputs for --MCP_INPUT placeholders in knowledge base scripts. | |
| script_path | No | The path to the script file to execute. Required if kb_script_id or script_content is not provided. | |
| kb_script_id | No | The ID of a knowledge base script to execute. Replaces script_content and script_path if provided. | |
| script_content | No | The content of the script to execute. Required if kb_script_id or script_path is not provided. | |
| timeout_seconds | No | The timeout for the script execution in seconds. Defaults to 60. | |
| output_format_mode | No | Controls osascript output formatting. 'auto': (Default) Smart selection based on language (AppleScript: human_readable, JXA: direct). 'human_readable': AppleScript -s h. 'structured_error': AppleScript -s s. 'structured_output_and_error': AppleScript -s ss. 'direct': No -s flags (recommended for JXA). | auto |
| report_execution_time | No | If true, the tool will return an additional message containing the formatted script execution time. Defaults to false. | |
| include_substitution_logs | No | If true, detailed logs of placeholder substitutions will be included in the output. | |
| include_executed_script_in_output | No | If true, the executed script content (after substitutions) or path will be included in the output. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations indicate destructiveHint=true. The description adds details about execution options like timeout, output formatting, and debugging flags such as including executed script, substitution logs, and execution time, which are beyond the annotation.
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 verbose but well-structured with numbered sections and bullet points. It front-loads the purpose and organizes parameters logically. Could be slightly shorter, but every section adds useful context.
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 11 parameters, no output schema, and destructive nature, the description covers script sources, inputs, and all execution options. It lacks explicit mention of return values but provides output formatting options and debugging features.
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 baseline is 3. The description provides extensive parameter explanations with examples and usage details (e.g., JSON input substitution), adding significant value beyond schema descriptions.
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 first sentence clearly states the tool's purpose: 'Automate macOS tasks using AppleScript or JXA... to control applications.' It uses specific verbs and resources, and distinguishes itself from the sibling tool 'get_scripting_tips'.
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 advises using 'get_scripting_tips' to find script IDs, providing guidance on script source selection. It explains when to use each script source but does not explicitly state when not to use the tool, though the destructive hint implies caution.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_scripting_tipsARead-only
Discover how to automate any app on your Mac with this comprehensive knowledge base of AppleScript/JXA tips and runnable scripts. This tool is essential for discovery and should be the FIRST CHOICE when aiming to automate macOS tasks, especially those involving common applications or system functions, before attempting to write scripts from scratch. It helps identify pre-built, tested solutions, effectively teaching you how to control virtually any aspect of your macOS experience.
Primary Use Cases & Parameters:
Discovering Solutions (Use
search_term):Parameter:
search_term(string, optional).Functionality: Performs a fuzzy search across all tip titles, descriptions, keywords, script content, and IDs. Ideal for natural language queries like "how to..." (e.g.,
search_term: "how do I get the current Safari URL and title?"). This is the most common way to find relevant tips.Output: Returns a list of matching tips in Markdown format.
Limiting Search Results (Use
limit):Parameter:
limit(integer, optional, default: 10).Functionality: Specifies the maximum number of script tips to return when using
search_termor browsing a specificcategory(withoutlist_categories: true). Does not apply iflist_categoriesis true.
Browsing by Category (Use
category):Parameter:
category(string, optional).Functionality: Shows tips from a specific category. Combine with
limitto control result count.Example:
category: "01_intro"orcategory: "07_browsers/chrome".
Listing All Categories (Use
list_categories: true):Parameter:
list_categories(boolean, optional).Functionality: Returns a structured list of all available categories with their descriptions. This helps you understand what automation areas are covered.
Output: Category tree in Markdown format.
Refreshing Database (Use
refresh_database: true):Parameter:
refresh_database(boolean, optional).Functionality: Forces a reload of the knowledge base if new scripts have been added. Typically not needed as the database refreshes automatically.
Best Practices:
Always start with search: Use natural language queries to find solutions (e.g., "send email from Mail app").
Browse categories when exploring: Use
list_categories: trueto see available automation areas.Use specific IDs for execution: Once you find a script, use its ID with
execute_scripttool for precise execution.
| Name | Required | Description | Default |
|---|---|---|---|
| limit | No | Maximum number of results to return. Default is 10. | |
| category | No | Specific category of tips. If omitted with no `search_term`, lists all categories. | |
| search_term | No | Keyword to search within tip titles, content, keywords, or IDs. | |
| list_categories | No | If true, returns only the list of available categories and their descriptions. Overrides other parameters. | |
| refresh_database | No | If true, forces a reload of the knowledge base before processing the request. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
While annotations already mark it as read-only, the description adds substantial behavioral context: returns results in Markdown, describes refresh_database behavior, and explains how parameters like search_term and category affect output.
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 sections and clear front-loading, but it is lengthy. However, every section earns its place given the tool's complexity and five parameters.
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?
Comprehensive coverage: parameter semantics, best practices, sibling tool context, and output format are all addressed. No output schema exists, so the description adequately explains what the tool returns.
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 adds significant value by explaining parameter interactions (e.g., list_categories overrides), providing example queries for search_term, and detailing default behaviors like limit.
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: discovering and retrieving pre-built AppleScript/JXA tips for macOS automation. It distinguishes itself from the sibling tool 'execute_script' by emphasizing that this tool is for discovery before 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?
Explicitly states when to use this tool (first choice for automation tasks) and provides guidance on alternatives (e.g., use execute_script for running scripts). Includes best practices like starting with search and browsing categories.
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.
2 tool updates
v1.0.0- Changed
execute_script21 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / arguments / descriptionAdded value: +"Optional arguments to pass to the script. For AppleScript, these are passed to the main `run` handler. For JXA, these are passed to the `run` function." - added
Input schema / properties / include_executed_script_in_output / defaultAdded value: +false - added
Input schema / properties / include_executed_script_in_output / descriptionAdded value: +"If true, the executed script content (after substitutions) or path will be included in the output." - added
Input schema / properties / include_substitution_logs / defaultAdded value: +false - added
Input schema / properties / include_substitution_logs / descriptionAdded value: +"If true, detailed logs of placeholder substitutions will be included in the output." - added
Input schema / properties / input_data / descriptionAdded value: +"Optional JSON object to provide named inputs for --MCP_INPUT placeholders in knowledge base scripts." - added
Input schema / properties / input_data / propertiesAdded value: +{} - added
Input schema / properties / kb_script_id / descriptionAdded value: +"The ID of a knowledge base script to execute. Replaces script_content and script_path if provided." - added
Input schema / properties / language / descriptionAdded value: +"Specifies the scripting language. Crucial for `script_content` and `script_path` if not 'applescript'. Defaults to 'applescript'. Inferred if using `kb_script_id`." - added
Input schema / properties / output_format_mode / defaultAdded value: +"auto" - added
Input schema / properties / output_format_mode / descriptionAdded value: +"Controls osascript output formatting. \n'auto': (Default) Smart selection based on language (AppleScript: human_readable, JXA: direct). \n'human_readable': AppleScript -s h. \n'structured_error': AppleScript -s s. \n'structured_output_and_error': AppleScript -s ss. \n'direct': No -s flags (recommended for JXA)." - added
Input schema / properties / report_execution_time / defaultAdded value: +false - added
Input schema / properties / report_execution_time / descriptionAdded value: +"If true, the tool will return an additional message containing the formatted script execution time. Defaults to false." - added
Input schema / properties / script_content / descriptionAdded value: +"The content of the script to execute. Required if kb_script_id or script_path is not provided." - added
Input schema / properties / script_path / descriptionAdded value: +"The path to the script file to execute. Required if kb_script_id or script_content is not provided." - added
Input schema / properties / timeout_seconds / defaultAdded value: +60 - added
Input schema / properties / timeout_seconds / descriptionAdded value: +"The timeout for the script execution in seconds. Defaults to 60." - added
Input schema / properties / timeout_seconds / maximumAdded value: +9007199254740991 - added
Input schema / properties / timeout_seconds / minimumAdded value: +-9007199254740991 - changed
Input schema / properties / timeout_seconds / typePrevious value: -"number"New value: +"integer"
- Changed
get_scripting_tips9 fields changed- removed
Input schema / additionalPropertiesRemoved value: -false - added
Input schema / properties / category / descriptionAdded value: +"Specific category of tips. If omitted with no `search_term`, lists all categories." - added
Input schema / properties / limit / defaultAdded value: +10 - added
Input schema / properties / limit / descriptionAdded value: +"Maximum number of results to return. Default is 10." - added
Input schema / properties / limit / maximumAdded value: +9007199254740991 - added
Input schema / properties / list_categories / defaultAdded value: +false - added
Input schema / properties / list_categories / descriptionAdded value: +"If true, returns only the list of available categories and their descriptions. Overrides other parameters." - added
Input schema / properties / refresh_database / descriptionAdded value: +"If true, forces a reload of the knowledge base before processing the request." - added
Input schema / properties / search_term / descriptionAdded value: +"Keyword to search within tip titles, content, keywords, or IDs."
2 tool updates
- First observed
execute_script - First observed
get_scripting_tips
TDQS
The two tools have clearly distinct purposes: execute_script runs scripts, while get_scripting_tips discovers scripts and provides knowledge. No overlap in functionality, making it easy for an agent to choose correctly.
Both tool names follow a consistent verb_noun pattern in snake_case (execute_script, get_scripting_tips), which is predictable and clear.
With only 2 tools, the server feels underdeveloped for a comprehensive macOS automation tool. While execution and discovery are covered, a richer toolset (e.g., script management, system status) would be expected. The count is borderline for the apparent scope.
The server covers the core needs of executing scripts and discovering pre-built solutions via a knowledge base. However, it lacks tools for managing scripts (e.g., listing custom scripts, editing them) and more direct system control. Some workflows may require more than these two tools.
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
A comprehensive Model Context Protocol (MCP) server that enables AI assistants to interact with yo…
Model Context Protocol server for Studex tools, notifications, and profile integrations
A Model Context Protocol server for Wix AI tools
Personal assistant MCP server with search, execute, packages, jobs, secrets, and integrations.
Related MCP Servers
- AlicenseAqualityFmaintenanceA Model Context Protocol server that enables running AppleScript code to interact with Mac applications and system features including Notes, Calendar, Contacts, Messages, file management, and more.1123463MIT
- AlicenseNot gradedqualityDmaintenanceA Model Context Protocol server that enables AI assistants to control Apple Keynote presentations through AppleScript automation, supporting comprehensive slide creation, management, and content operations.75MIT
- AlicenseBqualityDmaintenanceA Model Context Protocol server that enables direct integration with macOS Calendar application using AppleScript, allowing users to create, list, and search calendar events without requiring OAuth setup.86MIT
- AlicenseAqualityDmaintenanceA Model Context Protocol server that enables execution of AppleScript and JavaScript for Automation scripts on macOS, allowing programmatic control of applications and system functions through a rich knowledge base of pre-defined scripts.21,2948MIT
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/steipete/macos-automator-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server