MCP-AppleScript

MCP-AppleScript

A local MCP server that provides a secure bridge for automating macOS applications like Notes, Calendar, and Mail through AppleScript. It uses template-based execution and policy-based allowlists to enable safe, structured interaction with system tools.

Category
Visit Server

README

MCP-AppleScript

A local MCP server that exposes controlled AppleScript automation tools to MCP clients on macOS.

Overview

MCP-AppleScript provides a secure bridge between the Model Context Protocol and macOS automation via AppleScript. It consists of two components:

  • MCP Server (TypeScript/Node.js): Handles the MCP protocol, tool schemas, configuration, validation, logging, and policy enforcement
  • Swift Executor: Executes AppleScript commands via NSAppleScript and returns structured JSON results

Tools

All 10 Apple apps are accessed through generic app.* tools with an app parameter:

Tool Mode Description
applescript.ping readonly Health check — returns server version and supported apps
applescript.get_mode readonly Get current operation mode and enabled tools
applescript.set_mode readonly Change operation mode (readonly/create/full)
app.list_containers readonly List containers (folders, calendars, mailboxes, playlists, etc.)
app.list readonly List items in a container with pagination
app.get readonly Get a single item by ID
app.search readonly Search/filter items
app.create create Create a new item
app.action create App-specific actions (send, play, complete, do_javascript, etc.)
applescript.run_template create Execute a registered template by ID (policy-gated)
app.update full Update an item (confirmation required)
app.delete full Delete an item (confirmation required)
applescript.run_script full Execute raw AppleScript (confirmation required)

Supported Apps

Notes, Calendar, Reminders, Mail, Contacts, Messages, Photos, Music, Finder, Safari

Operation Modes

The server starts in readonly mode by default. Use applescript.set_mode to change modes on-the-fly:

Mode Description Available Tools
readonly No creation, editing, or deleting ping, get_mode, set_mode, app.list/get/search/list_containers
create Readonly + creation allowed + app.create, app.action, run_template
full All operations, potentially destructive + app.update, app.delete, run_script (requires confirmation)

When the mode changes, the client is notified via notifications/tools/list_changed and will only see tools available in the current mode.

Destructive Action Confirmation

In full mode, destructive tools (app.update, app.delete, run_script) require user confirmation:

  1. If the MCP client supports elicitation, a confirmation dialog is shown
  2. Otherwise, a confirmation token is returned — pass it back in a second call to confirm

Requirements

  • macOS 12.0 or later
  • Node.js 20+ (only for building from source)
  • Swift 5.9+ (only for building from source)
  • pnpm 8+ (only for building from source)

Installation

Option 1: Download pre-built binary (.dmg)

Download the latest .dmg from GitHub Releases:

  1. Open the .dmg and copy mcp-applescript to /usr/local/bin/:
    sudo cp /Volumes/MCP-AppleScript\ */mcp-applescript /usr/local/bin/
    
  2. Create a config file:
    mkdir -p ~/.config/applescript-mcp
    cat > ~/.config/applescript-mcp/config.json << 'EOF'
    {
      "defaultMode": "readonly",
      "apps": {
        "com.apple.Notes": { "enabled": true },
        "com.apple.iCal": { "enabled": true },
        "com.apple.reminders": { "enabled": true },
        "com.apple.mail": { "enabled": true },
        "com.apple.Contacts": { "enabled": true }
      }
    }
    EOF
    
  3. Add to your MCP client config (see Claude Desktop below)

The pre-built binary is a self-contained executable with Node.js and the Swift executor embedded — no runtime dependencies required.

Option 2: Build from source

git clone https://github.com/frouaix/MCPAppleScript.git
cd MCPAppleScript
./install.sh

The install script will:

  1. Install Node.js dependencies
  2. Build the TypeScript MCP server
  3. Build and install the Swift executor to /usr/local/bin/
  4. Create a default config at ~/.config/applescript-mcp/config.json

Claude Desktop Integration

Add to ~/Library/Application Support/Claude/claude_desktop_config.json:

{
  "mcpServers": {
    "applescript": {
      "command": "/usr/local/bin/mcp-applescript"
    }
  }
}

If building from source, use the dev path instead:

{
  "mcpServers": {
    "applescript": {
      "command": "node",
      "args": ["/path/to/MCPAppleScript/packages/mcp-server/dist/index.js"]
    }
  }
}

Configuration

Configuration lives at ~/.config/applescript-mcp/config.json (override via APPLESCRIPT_MCP_CONFIG env var):

