vault-cortex

MCP serverSearch

Standalone MCP server for Obsidian vaults — hybrid search, notes & files, memory, tasks, OAuth 2.1

Unavailable. This server has no hosted endpoint yet, so ahel can't serve it.

Connect ahel once, and every AI you use reads what you have installed.

From the project's README

As published by aliasunder/vault-cortex in README.md.

Vault Cortex is a standalone MCP server that gives any AI agent hybrid search, task management, structured memory, and read/write access to your Obsidian vault. No plugins, no running Obsidian, no separate bridge. One Docker container, your vault folder, a full tool suite + guided prompts. Run it on a remote server with Obsidian Sync, and the same vault is accessible from your phone, claude.ai, or any remote MCP client, secured with OAuth 2.1. Deploy it with one click or self-host it; either way, the vault is always yours.

ContentsWhat you get · Quick Start · How It Works · Hybrid Search · Memory · Tasks · Files · Tools · Prompts · Properties · Config · Daily Notes · Data Integrity · Auth · Deployment · One-click Deploy · Community Deployments

What you get

  • Remote access — works from your phone, a remote server, or any MCP client via OAuth 2.1. One click on Render or Railway gets you there with no server to manage; a VPS works too.
  • Plugin-free — Obsidian doesn't need to be running. The server works directly with .md files on disk. Headless sync keeps the vault current.
  • Hybrid search — FTS5 keyword matching + vector semantic similarity via RRF fusion, refined by cross-encoder reranking for intent-heavy queries. Keywords stay precise on exact terms and jargon; vectors find notes even when your words differ from the vault's.
  • Structured memory — dated, append-only entries accumulate into a personal knowledge layer, auto-initialized for AI personalization. Topic recall answers "what do I think about X?" with the current take and the dated history behind it — evolution included.
  • Tasks — Kanban-aware task queries and updates: triage by status, dates, or priority, then complete, reprioritize, or move tasks between lanes in one call. Parses both Tasks plugin emoji and Dataview inline-field formats.
  • Link graph — backlinks, outgoing links, and orphan detection across the vault
  • Files — read the vault's non-markdown files too: images arrive as actual images (shrunk to fit when needed), PDFs as structured text or rendered pages, canvases as readable outlines, data files as text
  • Obsidian-native — understands frontmatter, wikilinks, tags, headings, and daily notes
  • Guided workflows — built-in prompts for vault health, memory review, and daily reconciliation — assembled from live vault data each time

Tested across a 15-day trip through Europe. 30+ sessions from a phone, 216 tool calls, zero laptop access needed. Writes in one session were immediately available in the next, across cities and days.


Quick Start

Local (2 minutes — Docker + your vault folder)

Prerequisites: Docker (or a Docker-compatible runtime, e.g. OrbStack, Colima, Podman), Node.js >= 22.12 (only for the CLI — the server itself runs in Docker), and an Obsidian vault (or any folder of .md files).

npx vault-cortex@latest init

That's it — the CLI asks for your vault path, generates the auth token and config files, starts the server, and prints the connection details for your MCP client (CLI reference →).

Set up with the CLI? It manages the server from here on — configure, upgrade, start, restart, logs, down (CLI reference →).

Set up with Compose? Stick with Compose for updates too (docker compose pull && docker compose up -d) — the CLI and Compose manage the container independently.

# 1. Get the quickstart files
curl -O https://raw.githubusercontent.com/aliasunder/vault-cortex/main/deploy/local/docker-compose.yml
curl -O https://raw.githubusercontent.com/aliasunder/vault-cortex/main/deploy/local/.env.example

# 2. Configure
cp .env.example .env
# Edit .env — set MCP_AUTH_TOKEN (openssl rand -hex 32) and VAULT_PATH

# 3. Start
docker compose up

Full local guide → (includes Windows setup)

Remote (access from anywhere)

Your vault on a server, kept current by Obsidian Sync, reachable from your phone, claude.ai, or any MCP client. The one-click options ask for your vault name and timezone (plus the vault password if your vault is encrypted), then handle HTTPS, restarts, a generated MCP token, and persistent storage. Once deployed, a setup page walks you through signing in to Obsidian Sync in your browser. On your own server the CLI asks for the public URL and vault name, captures the Sync token for you, and generates the MCP token; HTTPS is yours to set up.

RailwayRenderSelf-hosted
CLI setup →
AccountRailway on the Hobby plan or higher — the 5 GB volume is includedRender with a card on fileA VPS with Docker
CostUsage-metered: typically $20–30 USD/mo for a personal vault — a little under Render for a quiet vault, a little over for a busy oneFlat: about $26 USD/mo for the Standard instance (2 GB) and 5 GB disk, billed by the secondWhatever your VPS costs
Pick it ifYou want the easier start — the template lands you in a configured projectA predictable bill matters more than setup polishYou already run a server or want full control
GuideRailway guide →Render guide →Remote guide →

All three need an Obsidian Sync subscription. Whichever you pick, the server is replaceable and your vault isn't — it stays in plain Markdown in Obsidian Sync and on your devices; the container only holds a copy.

