Skip to main content
Glama

✦ Grimoire

You already wrote it down. Your agent still can't see it.

Point it at the markdown vault you already have. Your agents read what you know, remember what they learn back into the same files, and act with credentials they can use but never see. One self-hosted Go binary, mounted over MCP.

CI license go benchmarks

Grimoire dark-mode editor

go install github.com/JeremiahM37/grimoire/go/cmd/grimoire@latest
go install github.com/JeremiahM37/grimoire/go/cmd/grimoire-mcp@latest

GRIMOIRE_VAULT=~/obsidian-vault grimoire serve &   # the folder you already have
claude mcp add grimoire -- grimoire-mcp            # your agent now has all of it

Or docker run -p 9111:9111 -v grimoire-vault:/vault ghcr.io/jeremiahm37/grimoire:latest. Releases ship static binaries for Linux, macOS and Windows on amd64/arm64.

To build the console from a source checkout, use Node 24 and the Go version in go/go.mod:

npm ci --prefix frontend
npm run build --prefix frontend
go -C go build -o grimoire ./cmd/grimoire
GRIMOIRE_VAULT=~/obsidian-vault ./go/grimoire

The console uses React and TypeScript. Its production assets are in frontend/dist; the server uses that directory when running from the checkout. Docker and release archives build and include those assets automatically, with no Node runtime required. Keep the generated worker and hashed assets together when deploying.

Point your agent at the notes you already have

The runbooks and decisions you have been writing for years already answer many of your agent's questions. Without a connection to those notes, you keep pasting the same context into new sessions. Grimoire makes that existing knowledge available alongside the facts your agents deliberately save.

Grimoire's substrate is a folder of markdown you already own — an Obsidian vault, a Logseq graph, a plain ~/notes. It needs no plugin and does not need Obsidian running, because it reads the files, not the app. Nothing is copied or converted; the watcher picks up edits you make in your own editor, and writes through Grimoire preserve foreign frontmatter byte-for-byte, so whatever notes app you use keeps working on the same files.

Everything else follows from that one decision.

Related MCP server: deeplore

The dark-mode workspace

Create notes in a dedicated panel, search titles and content, or explain the current note without changing it. The graph supports pan, zoom, search, and exploring a note’s connections on desktop and mobile. Both searches use arrow keys to choose a result, Enter to open it, and Escape to clear the query.

Rename, templates, canvas cards and other actions use in-app panels. Dialogs keep keyboard focus inside, return it on close, and fit above the mobile keyboard.

Notes and connections

Persistent project memory

Current searchable note graph

AgentDeck project facts stored as editable Markdown

These are real captures of the current React UI using a disposable sample vault, not personal notes. The project-memory image comes from a real AgentDeck → Grimoire provisioning and recall walkthrough, with no paid model calls.

Agent memory that lives in your own markdown

What an agent learns lands in those files too, as ordinary bullets with provenance. When it gets something wrong you fix the line — and the fix outranks a recognized conflicting agent write. Explicit correction targets avoid relying on fuzzy matching to identify the fact being corrected.

Persistent project memory in the current editor

Reconciliation compares authority before recency — human > agent > pulled — and a refused overwrite becomes a challenge you settle rather than a silent revert.

grimoire challenges                                    # what your agents dispute
grimoire challenges --note memory/ops.md --uphold ID   # your fact stands
grimoire challenges --note memory/ops.md --concede ID  # the agent was right

Hand edits need no marker: an entry's id is a hash of its own content, so text that changed after the id was minted is text another hand changed.

Automatic memory, on your terms

Grimoire is both document retrieval and persistent agent memory, not just a chat box over a folder. Search/RAG finds evidence in your notes and imported documents. remember writes durable, attributed facts; recall reads accepted current knowledge; correction history and challenges preserve disagreements. The files survive process restarts and remain readable outside Grimoire.

Automatic context is a separate, configurable read path:

Mode

What gets consulted

Manual/off

Nothing automatically; agents use explicit MCP tools when asked.

Scoped

Only the configured files or directories, within existing permissions.

All

The readable corpus, still excluding private/untrusted content from automatic context.

Optional native Claude Code/Codex hooks default to manual. When enabled, they select relevant excerpts without generation or embedding calls, skip obvious acknowledgements, deduplicate recent context, and impose a 2,400-byte default retrieval budget. No match means no injected excerpts. Explicit search_notes, recall, and ask_notes remain available for deeper lookup.

