关于 context
Cortland 是一套本地优先的 MCP 服务,供 AI Agent 使用 Mac 应用和个人数据。它整合邮件、日历、提醒事项、备忘录及上下文工具,并默认先预览操作,通过人工审批和本地审计记录控制执行。
主要功能
- 01提供 Mail、Calendar、Reminders 和 Notes 工具
- 02重要操作默认预览并需审批
- 03在本地记录工具活动审计日志
- 04上下文层仅存元数据指针,不存邮件正文
- 05提供 iMessage 桥接和所有者通知
适用场景
- 01搜索特定主题的邮件
- 02在简报中查看日历和邮件元数据
- 03在审批控制下创建提醒或备忘录
- 04接收无人值守 Agent 发出的通知
MCP 相关
Cortland 通过 stdio 向 MCP 客户端提供工具,包括 Cursor、Claude Code、Claude Desktop、Codex 和 LM Studio。读取操作无需审批;重要写入会先预览或等待人工批准。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
本地服务需要在你的电脑上运行后才能读取工具,维护者暂未提供工具列表。
详细介绍
Cortland 🍎
你的 Agent 提供大脑。Cortland 提供双手——以及人工把关。
让 AI 真正访问你的 Mac——邮件、日历、提醒事项、备忘录、文件—— 而不把钥匙交给它。每项重要操作都会先预览,通过模型无法触及的渠道等待 你的批准,记录在案,并且可以撤销。
Cortland 没有自己的模型、没有云端,也不能访问网络。这正是它的用意。 无论你已经在使用哪个 Agent——Claude、Codex、Cursor,还是永远不会离开 这台机器的本地 Gemma——它都能以受管控的方式访问你的真实数据,并联系你。
一个实际案例
一个 Agent 连续几天监控几家零售商的网页,等待一款限量版手柄重新上架。它终于补货时——我没在电脑旁,那时我也不在附近——手机响起了一条 iMessage。我买了一只。
Cortland 从未访问过网站。 它没有网页抓取工具,以前没有,以后也不会有。 监控工作由一个可以访问互联网的编码 Agent 完成。Cortland 负责联系我:在我自己的 Mac 上,通过“信息”应用;收件人固定在本地配置中,因此 Agent 生成的任何内容都无法把消息发给其他人。
这个分工就是这段故事要传达的核心。你的 Agent 负责推理和访问互联网。Cortland 拥有你的 Mac、你的 Apple 应用和你的注意力——而每一项对外操作仍会停下来征求批准。
值得一提的部分
第一个版本走了捷径,我只有在查看自己的审计日志后才发现。
当时还没有受管控的“通知人类”工具。“信息”桥接工具可以回复我,却无法主动发起对话——于是监控程序直接导入 Cortland 的发送模块并调用它。它确实能用,而且发送消息的确实是 Cortland:使用相同的本地主人标识、相同的 AppleScript 转义方式、相同的每小时速率上限。但它绕过了框架,而不是通过框架运行,所以运行了好几天,却留下了零条审计记录。
这说明项目没能通过自己的测试。没有正当途径可循的保证,只会被人绕开——而绕开它的人,正是写下这条保证的人。
解决办法是 notify_owner:它对写入安全,因为给你发消息并不是对外操作,消息本身就是审核流程的一环。它完全没有收件人参数——标识来自本地配置,因此模型输出和注入内容都无法重定向消息。每小时上限根据审计日志计算,而不是依赖内存,因此每次运行都会重新启动的 cron 作业也无法超出上限。现在,每条通知都会留下记录。这是一条真实记录,是向我自己的手机发送测试消息后从审计数据库中复制出来的:
notify_owner | Messages | write-safe | undo=none | dry_run=0 | ok
principal: cli:notify tool_version: 0.2.0
args: {"text":{"redacted":true,"length":84,"sha256":"3e389e33…"},
"source":"cortland-test"}
正文以长度和哈希值的形式存储——这条记录可以证明消息已发送,却不会保留消息内容。source 保持可读,因为它是一个受 slug 格式限制的标签,并非任何人都能编写的内容。
使用效果
像给联系人发短信一样发消息——这个桥接由一款 4 GB 模型在 8 GB 的 MacBook Air 上响应。所有数据都留在 Mac 上:
You: Add a reminder to call the vet tomorrow at 2pm
Cortland: Received — working on it…
Cortland: Added "Call vet" for tomorrow, Aug 3 at 2:00 PM.
短信界面需要一个第二个 Apple ID,仅在 Mac 上登录 Messages——它只是传声筒,不负责处理任务。它不拥有邮件、日历或任何数据。你可以像给任何联系人发消息一样用手机给它发短信;Mac 仍会以你的身份执行操作。你的系统 iCloud 仍归你所有。Claude Code、Cursor、Codex 和其他 MCP 客户端无需此步骤:它们通过 stdio 使用相同的工具。
询问本周安排——读取免费,无需批准:
You: Anything from the school this week?
Cortland: Three emails from Lincoln Elementary. Two are the weekly
newsletter; one from Ms. Alvarez on Tuesday asks for a
permission slip by Friday.
让它更改某项内容——每次写入都会暂停并请求批准:
提示词中的代码由框架生成,绝不会进入模型的上下文——因此,即使模型遭到完全的提示词注入,也无法伪造你的批准。忽略这条消息,操作就会过期并被拒绝。
询问它能做什么——根据实际安装的工具作答,因此不会夸大能力:
You: what can you do?
Cortland: Here's what I can do with your Mac:
• Calendar: list, look up, create, delete
• Mail: search, read, follow threads, draft, send (asks first), flag, file
• Notes: search, read, create, add to
• Reminders: list, search, create, tick off, delete
Anything that deletes or changes things asks you first — I text
you a code and wait for "yes <code>". Reads just happen.
在 Claude Code 或 Claude Desktop 中,相同的工具开箱即用:
你: 给 Ms. Alvarez 回复,告诉她周四会寄来证明单 Claude: [搜索邮件并阅读对话] 我可以从你的 Personal 账户发送给 [email protected]。请通过常用渠道批准。
mail_send 受写入权限门控。实时模式下,每项操作都需要人工批准。被盗的令牌只能提出请求。
要求
仅支持 macOS。此处的所有功能都无法在 Windows 或 Linux 上运行——这些工具通过 Automation 与 Apple 应用交互。
| 最低要求 | 舒适配置 | |
|---|---|---|
| OS | macOS 13 Ventura | macOS 15+ |
| Mac | 任何可运行 Ventura 的 Mac(Intel 可运行 Cursor/Claude) | Apple Silicon(M1 或更新机型) |
| Node | 20 LTS(node -v) | 22 |
| 工具链 | Xcode Command Line Tools(xcode-select -p) | 相同——better-sqlite3 需要编译原生代码 |
| 客户端 | 一个 MCP 应用:Cursor、Claude Code、Claude Desktop、Codex 或 LM Studio | 如果想给它发短信,还需要 Ollama |
| 内存 | 8 GB(云端/Cursor 模型,或 Gemma 4 E2B) | 使用更大的本地模型需要 16 GB+ |
| 磁盘 | 此仓库构建需要约 500 MB | 如果拉取 gemma4:e2b-it-qat,还需额外 6 GB |
| Apple 应用 | 你想让它操作的应用,并以你的身份登录 | Mail + Reminders 通常是首选组合 |
仅适用于 iMessage 桥接: macOS 13+(现代版 chat.db)、为运行 Node 的进程授予“完全磁盘访问权限”、Automation → Messages,以及一个登录了 Messages.app、而非系统设置的第二个 Apple ID。请参阅
SETUP.md §5.1。
将 Osaurus 用作客户端: Apple Silicon,macOS 15.5+。
无需开发者账户;Path A 无需 iCloud,也无需 API 密钥。
快速开始
最快体验“它搜到了我的邮件”——使用 Cursor(或 Claude Code)作为大脑,无需第二个 Apple ID,也无需 Ollama:
xcode-select --install # if `xcode-select -p` fails
git clone https://github.com/cortland-suite/cortland.git
cd cortland
npm install && npm run build # first install compiles sqlite — a minute
然后前往 Cursor Settings → MCP,添加服务器,将 node 指向
packages/mail/dist/server.js(以及 reminders/notes/calendar,如果需要)。
使用绝对路径。JSON 配置见
docs/08_local_models.md。
试着问:搜索本周来自学校的所有邮件。 macOS 会提示你授予 Automation 权限(Cursor → Mail)。请允许。
在你于 ~/Library/Application Support/cortland/config.json 中设置 "live": true 之前,写入操作都只会生成预览。即使启用后,发送或删除操作仍会逐项请求批准。
用手机给它发短信的步骤更多(需要第二个 Apple ID + Ollama)。 SETUP.md 提供了按顺序排列的步骤;docs/08 提供了图文说明。
为什么存在
大多数面向个人数据的 MCP 服务只是 AppleScript 的简单封装:
delete_email、send_message,模型一调用就立即执行。把收件箱交给这类工具,很难让人放心;其他替代方案也无济于事——云端助手(Poke、Arlo、Lindy)完全无法访问 Apple 原生数据,因为 Apple 没有为它们提供 API;而 OpenClaw 等可自托管 Agent 则不受管控(2026 年 1 月的 CVSS 评分为 8.8,权限门控仍在路线图上)。
Cortland 颠倒了默认设置。除非你选择启用实时模式,否则工具调用只会预览将要执行的操作;即使启用了实时模式,每项重要操作也都必须等待你的确认。负责强制执行这些规则的框架是一个小型库,其测试套件可证明每项保障都无法绕过,而且套件中的每个工具都基于这个框架构建。
保障措施
| 默认采用试运行模式 | 受管控的工具会预览而非执行操作。任何配置错误都会优先进入试运行模式。 |
| 人工审批在模型之外进行 | 审批通过原生对话框、由你移动的文件、客户端自己的 UI,或你回复的短信进行——绝不会通过模型文本进行。 |
| 所有操作均有审计记录 | 成功、失败、试运行、拒绝、驳回:每项操作都会在本地 SQLite 中留下独立记录。“我的工具实际执行了什么?”始终有据可查。 |
| 注册时强制要求可撤销 | 声称支持原生撤销的工具必须在写入前提供撤销方案,否则框架会拒绝注册。 |
| 内容是数据,不是指令 | 所有从邮件、备忘录或消息中读取的内容,都会返回在由随机数分隔的围栏内。 |
| 通过不提供能力来保障安全 | 不提供未经门控的发送功能。不邀请与会者。不读取他人的对话。 |
| 本地优先 | 无账户、无凭据、无云端。你的模型、你的设备、你的磁盘。 |
安装
从代码仓库安装:
git clone https://github.com/cortland-suite/cortland.git
cd cortland
npm install
npm run build
npx cortland setup
向导会在每个步骤前征求同意,并记录执行的操作。完整指南—— 包括 iMessage 桥接、权限和模型选择——请参阅 SETUP.md。连接 Cursor、Codex、LM Studio、Osaurus 或 Ollama:docs/08_local_models.md。
软件包
| 软件包 | 功能 |
|---|---|
@cortland/governed | 框架:默认试运行、审批门控、审计、溯源、撤销、注入围栏。基于它构建你自己的受管控工具。 |
@cortland/mail | Apple Mail:读取、搜索(两个层级)、会话串、草稿、发送(写入门控)。 |
@cortland/reminders | 提醒事项:列表、搜索、创建、完成、删除——支持原生撤销。 |
@cortland/notes | 备忘录:文件夹、搜索、读取、创建、追加。 |
@cortland/calendar | 日历:时间窗口查询、创建、删除。按设计,不支持发送邀请。 |
@cortland/context | 本地上下文层:邮件/日历元数据(仅指针,绝不包含正文)、简报、人员查询、纠正反馈循环。 |
@cortland/imessage | 给你自己的 AI 发短信。在“信息”中使用第二个 Apple ID(仅作传话工具);从设计上只允许所有者使用,通过回复进行审批,另有 notify_owner,让无人值守的 Agent 能主动联系你。 |
@cortland/folders | 文件夹即 API:从任意设备向 iCloud 中放入文件,即会运行已声明的本地流水线。 |
@cortland/remote | 通过你自己的专用网络,从其他设备访问这套工具。 |
@cortland/setup | 入门向导。 |
使用你自己的模型
Cortland 提供工具。你来选择大脑。
路径 A。 Cursor、Claude Code、Claude Desktop、Codex、LM Studio 或 Osaurus 托管模型。Cortland 是 MCP 插件。无需第二个 Apple ID。
路径 B。 你给它发消息。第二个 Apple ID 登录 Mac 上的“信息”(仅用作传话工具)。
Ollama 在本地运行 Gemma 4。你在同一对话中发送 yes <code>
即可批准。
在 8 GB M2 上经过实测:gemma4:e2b-it-qat(4.3 GB)能够可靠地调用工具,
也会如实拒绝。模型越小,治理契约就越重要,而不是越不重要。
操作指南,包括从全新安装开始配置 LM Studio 和 Osaurus: docs/08_local_models.md。全新 Mac 的配置顺序、 权限设置和 iMessage 第二个 Apple ID 的步骤:SETUP.md。
隐私模型
- 存储指针,而非副本。 上下文层存储引用消息 ID 的元数据;绝不存储正文。在“邮件”中删除消息后,指针就会失效并被清理。
- 模型使用需选择启用并明确声明。 无需模型也能完全确定性地运行。配置模型后,其网络出站连接会在配置中声明,并在每次运行时记录到审计日志。
- 不会回传任何数据。 唯一可选的出站调用是由你自行配置的推送通知,通知正文是固定字符串,不包含任何信息。
文档
- SETUP.md — 从全新 Mac 开始,配置可用的助手,并说明需要注意的问题。
- docs/08_local_models.md — 从零开始连接 Cursor、Codex、 LM Studio、Osaurus 或 Ollama,并附有图示。
- SECURITY.md — 如何报告问题,以及涵盖的范围。
docs/— 每个组件各有一份设计文档:框架契约(01)、 Mail(02)、以文件夹作为 API(03)、上下文层(04)、远程访问(05)、 iMessage 桥接程序(06)、威胁模型/审查指南(07)和本地模型(08)。NOTES.md— 工程日志:带日期的决策、待解决问题,以及每一项实地发现,包括那些令人尴尬的发现。
许可证
MIT。详见 LICENSE。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。