{"id":50016454,"url":"https://github.com/aliasunder/vault-cortex","last_synced_at":"2026-06-12T22:01:20.271Z","repository":{"id":358779799,"uuid":"1226067541","full_name":"aliasunder/vault-cortex","owner":"aliasunder","description":"MCP server for Obsidian vaults — plugin-free search, memory, and full vault access for any AI agent","archived":false,"fork":false,"pushed_at":"2026-06-06T20:03:44.000Z","size":929,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-06T21:20:15.103Z","etag":null,"topics":["ai-agent","ai-memory","ai-memory-system","better-sqlite3","docker","fts5-search","lightrag","lightsail","mcp","mcp-server","obsidian","obsidian-mcp","obsidian-mcp-server","obsidian-vault","rag","sst"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aliasunder.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-05-01T00:06:42.000Z","updated_at":"2026-06-06T20:03:47.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aliasunder/vault-cortex","commit_stats":null,"previous_names":["aliasunder/vault-cortex"],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/aliasunder/vault-cortex","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliasunder%2Fvault-cortex","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliasunder%2Fvault-cortex/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliasunder%2Fvault-cortex/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliasunder%2Fvault-cortex/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aliasunder","download_url":"https://codeload.github.com/aliasunder/vault-cortex/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aliasunder%2Fvault-cortex/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34263874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agent","ai-memory","ai-memory-system","better-sqlite3","docker","fts5-search","lightrag","lightsail","mcp","mcp-server","obsidian","obsidian-mcp","obsidian-mcp-server","obsidian-vault","rag","sst"],"created_at":"2026-05-20T04:01:00.420Z","updated_at":"2026-06-12T22:01:20.257Z","avatar_url":"https://github.com/aliasunder.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./assets/banner.svg\" width=\"720\" alt=\"Vault Cortex\"\u003e\n\u003c/p\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![CI](https://img.shields.io/github/actions/workflow/status/aliasunder/vault-cortex/ci.yml?branch=main\u0026logo=github\u0026label=CI\u0026cacheSeconds=43200)](https://github.com/aliasunder/vault-cortex/actions/workflows/ci.yml)\n[![Gitleaks](https://img.shields.io/github/actions/workflow/status/aliasunder/vault-cortex/gitleaks.yml?branch=main\u0026logo=github\u0026label=Gitleaks\u0026cacheSeconds=43200)](https://github.com/aliasunder/vault-cortex/actions/workflows/gitleaks.yml)\n[![Trivy](https://img.shields.io/github/actions/workflow/status/aliasunder/vault-cortex/trivy.yml?branch=main\u0026logo=github\u0026label=Trivy\u0026cacheSeconds=43200\u0026v=1)](https://github.com/aliasunder/vault-cortex/actions/workflows/trivy.yml)\n[![GitHub Release](https://img.shields.io/github/v/release/aliasunder/vault-cortex?cacheSeconds=43200)](https://github.com/aliasunder/vault-cortex/releases)\n[![License: MIT](https://img.shields.io/github/license/aliasunder/vault-cortex?v=1\u0026cacheSeconds=43200)](https://github.com/aliasunder/vault-cortex/blob/main/LICENSE)\n[![Node.js](https://img.shields.io/badge/Node.js-%3E%3D24-339933?logo=node.js\u0026logoColor=white)](https://nodejs.org/)\n[![TypeScript](https://img.shields.io/badge/TypeScript-6-3178C6?logo=typescript\u0026logoColor=white)](https://www.typescriptlang.org/)\n\n\u003c/div\u003e\n\n\u003cdiv align=\"center\"\u003e\n\n[![vault-cortex MCP server](https://glama.ai/mcp/servers/aliasunder/vault-cortex/badges/card.svg)](https://glama.ai/mcp/servers/aliasunder/vault-cortex)\n\n\u003c/div\u003e\n\n\u003c!-- TODO: Uncomment when demo GIF is recorded (see ^demo-gif task)\n\u003cp align=\"center\"\u003e\n  \u003cimg src=\"./assets/demo.gif\" width=\"600\" alt=\"Vault Cortex demo — vault_get_memory and vault_update_memory round-trip\"\u003e\n\u003c/p\u003e\n--\u003e\n\n## What is this?\n\n**Vault Cortex** gives any MCP client — Claude Desktop, Claude Code, Cursor, OpenCode — full access to your [Obsidian](https://obsidian.md) vault. Search notes, read and write content, query the link graph, manage structured memory, and resolve daily notes — all through 23 tools over a single Docker container.\n\nThe typical Obsidian + MCP setup requires three moving parts running simultaneously: Obsidian open → Local REST API plugin → a separate MCP server wrapping the REST API. **Vault Cortex** replaces all of that with Docker and your vault folder.\n\n- **Plugin-free** — Obsidian doesn't need to be running; headless sync keeps the vault current, and the server works directly with `.md` files on disk\n- **Remote access** — works from your phone, a remote server, or any MCP client via OAuth 2.1\n- **Ranked search** — SQLite FTS5 with BM25 scoring, stemming, phrase matching, and tag/property/folder filtering\n- **Structured memory** — dated entries, section targeting, auto-initialization for AI personalization\n- **Obsidian-native** — understands frontmatter, wikilinks, tags, headings, and daily notes\n\n### Roadmap\n\n| Phase | What                                                                                | Status   |\n| ----- | ----------------------------------------------------------------------------------- | -------- |\n| **1** | Vault CRUD, full-text search (FTS5), memory layer, OAuth 2.1                        | Complete |\n| **2** | Semantic search + knowledge graph via [LightRAG](https://github.com/HKUDS/LightRAG) | Planned  |\n\n## Quick Start\n\n### Local (2 minutes — Docker + your vault folder)\n\n**Prerequisites:** [Docker](https://docs.docker.com/get-docker/), Node.js \u003e= 20.12 (only for the CLI — the server itself runs in Docker), and an Obsidian vault (or any folder of `.md` files).\n\n```bash\nnpx vault-cortex@latest init\n```\n\nThat'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.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eManual setup\u003c/strong\u003e (no Node.js needed)\u003c/summary\u003e\n\n```bash\n# 1. Get the quickstart files\ncurl -O https://raw.githubusercontent.com/aliasunder/vault-cortex/main/deploy/local/docker-compose.yml\ncurl -O https://raw.githubusercontent.com/aliasunder/vault-cortex/main/deploy/local/.env.example\n\n# 2. Configure\ncp .env.example .env\n# Edit .env — set MCP_AUTH_TOKEN (openssl rand -hex 32) and VAULT_PATH\n\n# 3. Start\ndocker compose up\n```\n\n\u003c/details\u003e\n\n**[Full local guide →](./deploy/local/)**\n\n### Remote (access from anywhere — Docker + Obsidian Sync)\n\n**Prerequisites:** a VPS with [Docker](https://docs.docker.com/engine/install/), an [Obsidian Sync](https://obsidian.md/sync) subscription, and Node.js \u003e= 20.12 (only for the CLI — the server itself runs in Docker).\n\n```bash\n# On your VPS:\nnpx vault-cortex@latest init --mode remote\n```\n\nThat'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.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eManual setup\u003c/strong\u003e (no Node.js needed)\u003c/summary\u003e\n\n```bash\n# On your VPS:\nmkdir -p /opt/vault-cortex \u0026\u0026 cd /opt/vault-cortex\ncurl -O https://raw.githubusercontent.com/aliasunder/vault-cortex/main/deploy/remote/docker-compose.yml\ncurl -O https://raw.githubusercontent.com/aliasunder/vault-cortex/main/deploy/remote/.env.example\ncp .env.example .env\n# Edit .env — set MCP_AUTH_TOKEN, PUBLIC_URL, OBSIDIAN_AUTH_TOKEN, VAULT_NAME\ndocker compose up -d\n```\n\n\u003c/details\u003e\n\n**[Full remote guide →](./deploy/remote/)**\n\n### Connect your MCP client\n\nAdd the server URL as a remote/HTTP MCP server in any client — Claude Desktop, Claude Code, Cursor, OpenCode, or any other:\n\n| Setup      | Server URL                  |\n| ---------- | --------------------------- |\n| **Local**  | `http://localhost:8000/mcp` |\n| **Remote** | `\u003cPUBLIC_URL\u003e/mcp`          |\n\nOAuth 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.\n\n\u003e \"Remote MCP server\" refers to the connection type (HTTP) — in the local setup the server still runs entirely on your machine.\n\nSee [Authentication](#authentication) for both methods and token lifetimes.\n\n## Tools (23)\n\n| Category        | Tool                         | Description                                              |\n| --------------- | ---------------------------- | -------------------------------------------------------- |\n| **Vault CRUD**  | `vault_read_note`            | Read a note by path                                      |\n|                 | `vault_write_note`           | Create or overwrite a note with frontmatter              |\n|                 | `vault_patch_note`           | Heading-targeted edit (append, prepend, replace, insert) |\n|                 | `vault_replace_in_note`      | Find-and-replace text in a note                          |\n|                 | `vault_list_notes`           | List notes with optional glob/folder filter              |\n|                 | `vault_delete_note`          | Delete a note (protected paths enforced)                 |\n| **Search**      | `vault_search`               | Full-text search with tag/folder/property filters        |\n|                 | `vault_search_by_tag`        | Find notes by tag (exact or prefix match)                |\n|                 | `vault_search_by_folder`     | Browse notes in a folder with metadata                   |\n|                 | `vault_recent_notes`         | Recently modified or created notes                       |\n|                 | `vault_list_tags`            | All tags with usage counts                               |\n| **Memory**      | `vault_get_memory`           | Read structured memory (file, section, or all)           |\n|                 | `vault_update_memory`        | Append a dated entry to a memory section                 |\n|                 | `vault_delete_memory`        | Remove a specific memory entry by date                   |\n|                 | `vault_list_memory_files`    | Discover memory files and their sections                 |\n| **Properties**  | `vault_list_property_keys`   | All frontmatter keys with sample values                  |\n|                 | `vault_list_property_values` | Distinct values for a property key                       |\n|                 | `vault_search_by_property`   | Find notes by frontmatter key-value                      |\n|                 | `vault_update_properties`    | Add or update properties without touching the body       |\n| **Links**       | `vault_get_backlinks`        | Notes linking to a given path                            |\n|                 | `vault_get_outgoing_links`   | Links from a given note                                  |\n|                 | `vault_find_orphans`         | Notes with no incoming links                             |\n| **Daily Notes** | `vault_get_daily_note`       | Today's (or any date's) daily note                       |\n\n## Configuration\n\nAll settings are environment variables with sensible defaults.\n\n| Variable                    | Required?   | Default                              | Description                                                             |\n| --------------------------- | ----------- | ------------------------------------ | ----------------------------------------------------------------------- |\n| `MCP_AUTH_TOKEN`            | Yes         | —                                    | Bearer token for authentication (also the JWT signing key)              |\n| `VAULT_PATH`                | Local only  | —                                    | Host path to your vault (bind mount source; remote uses a named volume) |\n| `PUBLIC_URL`                | Remote only | —                                    | Public URL for OAuth discovery metadata                                 |\n| `MEMORY_DIR`                | —           | `About Me`                           | Vault folder for structured memory files                                |\n| `PROTECTED_PATHS`           | —           | `MEMORY_DIR, Daily Notes`            | Folders that `vault_delete_note` refuses to touch                       |\n| `ORPHAN_EXCLUDE_FOLDERS`    | —           | `Daily Notes, Templates, MEMORY_DIR` | Folders excluded from orphan detection                                  |\n| `TZ`                        | —           | `UTC`                                | IANA timezone for timestamps and daily note resolution                  |\n| `SERVICE_DOCUMENTATION_URL` | —           | GitHub repo URL                      | URL returned in OAuth discovery metadata                                |\n| `LOG_LEVEL`                 | —           | `info`                               | Logging verbosity: `debug`, `info`, `warn`, `error`                     |\n| `LOG_DIR`                   | —           | `/data/logs` (Docker)                | Directory for persistent log files. Logs survive container restarts.    |\n| `LOG_RETENTION_DAYS`        | —           | `30`                                 | Days to keep log files before automatic cleanup on startup              |\n\n**Smart defaults:** Setting `MEMORY_DIR` automatically updates the defaults for `PROTECTED_PATHS` and `ORPHAN_EXCLUDE_FOLDERS`. You only set those explicitly for a fully custom list.\n\nSee [`templates/memory/`](./templates/memory/) for memory file examples and the dated-entry design philosophy.\n\n## Authentication\n\nTwo methods, both validated at two layers (Lambda authorizer + Express middleware):\n\n| Method            | Used by                                                  | Token format         |\n| ----------------- | -------------------------------------------------------- | -------------------- |\n| **OAuth 2.1**     | Claude Desktop, Claude Code, claude.ai, any OAuth client | JWT (HS256, 24h)     |\n| **Static bearer** | Claude Code, MCP Inspector, curl                         | Raw `MCP_AUTH_TOKEN` |\n\nOAuth 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).\n\nSee [ARCHITECTURE.md → Auth](./ARCHITECTURE.md#auth-oauth-21--defense-in-depth) for the full flow diagram.\n\n## How It Works\n\n```mermaid\ngraph LR\n    Client[\"MCP Client\"] --\u003e|OAuth 2.1 / Bearer| Server[\"vault-mcp\"]\n    Server --\u003e|read/write| Vault[(\"/vault\u003cbr/\u003e.md files\")]\n    Server --\u003e|query| SQLite[(\"SQLite FTS5\")]\n    Sync[\"obsidian-sync\"] \u003c--\u003e|Obsidian Sync| Vault\n```\n\nThe vault `.md` files are the source of truth. SQLite FTS5 is rebuildable derived state — the index is built on startup and kept current by a file watcher. `obsidian-sync` keeps the vault in sync with your Obsidian apps (remote deployments only).\n\nSee [ARCHITECTURE.md](./ARCHITECTURE.md) for the full design, auth flow diagrams, and Phase 1/2 boundaries.\n\n## Deployment Options\n\n| Path          | What                                               | Guide                                |\n| ------------- | -------------------------------------------------- | ------------------------------------ |\n| **Local**     | Docker on your machine, vault bind-mounted         | [`deploy/local/`](./deploy/local/)   |\n| **Remote**    | VPS + Obsidian Sync, access from anywhere          | [`deploy/remote/`](./deploy/remote/) |\n| **AWS (SST)** | Full IaC: Lightsail + API Gateway + Lambda + CI/CD | [`DEPLOY.md`](./DEPLOY.md)           |\n\n## Development\n\n```bash\n# Run locally with hot reload\nPUBLIC_URL=http://localhost:8000 MCP_AUTH_TOKEN=local-dev-token VAULT_PATH=~/Vault npm run dev:mcp\n\n# Tests\nnpm test\n\n# Full check suite\nnpm run prettier:check \u0026\u0026 npm run lint \u0026\u0026 npm test \u0026\u0026 npm run build\n```\n\n**MCP Inspector** — interactive browser UI for testing tools:\n\n```bash\n# Start server (terminal 1), then:\nnpx @modelcontextprotocol/inspector\n# Enter http://localhost:8000/mcp as URL, local-dev-token as Bearer token\n```\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for the full development setup.\n\n## Companion: obsidian-vault skill\n\nThe MCP server works on its own with any client. For agents that support [skills](https://github.com/vercel-labs/skills) (Claude Code, Cursor, Windsurf, Cline, and [70+ others](https://github.com/vercel-labs/skills#supported-agents)), the **obsidian-vault** skill adds deeper knowledge of Obsidian-flavored markdown — frontmatter conventions, callout syntax, and plugin-specific formats like Dataview, Tasks, and Kanban.\n\n```bash\nnpx skills add aliasunder/agent-skills --skill obsidian-vault\n```\n\n[Skill source →](https://github.com/aliasunder/agent-skills/tree/main/skills/obsidian-vault)\n\n## Acknowledgments\n\nVault Cortex's remote capability exists because of [@Belphemur](https://github.com/Belphemur)'s [obsidian-headless-sync-docker](https://github.com/Belphemur/obsidian-headless-sync-docker) — a [headless Obsidian Sync](https://obsidian.md/help/sync/headless) client that runs in Docker without a display server. It's the piece that makes \"access your vault from anywhere\" possible.\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, code conventions, and PR guidelines.\n\n## License\n\n[MIT](./LICENSE)\n\n## Security\n\nReport vulnerabilities privately — see [SECURITY.md](./SECURITY.md).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faliasunder%2Fvault-cortex","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faliasunder%2Fvault-cortex","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faliasunder%2Fvault-cortex/lists"}