skill-pulse
Live, searchable index of public AI agent Skills scraped from GitHub. Find the right Claude / Cowork / Cursor skill in 5 seconds — no auth, just open and search.
Why
The "Skills" paradigm exploded in 2026 after Anthropic shipped the system in Claude / Cowork. addyosmani/agent-skills blew past 35k stars; anthropics/skills is being forked and remixed weekly. There's no single place to search across these libraries, see freshness, descriptions, and install commands. skill-pulse is that place.
Stack
- Node.js 18+ · Express ·
helmet·compression better-sqlite3(WAL) for storage with FTS5 full-text searchnode-cronfor periodic refreshes- Vanilla JS SPA, dark theme, mobile-friendly. No build step.
Real data sources (no mock / no seed data)
Every skill row is fetched live from the GitHub REST API at runtime:
| Source | URL | Frequency |
|---|---|---|
| Topic search — agent-skills, claude-skills, claude-code-skills, anthropic-skills | https://api.github.com/search/repositories?q=topic:<topic> | Daily 03:15 UTC |
| Curated parent repos (anthropics/skills, addyosmani/agent-skills, obra/superpowers, wshobson/agents, …) | https://api.github.com/repos/{owner}/{repo}/contents/... | Daily 03:15 UTC + hourly :07 |
| SKILL.md files inside each repo | https://api.github.com/repos/{owner}/{repo}/contents/<path>/SKILL.md | Same |
The data/seed-repos.txt file lists known parent repos to fetch — it is not seed data. Every skill in the DB came from a real SKILL.md (or, as a fallback for single-skill repos with no SKILL.md, the repo's own description).
GITHUB_TOKEN is optional. Without it the service uses the unauthenticated GitHub API (60 req/hr per IP) and trims its repo cap accordingly. With a token, the cap rises to 5000 req/hr.
Run it
cp .env.example .env # GITHUB_TOKEN is optional
npm install
npm start # listens on :4753 by default
Then visit http://localhost:4753/skill-pulse/.
The DB will be empty on first start; the server kicks off an initial background refresh ~1.5s after boot. Hit Refresh in the UI to trigger one manually any time.
Endpoints (all public — NO AUTH)
| Method | Path | Description |
|---|---|---|
| GET | /skill-pulse/health | Liveness JSON |
| GET | /skill-pulse/ | SPA |
| GET | /skill-pulse/api/skills | Paginated skill list. Query: q, category, repo, sort (recent/stars/name), limit, offset |
| GET | /skill-pulse/api/skills/:id | Single skill detail |
| GET | /skill-pulse/api/repos | Repo list with star deltas |
| GET | /skill-pulse/api/repos/:owner/:name | Repo detail (with skills) |
| GET | /skill-pulse/api/trending | Top star-gainers in current window |
| GET | /skill-pulse/api/stats | Totals, last refresh, top categories |
| POST | /skill-pulse/api/refresh | Triggers a refresh (in-process 60s cooldown) |
| GET | /skill-pulse/api/refresh/log | Recent refresh history |
| GET | /skill-pulse/api/refresh/:id | Single refresh detail |
Why no auth?
skill-pulse is intentionally fully public — read and refresh — because:
- The index only mirrors public GitHub data; nothing private is exposed.
- The author wants to inspect / kick refreshes from any device without logging in.
- Manual refresh is rate-limited in-process (60s cooldown) to prevent abuse.
There is no Basic Auth, no requireAuth middleware, no admin password, no ADMIN_PASS env var.
Cron schedule
15 3 *UTC — full daily refresh (topic search + every seed repo + every previously-known repo)7— hourly seed-only top-up to capture star deltas
Disable with ENABLE_CRON=false.
Files
skill-pulse/
├── server.js # Express bootstrap
├── db.js # SQLite WAL + schema + prepared statements
├── package.json
├── .env.example
├── README.md
├── CLAUDE.md
├── DEPLOY_MANIFEST.json
├── SPEC.md
├── data/
│ └── seed-repos.txt # parent repos to crawl (fetch list, not seed data)
├── fetchers/
│ ├── github.js # GitHub API client w/ rate-limit awareness
│ └── refresh.js # orchestrator
├── lib/
│ ├── frontmatter.js # tiny YAML frontmatter parser
│ ├── category.js # keyword classifier
│ └── log.js
├── routes/
│ ├── api.js
│ └── pages.js
├── public/
│ ├── index.html
│ ├── app.js
│ └── style.css
└── scripts/
└── refresh-once.js # CLI: node scripts/refresh-once.js
License
MIT — Cowork (Claude Opus 4.7).