Skip to main content
Glama
steipete

macOS Automator MCP Server

by steipete

macOS Automator MCP 🤖 - Your Friendly Neighborhood RoboScripter™

macOS Automator MCP Server

🎯 Mission Control: Teaching Robots to Click Buttons Since 2024

Welcome to the automated future where your Mac finally does what you tell it to! This Model Context Protocol (MCP) server transforms your AI assistant into a silicon-based intern who actually knows AppleScript and JavaScript for Automation (JXA).

No more copy-pasting scripts like a caveman - let the robots handle the robot work! Our knowledge base contains over 200 pre-programmed automation sequences, loaded faster than you can say "Hey Siri, why don't you work like this?"

Related MCP server: Keynote-MCP

🚀 Why Let Robots Run Your Mac?

  • Remote Control Reality: Execute AppleScript/JXA scripts via MCP - it's like having a tiny robot inside your Mac!

  • Knowledge Base of Power: 200+ pre-built automation recipes. From "toggle dark mode" to "extract all URLs from Safari" - we've got your robot needs covered.

  • App Whisperer: Control any macOS application programmatically. Make Finder dance, Safari sing, and Terminal... well, terminate things.

  • AI Workflow Integration: Connect your Mac to the AI revolution. Your LLM can now actually DO things instead of just talking about them!

