AgentSkillsCN

macos-notes

通过 AppleScript 创建、读取、搜索并管理 macOS 备忘录。当用户提出“记个笔记”“随手记录点什么”“保存一个想法”“撰写会议纪要”“阅读某条备忘录”“搜索备忘录”或任何与 macOS 上的 Apple 备忘录相关的操作时,均可使用此功能。触发条件包括诸如“把这件事记下来”“把这保存为一条备忘录”“创建一条关于 X 的备忘录”“显示我的备忘录”“在我的备忘录中搜索 X”“我之前写过关于 X 的什么内容”等请求。仅适用于 macOS。

SKILL.md
--- frontmatter
name: macos-notes
description: Create, read, search, and manage macOS Notes via AppleScript. Use when the user asks to take a note, jot something down, save an idea, create meeting notes, read a note, search notes, or anything involving Apple Notes on macOS. Triggers on requests like "note this down", "save this as a note", "create a note about X", "show my notes", "search my notes for X", "what did I write about X". macOS only.
license: MIT
compatibility: Requires macOS with Notes.app. Uses osascript (AppleScript) and python3 for JSON parsing.
metadata:
  author: lucaperret
  version: "1.0.0"
  openclaw:
    os: macos
    emoji: "\U0001F4DD"
    homepage: https://github.com/lucaperret/agent-skills
    requires:
      bins:
        - osascript
        - python3

macOS Notes

Manage Apple Notes via $SKILL_DIR/scripts/notes.sh. Notes content is stored as HTML internally; the script accepts plain text or HTML body and returns plaintext when reading.

Quick start

List folders

Always list folders first to discover accounts and folder names:

bash
"$SKILL_DIR/scripts/notes.sh" list-folders

Output format: account → folder (one per line).

Create a note

bash
echo '<json>' | "$SKILL_DIR/scripts/notes.sh" create-note

JSON fields:

FieldRequiredDefaultDescription
titleyes-Note title (becomes the first line / heading)
bodyno""Note content (plain text — converted to HTML automatically)
htmlno""Raw HTML body (overrides body if both provided)
foldernodefault folderFolder name (from list-folders)
accountnodefault accountAccount name (from list-folders)

Read a note

bash
echo '<json>' | "$SKILL_DIR/scripts/notes.sh" read-note

JSON fields:

FieldRequiredDefaultDescription
nameyes-Note title (exact match)
foldernoall foldersFolder to search in
accountnodefault accountAccount to search in

List notes

bash
echo '<json>' | "$SKILL_DIR/scripts/notes.sh" list-notes

JSON fields:

FieldRequiredDefaultDescription
foldernodefault folderFolder name
accountnodefault accountAccount name
limitno20Max notes to return

Search notes

bash
echo '<json>' | "$SKILL_DIR/scripts/notes.sh" search-notes

JSON fields:

FieldRequiredDefaultDescription
queryyes-Text to search for in note titles
accountnodefault accountAccount to search in
limitno10Max results to return

Interpreting natural language

Map user requests to commands:

User saysCommandKey fields
"Note this down: ..."create-notetitle, body
"Save meeting notes"create-notetitle: "Meeting notes — <date>", body
"What did I write about X?"search-notesquery: "X"
"Show my notes"list-notes(defaults)
"Read my note about X"read-notename: "X"
"Save this in my work notes"create-noteMatch closest account/folder from list-folders

Example prompts

"Note down the API key format: prefix_xxxx"

bash
echo '{"title":"API key format","body":"Format: prefix_xxxx"}' | "$SKILL_DIR/scripts/notes.sh" create-note

"Show my recent notes"

bash
echo '{}' | "$SKILL_DIR/scripts/notes.sh" list-notes

"What did I write about passwords?"

bash
echo '{"query":"password"}' | "$SKILL_DIR/scripts/notes.sh" search-notes

"Read my note about Hinge"

bash
echo '{"name":"Hinge"}' | "$SKILL_DIR/scripts/notes.sh" read-note

"Create a meeting summary in my iCloud notes"

bash
"$SKILL_DIR/scripts/notes.sh" list-folders

Then:

bash
echo '{"title":"Meeting summary — 2026-02-17","body":"Discussed roadmap.\n- Q1: launch MVP\n- Q2: iterate","account":"iCloud","folder":"Notes"}' | "$SKILL_DIR/scripts/notes.sh" create-note

Critical rules

  1. Always list folders first if the user hasn't specified an account/folder — folder names are reused across accounts
  2. Specify both account and folder when targeting a specific location — folder: "Notes" alone is ambiguous
  3. Password-protected notes are skipped — the script cannot read or modify them
  4. Pass JSON via stdin — never as a CLI argument (avoids leaking data in process list)
  5. All fields are validated by the script (type coercion, range checks) — invalid input is rejected with an error
  6. All actions are logged to logs/notes.log with timestamp, command, and note title
  7. Body uses plain text — newlines in body are converted to <br> automatically; use html for rich formatting
  8. Note title = first line — Notes.app treats the first line of the body as the note name