关于 Apple Contacts
面向 macOS Apple Contacts 的 MCP 服务,使用本地通讯录解析电话号码和邮箱对应的姓名,并提供联系人搜索与读取。写入功能默认关闭,且不需要授予全盘访问权限。
主要功能
- 01批量将号码和邮箱解析为姓名
- 02搜索、列出和读取联系人
- 03启用后创建和更新联系人
- 04对不明确的匹配返回状态而非猜测
适用场景
- 01将电话号码或邮箱解析为联系人
- 02搜索并查看通讯录记录
- 03在启用写入时创建或更新联系人
MCP 相关
作为 MCP 服务,它向客户端提供句柄解析、联系人搜索、列表和读取工具;设置 APPLE_CONTACTS_ALLOW_WRITES=1 后才注册联系人写入工具。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
npx -y @mgcrea/mcp-apple-contactsAPPLE_CONTACTS_ALLOW_WRITESRegister the mutating tools. Off by default, and the gate decides whether the write tools exist at all rather than merely refusing — an agent with writes off cannot see them.本地服务需要在你的电脑上安装运行环境(如 Node.js 18+)。各客户端的配置文件位置不同,请参考客户端文档。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
@mgcrea/mcp-apple-contacts
适用于 macOS Apple Contacts 通讯录的 Model Context Protocol 服务。
非官方。 与 Apple 无关。它会读取 Mac 上已有的通讯录。
存在的原因:解析联系方式
apple_contacts_resolve_handles 可批量将电话号码和电子邮件地址转换为姓名,每批最多
500 条。这里的其他功能都是为此服务的。
这里体现了文件通道规则关注的是能力,而非速度。Contacts 的脚本字典响应时间约为 65 ms——速度足够快,但仍无法胜任这项任务:解析电话号码需要为每个已存储号码建立一个以尾号为键的索引,无论进行多少次 Apple Events 往返,都无法生成这样的索引。因此,读取通过只读 SQLite 完成,并且没有 Apple Events 读取通道。
索引会基于 947 个电话键和 295 个电子邮件键,在 3 ms 内构建完成,然后在进程的整个生命周期内保留。
权限——这里有所不同
| 权限 | 用途 | 说明 |
|---|---|---|
| Contacts(自身权限) | 读取 | 会弹出提示——响应对话框即可 |
| 自动化 → Contacts | 仅写入 | 读取不受影响 |
Contacts 与这一系列中的其他所有功能都不同:它由自己的 TCC 服务保护,而非由“完全磁盘访问权限”保护;与“完全磁盘访问权限”不同,这项权限会_弹出提示_。因此,通常只需“响应对话框”,而不是“前往系统设置”——这里也不会要求你为通讯录授予整个磁盘的访问权限。
工具
读取:diagnostics、resolve_handles、search_contacts、list_contacts、get_contact。
写入工具仅在 APPLE_CONTACTS_ALLOW_WRITES=1 时注册——关闭此标志时,它们对模型不可见,而不只是被拒绝:create_contact、update_contact。
对于已在 Node 内部的调用方,resolveHandles() 也会从包根目录导出;这样就无需通过 MCP 来调用它。
配置
| 变量 | 默认值 | |
|---|---|---|
APPLE_CONTACTS_ALLOW_WRITES | off | 注册修改数据的工具。 |
APPLE_CONTACTS_PHONE_SUFFIX_DIGITS | 9 | 尾号键长度;6–15。 |
APPLE_CONTACTS_INDEX_MODE | auto | auto | ro | immutable | off。 |
APPLE_CONTACTS_STORE | auto | 指定存储路径。 |
APPLE_CONTACTS_OSASCRIPT_TIMEOUT_MS | 30000 | 为首次运行时的权限提示设置的超时时间。 |
这些注意事项可能会让你踩坑
- 存储并非单一。
locate.ts返回一个列表,每次查询都会遍历所有存储区——在真实机器上,stores=2/2, contacts=421,与 Apple Events 的结果完全一致。只读取第一个存储区的服务 会悄无声息地漏掉一个账户。 - 尾号键为 9 位,且长度保存在查找对象中,这样索引和查询就不会出现偏差。在真实通讯录上, 对 7、9 和 10 位长度进行自连接后可以得出结论:7 位和 9 位产生相同的冲突(947 个键中有 10 个,占 1.1%),而 10 位会漏掉一个键,同时无法关联国内号码与 E.164 号码。
- 遇到歧义时只报告状态,绝不猜测——
resolved/unknown/ambiguous/shortcode。 工具说明中将unknown说明为预期情况,而非错误。 Z_ENT会筛选出ABCDContact。 如果没有它,列表工具会把群组当作联系人返回。- 写入可能成功,却仍未持久化。 Contacts 会将更改保存在未保存的缓冲区中,因此修改操作可能在同一脚本内正确读取到结果,却永远不会写入存储区。每个写入脚本都会保存,然后重新读取。
许可证
MIT。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。