🔧 Robot Requirements (Prerequisites)

  • Node.js (version >=24.0.0) - Because even robots need a runtime

  • macOS - Sorry Windows users, this is an Apple-only party 🍎

  • ⚠️ CRITICAL: Permission to Automate (Your Mac's Trust Issues):

    • The application running THIS MCP server (e.g., Terminal, your Node.js application) requires explicit user permissions on the macOS machine where the server is running.

    • Automation Permissions: To control other applications (Finder, Safari, Mail, etc.).

      • Go to: System Settings > Privacy & Security > Automation.

      • Find the application running the server (e.g., Terminal) in the list.

      • Ensure it has checkboxes ticked for all applications it needs to control.

      • See example: docs/automation-permissions-example.png (placeholder image).

    • Accessibility Permissions: For UI scripting via "System Events" (e.g., simulating clicks, keystrokes).

      • Go to: System Settings > Privacy & Security > Accessibility.

      • Add the application running the server (e.g., Terminal) to the list and ensure its checkbox is ticked.

    • First-time attempts to control a new application or use accessibility features may still trigger a macOS confirmation prompt, even if pre-authorized. The server itself cannot grant these permissions.

🏃‍♂️ Quick Start: Release the Robots!

The easiest way to deploy your automation army is via npx. No installation needed - just pure robot magic!

Add this to your MCP client's mcp.json and watch the automation begin:

{
  "mcpServers": {
    "macos_automator": {
      "command": "npx",
      "args": ["-y", "@steipete/macos-automator-mcp@latest"]
    }
  }
}

🛠️ Robot Workshop Mode (Local Development)

Want to tinker with the robot's brain? Clone the repo and become a robot surgeon!

  1. Clone the repository:

    git clone https://github.com/steipete/macos-automator-mcp.git
    cd macos-automator-mcp
    pnpm install # Ensure dependencies are installed
  2. Configure your MCP client: Update your MCP client's configuration to point to the absolute path of the start.sh script within your cloned repository.

    Example mcp.json configuration snippet:

    {
      "mcpServers": {
        "macos_automator_local": {
          "command": "/absolute/path/to/your/cloned/macos-automator-mcp/start.sh",
          "env": {
            "LOG_LEVEL": "DEBUG"
          }
        }
      }
    }

    Important: Replace /absolute/path/to/your/cloned/macos-automator-mcp/start.sh with the correct absolute path on your system.

    The start.sh script will automatically use tsx to run the TypeScript source directly if a compiled version is not found, or run the compiled version from dist/ if available. It respects the LOG_LEVEL environment variable.

    Note for Developers: The start.sh script, particularly if modified to remove any pre-existing compiled dist/server.js before execution (e.g., by adding rm -f dist/server.js), is designed to ensure you are always running the latest TypeScript code from the src/ directory via tsx. This is ideal for development to prevent issues with stale builds. For production deployment (e.g., when published to npm), a build process would typically create a definitive dist/server.js which would then be the entry point for the published package.

🤖 Robot Toolbox

1. execute_script - The Script Launcher 9000

Your robot's primary weapon for macOS domination. Feed it AppleScript or JXA, and watch the magic happen! Scripts can be provided as inline content (script_content), an absolute file path (script_path), or by referencing a script from the built-in knowledge base using its unique kb_script_id.

Script Sources (mutually exclusive):

  • script_content (string): Raw script code.

  • script_path (string): Absolute POSIX path to a script file (e.g., .applescript, .scpt, .js).

  • kb_script_id (string): The ID of a pre-defined script from the server's knowledge base. Use the get_scripting_tips tool to discover available script IDs and their functionalities.

Language Specification:

  • language (enum: 'applescript' | 'javascript', optional): Specify the language.

    • If using kb_script_id, the language is inferred from the knowledge base script.

    • If using script_content or script_path and language is omitted, it defaults to 'applescript'.

Passing Inputs to Scripts:

  • arguments (array of strings, optional):

    • For script_path: Passed as standard arguments to the script's on run argv (AppleScript) or run(argv) (JXA) handler.

    • For kb_script_id: Used if the pre-defined script is designed to accept positional string arguments (e.g., replaces placeholders like --MCP_ARG_1, --MCP_ARG_2). Check the script's argumentsPrompt from get_scripting_tips.

  • input_data (JSON object, optional):

    • Primarily for kb_script_id scripts designed to accept named, structured inputs.

    • Values from this object replace placeholders in the script (e.g., --MCP_INPUT:yourKeyName). See argumentsPrompt from get_scripting_tips.

    • Values (strings, numbers, booleans, simple arrays/objects) are converted to their AppleScript literal equivalents.

Other Options:

  • timeout_seconds (integer, optional, default: 60): Maximum execution time.

  • output_format_mode (enum, optional, default: 'auto'): Controls osascript output formatting flags.

    • 'auto': (Default) Uses human-readable for AppleScript (-s h), and direct output (no -s flags) for JXA.

    • 'human_readable': Forces -s h (human-readable output, mainly for AppleScript).

    • 'structured_error': Forces -s s (structured error reporting, mainly for AppleScript).

    • 'structured_output_and_error': Forces -s ss (structured output for main result and errors, mainly for AppleScript).

    • 'direct': No -s flags are used (recommended for JXA, also the behavior for JXA in auto mode).

  • include_executed_script_in_output (boolean, optional, default: false): If true, the output will include the full script content (after any placeholder substitutions for knowledge base scripts) or the script path that was executed. This is appended as an additional text part in the output content array.

  • include_substitution_logs (boolean, optional, default: false): If true, detailed logs of placeholder substitutions performed on knowledge base scripts are included in the output. This is useful for debugging how input_data and arguments are processed and inserted into the script. The logs are prepended to the script output on success or appended to the error message on failure.

  • report_execution_time (boolean, optional, default: false): If true, an additional message with the formatted script execution time will be included in the response content array.

SECURITY WARNING & MACOS PERMISSIONS: (Same critical warnings as before about arbitrary script execution and macOS Automation/Accessibility permissions).

Examples:

  • (Existing examples for inline/file path remain relevant)

  • Using Knowledge Base Script by ID:

    {
      "toolName": "execute_script",
      "input": {
        "kb_script_id": "safari_get_active_tab_url",
        "timeout_seconds": 10
      }
    }
  • Using Knowledge Base Script by ID with input_data:

    {
      "toolName": "execute_script",
      "input": {
        "kb_script_id": "finder_create_folder_at_path",
        "input_data": {
          "folder_name": "New MCP Folder",
          "parent_path": "~/Desktop"
        }
      }
    }

Response Format:

The execute_script tool returns a response in the following format:

{
  content: Array<{
    type: 'text';
    text: string;
  }>;
  isError?: boolean;
}
  • content: An array of text content items containing the script output

  • isError: (boolean, optional) Set to true when the script execution produced an error. This flag is set when:

    • The script output (stdout) starts with "Error" (case-insensitive)

    • This helps clients easily determine if the execution failed without parsing the output text

Example Response (Success):

{
  "content": [
    {
      "type": "text",
      "text": "Script executed successfully"
    }
  ]
}

Example Response (Error):

{
  "content": [
    {
      "type": "text",
      "text": "Error: Cannot find application 'Safari'"
    }
  ],
  "isError": true
}

2. get_scripting_tips - The Robot's Encyclopedia

Your personal automation librarian! Searches through 200+ pre-built scripts faster than you can Google "how to AppleScript". Perfect for when your robot needs inspiration.

Arguments:

  • list_categories (boolean, optional, default: false): If true, returns only the list of available knowledge base categories and their descriptions. Overrides other parameters.

  • category (string, optional): Filters tips by a specific category ID (e.g., "finder", "safari").

  • search_term (string, optional): Searches for a keyword within tip titles, descriptions, script content, keywords, or IDs.

  • refresh_database (boolean, optional, default: false): If true, forces a reload of the entire knowledge base from disk before processing the request. This is useful during development if you are actively modifying knowledge base files and want to ensure the latest versions are used without restarting the server.

  • limit (integer, optional, default: 10): Maximum number of results to return.

Output:

  • Returns a Markdown formatted string containing the requested tips, including their title, description, script content, language, runnable ID (if applicable), argument prompts, and notes.

Example Usage:

  • List all categories: { "toolName": "get_scripting_tips", "input": { "list_categories": true } }

  • Get tips for "safari" category: { "toolName": "get_scripting_tips", "input": { "category": "safari" } }

  • Search for tips related to "clipboard": { "toolName": "get_scripting_tips", "input": { "search_term": "clipboard" } }

3. accessibility_query - The UI X-Ray Vision

Give your robot superhero powers to see and click ANY button in ANY app! This tool peers into the soul of macOS applications using the accessibility framework. Powered by the mystical ax binary, it's like having X-ray vision for user interfaces.

The ax binary, and therefore this tool, can accept its JSON command input in multiple ways:

  1. Direct JSON String Argument: If ax is invoked with a single command-line argument that is not a valid file path, it will attempt to parse this argument as a complete JSON string.

  2. File Path Argument: If ax is invoked with a single command-line argument that is a valid file path, it will read the complete JSON command from this file.

  3. STDIN: If ax is invoked with no command-line arguments, it will read the complete JSON command (which can be multi-line) from standard input.

This tool exposes the complete macOS accessibility API capabilities, allowing detailed inspection of UI elements and their properties. It's particularly useful for automating interactions with applications that don't have robust AppleScript support or when you need to inspect the UI structure in detail.

Input Parameters:

  • command (enum: 'query' | 'perform', required): The operation to perform.

    • query: Retrieves information about UI elements.

    • perform: Executes an action on a UI element (like clicking a button).

  • locator (object, required): Specifications to find the target element(s).

    • app (string, required): The application to target, specified by either bundle ID or display name (e.g., "Safari", "com.apple.Safari").

    • role (string, required): The accessibility role of the target element (e.g., "AXButton", "AXStaticText").

    • match (object, required): Key-value pairs of attributes to match. Can be empty ({}) if not needed.

    • navigation_path_hint (array of strings, optional): Path to navigate within the application hierarchy (e.g., ["window[1]", "toolbar[1]"]).

  • return_all_matches (boolean, optional): When true, returns all matching elements rather than just the first match. Default is false.

  • attributes_to_query (array of strings, optional): Specific attributes to query for matched elements. If not provided, common attributes will be included. Examples: ["AXRole", "AXTitle", "AXValue"]

  • required_action_name (string, optional): Filter elements to only those supporting a specific action (e.g., "AXPress" for clickable elements).

  • action_to_perform (string, optional, required when command="perform"): The accessibility action to perform on the matched element (e.g., "AXPress" to click a button).

  • report_execution_time (boolean, optional): If true, the tool will return an additional message containing the formatted script execution time. Defaults to false.

  • limit (integer, optional): Maximum number of lines to return in the output. Defaults to 500. Output will be truncated if it exceeds this limit.

  • max_elements (integer, optional): For return_all_matches: true queries, this specifies the maximum number of UI elements the ax binary will fully process and return attributes for. If omitted, an internal default (e.g., 200) is used. This helps manage performance when querying UIs with a very large number of matching elements (like numerous text fields on a complex web page). This is different from limit, which truncates the final text output based on lines.

  • debug_logging (boolean, optional): If true, enables detailed debug logging from the underlying ax binary. This diagnostic information will be included in the response, which can be helpful for troubleshooting complex queries or unexpected behavior. Defaults to false.

  • output_format (enum: 'smart' | 'verbose' | 'text_content', optional, default: 'smart'): Controls the format and verbosity of the attribute output from the ax binary.

    • 'smart': (Default) Optimized for readability. Omits attributes with empty or placeholder values. Returns key-value pairs.

    • 'verbose': Maximum detail. Includes all attributes, even empty/placeholders. Key-value pairs. Best for debugging element properties.

    • 'text_content': Highly compact for text extraction. Returns only concatenated text values of common textual attributes (e.g., AXValue, AXTitle). No keys are returned. Ideal for quickly getting all text from elements; the attributes_to_query parameter is ignored in this mode.

Example Queries (Note: key names have changed to snake_case):

  1. Find all text elements in the front Safari window:

    {
      "command": "query",
      "return_all_matches": true,
      "locator": {
        "app": "Safari",
        "role": "AXStaticText",
        "match": {},
        "navigation_path_hint": ["window[1]"]
      }
    }
  2. Find and click a button with a specific title:

    {
      "command": "perform",
      "locator": {
        "app": "System Settings",
        "role": "AXButton",
        "match": { "AXTitle": "General" }
      },
      "action_to_perform": "AXPress"
    }
  3. Get detailed information about the focused UI element:

    {
      "command": "query",
      "locator": {
        "app": "Mail",
        "role": "AXTextField",
        "match": { "AXFocused": "true" }
      },
      "attributes_to_query": [
        "AXRole",
        "AXTitle",
        "AXValue",
        "AXDescription",
        "AXHelp",
        "AXPosition",
        "AXSize"
      ]
    }

Note: Using this tool requires that the application running this server has the necessary Accessibility permissions in macOS System Settings > Privacy & Security > Accessibility.

🎮 Robot Playground: Cool Things Your New Robot Friend Can Do

  • Application Control (Teaching Apps Who's Boss):

    • Get the current URL from Safari: { "input": { "script_content": "tell application \"Safari\" to get URL of front document" } }

    • Get subjects of unread emails in Mail: { "input": { "script_content": "tell application \"Mail\" to get subject of messages of inbox whose read status is false" } }

  • File System Operations (Digital Housekeeping):

    • List files on the Desktop: { "input": { "script_content": "tell application \"Finder\" to get name of every item of desktop" } }

    • Create a new folder: { "input": { "script_content": "tell application \"Finder\" to make new folder at desktop with properties {name:\"Robot's Secret Stash\"}" } }

  • System Interactions (Mac Mind Control):

    • Display a system notification: { "input": { "script_content": "display notification \"🤖 Beep boop! Task complete!\" with title \"Robot Report\"" } }

    • Set system volume: { "input": { "script_content": "set volume output volume 50" } } (0-100)

    • Get current clipboard content: { "input": { "script_content": "the clipboard" } }

🔧 When Robots Rebel (Troubleshooting)

  • "Access Denied" Drama: Your robot lacks permissions! Check System Settings > Privacy & Security. Give your Terminal the keys to the kingdom.

  • Script Syntax Sadness: Even robots make typos. Test scripts in Script Editor first - it's like spell-check for automation.

  • Timeout Tantrums: Some tasks take time. Increase timeout_seconds if your robot needs more than 60 seconds to complete its mission.

  • File Not Found Fiasco: Robots need absolute paths, not relative ones. No shortcuts in robot land!

  • JXA Output Oddities: JavaScript robots are picky. Use output_format_mode: 'direct' or let 'auto' mode handle it.

🎛️ Robot Control Panel (Configuration)

Fine-tune your robot's behavior with these environment variables:

  • LOG_LEVEL: How chatty should your robot be?

    • DEBUG: Robot tells you EVERYTHING (TMI mode)

    • INFO: Normal robot chatter

    • WARN: Only important stuff

    • ERROR: Silent mode (robot speaks only when things explode)

    • Example: LOG_LEVEL=DEBUG npx @steipete/macos-automator-mcp@latest

  • KB_PARSING: When should the robot load its brain?

    • lazy (default): Loads knowledge on-demand (fast startup, lazy robot)

    • eager: Loads everything at startup (slower start, ready-to-go robot)

    • Example: KB_PARSING=eager ./start.sh

👨‍🔬 Robot Scientists Welcome!

Want to upgrade your robot? Check out DEVELOPMENT.md for the full technical manual on teaching new tricks to your automation assistant.

🧠 Teach Your Robot New Tricks (Local Knowledge Base)

Your robot can learn custom skills! Create your own automation recipes and watch your robot evolve.

By default, the application will look for this local knowledge base at ~/.macos-automator/knowledge_base. You can customize this path by setting the LOCAL_KB_PATH environment variable.

Example:

Suppose you have a local knowledge base at /Users/yourname/my-custom-kb. Set the environment variable: export LOCAL_KB_PATH=/Users/yourname/my-custom-kb

Or, if you are running the validator script, you can use the --local-kb-path argument: pnpm run validate -- --local-kb-path /Users/yourname/my-custom-kb

Structure and Overrides:

  • Your local knowledge base should mirror the category structure of the main knowledge_base (e.g., 01_applescript_core, 05_web_browsers/safari, etc.).

  • You can add new .md tip files or _shared_handlers (e.g., .applescript or .js files).

  • If a tip ID (either from frontmatter id: or generated from filename/path) in your local knowledge base matches an ID in the embedded knowledge base, your local version will override the embedded one.

  • Similarly, shared handlers with the same name and language (e.g., my_utility.applescript) in your local _shared_handlers directory will override any embedded ones with the same name and language within the same category (or globally if you place them at the root of your local KB's _shared_handlers).

  • Category descriptions from _category_info.md in your local KB can also override those from the embedded KB for the same category.

This allows for personalization and extension of the available automation scripts and tips without modifying the core application files.

🤝 Join the Robot Revolution!

Found a bug? Got a cool automation idea? Your robot army needs YOU! Submit issues and pull requests to the GitHub repository.

💪 Robot Superpowers Showcase

Here's what your new silicon sidekick can do out of the box:

🖥️ Terminal Tamer

  • Command Line Wizardry: Open new tabs, run commands, capture output - your robot speaks fluent bash!

    { "input": { "kb_script_id": "terminal_app_run_command_new_tab", "input_data": { "command": "echo '🤖 Hello World!'" } } }

🌐 Browser Bot

  • Web Automation Master: Control Chrome and Safari like a puppet master!

    { "input": { "kb_script_id": "safari_get_front_tab_url" } }
  • JavaScript Injection: Make web pages dance to your robot's tune

  • Screenshot Sniper: Capture any webpage faster than you can say "cheese"

⚙️ System Sorcerer

  • Dark Mode Toggle: Because robots have sensitive optical sensors

    { "input": { "kb_script_id": "systemsettings_toggle_dark_mode_ui" } }
  • Clipboard Commander: Copy, paste, and manipulate like a pro

  • Notification Ninja: Send alerts that actually get noticed

📁 File System Feng Shui

  • Folder Creator 3000: Organize your digital life with robotic precision

    { "input": { "kb_script_id": "finder_create_new_folder_desktop", "input_data": { "folder_name": "Robot Paradise" } } }
  • Text File Telepathy: Read and write files faster than humanly possible

📱 App Whisperer

  • Calendar Conductor: Schedule meetings while you sleep

  • Email Automator: Send emails without lifting a finger

  • Music Maestro: DJ your playlists programmatically

    { "input": { "kb_script_id": "music_playback_controls", "input_data": { "action": "play" } } }

🎯 Pro Tip: Use get_scripting_tips to discover all 200+ automation recipes!

This project is licensed under the MIT License - which means your robot is free to roam! See the LICENSE file for the fine print.


🤖 Remember: With great automation power comes great responsibility. Use your robot wisely!

Available Tools

2 tools
execute_scriptA
Destructive

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. Use get_scripting_tips to find IDs and inputs. Supports placeholder substitution via input_data or arguments. 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): For kb_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): For script_path (passes to on run argv / run(argv)). For kb_script_id, used for positional args (e.g., --MCP_ARG_1).

3. Execution Options (Optional):

  • language ('applescript' | 'javascript'): Specify for script_content/script_path (default: 'applescript'). Inferred for kb_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'): Controls osascript output formatting.

    • 'auto': Smart default - resolves to 'human_readable' for AppleScript and 'direct' for JXA.

    • 'human_readable': For AppleScript, uses -s h flag.

    • 'structured_error': For AppleScript, uses -s s flag (structured errors).

    • 'structured_output_and_error': For AppleScript, uses -s ss flag (structured output & errors).

    • 'direct': No special output flags (recommended for JXA).

  • include_executed_script_in_output (boolean, optional, default: false): If true, 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): For kb_script_id, includes detailed placeholder substitution logs.

  • report_execution_time (boolean, optional, default: false): If true, an additional message with the formatted script execution time will be included in the response. Defaults to false.

