Files
hermes-skills/jotty/SKILL.md
Hermes Agent b0d790be34 Add all 104 active skills from all 16 Hermes profiles
12 unversioned skills now versioned at 1.0.0:
agent-communication, ascii-video, external-reasoning-augmentation,
jotty-notes-api, minecraft-modpack-server, obsidian, pokemon-player,
powerpoint, social-search, songwriting-and-ai-music,
workspace-context-organization, youtube-content

Total repo: 141 skills across all profile scopes
2026-07-04 11:44:04 -05:00

11 KiB

name, description, version, author
name description version author
jotty Talk to the Jotty (jotty.page) self-hosted notes + checklists app via its REST API. Use for Zoe's homework notes, reading logs, study checklists, and todos. Default to the openz instance at 10.0.0.212:3000 with the openz API key. 1.0.0 Hermes Agent (openz profile)

Jotty (jotty.page) — openz profile

Jotty is a self-hosted, file-based notes + checklists app. This skill covers the REST API only — not the web UI. Source: https://github.com/fccview/jotty/blob/main/howto/API.md

openz instance:

  • Base URL: http://10.0.0.212:3000
  • API key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0 (owner: Zoe)
  • App version confirmed live: 1.25.1
  • Web UI: http://10.0.0.212:3000/

Auth header (all non-public endpoints):

x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0

Two important gotchas before doing anything:

  1. Port is 3000, not 80. Health check on 10.0.0.212 (no port) returns nothing. Always use :3000.
  2. No CLI flag for the key — it lives in the x-api-key header. If you curl and forget it, you get 401.

Quick verification (do this first when in doubt)

curl -s -m 5 http://10.0.0.212:3000/api/health
# → {"status":"healthy","version":"1.25.1","timestamp":"..."}

curl -s -m 5 -H "x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0" \
  http://10.0.0.212:3000/api/summary
# → {"summary":{"username":"Zoe","notes":{...},"checklists":{...},...}}

If the health check returns a version, the instance is up. If /api/summary returns Zoe's username, the key is valid. If either fails, stop and tell the user — don't try to read/write with a broken instance.


Endpoint reference (CRUD + tasks + admin)

All endpoints below are http://10.0.0.212:3000 + the path. All require the x-api-key header except /api/health.

Notes

Method Path Purpose
GET /api/notes List all notes. Query: category, q (search title/content)
GET /api/notes/{noteId} Get one note
POST /api/notes Create. Body: {title, content, category?}
PUT /api/notes/{noteId} Update. Body: {title, content, category, originalCategory?}
DELETE /api/notes/{noteId} Delete

Checklists (regular + task type)

Method Path Purpose
GET /api/checklists List. Query: category, type=simple|task, q
POST /api/checklists Create. Body: {title, category?, type?: "simple"|"task"}
PUT /api/checklists/{listId} Update title/category
DELETE /api/checklists/{listId} Delete whole list
POST /api/checklists/{listId}/items Add item. Body: {text, parentIndex?} (regular) or {text, status, time, parentIndex?} (task)
PATCH /api/checklists/{listId}/items/{itemIndex} Update fields: text, description, priority, score, startDate, targetDate, estimatedTime. Omitted fields are left unchanged.
PUT /api/checklists/{listId}/items/{itemIndex}/check Mark complete (supports nested 0.1.2 style paths)
PUT /api/checklists/{listId}/items/{itemIndex}/uncheck Mark incomplete
DELETE /api/checklists/{listId}/items/{itemIndex} Delete item (nested paths supported)

Task checklists (Kanban) — /api/tasks/*

Method Path Purpose
GET /api/tasks List task checklists. Query: category, status, q
GET /api/tasks/{taskId} Get one task
POST /api/tasks Create. Body: {title, category?, statuses?: [{id,label,color?,order}]}
PUT /api/tasks/{taskId} Update title/category
DELETE /api/tasks/{taskId} Delete
GET /api/tasks/{taskId}/statuses List Kanban columns
POST /api/tasks/{taskId}/statuses Add column. Body: {id, label, color?, order?}
PUT /api/tasks/{taskId}/statuses/{statusId} Update column
DELETE /api/tasks/{taskId}/statuses/{statusId} Delete column (items fall to first available)
POST /api/tasks/{taskId}/items Add task item. Body: {text, status?, parentIndex?}
GET /api/tasks/{taskId}/items/{itemIndex} Get one item (includes nested children)
PUT /api/tasks/{taskId}/items/{itemIndex}/status Move to column. Body: {status}
DELETE /api/tasks/{taskId}/items/{itemIndex} Delete task item

Meta endpoints

Method Path Purpose
GET /api/health Public. {status, version, timestamp}
GET /api/summary Stats: note/checklist counts, completion rates, category breakdowns
GET /api/categories List categories with counts. Excludes archived.
GET /api/user/{username} User info (full if self/admin, public otherwise)
GET /api/tasks Already covered above (task checklists)

Admin / exports / logs

Method Path Purpose
POST /api/admin/rebuild-index Admin only. Body: {username} — rebuilds internal link index
POST /api/exports Initiate export. Body: {type: "all_checklists_notes"|"user_checklists_notes"|"all_users_data"|"whole_data_folder", username?}
GET /api/exports Get export progress + download URL
GET /api/logs Audit logs. Query: username?, action?, category?, level?, startDate?, endDate?, success?, limit?, offset?
POST /api/logs/export Export logs. Body: {format: "json"|"csv", filters?: {...}}
GET /api/logs/stats Admin only — aggregated log stats
POST /api/logs/cleanup Admin only — delete logs older than retention

The ck_ca2d142ec7d2adc2574e4aa73ecef3b0 key is not an admin key — /api/logs/stats, /api/logs/cleanup, /api/admin/rebuild-index will return 403 if attempted.


Working with this API — patterns that work

1. Read-then-write for updates

Items are identified by 0-based index within their parent. Indices shift when items are added/removed, so the safe pattern is:

GET /api/checklists/{id} → find current index for "Feed chickens" → PUT /items/{idx}/check

Never cache an index across operations.

2. Nested items use dot-path indices

  • "0" — first top-level item
  • "0.1" — second child of first item
  • "2.0.1" — first child of grandchild 0 of top-level item 2

Same path syntax works for /check, /uncheck, DELETE, and parentIndex on create.

3. Categories are auto-created on first use

If you POST a note with category: "Marine Biology" and that category doesn't exist, Jotty creates it. The /api/categories endpoint then reflects the new tree. No need to pre-register.

4. Note content is markdown

Jotty renders GitHub-flavored markdown. Pass markdown in the content field. For writing-heavy workflows (book reports, study notes), prefer this over checklists.

5. Search is exact-token, not fuzzy

?q=meeting matches titles and item text containing "meeting" as a substring. For broader discovery, fetch the list and filter client-side.


Common recipes for Zoe (openz profile)

Save a quick note

curl -X POST -H "x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0" \
  -H "Content-Type: application/json" \
  -d '{"title":"Marine Biology - Coral Reefs","content":"# Notes\n\n- Reefs cover <1% of ocean floor\n- ...","category":"School/Marine Bio"}' \
  http://10.0.0.212:3000/api/notes

Capture the returned id for future updates.

Add a homework item to an existing checklist

# 1. Find list
curl -s -H "x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0" \
  http://10.0.0.212:3000/api/checklists | jq '.checklists[] | {id,title,items_count: (.items|length)}'

# 2. Append item (use id from step 1)
curl -X POST -H "x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0" \
  -H "Content-Type: application/json" \
  -d '{"text":"Read chapter 4 by Friday"}' \
  http://10.0.0.212:3000/api/checklists/<listId>/items

Check off a todo

# Get current index (may have shifted since last read)
curl -s -H "x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0" \
  http://10.0.0.212:3000/api/checklists/<listId> \
  | jq '.checklists.items // .items | to_entries[] | select(.value.text=="Read chapter 4 by Friday") | .key'

# Then mark complete (use the index above, e.g. "3")
curl -X PUT -H "x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0" \
  http://10.0.0.212:3000/api/checklists/<listId>/items/3/check

Find a note by title

curl -s -H "x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0" \
  "http://10.0.0.212:3000/api/notes?q=coral" | jq '.notes[] | {id,title,category}'

Read a specific note's content

curl -s -H "x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0" \
  http://10.0.0.212:3000/api/notes/<noteId> | jq -r '.notes.content // .content'

Daily / weekly status for Zoe

curl -s -H "x-api-key: ck_ca2d142ec7d2adc2574e4aa73ecef3b0" \
  http://10.0.0.212:3000/api/summary

Error handling

HTTP codes Jotty returns:

  • 200 — success
  • 400 — bad request (malformed body, missing required field)
  • 401 — missing or invalid x-api-key
  • 403 — admin-only endpoint hit with non-admin key
  • 404 — UUID not found / wrong category
  • 500 — server error

Error body: {"error": "message"}. The 404s are common when an item index is stale or originalCategory was wrong on update — re-GET the resource and retry with current values.


Agent behavior (openz profile)

When Zoe mentions something worth remembering — a homework plan, reading log, book idea, recurring task, follow-up, or anything that would benefit from being written down — suggest adding it as a Jotty note or checklist item. Offer the suggestion in chat; do not auto-write without asking.

After creating a note or checklist, always provide the URL link so Zoe can open it directly:

  • Notes: http://10.0.0.212:3000/notes/<id>
  • Checklists: http://10.0.0.212:3000/checklists/<id>
  • Category-filtered listing: http://10.0.0.212:3000/?category=<url-encoded-category>

What this skill is NOT

  • Not a web UI driver. Use the API only. The web UI is at http://10.0.0.212:3000/ for Zoe's browser/PWA.
  • Not shared across profiles. The instance is openz-specific. Don't reference this URL from open1 or other profiles.
  • Not for large files / attachments. Jotty stores notes as markdown text. For images/binary, host them elsewhere and link.
  • Not an admin tool. The ck_ca2d142... key is Zoe's user key. Admin operations (rebuild-index, log stats) will 403.

Reference files

  • references/api-endpoints.md — full endpoint table copied from upstream docs (kept here in case GitHub rate-limits)
  • references/live-state.md — snapshot of Zoe's account as of first run (1 note "Zoe Test Note", 2 checklists "To-do" and "ToDo for Zoe", all in Uncategorized)