mcp-skillbox
by beremaran
README.md
# mcp-skillbox
> **⚠️ Archived** — This repository is archived. Its functionality (skill discovery via `list_skills`/`search_skills`/`load_skill`) has been consolidated into the [opencode-beanie-plugin](https://github.com/beremaran/opencode-beanie-plugin) (feature: `skillbox`). Please use that instead.
An MCP (Model Context Protocol) server that aggregates agent skills from [skills.sh](https://skills.sh) and compatible GitHub skill repositories and exposes exactly three tools — `list_skills`, `search_skills`, `load_skill` — so agents can discover and load skills **without bloating their context window**: metadata-first browsing (compact summaries, no descriptions by default), and full skill content fetched only on demand, with byte caps and size reporting.
## Features
- **Context-budget design**: `list_skills` and `search_skills` return compact metadata only (no descriptions by default); full skill content is fetched only via `load_skill`, on demand.
- **Description truncation** at 300 chars when descriptions are requested (`include_description`).
- **`size_bytes` reporting** on every loaded file, plus `max_bytes` caps — both per-call (`load_skill`) and registry-level (`SKILL_MAX_BYTES`).
- **TTL caching** (list/search 60s, details 5 min, GitHub trees 10 min) to cut API calls.
- **Resilient HTTP**: retries with exponential backoff + jitter, timeouts, and `Retry-After` handling for 429s.
- **Registry abstraction** with two adapters: skills.sh (OIDC token mode, richer data incl. install counts) and GitHub (unauthenticated mode that works out of the box).
- **Optional skills.sh OIDC token mode** for install counts and leaderboard data.
## Tools
| Tool | Purpose | Key params | Context cost |
| --- | --- | --- | --- |
| `list_skills` | Browse available skills; compact metadata (id, name, source, installs) | `view`, `page`, `per_page`, `include_description` | Low (no descriptions by default; ≤300 chars if requested) |
| `search_skills` | Find skills by keyword in name/description | `query` (min 2 chars), `limit`, `owner`, `include_description` | Low (≤300-char previews) |
| `load_skill` | Fetch the FULL `SKILL.md` plus optional supporting files | `id`, `include_supporting_files`, `max_bytes` | High — the only expensive call; use only after picking a skill |
> `load_skill` is the only context-heavy call; `list_skills`/`search_skills` are intentionally cheap.
## How it works / architecture
`src/server.ts` registers the 3 tools; `factory.createRegistry()` picks the adapter (auto: token → skills.sh, else GitHub); each adapter implements the `SkillRegistry` interface (`listSkills`/`searchSkills`/`loadSkill`); both use TTL caches and retry/backoff. GitHub mode reads repo trees via the GitHub API and fetches `SKILL.md` files from `raw.githubusercontent.com`.
```
┌─────────────┐ stdio JSON-RPC ┌───────────────────────────────┐
│ Agent / │ ◄────────────────► │ mcp-skillbox (src/server.ts) │
│ MCP client │ │ list_skills / search_skills │
└─────────────┘ │ / load_skill (3 tools) │
└───────────────┬───────────────┘
│ SkillRegistry
┌───────────────▼───────────────┐
│ factory.createRegistry(config)│
│ auto: token ? skills.sh │
│ : github │
└──────┬──────────────────────────────────┬────────┘
│ │
┌▼───────────────────────┐ ┌──────▼─────────────────┐
│ skills.sh API │ │ GitHub API (trees) │
│ /api/v1/* │ │ + raw.githubusercontent│
│ Bearer OIDC │ │ (unauthenticated) │
└────────────────────────┘ └────────────────────────┘
TTL caches + retry/backoff live in both adapters
```
## Requirements
- Node.js >= 18
- npm
## Install & run
```
npm install
npm run build
npm run smoke:mcp # optional end-to-end check over a real stdio MCP session
```
## MCP client configuration
mcp-skillbox speaks MCP over stdio; register it in any MCP-capable client. All configs below assume a local checkout; swap in `npx -y github:beremaran/mcp-skillbox` (works today; once published, `npx -y mcp-skillbox`).
### Claude Code
Add to `.mcp.json` (project) or `~/.claude.json` (user):
```json
{
"mcpServers": {
"skillbox": {
"command": "npx",
"args": ["-y", "mcp-skillbox"],
"env": {
"SKILLS_SH_TOKEN": "your-vercel-oidc-token"
}
}
}
}
```
For local development use the built artifact directly:
```json
{
"mcpServers": {
"skillbox": {
"command": "node",
"args": ["/absolute/path/to/agent-skillbox/dist/index.js"],
"env": {}
}
}
}
```
Equivalent CLI form:
```
claude mcp add skillbox -- npx -y mcp-skillbox
claude mcp add skillbox -- node /absolute/path/to/agent-skillbox/dist/index.js
```
### opencode
Add to `opencode.json` under the `mcp` key. Verified schema (opencode 1.18.x): a local stdio server uses `"type": "local"` and `command` is an **ARRAY** of strings (executable + args together — there is no separate `args` key):
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"skillbox": {
"type": "local",
"command": ["node", "/absolute/path/to/agent-skillbox/dist/index.js"],
"enabled": true,
"environment": {
"SKILLS_SH_TOKEN": "your-vercel-oidc-token"
}
}
}
}
```
### Cursor / VS Code / any stdio MCP client
Generic `mcpServers` shape:
```json
{
"mcpServers": {
"skillbox": {
"command": "node",
"args": ["/absolute/path/to/agent-skillbox/dist/index.js"]
}
}
}
```
### Published package
From the public GitHub repo (works today): `npx -y github:beremaran/mcp-skillbox` (command `npx`, args `["-y", "github:beremaran/mcp-skillbox"]`). Once published to npm, any client can also use `npx -y mcp-skillbox` (command `npx`, args `["-y", "mcp-skillbox"]`).
## Environment variables
| Variable | Default | Description |
| --- | --- | --- |
| `SKILLS_SH_TOKEN` | (none) | Optional. Enables the skills.sh API mode with richer data (install counts, leaderboard views). Obtainable from a Vercel project via OIDC, per the skills.sh docs. |
| `SKILL_REGISTRY` | `auto` | `auto` (token present → skills.sh, else GitHub), `skills-sh`, or `github`. |
| `SKILL_GITHUB_SOURCES` | `vercel-labs/skills, anthropics/skills, obra/superpowers, mattpocock/skills, microsoft/azure-skills, supabase/agent-skills, prisma/skills` | Comma-separated `owner/repo` list for GitHub mode. |
| `SKILL_MAX_BYTES` | `200000` | Registry-level byte cap applied to loaded skill content. |
| `GITHUB_TOKEN` | (none) | Optional GitHub token; sent as Authorization on `api.github.com` calls to raise API rate limits. |
| `SKILL_DEBUG` | (none) | Set to `1` or `true` to log registry selection and diagnostics to stderr. |
## How registry selection works
In `auto` mode: if `SKILLS_SH_TOKEN` is set → skills.sh registry (its API requires `Authorization: Bearer <VERCEL_OIDC_TOKEN>`; requests without it get 401, rate limit ~600 req/min). Otherwise → GitHub registry using the public GitHub API + `raw.githubusercontent.com`, which works immediately with no credentials. `SKILL_REGISTRY=github` or `=skills-sh` forces a specific adapter (skills-sh without a token throws a clear `RegistryAuthError`).
## Example agent conversation (context-budget behavior)
```
Agent: I need to add tests for a React component. Let me find a skill.
Agent → search_skills({ query: "react testing", include_description: true })
mcp-skillbox → { count: 3, results: [
{ id: "vercel-labs/agent-skills/react-testing", name: "React Testing", source: "vercel-labs/agent-skills", description: "Setup and patterns for testing React components with Vitest..." },
{ id: "mattpocock/skills/react-hooks-testing", name: "React Hooks Testing", source: "mattpocock/skills", description: "Best practices for testing custom React hooks in isolation..." },
{ id: "prisma/skills/e2e-testing", name: "E2E Testing", source: "prisma/skills", description: "End-to-end testing setup for web apps..." }
] }
Agent: "react-testing" is the best fit.
Agent → load_skill({ id: "vercel-labs/agent-skills/react-testing" })
mcp-skillbox → { id: "vercel-labs/agent-skills/react-testing", name: "React Testing", files: [
{ path: "SKILL.md", size_bytes: 8421, contents: "# React Testing\n..." }
] }
Agent: Uses the full SKILL.md instructions to write the tests.
```
The agent only ever paid for the full content of the skill it actually used — the two losing skills cost nothing beyond their ~300-char previews.
## Development
- `npm test` — vitest unit/integration tests (8 files)
- `npm run typecheck` — `tsc --noEmit`
- `npm run build` — emit `dist/`
- `npm run dev` — watch build
- `npm run smoke` — real-network GitHub registry smoke (`tsx src/smoke.ts`)
- `npm run smoke:mcp` — full end-to-end MCP smoke over stdio (`node scripts/mcp-smoke.mjs`; spawns `dist/index.js`, lists 3 tools, calls `list_skills` + `load_skill` for real)
- Tests live in `tests/` (cache, factory, frontmatter, github, http, index, server, skills-sh).
> **IMPORTANT**: The `@modelcontextprotocol/sdk` root import is broken in v1.30.0 — always import from subpaths (`@modelcontextprotocol/sdk/server/mcp.js`, `/server/stdio.js`, `/client/index.js`, `/inMemory.js`). The `registerTool(name, config, callback)` form is the tool-registration API.
## Limitations & roadmap
- skills.sh install counts/leaderboard require the OIDC token; GitHub mode has no install counts.
- GitHub unauthenticated API rate limits (~60 req/hr for contents/trees) — mitigated by tree caching (10 min TTL) and fetching file contents from `raw.githubusercontent.com` (which is not rate-limited the same way).
- No write/install tools yet. Roadmap: install skills to a target directory, packs support, multi-registry federation, HTTP/SSE transport, resource endpoints for installed skills.
## License
MIT — see [LICENSE](LICENSE).
TDQS
A4.2/5.0
Scored across 3 tools
Disambiguation5/5
Each tool has a distinct role: list for browsing, search for finding by keyword, load for retrieving full content. There is no overlap in functionality or purpose.
Naming Consistency4/5
Tools follow a verb_noun pattern, but 'list_skills' and 'search_skills' use plural while 'load_skill' uses singular. This minor inconsistency is predictable and does not cause confusion.
Tool Count5/5
With 3 tools, the server is well-scoped for a skill registry: browse, search, and retrieve full content. Each tool serves a necessary function without unnecessary bloat.
Completeness5/5
The tool surface covers the full workflow for discovering and using skills: listing available skills, searching them, and loading the full content when needed. No obvious gaps exist for the stated purpose.
Maintenance
ActivitySlowing
ResponsivenessNo issues