# Vault Cortex

> Standalone MCP server for Obsidian vaults — plugin-free search, memory, link graph, and full vault access for any AI agent. Local or fully remote: one Docker container, Streamable HTTP, OAuth 2.1.

- **Type:** MCP server
- **Install:** `agentstack add mcp-aliasunder-vault-cortex`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [aliasunder](https://agentstack.voostack.com/s/aliasunder)
- **Installs:** 0
- **Category:** [Databases](https://agentstack.voostack.com/c/databases)
- **Latest version:** 0.1.0
- **License:** MIT
- **Upstream author:** [aliasunder](https://github.com/aliasunder)
- **Source:** https://github.com/aliasunder/vault-cortex
- **Website:** https://www.npmjs.com/package/vault-cortex

## Install

```sh
agentstack add mcp-aliasunder-vault-cortex
```

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

## 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](https://obsidian.md) 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 `.md` files 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](https://publish.obsidian.md/tasks/) emoji and [Dataview](https://blacksmithgu.github.io/obsidian-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](https://docs.docker.com/get-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).

```bash
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)

```bash
# 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](https://docs.docker.com/engine/install/), an [Obsidian Sync](https://obsidian.md/sync) subscription, and Node.js >= 20.12 (only for the CLI — the server itself runs in Docker).

```bash
# 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)

```bash
# 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:**

```bash
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` PUBLIC_URL, add it directly in the connector dialog; for a localhost server, register it in `claude_desktop_config.json` through the [mcp-remote](https://github.com/geelen/mcp-remote) stdio bridge instead:

```json
{
  "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

```mermaid
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](https://modelcontextprotocol.io/clients) for the latest.

## Properties

Vault Cortex indexes every [property](https://help.obsidian.md/Editing+and+formatting/Properties) 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](https://help.obsidian.md/Editing+and+formatting/Callouts) (`> [!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](https://github.com/aliasunder)
- **Source:** [aliasunder/vault-cortex](https://github.com/aliasunder/vault-cortex)
- **License:** MIT
- **Homepage:** https://www.npmjs.com/package/vault-cortex

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:** yes
- **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-aliasunder-vault-cortex
- Seller: https://agentstack.voostack.com/s/aliasunder
- 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%.
