
GrayMatter
io.github.angelnicolasc由 GitHub 帳號 angelnicolasc 發布v0.16.4更新於 Oct 26, 2026
Persistent agent memory as a single Go binary: knowledge graph, TUI observability, zero infra.
概覽
GrayMatter 是一個本機 Go 單一執行檔,為 AI 代理提供持久記憶與自建知識圖譜,並以 stdio 方式作為 MCP 伺服器運作。
- 可以做什麼
- 儲存、修訂、遺忘、固定並檢索代理記憶,支援信心標籤與可解釋的排序憑據
- 建立並檢視由具型別實體與共現邊構成的知識圖譜,可輸出為離線頁面或 Graphviz 格式
- 透過終端機工作台瀏覽與整理記憶,含記憶、召回、活動、圖譜、用量與狀態六個檢視
- 在權杖預算內把高權重事實投影到 CLAUDE.md 或 AGENTS.md,並稽核指令檔案的權杖與過時內容
- 安裝 Claude Code 掛鉤以在每輪注入召回,並將記憶匯出為相容於 Obsidian 的 Markdown
- 適用情境
- 適合需要代理跨工作階段記住事實、又不想反覆注入完整對話歷史的情況,且希望記憶保存在本機、不依賴託管服務。適用於 Go 或基於 MCP 的代理環境,想在單一執行檔中同時取得召回、整理與圖譜檢視能力。
- 執行需求
- 以本機 stdio 程序執行;README 提供 go install、Homebrew、Scoop、Nix 或預先編譯執行檔等安裝方式。儲存不需帳號或 API 金鑰。選用的向量嵌入供應商使用 OPENAI_API_KEY 或 VOYAGE_API_KEY,或本機 Ollama;否則退化為純關鍵字檢索。資料存放在 .graymatter 目錄中。
安裝
在 SourceWeft 中
- 開啟 儀表板中的 GrayMatter,將其新增到工作區。
- 為需要使用其工具的對話啟用該服務。
Desktop only,透過 STDIO。 STDIO 服務會啟動本機處理程序,因此需要 SourceWeft 桌面主機。
其他 MCP 客戶端
參照 儲存庫 中的啟動說明。
README
GrayMatter
[Documentation] [CI] [Go Reference] [Latest Release] [Glama MCP server score] [Coverage (multi-platform union): core 90%, CLI 81%] [Platforms] [License]
AI agents forget everything between sessions. GrayMatter gives them persistent memory, a self-building knowledge graph, and cuts context tokens by 90%.
One binary. Drop it in. Run it. No Docker, no databases, no config files, no cloud accounts, no bullshit.
General-purpose MCP server. Zero vendor lock-in.
Works with Claude Code, Cursor, Codex, OpenCode, Antigravity — and any MCP-compatible client.
Also a plain Go library if you don't use MCP.
Free. Offline. No account required.
Why
Every AI agent is stateless by default. Each run re-injects the full conversation history — and that history grows linearly. Two prompts in and you've already burned half of your daily quota.
That's not just a memory problem. That's a money and performance problem.
Mem0, Zep, Supermemory solve this — but they're Python/TypeScript-only and require a running server. The Go ecosystem has no production-ready, embeddable, zero-dependency memory layer for agents.
That gap is GrayMatter.
[Context tokens per query vs full-history injection]
~90% reduction in context tokens — versus full-history injection.
Remembers what a sliding window forgets: facts planted 96 sessions back come back 83% of the time.
Context quality improves over time as consolidation surfaces only what matters.
No Docker. No Redis. No API key required for storage.
Drop it in once. It auto-connects to Claude Code, Cursor, Codex, OpenCode, Antigravity — any MCP-compatible client picks it up automatically.
Knowledge Graph
Your agent doesn't just remember facts — it builds a map of how they connect.
Run the daemon with --kg and every consolidation cycle extracts typed
entities (person, organization, project) and links the ones that appear
together. No manual tagging. No configuration. The graph builds itself from
ordinary use.
Every edge carries receipts: the fact IDs that produced it.
Export to Obsidian with one command — entities become notes,
connections become wikilinks, and the whole graph renders natively.
The graph as one self-contained page — inline force-directed SVG, zero external assets, works offline. Hover any edge to see the fact IDs that produced it:
Watch it build, one frame per session:
Observability
You can't improve what you can't see.
[GrayMatter TUI: creating and pinning a memory, activity, usage and system status]
graymatter tui opens a memory workbench with six views:
Press 1–6 to switch views, / for the command palette, n for namespaces,
f to filter, Tab to move focus, and ? for contextual controls. Memory opens
first. Narrow terminals show one pane at a time; larger terminals show the list
and inspector together. --theme dark|light|terminal and optional --mouse
adapt the workbench to your terminal. --read-only prevents memory and session
mutations; it requires an existing store and either a running daemon or explicit
--no-daemon.
Usage stays available in the footer as well as its own view. Limits are reported per account and window; API costs retain currency, period, source and whether they are reported or estimated. Missing data remains unavailable, and failed refreshes keep the last observation marked stale. No account is connected automatically. See the workbench guide and Usage setup.
graymatter doctor --graph extends visibility to the knowledge graph itself:
hubs by degree, articulation points, orphans, and a declared connectivity
ratio — printed or emitted as JSON.
What GrayMatter gives you
Quick start
Install and see it working in under a minute — no API keys, no Ollama:
Standard doctor does not write a probe, start a daemon, execute a binary on
PATH, or test whether the data directory is writable. Its config checks find
references in files; they do not prove which settings a client loaded. In JSON,
ok means no check failed, while readiness: not_evaluated keeps readiness
separate from the observations. The --health, --graph, --audit, and
--embeddings modes have separate contracts; graph rendering can write HTML.
graymatter init --global still performs that normal setup in the current
directory. It additionally installs the managed memory instructions in Claude
Code and OpenCode's home-scoped instruction files. It does not globalize
project-scoped MCP configs. If Claude's MCP server is already registered at
user scope and the instructions are already available globally, you do not
need to repeat local client setup in each repository. For a new user-scoped
Claude MCP registration, run once:
To prepare only the current project's memory directory before a session, use
graymatter init --store-only (available since v0.20.0). It creates
.graymatter/MEMORY.md if needed and leaves an existing regular
.graymatter/gray.db untouched. It does not
write client configs, instructions or hooks, change PATH, open the database,
or verify runtime health. If neither leaf is regular, symlink or other
nonregular MEMORY.md/gray.db entries cause an error; use --dir to select
the real data directory. You can repeat it safely:
For launchers that find the Git checkout or worktree root before running this
command, see the Claude Code examples.
Global hooks are optional (graymatter hooks install --scope global) and skip
unprepared directories. MCP can itself create gray.db when it starts, even
without init --store-only; this command does not prevent that behavior.
Project-scoped clients still need their own MCP config. Codex is the exception
in the table below because its MCP config is already home-scoped.
For a new, opt-in guarded Claude user registration, use --no-create and
prepare each selected checkout before connecting:
Reconnect the MCP client after preparation. --no-create is not added to
existing entries by init; update a custom registration deliberately. It
requires a regular gray.db, or a regular MEMORY.md when the database is
absent. It is neither a database health check nor a read-only mode: an accepted
server can create and write runtime files. Hooks and MCP reject a symlink,
directory, or other nonregular gray.db even in the default eager mode. For a
custom store, use the same absolute --dir for preparation, MCP, and hooks.
Before downgrading to a binary without --no-create, remove the flag from the
registration; an older binary rejects it instead of retrying with eager
creation.
MCP stdio and hooks now select one project root per invocation. With an
omitted --dir, they use that root's .graymatter directory; an explicit
relative --dir is instead relative to the process working directory. If a
previous process-directory store contains data at a different location,
select the intended store explicitly rather than moving it automatically.
See project routing and migration for
worktree, hook namespace, custom-store, and HTTP behavior.
graymatter demo seeds a scratch store, runs consolidation, and opens the
TUI — then graymatter kg render --out kg-graph.html shows the graph it
built. Restart your editor. Seven memory tools are live.
Package managers — Homebrew, Scoop, Nix
Pre-built binaries — Linux, macOS, Windows
MCP client wiring — Claude Code, Cursor, Codex, OpenCode, Antigravity, and anything else
graymatter init configures every supported client at once. Existing entries
from other MCP servers and customized GrayMatter entries are preserved.
Normal init preserves an existing GrayMatter MCP entry, including custom
commands, remote endpoints, disabled settings and environment. To replace one
deliberately, select it explicitly:
graymatter init --only claudecode --replace-mcp. Invalid config files now
stop setup before any write; a later
partial apply returns nonzero while retaining successful actions for retry.
Scripts that accept a known partial result can opt into --best-effort.
init --json reports preparation actions with runtime_verified:false; it
does not certify a live client's setup. On Windows, interactive init asks
separately before changing user PATH, defaults to No, and honors --no-path.
Windows may reject edits to existing setup files with unsupported_metadata
when the audit SACL cannot be read; it leaves those files untouched. This also
applies to existing instructions during normal init. Edit that file manually,
use --skip-instructions to omit it, or run with permission to read its audit
SACL.
Also works out of the box: Pi (reads .mcp.json natively), Zed, Cline,
and any MCP-compatible client — point them at graymatter mcp serve.
Per-client verified configs for 25 clients, including the ones that need a
different shape (VS Code's servers key, Codex TOML, Zed's
context_servers), live in docs/integrations.md.
See docs/AGENTS.md for tool parameters and query patterns.
Token efficiency
Numbers produced by go run ./benchmarks/token_count — real Recall calls,
keyword embedder, no LLM required:
Does it return the right facts?
Tokens are only half the question. A second benchmark checks whether the returned facts actually answer the query, against a real sliding window:
At equal fact count, relevance-selected facts cost slightly more tokens than a
window's newest-first picks. With MinRelevance, GrayMatter drops below the
window's cost while keeping full recall of old facts. Method and per-query
detail in benchmarks/RESULTS.md.
Every figure on this page is machine-checked against a live run in CI.
Memory lifecycle
Consolidation is the only "smart" step. Everything else is deterministic.
Hooks (Claude Code, opt-in)
graymatter hooks install writes the hook block into .claude/settings.json
and after that the hook runner supplies routine recall automatically:
Hooks and MCP are complementary. Every non-empty hook recall begins with a
bracketed GrayMatter hook recall ran marker naming the namespace it actually
queried. This page never spells that marker out in full, so an agent reading
the docs cannot mistake them for a live recall. The agent reuses
only the newest block available for the session's initial turn. If that ID
matches its own, each non-empty section replaces that scope's startup search.
If the IDs differ, it reruns both project and __shared__ searches because
cross-namespace deduplication may have placed a shared fact in the project
section. Missing sections also fall back to MCP. Focused and batch searches,
writes, corrections, aliases, and checkpoint tools always remain available.
Failure contract: hook errors exit 0 with empty stdout, so a broken memory
does not break the session. Routing conflicts are reported briefly on stderr
before a store or hooks.log is opened; errors after startup can leave a
receipt in <dataDir>/hooks.log. graymatter hooks doctor verifies
registration, the recorded binary path, and store latency; the hot path is
machine-checked in benchmarks/hook_latency with
hardware-relative gates — the recall's marginal cost against the same machine's checkpoint
baseline (≤ 200 ms) and in-process scaling (≤ 2.5× of linear at 10k facts) —
because absolute wall-clock numbers on shared CI runners measure the runner
queue, not the code. Reference-hardware figure: p99 121 ms user-prompt on a
10k-fact store, no LLM, localhost only by construction.
For experimental lexical selection in prompt hooks, see lexical hook packets. This local, deterministic policy selects whole facts from a wider candidate pool without another model. The default remains native recall.
Context block (opt-in)
graymatter context-sync projects the highest-weight live facts into a managed
block inside CLAUDE.md / AGENTS.md, inside an explicit token budget.
Safety properties:
- Content outside the markers is never touched.
- Every rewrite leaves the previous file as
<file>.bak. - Hand edits are detected and warned about before overwrite — never silent.
- Deterministic projection: same store state, same block bytes.
CLI
Confidence options
Available since v0.20.0. A label is the writer's declaration, not verification
performed by GrayMatter:
unverified < inferred < verified. New writes validate exact labels and commit
the label with the fact's text and ID. Omitted add labels remain legacy inferred.
An omitted revision label takes the weakest live target confidence, capped at
inferred; generated summaries use the same rule and LLM extractions are
unverified. Pin and decay preserve labels.
memory_add and reflect add/update accept confidence; memory_search and
memory_search_batch accept min_confidence and confidence_weight.
Filtering precedes corpus statistics, ranks and top-k. A finite weight in
[0, 0.5] applies final = base_RRF * (1 + weight * c), with verified c=1,
inferred/legacy c=0, and unverified/unknown c=-1. The default remains zero;
explicit zero keeps an explicit filter. Explain preserves base RRF in
ranks.fused_score and adds final-score receipts. Options add the effective
retrieval policy in text and JSON, including empty results.
Any explicit filter suppresses graph neighbor hints because they have no
confidence receipts. Custom vector backends need an eligible-ID or explicit
exhaustion capability for complete filtered search. Unsupported daemon options
return an update/restart error. --shared and --all are mutually exclusive;
explain supports a single agent-scoped query and cannot combine with those
flags or batch. See the full contract
and compatibility and rollout.
Library usage
Full agent pattern — recall before LLM, fence untrusted data, store after
Config
Design decisions
Tradeoffs written down rather than left as folklore. Each ADR includes the condition under which it should be reversed.
Storage
Single file: .graymatter/gray.db. No migrations. Append-only with decay-based eviction.
Embeddings
GrayMatter degrades gracefully across four modes, always finding a way to work:
Contributing
Testing
Full suite requires no LLM and no network. Runs clean on Linux, macOS, Windows.
Coverage, measured as the multi-platform union in CI (coverage-union job):
core library ≈ 90%, CLI module ≈ 81%. Gates: core ≥ 82%, CLI ≥ 72%, and they
only ratchet upward. Fuzz targets: FuzzTokenize, FuzzUnmarshalFact,
FuzzKeywordScore, exercised nightly plus a nightly mutation-testing run
whose surviving-mutant report feeds the test-writing queue.
Build from source
Metrics & APM hooks
The REST server exposes /metrics behind the bearer token. Library users get
OnRecall, OnPut, and OnVectorIndexError hooks plus a pluggable
VectorBackend interface.
Security
Network surfaces bind loopback-only with bearer auth. Memory is untrusted input: recalled facts are fenced, never concatenated as system prompt. See docs/threat-model.md.
What GrayMatter is NOT
Not tied to any vendor. Not a framework. Not a hosted service. Not a knowledge-base UI. Not trying to win the enterprise memory market.
It is exactly one thing: the missing stateful layer for Go agents, packaged as an MCP server and a library you import in three lines.
How it compares
Code graphs parse your source tree and expose symbols, call edges, and blast radius. The repo is the source of truth. GrayMatter never reads your source — facts exist only because something deliberately wrote them, and they carry a 30-day half-life that code graphs must never have, since a stale fact means something changed and a stale code graph means nothing did.
Context compressors shrink payloads already moving through the transport. GrayMatter never sees your traffic — the agent writes one distilled sentence and recalls a handful later. Some compressors ship session memory; the difference is scope. They stack.
Roadmap
- Ollama-backed consolidation LLM — shipped in v0.14.0: propose/apply with tombstone receipts, fully local (ADR-011)
- Cross-project memory federation (read-only) — #12, deferred until a multi-project store demonstrates the need
- WebSocket streaming for REST API
- MCP 2026-07-28 stateless protocol support
GrayMatter — v0.20.1 — October 2026
來源:README.md,提交 55b7ed8
工具
0版本歷史
1- v0.16.4最新Sep 16, 2026
評分
已滿足適用檢查項的 50%
該評分衡量此收錄條目的完整程度,依據註冊中心條目、端點與公開來源計算得出。它不是對伺服器本身的評價,也不表示伺服器安全或目前可用:可連通性是帶日期的檢查結果,評分也不包含安裝量或使用者評價。
- 近 30 天內可連通25 分
請保持端點能夠回應 MCP 握手;SourceWeft 每 30 天探測一次。
- 已宣告認證方式10 分
請在註冊中心條目中宣告憑證請求標頭,或保持端點能夠回應探測,以便判定其認證方式。
- 已列出工具15 分
請讓伺服器在無憑證時回應 tools/list,或發布可在沙箱中無憑證啟動的軟體包。
- 描述必需15 分
- 圖示10 分
- 文件15 分
- 授權條款10 分