New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

skill-router-mcp

Package Overview
Dependencies
Maintainers
1
Versions
1
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

skill-router-mcp

Semantic skill routing for SKILL.md libraries, served over MCP to any agent

latest
Source
npmnpm
Version
0.1.0
Version published
Maintainers
1
Created
Source

skill-router-mcp

Skill routing for SKILL.md libraries, served over MCP to any agent.

Point it at a directory of Agent Skills (SKILL.md files with YAML frontmatter) and any MCP client — Claude Code, Cursor, Windsurf, Codex, or your own agent — can discover skills, match a task to the best one, and load instructions on demand without blowing its context window.

skill-router-mcp demo

match_skill("create a word document")
  → [{ name: "docx", score: 0.85, requires: ["filesystem", "python"] }, ...]
get_skill("docx")
  → full SKILL.md instructions (token-capped, section-aware)

Why this exists (honest version)

Claude Code and Codex now load Agent Skills natively, and several MCP skill servers already exist (skillz, mcp-skill-hub, skillserver, Skills Over MCP). What none of them do is rank skills against a task query — they rely on the host LLM picking from descriptions, which degrades as skill libraries grow. This project's focus is the routing layer: a scored match_skill backed by local embeddings (Ollama + nomic-embed-text, with automatic keyword fallback), plus strict path security and context-window discipline.

Measured on a 48-query labeled benchmark over 16 skills (queries written before measuring, not tuned):

EngineTop-1Top-3MRRms/query
keyword77.1%85.4%0.813~1
semantic (nomic-embed-text)93.8%97.9%0.958~69

Both engines score 100% on queries that share words with the skill description — the gap is entirely on paraphrased (62.5% → 93.8%) and indirect (68.8% → 87.5%) queries like "combine several invoices into a single file for printing" → pdf. Reproduce with npm run benchmark.

Every match_skill response reports which engine produced the ranking (semantic or keyword), so fallback is never silent.

Install & run

npm install
npm run build
SKILLS_ROOT=/path/to/skills node dist/index.js

Claude Code (.mcp.json in your project, or claude mcp add):

{
  "mcpServers": {
    "skill-router": {
      "command": "node",
      "args": ["/absolute/path/to/skill-router-mcp/dist/index.js"],
      "env": { "SKILLS_ROOT": "/absolute/path/to/your/skills" }
    }
  }
}

Tools

ToolPurpose
list_skills()All skills — name + description only (cheap, call first)
match_skill(query, top_k?)Top-k skills for a task, with 0–1 scores and requires
get_skill(name)Full SKILL.md, capped at MAX_TOKENS (default 8000); returns truncated + sections
get_skill_section(name, section)One H2 section — for skills too big for one fetch
rescan_skills()Force re-index (a chokidar watcher also auto-reindexes)

SEP-2640 resources

Skills are also served through the MCP Resources primitive per the Skills Over MCP Working Group draft (SEP-2640), so any spec-aware host can consume them without knowing this server's tools:

  • skill://index.json — enumerable discovery index (Agent Skills discovery schema 0.2.0)
  • skill://<name>/SKILL.md — each skill as a text/markdown resource, with requires/works_in frontmatter exposed under the io.modelcontextprotocol.skills/ _meta prefix
  • The io.modelcontextprotocol/skills extension capability is declared at initialization

Resource reads pass through the same allowlist validation as the tools.

Skill format

Standard Agent Skills format, with two optional routing fields:

---
name: docx
description: "Use when the user wants to create or edit Word documents."
requires: [filesystem, python]   # tools the agent needs to execute this skill
works_in: [claude_code]          # environments the skill is known to work in
---
# Instructions...

Agents should check requires against their own toolset before loading a skill — this server delivers instructions; your agent supplies execution.

Configuration

Env varDefaultMeaning
SKILLS_ROOT./skillsDirectory scanned (recursively) for SKILL.md files
MAX_TOKENS8000Token cap on get_skill responses
WATCH_SKILLStrueSet false to disable the file watcher (network drives, Docker volumes — use rescan_skills instead)
EMBEDDINGSautoauto = semantic if Ollama is reachable, else keyword; on / off to force
OLLAMA_URLhttp://127.0.0.1:11434Ollama endpoint for embeddings
EMBEDDING_MODELnomic-embed-textEmbedding model (ollama pull nomic-embed-text first)

Skill vectors are cached by content hash in ~/.cache/skill-router-mcp/embeddings.json, so restarts and re-indexes only embed skills whose text changed. If Ollama goes down mid-session, matching degrades to keyword automatically — routing never hard-fails.

Security model

  • Allowlist, not paths. Skill names are sanitized to [a-z0-9_-], looked up in an index built at startup, and the resolved file is canonicalized and verified to live inside SKILLS_ROOT. User input never constructs a path.
  • Rejected lookups are logged to stderr.
  • Trust boundary: skill content is injected into your agent's context. Only point SKILLS_ROOT at skills you trust — a 2026 study of 31k marketplace skills found ~26% contained prompt-injection or exfiltration patterns.
  • Index-time content lint. Every skill is scanned for suspicious patterns: prompt injection ("ignore previous instructions"), concealment ("don't tell the user"), exfiltration (send-to-URL, known exfil endpoints), credential access (~/.ssh, .env, API-key harvesting), pipe-to-shell, decode-and-execute, destructive commands, and opaque base64 blobs. Findings are logged at index time, shown as lint_warnings in list_skills, and attached to get_skill responses before the content so a reviewing agent sees the warning first. The lint flags — it never blocks — and rules favor precision over recall.

Roadmap

  • Embedding-based match_skill (local, Ollama nomic-embed-text) behind the Matcher interface, with content-hash caching + keyword fallback
  • Routing benchmark: keyword vs. embeddings on a 48-query labeled set — see benchmark/RESULTS.md
  • Index-time content lint for suspicious skill patterns (10 rules, surfaced in list_skills and get_skill)
  • SEP-2640 alignment: skill:// resources, skill://index.json discovery index, and the skills extension capability

Development

npm test               # vitest: security, indexer, matchers, content
npm run build          # tsc → dist/
node scripts/smoke.mjs # drive the built server over stdio with real queries
npm run benchmark      # keyword vs semantic routing accuracy (needs Ollama)

MIT

Keywords

mcp

FAQs

Package last updated on 08 Jul 2026

Related posts