Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 

README.md

Local Quickstart

Run Vault Cortex on your machine against a local Obsidian vault. No cloud, no Obsidian Sync — just Docker and a folder of .md files.

Fastest path: npx vault-cortex@latest init does all of the below interactively — generates the token and config files, starts the server, and prints the connection details. The steps below are the manual equivalent.

Prerequisites

  • Docker (v20.10+)
  • An Obsidian vault (or any folder of Markdown files)

Setup

1. Get the files. Download this directory, or clone the repo and cd deploy/local.

2. Create your .env file:

cp .env.example .env

3. Fill in the two required values:

Variable Value
MCP_AUTH_TOKEN Generate with openssl rand -hex 32
VAULT_PATH Absolute path to your vault (e.g. /Users/you/Documents/MyVault)

On Windows? Set WINDOWS_MODE=true in your .env — then VAULT_PATH can point at a normal Windows path like C:\Users\you\MyVault. See Windows (Docker Desktop) below.

4. Start the server:

docker compose up

Add -d to run in the background. First start pulls the image (~150MB) and builds the search index — this takes a few seconds depending on vault size.

Connect your MCP client

The server listens at http://localhost:8000/mcp.

Claude Code:

  1. Run claude mcp add --scope user --transport http vault-cortex http://localhost:8000/mcp (--scope user registers it for every project; drop it to scope the server to the current directory only)
  2. Approve the consent page in your browser with your MCP_AUTH_TOKEN.
  3. Done. The client receives auto-refreshing access tokens, so the token itself never sits in client config.

Claude Desktop: the "Add custom connector" dialog only accepts https URLs, so a localhost server can't be added there. Register it in claude_desktop_config.json (Settings → Developer → Edit Config) 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>"
      ]
    }
  }
}

On Windows, spaces inside args can be mangled — move the header value into an env var instead: "--header", "Authorization:${AUTH_HEADER}" with "env": { "AUTH_HEADER": "Bearer <your MCP_AUTH_TOKEN>" }.

Other OAuth clients (Cursor and most MCP clients):

  1. Add http://localhost:8000/mcp as a remote MCP server, leaving OAuth Client ID and Secret empty.
  2. A consent page opens in your browser — approve with your MCP_AUTH_TOKEN.
  3. Done. The client receives auto-refreshing access tokens, so the token itself never sits in client config.
  • "Remote" refers to the connection type (HTTP, as opposed to a stdio process the client launches itself) — this server still runs entirely on your machine.
  • Claude Mobile and claude.ai web can't reach localhost — use the remote quickstart for access from other devices.

Bearer token (MCP Inspector, scripts, clients without OAuth): Enter http://localhost:8000/mcp as the server URL and your token as the Bearer token.

curl:

curl -H "Authorization: Bearer <your-token>" http://localhost:8000/mcp

Verify

# Health check (no auth required):
curl http://localhost:8000/healthz
# → {"ok":true}

# OAuth discovery (no auth required):
curl http://localhost:8000/.well-known/oauth-protected-resource

Stop

# Stop the server (search index is preserved in a Docker volume):
docker compose down

# Stop and delete all data (index rebuilds on next start):
docker compose down -v

Troubleshooting

invalid_client / "Invalid client_id" when connecting. Your MCP client cached an OAuth registration from a previous server at this address. Recreating the server (docker compose down -v, or scaffolding a fresh instance) resets oauth.db, so the cached client_id no longer exists and /authorize rejects it. Clear the client's stored authorization for this server and reconnect so it registers fresh:

  • Claude Code: claude mcp remove <name>, then claude mcp add --scope user --transport http <name> http://localhost:8000/mcp.
  • Claude Desktop / mcp-remote: delete ~/.mcp-auth and restart the client.
  • Other clients: remove and re-add the server.

"Invalid token" on the consent page even with the correct token. The consent form trims surrounding whitespace and line breaks from the token before checking it, so a value copied out of a terminal (where a long token can wrap across lines) still works. If you still see this error, double-check you copied the full MCP_AUTH_TOKEN from your .env — a missing or extra character is the usual cause.

Windows (Docker Desktop)

vault-cortex runs in a Linux container, so on Windows it reaches your vault through Docker Desktop's WSL2 bridge. Two things need a non-default code path across that bridge: live re-indexing (the file watcher's native filesystem events don't cross it) and vault_move_note (its atomic hard-link write isn't supported there). Setting WINDOWS_MODE=true handles both — the watcher switches to polling and moves use a rename-based write — so a vault on a C:\ drive works out of the box:

# in .env
VAULT_PATH=C:\Users\you\MyVault
WINDOWS_MODE=true

WINDOWS_MODE is safe to leave on for any Windows setup; reading, writing, and search work with or without it — it only changes how re-indexing and moves are done.

For best performance, keep the vault inside the WSL2 filesystem (ext4) instead — native filesystem events are lighter than polling, and you can leave WINDOWS_MODE off:

# inside WSL (e.g. Ubuntu) — vault lives on ext4
mkdir -p ~/vaults/MyVault
# then in .env:  VAULT_PATH=/home/you/vaults/MyVault

You can still open and edit a WSL-hosted vault in Obsidian on Windows — it shows up in File Explorer at \\wsl$\Ubuntu\home\you\vaults\MyVault.

Memory

On first startup, if your vault doesn't already have a memory folder (default: About Me/), the server creates one with template files (Me.md, Opinions.md, Principles.md). Agents can also create new memory files and sections on the fly via vault_update_memory — no manual setup needed.

Configuration

Only MCP_AUTH_TOKEN and VAULT_PATH are required. For optional settings (memory folder, protected paths, orphan exclusions, timezone), see the Configuration section in the main README.

Building from source

If you want to modify vault-cortex and build from source, clone the repo and use docker-compose.local.yml in the repo root instead. See CONTRIBUTING.md for the full development setup.