The setup page. Deploy without an Obsidian Sync token and the server starts in setup mode: opening its URL in a browser lands on a sign-in page at /setup. Enter your Obsidian account credentials once (two-factor supported) — you sign in with Obsidian directly; the server keeps only the Sync token from that sign-in, restarts, and downloads your vault.

Self-hosted: your own VPS

The vault-cortex CLI sets up the same container on any Linux box you run — you manage the server, the image, and updates. You need Node.js >= 22.12 for the CLI itself; the server runs in Docker.

# On your VPS:
npx vault-cortex@latest init --mode remote

That's it — the CLI walks through the public URL, Obsidian Sync token (it can run get-sync-token for you), vault name, the vault password for an encrypted vault, and auth config, then starts the server (CLI reference →).

Set up with the CLI? It manages the server from here on — configure, upgrade, start, restart, logs, down (CLI reference →).

Set up with Compose? Stick with Compose for updates too (docker compose pull && docker compose up -d) — the CLI and Compose manage the container independently.

# On your VPS:
mkdir -p /opt/vault-cortex && cd /opt/vault-cortex
curl -O https://raw.githubusercontent.com/aliasunder/vault-cortex/main/deploy/remote/docker-compose.yml
curl -O https://raw.githubusercontent.com/aliasunder/vault-cortex/main/deploy/remote/.env.example
cp .env.example .env
# Edit .env — set MCP_AUTH_TOKEN, PUBLIC_URL, VAULT_NAME (OBSIDIAN_AUTH_TOKEN optional — /setup handles it)
docker compose up -d

Left OBSIDIAN_AUTH_TOKEN empty? Once the container is up, open <PUBLIC_URL>/setup in your browser and sign in — set up HTTPS first, since the page sends your Obsidian password to the server (full walkthrough →).

Connect your MCP client

SetupServer URL
Localhttp://localhost:8000/mcp
Remote (one-click)https://<host>/mcp<host> is the domain Render or Railway shows on the service page
Remote (self-hosted)<PUBLIC_URL>/mcp

Add the server URL in any MCP client — Claude Code, Claude Desktop, Cursor, OpenCode, or any other. OAuth clients open a consent page in your browser — approve with your token, and the client handles token renewal from then on. Clients without OAuth (MCP Inspector, scripts) send the token directly as an Authorization: Bearer header.

Claude Code:

claude mcp add --scope user --transport http vault-cortex http://localhost:8000/mcp   # local (or <PUBLIC_URL>/mcp)

--scope user registers the server for every project; omit it to scope it to the current directory only.

The "Add custom connector" dialog only accepts https URLs. With an https PUBLIC_URL, add it directly in the connector dialog; for a localhost server, register it in claude_desktop_config.json through the mcp-remote stdio bridge instead:

{
  "mcpServers": {
    "vault-cortex": {
      "command": "npx",
      "args": [
        "-y",
        "mcp-remote",
        "http://localhost:8000/mcp",
        "--header",
        "Authorization: Bearer <your MCP_AUTH_TOKEN>"
      ]
    }
  }
}

claude.ai (web and mobile) connects to the remote setup only — its connectors are fetched server-side and can never reach localhost.

"Remote MCP server" refers to the connection type (HTTP) — in the local setup the server still runs entirely on your machine.

See Authentication for both methods and token lifetimes.


How It Works

Everything runs in one Docker container, working directly with the .md files on disk:

  • Your vault stays the source of truth — the server reads and writes the same plain Markdown files your Obsidian apps do.
  • Search is derived data — a file watcher keeps the index (keywords + vectors) current as notes change, and it can be rebuilt from your notes at any time.
  • The remote image adds a sync loop — a bundled Obsidian Sync service keeps the container's vault current with every device: edit a note on your phone and it's searchable moments later; an agent writes a note and it shows up in Obsidian.
graph LR
    subgraph container ["One Docker container"]
        Sync["sync service<br/>(remote image)"]
        Vault[("/vault<br/>.md files — source of truth")]
        Index[("search index<br/>keywords + vectors")]
        Server["MCP server"]
        Sync <-->|read/write| Vault
        Vault -->|file watcher| Index
        Server <-->|read/write| Vault
        Server -->|query| Index
    end
    Obsidian["Your Obsidian apps<br/>(phone, laptop)"] <-->|Obsidian Sync| Sync
    Client["Any MCP client<br/>(Claude, Cursor, claude.ai)"] -->|OAuth 2.1 / Bearer| Server

See ARCHITECTURE.md for the full design, auth flow diagrams, and component breakdown.


Hybrid Search

Keyword search alone fails when your vocabulary doesn't match the vault's — "aspirations" won't find a note about "targets", "coworkers" won't surface your "references" file. In testing against a real vault, 30% of natural-language queries returned zero or tangential results with keywords alone. Hybrid search eliminated those misses — vectors bridge the vocabulary gap, and the reranker rescues intent-heavy queries where neither signal is strong on its own.

Hybrid search combines three ranking signals via Reciprocal Rank Fusion:

  • Keywords (FTS5) stay precise on exact terms, jargon, and property values
  • Vectors (sqlite-vec) bridge the vocabulary gap by matching on meaning
  • Reranker (cross-encoder) refines ordering by scoring each query-document pair jointly — rescues intent-heavy queries where keywords and vectors both miss

