Skip to content

ry-animal/mcp-skill-graph

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

12 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Skill Graph Builder MCP Server

An MCP server for building, validating, and traversing graph-structured agent skill systems — networks of composable Markdown files connected through wikilinks.

Skills are organized as a navigable graph where each node is a standalone Markdown file and edges are semantic wikilinks that tell an agent when and why to follow a connection.

Why Skill Graphs?

Traditional agent skills are flat: one file, one capability, loaded in full. This works for simple tasks but breaks down when:

  • A domain is too large for a single context window — the LLM has to load everything even when it only needs one procedure
  • Concepts repeat across capabilities (error handling, auth patterns, rollback steps) and end up duplicated or inconsistent
  • The agent needs to make routing decisions before committing to a full procedure
  • Teams want modular, version-controlled knowledge they can diff, review, and update independently

A skill graph solves this by treating skills as a navigable network. Each node is a small Markdown file. Edges are wikilinks embedded in prose that tell the agent when and why to follow a connection — not just that one exists.

The mental model: a senior engineer onboarding you to a codebase. They don't hand you one giant doc. They give you a map, point you to the right modules, explain how pieces connect, and let you go deeper only where needed.

When to use this

Situation Recommendation
Small, self-contained skill (< 200 lines) Keep it flat. No graph needed.
Skill with 3+ distinct procedures Decompose into leaf nodes under a MoC
Concepts reused across 2+ skills Extract to a shared-concept node
Domain too large for one context window Full graph with MoC routing layer
Existing monolithic skill file Use decompose_skill to automate decomposition

How It Works

An agent navigates a skill graph by reading nodes progressively:

Agent receives task → reads SKILL.md (root MoC)
  → finds the right sub-domain → follows wikilink to sub-MoC
    → identifies the right procedure → follows wikilink to leaf-skill
      → executes the procedure → follows wikilinks to shared concepts as needed

At each step the agent only loads what it needs. A 500-line monolithic skill becomes a 5-node graph where the average interaction loads 2-3 nodes totaling ~100 lines.

Node authoring example

A wikilink must always appear in prose that explains when to follow it:

<!-- BAD: bare wikilink, no context -->
- [[rollback]]

<!-- GOOD: wikilink in prose with decision context -->
If health checks fail after deployment, immediately follow [[rollback]] to revert
to the last known good image tag.

This is enforced by Validation Rule 4 — validate_graph will flag bare wikilinks.


Architecture

graph TB
    subgraph MCP["MCP Server (FastMCP)"]
        direction TB
        Tools["17 Tools"]
        Resources["3 Resources\ngraph://name/node/{node}\ngraph://name/topology\ngraph://name/mermaid"]
        Prompts["3 Prompts\ndomain_discovery\nnode_authoring_guide\nvalidation_report"]
    end

    subgraph Core["Core Layer"]
        direction TB
        Graph["SkillGraph\n(networkx.DiGraph)"]
        GraphMgr["GraphManager\n(multi-graph cache)"]
        Validator["Validator\n(7 rules)"]
        Parser["Parser\n(frontmatter + wikilinks)"]
        Storage["GraphStorage\n(filesystem I/O)"]
    end

    subgraph Disk["Filesystem"]
        direction TB
        SKILL["graphs/{name}/SKILL.md\n(root MoC)"]
        Nodes["graphs/{name}/nodes/*.md"]
        Refs["graphs/{name}/references/*"]
    end

    subgraph LLM["LLM Sampling (ctx.sample)"]
        Stage1["Stage 1: Node Inventory"]
        Stage2["Stage 2: Batch Node Authoring"]
    end

    Tools --> GraphMgr
    Tools --> Storage
    Tools --> Validator
    Resources --> Storage
    GraphMgr --> Graph
    Graph --> Parser
    Parser --> Storage
    Storage --> Disk
    Tools -->|decompose_skill| LLM
    LLM --> Storage
Loading

Component Responsibilities

Component File Role
FastMCP server server.py Tool/resource/prompt registration, lifespan context
SkillGraph graph.py In-memory networkx graph; BFS, cycle detection, Mermaid output
GraphManager graph.py Multi-graph cache with async locks
Validator validator.py 7 graph integrity rules (orphans, depth, wikilink prose, etc.)
Parser parser.py Frontmatter parsing, wikilink extraction, code-block filtering
GraphStorage storage.py Filesystem CRUD; resolves node paths
models.py models.py Pydantic v2 models for all inputs/outputs

Node Types

graph LR
    MoC["map-of-content\nRouting + wikilinks\nMax 80 lines"]
    Leaf["leaf-skill\nFull procedure\nSelf-contained"]
    Shared["shared-concept\nReusable knowledge\nReferenced by ≥2 nodes"]
    Ref["reference\nStatic data\nLoaded on demand"]

    MoC -->|links to| MoC
    MoC -->|links to| Leaf
    MoC -->|links to| Shared
    Leaf -->|references| Shared
    Leaf -->|references| Ref
