Content
# Apple MCP Pro
> A maintained, hardened **Model Context Protocol (MCP)** server that gives AI agents — Claude, Cursor, Windsurf, Continue, or any MCP-compatible client — first-class access to the macOS ecosystem. **24 tools**, one binary, zero external dependencies beyond the system you already run on.
[](LICENSE)
[](#requirements)
[](https://modelcontextprotocol.io)
[](https://www.typescriptlang.org/)
Apple MCP Pro is an actively maintained fork of [Dhravya Shah's original `apple-mcp`](https://github.com/Dhravya/apple-mcp). It keeps everything that worked, fixes the AppleScript hangs that broke Calendar / Reminders / Contacts on Sonoma+, and adds **17 new tools** covering the rest of the macOS surface area an agent needs to actually be useful on a Mac.
If you want to give an LLM a real seat at your Mac — not just send a text or read a note, but search Spotlight, control Music, take a screenshot, read your battery state, look up a word, get the weather, see what's in Safari — this is the server you wire up.
---
## Why this fork exists
The original `apple-mcp` is a great proof-of-concept and is referenced by every major MCP catalog. But on macOS Sonoma and Sequoia, several of its core tools (`reminders.list`, `notes.list`, `contacts.search`, `calendar.create`) hang indefinitely because of a long-standing AppleScript regression: building dictionary records inside a repeat loop wedges `osascript`. That bug alone made the server unusable for daily agent work.
Apple MCP Pro fixes those four hangs, replaces the slowest paths with direct SQLite reads (Contacts is now ~100× faster on a 1k-contact library), wraps every AppleScript call in a hard timeout so a wedged Apple app can never block the agent, and ships 17 additional tools so the agent can actually live on the Mac.
---
## What you get
**Original 7 tools (now hardened):**
| Tool | What it does |
|---|---|
| `contacts` | Search Apple Contacts (SQLite-backed, no AppleScript hang). |
| `notes` | Search, list, create Apple Notes. |
| `messages` | Send, read, schedule, list-unread iMessages. |
| `mail` | Read unread, search, send, list mailboxes/accounts. |
| `reminders` | List, search, open, create across all Reminders lists. |
| `calendar` | Search, list, create, open events (JXA-backed, bypasses the AppleScript wedge). |
| `maps` | Search, save, get directions, manage guides, drop pins in Apple Maps. |
**5 new system tools:**
| Tool | What it does |
|---|---|
| `clipboard` | Read or write the system clipboard (`pbpaste` / `pbcopy`). |
| `spotlight` | Search by filename or by indexed content (`mdfind`), with optional path scope. |
| `shortcuts` | List or run user Shortcuts via the system `shortcuts` CLI. |
| `notify` | Post a Notification Center alert with optional subtitle and sound. |
| `music` | Now-playing, transport (play/pause/next/previous/stop), library search. |
**12 new ecosystem tools:**
| Tool | What it does |
|---|---|
| `screenshot` | Full-screen, silent-full, window, or region capture via `screencapture`. |
| `safari` | Read open tabs, bookmarks, or reading list. |
| `system_info` | Battery, network, disk, displays — individually or `all`. |
| `voice_memos` | List Voice Memos by reading `CloudRecordings.db` directly. |
| `photos` | List albums, search Photos library. |
| `weather` | Weather snapshot via `wttr.in` (no API key). |
| `dictionary` | Word definitions (Dictionary.app fallback). |
| `sound_volume` | Get or set output volume + mute. |
| `textedit` | Open files or create new TextEdit documents. |
| `books` | List Apple Books library via SQLite. |
| `time_machine` | Backup status, last-backup time, destination, free space. |
| `finder` | Selection, current folder, reveal-path. |
All 24 tools share one binary, one MCP connection, one set of permissions.
---
## Requirements
- **macOS 13 (Ventura) or newer.** Tested on 13, 14, 15.
- **[Bun](https://bun.sh)** for the easy install path, or any Node 18+ runtime if you build from source.
- The first time the agent calls a tool that touches a protected app (Contacts, Calendar, Reminders, Notes, Photos, Mail, Messages, Music), macOS will prompt for permission. Grant it once.
- Some tools need specific TCC permissions:
- `screenshot` → **Screen Recording**
- `safari` reading list → **Full Disk Access**
- `voice_memos`, `books` → **Full Disk Access** (they read SQLite stores in `~/Library`)
---
## Install
### Quick start (Claude Desktop, Cursor, Continue, etc.)
Add this to your MCP client config (`claude_desktop_config.json`, `~/.cursor/mcp.json`, etc.):
```json
{
"mcpServers": {
"apple-mcp-pro": {
"command": "bunx",
"args": ["--no-cache", "apple-mcp-pro"]
}
}
}
```
Restart the client. The agent now has all 24 tools available.
### Claude Code
```bash
claude mcp add apple-mcp-pro -- bunx --no-cache apple-mcp-pro
```
### From source
```bash
git clone https://github.com/manuaudio/apple-mcp-pro.git
cd apple-mcp-pro
bun install
bun run build
# point your MCP client at: node /full/path/to/apple-mcp-pro/dist/index.js
```
---
## Usage examples
These work as natural-language prompts in any MCP-aware agent:
```
"What's playing in Music? Pause it and take a screenshot of my desktop."
```
```
"Find every note containing 'invoice', email the latest one to my accountant, and remind me on Friday to follow up."
```
```
"Search Spotlight for files named 'tax' modified this year and copy the list to my clipboard."
```
```
"What's my battery, free disk, and Time Machine status? Notify me if anything looks bad."
```
```
"Look up 'serendipity', add the definition to a new Note, and read me the weather in Tokyo."
```
```
"Show me my open Safari tabs, then create a reminder to review them tomorrow at 9 AM."
```
The whole point of having a unified server is that the model can chain these without your client juggling multiple connections.
---
## Tool reference (raw JSON-RPC)
If you're building an MCP client or testing directly, every tool follows this shape:
```json
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "<tool>",
"arguments": { ... }
}
}
```
A few high-value examples:
```json
// Get the next 7 days of calendar events
{ "name": "calendar", "arguments": { "operation": "list", "limit": 20 } }
// Create a reminder due tomorrow 2 PM
{ "name": "reminders", "arguments": {
"operation": "create",
"name": "Call dentist",
"dueDate": "2026-05-07T14:00:00",
"listName": "Reminders" } }
// Spotlight content search restricted to ~/Documents
{ "name": "spotlight", "arguments": {
"operation": "content", "query": "Q1 forecast",
"onlyIn": "/Users/me/Documents", "limit": 10 } }
// Take a silent full-screen screenshot to a path
{ "name": "screenshot", "arguments": {
"mode": "silent-full",
"outputPath": "/tmp/desktop.png" } }
// Set system volume to 30%
{ "name": "sound_volume", "arguments": { "operation": "set", "level": 30 } }
// Get current weather
{ "name": "weather", "arguments": { "location": "Los Angeles" } }
```
Full input schema for each tool is published via `tools/list` — your MCP client will surface it automatically.
---
## What changed vs. the original `apple-mcp`
This is the substance behind the rebrand. Each item is one or more commits in this repo's history.
**Bug fixes**
- **`reminders.list` no longer hangs.** The original built `{name:..., id:...}` records inside a repeat loop, which wedges `osascript` on Sonoma+. Replaced with a bulk getter pattern that uses `name of every list` + `id of every list` joined with an ASCII unit-separator. Same fix applied to `notes`.
- **`calendar.create` no longer hangs.** Switched to **JXA** (`osascript -l JavaScript`) which sidesteps the AppleScript wedge in `Calendar.app`'s scripting bridge.
- **`contacts` is ~100× faster.** Reads `~/Library/Application Support/AddressBook/Sources/*/AddressBook-v22.abcddb` directly instead of iterating via AppleScript. A 1,251-contact library went from 12 s to ~100 ms per call.
**Defense-in-depth**
- New shared `runOsascriptSafe` helper wraps every `osascript` call in a hard `timeoutMs`. A wedged Apple app can never block the agent again — it returns `null` and the tool reports a clean error.
**New surface area**
- 17 additional tools (listed above) covering clipboard, Spotlight, Shortcuts, notifications, Music, screenshots, Safari, system info, Voice Memos, Photos, weather, dictionary, sound volume, TextEdit, Books, Time Machine, Finder.
**Validation**
- Edge-case inputs (bad operations, missing arguments, empty strings) now return structured `Error in <tool> tool: ...` messages instead of crashing the server.
---
## Architecture notes
- **Single binary.** All 24 tools dispatch from one `index.ts` over stdio JSON-RPC.
- **Lazy module loading.** Tool implementations import on first use, so cold-start is fast even with 24 tools registered.
- **Direct SQLite where it pays off.** Contacts, Voice Memos, Books are read out of their on-disk SQLite stores, which is both faster and avoids triggering the corresponding app's launchd activation.
- **JXA where AppleScript wedges.** Calendar's scripting bridge is unreliable; JXA is more stable for write paths.
- **Hard timeouts everywhere.** The `osascriptWithTimeout` wrapper is the single chokepoint for AppleScript — change it once, harden everything.
---
## Local development
```bash
git clone https://github.com/manuaudio/apple-mcp-pro.git
cd apple-mcp-pro
bun install
bun run dev # runs index.ts directly
bun run build # produces dist/index.js
bun run test # runs the test suite (integration tests need the relevant Apple apps)
```
To exercise a tool without a full MCP client, you can pipe two JSON-RPC frames into the server:
```bash
{
echo '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2024-11-05","capabilities":{},"clientInfo":{"name":"t","version":"1"}}}'
sleep 1
echo '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"weather","arguments":{"location":"Tokyo"}}}'
sleep 5
} | bun run index.ts
```
---
## Contributing
Pull requests welcome. Two principles to keep things sane:
1. **Every new tool ships with a hard timeout.** Use `runOsascriptSafe` (or its equivalent) — never call `osascript` raw.
2. **If a path can be served from SQLite, prefer SQLite.** AppleScript should be a last resort for read-only operations.
Open an issue first for anything that touches the existing tool schemas — clients depend on those.
---
## License
MIT. See [LICENSE](LICENSE).
This project is a fork of [`apple-mcp`](https://github.com/Dhravya/apple-mcp) by **Dhravya Shah**, used and redistributed under the terms of its MIT license. All original copyright notices are preserved. New code in this fork is © 2026 Manu Jiménez.
---
## Credits
- **[Dhravya Shah](https://github.com/Dhravya)** — original author of `apple-mcp`. Thank you for the foundation.
- **[Anthropic](https://www.anthropic.com/)** — for the Model Context Protocol specification.
- Everyone who filed the AppleScript-hang bugs upstream and kept the conversation going.
---
## Roadmap
- `safari.openTab`, `safari.closeTab` — write operations on tabs.
- `shortcuts.export` — round-trip a Shortcut to disk for inspection.
- `homekit` — read scenes/devices via the Home framework (research-stage).
- `screen_time` — read app usage from the ScreenTime SQLite store (research-stage).
- Optional websocket transport for remote use behind Tailscale.
If a tool you want isn't here, open an issue with the use case — that's the fastest way to get it on the list.
MCP Config
Below is the configuration for this MCP Server. You can copy it directly to Cursor or other MCP clients.
mcp.json
Connection Info
You Might Also Like
everything-claude-code
Complete Claude Code configuration collection - agents, skills, hooks,...
markitdown
Python tool for converting files and office documents to Markdown.
awesome-claude-skills
A curated list of awesome Claude Skills, resources, and tools for...
antigravity-awesome-skills
The Ultimate Collection of 130+ Agentic Skills for Claude...
claude-context-mode
claude-context-mode plugin reduces MCP context bloat, saving up to 99% of tokens.
context-mode
MCP is the protocol for tool access. We're the virtualization layer for context.