Skip to main content
Glama
README.md
# vault-graph-mcp

> MCP server that exposes a markdown vault as a **traversable knowledge graph** via NetworkX.
> Runs on **Windows, macOS, Linux** — zero compilation, just `uv` or `pip`.

## What it does

- Walks your vault, parses **`[[wikilinks]]`** AND **`[text](path.md)`** links
- Builds a directed NetworkX graph with typed edges (wikilink, mdlink, backlink, **implicit**)
- **Implicit edges**: Uses sentence-transformers embeddings to find semantically similar notes that were NEVER explicitly linked — the author's blind spots become visible
- Exposes 9 MCP tools for AI agents:

| Tool | Description |
|---|---|
| `vault_search` | Search notes by title, path, or tag |
| `vault_read` | Read full markdown content of a note |
| `vault_neighbors` | Direct neighbors with multi-hop depth |
| `vault_backlinks` | All notes linking TO a target note |
| `vault_traverse` | DFS tree walk from a starting note |
| `vault_path` | Shortest path(s) between two notes |
| `vault_list` | List notes filtered by folder or tag |
| `vault_stats` | Graph stats, top connected, orphans, implicit edge metrics |
| `vault_similar` | Find semantically similar notes (implicit connections via embeddings) |

## Quick Start (Windows)

### 1. Install uv (if you don't have it)

```powershell
winget install --id=astral-sh.uv
```

### 2. Clone the repo

```powershell
git clone https://github.com/ReneRichartz/vault-graph-mcp.git
cd vault-graph-mcp
```

### 3. Install

```powershell
pip install -e .
```

Or with uv (recommended):

```powershell
uv pip install -e .
```

### 4. VS Code MCP Configuration

Create `.vscode/mcp.json` in your workspace:

```json
{
  "servers": {
    "vault-graph": {
      "type": "stdio",
      "command": "uvx",
      "args": [
        "--from", "C:\\Users\\rene\\vault-graph-mcp",
        "vault-graph-mcp"
      ],
      "env": {
        "VAULT_GRAPH_PATH": "C:\\Users\\rene\\mein-fscm-vault",
        "VAULT_IMPLICIT_THRESHOLD": "0.35"
      }
    }
  }
}
```

Alternatively, if installed via pip:

```json
{
  "servers": {
    "vault-graph": {
      "type": "stdio",
      "command": "python",
      "args": ["-m", "vault_graph_mcp.server"],
      "env": {
        "VAULT_GRAPH_PATH": "C:\\Users\\rene\\mein-fscm-vault",
        "VAULT_IMPLICIT_THRESHOLD": "0.35"
      }
    }
  }
}
```

VS Code will auto-detect the server and offer to start it.

### 5. Use in VS Code Agent Chat

Switch to **Agent Mode** (Ctrl+Shift+I, then select "Agent") and ask:

> "Search my vault for sales order entities and show me their dependencies."

> "What notes link to the Pricing Engine?"

> "Find the shortest path between Customer Master and Inventory Reservation."

> "What notes are similar to my microbiome article — even if I never linked them?"

## Environment Variables

| Variable | Description | Default |
|---|---|---|
| `VAULT_GRAPH_PATH` | Absolute path to your markdown vault root | `.` (current dir) |
| `VAULT_IMPLICIT_THRESHOLD` | Cosine similarity threshold for implicit edges (0.0–1.0). Set to `0` to disable. | `0.35` |

## Architecture

```
vault-graph-mcp/
├── pyproject.toml
└── src/vault_graph_mcp/
    ├── __init__.py
    ├── parser.py     # Link extraction: [[wikilinks]] + [text](path.md)
    ├── graph.py      # NetworkX builder (4 phases, incl. implicit)
    ├── implicit.py   # Semantic similarity via sentence-transformers
    └── server.py     # MCP server (9 tools)
```

## Link Resolution

The resolver matches link targets to graph nodes in this order:

1. **Exact match** on node ID (relative path)
2. **Case-insensitive match** on node ID
3. **Last component match** (filename without extension)
4. **Title match** (from `title:` frontmatter or H1 heading)
5. **Normalized match** (dashes → spaces: `sales-order-header` ≈ "sales order header")
6. **Substring match** (target appears anywhere in node ID)

This means your Microsoft Learn-style `[text](path.md)` links resolve correctly **without any conversion** to wikilinks.

## Implicit Edges

Phase 4 of the graph builder uses `sentence-transformers/all-MiniLM-L6-v2` to embed every note and compute pairwise cosine similarity. Pairs above `VAULT_IMPLICIT_THRESHOLD` become bidirectional `implicit` edges with a `weight` attribute.

**Example**: In a vault with no links between "Schottland Mobile Home Parks" and "Golfplatz-Vergleich", the embedder finds them at sim=0.41 because both discuss Scottish locations — a connection the author never wrote down.

Tune the threshold:
- `0.30` — loose, finds more connections (good for exploration)
- `0.35` — default, balanced precision/recall
- `0.50` — strict, only strong thematic overlap
- `0` — disable implicit edges entirely

Maintenance

ActivitySlowing
ResponsivenessNo issues