内容
# macOS 生态系统 MCP 服务器
一款适用于 Claude 的快速、原生的模型上下文协议(MCP)服务器,提供对 macOS 生产力应用程序的直接访问:**提醒事项**、**日历** 和 **备忘录**。
## 为什么要重写?
原始的 Node.js/TypeScript 服务器对每个工具调用都使用 `osascript` — 每次调用都会增加 300–800 毫秒的过程启动开销。
这个 Swift 重写版本:
- 原生使用 **EventKit** 来处理提醒事项和日历(无需子进程)
- 仅对 **备忘录** 调用使用 `osascript`(Notes.framework 是私有的)
- 编译为 **单个独立的二进制文件** — 无需 Node.js 运行时环境
- 直接通过 [官方 Swift SDK](https://github.com/modelcontextprotocol/swift-sdk) 与 MCP stdio 协议通信
## 功能
### 🗓️ 提醒事项(4 个工具 — EventKit)
- `reminders_add` — 创建带有标题、备注、截止日期和优先级的提醒事项
- `reminders_list` — 列出提醒事项,按列表和完成状态筛选
- `reminders_complete` — 将提醒事项标记为已完成(按 ID 或标题)
- `reminders_search` — 按关键词搜索提醒事项
### 📅 日历(5 个工具 — EventKit)
- `calendar_create_event` — 创建带有地点、备注和提醒的事件
- `calendar_list_events` — 在指定日期范围内列出事件
- `calendar_find_free_time` — 查找可用的时间段
- `calendar_update_event` — 修改现有事件
- `calendar_delete_event` — 删除事件
### 📝 备忘录(3 个工具 — osascript)
- `notes_create` — 创建带有标题和正文(支持 HTML)的备忘录
- `notes_append` — 在现有备忘录中追加内容
- `notes_search` — 按关键词搜索备忘录
## 要求
- macOS 13 Ventura 或更高版本
- Xcode 15+ / Swift 5.9+(仅限编译)
- 在 **系统设置 → 隐私和安全** 中授予提醒事项、日历和备忘录的访问权限
## 从源代码构建
```bash
git clone https://github.com/neverprepared/macos-ecosystem-mcp.git
cd macos-ecosystem-mcp
swift build -c release
```
二进制文件位于:
```
.build/release/macos-mcp
```
系统范围内安装:
```bash
sudo cp .build/release/macos-mcp /usr/local/bin/macos-mcp
```
## macOS 权限
二进制文件首次运行时,它将请求访问权限。您也可以提前授予权限:
1. **系统设置 → 隐私和安全 → 提醒事项** — 添加 `macos-mcp`
2. **系统设置 → 隐私和安全 → 日历** — 添加 `macos-mcp`
3. **系统设置 → 隐私和安全 → 自动执行 → 备忘录** — 添加 `macos-mcp`
## Claude 桌面配置
将以下内容添加到 `~/Library/Application Support/Claude/claude_desktop_config.json`:
```json
{
"mcpServers": {
"macos-ecosystem": {
"command": "/usr/local/bin/macos-mcp"
}
}
}
```
或使用本地构建路径:
```json
{
"mcpServers": {
"macos-ecosystem": {
"command": "/path/to/macos-ecosystem-mcp/.build/release/macos-mcp"
}
}
}
```
编辑配置后重启 Claude 桌面。
## 工具参考
### reminders_add
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
| title | 字符串 | ✓ | — | 提醒事项标题 |
| list | 字符串 | | "Reminders" | 列表名称 |
| notes | 字符串 | | — | 正文文本 |
| dueDate | 字符串 | | — | ISO 8601 日期-时间 |
| priority | none\|low\|medium\|high | | "none" | 优先级 |
### reminders_list
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
| list | 字符串 | | — | 按列表筛选 |
| includeCompleted | 布尔值 | | false | 包括已完成的 |
| limit | 整数 | | 50 | 最大结果数(1–100) |
### reminders_complete
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
| reminderId | 字符串 | (之一) | EventKit calendarItemIdentifier |
| title | 字符串 | (之一) | 提醒事项标题 |
| list | 字符串 | | 限制搜索到列表 |
### reminders_search
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
| query | 字符串 | ✓ | — | 搜索关键词 |
| list | 字符串 | | — | 限制到列表 |
| includeCompleted | 布尔值 | | false | 包括已完成的 |
| limit | 整数 | | 20 | 最大结果数 |
### calendar_create_event
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
| title | 字符串 | ✓ | — | 事件标题 |
| startDate | 字符串 | ✓ | — | ISO 8601 开始时间 |
| endDate | 字符串 | ✓ | — | ISO 8601 结束时间 |
| calendar | 字符串 | | 系统默认 | 日历名称 |
| location | 字符串 | | — | 地点 |
| notes | 字符串 | | — | 描述 |
| allDay | 布尔值 | | false | 全天事件 |
| alerts | 整数[] | | — | 警报偏移量(分钟) |
### calendar_list_events
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
| startDate | 字符串 | ✓ | — | ISO 8601 范围开始 |
| endDate | 字符串 | ✓ | — | ISO 8601 范围结束 |
| calendar | 字符串 | | — | 按日历筛选 |
| limit | 整数 | | 50 | 最大结果数 |
### calendar_find_free_time
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
| date | 字符串 | ✓ | — | ISO 8601 搜索日期 |
| duration | 整数 | ✓ | — | 需要的时间段(15–480 分钟) |
| workingHoursStart | 整数 | | 9 | 开始小时(0–23) |
| workingHoursEnd | 整数 | | 17 | 结束小时(0–23) |
| calendar | 字符串 | | — | 限制到日历 |
### calendar_update_event
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
| eventId | 字符串 | ✓ | EKEvent eventIdentifier |
| title | 字符串 | | 新标题 |
| startDate | 字符串 | | 新的 ISO 8601 开始时间 |
| endDate | 字符串 | | 新的 ISO 8601 结束时间 |
| location | 字符串 | | 新地点 |
| notes | 字符串 | | 新描述 |
### calendar_delete_event
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
| eventId | 字符串 | (之一) | EKEvent eventIdentifier |
| title | 字符串 | (之一) | 事件标题 |
| date | 字符串 | | ISO 8601 日期,用于缩小搜索范围 |
### notes_create
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
| title | 字符串 | ✓ | — | 备忘录标题 |
| body | 字符串 | ✓ | — | 备忘录正文 |
| folder | 字符串 | | "Notes" | 文件夹名称 |
### notes_append
| 参数 | 类型 | 必需 | 描述 |
|---|---|---|---|
| noteId | 字符串 | (之一) | AppleScript 备忘录 ID |
| title | 字符串 | (之一) | 备忘录标题 |
| folder | 字符串 | | 缩小搜索范围 |
| content | 字符串 | ✓ | 要追加的内容 |
### notes_search
| 参数 | 类型 | 必需 | 默认值 | 描述 |
|---|---|---|---|---|
| query | 字符串 | ✓ | — | 搜索关键词 |
| folder | 字符串 | | — | 限制到文件夹 |
| limit | 整数 | | 20 | 最大结果数 |
## 架构
```
Sources/macos-mcp/
├── App.swift # @main 入口 — MCP 服务器设置和工具调度
├── ToolDefinitions.swift # 所有 12 个工具的 JSON 模式定义
├── EventKitManager.swift # 封装 EKEventStore 的 Swift 演员(提醒事项 + 日历)
└── NotesHandler.swift # 用于备忘录操作的 osascript 运行程序
```
## 关于标记提醒事项的说明
EventKit 不公开提醒事项的“标记”状态(它是 Reminders 应用特有的属性,不在 EventKit API 中)。创建提醒事项时,`flagged` 参数会被接受,但会被静默忽略。
## 许可证
MIT