skills-mcp-server
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-server │
│ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ 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
offsetandlimit - 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)
Install & Build
git clone https://github.com/LucasRomanzin/skills-mcp-server.git
cd skills-mcp-server
npm install
npm run build
Run Locally (stdio)
node dist/index.js
Run as HTTP Server (SSE)
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
{
"mcpServers": {
"skills": {
"command": "node",
"args": ["/path/to/skills-mcp-server/dist/index.js"],
"env": {
"SKILLS_DIR": "/path/to/skills-mcp-server/skills"
}
}
}
}
Remote (HTTP/SSE) — Cursor, VS Code, any MCP client
{
"mcpServers": {
"skills": {
"url": "http://localhost:3000/mcp"
}
}
}
AWS Lambda (after deploy)
{
"mcpServers": {
"skills": {
"url": "https://<function-url-id>.lambda-url.<region>.on.aws/mcp"
}
}
}
See 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
---
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