apple-notes

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

apple-notes — manage Apple Notes locally via AppleScript

apple-notes — 通过 AppleScript 本地管理 Apple Notes

Drives the user's real Apple Notes through
Notes.app
on macOS. Apple never shipped a cloud API for Notes, so there is nothing to OAuth into and no token to inject — this skill runs on the user's own Mac and talks to Notes.app with AppleScript (
osascript
). It works wherever an agent runs on macOS: the AceDataCloud desktop app (which executes local tools / local MCP on the user's Mac), Claude Code on macOS, or a CodingBridge node on the user's Mac.
surfaces: [mac]
in the frontmatter marks this skill as macOS-desktop only — it cannot run on the web / iOS / Android / Windows surfaces (there is no local
Notes.app
there). The skill/connector directory UI reads this to badge the card ("macOS desktop") and steer users to install it from the macOS desktop app. Absent
surfaces
, a skill is assumed available everywhere.
The skill ships
scripts/notes.py
— self-contained, Python standard library only (it shells out to
osascript
; no
pip install
, no
brew
). Dynamic values are passed as environment variables, never interpolated into the AppleScript source, so note content can't break the script or inject commands.
通过 macOS 上的
Notes.app
操作用户的真实Apple Notes。苹果从未为 Notes 推出云 API,因此无需进行 OAuth 授权,也无需注入令牌 —— 该技能在用户自己的 Mac上运行,通过 AppleScript(
osascript
)与 Notes.app 交互。只要 Agent 在 macOS 上运行,它就能正常工作:比如AceDataCloud 桌面应用(在用户 Mac 上执行本地工具/本地 MCP)、macOS 版 Claude Code,或是用户 Mac 上的 CodingBridge 节点。
surfaces: [mac]
在前置元数据中标记此技能为仅支持 macOS 桌面端 —— 无法在网页/iOS/Android/Windows 平台运行(这些平台没有本地
Notes.app
)。技能/连接器目录 UI 会读取此标记,为卡片添加“macOS 桌面端”标识,并引导用户从 macOS 桌面应用安装该技能。如果没有
surfaces
标记,则默认该技能可在所有平台使用。
该技能附带
scripts/notes.py
—— 一个独立的 Python 脚本,仅依赖 Python 标准库(它通过调用
osascript
执行操作;无需
pip install
,无需
brew
安装依赖)。动态值通过环境变量传递,绝不会直接插入到 AppleScript 源码中,因此笔记内容不会破坏脚本或注入恶意命令。

Requirements

要求

  • macOS with the Notes app.
    python3
    (system Python is fine).
  • Automation permission. The first call triggers a macOS prompt: "Terminal wants to control Notes." Approve it, or enable it under System Settings › Privacy & Security › Automation › (your terminal / agent) › Notes. On an authorization error the CLI tells the user exactly this — do not loop-retry.
  • Referencing Notes launches the app in the background (no window is forced open).
sh
NOTES="${SKILL_DIR:-.}/scripts/notes.py"   # run from this skill's directory
python3 "$NOTES" folders                    # smoke-test the connection
  • macOS 系统,且已安装 Notes 应用。需具备
    python3
    (系统自带的 Python 即可)。
  • 自动化权限。首次调用时会触发 macOS 提示:“终端想要控制 Notes。” 请批准该请求,或在系统设置 › 隐私与安全性 › 自动化 ›(你的终端/Agent)› Notes中启用权限。如果出现授权错误,CLI 会明确告知用户上述操作步骤 —— 请勿循环重试。
  • 调用相关操作时会在后台启动 Notes 应用(不会强制打开应用窗口)。
sh
NOTES="${SKILL_DIR:-.}/scripts/notes.py"   # 从该技能的目录运行
python3 "$NOTES" folders                    # 测试连接是否正常

Commands

命令

CommandRead/WritePurpose
folders
readList folders with note counts
list [--folder F] [--limit N]
readList notes (newest first): id, title, folder, dates
search QUERY [--folder F] [--limit N]
readCase-insensitive substring match on title + body
view NOTE_ID [--format json|text|html]
readShow one note (metadata + body)
export NOTE_ID [--format md|html|text] [-o FILE]
readExport one note to Markdown/HTML/text
create --title T [--body B | --body-file F] [--folder F]
writeCreate a note
append NOTE_ID [--body B | --body-file F]
writeAppend text to an existing note
move NOTE_ID --folder F
writeMove a note to another folder
new-folder NAME
writeCreate a folder
delete NOTE_ID
writeMove a note to Recently Deleted (recoverable)
Most commands print JSON (and errors are always JSON:
{"error": ...}
). The exceptions print raw note content to stdout:
view --format text|html
and
export
without
-o
.
NOTE_ID
is the opaque
x-coredata://…
id returned by
list
/
search
— always fetch a fresh id first; do not guess one.
命令读写权限用途
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": ...}
)。例外情况是:
view --format text|html
和不带
-o
参数的
export
命令会将笔记原始内容输出到标准输出。
NOTE_ID
list
/
search
命令返回的不透明格式
x-coredata://…
ID —— 请始终先获取最新的 ID;切勿猜测。