ParametersJSON Schema
NameRequiredDescriptionDefault
languageNoSpecifies the scripting language. Crucial for `script_content` and `script_path` if not 'applescript'. Defaults to 'applescript'. Inferred if using `kb_script_id`.
argumentsNoOptional 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_dataNoOptional JSON object to provide named inputs for --MCP_INPUT placeholders in knowledge base scripts.
script_pathNoThe path to the script file to execute. Required if kb_script_id or script_content is not provided.
kb_script_idNoThe ID of a knowledge base script to execute. Replaces script_content and script_path if provided.
script_contentNoThe content of the script to execute. Required if kb_script_id or script_path is not provided.
timeout_secondsNoThe timeout for the script execution in seconds. Defaults to 60.
output_format_modeNoControls 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_timeNoIf true, the tool will return an additional message containing the formatted script execution time. Defaults to false.
include_substitution_logsNoIf true, detailed logs of placeholder substitutions will be included in the output.
include_executed_script_in_outputNoIf true, the executed script content (after substitutions) or path will be included in the output.

TDQS

A4.9/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

Annotations provide destructiveHint=true, and the description complements this with extensive behavioral details: timeout defaults, output formatting flags (-s h, -s s, etc.), placeholder substitution behavior, debug options (include_executed_script_in_output, include_substitution_logs), and execution time reporting. This goes well 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long due to tool complexity but is well-structured with numbered sections, code examples, and bullet lists. Every section provides actionable information—no filler. The front-loading of purpose and clear formatting make it easy to navigate.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness4/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

