grove
Health Gecti
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Community trust — 19 GitHub stars
Code Basarisiz
- process.env — Environment variable access in src/blame-warmup.ts
- exec() — Shell command execution in src/blame.ts
- process.env — Environment variable access in src/blame.ts
- exec() — Shell command execution in src/db.ts
- process.env — Environment variable access in src/db.ts
Permissions Gecti
- Permissions — No dangerous permissions requested
Bu listing icin henuz AI raporu yok.
Open-source MCP server over a git-backed Obsidian vault. Single-user, self-host. Six tools, hybrid search, provenance/blame, auto-link discovery.
Grove
Open-source MCP server that makes your Obsidian vault searchable and writable from any AI client.
Six tools, one git-backed vault, single-user. Claude, ChatGPT, Cursor, or any MCP-compatible client connects and gets structured access — search, read, write-back, graph diagnostics. Your vault stays yours: markdown files in a git repo, versioned forever.
┌─────────────────────────────────────────────────────────┐
│ MCP client (Claude / Cursor / …) │
└──────────────────────┬──────────────────────────────────┘
│ MCP — Streamable HTTP + Bearer
▼
┌─────────────────────────────────────────────────────────┐
│ grove-server │
│ 6 tools · write queue · provenance · discovery │
└──────────────────────┬──────────────────────────────────┘
│
┌──────────┼──────────┐
▼ ▼ ▼
Hybrid Vault Discovery
Search (git) worker
BM25+Vec (extract → link)
About this repo. Grove was a hosted product 2026-04 → 2026-05. The repo
you're looking at is the open-source cathedral that came out of it: a
personal MCP layer over an Obsidian vault, single-user, self-host. The
multi-tenant SaaS layer, autonomous-agent layer, encryption, trails,
waitlist, and admin portal have all been stripped. SeeRETROSPECTIVE.md
for the full history.
The six tools
| Tool | What it does |
|---|---|
query |
Hybrid BM25 + vector + title search with RRF fusion. Returns ranked snippets with URLs. |
get |
Read a note by path or title. Surfaces per-segment provenance (durable vs perishable voice). |
multi_get |
Batch read via glob or comma-separated paths. |
write_note |
Create / update / soft-delete / hard-delete / move a note. Single op or batch (atomic optional). |
list_notes |
List notes matching a pattern. Optional alias resolution. |
vault_status |
Health, history, diagnostics, graph, lifecycle digest, discovery state, perf counters. |
Every write is a git commit. Every commit can carry provenance trailers that the read path surfaces via blame so future readers know what's the user's standing thinking vs an AI's moment-in-time synthesis.
Quick start
You need:
- Node ≥ 22
- A git-backed Obsidian-style markdown vault on disk
- A QMD index for the vault (Grove reads BM25 + vector hits from it)
- A Voyage AI API key for per-write embeddings (
voyage-4-large)
git clone https://github.com/jmilinovich/grove.git
cd grove
npm install
Set the env vars:
export GROVE_VAULT=/path/to/your/vault # absolute path to the git repo
export GROVE_API_KEY=$(openssl rand -hex 32) # your bearer token — keep secret
export VOYAGE_API_KEY=... # Voyage AI key for embeddings
Then start the server:
npx tsx src/server.ts
It listens on http://127.0.0.1:8420/mcp. Point any MCP client at that URL with Authorization: Bearer <GROVE_API_KEY>.
Local-only without a token
For purely local development you can disable auth:
GROVE_AUTH=none GROVE_VAULT=/path/to/vault npx tsx src/server.ts
Only do this when the listener is bound to localhost.
Discovery worker (optional)
The discovery worker runs in the background and auto-wikilinks new notes by extracting entities from each write. It's a separate process:
GROVE_VAULT=/path/to/vault \
ANTHROPIC_API_KEY=... \
npx tsx src/discovery-worker.ts
If you don't run it, writes still work — they just don't get auto-linked. The discovery queue + cache live in ~/.grove/state.db and will resume when the worker comes back.
Env reference
| Var | Required? | Default | Purpose |
|---|---|---|---|
GROVE_VAULT |
yes | $HOME/life |
Absolute path to the vault git repo |
GROVE_API_KEY |
yes (unless GROVE_AUTH=none) |
empty | Bearer token clients must send |
GROVE_AUTH |
no | bearer |
Set to none to disable auth (localhost only) |
GROVE_PORT |
no | 8420 |
HTTP listen port |
GROVE_STATE_DB |
no | ~/.grove/state.db |
SQLite state file (discovery queue, provenance, blame cache) |
GROVE_PUBLIC_BASE_URL |
no | grove://vault |
Prefix used when minting URLs returned by tool calls |
VOYAGE_API_KEY |
for embed-on-write | — | Voyage AI key |
ANTHROPIC_API_KEY |
for the discovery worker | — | Anthropic key for the extract→link engine |
GROVE_INTERNAL_TOKEN |
optional | — | Bearer for the /internal/post-sync-warmup cron hook |
What's in the box
src/
├── server.ts # MCP HTTP server, the 6 tools, bearer-auth gate
├── rest.ts # write / delete / move / batch handlers (git write-queue)
├── write-queue.ts # single-writer mutex per vault
├── hybrid-search.ts # BM25 + vector + RRF fusion over the QMD index
├── embed-single.ts # per-write embed → Voyage AI → QMD index
├── notes-validate.ts # frontmatter validation, hash, serialize/parse
├── provenance.ts # durable/perishable voice, commit trailers
├── blame.ts # per-segment authorship from git blame + trailers
├── discovery*.ts # extract → link engine (auto-wikilinking on write)
├── graph-health.ts # vault health metrics + flags
├── vault-graph.ts # wikilink graph + clusters
├── vault-stats.ts # cached stats for vault_status
├── vault-config.ts # detection + loading of the vault structure
└── db.ts # single SQLite state-db for discovery + provenance + blame
Code conventions
- TypeScript strict mode. No
anyexcept at untyped externals. - Raw
node:http. No Express / Fastify. - Node ≥ 22, ESM only, built-in
fetch+crypto. - Dependencies are intentionally minimal (
@modelcontextprotocol/sdk,better-sqlite3,zod,yaml). - The vault is sacred — Grove is plumbing. Never restructure or make policy decisions about vault content.
Architecture rules
- The vault is the source of truth. All other state (state.db, QMD index) is derived. If they diverge, the derived state is wrong — rebuild it.
- All writes are serialized via the write queue. No concurrent git operations.
- Every write creates a git commit with attribution.
- Search index updates synchronously on write so the agent's next call sees the change.
- Keep the tool count small. Six tools today. If you're adding a tenth, stop and reconsider.
License
MIT. See LICENSE.
Yorumlar (0)
Yorum birakmak icin giris yap.
Yorum birakSonuc bulunamadi