mcp-markdown-vault
Provides Docker container deployment option with multi-arch support via GitHub Container Registry, enabling SSE transport mode for multi-client setups and containerized vault operations.
Enables MCP server capabilities for Logseq graphs, offering markdown file operations, semantic search, fragment retrieval, and surgical editing for Logseq's knowledge base structure.
Provides headless semantic MCP server functionality for Obsidian vaults, enabling direct read/write operations, surgical AST-based editing, semantic search, and workflow tracking without requiring the Obsidian app or plugins.
Supports optional integration with Ollama for higher-quality embeddings in semantic search functionality, using models like nomic-embed-text for improved vector search results.
π Markdown Vault MCP Server
Headless semantic MCP server for Obsidian, Logseq, Dendron, Foam, and any folder of markdown files.
npm install and point it at a folder. Hybrid search, AST editing, zero-config embeddings. No app, no plugins, no API keys.
π‘ Why this server?
TL;DR β One
npxcommand. No running app. No plugins. No vector DB. Semantic search works out of the box.
Differentiator | Details | |
π« | No app or plugins required | Most Obsidian MCP servers (mcp-obsidian, obsidian-mcp-server) need Obsidian running with the Local REST API plugin. This server reads and writes |
π§ | Built-in semantic search, zero setup | Hybrid search: cosine-similarity vectors + TF-IDF + word proximity. Local embeddings ( |
π¬ | Surgical AST-based editing |
|
π | Tool-agnostic | Obsidian vaults, Logseq graphs, Dendron workspaces, Foam, or any plain folder of |
π¦ | Single package, no infrastructure | Unlike Python alternatives that need ChromaDB or other vector stores, everything runs in one Node.js process. |
π Obsidian Β· π Logseq Β· π³ Dendron Β· π«§ Foam Β· π Any .md folder
β¨ Features
Feature | Description | |
ποΈ | Headless vault ops | Read, create, update, edit, delete |
π | Read by heading | Read a single section by heading title β returns only content under that heading (up to the next same-level heading), saving context window space |
π¦ | Bulk read | Read multiple files and/or heading-scoped sections in a single call β reduces MCP round-trips with per-item fault tolerance |
π¬ | Surgical editing | AST-based patching targets specific headings or block IDs β never overwrites the whole file |
π | Fragment retrieval | Heading-aware chunking + TF-IDF + proximity scoring returns only relevant sections |
π | Scoped search | Optional directory filter for |
π§ | Semantic search | Hybrid vector + lexical search with background auto-indexing |
β‘ | Zero-setup embeddings | Built-in local embeddings via |
π | Workflow tracking | Petri net state machine with contextual LLM hints |
π | Dual transport | Stdio (single client) or SSE over HTTP (multi-client, Docker-friendly) |
βοΈ | Freeform editing | Line-range replacement and string find/replace as AST fallback |
π·οΈ | Frontmatter management | AST-based read and update of YAML frontmatter β safely manage tags, statuses, and metadata without corrupting file structure |
π | Dry-run / diff preview | Preview any edit operation as a unified diff without saving β set |
π | Templating / scaffolding | Create new notes from template files with |
πΊοΈ | Vault overview | Structural map of the vault β total file count, recursive folder tree with file counts and last modification dates per folder |
π¦ | Batch edit | Apply multiple edit operations in a single call β sequential execution, stops on first error, supports |
π | Backlinks index | Find all notes linking to a given path β supports wikilinks and markdown links with line numbers and context snippets |
π― | Typo resilience | Levenshtein-based fuzzy matching for edit operations |
π οΈ MCP Tools
Tool | Actions | Description |
π vault |
| Full CRUD for vault notes + template scaffolding |
βοΈ edit |
| AST-based patching + freeform fallback + frontmatter update + batch edit (supports |
ποΈ view |
| Fragment retrieval, cross-vault search, hybrid semantic search, read by heading, frontmatter read, bulk read, backlinks |
π workflow |
| Petri net state machine control |
βοΈ system |
| Server health, indexing info, vault structure overview |
All tool responses include contextual hints based on the current workflow state.
π Quick Start
Prerequisites
π¦ Install from NPM
npm install -g @wirux/mcp-markdown-vaultThen run directly:
VAULT_PATH=/path/to/your/vault markdown-vault-mcpπ MCP Client Configuration
Add to your MCP client config (e.g. Claude Desktop, Claude Code):
{
"mcpServers": {
"markdown-vault": {
"command": "npx",
"args": ["-y", "@wirux/mcp-markdown-vault"],
"env": {
"VAULT_PATH": "/path/to/your/vault"
}
}
}
}
npx -yauto-installs the package if not already present β no global install needed.
π³ Docker
Pull the pre-built multi-arch image from GitHub Container Registry:
docker pull ghcr.io/wirux/mcp-markdown-vault:latestOr use Docker Compose:
docker compose upEdit docker-compose.yml to point at your markdown vault directory. The default compose file uses SSE transport on port 3000.
π οΈ Development (from source)
git clone https://github.com/Wirux/mcp-obsidian.git
cd mcp-obsidian
npm install
npm run build
VAULT_PATH=/path/to/your/vault node dist/index.jsπ Transport Modes
Mode | Use case | How it works |
π‘ | Single-client desktop apps (Claude Desktop) | Reads/writes stdin/stdout; 1:1 connection |
π | Multi-client setups (Docker, Claude Code) | HTTP server with SSE streams; one connection per client |
SSE starts an HTTP server on PORT (default 3000):
GET /sseβ establishes an SSE stream (one per client)POST /messages?sessionId=...β receives JSON-RPC messages
MCP_TRANSPORT_TYPE=sse PORT=3000 VAULT_PATH=/path/to/vault npx @wirux/mcp-markdown-vaultEach SSE client gets its own workflow state. Shared resources (vault, vector index, embedder) are reused across all connections.
π§ Embedding Providers
The server selects an embedding provider automatically:
| Ollama reachable? | Provider used |
β No | β | π Local ( |
β Yes | β Yes | π¦ Ollama ( |
β Yes | β No | π Local (fallback with warning) |
No configuration needed for local embeddings β the model downloads on first use and is cached automatically.
βοΈ Configuration
Variable | Default | Description |
|
| Markdown vault directory |
|
|
|
|
| HTTP port (SSE mode only) |
| (unset) | Set to enable Ollama embeddings |
|
| Ollama embedding model name |
|
| Ollama embedding vector dimensions |
ποΈ Architecture
Clean Architecture with strict layer separation:
src/
βββ domain/ π· Errors, interfaces (ports), value objects
βββ use-cases/ πΆ Business logic (AST, chunking, search, workflow)
βββ infrastructure/ π’ Adapters (file system, Ollama, vector store)
βββ presentation/ π£ MCP tool bindings, transport layer (stdio/SSE)See CLAUDE.md for detailed architecture docs and CHANGELOG.md for implementation history.
π’ CI/CD & Release
Fully automated via GitHub Actions and Semantic Release:
Workflow | Trigger | What it does |
PR Check | Pull request to | Lint β Build β Test |
Release | Push to | Lint β Test β Semantic Release (NPM + GitHub Release) β Docker build & push to |
Versioning follows Conventional Commits β
feat:= minor,fix:= patch,feat!:/BREAKING CHANGE:= majorDocker images are built for
linux/amd64andlinux/arm64via QEMUNPM package published as
@wirux/mcp-markdown-vaultDocker image available at
ghcr.io/wirux/mcp-markdown-vault
π§ͺ Testing
318 tests across 31 files, written test-first (TDD).
npm test # Run all tests
npx vitest run src/use-cases/ast-patcher.test.ts # Single file
npm run test:watch # Watch mode
npm run test:coverage # Coverage reportTests use real temp directories for file system operations and in-memory MCP transport for integration tests. No external services required.
π Security
π‘οΈ All file paths validated through
SafePathvalue object before any I/Oπ« Blocks path traversal:
../, URL-encoded (%2e%2e), double-encoded (%252e), backslash, null bytesβοΈ Atomic file writes (temp file + rename) prevent partial writes
π€ Docker container runs as non-root user
π License
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/wirux/mcp-markdown-vault'
If you have feedback or need assistance with the MCP directory API, please join our Discord server