| name | reading-list |
| version | 1.0 |
| description | Operate the reading-list API to save, manage, tag, search, and export articles. |
| tools | ["Bash","Read","Write","Edit"] |
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
pnpm install
pnpm dev
pnpm build && pnpm start
docker compose up
Saving articles
curl -X POST http://localhost:3000/api/articles \
-H 'Content-Type: application/json' \
-b 'session=...' \
-d '{"url": "https://blog.golang.org/structured-concurrency"}'
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
curl http://localhost:3000/api/articles
curl "http://localhost:3000/api/articles?status=unread"
curl "http://localhost:3000/api/articles?tag=golang"
curl "http://localhost:3000/api/articles?status=unread&sort=created_at&order=desc"
curl "http://localhost:3000/api/articles?status=unread&archived=0"
curl "http://localhost:3000/api/articles?q=goroutines+concurrency"
Updating article state
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"status": "read"}'
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"read_pct": 65}'
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"starred": 1}'
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"archived": 1}'
curl -X PATCH http://localhost:3000/api/articles/:id \
-H 'Content-Type: application/json' \
-d '{"archived": 0}'
Retrying failed articles
curl -X POST http://localhost:3000/api/articles/:id/refetch
Deleting articles
curl -X DELETE http://localhost:3000/api/articles/:id
Tags
curl http://localhost:3000/api/tags
curl -X POST http://localhost:3000/api/tags \
-H 'Content-Type: application/json' \
-d '{"name": "golang", "color": "#00ACD7"}'
curl -X PATCH http://localhost:3000/api/tags/:id \
-H 'Content-Type: application/json' \
-d '{"name": "go"}'
curl -X DELETE http://localhost:3000/api/tags/:id
curl -X POST http://localhost:3000/api/articles/:id/tags \
-H 'Content-Type: application/json' \
-d '{"tagId": "tag_xyz"}'
curl -X DELETE http://localhost:3000/api/articles/:articleId/tags/:tagId
Full-text search
curl "http://localhost:3000/api/search?q=goroutines"
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
curl -X POST http://localhost:3000/api/import \
-F 'file=@bookmarks.html'
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
curl http://localhost:3000/api/export > reading-list-backup.json
curl "http://localhost:3000/api/export?includeContent=1" > full-backup.json
Authentication
reading-list uses a single-password auth model. To get a session:
CSRF=$(curl -s http://localhost:3000/api/csrf | jq -r '.token')
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"}'
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.