apple-notes — 通过 AppleScript 在本地管理 Apple Notes
该技能通过 macOS 上的 Notes.app 操作用户真实的 Apple Notes。由于 Apple 从未为 Notes 提供云端 API,因此没有可 OAuth 授权的接口,也没有可注入的令牌——该技能运行在用户自己的 Mac 上,使用 AppleScript(osascript)与 Notes.app 通信。它可以在任何运行于 macOS 的智能体环境中工作:AceDataCloud 桌面应用(在用户 Mac 上执行本地工具 / 本地 MCP)、macOS 上的 Claude Code,或用户 Mac 上的 CodingBridge 节点。
frontmatter 中的 surfaces: [mac] 标记该技能仅限 macOS 桌面端——它无法在网页 / iOS / Android / Windows 端运行(这些平台没有本地 Notes.app)。技能/连接器目录界面会读取该标记,在卡片上显示徽章(“macOS desktop”)并引导用户从 macOS 桌面应用安装。若未标注 surfaces,则默认该技能在所有平台可用。
该技能附带 scripts/notes.py——自包含,仅使用 Python 标准库(通过 shell 调用 osascript;无需 pip install,也无需 brew)。动态值以环境变量传递,绝不拼接进 AppleScript 源码,因此备忘录内容不会破坏脚本或注入命令。
环境要求
- macOS 且已安装 Notes 应用。
- python3(系统自带 Python 即可)。
- 自动化权限。首次调用会触发 macOS 弹窗:“Terminal wants to control Notes.” 请批准,或在“系统设置 › 隐私与安全性 › 自动化 ›(你的终端 / 智能体)› Notes”中启用。若出现授权错误,CLI 会明确告知用户这一点——请勿循环重试。
引用 Notes 会在后台启动该应用(不会强制打开窗口)。
NOTES="${SKILL_DIR:-.}/scripts/notes.py" # 从该技能目录运行
python3 "$NOTES" folders # 连接冒烟测试
命令
| 命令 | 读/写 | 用途 |
|---|---|---|
| folders | 读 | 列出文件夹及备忘录数量 |
| list [--folder F] [--limit N] | 读 | 列出备忘录(最新优先):id、标题、文件夹、日期 |
| search QUERY [--folder F] [--limit N] | 读 | 对标题 + 正文进行不区分大小写的子串匹配 |
| view NOTE_ID [--format json|text|html] | 读 | 显示单条备忘录(元数据 + 正文) |
| export NOTE_ID [--format md|html|text] [-o FILE] | 读 | 将单条备忘录导出为 Markdown/HTML/文本 |
| create --title T [--body B | --body-file F] [--folder F] | 写 | 创建备忘录 |
| append NOTE_ID [--body B | --body-file F] | 写 | 向已有备忘录追加文本 |
| move NOTE_ID --folder F | 写 | 将备忘录移动到其他文件夹 |
| new-folder NAME | 写 | 创建文件夹 |
| delete NOTE_ID | 写 | 将备忘录移至“最近删除”(可恢复) |
大多数命令输出 JSON(错误始终为 JSON:{"error": ...})。例外情况直接向 stdout 输出原始备忘录内容:view --format text|html 和不带 -o 的 export。NOTE_ID 是 list / search 返回的不透明 x-coredata://… id——务必先获取新的 id;不要猜测。
读取示例
python3 "$NOTES" folders
python3 "$NOTES" list --limit 20
python3 "$NOTES" list --folder "Work" --limit 50
python3 "$NOTES" search "invoice" --limit 20
python3 "$NOTES" view "x-coredata://…/p42"
python3 "$NOTES" export "x-coredata://…/p42" --format md -o note.md
写操作受限(除非末尾带 --confirm,否则为 dry-run)
create、append、move、new-folder 和 delete 会更改用户的真实备忘录。若末尾不带 --confirm,它们会执行 dry-run 并打印将要执行的操作。--confirm 仅在作为最后一个参数时生效。请始终展示 dry-run 结果,获得明确的“yes”后,再追加 --confirm 重新运行。
# 创建 — 先 dry-run,再确认
python3 "$NOTES" create --title "Groceries" --body "milk\neggs" # 预览
python3 "$NOTES" create --title "Groceries" --body "milk\neggs" --confirm # 写入
# 在文件夹中创建,正文来自文件
python3 "$NOTES" create --title "Spec" --body-file draft.md --folder "Work" --confirm
# 追加到已有备忘录
python3 "$NOTES" append "x-coredata://…/p42" --body "one more line" --confirm
# 移动 / 整理
python3 "$NOTES" new-folder "Archive" --confirm
python3 "$NOTES" move "x-coredata://…/p42" --folder "Archive" --confirm
# 删除 → 进入“最近删除”(约 30 天内可恢复)
python3 "$NOTES" delete "x-coredata://…/p42" --confirm
内容按纯文本处理(每行成为一个段落;--title 是备忘录的第一行,Notes 将其显示为标题)。输入中的 HTML 会被转义,因此无法注入标记。在 --body 中使用 \n 换行,或通过 --body-file 传入文件。
注意事项
- 这是用户的真实 Notes 账户。任何写入前请确认。
list会扫描整个资料库——对于大型账户可能需要几秒钟。用--folder缩小范围,用--limit限制数量(默认 50)。search在 Notes 内部过滤,速度更快。- 附件 / 图片:包含图片或附件的备忘录可以读取并导出为文本,但
append可能无法保留内嵌附件——避免在此编辑附件类备忘录;请在 Notes 中打开它们。 - 导出 → Markdown 会转换常见的 Notes 格式(标题、粗体/斜体、列表、链接、换行)。富对象(表格、绘图、扫描文档)会降级为纯文本。
move仅在单个账户内移动(例如 iCloud)。跨账户移动会失败。- 切勿假设 NOTE_ID——id 与存储相关;请始终先从
list/search获取。 - 若出现持续授权错误,说明缺少自动化权限——告知用户授予该权限(见“环境要求”)并停止;不要循环重试。