A minimal example: an MCP server that suggests and serves Agent Skills, and a LangGraph deep agent that asks the router for suggestions, loads the best skill, and uses it.
The server ships with 108 example skills pulled from public sources (nvidia/skills, anthropics/skills; the VoltAgent list was also surveyed).
cp .env.example .env # then put your OpenRouter key in it
docker compose up --buildThat starts the MCP server (108 skills) and runs the agent once on a demo task. You'll see:
TASK: How do I merge several PDFs into one and add page numbers?
PROPOSED SKILLS (MCP suggest_skills):
0.74 pdf — Use this skill whenever the user wants to do anything with PDF files...
0.619 pptx — Use this skill any time a .pptx file is involved...
0.593 docx — Use this skill whenever the user wants to create, read, edit... Word documents
...
LOADED SKILLS (MCP get_skill): ['pdf']
RESULT:
from pypdf import PdfReader, PdfWriter
... (working code, following the loaded pdf skill's instructions)
docker compose run --rm agent "Turn this PowerPoint into branded slides"Set in .env (never committed):
| var | default | notes |
|---|---|---|
OPENROUTER_API_KEY |
— | required to run the agent (get one) |
MODEL |
qwen/qwen3.6-27b |
any OpenRouter model |
Without a key, the demo still prints the router's skill suggestions (the embedding router needs no LLM).
mcp_server/— FastMCP server over streamable HTTP, three tools:list_skills()— every skill's name + descriptionsuggest_skills(task, k)— top-k skills by embedding similarity (CPU, fastembed — no GPU)get_skill(name)— the fullSKILL.mdto load
agent/run.py— a deepagents LangGraph agent wired to those tools vialangchain-mcp-adapters. It suggests → loads → follows the skill.skills/<name>/SKILL.md— each skill's YAMLdescriptionis the routing key; the body is what the agent loads.
Refresh skills from source: python scripts/fetch_skills.py.