Apple MCP: How to Use Apple MCP Servers
In the evolving landscape of AI-assisted computing, the integration of Apple's ecosystem with the Model Context Protocol (MCP) represents a significant advancement in how language models interact with Apple's suite of applications, services, and platforms. Apple MCP servers establish a standardized bridge between conversational AI models and Apple's tightly integrated ecosystem, enabling AI assistants to access calendars, notes, reminders, device information, and system functions across macOS, iOS, and iPadOS environments. This technical implementation transforms AI assistants from isolated text generators into context-aware agents capable of seamless integration with Apple's platforms while maintaining the company's stringent privacy and security standards.
Introduction
The Model Context Protocol provides a standardized framework for connecting AI models with external tools and data sources. Apple MCP servers implement this protocol to create a secure, privacy-preserving interface between AI assistants and Apple's application ecosystem. By leveraging various Apple APIs, frameworks, and services, MCP servers enable language models to programmatically interact with Calendar, Reminders, Notes, Finder, Spotlight, and system functions—all while respecting user permissions and maintaining Apple's privacy-by-design philosophy.
https://github.com/apple-mcp/apple-mcp-server (opens in a new tab)
Technical Architecture of Apple MCP
MCP Protocol Foundation
Apple MCP operates within the Model Context Protocol architecture, which defines several key components:
-
Transport Layer:
- STDIO (Standard Input/Output): Direct process communication
- SSE (Server-Sent Events): HTTP-based asynchronous communication
- WebSocket: Bidirectional real-time communication
-
Resource Types:
- Prompts: Templated interaction patterns for Apple services
- Tools: Executable operations on Apple platforms
- Resources: Structured data from Apple applications
-
Serialization Format: JSON for structured data exchange between client and server
Apple MCP Architecture
The Apple MCP server implements a layered architecture optimized for Apple platform integration:
apple-mcp/
├── src/
│ ├── auth/
│ │ ├── authorization.swift # Authorization management
│ │ ├── permissions.swift # Permission handling
│ │ └── keychain-access.swift # Secure credential storage
│ ├── services/
│ │ ├── calendar-service.swift # Calendar operations
│ │ ├── reminder-service.swift # Reminders operations
│ │ ├── notes-service.swift # Notes operations
│ │ ├── finder-service.swift # Finder operations
│ │ └── spotlight-service.swift # Spotlight search
│ ├── tools/
│ │ ├── calendar-tools.swift # Calendar management tools
│ │ ├── reminder-tools.swift # Task management tools
│ │ ├── notes-tools.swift # Note management tools
│ │ ├── finder-tools.swift # File operations tools
│ │ └── system-tools.swift # System interaction tools
│ ├── resources/
│ │ ├── calendar-resources.swift # Calendar data resources
│ │ └── device-info.swift # Device metadata
│ └── server.swift # MCP server implementation
├── config/
│ └── apple-config.swift # Configuration schema
└── Package.swift # Swift package definition
The core technical implementation consists of:
- Permission Manager: Handles TCC (Transparency, Consent, and Control) permissions
- Bridging Layer: Connects Swift APIs to MCP protocol
- Event Serialization: Converts Apple's data structures to MCP-compatible formats
- Privacy Controls: Implements data minimization and user consent flows
- Tool Implementations: Translates MCP commands to AppKit/EventKit calls
Setup and Installation
Prerequisites
To implement Apple MCP, ensure you have:
- macOS 12 (Monterey) or newer
- Xcode 14+ with Swift 5.7+
- Required privacy permissions for target applications
- An MCP-compatible client (e.g., Claude Desktop, Cursor, VS Code)
Permission Configuration
Apple's security model requires explicit user consent for accessing sensitive data. The MCP server must request and manage these permissions:
- Calendar Access: Full or read-only access to Calendar data
- Reminders Access: Permission to read and create reminders
- Files & Folders: Access to specific directories
- Automation: Permission to control specified applications
- Contacts: Optional access to contact information
These permissions are managed through macOS's TCC (Transparency, Consent, and Control) framework:
import AppKit
class PermissionManager {
func requestCalendarAccess() -> Bool {
let eventStore = EKEventStore()
var accessGranted = false
let semaphore = DispatchSemaphore(value: 0)
eventStore.requestAccess(to: .event) { (granted, error) in
accessGranted = granted
semaphore.signal()
}
_ = semaphore.wait(timeout: .distantFuture)
return accessGranted
}
func requestRemindersAccess() -> Bool {
// Similar implementation for Reminders
}
func requestFileAccess(at url: URL) -> Bool {
// Request file access using NSOpenPanel or Security-scoped bookmarks
}
}
Installation Methods
Option 1: Using Homebrew
brew install apple-mcp
Option 2: Using Smithery
npx -y @smithery/cli install apple-mcp --client claude
Option 3: Manual Installation from Source
git clone https://github.com/apple-mcp/apple-mcp-server
cd apple-mcp-server
swift build -c release
cp -f .build/release/apple-mcp /usr/local/bin/
Configuration
The Apple MCP server accepts several configuration parameters:
-
Service Access Configuration:
APPLE_MCP_CALENDAR_ACCESS
: Enable/disable Calendar accessAPPLE_MCP_REMINDERS_ACCESS
: Enable/disable Reminders accessAPPLE_MCP_NOTES_ACCESS
: Enable/disable Notes accessAPPLE_MCP_FILES_ACCESS
: Enable/disable filesystem access
-
Privacy Controls:
APPLE_MCP_DATA_MINIMIZATION
: Level of data minimization (basic/moderate/strict)APPLE_MCP_CONFIRM_ACTIONS
: Require confirmation for actions (true/false)APPLE_MCP_MAX_RESULTS
: Maximum number of results returned
-
Performance Settings:
APPLE_MCP_CACHE_TTL
: Cache duration for service data in secondsAPPLE_MCP_REQUEST_TIMEOUT
: Operation timeout in milliseconds
Example configuration in config.json
:
{
"services": {
"calendar": {
"enabled": true,
"accessLevel": "readWrite",
"maxEventsReturned": 50,
"defaultCalendarName": "Personal"
},
"reminders": {
"enabled": true,
"accessLevel": "readWrite",
"defaultListName": "Tasks"
},
"notes": {
"enabled": true,
"accessLevel": "readOnly",
"maxNotesReturned": 20
},
"finder": {
"enabled": true,
"allowedPaths": ["~/Documents", "~/Downloads"],
"blockedPatterns": [".ssh", ".keychain"]
}
},
"privacy": {
"confirmModifyActions": true,
"dataMinimization": "moderate",
"logLevel": "minimal"
},
"performance": {
"cacheEnabled": true,
"cacheTTL": 300,
"timeout": 10000
}
}
Integration with MCP Clients
Claude Desktop Integration
To integrate with Claude Desktop, edit the configuration file:
- macOS:
~/Library/Application\ Support/Claude/claude_desktop_config.json
Add the following configuration:
{
"mcpServers": {
"apple": {
"command": "/usr/local/bin/apple-mcp",
"args": ["serve", "--config-path", "~/Library/Application Support/AppleMCP/config.json"],
"env": {
"APPLE_MCP_CALENDAR_ACCESS": "true",
"APPLE_MCP_REMINDERS_ACCESS": "true",
"APPLE_MCP_DATA_MINIMIZATION": "moderate"
}
}
}
}
VS Code Integration
For VS Code with GitHub Copilot, add to settings.json:
{
"github.copilot.chat.mcpServers": [
{
"name": "apple",
"command": "/usr/local/bin/apple-mcp",
"args": ["serve"],
"env": {
"APPLE_MCP_CALENDAR_ACCESS": "true",
"APPLE_MCP_FILES_ACCESS": "true"
}
}
]
}
Core Functionality and Technical Usage
Available Tools
The Apple MCP server exposes several tools across Apple's application ecosystem:
1. Calendar Operations
-
apple_calendar_get_events: Retrieves calendar events
struct GetEventsOptions: Codable { var startDate: Date var endDate: Date var calendars: [String]? var includeDeclined: Bool? var includeDetails: Bool? var limit: Int? }
-
apple_calendar_create_event: Creates calendar events
struct CreateEventOptions: Codable { var title: String var startDate: Date var endDate: Date var calendar: String? var location: String? var notes: String? var url: String? var allDay: Bool? var participants: [String]? var recurrenceRule: RecurrenceOptions? var alarms: [AlarmOptions]? }
2. Reminder Operations
-
apple_reminders_get_tasks: Retrieves reminders
struct GetTasksOptions: Codable { var lists: [String]? var includeCompleted: Bool? var dueBefore: Date? var dueAfter: Date? var limit: Int? }
-
apple_reminders_create_task: Creates reminders
struct CreateTaskOptions: Codable { var title: String var notes: String? var dueDate: Date? var priority: Int? var list: String? var url: String? var location: LocationOptions? }
3. Notes Operations
-
apple_notes_search: Searches Notes content
struct SearchNotesOptions: Codable { var query: String var folders: [String]? var limit: Int? var includeArchived: Bool? var includeDeleted: Bool? }
-
apple_notes_create: Creates a note
struct CreateNoteOptions: Codable { var title: String var content: String var folder: String? var attachments: [AttachmentOptions]? }
4. Finder Operations
-
apple_finder_search: Searches files via Spotlight
struct FinderSearchOptions: Codable { var query: String var locations: [String]? var fileTypes: [String]? var modifiedAfter: Date? var modifiedBefore: Date? var limit: Int? }
-
apple_finder_get_info: Retrieves file metadata
struct FileInfoOptions: Codable { var path: String var includeAttributes: Bool? var includePreview: Bool? }
Technical Usage Patterns
Multi-step Calendar Workflow
// Find free time slots for meeting
let today = Date()
let nextWeek = Calendar.current.date(byAdding: .day, value: 7, to: today)!
let busyTimes = await tools.apple_calendar_get_events({
startDate: today,
endDate: nextWeek,
calendars: ["Work"],
includeDeclined: false
})
// Find a free 1-hour slot
let workDayStart = 9 // 9 AM
let workDayEnd = 17 // 5 PM
let meetingDuration = 3600 // 1 hour in seconds
let freeSlots = findFreeTimeSlots(
busyTimes: busyTimes,
startDate: today,
endDate: nextWeek,
workDayStart: workDayStart,
workDayEnd: workDayEnd,
duration: meetingDuration
)
// Create calendar event in first available slot
if let firstFreeSlot = freeSlots.first {
let eventCreated = await tools.apple_calendar_create_event({
title: "Project Planning Meeting",
startDate: firstFreeSlot.start,
endDate: firstFreeSlot.end,
calendar: "Work",
location: "Conference Room A",
notes: "Discuss Q3 project roadmap",
participants: ["colleague@example.com"]
})
if (eventCreated.success) {
// Create reminder for preparation
await tools.apple_reminders_create_task({
title: "Prepare presentation for planning meeting",
dueDate: Calendar.current.date(byAdding: .hour, value: -2, to: firstFreeSlot.start)!,
priority: 2,
list: "Work"
})
}
}
Integrated Document Workflow
// Search for documents related to project
const projectDocs = await tools.apple_finder_search({
query: "project proposal financials",
locations: ["~/Documents/Projects"],
fileTypes: ["pdf", "docx", "xlsx"],
modifiedAfter: Calendar.current.date(byAdding: .month, value: -1, to: Date())!,
limit: 5
})
// Create a meeting note combining document information
let noteContent = "# Project Review Notes\n\nRelevant documents:\n"
for doc in projectDocs.results {
// Get file metadata
const fileInfo = await tools.apple_finder_get_info({
path: doc.path,
includeAttributes: true
})
noteContent += `\n## ${doc.name}\n`
noteContent += `- Last modified: ${fileInfo.attributes.modificationDate}\n`
noteContent += `- Size: ${formatFileSize(fileInfo.attributes.size)}\n`
noteContent += `- Path: ${doc.path}\n\n`
}
// Create a note with the compiled information
await tools.apple_notes_create({
title: "Project Documentation Summary",
content: noteContent,
folder: "Work Projects"
})
// Add a calendar event for document review
await tools.apple_calendar_create_event({
title: "Project Documentation Review",
startDate: Calendar.current.date(byAdding: .day, value: 1, to: Date())!,
endDate: Calendar.current.date(byAdding: .day, value: 1, to: Date()!, hour: 11)!,
calendar: "Work",
notes: "Review project documentation\n" + noteContent
})
Advanced Implementation Considerations
Apple's Privacy Framework Integration
Apple MCP implements robust privacy measures aligned with Apple's privacy philosophy:
-
Data Minimization:
func applyPrivacyFilters<T: AppleData>(data: T, level: PrivacyLevel) -> T { switch level { case .minimal: return data.withMinimalData() case .moderate: return data.withModerateData() case .complete: return data } }
-
User Consent Dialogs:
class ConsentManager { func requestConsentForAction(description: String, sensitivity: SensitivityLevel) -> Bool { if sensitivity == .low && !configuration.confirmLowSensitivityActions { return true } let alert = NSAlert() alert.messageText = "Action Confirmation" alert.informativeText = "An AI assistant wants to perform this action:\n\n\(description)" alert.addButton(withTitle: "Allow") alert.addButton(withTitle: "Deny") return alert.runModal() == .alertFirstButtonReturn } }
Integration with Apple's Automation Framework
For advanced system operations:
class AppleScriptExecutor {
func executeScript(_ script: String, withParameters params: [String: Any] = [:]) throws -> Any? {
var scriptText = script
// Replace parameters in script
for (key, value) in params {
let placeholder = "{{" + key + "}}"
let escapedValue = escapeAppleScriptString(String(describing: value))
scriptText = scriptText.replacingOccurrences(of: placeholder, with: escapedValue)
}
// Validate script for security
guard isScriptAllowed(scriptText) else {
throw AppleMCPError.scriptNotAllowed("Script contains disallowed operations")
}
// Execute the script
var error: NSDictionary?
let scriptObject = NSAppleScript(source: scriptText)
let output = scriptObject?.executeAndReturnError(&error)
if let error = error {
throw AppleMCPError.scriptExecutionFailed(error["NSAppleScriptErrorMessage"] as? String ?? "Unknown error")
}
return output?.stringValue
}
private func isScriptAllowed(_ script: String) -> Bool {
// Security validation logic
let blockedPatterns = [
"do shell script",
"system events",
"system preferences",
"keychain",
// Add other sensitive operations
]
return !blockedPatterns.contains { pattern in
script.lowercased().contains(pattern.lowercased())
}
}
}
Troubleshooting Common Technical Issues
Permission and TCC Database Issues
If permission prompts fail to appear:
-
Reset TCC database (requires disabling SIP):
tccutil reset All com.apple-mcp.server
-
Check TCC database entries:
sqlite3 ~/Library/Application\ Support/com.apple.TCC/TCC.db \ "SELECT * FROM access WHERE client='com.apple-mcp.server'"
-
Grant permissions via Privacy & Security in System Settings
Sandboxing and Entitlement Issues
To resolve application sandbox constraints:
<!-- Entitlements.plist -->
<dict>
<key>com.apple.security.app-sandbox</key>
<true/>
<key>com.apple.security.automation.apple-events</key>
<true/>
<key>com.apple.security.personal-information.calendars</key>
<true/>
<key>com.apple.security.personal-information.reminders</key>
<true/>
<key>com.apple.security.files.user-selected.read-write</key>
<true/>
</dict>
Event Kit Sync Issues
When calendar or reminder operations seem out of date:
class EventKitSyncManager {
let eventStore = EKEventStore()
func forceSync() {
// Trigger EventKit synchronization
NotificationCenter.default.addObserver(
self,
selector: #selector(syncComplete),
name: NSNotification.Name.EKEventStoreChanged,
object: eventStore
)
eventStore.refreshSourcesIfNecessary()
// Wait for sync with timeout
let syncTimeout = DispatchTime.now() + 10.0
let semaphore = DispatchSemaphore(value: 0)
DispatchQueue.global(qos: .background).async {
_ = semaphore.wait(timeout: syncTimeout)
}
}
@objc func syncComplete() {
NotificationCenter.default.removeObserver(
self,
name: NSNotification.Name.EKEventStoreChanged,
object: eventStore
)
semaphore.signal()
}
}
Conclusion
Apple MCP servers represent a sophisticated technical bridge between conversational AI and Apple's ecosystem of applications and services. By implementing the Model Context Protocol with Apple's frameworks and APIs, these servers enable AI assistants to seamlessly integrate with Calendar, Reminders, Notes, Finder, and system functions—all while maintaining Apple's stringent privacy standards and smooth user experience.
This implementation establishes a foundation for building privacy-respecting, secure integrations that leverage the power of Apple's ecosystem while providing AI assistants with contextual awareness and operational capabilities. As both MCP and Apple's platforms continue to evolve, we can expect further advancements in integration depth, privacy features, and ecosystem coverage.
For developers seeking to extend their AI systems with Apple platform capabilities, Apple MCP offers a standardized approach that respects Apple's design philosophy while unlocking powerful new interaction modalities for AI assistants. The result is a more contextually aware, helpful AI experience that feels native to the Apple ecosystem while maintaining the privacy and security that users expect.