# Vaultforge

> Local MCP server for Obsidian vault operations — search, intelligence, canvas tools

- **Type:** MCP server
- **Install:** `agentstack add mcp-blacksmithers-vaultforge`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [blacksmithers](https://agentstack.voostack.com/s/blacksmithers)
- **Installs:** 0
- **Category:** [Productivity](https://agentstack.voostack.com/c/productivity)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [blacksmithers](https://github.com/blacksmithers)
- **Source:** https://github.com/blacksmithers/vaultforge

## Install

```sh
agentstack add mcp-blacksmithers-vaultforge
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

The most capable MCP server for Obsidian.

  27 tools · Canvas with auto-layout · BM25 smart search · Vault intelligence
  No Obsidian plugin required · Works on macOS, Linux, Windows

  Canvas ·
  Search ·
  Intelligence ·
  All 27 Tools ·
  Install

---

## The Problem with Every Other Obsidian MCP

I checked them all — mcp-obsidian, mcpvault, obsidian-mcp-server, obsidian-mcp-tools, obsidian-mcp-plugin. They read files. They write files. Some search. That's it.

None of them can create a visual diagram. None of them rank search results by relevance. None of them can tell an agent *"here are the 12 themes in this vault and which files belong to which."*

VaultForge does all three.

| Feature | VaultForge | mcp-obsidian | mcpvault | obsidian-mcp-server |
|---------|:-:|:-:|:-:|:-:|
| Read / Write / Delete notes | ✅ | ✅ | ✅ | ✅ |
| Full-text search | ✅ | ✅ | ✅ | ✅ |
| Edit in-place | ✅ | ❌ | ✅ | ❌ |
| Batch operations | ✅ | ❌ | ❌ | ❌ |
| Daily notes | ✅ | ❌ | ❌ | ✅ |
| Vault stats | ✅ | ❌ | ✅ | ❌ |
| **Canvas — create with auto-layout** | ✅ | ❌ | ❌ | ❌ |
| **Canvas — semantic read** | ✅ | ❌ | ❌ | ❌ |
| **Canvas — patch (add/remove/update)** | ✅ | ❌ | ❌ | ❌ |
| **Canvas — re-layout (dagre)** | ✅ | ❌ | ❌ | ❌ |
| **BM25 smart search (Orama)** | ✅ | ❌ | ❌ | ❌ |
| **Vault theme mapping (TF-IDF)** | ✅ | ❌ | ❌ | ❌ |
| **Vault reorganization engine** | ✅ | ❌ | ❌ | ❌ |
| **Regex find-and-replace (grep-sub)** | ✅ | ❌ | ❌ | ❌ |
| **Batch rename / move with link updates** | ✅ | ❌ | ❌ | ❌ |
| **Backlink analysis** | ✅ | ❌ | ❌ | ❌ |
| **Frontmatter as structured data** | ✅ | ❌ | ❌ | ❌ |
| **Directory management (delete, prune)** | ✅ | ❌ | ❌ | ❌ |
| No Obsidian plugin required | ✅ | ❌ | ✅ | ❌ |

---

## Fewer Tokens. Same Intelligence.

The other Obsidian MCPs weren't designed for AI agents — they were designed for humans who happen to use AI. Every tool returns raw, verbose data that burns through context windows. VaultForge is **AI-infrastructure**: every response is shaped to minimize token consumption while maximizing semantic density.

| Operation | Traditional MCP | VaultForge | Savings |
|---|---|---|---|
| Read a canvas | Raw JSON — coordinates, hex IDs, pixel dimensions | Semantic graph: labels + connections only | ~70-80% fewer tokens |
| Search vault | Unranked grep dump — agent reads 50 results to find 3 | BM25-ranked top results with relevance scores | ~90% fewer tokens |
| Understand vault structure | Agent reads files one by one (N calls × M tokens each) | One `vault_themes()` call returns clustered map | ~95% fewer tokens |

Tokens = API cost, context window space, and latency. Fewer tokens means faster, cheaper, smarter agents.

---

## Three Things No Other MCP Can Do

### 🎨 Canvas Tools

> The agent thinks in graphs. The tool thinks in pixels.

AI agents create, read, modify, and re-layout [JSON Canvas](https://jsoncanvas.org/) files without touching a single coordinate. The agent describes a semantic graph. VaultForge calculates all geometry using [dagre](https://github.com/dagrejs/dagre) — the same Sugiyama layout engine behind Mermaid and React Flow.

**canvas_create** — describe nodes and edges, get a fully laid-out `.canvas` file:

```
Agent sends:                              Obsidian renders:
                                          
  nodes:                                  ┌───────────┐
    - API Gateway                         │    API    │───┐
    - Auth Service                        │  Gateway  │   │
    - Database                            └───────────┘   │
    - Cache                               ┌───────────┐   │   ┌───────────┐
  edges:                                  │   Auth    │───┼──▶│ Database  │
    - API Gateway → Auth Service          │  Service  │   │   └───────────┘
    - API Gateway → Cache                 └───────────┘   │
    - Auth Service → Database                             │   ┌───────────┐
    - Cache → Database                                    └──▶│   Cache   │
  layout: { direction: "LR" }                                 └───────────┘
```

**canvas_read** — semantic graph, not raw JSON:

```
Instead of:  {"id":"231bf38f","x":-635,"y":-420,"width":250,"height":70,...}
Agent gets:  { label: "AXON", connections: ["Strategy", "AWS", "Resistance"] }
```

A typical canvas with 15 nodes returns ~200 tokens as a semantic graph vs ~2,000+ tokens as raw JSON Canvas. The agent gets the same information at 10% of the cost.

**canvas_patch** — modify with relative positioning:

```
add_nodes: [{ label: "New Module", near: "API Gateway", position: "below" }]
remove_nodes: ["Deprecated Service"]  →  cascade-removes all connected edges
```

**canvas_relayout** — fix a messy canvas with one call. Preview before committing.

---

### 🔍 Smart Search

> Not grep. Elasticsearch-grade.

[Orama](https://github.com/oramasearch/orama) BM25-ranked search with typo tolerance, stemming (26 languages), and field boosting. No ML, no API keys, no internet.

```
smart_search("stripe webhook")

  → Stripe-Webhooks.md             score: 0.92
    "...webhook endpoint configuration for handling Stripe events..."
  
  → Refactor-Prompts.md            score: 0.61
    "...refactor the Stripe integration to use webhook signatures..."

vs search_content("stripe webhook")
  → Returns EVERY file containing "stripe", unranked, no scoring
```

Unranked grep forces the agent to consume every result to find relevance. BM25 puts the answer at the top. Fewer results read = fewer tokens burned = faster, cheaper responses.

**Field boosting:** title (3×) > tags (2.5×) > headings (2×) > content (1×).

**Persistent index** at `.vaultforge/search-index.json` — survives restarts.

---

### 🧠 Vault Intelligence

> Your vault has folders. Now it has a map.

Files land where the energy of the moment puts them. Themes bleed across folders — "SpecForge" ends up in `Projetos/`, `AI/prompts/`, `Content/`, and `Empresas/`. Nobody maintains a perfect taxonomy.

**vault_themes** — scans every file, extracts distinctive terms via TF-IDF, clusters by similarity:

```json
{
  "themes": [
    {
      "label": "SpecForge Frontend",
      "key_terms": ["impl", "dashboard", "widget"],
      "files": 12,
      "folders": ["32-AI/prompts/specforge"],
      "coherence": 0.89
    },
    {
      "label": "Content Strategy",
      "files": 6,
      "folders": ["80-Content", "70-Empresas"],
      "cross_folder": true
    }
  ],
  "orphans": 5,
  "cross_folder_warnings": 3
}
```

Without this, an agent needs to `read_note` on every file individually to understand vault structure — hundreds of tool calls, thousands of tokens. One `vault_themes()` call replaces all of them.

**vault_suggest** — actionable reorganization from the atlas:

```json
{
  "suggestions": [
    { "type": "consolidate", "action": "Move Launch-Strategy.md → 80-Content/" },
    { "type": "create_moc", "action": "Create MOC-SpecForge-Frontend.md linking 12 files" },
    { "type": "archive", "action": "Move 8 stale files to 90-Archive/" }
  ]
}
```

**The full workflow:**

```
"Organize my vault"
  → vault_themes()      maps 179 files into 15 themes
  → vault_suggest()     generates 20 reorganization actions  
  → human approves      "do it, skip the archive stuff"
  → batch execution     moves files, creates MOCs
  → canvas_create()     visual theme map in Obsidian
```

The vault maps itself.

---

## All Tools

### Notes (6)
| Tool | What it does |
|------|-------------|
| `read_note` | Read content + metadata. Fuzzy path resolution. |
| `write_note` | Create or overwrite. |
| `edit_note` | In-place find and replace. Exact match, must be unique. |
| `edit_regex` | Regex find-and-replace. Single file or grep-sub across vault. Capture groups, dry run. |
| `append_note` | Append to existing, or create if missing. |
| `delete_note` | Move to `.trash` (safe) or permanent. Optional `cleanup_empty_parents` removes empty parent dirs. |

### Search & Discovery (8)
| Tool | What it does |
|------|-------------|
| `smart_search` | **BM25-ranked.** Typo tolerance, field boosting, snippets. |
| `search_reindex` | Force re-index after bulk operations. |
| `search_vault` | Fast filename/path search from in-memory index. |
| `search_content` | Full-text grep. For exact/literal matches. |
| `list_dir` | Directory listing with created/modified timestamps. Sort by name, date, or size. |
| `recent_notes` | Recently modified files. Instant from index. |
| `daily_note` | Today's daily note (or any date). |
| `vault_status` | File counts, types, index health. |

### Files (3)
| Tool | What it does |
|------|-------------|
| `batch_rename` | Rename/move files. Explicit pairs or regex patterns. Auto-updates wikilinks. Dry run default. |
| `delete_folder` | Delete empty or non-empty directories. Moves to `.trash` by default. Safety guards for `.obsidian`, `.git`, `.trash`. |
| `prune_empty_dirs` | Find and remove all empty directories. Dry run default. Bottom-up pruning handles cascading empty dirs. |

### Links (2)
| Tool | What it does |
|------|-------------|
| `update_links` | Update all wikilinks across vault after moving/renaming a file. Dry run default. |
| `backlinks` | Find all files that link to a given file. Line numbers, context, embed detection. |

### Metadata (1)
| Tool | What it does |
|------|-------------|
| `frontmatter` | Read/write/merge YAML frontmatter as structured data. No string parsing needed. |

### Canvas (4)
| Tool | What it does |
|------|-------------|
| `canvas_create` | Semantic graph → auto-laid-out `.canvas` via dagre. |
| `canvas_read` | Canvas → semantic graph (labels + connections, not coordinates). |
| `canvas_patch` | Add/remove/update with relative positioning + fuzzy matching. |
| `canvas_relayout` | Re-layout existing canvas. Preview before committing. |

### Intelligence (2)
| Tool | What it does |
|------|-------------|
| `vault_themes` | TF-IDF theme extraction + clustering. Vault atlas with cross-folder warnings. |
| `vault_suggest` | Reorganization engine: consolidate, create MOCs, archive stale, triage orphans. |

### Batch (1)
| Tool | What it does |
|------|-------------|
| `batch` | Execute multiple operations — read, write, edit, regex, rename, frontmatter, delete. Delete ops support `cleanup_empty_parents`. |

---

## Install

### Prerequisites

- A folder with Markdown files (Obsidian vault or any structure)
- One of: [Claude Desktop](https://claude.ai/download), [Claude Code](https://docs.anthropic.com/en/docs/claude-code), [VS Code](https://code.visualstudio.com/), [Cursor](https://cursor.com/), [Windsurf](https://windsurf.com/), or any MCP-compatible client
- [Node.js](https://nodejs.org/) v22+ (not required for `.mcpb` one-click install)

**Obsidian app is not required.** VaultForge operates directly on the filesystem. If Obsidian is open, it picks up changes in real time.

### Claude Desktop (one-click)

**Windows** — [⬇ Download vaultforge.mcpb](https://github.com/blacksmithers/vaultforge/releases/latest/download/vaultforge.mcpb) — open the file, enter your vault path, done.

**macOS:**
```bash
curl -fsSL https://github.com/blacksmithers/vaultforge/releases/latest/download/vaultforge.mcpb -o /tmp/vaultforge.mcpb && open /tmp/vaultforge.mcpb
```

**Linux:**
```bash
curl -fsSL https://github.com/blacksmithers/vaultforge/releases/latest/download/vaultforge.mcpb -o /tmp/vaultforge.mcpb && xdg-open /tmp/vaultforge.mcpb
```

### Claude Code

```bash
claude mcp add vaultforge -- npx -y @blacksmithers/vaultforge /path/to/your/vault
```

### VS Code / Cursor / Windsurf

Add to your MCP settings JSON (`.vscode/mcp.json`, `.cursor/mcp.json`, or equivalent):

```json
{
  "servers": {
    "vaultforge": {
      "command": "npx",
      "args": ["-y", "@blacksmithers/vaultforge", "/path/to/your/vault"]
    }
  }
}
```

### Any MCP client

Use this universal pattern — any client that supports MCP stdio transport will work:

- **Command:** `npx`
- **Args:** `["-y", "@blacksmithers/vaultforge", "/path/to/your/vault"]`

Global install + manual Claude Desktop config

```bash
npm install -g @blacksmithers/vaultforge
```

Edit `claude_desktop_config.json`:

| OS | Config file location |
|----|---------------------|
| macOS | `~/Library/Application Support/Claude/claude_desktop_config.json` |
| Windows | `%APPDATA%\Claude\claude_desktop_config.json` |
| Linux | `~/.config/Claude/claude_desktop_config.json` |

```json
{
  "mcpServers": {
    "vaultforge": {
      "command": "vaultforge",
      "args": ["/path/to/your/vault"]
    }
  }
}
```

### Verify

Ask your AI assistant: *"List the files in my vault"* — if it responds with your vault contents, you're connected.

---

## Under the Hood

### Three Engines, One Index

```
@orama/orama (BM25 index — single source of truth)
  ├── smart_search      query-driven    "find files about X"
  ├── vault_themes      corpus-driven   "what themes exist?"
  └── vault_suggest     action-driven   "how should I reorganize?"

@dagrejs/dagre (Sugiyama graph layout)
  ├── canvas_create     semantic graph → positioned canvas
  ├── canvas_patch      relative edits → absolute coordinates
  └── canvas_relayout   messy canvas → optimized layout

Wikilink engine (zero dependencies)
  ├── update_links      safe moves with automatic link repair
  ├── backlinks         impact analysis before moves/deletes
  └── batch_rename      rename + link update in one operation
```

### Dependencies

Two packages. Both MIT, TypeScript-native, zero sub-dependencies:

| Package | Purpose | Size |
|---------|---------|------|
| [`@dagrejs/dagre`](https://github.com/dagrejs/dagre) | Sugiyama graph layout | ~15KB |
| [`@orama/orama`](https://github.com/oramasearch/orama) | BM25 search engine | ~2KB core |

### Architecture

```
src/
├── tools/
│   ├── notes/                  read, write, edit, edit_regex, append, delete
│   │   └── edit-regex.ts             regex find-and-replace
│   ├── files/                  rename, move, directory management
│   │   ├── batch-rename.ts           rename/move with link updates
│   │   ├── delete-folder.ts          delete directories with safety guards
│   │   └── prune-empty-dirs.ts       find and remove empty directories
│   ├── links/                  wikilink management
│   │   ├── link-utils.ts             shared wikilink regex engine
│   │   ├── update-links.ts           fix links after moves
│   │   └── backlinks.ts              impact analysis
│   ├── metadata/               frontmatter operations
│   │   └── frontmatter.ts            read/write/merge YAML frontmatter
│   ├── search/                 search_vault, search_content, list_dir, recent, daily, status
│   │   ├── smart-search.ts           BM25 search via Orama
│   │   ├── search-reindex.ts         full/incremental re-index
│   │   ├── orama-engine.ts           Orama wrapper + persistence
│   │   └── markdown-parser.ts        strip md, extract frontmatter/headings
│   ├── intelligence/           vault analysis + reorganization
│   │   ├── vault-themes.ts           TF-IDF extraction + clustering
│   │   └── vault-suggest.ts          suggestions + batch execution
│   ├── canvas/                 JSON Canvas (jsoncanvas.org spec v1.0)
│   │   ├── canvas-create.ts
│   │   ├── canvas-read.ts
│   │   ├── canvas-patch.ts
│   │   ├── canvas-relayout.ts
│   │   ├── layout-engine.ts          dagre wrapper + edge side calc
│   │   ├── canvas-utils.ts           ID gen, text height, fuzzy match
│   │   └── types.ts
│   └── batch/                  multi-operation execution
```

---

## Roadmap

What's coming next. Ordered by priority — community input shapes the sequence.

### v0.6.0 — Vault Graph & Tags
- **`vault_graph`** — Export the vault's link graph as a JSON adjacency list. Nodes = files, edges = wikilinks. Enables agents to reason about knowledge structure, find clusters, detect orphans, and identify bridge notes. Output compatible with D3, Cytoscape, or canvas_create for visual rendering.
- **`tag_search`** — Search by YAML frontmatter t

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [blacksmithers](https://github.com/blacksmithers)
- **Source:** [blacksmithers/vaultforge](https://github.com/blacksmithers/vaultforge)
- **License:** MIT

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** yes
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** no
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-blacksmithers-vaultforge
- Seller: https://agentstack.voostack.com/s/blacksmithers
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
