skill-catalog
Read-only MCP server exposing the repo skill catalog (skills/, docs/public/generated-registries/skills-catalog-index.json)
MCP
FastMCP
2 deps
mcp/skill-catalog/server.py
Read-only MCP server exposing the repo skill catalog (skills/, docs/public/generated-registries/skills-catalog-index.json)
| Field | Value |
|---|---|
| Name | mcp-skill-catalog |
| Version | 0.1.0 |
| Python | >=3.13 |
fastmcp>=2wagents
{ "$schema": "https://gofastmcp.com/public/schemas/fastmcp.json/v1.json", "source": { "path": "server.py", "entrypoint": "mcp" }, "environment": { "type": "uv" }}Server Source
Section titled “Server Source”"""MCP server: skill-catalog.
Read-only access to the repo skill catalog: frontmatter-derived catalognodes (`wagents.catalog.collect_nodes`, kind == "skill") and the generatedpublic machine SSOT (`docs/public/generated-registries/skills-catalog-index.json`).No tool in this server mutates the repository."""
from __future__ import annotations
from typing import Any
from fastmcp import FastMCP
from wagents.mcp_shared.catalog_readers import catalog_summary, find_node, load_skills_catalog_index, node_to_dict
mcp = FastMCP("Skill Catalog")
_READ_ONLY = { "readOnlyHint": True, "destructiveHint": False, "idempotentHint": True, "openWorldHint": False,}
@mcp.tool(annotations=_READ_ONLY)def list_skills(query: str = "") -> list[dict[str, Any]]: """List repo skills from frontmatter-derived catalog nodes.
Use this to browse or search the skill catalog by name/description/tags. Pass *query* (case-insensitive substring) to filter by id, title, or description; leave empty to list every skill. Returns lightweight summaries (id, title, description, source_path) — use `get_skill` for full frontmatter metadata on a specific skill. """ from wagents.catalog import collect_nodes
needle = query.strip().lower() results = [] for node in collect_nodes(): if node.kind != "skill": continue haystack = f"{node.id} {node.title} {node.description}".lower() if needle and needle not in haystack: continue results.append({ "id": node.id, "title": node.title, "description": node.description, "source_path": node.source_path, }) return sorted(results, key=lambda r: r["id"])
@mcp.tool(annotations=_READ_ONLY)def get_skill(skill_id: str) -> dict[str, Any]: """Return full catalog metadata (frontmatter, body, source path) for one skill.
*skill_id* is the kebab-case skill name matching its directory under `skills/<skill_id>/SKILL.md`. Raises if the skill is not found in the catalog — call `list_skills` first if the exact id is unknown. """ node = find_node("skill", skill_id) if node is None: raise ValueError(f"No skill found with id={skill_id!r}. Call list_skills() to browse available ids.") return node_to_dict(node)
@mcp.tool(annotations=_READ_ONLY)def skills_catalog_index() -> dict[str, Any]: """Return the generated public skills-catalog-index.json payload.
This is the machine SSOT for the public skills catalog (custom + curated external), including trust tiers, install commands, and target agents — a superset of frontmatter-only data available from `list_skills`. Regenerated by `wagents docs generate`; returns an empty index shape ({"version": 0, "skills": []}) if it has not been generated yet. """ return load_skills_catalog_index()
@mcp.tool(annotations=_READ_ONLY)def skill_catalog_summary() -> dict[str, int]: """Return coarse counts of catalog nodes by kind (skills, agents, mcp).
Useful as a cheap sanity check before running broader catalog queries. """ return catalog_summary()
if __name__ == "__main__": mcp.run()Resources
Section titled “Resources”MCP OverviewBrowse all MCP documentation in this site.
CLI ReferenceScaffold new MCP servers with wagents.
