Labsco
aliasunder logo

Vault Cortex

β˜… 5

from aliasunder

MCP server for Obsidian vaults β€” search, memory, link graph, 23 tools, OAuth-protected.

πŸ”₯πŸ”₯πŸ”₯πŸ”₯βœ“ VerifiedPaid serviceAdvanced setup

Vault Cortex is a standalone MCP server that gives any AI agent hybrid search, structured memory, and read/write access to your Obsidian vault. No plugins, no running Obsidian, no separate bridge. One Docker container, your vault folder, 25 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 Β· Quick Start Β· How It Works Β· Hybrid Search Β· Tools Β· Prompts Β· Config Β· Auth Β· Deployment

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 ** β€” 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 ** β€” 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 entries, section targeting, auto-initialization for AI personalization

  • ** Link graph ** β€” backlinks, outgoing links, and orphan detection across the vault

  • ** Obsidian-native ** β€” understands frontmatter, wikilinks, tags, headings, and daily notes

  • ** Guided workflows ** β€” 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, 70+ tool calls, zero laptop access needed. Writes in one session were immediately available in the next, across cities and days.

How It Works

Copy & paste β€” that's it
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 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.

Tools (25)

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 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? Reviews a day's daily note with outgoing links (broken-link detection), backlinks, and date-specific activity β€” guides reconciliation, link following, and pattern recognition

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 templates use > [!info] Scope of this file callouts for this, and any note in your vault can use the same pattern.

Authentication

For a server with read/write access to personal notes, authentication is not optional. Vault Cortex implements the full OAuth 2.1 specification, including PKCE and refresh-token rotation. The AWS (SST) deployment adds defense-in-depth: requests are validated at two independent layers (API Gateway Lambda authorizer + Express middleware). Per BlueRock's 2026 MCP security analysis, only 8.5% of MCP servers implement OAuth; 41% have no authentication at all.

Two methods:

Method Used by Token format OAuth 2.1 Claude Desktop, Claude Code, claude.ai, any OAuth client JWT (HS256, 24h) Static bearer Claude Code, MCP Inspector, curl Raw MCP_AUTH_TOKEN

OAuth uses dynamic client registration β€” no Client ID/Secret needed. A consent page opens in your browser; enter your MCP_AUTH_TOKEN to approve. Refresh tokens have a 60-day sliding expiry (daily users never re-authenticate).

See ARCHITECTURE.md β†’ Auth for the full flow diagram.

Development

Copy & paste β€” that's it
# Run locally with hot reload
PUBLIC_URL=http://localhost:8000 MCP_AUTH_TOKEN=local-dev-token VAULT_PATH=~/Vault npm run dev:mcp

# Tests
npm test

# Full check suite
npm run prettier:check && npm run lint && npm test && npm run build

MCP Inspector β€” interactive browser UI for testing tools:

Copy & paste β€” that's it
# Start server (terminal 1), then:
npx @modelcontextprotocol/inspector
# Enter http://localhost:8000/mcp as URL, local-dev-token as Bearer token

See CONTRIBUTING.md for the full development setup.

Companion: obsidian-vault skill

The MCP server works on its own with any client. For agents that support skills (Claude Code, Cursor, Windsurf, Cline, and 70+ others), the obsidian-vault skill adds deeper knowledge of Obsidian-flavored markdown β€” frontmatter conventions, callout syntax, and plugin-specific formats like Dataview, Tasks, and Kanban.

Copy & paste β€” that's it
npx skills add aliasunder/agent-skills --skill obsidian-vault

Skill source β†’

Roadmap

Phase What Status 1 Vault CRUD, full-text search (FTS5), memory layer, OAuth 2.1 Complete 2a Hybrid search β€” FTS5 + vector + RRF fusion, heading-aware chunking Complete 2b Reranker β€” cross-encoder reranking, position-aware score blending Complete 3 Graph memory β€” automated relationship extraction for relational queries that hand-maintained wikilinks miss Exploring

Acknowledgments

Vault Cortex's remote capability exists because of @Belphemur's obsidian-headless-sync-docker β€” a headless Obsidian Sync client that runs in Docker without a display server. It's the piece that makes "access your vault from anywhere" possible. The remote stack runs a small fork that adds a build-time config chown and --device-name on the initial Sync registration (upstream PR #8 remains open).

The hybrid search pipeline draws on patterns from @tobi's qmd β€” RRF fusion with rank bonuses, position-aware score blending for cross-encoder reranking, content-hash gating, and heading-aware chunking.

Contributing

See CONTRIBUTING.md for development setup, code conventions, and PR guidelines.

License

MIT

Security

Report vulnerabilities privately β€” see SECURITY.md.