Correction APIs accept target_id, target_path, and expected_text together. Stale targets are rejected; lower-authority writes challenge human/immutable facts instead of replacing them. Unresolved challenges are omitted from default fact recall, but remain inspectable. This does not solve every paraphrased contradiction or guarantee that an agent follows the supplied context.

With AgentDeck

AgentDeck manages agents, tasks, worktrees, approvals, and terminals. Grimoire supplies their durable knowledge. Set AGENTDECK_GRIMOIRE_URL and choose AGENTDECK_GRIMOIRE_CONTEXT_MODE=project to connect them:

  • Creating, importing, or promoting a project provisions a unique memory note. The association survives renaming; setup failures are visible and retryable.

  • Launches, task dispatch, and messages sent through Deck retrieve only the assigned project's context by default. Additional reference paths are explicit.

  • Agents receive the memory destination; requested handoffs save to the same topic. Conversation transcripts are not automatically turned into facts.

  • Unassigned sessions get no automatic project memory. Manual/off and all-corpus modes remain available, and Grimoire works independently of AgentDeck.

Direct terminal typing requires the optional native hook for per-prompt lookup. See configuration, API, cost controls, and limitations.

Credentials it can use but never read

An encrypted vault (Argon2id + Fernet). You mint a scoped, time-boxed grant; the server injects the secret into the outbound call and returns the response. The key never enters the agent's context, so it cannot be logged, memorised or extracted by prompt injection — and revoking is one row, not a key rotation. Agents without a grant can ask; asking grants nothing.

MCP tools: what Claude gets in one mount

tools

Credentials — use, never read

use_credential · list_grants · request_credential · check_credential_request

Agent memory

remember · recall · forget · memory_changes · memory_graph · memory_feedback · memory_scopes · consolidate_memory

Knowledge

search_notes · ask_notes · read_note · list_notes · backlinks · list_tags · stale_notes

Knowledge expansion

query_knowledge · knowledge_graph · read_source · extract_relationships · list_documents · refresh_document · import_document

The web

search_web · open_urls

Writing

create_note · update_note · append_daily

Exact values

get_fact · set_fact

Orientation

get_briefing · kb_info

Any MCP client works. grimoire agent-setup prints the config plus a CLAUDE.md/AGENTS.md snippet, since agents read context files more reliably than they browse tool lists.

{ "mcpServers": { "grimoire": {
    "command": "/path/to/grimoire-mcp",
    "env": { "GRIMOIRE_URL": "http://localhost:9111",
             "GRIMOIRE_AGENT_NAME": "my-agent" } } } }

Retrieval is inspectable — "what would the agent see for X?" returns the exact chunks. Untrusted content (connectors, web pages) carries an origin, is fenced before a reader sees it, and may not supersede something you wrote.

Documents and knowledge workflows

The browser workspace can upload and browse imported documents, ask questions, open cited sources, and explore the graph. The same operations are available without the browser:

grimoire document-import report.pdf --json
grimoire documents
grimoire documents refresh documents/report.md
grimoire documents watch ~/incoming
grimoire knowledge extract notes/plan.md notes/decision.md --json
grimoire query --watch ~/incoming --plain

Imports accept Markdown, plain text, PDF, and DOCX. PDF extraction requires pdftotext (on Debian, install poppler-utils); image-only or scanned PDFs are reported as unsupported rather than silently OCRed. DOCX text is read from the document XML. Imported notes retain source metadata. Refresh updates notes owned by the importer; a manual edit is preserved and reported, and deleting a source does not remove unrelated hand-authored notes. Direct edits to ordinary Markdown are picked up by the native vault watcher. Watch folders reconcile recursively on startup and then apply file updates and deletes. They do not watch files outside the selected folder, and a process must remain running for updates to continue.

Use document-import FILE --path EXISTING_NOTE or MCP import_document's optional path to replace an imported document explicitly. Use the generated note path returned by the first import; reusing a filename alone does not replace it.