{
  "executorPath": "/usr/local/bin/applescript-executor",
  "defaultTimeoutMs": 12000,
  "defaultMode": "readonly",
  "modes": {
    "readonly": ["applescript.ping", "applescript.get_mode", "applescript.set_mode", "app.list_containers", "app.list", "app.get", "app.search"],
    "create": ["app.create", "app.action", "applescript.run_template"],
    "full": ["app.update", "app.delete", "applescript.run_script"]
  },
  "apps": {
    "com.apple.Notes": { "enabled": true },
    "com.apple.iCal": { "enabled": true },
    "com.apple.reminders": { "enabled": true },
    "com.apple.mail": { "enabled": true },
    "com.apple.Contacts": { "enabled": true },
    "com.apple.MobileSMS": { "enabled": true },
    "com.apple.Photos": { "enabled": true },
    "com.apple.Music": { "enabled": true },
    "com.apple.finder": { "enabled": true },
    "com.apple.Safari": { "enabled": true }
  },
  "runScript": {
    "enabled": false,
    "allowedBundleIds": []
  },
  "logging": {
    "level": "info",
    "redact": ["email", "content", "body"]
  }
}

Modes

The modes section controls which tools are available at each operation mode level. Modes are cumulative — create includes all readonly tools, full includes all create tools. You can customize this to promote tools to a lower mode or restrict them to a higher one.

Policy Model

  • Per-app allowlists: Each app must be explicitly configured and enabled
  • Per-tool permissions: Control which tools can target which apps
  • Per-mode tool gating: Each tool requires a minimum mode level (configurable via modes)
  • run_script disabled by default: Raw AppleScript execution requires explicit opt-in
  • Timeouts enforced: All operations are time-bounded

Automation Permissions (TCC)

On first use, macOS will prompt for automation permissions:

  1. Open System SettingsPrivacy & SecurityAutomation
  2. Find your terminal or the executor binary
  3. Enable permissions for the apps you want to automate (Notes, Calendar, Reminders, Mail, Contacts, etc.)

If you see AUTOMATION_DENIED errors, check these permissions.

Architecture

MCP Client (Claude, etc.)
    ↕ stdio (JSON-RPC)
TypeScript MCP Server
    ↕ JSON over stdin/stdout
Swift Executor (applescript-executor)
    ↕ Apple Events
macOS Apps (Notes, Calendar, Reminders, Mail, Contacts, Messages, Photos, Music, Finder, Safari)

The Node process is the only MCP-facing component. Swift is a helper invoked locally for each tool call. See docs/ARCHITECTURE.md for details.

Development

# Install dependencies
pnpm install

# Build everything
pnpm build

# Run unit tests (150 tests)
pnpm test:unit

# Run integration tests (4 tests, requires macOS)
pnpm test:integration

# Build Swift executor
cd packages/executor-swift && swift build

# Run the server in development mode
cd packages/mcp-server && pnpm dev

Building the standalone binary

# Build self-contained binary (Node.js SEA + embedded Swift executor)
pnpm build:sea

# Package as .dmg
pnpm build:dmg

Output: dist/mcp-applescript (~107MB, ~40MB as .dmg)

Security

  • Three operation modes (readonly → create → full) with safe default
  • Destructive action confirmation via MCP elicitation or confirmation tokens
  • Template-based execution prevents arbitrary script injection
  • Per-app, per-tool permission model with explicit allowlists
  • Input validation with Zod schemas on all tool parameters
  • Sensitive data redaction in logs (configurable)
  • Timeout enforcement on all executor operations
  • Stable error codes for all failure modes

Project Structure

MCPAppleScript/
  packages/
    mcp-server/          # TypeScript MCP server
      src/
        index.ts         # Stdio entrypoint
        server.ts        # MCP server + tool registration
        sea.ts           # SEA binary support (executor extraction)
        adapters/        # ResourceAdapter pattern: per-app adapters (10 apps)
        config/          # Configuration loading + Zod schemas
        mode/            # Operation mode manager + confirmation
        policy/          # Allowlist/denylist enforcement
        exec/            # Executor spawning + IPC
        util/            # Errors, logging, JSON utils
    executor-swift/      # Swift executor CLI
      Sources/Executor/
        main.swift       # JSON dispatcher
        AppleScriptRunner.swift  # Template dispatch to per-app modules
        {App}Templates.swift     # Per-app AppleScript templates (10 files)
        AppTargeting.swift       # Bundle ID handling
        Errors.swift     # Error code mapping
        JsonIO.swift     # Stdin/stdout JSON I/O
  scripts/
    build-sea.sh         # Build self-contained binary (Node.js SEA)
    build-dmg.sh         # Package binary as .dmg
  docs/                  # Architecture documentation
  install.sh             # One-step installer (build from source)

License

MIT — see LICENSE

Author

François Rouaix

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured