Install
$ agentstack add mcp-aliasunder-vault-cortex ✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.
Security review
✓ PassedNo issues found. Passed automated security review. · v0.1.0 How review works →
- ✓ Prompt-injection patterns
- ✓ Secret / credential exfiltration
- ✓ Dangerous shell & filesystem operations
- ✓ Untrusted network calls
- ✓ Known-malicious package signatures
What it can access
- ● Network access Used
- ✓ Filesystem access No
- ✓ Shell / process execution No
- ● Environment & secrets Used
- ✓ Dynamic code execution No
From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.
Verified badge
Passed review? Show it. Paste this badge into your README, it links to the public security report.
Reliability & compatibility
Declared compatibility
Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.
We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.
How agent discovery & health will work →About
[](https://github.com/aliasunder/vault-cortex/actions/workflows/ci.yml) [](https://github.com/aliasunder/vault-cortex/actions/workflows/gitleaks.yml) [](https://github.com/aliasunder/vault-cortex/actions/workflows/trivy.yml) [](https://github.com/aliasunder/vault-cortex/releases) [](https://github.com/aliasunder/vault-cortex/blob/main/LICENSE) [](https://deepwiki.com/aliasunder/vault-cortex) [](https://glama.ai/mcp/servers/aliasunder/vault-cortex)
Vault Cortex is a standalone MCP server that gives any AI agent hybrid search, task queries, structured memory, and read/write access to your Obsidian vault. No plugins, no running Obsidian, no separate bridge. One Docker container, your vault folder, 26 tools + 3 guided prompts. Deploy on a VPS with Obsidian Sync and the same vault is accessible from your phone, claude.ai, or any remote MCP client, secured with OAuth 2.1.
Contents — [What you get](#what-you-get) · [Quick Start](#quick-start) · [How It Works](#how-it-works) · [Hybrid Search](#hybrid-search) · [Tools](#tools-26) · [Prompts](#prompts-3) · [Config](#configuration) · [Auth](#authentication) · [Deployment](#deployment-options)
What you get
Search the vault Reason over notes Write back to Obsidian
All three demos run on Claude mobile. The vault is on a remote server, not the phone.
- [Remote access](#deployment-options) — works from your phone, a remote server, or any MCP client via OAuth 2.1. Deploy on a VPS with Obsidian Sync for access from anywhere.
- [Plugin-free](#how-it-works) — Obsidian doesn't need to be running. The server works directly with
.mdfiles on disk. Headless sync keeps the vault current. - [Hybrid search](#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](#tools-26) — dated entries, section targeting, auto-initialization for AI personalization
- [Task queries](#tools-26) — vault-wide task index parsing both Tasks-plugin emoji and Dataview inline-field formats. Filter by status, six date fields, priority, folder, or heading.
- [Link graph](#tools-26) — backlinks, outgoing links, and orphan detection across the vault
- [Obsidian-native](#properties) — understands frontmatter, wikilinks, tags, headings, and daily notes
- [Guided workflows](#prompts-3) — three 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, Node.js >= 20.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.
Manual setup (no Node.js needed)
# 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 →](./deploy/local/) (includes [Windows setup](./deploy/local/#windows-docker-desktop))
Remote (access from anywhere — Docker + Obsidian Sync)
Prerequisites: a VPS with Docker, an Obsidian Sync subscription, and Node.js >= 20.12 (only for the CLI — the server itself 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 the token generator for you), and auth config, then starts the server.
Manual setup (no Node.js needed)
# 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, OBSIDIAN_AUTH_TOKEN, VAULT_NAME
docker compose up -d
[Full remote guide →](./deploy/remote/)
Connect your MCP client
| Setup | Server URL | | ---------- | --------------------------- | | Local | http://localhost:8000/mcp | | Remote | /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 /mcp)
--scope user registers the server for every project; omit it to scope it to the current directory only.
Claude Desktop (localhost requires mcp-remote bridge)
The "Add custom connector" dialog only accepts https URLs. With an https PUBLICURL, 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 "
]
}
}
}
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](#authentication) for both methods and token lifetimes.
How It Works
graph LR
Client["MCP Client"] -->|OAuth 2.1 / Bearer| Server["vault-mcp"]
Server -->|read/write| Vault[("/vault.md files")]
Server -->|FTS5 + vector| SQLite[("SQLite\nFTS5 + sqlite-vec")]
Sync["obsidian-sync"] |Obsidian Sync| Vault
The search index is rebuildable derived state — FTS5 keyword tables rebuild on startup, vector embeddings persist across restarts with content-hash gating (only changed notes re-embed). A file watcher keeps both current, and queries fuse both signals via Reciprocal Rank Fusion. obsidian-sync keeps the vault in sync with your Obsidian apps (remote deployments only).
See [ARCHITECTURE.md](./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](./ARCHITECTURE.md#hybrid-search-r8):
- 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](./ARCHITECTURE.md#hybrid-search-r8) for model details, blend weights, and the full pipeline breakdown.
Tools (26)
| Category | Tool | Description | | --------------- | ---------------------------- | ---------------------------------------------------------- | | Vault CRUD | vault_read_note | Read a note — full body, properties, outline, or a section | | | vault_write_note | Create or overwrite a note with properties | | | vault_patch_note | Heading-targeted edit (append, prepend, replace, insert) | | | vault_replace_in_note | Find-and-replace text in a note | | | vault_delete_span | Delete a block of lines by short anchors, no full re-quote | | | vault_list_notes | List notes with optional glob/folder filter | | | vault_delete_note | Delete a note (protected paths enforced) | | | vault_move_note | Move or rename a note, rewriting links across the vault | | Search | vault_search | Hybrid search with tag/folder/property filters | | | vault_search_by_tag | Find notes by tag (exact or prefix match) | | | vault_search_by_folder | Browse notes in a folder with metadata | | | vault_recent_notes | Recently modified or created notes | | | vault_list_tags | All tags with usage counts | | | vault_list_tasks | Vault-wide task triage — status, date, priority filters | | Memory | vault_get_memory | Read structured memory (file, section, or all) | | | vault_update_memory | Append a dated entry to a memory section | | | vault_delete_memory | Remove a specific memory entry by date | | | vault_list_memory_files | Discover memory files and their sections | | Properties | vault_list_property_keys | All property keys with sample values | | | vault_list_property_values | Distinct values for a property key | | | vault_search_by_property | Find notes by property key-value | | | vault_update_properties | Add or update properties without touching the body | | Links | vault_get_backlinks | Notes linking to a given path | | | vault_get_outgoing_links | Links from a given note | | | vault_find_orphans | Notes with no incoming links | | Daily Notes | vault_get_daily_note | Today's (or any date's) daily note |
Prompts (3)
Tools are model-driven — the assistant calls them. Prompts are workflows you trigger. Each one queries the search index, link graph, and memory layer at invocation time, then assembles the results with guided instructions — so the session starts grounded in your vault's actual state, not assumptions.
| Prompt | Arguments | What it does | | ------------------- | --------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | vault-orientation | — | Surveys vault stats, folder distribution, property adoption rates (flags low adoption), orphans, broken link count, tags, recent notes, and the memory layer — with contextual tool suggestions | | memory-review | file?, max_chars? | Structural overview (scope callouts, section entry counts) + dated content as a timeline. Guided reflection: evolution narrative, scope-fit, backfill gaps, and coverage analysis. Hidden when MEMORY_ENABLED=false. | | daily-review | date?, max_chars? | Reconciles a day — daily note, vault-wide task status (due/overdue, scheduled), modified notes, outgoing links (broken-link detection), and backlinks — surfaces what happened, what's open, and what needs follow-up |
Prompts adapt to your configuration (MEMORY_DIR, daily-notes settings) and work for any vault out of the box. Pass max_chars to cap embedded content if your client has payload limits.
> Client support: Prompts work in Claude Desktop (Chat and Cowork — via the + menu under your connector), Claude Code (slash commands), and OpenCode. Support in other clients (Cursor, Windsurf) varies — see the MCP clients matrix for the latest.
Properties
Vault Cortex indexes every property in your notes, but five get promoted treatment — dedicated columns for fast filtering, and top-level fields in every search and discovery result:
| Property | What you can do | | --------- | ------------------------------------------------------------------------------------------------------------ | | title | Display name in search results; falls back to the filename when missing | | tags | Search and filter by tag, including parent-child hierarchies (project matches project/vault-cortex) | | type | Filter by note type — meeting, person, session-log, or any value your vault uses | | created | Sort by creation date and see when each note was created alongside every search result | | related | Filter for notes that cross-reference a specific link — surfaces connections invisible without a graph query |
All other properties are still fully queryable — use vault_search with filters.properties for combined text + metadata queries, or vault_search_by_property for metadata-only lookups. vault_list_property_keys and vault_list_property_values discover what properties exist across your vault.
These are conventions, not requirements — Vault Cortex works with any property schema. Promoted properties just give you richer filtering and cleaner results out of the box.
Leading callouts get the same treatment. When a note's first body content is an Obsidian callout (> [!type]) — either right after frontmatter or right after the title heading — it's indexed and surfaced alongside every search and discovery result. This makes notes self-describing: an agent scanning results can see what each note is for_ before deciding which to read. The memory tem
…
Source & license
This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.
- Author: aliasunder
- Source: aliasunder/vault-cortex
- License: MIT
- Homepage: https://www.npmjs.com/package/vault-cortex
Install and usage instructions live in the source repository linked above.
Reviews
No reviews yet, be the first.
Write a review
Versions
- v0.1.0 Imported from the upstream source.