The HTTP equivalents are POST /api/documents/import (multipart field file), GET /api/documents, POST /api/documents/refresh, POST /api/knowledge/query, GET /api/knowledge/source, and GET /api/knowledge/graph. Query supports depth, limit, after, before, and expand. Graph supports depth, limit, seed, relation, q, min_degree, drop_noisy, include_documents, and include_chunks. after and before filter note dates/source timestamps; they are corpus filters, not a claim about when an answer was generated.

Relationship extraction is an explicit model operation: POST /api/knowledge/extract accepts up to ten note paths and returns per-file indexed, cached, or error results. --force asks for a fresh extraction. It requires a configured LLM and writes cached semantic relationships. knowledge_graph remains model-free and works offline: it shows structural relationships plus any cached semantic relationships already available. No measured accuracy advantage over other systems is claimed here; compare systems only with a reproducible evaluation.

Imports are limited to 25 MiB, with at most 8 MiB of extracted text. Semantic indexing accepts at most 1 MiB per source, processes overlapping 8 KiB chunks, and reports an error rather than silently indexing a prefix if it exceeds 256 relationships. Source previews are capped at 1 MiB and marked when truncated. PDF OCR is not included. A folder watcher stops with an explicit source error on a failed import or a manual-edit conflict; correct it and restart the watcher.

MCP clients get the same parity through query_knowledge, knowledge_graph, read_source, list_documents, refresh_document, and import_document. extract_relationships is deliberately annotated as model-spending and cache-writing; it returns an MCP isError result for an unavailable model or per-file extraction failure. import_document takes {filename, content} where content is base64-encoded bytes, while refresh_document takes a document path.

Cloud agents too, not just local ones

A local agent launches grimoire-mcp over stdio. A hosted one — Claude.ai, ChatGPT, Codex, DeepSeek — cannot, so the same server speaks streamable HTTP:

GRIMOIRE_MCP_TRANSPORT=http \
GRIMOIRE_MCP_ADDR=0.0.0.0:9112 \
GRIMOIRE_MCP_TOKEN=$(openssl rand -hex 32) grimoire-mcp

One implementation, two doors — a test asserts the transports answer identically, so they cannot drift.

It refuses to bind anything but loopback without a token. That transport carries remember, create_note and the credential broker, so an unauthenticated public bind would publish the vault and the ability to spend its secrets. Put it behind your own TLS (a reverse proxy, tailscale serve, or a tunnel) and give the client the URL plus the token.

Know which agent is actually asking

Once agents run on more than one machine, the name on a memory stops being a detail. The authority lattice, the read-audit trail and the cost report are all keyed on who said something — and that name was a header the caller set about itself.

An overlay network already authenticated the caller before Grimoire saw the connection, so ask it:

GRIMOIRE_IDENTITY=tailscale grimoire      # or zerotier, mtls, proxy

GET /api/identity then reports the verified caller, what it claimed to be, and the name that will actually be recorded — the three things you need to tell a working configuration from one that silently never matches.

Off unless you set it, and it is deliberately two separate decisions. A verified identity always replaces the self-asserted name for attribution. It grants access only where you mapped it to an account:

grimoire user map tailscale jam@github jam

Identity never comes from a forwarded header, even behind a trusted proxy — a caller that could name its own address could claim any node on the overlay.

Run the credential vault, don't just fill it

The broker is the point: an agent gets a scoped, expiring grant and the server makes the call, so the value never reaches the agent. But a store you cannot operate is a store nobody rotates, and an unrotated credential is the one that leaks. So the operations are there too:

grimoire secret add stripe --expires 2026-11-30 --note "billing"
grimoire secret check          # non-zero if anything expired or is due
grimoire secret history stripe # what it used to be, and why it changed
grimoire secret restore stripe # put it back
grimoire secret scan           # credentials pasted into notes instead of stored

Every write keeps the value it replaced, so rotation is no longer a one-way door — paste the new key, find out the service was not ready, put the old one back. History is sealed with everything else and is never returned: you can see when and why a value changed, never what it was.

grimoire secret scan reads your notes, not the vault. A key pasted into a note while debugging is the likeliest way a credential escapes a system whose substrate is markdown you sync to your phone, and findings are masked — a report that quoted the key would copy the leak somewhere new.

Grants are bounded in count as well as time: max_uses: 1 for "post this one webhook" is a tighter thing to hand out than fifteen minutes in which an agent may make any number of calls. Names can carry a namespace (prod/stripe), and grimoire run --prefix prod -- cmd is the bounded form of --all — a build that needs the production keys has no business being handed the rest.

grimoire run NAME -- cmd puts a value in a child's environment. That hands over the value, which is exactly what the broker avoids, so it is for your own commands — agents get grants.

Pull in what you already wrote elsewhere

Ten connectors write into the vault as ordinary markdown with provenance in the frontmatter — not a parallel document store, so search, retrieval and the editor work on them for free and they survive Grimoire being uninstalled.

Chat

Slack · Discord

Docs

Notion · Confluence · Google Drive

Tickets

Linear · Jira · GitHub issues

Reading

Readwise · RSS/Atom

Pulled content carries trust: untrusted, is fenced before a reader sees it, and may not supersede something you wrote.

What the AI here has cost

grimoire doctor tells you the vault is healthy; AI usage (command palette, or GET /api/usage) tells you what it spent getting there — by provider, by model, by which part asked, and by which agent triggered it.

Read the scope before the number. This is not your total AI spend. Grimoire is mounted by agents and never sees the conversation an agent has with its own provider, so it cannot know what your coding agent costs. What it reports exactly is the calls it made: answering, reranking, classifying, on a key you configured. Anything else would be invented.

Seventeen providers are priced — OpenAI, Anthropic, Google, Groq, Together, Fireworks, DeepSeek, Mistral, Perplexity, xAI, Cerebras, DeepInfra, Azure, OpenRouter — plus Ollama, LM Studio and vLLM, which are free because they run on your hardware. The provider is identified from the API base URL, not the configured backend name, because pointing the OpenAI-compatible backend at Groq means Groq is billing you.

A model with no price on file reports unknown, never $0.00, and the total reads "at least" — a zero presented as a total makes an unmetered provider look free, which is the expensive direction to be wrong in.

Also a self-hosted notes app

Not wiring up agents yet? It is a full offline PWA in its own right — CodeMirror live preview, wiki-links, backlinks, graph, daily notes, transclusion, canvas, query blocks, templates. Mount an existing vault and daily-drive it; the agent substrate is there when you want it.

Measured

Pre-registered protocols, nulls and corrections published alongside — including one that cost a feature its default. Full methods and per-question data in benchmarks/.

result

LongMemEval — hybrid retrieval

77.5%, +8.5 over dense-only (p=0.0005) and over full-context at 15× fewer tokens

Correction durability

recency-only loses 20/20 hand corrections; authority lattice keeps 20/20

Update recognition

17/37 held-out knowledge updates, up from 14/37, at no cost in false supersessions

Prompt injection

0/40 injected instructions obeyed when fenced — but the pre-declared bar was not met; see the report

Config, security and docs

  • Config — every knob is an env var: docs/CONFIG.md. Nothing is required; an empty environment gives a working server.

  • Selective automatic memory — manual, scoped, or whole-vault lookup, bounded native hooks, and AgentDeck integration: docs/AUTOMATIC_MEMORY.md.

  • Security — threat model, what is and is not defended: SECURITY.md.

  • Architecturedocs/ARCHITECTURE.md · design decisionsDESIGN.md · pluginsdocs/PLUGINS.md

  • Diagnosinggrimoire doctor compares the vault, the index and what an agent can actually reach, and names the fix for whatever disagrees. Exits non-zero, so it works from a healthcheck too.

  • Testscd go && go test ./..., plus a verify suite that drives a real headless browser against a live server.

  • grimoire help lists the CLI. grimoire eval measures retrieval on your vault rather than on a public corpus.

MIT.

Related MCP Connectors

Related MCP Servers

  • F
    license
    Not graded
    quality
    D
    maintenance
    Self-hosted RAG-powered knowledge base that surfaces context from structured notes and transcripts, exposing each project as an MCP tool.
    -
  • A
    license
    Not graded
    quality
    C
    maintenance
    A private, self-hosted MCP server that wraps a retrieval pipeline over your own data, enabling trusted AI agents to access and manage your personal memory through standard MCP tools.
    Apache 2.0
  • A
    license
    Not graded
    quality
    B
    maintenance
    A self-hosted server providing shared memory, RAG document search, project maps, and role-based prompts for all AI agents via MCP and REST, enabling persistent context across devices and tools.
    2
    MIT