Loading

decompose_skill Pipeline

sequenceDiagram
    participant Client
    participant Tool as decompose_skill
    participant LLM as ctx.sample()
    participant FS as GraphStorage

    Client->>Tool: content/file_path + graph_name
    Tool->>Tool: Stage 0: validate inputs
    Tool->>LLM: Stage 1: "produce node inventory"
    LLM-->>Tool: JSON array [{name, type, links, ...}]
    loop For each batch of N nodes
        Tool->>LLM: Stage 2: "author node body for batch"
        LLM-->>Tool: JSON array [{name, body}]
    end
    Tool->>Tool: Assemble NodeSpec objects
    alt dry_run=False
        Tool->>FS: scaffold + write nodes
        Tool->>Tool: validate_graph
    end
    Tool-->>Client: DecomposeResult {nodes, validation_report, batch_errors}
Loading

Installation

pip install -e ".[dev]"

Or with uv:

uv sync --extra dev

MCP Client Configuration

Add to your Claude Code settings.json:

{
  "mcpServers": {
    "skill-graph-builder": {
      "command": "fastmcp",
      "args": ["run", "src/skill_graph/server.py"],
      "env": {
        "SKILL_GRAPHS_BASE_PATH": "./graphs"
      }
    }
  }
}

Or using python -m:

{
  "mcpServers": {
    "skill-graph-builder": {
      "command": "python",
      "args": ["-m", "skill_graph.server"],
      "env": {
        "SKILL_GRAPHS_BASE_PATH": "/path/to/your/graphs"
      }
    }
  }
}

Quick Start

Build a graph from scratch

1. scaffold_project(graph_name="my-domain")
2. discover_domain(graph_name="my-domain", domain="...", capabilities=[...], audience="...")
3. create_node(...) for each node in the inventory
4. validate_graph(graph_name="my-domain")
5. read_node / follow_link / search_graph to traverse

Decompose an existing skill file (LLM-powered)

decompose_skill(
    graph_name="my-domain",
    file_path="/path/to/monolithic-skill.md",
    dry_run=True,   # preview first
)

Requires an MCP client that supports LLM sampling (ctx.sample()).


Tool Reference

Traversal

Tool Description
list_graphs List all managed skill graph projects
graph_stats Node counts, depth, link density
read_node Read a node (frontmatter + body)
follow_link Follow a validated wikilink to another node
search_graph Search nodes by query (descriptions, body, tags)

Authoring

Tool Description
create_node Create a new node with frontmatter validation
update_node Partially update an existing node
delete_node Delete a node (refuses if inbound links exist)

Validation

Tool Description
validate_frontmatter Validate a single node's frontmatter
validate_graph Run all 7 graph integrity rules

Structure

Tool Description
scaffold_project Create directory structure for a new graph
export_graph Export as JSON, Mermaid, or node inventory table

Design & Discovery

Tool Description
discover_domain Generate draft node inventory from domain + capabilities
design_topology Validate and diagram a node inventory
visualize_graph Generate Mermaid or ASCII diagram of an existing graph
add_traversal_narrative Trace agent path through the graph for a scenario

LLM-Powered Decomposition

Tool Description
decompose_skill Decompose a monolithic Markdown file into a full skill graph using LLM sampling

decompose_skill parameters:

Parameter Type Default Description
graph_name str required Target graph name (kebab-case)
content str | None None Raw Markdown content
file_path str | None None Path to a .md file (alternative to content)
dry_run bool False Preview decomposition without writing files
batch_size int 4 Nodes authored per LLM call

Validation Rules

The server enforces 7 graph integrity rules on every validate_graph call:

# Rule
1 No orphan nodes — every node reachable from root MoC
2 No dead-end MoCs — every map-of-content links to ≥1 node
3 Shared concepts are shared — shared-concept referenced by ≥2 nodes
4 Wikilinks carry context — every [[link]] has surrounding prose
5 Leaf skills are self-contained — ≥1 section with ≥3 lines of non-link prose
6 Depth ≤ 4 — no node is more than 4 hops from the root
7 No unescaped circular dependencies — cycles require conditional prose

Environment Variables

Variable Default Description
SKILL_GRAPHS_BASE_PATH ./graphs Base directory for skill graph projects

Running Tests

uv run python -m pytest tests/unit/ -v         # Unit tests
uv run python -m pytest tests/integration/ -v  # Integration tests
uv run python -m pytest --cov=skill_graph      # With coverage

About

An MCP server for building, validating, and traversing **graph-structured agent skill systems** — networks of composable Markdown files connected through wikilinks.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages