skills/readeck/SKILL.md
Bookmark manager for saving, searching, and annotating web content. Use when: (1) saving a webpage for later reference, (2) searching previously saved bookmarks, (3) adding highlights/annotations to saved content, (4) user asks to 'bookmark this' or 'save this article'. Requires READECK_BASE_URL and READECK_API_KEY environment variables.
npx skillsauth add jcsaaddupuy/badrobots readeckInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Save, search, annotate, and recall web bookmarks. Use as a persistent memory layer: bookmark valuable pages, highlight key passages with notes, and retrieve them during research.
All requests use Bearer token via $READECK_BASE_URL and $READECK_API_KEY.
curl -s -X POST "$READECK_BASE_URL/api/bookmarks" \
-H "Authorization: Bearer $READECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com/article", "labels": ["ai-assistant"]}'
# Wait for processing, then retrieve
sleep 5
curl -s "$READECK_BASE_URL/api/bookmarks?search=example.com" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,title,url,labels}]'
Returns a compact summary — no article content.
curl -s "$READECK_BASE_URL/api/bookmarks" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,title,url,site,labels,description,word_count,reading_time,has_article,is_archived,is_marked,created}]'
Pagination:
curl -s "$READECK_BASE_URL/api/bookmarks?limit=20&offset=0" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,title,url,site,labels,description,word_count,reading_time,has_article,is_archived,is_marked,created}]'
Supports full-text search, label filter, and collection filter (combinable):
# Full-text search
curl -s "$READECK_BASE_URL/api/bookmarks?search=<query>" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,title,url,site,labels,description,word_count,reading_time,has_article,is_archived,is_marked,created}]'
# Filter by label
curl -s "$READECK_BASE_URL/api/bookmarks?labels=<label>" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,title,url,site,labels,description,word_count,reading_time,has_article,is_archived,is_marked,created}]'
# Filter by collection ID
curl -s "$READECK_BASE_URL/api/bookmarks?collection=<collection_id>" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,title,url,site,labels,description,word_count,reading_time,has_article,is_archived,is_marked,created}]'
Metadata only — no article body.
curl -s "$READECK_BASE_URL/api/bookmarks/{ID}" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '{id,title,url,site,site_name,lang,authors,labels,description,word_count,reading_time,has_article,is_archived,is_marked,created,updated}'
The article endpoint returns HTML. Save it then strip tags for readable plain text:
# Save HTML
curl -s "$READECK_BASE_URL/api/bookmarks/{ID}/article" \
-H "Authorization: Bearer $READECK_API_KEY" > article.html
# Plain text for reading
python3 -c "import re,sys;html=open(sys.argv[1]).read();print(re.sub(r'<[^>]+>','',html))" article.html
No single combined endpoint exists. Make two calls and merge:
ID="{ID}"
# 1. Metadata
curl -s "$READECK_BASE_URL/api/bookmarks/$ID" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '{id,title,url,labels,description,word_count,reading_time,created}'
# 2. Highlights
curl -s "$READECK_BASE_URL/api/bookmarks/$ID/annotations" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,text,note,color,created}]'
curl -s "$READECK_BASE_URL/api/bookmarks/{ID}/annotations" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,text,note,color,created}]'
Use scripts/annotate.py — it automatically extracts paragraphs with correct XPath and creates the highlight:
# bookmark_id "text to highlight" "annotation note" color
uv run SKILL_DIR/scripts/annotate.py <ID> "text to highlight" "why this matters" yellow
# Colors: yellow (default), red, blue, green, transparent
uv run SKILL_DIR/scripts/annotate.py <ID> "text" "note" red
# List all paragraphs in the article (debug)
uv run SKILL_DIR/scripts/annotate.py <ID> --list
<div> elements to build correct XPath (e.g., section[1]/div[1]/div[1]/p[1])yellow, red, blue, green, transparent
Readeck uses XPath selectors that reflect the actual DOM structure. The path must include all nested div elements:
curl -s -X POST "$READECK_BASE_URL/api/bookmarks/{ID}/annotations" \
-H "Authorization: Bearer $READECK_API_KEY" \
-H "Content-Type: application/json" \
-d '{"text": "highlighted text", "note": "why this matters", "start_selector": "section[1]/div[1]/div[1]/p[1]", "start_offset": X, "end_selector": "section[1]/div[1]/div[1]/p[1]", "end_offset": Y, "color": "yellow"}'
Gotchas:
div elements: section[1]/div[N]/div[N]/p[N] - NOT just section[1]/p[N]section[1]/div[...]/blockquote[N]/p[N]--list first to see the correct XPath for paragraphscurl -s -X DELETE "$READECK_BASE_URL/api/bookmarks/{ID}/annotations/{HIGHLIGHT_ID}" \
-H "Authorization: Bearer $READECK_API_KEY"
Collections group bookmarks by label filters. Use labels field to query bookmarks belonging to a collection.
curl -s "$READECK_BASE_URL/api/bookmarks/collections" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,name,labels}]'
To list bookmarks in a collection, use its id:
curl -s "$READECK_BASE_URL/api/bookmarks?collection=<collection_id>" \
-H "Authorization: Bearer $READECK_API_KEY" \
| jq '[.[] | {id,title,url,labels,description,word_count,created}]'
Use Readeck as a persistent knowledge base during research:
labels: ["topic", "ai-assistant"])?search=, ?labels=)note explaining their relevancedevelopment
DuckDB patterns for JSON/JSONL analysis, array unnesting, and common gotchas. Use when querying JSON files, nested data, or encountering "UNNEST not supported here" errors.
development
Mealie recipe manager API: recipes, shopping lists, meal plans. Requires MEALIE_BASE_URL and MEALIE_API_KEY.
business
TimeWarrior time tracking: start/stop intervals, query durations by tag or issue, compute totals for issue tracker time reporting
data-ai
YAML parsing and manipulation with yq