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.
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
NSAppleScriptand 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:
- If the MCP client supports elicitation, a confirmation dialog is shown
- 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:
- Open the
.dmgand copymcp-applescriptto/usr/local/bin/:sudo cp /Volumes/MCP-AppleScript\ */mcp-applescript /usr/local/bin/ - 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 - 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:
- Install Node.js dependencies
- Build the TypeScript MCP server
- Build and install the Swift executor to
/usr/local/bin/ - 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_scriptdisabled 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:
- Open System Settings → Privacy & Security → Automation
- Find your terminal or the executor binary
- 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
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。