reading-list
Operate the reading-list API to save, manage, tag, search, and export articles.
Best use case
reading-list is best used when you need a repeatable AI agent workflow instead of a one-off prompt.
Operate the reading-list API to save, manage, tag, search, and export articles.
Teams using reading-list should expect a more consistent output, faster repeated execution, less prompt rewriting.
When to use this skill
- You want a reusable workflow that can be run more than once with consistent structure.
When not to use this skill
- You only need a quick one-off answer and do not need a reusable workflow.
- You cannot install or maintain the underlying files, dependencies, or repository context.
Installation
Claude Code / Cursor / Codex
Manual Installation
- Download SKILL.md from GitHub
- Place it in
.claude/skills/reading-list/SKILL.mdinside your project - Restart your AI agent — it will auto-discover the skill
How reading-list Compares
| Feature / Agent | reading-list | Standard Approach |
|---|---|---|
| Platform Support | Not specified | Limited / Varies |
| Context Awareness | High | Baseline |
| Installation Complexity | Unknown | N/A |
Frequently Asked Questions
What does this skill do?
Operate the reading-list API to save, manage, tag, search, and export articles.
Where can I find the source code?
You can find the source code on GitHub using the link provided at the top of the page.
SKILL.md Source
# reading-list skill
reading-list is a personal read-it-later app. It fetches article content using Mozilla Readability and stores clean, extracted text in SQLite. Articles can be tagged, filtered by status, searched by full text, and delivered as a daily email digest.
## Environment
```
PORT=3000
DB_PATH=./data/reading-list.db
SESSION_SECRET=<random string>
AUTH_PASSWORD=<bcrypt hash> # generate: node -e "require('bcryptjs').hash('mypassword',10).then(console.log)"
FETCH_TIMEOUT_MS=10000
# Optional: digest email
DIGEST_SMTP_HOST=smtp.example.com
DIGEST_SMTP_PORT=587
DIGEST_SMTP_USER=you@example.com
DIGEST_SMTP_PASS=<password>
DIGEST_FROM=reading-list@example.com
NODE_ENV=production
```
## Starting
```bash
pnpm install
pnpm dev # hot reload
pnpm build && pnpm start
docker compose up # production
```
## Saving articles
```bash
# Save a URL (triggers async fetch + extraction)
curl -X POST http://localhost:3000/api/articles \
-H 'Content-Type: application/json' \
-b 'session=...' \
-d '{"url": "https://blog.golang.org/structured-concurrency"}'
# Poll until status != 'pending'
curl http://localhost:3000/api/articles/:id
```
Extraction is asynchronous. The article starts with `status='pending'` and transitions to `status='unread'` when complete or `status='failed'` if the fetch fails.
## Listing and filtering articles
```bash
# All articles
curl http://localhost:3000/api/articles
# Unread only
curl "http://localhost:3000/api/articles?status=unread"
# Filter by tag
curl "http://localhost:3000/api/articles?tag=golang"
# Unread + sorted by newest
curl "http://localhost:3000/api/articles?status=unread&sort=created_at&order=desc"
# Unread, not archived
curl "http://localhost:3000/api/articles?status=unread&archived=0"
# Full-text search
curl "http://localhost:3000/api/articles?q=goroutines+concurrency"
```
## Updating article state
```bash
# Mark as read
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"status": "read"}'
# Update read progress (0-100)
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"read_pct": 65}'
# Star an article
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"starred": 1}'
# Archive
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"archived": 1}'
# Unarchive
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"archived": 0}'
```
## Retrying failed articles
```bash
curl -X POST http://localhost:3000/api/articles/:id/refetch
```
## Deleting articles
```bash
curl -X DELETE http://localhost:3000/api/articles/:id
```
## Tags
```bash
# List tags
curl http://localhost:3000/api/tags
# Create a tag
curl -X POST http://localhost:3000/api/tags \
-H 'Content-Type: application/json' \
-d '{"name": "golang", "color": "#00ACD7"}'
# Rename a tag
curl -X PATCH http://localhost:3000/api/tags/:id \
-H 'Content-Type: application/json' \
-d '{"name": "go"}'
# Delete a tag (removes from all articles)
curl -X DELETE http://localhost:3000/api/tags/:id
# Add tag to article
curl -X POST http://localhost:3000/api/articles/:id/tags \
-H 'Content-Type: application/json' \
-d '{"tagId": "tag_xyz"}'
# Remove tag from article
curl -X DELETE http://localhost:3000/api/articles/:articleId/tags/:tagId
```
## Full-text search
```bash
# Search all fields (title, excerpt, content)
curl "http://localhost:3000/api/search?q=goroutines"
# Search returns highlighted snippets
curl "http://localhost:3000/api/search?q=structured+concurrency"
```
The search endpoint uses SQLite FTS5. Queries support:
- Simple words: `concurrency`
- Phrases: `"structured concurrency"` (URL-encode as `%22structured+concurrency%22`)
- Prefix: `gorout*`
## Import bookmarks
```bash
# Import Netscape HTML (browser export)
curl -X POST http://localhost:3000/api/import \
-F 'file=@bookmarks.html'
# Import JSON array of URLs
curl -X POST http://localhost:3000/api/import \
-H 'Content-Type: application/json' \
-d '[
{"url": "https://example.com/article1", "title": "Article 1"},
{"url": "https://example.com/article2"}
]'
```
All imported articles are queued for async extraction.
## Export
```bash
# Export all articles as JSON
curl http://localhost:3000/api/export > reading-list-backup.json
# Export with article content included
curl "http://localhost:3000/api/export?includeContent=1" > full-backup.json
```
## Authentication
reading-list uses a single-password auth model. To get a session:
```bash
# Get CSRF token first
CSRF=$(curl -s http://localhost:3000/api/csrf | jq -r '.token')
# Login
curl -X POST http://localhost:3000/api/auth/login \
-H 'Content-Type: application/json' \
-H "X-CSRF-Token: $CSRF" \
-c cookies.txt \
-d '{"password": "mypassword"}'
# Use session cookie in subsequent requests
curl http://localhost:3000/api/articles -b cookies.txt
```
## Bookmarklet
The bookmarklet JavaScript is available from the settings page at `GET /api/settings/bookmarklet`. Paste it as the URL of a browser bookmark to enable one-click saving.Related Skills
Skill: Uptime Monitoring
## Overview
Skill: Status Page
## Overview
Skill: unit-conversion
## Overview
Skill: recipe-scaler
## Overview
email-digest
Configure, test, and troubleshoot the reading-list daily email digest delivered via nodemailer.
websocket-realtime
Use the WebSocket connection in poll-builder to receive live vote updates. Use when you need to stream real-time poll results, monitor a poll for new votes, or build a live dashboard. Triggers include "live results", "real-time updates", "stream votes", "watch poll", or "WebSocket".
poll-builder
Self-hosted poll creation tool with real-time results. Use when you need to create a poll, check vote counts, close a poll, export results, or get the shareable link for a poll. Triggers include "create poll", "vote", "poll results", "survey", "collect votes", "share poll", or any task involving polling or voting.
Skill: personal-finance
## Overview
Skill: csv-import
## Overview
Skill: Syntax Highlighting
## Purpose
Skill: Pastebin Core
## Purpose
Skill: Cost Reporting
## Overview