The description thoroughly covers script input methods, options, and debugging aids. However, with no output schema, it does not explicitly describe the overall return value structure, only mentioning that certain flags add info to 'the response.' This is a minor gap given the tool's complexity.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema coverage is 100%, so baseline is 3, but the description adds substantial value: concrete examples for each script source, explanation of --MCP_INPUT placeholder mechanics, positional vs named arguments, default behavior for output_format_mode per language, and clear descriptions of all boolean options. This significantly exceeds schema-only information.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a specific verb+resource statement: 'Automate macOS tasks using AppleScript or JXA (JavaScript for Automation) to control applications like Terminal, Chrome, Safari, Finder, etc.' This clearly distinguishes it from the sibling tool get_scripting_tips, which is for finding scripts, not executing them.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly names the alternative tool: 'Use get_scripting_tips to find IDs and inputs.' It also provides clear when-to-use guidance for each script source (kb_script_id recommended, script_content for simple/dynamic, script_path for path-based), and explains when to specify language and other options.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

get_scripting_tipsA
Read-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_term or browsing a specific category (without list_categories: true). Does not apply if list_categories is true.

  • Browsing by Category (Use category):

    • Parameter: category (string, optional).

    • Functionality: Shows tips from a specific category. Combine with limit to control result count.

    • Example: category: "01_intro" or category: "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:

  1. Always start with search: Use natural language queries to find solutions (e.g., "send email from Mail app").

  2. Browse categories when exploring: Use list_categories: true to see available automation areas.

  3. Use specific IDs for execution: Once you find a script, use its ID with execute_script tool for precise execution.

ParametersJSON Schema
NameRequiredDescriptionDefault
limitNoMaximum number of results to return. Default is 10.
categoryNoSpecific category of tips. If omitted with no `search_term`, lists all categories.
search_termNoKeyword to search within tip titles, content, keywords, or IDs.
list_categoriesNoIf true, returns only the list of available categories and their descriptions. Overrides other parameters.
refresh_databaseNoIf true, forces a reload of the knowledge base before processing the request.

TDQS

A5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description goes beyond the readOnlyHint annotation by disclosing output formats (Markdown), fuzzy search behavior, category tree structure, and the refresh_database behavior (forces reload, auto-refresh). It clearly explains how list_categories overrides other parameters, which is a subtle behavioral trait. 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.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is long but meticulously structured with headings, bullet points, and examples. The core purpose is front-loaded, and every section earns its place by explaining use cases, parameter behavior, and best practices. No redundant filler.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given no output schema, the description fully covers return formats ('list of matching tips in Markdown format', 'Category tree in Markdown format'). It also covers all 5 parameters, their interplay, and the relationship with the sibling tool, making it complete for effective agent use.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters5/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Although the schema already covers all parameters (100% coverage), the description enriches each parameter with practical meaning: search_term examples, limit's interaction with category/list_categories, category path examples, and refresh_database's typical usage. It explains nuances like 'Does not apply if list_categories is true', which is not in the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description opens with a clear, specific purpose: 'Discover how to automate any app on your Mac' via a knowledge base of AppleScript/JXA tips. It further distinguishes itself from the sibling tool execute_script by positioning itself as the 'FIRST CHOICE' for discovery, making the tool's role unmistakable.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description explicitly states when to use this tool versus alternatives: 'should be the FIRST CHOICE when aiming to automate macOS tasks... before attempting to write scripts from scratch.' It also points to the sibling tool ('Use its ID with execute_script tool'), and provides a 'Best Practices' section with concrete usage scenarios.

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.

  1. 2 tool updatesv1.0.0
    • Changedexecute_script21 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / arguments / description
        Added 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."
      • addedInput schema / properties / include_executed_script_in_output / default
        Added value: +false
      • addedInput schema / properties / include_executed_script_in_output / description
        Added value: +"If true, the executed script content (after substitutions) or path will be included in the output."
      • addedInput schema / properties / include_substitution_logs / default
        Added value: +false
      • addedInput schema / properties / include_substitution_logs / description
        Added value: +"If true, detailed logs of placeholder substitutions will be included in the output."
      • addedInput schema / properties / input_data / description
        Added value: +"Optional JSON object to provide named inputs for --MCP_INPUT placeholders in knowledge base scripts."
      • addedInput schema / properties / input_data / properties
        Added value: +{}
      • addedInput schema / properties / kb_script_id / description
        Added value: +"The ID of a knowledge base script to execute. Replaces script_content and script_path if provided."
      • addedInput schema / properties / language / description
        Added value: +"Specifies the scripting language. Crucial for `script_content` and `script_path` if not 'applescript'. Defaults to 'applescript'. Inferred if using `kb_script_id`."
      • addedInput schema / properties / output_format_mode / default
        Added value: +"auto"
      • addedInput schema / properties / output_format_mode / description
        Added 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)."
      • addedInput schema / properties / report_execution_time / default
        Added value: +false
      • addedInput schema / properties / report_execution_time / description
        Added value: +"If true, the tool will return an additional message containing the formatted script execution time. Defaults to false."
      • addedInput schema / properties / script_content / description
        Added value: +"The content of the script to execute. Required if kb_script_id or script_path is not provided."
      • addedInput schema / properties / script_path / description
        Added value: +"The path to the script file to execute. Required if kb_script_id or script_content is not provided."
      • addedInput schema / properties / timeout_seconds / default
        Added value: +60
      • addedInput schema / properties / timeout_seconds / description
        Added value: +"The timeout for the script execution in seconds. Defaults to 60."
      • addedInput schema / properties / timeout_seconds / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / timeout_seconds / minimum
        Added value: +-9007199254740991
      • changedInput schema / properties / timeout_seconds / type
        Previous value: -"number"New value: +"integer"
    • Changedget_scripting_tips9 fields changed
      • removedInput schema / additionalProperties
        Removed value: -false
      • addedInput schema / properties / category / description
        Added value: +"Specific category of tips. If omitted with no `search_term`, lists all categories."
      • addedInput schema / properties / limit / default
        Added value: +10
      • addedInput schema / properties / limit / description
        Added value: +"Maximum number of results to return. Default is 10."
      • addedInput schema / properties / limit / maximum
        Added value: +9007199254740991
      • addedInput schema / properties / list_categories / default
        Added value: +false
      • addedInput schema / properties / list_categories / description
        Added value: +"If true, returns only the list of available categories and their descriptions. Overrides other parameters."
      • addedInput schema / properties / refresh_database / description
        Added value: +"If true, forces a reload of the knowledge base before processing the request."
      • addedInput schema / properties / search_term / description
        Added value: +"Keyword to search within tip titles, content, keywords, or IDs."
  2. 2 tool updates
    • First observedexecute_script
    • First observedget_scripting_tips

TDQS

A4.4/5.0

Scored across 2 tools

Disambiguation5/5

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.

Naming Consistency5/5

Both tool names follow a consistent verb_noun pattern in snake_case (execute_script, get_scripting_tips), which is predictable and clear.

Tool Count3/5

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.

Completeness3/5

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

ActivitySlowing
ResponsivenessWithin a week

Related MCP Connectors

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    A Model Context Protocol server that enables AI assistants to control Apple Keynote presentations through AppleScript automation, supporting comprehensive slide creation, management, and content operations.
    35 PyPI
    76
    MIT
  • A
    license
    A
    quality
    D
    maintenance
    A 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.
    2
    1,211 npm
    8
    MIT