Initial commit — Apple Apps MCP server with native macOS config app
Python MCP server (FastMCP) providing Claude Code/CoWork access to Apple Reminders, Calendar, Mail, Contacts, Find My, and Maps via AppleScript. Includes a native SwiftUI config/installer app and a compiled EventKit helper for fast reminder queries on large databases (8,000+ items). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,79 @@
|
||||
#!/bin/bash
|
||||
# Apple MCP Server — Setup Script
|
||||
# Creates venv via uv, installs deps, registers in ~/.claude.json
|
||||
|
||||
set -e
|
||||
|
||||
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||||
CLAUDE_JSON="$HOME/.claude.json"
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
|
||||
echo "=== Apple MCP Server Setup ==="
|
||||
echo ""
|
||||
|
||||
# 0. Check for uv
|
||||
if ! command -v uv &>/dev/null; then
|
||||
echo "Installing uv (Python package manager)..."
|
||||
curl -LsSf https://astral.sh/uv/install.sh | sh
|
||||
export PATH="$HOME/.local/bin:$PATH"
|
||||
fi
|
||||
|
||||
# 1. Create virtual environment with Python 3.13
|
||||
echo "[1/3] Creating Python 3.13 virtual environment..."
|
||||
if [ ! -d "$SCRIPT_DIR/.venv" ]; then
|
||||
uv venv --python 3.13 "$SCRIPT_DIR/.venv"
|
||||
echo " Created .venv with Python 3.13"
|
||||
else
|
||||
echo " .venv already exists, skipping"
|
||||
fi
|
||||
|
||||
# 2. Install dependencies
|
||||
echo "[2/3] Installing dependencies..."
|
||||
cd "$SCRIPT_DIR"
|
||||
uv pip install -r requirements.txt
|
||||
echo " Installed mcp[cli] and pydantic"
|
||||
|
||||
# 3. Register in ~/.claude.json (user-scope MCP server)
|
||||
echo "[3/3] Registering MCP server in Claude Code..."
|
||||
|
||||
PYTHON_PATH="$SCRIPT_DIR/.venv/bin/python"
|
||||
SERVER_PATH="$SCRIPT_DIR/apple_mcp.py"
|
||||
|
||||
"$PYTHON_PATH" << PYEOF
|
||||
import json
|
||||
from pathlib import Path
|
||||
|
||||
claude_json = Path("$CLAUDE_JSON")
|
||||
data = {}
|
||||
if claude_json.exists():
|
||||
with open(claude_json) as f:
|
||||
data = json.load(f)
|
||||
|
||||
if "mcpServers" not in data:
|
||||
data["mcpServers"] = {}
|
||||
|
||||
data["mcpServers"]["apple-apps"] = {
|
||||
"command": "$PYTHON_PATH",
|
||||
"args": ["$SERVER_PATH"]
|
||||
}
|
||||
|
||||
with open(claude_json, "w") as f:
|
||||
json.dump(data, f, indent=2)
|
||||
f.write("\n")
|
||||
|
||||
print(" Registered 'apple-apps' in ~/.claude.json")
|
||||
PYEOF
|
||||
|
||||
echo ""
|
||||
echo "=== Setup Complete ==="
|
||||
echo ""
|
||||
echo "Config file: $SCRIPT_DIR/config.json"
|
||||
echo " Edit this to control which apps Claude can access and read/write permissions."
|
||||
echo ""
|
||||
echo "Current config:"
|
||||
cat "$SCRIPT_DIR/config.json"
|
||||
echo ""
|
||||
echo "Restart Claude Code for the MCP server to start."
|
||||
echo ""
|
||||
echo "NOTE: On first use, macOS will ask for permission to access Reminders,"
|
||||
echo "Calendar, Mail, Contacts, etc. Click 'OK' to grant access."
|
||||
Reference in New Issue
Block a user