A CLI and API for managing notes from the terminal—pipe in data, sync to local markdown, and let AI agents read and write your knowledge base.
Sometimes the bottleneck is getting ideas out of your head. Voice-note an idea on a walk, have the CLI sync it to your machine. Now a daily cron job can fire up claude code or codex, read what you said and act on it.
The same pipe works for real-world data. Sensor readings, deploy metadata, server metrics—anything that can hit a CLI can feed your knowledge base and become searchable, AI-readable context alongside your regular notes.
A CLI makes your data portable both into and out of Grug Notes.
The CLI is a Python package that wraps the Grug Notes API. API keys are available on paid plans, so after upgrading you can authenticate from your Settings page and verify the connection.
pip install grugnotes-cli
# or
uv pip install grugnotes-cli
grugnotes # opens settings page to grab your API key
grugnotes status # verify connection
API keys are scoped to a single space. You can generate keys that access all prompts in that space or only a specific allowlist—handy for limiting what a script or agent can touch.
sync init pulls your notes down as plain markdown files, organized by prompt and date. Edit them in VS Code, Vim, or any editor, then push changes back.
grugnotes sync init # clone all notes as markdown
grugnotes sync init --prompt daily-notes # or just one prompt
grugnotes sync init --save-key # persist API key in sync dir
# edit files in your editor of choice...
grugnotes sync status # see what changed
grugnotes sync push # push edits back to Grug Notes
By default, API keys from environment variables aren't saved to disk. Pass --save-key to persist the key inside the sync directory so future commands in that directory work without setting GRUGNOTES_API_KEY.
For continuous sync while you work, sync watch polls for changes and pushes automatically:
grugnotes sync watch # poll every 30s (default)
If your sync state gets out of whack, sync reset rebuilds it from the remote without deleting unmatched local files:
grugnotes sync reset # rebuild sync state from remote
grugnotes sync reset --dry-run # preview first
Use prompts to list all available prompts (categories) in your space, or prompts-search to find one by name without making an API call:
grugnotes prompts --json # list all prompts
grugnotes prompt daily-notes --json # get details for one prompt
grugnotes prompts-search daily --json # offline search of synced prompts
prompts-search matches by exact name, then starts-with, then contains—handy when you know roughly what a prompt is called but not the exact slug.
Most commands support --json for machine-readable output. sync watch is the main exception because it is a long-running log stream. Pipe JSON output through jq (a command-line JSON processor) for easy extraction:
# list all dates with daily notes
grugnotes read daily-notes --json | jq '.data[].date'
# count total notes
grugnotes notes --json | jq '.data | length'
# append a log entry from a script
grugnotes create daily-notes "Deploy completed at $(date)" --append
Combine with cron for recurring jobs. For example, append a daily standup reminder every weekday morning:
# crontab -e
0 9 * * 1-5 grugnotes create daily-notes "standup reminder: what did you ship?" --append
On macOS, consider using launchd instead of cron—it handles sleep/wake correctly so jobs don't silently get skipped when your laptop is closed.
When scripts modify synced files, always pull first to avoid overwriting server-side changes:
grugnotes sync pull # get latest
echo "new content" >> grugnotes/daily-notes/2026-03-15.md
grugnotes sync push # push back
Give your AI agent access to Grug Notes by setting an environment variable. API keys are available on paid plans, and the CLI ships with an AGENTS.md skill file that teaches agents how to use it safely.
export GRUGNOTES_API_KEY="gn_..."
# find the AGENTS.md file bundled with the CLI
python -c "import importlib.resources; print(importlib.resources.files('grugnotes_cli').parent / 'AGENTS.md')"
Point your agent at that file (or copy it into your project) so it learns the CLI commands and safety rules automatically.
Key rules from the skill file that keep agents well-behaved:
--json whenever a command supports it--dry-run before mutating sync operationssync push or editsync watch—it's a long-running process not suited for agentsA typical agent workflow—read today's notes, append a summary, fix a typo:
# read today's notes
grugnotes read "$(date +%Y-%m-%d)" --json | jq '.data[]'
# append a meeting summary
grugnotes create daily-notes "Meeting notes: discussed Q2 planning" --append --json
# fix a typo in note #42
grugnotes edit 42 --old "teh" --new "the" --json
API keys don't have to be all-or-nothing. Each key is fixed to one space, and you can restrict it to a prompt allowlist:
Permissions are set at creation—create a new key if you need different access. If a restricted key tries to create a note in an unauthorized prompt, the API returns a 404—the agent never even sees prompts outside its scope.
# a restricted key can only read/write its allowed prompts
grugnotes notes --json # only returns allowed prompts
grugnotes create secret-stuff "hello" --json # 404 if not in allowlist
API requests are throttled per key: 200 reads/min and 200 writes/min. If you exceed the limit, the API returns 429 with a Retry-After header. The CLI handles this automatically—it backs off and retries until the window resets.
For most workflows this is invisible. A bulk sync push of hundreds of files will throttle itself and keep going rather than crashing.
Sign up, upgrade to a paid plan, grab an API key from Settings, and start piping data into your knowledge base.
Start Free Trial