Read examples

读取操作示例

sh
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
sh
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

Writes are GATED (dry-run unless trailing
--confirm
)

写入操作需确认(未添加
--confirm
则为试运行)

create
,
append
,
move
,
new-folder
, and
delete
change the user's real notes. Without a trailing
--confirm
they dry-run and print what they would do.
--confirm
is honored only as the very last argument. Always show the dry-run, get an explicit "yes", then re-run with
--confirm
appended.
sh
undefined
create
append
move
new-folder
delete
命令会修改用户的真实笔记。如果末尾没有添加
--confirm
参数,它们将仅执行试运行并输出将要执行的操作。
--confirm
参数仅作为最后一个参数时才会生效。请始终先展示试运行结果,获取用户明确的“确认”后,再添加
--confirm
参数重新运行命令。
sh
undefined

Create — dry-run, then confirm

创建笔记 —— 先试运行,再确认

python3 "$NOTES" create --title "Groceries" --body "milk\neggs" # preview python3 "$NOTES" create --title "Groceries" --body "milk\neggs" --confirm # writes
python3 "$NOTES" create --title "Groceries" --body "milk\neggs" # 预览操作 python3 "$NOTES" create --title "Groceries" --body "milk\neggs" --confirm # 执行写入

Create in a folder, body from a file

在指定文件夹创建笔记,正文来自文件

python3 "$NOTES" create --title "Spec" --body-file draft.md --folder "Work" --confirm
python3 "$NOTES" create --title "Spec" --body-file draft.md --folder "Work" --confirm

Append to an existing note

向现有笔记追加内容

python3 "$NOTES" append "x-coredata://…/p42" --body "one more line" --confirm
python3 "$NOTES" append "x-coredata://…/p42" --body "one more line" --confirm

Move / organize

移动/整理笔记

python3 "$NOTES" new-folder "Archive" --confirm python3 "$NOTES" move "x-coredata://…/p42" --folder "Archive" --confirm
python3 "$NOTES" new-folder "Archive" --confirm python3 "$NOTES" move "x-coredata://…/p42" --folder "Archive" --confirm

Delete → goes to Recently Deleted (recoverable ~30 days)

删除笔记 → 移至“最近删除”文件夹(约30天内可恢复)

python3 "$NOTES" delete "x-coredata://…/p42" --confirm

Content is treated as **plain text** (each line becomes a paragraph; the
`--title` is the note's first line, which Notes shows as the title). HTML in the
input is escaped, so it can't inject markup. Use `\n` for line breaks in
`--body`, or pass a file with `--body-file`.
python3 "$NOTES" delete "x-coredata://…/p42" --confirm

内容会被视为**纯文本**(每一行会成为一个段落;`--title` 参数指定的内容会作为笔记的第一行,Notes 应用会将其显示为标题)。输入中的 HTML 会被转义,因此无法注入标记。在 `--body` 参数中使用 `\n` 表示换行,或通过 `--body-file` 参数传入文件内容。

Gotchas

注意事项

  • This is the user's real Notes account. Confirm before any write.
  • list
    scans the whole library
    — for large accounts it can take a few seconds. Narrow with
    --folder
    , and cap with
    --limit
    (default 50).
    search
    filters inside Notes and is faster.
  • Attachments / images: notes containing images or attachments can be read and exported as text, but
    append
    may not preserve embedded attachments — avoid editing attachment notes here; open them in Notes instead.
  • Export → Markdown converts common Notes formatting (headings, bold/italic, lists, links, line breaks). Rich objects (tables, drawings, scanned docs) degrade to plain text.
  • move
    stays within one account
    (e.g. iCloud). Cross-account moves fail.
  • Never assume a
    NOTE_ID
    — ids are store-specific; always get them from
    list
    /
    search
    first.
  • On a persistent authorization error, the Automation permission is missing — tell the user to grant it (see Requirements) and stop; do not retry in a loop.
  • 操作的是用户真实的 Notes 账户。执行任何写入操作前请确认。
  • list
    命令会扫描整个笔记库
    —— 对于笔记数量较多的账户,可能需要几秒时间。可通过
    --folder
    参数缩小范围,并通过
    --limit
    参数限制结果数量(默认50条)。
    search
    命令在 Notes 内部进行过滤,速度更快。
  • 附件/图片:包含图片或附件的笔记可以被读取并导出为文本,但
    append
    操作可能无法保留嵌入式附件 —— 请避免在此处编辑包含附件的笔记;建议直接在 Notes 应用中打开编辑。
  • 导出为 Markdown:会转换 Notes 中的常见格式(标题、粗体/斜体、列表、链接、换行)。复杂对象(表格、绘图、扫描文档)会降级为纯文本。
  • move
    命令仅支持同一账户内移动
    (例如 iCloud 账户内)。跨账户移动会失败。
  • 切勿假设
    NOTE_ID
    固定不变
    —— ID 与存储位置相关;请始终通过
    list
    /
    search
    命令获取最新的 ID。
  • 如果持续出现授权错误,说明缺少自动化权限 —— 告知用户授予权限(参见“要求”部分)并停止操作;请勿循环重试。