All models run locally (~45MB total, no external API). Set EMBEDDING_ENABLED=false for keyword-only search, or RERANK_MODE=none to skip reranking for lower latency.

See ARCHITECTURE.md → Hybrid Search for model details, blend weights, and the full pipeline breakdown.


Memory

A memory layer that only grows is only useful if agents can retrieve the right entries without dumping everything into context. Once you have hundreds of dated entries across multiple files — preferences, principles, communication style, ongoing commitments — reading whole files wastes context on irrelevant material and buries the signal. The memory system is designed for targeted retrieval: agents accumulate knowledge over time and recall exactly what's relevant to the task at hand.

The layer is a folder of plain Markdown files (default: About Me/) holding dated entries under topic headings — auto-created with starter templates on first run, grown by agents through vault_update_memory. Three properties make it work:

  • Append-only — entries are never overwritten; corrections arrive as new dated entries. The layer becomes a personal knowledge base that captures your current state and the evolution behind it
  • Topic recallvault_memory_recall retrieves every relevant entry across all memory files at once, keyword- and semantically-matched, oldest first. Ask "what do I think about X?" and get the current take plus the dated history of how it developed — no need to read entire files or guess which file holds what
  • Grows without degrading — capping results (limit) drops the least-relevant entries, never a slice of the timeline. A memory layer with 500 entries serves a targeted query as well as one with 50

Files that describe what's current rather than what has been true (routines, active commitments) can declare entry-policy: living in frontmatter — their expired entries are prunable rather than preserved, keeping the current-state picture accurate.

The whole layer is optional — set MEMORY_ENABLED=false to hide the memory tools and skip the folder auto-creation entirely.

See ARCHITECTURE.md → Memory for the recall pipeline, indexing model, auto-initialization, and opt-out behavior, and templates/memory for the file format, entry-policy convention, and starter templates.


Tasks

Task metadata lives in plain markdown — scattered across files, encoded in emoji signifiers or inline fields, organized under Kanban headings. An agent answering "what's overdue?" would need to parse every file and understand your chosen format; completing a task on a Kanban board means knowing the board's lane structure, the date syntax, and which heading is the done lane.

The task layer handles this so agents don't have to:

  • Find — filter by status, six date fields (due, scheduled, start, created, done, cancelled), priority, folder, or Kanban lane. Each result carries its note path, line number, and nearest heading when the task sits under one (the lane on a Kanban board) — no follow-up reads needed to locate a task
  • Create — add a correctly-formatted task in one call: description, priority, dates, block_id, and checklist sub-items, placed under a heading or nested under a parent task
  • Update — complete, reprioritize, edit the text, set or clear dates, add checklist items, and move tasks between headings in a single call. Marking a task done auto-detects the done lane and stamps the completion date; reversing it removes the date
  • Both formats — whichever format you use, Tasks plugin emoji signifiers or Dataview inline fields, the server reads both and writes in the format your Tasks plugin is configured for

See ARCHITECTURE.md → Tasks for the indexing model, date cascade sorting, and Kanban lane detection.


Files

Your notes embed screenshots, reference architecture diagrams, and link out to canvases and data files — but to an agent reading markdown, ![[diagram.png]] is just text. vault-cortex treats files as part of the vault rather than clutter around it — linked, sized, and readable, each in the form an agent can actually use:

  • Images — the image itself, not the filename. Screenshots and diagrams are downscaled and recompressed server-side when they exceed what MCP clients accept, so even a phone session can look at a 5MB architecture diagram
  • Canvases — a Canvas board arrives as a readable outline: its groups, each card's content in reading order, and the connections between them. Canvas content is full-text searchable, and file references on the board appear in the link graph — backlinks and outgoing links work just like note-to-note links. The exact JSON source is one flag away when full fidelity matters
  • PDFs — text is extracted with heading hierarchy, code blocks, and hyperlinks preserved; PDF content is full-text searchable alongside your notes. Set raw: true to render pages as images instead, showing layout, diagrams, and tables that text extraction can't preserve — scanned and image-only PDFs work in this mode
  • Text and data files — TXT, SVG, JSON, XML, CSV, YAML, logs, and Bases files return exactly as written; the first 100 KB of content is full-text searchable. Big data files and logs can be read a line range at a time, with each page reporting where you are and how much file remains
  • Browse — list any visible folder's files with per-extension counts and file sizes; files a note links to report their size in the link graph too

Set FILE_TOOLS_ENABLED=false to hide the file tools — useful when your remote vault syncs without attachments.

See ARCHITECTURE.md → Files for the image pipeline and dispatch model.


Tools

Shortened here. Read the whole README on GitHub.

Signals

GitHub stars
19
Forks
1
Last commit
Sep 2026
Advanced
Delivery
vault-cortex MCP server → your ahel gateway (mcp.ahel.ai) → every connected AI client.
Catalog kind
mcp-server
Gateway key
io-github-aliasunder-vault-cortex
Source
github.com/aliasunder/vault-cortex