Skip to main content
Glama
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