skills-mcp-server
README.md
# skills-mcp
A high-performance MCP (Model Context Protocol) server that exposes a catalog of **1300+ AI skills** through BM25-ranked search, structured metadata, and context-efficient responses.
Built to solve one problem: **thousands of skills destroy your context window**. This server indexes them, ranks them, and serves only what you need.
```
┌────────────────────────────────────────────────────────────┐
│ IDE / AI Client │
│ (Claude, Cursor, Gemini, Copilot, Windsurf, ...) │
│ │
│ "find me a skill for React dashboards" │
└──────────────────────┬─────────────────────────────────────┘
│ MCP Protocol
▼
┌────────────────────────────────────────────────────────────┐
│ skills-mcp │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ Indexer │ │ BM25 │ │ 6 MCP │ │
│ │ 1300+ │──│ Search │──│ Tools │ │
│ │ skills │ │ Engine │ │ │ │
│ └──────────┘ └──────────┘ └──────────┘ │
│ │
│ Transports: stdio | HTTP/SSE | AWS Lambda │
└────────────────────────────────────────────────────────────┘
```
---
## Features
- **BM25-ranked search** — Not keyword matching. Real relevance scoring with field weighting (name 3x, description 2x, tags 2x, body 1x)
- **Context-efficient** — Read skill metadata (~500 chars), summary (~2K chars), or full content (capped at 25K chars). You control how much context to spend
- **Structured metadata** — YAML frontmatter parsed into typed fields: name, description, tags, category, risk, author, tools
- **Pagination everywhere** — Every list/search tool supports `offset` and `limit`
- **3 transport modes** — stdio for local IDEs, HTTP/SSE for remote access, AWS Lambda for serverless
- **Fast startup** — 1300+ skills indexed in ~1.5 seconds. ~3MB memory footprint (vs 65MB raw)
- **6 specialized tools** — Browse, list, search, read, inspect, refresh
---
## Quick Start
### Prerequisites
- Node.js 18+
- The `skills/` directory with SKILL.md files (see [Skill Format](#skill-format))
### Install & Build
```bash
git clone https://github.com/LucasRomanzin/skills-mcp.git
cd skills-mcp
npm install
npm run build
```
### Run Locally (stdio)
```bash
node dist/index.js
```
### Run as HTTP Server (SSE)
```bash
node dist/http.js
# Server starts on http://localhost:3000
# MCP endpoint: http://localhost:3000/mcp
# Health check: http://localhost:3000/health
```
---
## MCP Tools
### `skills_browse_categories`
List all skill categories with counts. Use this first.
```
Input: { response_format?: "markdown" | "json" }
Output: Table with 9 categories and skill counts
```
### `skills_search`
BM25-ranked full-text search across names, descriptions, tags, and content.
```
Input: { query: string, category?: string, risk?: string, offset?: 0, limit?: 10 }
Output: Ranked results with name, description, category, tags, score
```
### `skills_list_by_category`
List skills within a specific category with pagination.
```
Input: { category: string, offset?: 0, limit?: 20 }
Output: Paginated skill list with metadata
```
### `skills_read`
Read skill content with context control.
```
Input: { slug: string, section?: "metadata" | "summary" | "full", file?: string }
section="metadata" → ~500 chars (frontmatter fields + file list)
section="summary" → ~2500 chars (metadata + first 2000 chars of body)
section="full" → up to 25000 chars (complete content, truncated if larger)
```
### `skills_inspect`
Get structured metadata for multiple skills + related skills by tag overlap.
```
Input: { slugs: string[] (1-10), response_format?: "json" }
Output: Metadata + related_skills for each slug
```
### `skills_refresh_index`
Rebuild the in-memory index after adding/removing/modifying skills on disk.
```
Input: {}
Output: Previous count, new count, duration
```
---
## IDE Configuration
### Claude Desktop / Claude Code
```json
{
"mcpServers": {
"skills": {
"command": "node",
"args": ["/path/to/skills-mcp/dist/index.js"],
"env": {
"SKILLS_DIR": "/path/to/skills-mcp/skills"
}
}
}
}
```
### Remote (HTTP/SSE) — Cursor, VS Code, any MCP client
```json
{
"mcpServers": {
"skills": {
"url": "http://localhost:3000/mcp"
}
}
}
```
### AWS Lambda (after deploy)
```json
{
"mcpServers": {
"skills": {
"url": "https://<function-url-id>.lambda-url.<region>.on.aws/mcp"
}
}
}
```
> See **[docs/SETUP.md](docs/SETUP.md)** for complete step-by-step setup guides for all modes and IDEs.
---
## Deployment Modes
| Mode | Command | Use Case | SSE Streaming |
|------|---------|----------|---------------|
| **stdio** | `node dist/index.js` | Local IDEs (Claude, Cursor, Gemini CLI) | N/A |
| **HTTP** | `node dist/http.js` | Dev server, EC2, VPS, Docker | Yes |
| **Lambda** | SAM deploy | Serverless, auto-scaling, pay-per-use | Yes (response streaming) |
---
## Skill Format
Each skill is a directory under `skills/` containing at minimum a `SKILL.md` file with YAML frontmatter:
```
skills/
├── CATALOG.md # Category-to-skill mapping (auto-generated)
├── my-skill/
│ ├── SKILL.md # Required: frontmatter + content
│ ├── references/ # Optional: additional .md files
│ └── scripts/ # Optional: helper scripts
```
### SKILL.md Structure
```markdown
---
name: my-skill
description: What this skill does in one sentence.
tags:
- react
- dashboard
- frontend
risk: safe
source: community
author: your-name
tools:
- claude-code
- cursor
---
# My Skill
## Overview
...
## When to Use This Skill
...
```
### Frontmatter Fields
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | Yes | Skill identifier |
| `description` | string | Yes | One-line description |
| `tags` | string[] | No | Searchable keywords |
| `risk` | enum | No | `safe`, `critical`, `offensive`, `unknown`, `none` |
| `source` | string | No | Origin (`community`, `official`) |
| `author` | string | No | Creator name |
| `tools` | string[] | No | Compatible AI tools |
---
## Architecture
```
src/
├── index.ts # stdio entry point
├── http.ts # Express HTTP/SSE entry point
├── lambda.ts # AWS Lambda handler
├── server.ts # McpServer factory (shared)
├── constants.ts # CHARACTER_LIMIT, pagination defaults
├── types.ts # TypeScript interfaces
├── indexer.ts # Frontmatter parser + skill index builder
├── catalog.ts # CATALOG.md parser → category mapping
├── search.ts # BM25 scoring engine
├── tools/
│ ├── browse.ts # skills_browse_categories
│ ├── list.ts # skills_list_by_category
│ ├── search.ts # skills_search
│ ├── read.ts # skills_read
│ ├── inspect.ts # skills_inspect
│ └── refresh.ts # skills_refresh_index
└── utils/
├── frontmatter.ts # gray-matter wrapper + tag normalization
├── format.ts # Markdown/JSON response formatters
├── truncate.ts # CHARACTER_LIMIT enforcement
└── paginate.ts # Generic pagination
```
### Search Engine
The BM25 implementation indexes each skill as a weighted document:
| Field | Weight | Example |
|-------|--------|---------|
| `name` | 3x | "react-patterns" repeated 3 times |
| `description` | 2x | "Modern React patterns..." repeated 2 times |
| `tags` | 2x | "react frontend hooks" repeated 2 times |
| `category` | 1x | "development" |
| `summary` | 1x | First 500 chars of body |
Scoring uses BM25 with k1=1.5, b=0.75. Results are sorted by relevance score descending.
**Performance**: search across 1300+ skills completes in <10ms.
---
## Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `SKILLS_DIR` | `~/skills-mcp/skills` | Path to the skills directory |
| `PORT` | `3000` | HTTP server port (http.ts only) |
---
## Tech Stack
- **TypeScript** — Strict mode, ESM
- **MCP SDK** v1.29+ — `StreamableHTTPServerTransport`, `WebStandardStreamableHTTPServerTransport`
- **gray-matter** — YAML frontmatter parsing
- **Zod** — Input validation schemas
- **BM25** — Custom implementation (~80 lines), zero external dependencies
---
## License
MIT
This server cannot be deployed
Maintenance
ActivityInactive
ResponsivenessNo issues