The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Agent Memory MCP listing page.
A memory, docs, and repo context layer for engineering agents.
agent-memory-mcp helps agents work with live engineering context, not just isolated notes. It combines typed memory, document retrieval, and repository-aware tools so Claude, Cursor, Codex, and other MCP clients can recall decisions, search runbooks, inspect project docs, and reuse operational knowledge across sessions.
It is designed for engineering workflows such as:
Most memory MCP servers focus on "store a note, recall a note."
agent-memory-mcp is aimed at a wider engineering context layer:
This makes it a better fit when the agent needs to answer questions like:
CLAUDE.md / .cursorrulesReference docs: HOOKS · MCP_TOOLS · SHARED_SERVICE · STEWARDSHIP · SEDIMENTATION · BACKUP_RESTORE · SECURITY · THREAT_MODEL · CONTRIBUTING · CHANGELOG
.env: run from your project root without manually sourcing environment variablesagent-memory-mcp reembed for memory migration and agent-memory-mcp index for RAG rebuilds after switching modelsstats and memory_stats show how many memories belong to each embedding model, and name the ones no semantic query can reach — records the encoder refused outright, and records embedded from their opening onlysource_type, confidence, freshness, owner, and last_verified_at, and ranking uses trust/freshness instead of similarity alone/console127.0.0.1 by default; non-loopback binds require auth unless you explicitly opt into unsafe unauthenticated accesssteward_run executes a full maintenance cycle — duplicate detection, conflict resolution, stale entry scanning, and canonical promotion candidates — with a single commanddrift_scan compares memory entries against live repo files and docs to find stale, missing, or changed referencesverify_entry and verification_candidates let agents and users track when knowledge was last verified and what needs attentionsteward_policy and environment variablesvalid_from / valid_until timestamps, and recall_as_of retrieves knowledge that was valid at a specific point in timemark_outdated with a superseding entry automatically builds bidirectional links (superseded_by / replaces) and sets temporal boundariesknowledge_timeline shows the chronological evolution of knowledge on a topicMCP_RECALL_HALFLIFE_DAYS, and note that MCP_RECALL_DECAY_TYPES (default working) decides which types age at all — the type axis matters more than the rateauto_merge_duplicate_min_confidence in steward_policy)The recommended path is: run locally first, prove value on one repo, then expand.
Run these commands from your project root.
Install the binary with one of these options:
Then configure one embedding provider:
bge-m3 for a local setupThe binary auto-loads .env from the current directory, so you do not need source .env.
The recommended solo-local preset keeps all runtime state inside one directory:
Use local-only mode when you want embeddings without sending text to hosted APIs.
In local-only mode:
agent-memory-mcp never calls Jina AIagent-memory-mcp never calls OpenAI-compatible embedding APIsWhat still uses the network:
http://localhost:11434http://127.0.0.1:8080/v1If no local backend is running or no supported local model is available, embedding requests fail with a local-only specific error telling you to start the backend or disable MCP_EMBEDDING_MODE=local-only.
If you already run llama.cpp (Apple Silicon native, GGUF models), point the server at its OpenAI-compatible /v1/embeddings endpoint instead of installing Ollama. It is opt-in — set LLAMACPP_BASE_URL to enable it. Once set it joins the fallback chain before Ollama (Jina → OpenAI → llama.cpp → Ollama) and works in local-only mode.
llama.cpp returns the model's native embedding dimension, so make sure MCP_EMBEDDING_DIMENSION matches it (1024 for bge-m3) — a mismatch is rejected at recall time.
On slow self-hosted hardware (Ollama with bge-m3 on a low-core or ARM VPS), a single chunk can take 4-7 seconds to embed and the default 5s timeout will fire repeatedly. Raise the limits:
Invalid values fall back to the defaults, so the service still starts.
A single-slot llama-server processes requests strictly serially. With MCP_RAG_AUTO_INDEX / MCP_RAG_FILE_WATCHER enabled, background reindex batches (50 chunks each) hold the only slot for tens of seconds, so interactive recall / semantic_search / index_documents queue behind them and hit context deadline exceeded — the server looks "degraded" even though throughput is fine. Give the embedding server parallel slots so interactive calls slip in alongside the batch:
-npsplits the context. Per-slot context isctx_size / n_parallel. bge-m3 is an encoder — every chunk must fit in one slot whole, and-b/-ubmust be ≥ the largest chunk in tokens, or it fails with "input too large to process". So with-np 4you need-c 32768to keep 8192 per slot; do not lower-c,-b, or-ubbelow the single-slot value when adding slots.
Measured effect (Apple Silicon, bge-m3 Q8_0): a 50-input batch drops from ~50s to ~5s, and an interactive probe under batch load drops from 8–20s to ~0.03s.
Also smooth the reindex avalanche for large, frequently-edited files (whole-file re-chunk on every edit can re-trigger mid-cycle):
For MCP clients such as Claude Desktop, Cursor, or Codex:
For direct CLI use, the same binary already works without an MCP client:
If you are working from the source checkout, you can run the same flow with:
Once local mode is running against a project, index docs and search them:
Typical high-value sources include:
docs/README.mdCHANGELOG.mdWhen local mode proves useful, move in three steps:
Fastest shared-service path:
This keeps the same retrieval stack, but packages it for team use.
Reference docs:
This installs the binary, creates a default config, and starts the service on 127.0.0.1:18080 with memory enabled. RAG document search is disabled by default — enable it by editing the config:
Set MCP_RAG_ENABLED=true, MCP_ROOT=/path/to/your/project, and MCP_INDEX_DIRS=docs,README.md. Changes are picked up automatically within ~30 seconds, or force reload with kill -HUP $(pgrep agent-memory-mcp).
Manage the service:
If you previously installed via Cask and want brew services:
Download a prebuilt archive from the Releases page.
The release archives include the version in their filename, so resolve the latest tag first:
Or with docker compose:
The MCP HTTP endpoint will be available at http://localhost:18080/mcp.
By default, bare-metal HTTP mode now binds to 127.0.0.1. For shared/container deployments, set MCP_HTTP_HOST=0.0.0.0 and a bearer token.
The binary also works as a standalone CLI:
Run agent-memory-mcp <command> -help for details on any command.
CLI memory commands and MCP memory tools now share the same validation and normalization rules:
verified timestamps are hidden from trust summaries in both CLI and MCP outputWhen no command is given (or flags start with -), the binary starts the MCP server as before -- full backward compatibility.
Use the built-in generator to produce a project-local config that starts the server from your repo root.
This is the recommended path because it:
.env loading working without duplicating settings into every MCP client.agent-memory/ relative to the project rootYou can override the detected project root or binary path with -root and -command.
Paste into ~/Library/Application Support/Claude/claude_desktop_config.json:
Example generated output:
Paste into ~/.cursor/mcp.json:
Example generated output:
Paste into ~/.codex/config.toml:
Example generated output:
Without these snippets, the agent will only use basic store_memory and recall_memory. To unlock session close, engineering memory types, project bank, and consolidation, add relevant snippets to your agent's instructions.
Where to put them:
CLAUDE.md at the project root.cursorrules at the project rootAGENTS.mdPick the snippets that match your workflow. Start with "Start-of-session recall" and "Coding close" — they cover the most common case.
Start the server in HTTP mode:
Then point your HTTP-capable MCP client or proxy at:
The /mcp endpoint supports the MCP Streamable HTTP transport: JSON-RPC requests go over POST, and clients that need a server-push channel (Cursor and similar) open it with GET and Accept: text/event-stream. The server keeps that stream alive with periodic keepalive comments. A plain GET without the SSE Accept header still returns 405.
For retrieval inspection in a browser, open:
The console is a lightweight UI for:
In shared mode, the page itself is static, but live queries from the console still require the same bearer token as /mcp.
For shared HTTP mode:
MCP_HTTP_HOST=127.0.0.1; this is the safe local defaultMCP_HTTP_HOST=0.0.0.0MCP_HTTP_AUTH_TOKEN to require Authorization: Bearer <token> on /mcpMCP_HTTP_AUTH_TOKEN, unless you explicitly set MCP_HTTP_INSECURE_ALLOW_UNAUTHENTICATED=true/health for load balancer or container health checkslocal -> team laptop -> shared service path| Command | Description |
|---|---|
serve | Start MCP server (stdio/http) -- default when no command given |
store | Store a memory (-content, -title, -type, -tags, -context, -importance, -stdin) |
recall | Memory recall with trust-aware ranking (positional query, -type, -tags, -limit, -json) |
list | List memories (-type, -context, -limit, -json) |
delete | Delete a memory by ID (positional) |
search | RAG hybrid search with trust metadata (positional query, -limit, -source-type, -debug, -json) |
index | Re-index documents for RAG |
close-session | Analyze an end-of-session summary and produce a close-session report (-summary, -stdin, -mode, -context, -service, -tags, -metadata, -started-at, -ended-at, -raw-only, -json) |
review-session | Review-oriented alias for close-session with the same inputs and report surface |
accept-session | Save the raw summary and auto-apply low-risk session changes (-summary, -stdin, -mode, -context, -service, -tags, -metadata, -started-at, -ended-at, -raw-only, -json) |
stats | Show memory statistics (-json) |
config | Generate ready MCP client config snippets |
project-bank | Show structured project bank views (canonical_overview, decisions, runbooks, incidents, caveats, migrations, review_queue) |
resolve-review-item | Resolve a pending review queue item (<id>, -resolution, -note, -owner, -json) |
reembed | Re-generate memory embeddings with the active model (-json) |
export | Export all memories to JSON (-o file, default stdout) |
import | Import memories from JSON (positional file or stdin) |
index-triples | Retrofit (subj, rel, obj) triples for memories that lack them (-resume, -force, -limit, -context, -dry-run, -progress-every, -json). Powers the recall_multihop MCP tool — see MCP_TRIPLE_EXTRACTOR_* envs. |
dead-ends-stale | List dead_end memories older than -age (default 12 months) for re-evaluation (-limit, -json) |
setup | Auto-configure Claude Code hooks in ~/.claude/settings.json (-command, -dry-run, -force). See docs/HOOKS.md |
hooks-config | Print Claude Code hooks JSON for manual paste into settings.json (-command, -json) |
context-inject | SessionStart hook payload: recent memories + pending raw summaries (-limit, -pending-limit, -context, -service) |
auto-capture | SessionEnd hook: read transcript from stdin, run extract → plan → apply pipeline (-stdin, -summary, -mode, -context, -service, -tags, -dry-run, -json) |
checkpoint | PreCompact hook: save a raw session checkpoint before context compression (-stdin, -summary, -boundary, -context, -service, -tags) |
sweep-archive | Scan MCP_TASK_ARCHIVE_ROOTS and run end-task on every archived slug (T47) |
end-task | Consolidate working/procedural memories tied to one archived task slug (T47) |
mark-dead-end | Record an abandoned approach with its failure rationale (T46) |
sediment-cycle | Apply layer transitions for memory sedimentation: trivial promotions auto-apply, the rest queue for review (T48) |
recount-refs | Backfill referenced_by_count metadata from existing cross-memory edges (idempotent) |
| Tool | Description |
|---|---|
store_memory | Store a memory with content, type, tags, and importance |
recall_memory | Recall memories by semantic/text query with optional filters and trust-aware ranking |
update_memory | Update an existing memory by ID |
delete_memory | Delete a memory by ID |
list_memories | List all memories with optional type/context filtering |
memory_stats | Get memory statistics (counts by type) |
merge_duplicates | Merge duplicate memories into a primary entry and archive the rest |
mark_outdated | Mark a memory as outdated or superseded so trust-aware recall downranks it |
promote_to_canonical | Promote a memory to canonical knowledge and boost its trust ranking |
conflicts_report | Report duplicate candidates, conflicting statuses, and multiple canonical entries |
list_canonical_knowledge | List canonical knowledge entries projected from confirmed memories |
recall_canonical_knowledge | Recall canonical knowledge only, excluding raw memories from results |
recall_multihop | Multi-hop graph-walk recall over the (subj, rel, obj) triple corpus — returns memories ranked by aggregated path score with the chain of triples that reached each result. Use for cross-memory reasoning queries that single-hop search cannot trace. Requires MCP_TRIPLE_EXTRACTOR_* populated; backfill via index-triples CLI. |
| Tool | Description |
|---|---|
semantic_search | Hybrid search across indexed documents with optional source_type, trust metadata, and debug explain mode |
index_documents | Re-index documents for RAG search |
| Tool | Description |
|---|---|
repo_list | List files and folders under allowlisted paths |
repo_read | Read a file from allowlisted paths |
repo_search | Text search across allowlisted paths |
| Tool | Description |
|---|---|
store_decision | Store an engineering decision with rationale, status, and consequences |
store_incident | Store an incident with impact, root cause, resolution, service, and severity |
store_runbook | Store a runbook with procedure, trigger, verification, and rollback notes |
store_postmortem | Store a postmortem with root cause and action items |
close_session | Analyze a finished session into raw summary metadata, candidate knowledge items, and review-safe consolidation actions |
analyze_session | Compatibility alias for close_session with the same planning and reporting behavior |
review_session_changes | Render the explainable review report for a finished session without forcing writes |
accept_session_changes | Persist the raw summary and auto-apply only low-risk consolidation actions |
resolve_review_item | Resolve a pending review queue item so it disappears from the active inbox while keeping an audit trail |
search_runbooks | Search runbook memories plus indexed runbook docs |
recall_similar_incidents | Recall similar incidents from memory and indexed postmortems |
end_task | Consolidate memory for an archived task slug: outdate working/procedural entries, route high-importance ones to the review queue |
sweep_archive | Pull-mode scan over MCP_TASK_ARCHIVE_ROOTS that runs end_task on every archived slug |
store_dead_end | Record an attempted approach that failed (plus the why and the alternative used) so retrieval can surface it as a pitfall warning on related queries. Use this for standalone failures with no decision context. Use store_decision -avoided-dead-end-id <id> when the dead end is part of a larger architectural decision and you want to link both records into one rationale chain (T46) |
promote_sediment | Promote a memory to a higher sediment layer (surface → episodic → semantic → character). See docs/SEDIMENTATION.md |
demote_sediment | Demote a memory one sediment layer down |
sediment_cycle | Run the sediment transition cycle — auto-applies trivial promotions, routes non-trivial ones to the review queue |
summarize_project_context | Summarize recent decisions, runbooks, incidents, and related docs |
project_bank_view | Show a structured project bank view for canonical knowledge, decisions, runbooks, incidents, caveats, migrations, the review queue, or sediment promotion candidates |
| Tool | Description |
|---|---|
steward_run | Run a knowledge stewardship cycle: scan for duplicates, conflicts, stale entries, and canonical promotion candidates |
steward_report | Retrieve the latest stewardship report or a specific one by run ID |
steward_policy | Get or update the stewardship policy that controls detection thresholds, auto-apply rules, and scheduling |
steward_status | Show current stewardship status: policy mode, last run summary, pending review count, next scheduled run |
drift_scan | Compare memory entries against live sources (repo files, docs) to detect drift, missing references, and stale unverified knowledge |
verification_candidates | List memories that need verification, ranked by urgency |
verify_entry | Mark a memory as verified, updating its verification metadata |
steward_inbox | List stewardship inbox items — review-required actions from maintenance runs, drift scans, and session consolidation |
steward_inbox_resolve | Resolve a steward inbox item by applying an action: merge, mark_outdated, promote, verify, suppress, or defer |
| Tool | Description |
|---|---|
recall_as_of | Retrieve knowledge that was valid at a specific point in time, filtering by temporal validity |
knowledge_timeline | Show the chronological evolution of knowledge on a topic — how entries were created, superseded, and replaced over time |
Every MCP client loads the full JSON schema of every tool at initialize time —
before your first message. With ~40 tools that schema payload alone can occupy
tens of KB of the model's context window on every session. Two secondary costs
compound it: LLMs get measurably worse at picking the right tool as the count
climbs past ~20–40, and frequent session reloads re-pay the whole cost.
Set MCP_TOOL_GROUPING=true to collapse the core toolset into a handful of
grouped meta-tools, each dispatching by a required action discriminator:
Groups: repo · memory · memory_admin · engineering · search ·
session, plus the index_documents and project_bank_view singletons — the
default surface drops from 41 tools to 8 (~42% smaller schema payload).
false; the flag only changes what
tools/list returns.tools/call accepts the grouped form
(memory + action=store) and the legacy name (store_memory) regardless
of the flag, so existing scripts never break.steward_inbox_resolve already uses its own
action argument — grouping deliberately leaves them ungrouped.Trade-off: each grouped call carries a slightly larger per-call schema (the union
of its actions' arguments). Prefer grouping for high-volume agent runs where
discovery cost dominates; leave it off for interactive debugging where seeing
each tool by name is clearer. Policy reference: docs/concepts/lifecycle.md
covers the related archive-sweep surface.
All configuration is via environment variables. See .env.example for the full list.
Config files are loaded in this order (each file only fills in values not already set):
--config /path/to/file (explicit path, skips chain; accepted by every command, not just serve).env in the current directory~/.config/agent-memory-mcp/config.env (XDG)$(brew --prefix)/etc/agent-memory-mcp/config.env (Homebrew)For solo local mode, copy .env.example to .env in your project root. For brew services, the config is auto-created at $(brew --prefix)/etc/agent-memory-mcp/config.env.
When running as a service (HTTP mode), the config file is watched for changes every 30 seconds. RAG-related settings (index dirs, embedding keys, enabled/disabled) are applied without restart. HTTP settings (port, host) require a full restart.
You can also force an immediate reload:
| Variable | Default | Description |
|---|---|---|
MCP_ROOT | Current dir | Project root path |
MCP_ALLOW_DIRS | "" (only MCP_ROOT) | Comma-separated extra repo-relative paths the file tools (repo_list, repo_read, repo_search) may read. Paths must stay under MCP_ROOT; absolute paths or .. traversal are rejected at config load. Critical for shared/HTTP mode — keep narrow |
MCP_MAX_FILE_BYTES | 2097152 | Max file size (bytes) repo_read will return; larger files are rejected |
MCP_MAX_SEARCH_RESULTS | 200 | Hard cap for repo_search result count |
MCP_MAX_DEPTH | 3 | Max directory recursion depth for repo_list |
MCP_STDIO_MODE | line | Stdio framing: line (newline-delimited) or lsp (Content-Length headers) |
MCP_TOOL_GROUPING | false | Collapse the core toolset into grouped meta-tools on tools/list to cut the discovery schema payload (~42% smaller, 41→8 tools). tools/call accepts both grouped (memory+action) and legacy names regardless. See Tool grouping mode |
MCP_MEMORY_ENABLED | true | Enable memory tools |
MCP_MEMORY_PREVIEW_RUNES | 0 | Override the per-surface truncation cap (rune-based) for memory content/summary fields in MCP tool responses (recall_memory, list_memories, search_runbooks, …). 0 keeps the built-in caps (150/220/300); a positive value forces that single cap on all surfaces; a negative value disables truncation (full text). |
MCP_RAG_ENABLED | true | Enable RAG/search tools (Homebrew service preset overrides this to false until you set MCP_ROOT) |
MCP_HTTP_MODE | stdio | Transport: stdio or http |
MCP_HTTP_HOST | 127.0.0.1 | HTTP bind host; set 0.0.0.0 for shared/container deployments |
MCP_HTTP_PORT | 18080 | HTTP port (when in HTTP mode) |
MCP_HTTP_AUTH_TOKEN | - | Bearer token required for non-loopback/shared HTTP mode |
MCP_HTTP_INSECURE_ALLOW_UNAUTHENTICATED | false | Explicit unsafe override for non-loopback HTTP without auth |
JINA_API_KEY | - | Jina AI API key for embeddings |
OPENAI_API_KEY | - | OpenAI API key (or compatible: Together, Mistral) |
OPENAI_BASE_URL | https://api.openai.com/v1 | OpenAI-compatible base URL |
OPENAI_EMBEDDING_MODEL | text-embedding-3-small | Embedding model name |
OLLAMA_BASE_URL | http://localhost:11434 | Ollama URL (local fallback) |
LLAMACPP_BASE_URL | - | llama.cpp OpenAI-compatible base URL (e.g. http://127.0.0.1:8080/v1); empty disables it |
LLAMACPP_EMBEDDING_MODEL | bge-m3 | llama.cpp embedding model label (used only when LLAMACPP_BASE_URL is set). The label is part of the derived model id stored on every record, so changing it invalidates the bank exactly as changing the model does — see docs/EMBEDDING_MIGRATION.md |
MCP_EMBEDDING_MODE | auto | Embedding mode: auto or local-only |
MCP_EMBEDDING_DIMENSION | 1024 | Vector dimension (change requires re-indexing) |
MCP_EMBEDDING_TIMEOUT | 5s | Per-request embedding timeout; raise on slow local backends |
MCP_EMBEDDING_MAX_RETRIES | 1 | Embedding retry count on transient failures |
MCP_INDEX_DIRS | docs | Comma-separated directories and individual files to index for RAG. Code fallback is docs; the shipped .env.example preset sets docs,README.md,CHANGELOG.md for a typical project layout |
MCP_RAG_AUTO_INDEX | true | Index documents on startup. Code default is true (good for HTTP/service mode); the solo-local .env.example preset turns it off so you control indexing with explicit agent-memory-mcp index runs |
MCP_RAG_FILE_WATCHER | false | Watch MCP_INDEX_DIRS for changes and reindex incrementally; useful for long-running shared/service instances |
MCP_INDEX_EXCLUDE_DIRS | built-in defaults | Extra directory names or repo-relative paths to exclude from RAG indexing |
MCP_INDEX_EXCLUDE_GLOBS | - | Extra glob patterns matched against repo-relative paths, for example docs/internal/*.md |
MCP_REDACT_SECRETS | true | Redact common secret-like content before documents are indexed |
MCP_ARCHIVE_SWEEP_ENABLED | true | Zero-ops consolidation: a background loop marks archived-task working memories outdated (or promotes durable ones) with no manual runs. Auto-discovers <MCP_ROOT>/tasks/archive; no-op if absent. See Zero-ops consolidation |
MCP_ARCHIVE_SWEEP_INTERVAL | 1h | Background archive-sweep cadence. 0 disables the loop |
MCP_SESSION_TRACKING_ENABLED | true | Enable background session tracking, auto raw summaries, and low-risk close-session orchestration |
MCP_SESSION_IDLE_TIMEOUT | 10m | Idle timeout before the active background session auto-closes |
MCP_SESSION_CHECKPOINT_INTERVAL | 30m | Interval for periodic raw checkpoint snapshots during active sessions |
MCP_SESSION_MIN_EVENTS | 2 | Minimum tracked MCP tool calls before background auto-close runs |
MCP_DATA_PATH | data | Base path for data storage |
MCP_RAG_INDEX_PATH | <MCP_DATA_PATH>/rag-index | Override the SQLite vector index location |
MCP_MEMORY_DB_PATH | <MCP_DATA_PATH>/memory-store/memories.db | Override the SQLite memory database path |
MCP_LOG_PATH | <MCP_DATA_PATH>/logs/mcp-diagnostics.log | Override the diagnostics log file path |
MCP_STATS_ENABLED | false | Append per-call usage records (jsonl) for self-observability |
MCP_STATS_PATH | <MCP_DATA_PATH>/logs/mcp-usage.jsonl | Stats jsonl output path |
MCP_STATS_SAMPLE_RATE | 1.0 | Fraction (0.0–1.0) of calls to record when stats are enabled |
MCP_STEWARD_ENABLED | auto | Enable knowledge stewardship (auto-enabled in HTTP mode with memory) |
MCP_STEWARD_MODE | manual | Stewardship mode: off, manual, scheduled, event_driven |
MCP_STEWARD_SCHEDULE_INTERVAL | 24h | Interval between scheduled stewardship runs |
MCP_STEWARD_DUPLICATE_THRESHOLD | 0.85 | Similarity threshold for duplicate detection |
MCP_STEWARD_STALE_DAYS | 30 | Days before a memory is considered stale |
MCP_STEWARD_CANONICAL_MIN_CONFIDENCE | 0.80 | Minimum confidence for canonical promotion candidates |
MCP_CHECKPOINT_DEDUP_THRESHOLD | 0.9 | Jaccard similarity threshold above which a checkpoint is considered a duplicate of the previous one in the same context |
MCP_CHECKPOINT_DEDUP_WINDOW | 10m | Time window for the dedup lookup — only checkpoints newer than this are compared |
MCP_CHECKPOINT_DEDUP_MIN_CHARS | 100 | Minimum content length (chars) before a checkpoint is eligible to be saved; shorter content is dropped as empty |
MCP_CHECKPOINT_DEDUP_DISABLED | false | Escape hatch: disable checkpoint-hook deduplication entirely |
MCP_TASK_ARCHIVE_ROOTS | - | Colon-separated archive roots for sweep-archive / end-task (e.g. /home/you/tasks/archive). Empty disables the feature |
MCP_TASK_SLUG_PATTERN | - | Optional regex filtering archive subdirectory names; invalid regex fails config load |
MCP_RERANK_ENABLED | false | Master gate for the neural reranker stage after hybrid search. Must be true AND MCP_RERANK_PROVIDER must be a real provider (jina) for the reranker to run |
MCP_RERANK_PROVIDER | disabled | Reranker provider: jina or disabled. With disabled (or empty) the pipeline degrades to hybrid-only ranking even when MCP_RERANK_ENABLED=true |
JINA_RERANKER_MODEL | jina-reranker-v2-base-multilingual | Jina reranker model id |
MCP_RERANK_TIMEOUT | 5s | Hard timeout for one rerank call; on timeout the hybrid order is kept and rerank_failed:timeout is added to debug signals |
MCP_RERANK_TOP_N | 40 | Number of top hybrid candidates sent to the reranker; clamped to 100 at call time |
MCP_RETRIEVAL_STRICT | false | Turn silent degradation on the read path into a failed call: an embedding provider falling through to the next one, a reranker timing out, a multihop query with no graph to walk. Intended for measurement runs (make eval enables it) and for diagnosing a half-configured install — leave it off in production, where a worse answer beats no answer. Regardless of this flag, every semantic_search response carries a retrieval block naming the path that actually served it |
MCP_SEDIMENT_ENABLED | false | Enable layer-aware retrieval scoring (character always surfaced, surface excluded outside context). Schema migration + backfill always run; only retrieval weighting is gated. See docs/SEDIMENTATION.md |
MCP_RECALL_CENTERED | true | Score memory recall over mean-centered embeddings instead of raw cosine. Adopted on a measured win (T76a): on 345 machine-labelled queries against a live bank, Hit@5 went 0.6232 → 0.7217 and MRR 0.4922 → 0.5739. Raw cosine on real corpora is anisotropic — unrelated pairs sat at a median of 0.555, so minScore cleared 100% of candidates and gated nothing; centered, the same sample clears it at 34.1%. Banks with fewer than 100 embeddings ignore this and use raw cosine, since a mean over a handful of vectors is dominated by the vectors it must cancel. Set false to score the way earlier releases did |
MCP_RECALL_HALFLIFE_DAYS | 0 | T68 exponential age decay on recall scoring (half-life in days; a card this old scores at half weight). 0 disables decay — the default since T121 measured it: over 345 machine-labelled queries Hit@5 was 0.7217 with decay off against 0.1942 at the previous 30-day default, monotone in between (365d 0.6087, 180d 0.4609, 90d 0.2870), and no age bucket where decay paid for itself. Preferring the current version of a fact is already handled semantically by supersession and lifecycle status; a calendar multiplier cannot tell "written a while ago" from "no longer true". Evergreen entries (canonical knowledge, character layer) never decay |
MCP_RECALL_DECAY_TYPES | working | Which memory types age when decay is enabled at all. The type axis dominates the rate: at the same 30-day half-life, decaying every type scored Hit@5 0.1942 while decaying only working scored 0.7043 — the old behaviour aged patterns and facts, which is the knowledge the bank exists to accumulate. Empty means every type decays |
MCP_RAG_KEEP_NOISE | false | T49 escape hatch: keep noisy Markdown sections (Table of Contents / References / Changelog / etc.) in the index instead of dropping them at chunking time |
MCP_RAG_MAX_CHUNKS_PER_DOC | 1 | How many chunks of one document may occupy a search result list. Adjacent chunks of a file carry nearly the same score, so an uncapped top-5 unfolded into 2.07 distinct documents on 250 questions — over half the list spent on more of a file already shown. At one chunk per document that is 5.00, R@5 by document 0.5104 → 0.8676 and nDCG@5 0.6184 → 0.8927, while first-hit metrics hold (Hit@5 0.9600 → 0.9640, MRR 0.9580 → 0.9590); 207 of 250 queries improved and none got worse (T127). The cap is a preference, not a quota — when fewer documents exist than the limit asks for, the skipped chunks are added back rather than the list coming up short. 0 restores the uncapped order, 2 is the middle position (3.11 documents, R@5 0.7648) |
MCP_TRIPLE_EXTRACTOR_ENABLED | false | T50 knowledge-graph layer. Enable to fire an async LLM call on every memory write that extracts 3-7 (subj, rel, obj) triples powering recall_multihop |
MCP_TRIPLE_EXTRACTOR_BASE_URL | - | OpenAI-compatible /chat/completions endpoint (DeepSeek, Together, Groq, Qwen, …); falls back to OPENAI_BASE_URL when empty |
MCP_TRIPLE_EXTRACTOR_API_KEY | - | Bearer token for the extractor. Falls back to OPENAI_API_KEY only when MCP_TRIPLE_EXTRACTOR_BASE_URL is empty or equal to OPENAI_BASE_URL. Pointing the extractor at a third-party endpoint without giving it its own key disables extraction with an explicit message — the OpenAI key is never sent to an address it was not issued for |
MCP_TRIPLE_EXTRACTOR_MODEL | - | Model id passed to the extractor (e.g. deepseek-chat, qwen2.5-72b-instruct) |
MCP_TRIPLE_EXTRACTOR_TIMEOUT | 30s | Per-request timeout for the extractor HTTP call |
The server creates these directories under MCP_DATA_PATH:
rag-index/ -- SQLite vector index for document searchmemory-store/ -- SQLite database for agent memoriesThe recommended solo-local preset stores them under .agent-memory/.
RAG indexing scans supported docs and engineering text files, but you can further reduce risk with explicit controls:
.git, .agent-memory, node_modules, logs, and .terraformMCP_INDEX_EXCLUDE_DIRS for repo-relative path excludes such as docs/private,runbooks/internalMCP_INDEX_EXCLUDE_GLOBS for glob-style excludes such as docs/internal/*.mdMCP_REDACT_SECRETS=true to redact common secret-like lines and private key blocks before indexingThis is especially important if you use hosted embedding providers or shared HTTP mode.
When the MCP server is running with the default session-tracking policy, it keeps a lightweight background session buffer.
Current behavior:
close_session runnotifications/session_event and event=task_done|final_summary|checkpoint|resetsafe_auto_apply policyTo inspect the inbox, use project_bank_view view=review_queue or agent-memory-mcp project-bank -view review_queue.
To close an item after manual review, use resolve_review_item or agent-memory-mcp resolve-review-item <id>.
Example notification payload:
If you want to tune or disable this behavior, use MCP_SESSION_TRACKING_ENABLED, MCP_SESSION_IDLE_TIMEOUT, MCP_SESSION_CHECKPOINT_INTERVAL, and MCP_SESSION_MIN_EVENTS.
Document indexing now treats chunk updates and tracking metadata as one logical state.
dirty before changing chunksready together with indexed_files, embedding_model, and last_indexedindex_documents / agent-memory-mcp index run detects the dirty state and forces a rebuildThis makes incremental indexing more predictable after crashes, provider interruptions, or storage errors.
The indexer now classifies engineering sources and carries that metadata into retrieval.
Supported source types:
docs for README.md and general Markdown docsadr and rfc for architecture decision and RFC-style documentschangelog for CHANGELOG.md and release-note style docsrunbook and postmortem for operational knowledgeci_config for GitHub Actions, GitLab CI, and Jenkins pipeline fileshelm, terraform, and k8s for source-aware infra filesUse source_type when you want to narrow retrieval to a specific class of knowledge:
The MCP semantic_search tool also accepts source_type and debug.
Search now uses multiple ranking signals instead of cosine similarity alone.
Current ranking signals:
source_type filtering when you want a narrower retrieval setThe retrieval pipeline now works in two stages:
Only the merged candidate set is reranked. This keeps shared-service retrieval more predictable as the indexed corpus grows.
This means a strong keyword hit in a runbook or changelog can outrank a semantically similar but less task-relevant document.
Retrieval now carries explicit trust metadata for both stored memories and indexed docs.
Each result can expose:
source_typeconfidencelast_verified_atownerfreshness_scoreWhat this means in practice:
search / recall and MCP semantic_search / recall_memory now show trust summaries in human-readable outputEngineering workflow tools also stamp stored entries with last_verified_at so fresh operational knowledge is easier to trust and rank.
Use debug mode when you want retrieval to explain why a document was returned.
CLI:
MCP:
semantic_search with debug: truedebug unset or false for the normal compact responseDebug mode adds:
source_type=runbooksource, confidence, freshness, owner, verifiedsemantic, keyword_raw, keyword_normalized, recency_boost, source_boost, confidence_boost, final_scorekeyword_match or source_type:runbookIf you want a faster inspection workflow than raw CLI or JSON-RPC calls, use the built-in console in HTTP mode:
What it is good for:
The console is intentionally lightweight and does not replace MCP tools or CLI workflows.
These MCP tools map domain-specific workflows onto the existing memory and retrieval backends.
Recommended starting points:
store_decision for architectural or operational choices such as disabling HPA or pinning an ingress versionstore_incident for short-lived operational facts you want to recall during active debuggingstore_runbook for procedural steps, rollback instructions, and verification notesstore_postmortem for durable incident learnings and action itemsclose_session when you want an explicit end-of-session plan with rationale, traces, and review-safe actionsaccept_session_changes when the close-session report is low risk and you want to persist the raw summary plus apply safe updatesresolve_review_item when the background inbox already contains a reviewed item and you want to clear it without deleting the audit trailsearch_runbooks when you need a fix path and want both memory-stored runbooks and indexed runbook docsrecall_similar_incidents when you are triaging an outage or regressionsummarize_project_context at session start to get a compact operational briefingproject_bank_view when you want maintained knowledge by view instead of raw recall results, including review_queue for pending background decisionsThese workflow tools also add verification metadata so that retrieval can treat newly stored operational knowledge as fresher and more trustworthy than anonymous raw notes.
The memory layer now supports a manual consolidation workflow without deleting historical notes.
Use these MCP tools when the same project knowledge starts to drift:
merge_duplicates to consolidate repeated notes into one primary memory and archive the rest as merged duplicatesmark_outdated to demote stale runbooks, superseded decisions, or obsolete incident notes without losing thempromote_to_canonical to mark the current best memory as canonical knowledgeconflicts_report to surface duplicate_candidates, status_conflict, and multiple_canonical groupsCurrent behavior:
Every closed task leaves behind working memories (Task started, per-phase
notes, Session close, auto-extracted review items). Left alone they accumulate
linearly and keep surfacing in recall for tasks that are already done. The
service consolidates them automatically — no cron, no manual cleanup, no config:
MCP_ARCHIVE_SWEEP_INTERVAL, default 1h)
sweeps archived tasks: durable entries (procedural, or importance ≥ 0.70) are
promoted, the rest are marked outdated. It runs a first pass shortly after
startup, which also backfills any archive that accumulated before the loop
existed.MCP_TASK_ARCHIVE_ROOTS unset it watches the
<MCP_ROOT>/tasks/archive convention; a missing directory is a silent no-op.end_task and sweep_archive tools default to the same consolidating
behavior, so an explicit /end-task consolidates immediately.Policy details (state derivation, promotion threshold, idempotency,
symlink/traversal guards): docs/concepts/lifecycle.md.
Turn the loop off with MCP_ARCHIVE_SWEEP_ENABLED=false.
The project now exposes two distinct layers:
raw memory: captured notes, incidents, decisions, and procedural memories as they were storedcanonical knowledge: confirmed entries projected from memories promoted with promote_to_canonicalWhat this changes:
list_canonical_knowledge gives you the current confirmed knowledge set without raw noiserecall_canonical_knowledge searches only canonical entriessummarize_project_context surfaces canonical knowledge before raw memory sections when canonical entries existlayer=raw, layer=canonical, or layer=documentMigration story:
promote_to_canonicaldecision or service:api are still recognized by the canonical layerThe stewardship layer provides automated and manual knowledge maintenance.
steward_run executes a full maintenance cycle in one call:
dry_run=false, applies safe actions and sends the rest to the stewardship inboxdrift_scan compares memory entries against live repo files:
source_changed when a referenced file was modified after the memory was last verifiedsource_missing when a referenced file path no longer existsstale_unverified when entries exceed the stale thresholdverification_candidates ranks memories that need verification:
verification_failed or needs_update status: high urgencysteward_inbox is the single place for all review-required actions. Resolve items with steward_inbox_resolve using actions like merge, mark_outdated, promote, verify, suppress, or defer.
Stewardship is auto-enabled in HTTP mode when memory is available. Configure thresholds and mode via MCP_STEWARD_* environment variables. See steward_policy for runtime configuration.
For a detailed guide, see Stewardship Guide.
Memories can carry temporal metadata that tracks when knowledge was valid and how it evolved:
valid_from / valid_until — the time window during which this knowledge was truesuperseded_by / replaces — bidirectional links forming supersession chainsobserved_at — when knowledge was first observed (may differ from created_at)recall_as_of retrieves knowledge that was valid at a specific timestamp. This is useful for questions like "what was our database strategy in January?" or "what changed between these two dates?"
knowledge_timeline shows the chronological evolution of entries matching a query, ordered by valid_from.
When mark_outdated is called with a superseding entry, the system automatically sets valid_until on the old entry and valid_from + replaces on the new entry, building a navigable chain.
Core deployment guidance:
MCP_HTTP_MODE=stdio, prefer MCP_EMBEDDING_MODE=local-only if you need no-send semanticsMCP_HTTP_HOST=0.0.0.0, set MCP_HTTP_AUTH_TOKEN, keep TLS at the reverse proxy, and scope MCP_ALLOW_DIRS narrowlyMCP_INDEX_EXCLUDE_DIRS / MCP_INDEX_EXCLUDE_GLOBS.agent-memory/ or use agent-memory-mcp export for memory-only backupsReference docs:
The server supports three embedding providers in auto mode:
jina-embeddings-v3, native 1024 dimensions, multilingualtext-embedding-3-small or any OpenAI-compatible API. Native dimension is 1536; the server requests dimensions=1024 via the OpenAI MRL parameter to match the rest of the stackbge-m3, native 1024 dimensions, runs locally for freeAll three are normalized to the same vector dimension (MCP_EMBEDDING_DIMENSION, default 1024), but they are not interchangeable: each model has its own embedding space. Matching dimensions do not make cosine similarity safe across different models — that is why the server tags every memory with its embedding_model and refuses to mix them at recall time.
What auto mode means in practice:
embedding_model they were created withembedding_model does not match the current query model and falls back to text matching for those recordsThis avoids the dangerous case where provider fallback returns confident but incorrect semantic matches.
If you change provider or model intentionally, treat it as a migration:
You can increase the dimension via MCP_EMBEDDING_DIMENSION for higher accuracy (for example 3072 with text-embedding-3-large), but any dimension or model change requires re-indexing and re-embedding.
If you set MCP_EMBEDDING_MODE=local-only, hosted providers are skipped entirely and only Ollama is used for embeddings.
auto mode without silent corruption of semantic recallagent-memory-mcp statsSee Installation Options for details and config location.
This builds the binary, creates a .env file, and installs a launchd service that auto-starts on login.
Manual control:
The server tries Jina → OpenAI → Ollama in auto mode and stops at the first available one. If none is reachable, embeddings (and therefore semantic recall) are disabled.
JINA_API_KEY, OPENAI_API_KEY, or run Ollama with bge-m3 pulled (ollama pull bge-m3)MCP_EMBEDDING_MODE=local-only only Ollama is consulted; verify OLLAMA_BASE_URL (default http://localhost:11434) respondsCLI agent-memory-mcp store … without an embedder still saves the memory but skips the vector — the record will only be retrievable via text/keyword search until you run agent-memory-mcp reembed.
The RAG index and stored memories are tagged with the embedding model that produced them. If you switch provider or model, retrieval refuses to mix vector spaces:
18080 takenAnother agent-memory-mcp (or unrelated service) holds the port:
If two instances were started, stop one (brew services stop agent-memory-mcp or kill <pid>) or change MCP_HTTP_PORT.
brew services start agent-memory-mcp does not start the daemonMost common causes:
brew uninstall --cask agent-memory-mcp && brew install ipiton/tap/agent-memory-mcpcat $(brew --prefix)/etc/agent-memory-mcp/config.envtail -f $(brew --prefix)/var/log/agent-memory-mcp/mcp-diagnostics.logAfter agent-memory-mcp setup, restart Claude Code (hooks load at process start). Verify the merge:
If you upgraded via brew upgrade, re-run agent-memory-mcp setup --force so the hook command points to the new binary path. See docs/HOOKS.md.
In HTTP mode the server refuses non-loopback binds without MCP_HTTP_AUTH_TOKEN. Either:
MCP_HTTP_AUTH_TOKEN=$(openssl rand -hex 32)) — recommendedMCP_HTTP_INSECURE_ALLOW_UNAUTHENTICATED=trueagent-memory-mcp project-bank canonical_overview and … review_queue to spot raw session summaries that should be promoted or marked outdatedMCP_STEWARD_MODE=scheduled triggers periodic dedup/stale scansMCP_CHECKPOINT_DEDUP_THRESHOLD, MCP_CHECKPOINT_DEDUP_WINDOW)agent-memory-mcp export > backup.json (see docs/BACKUP_RESTORE.md)recall_multihop returns emptyThe multi-hop graph walks the (subj, rel, obj) triple corpus. It's empty until you either:
MCP_TRIPLE_EXTRACTOR_ENABLED=true and write new memories (extraction is async on every store)agent-memory-mcp index-triples (idempotent, supports --resume)Both paths require MCP_TRIPLE_EXTRACTOR_* (see Key variables) — extraction calls an OpenAI-compatible /chat/completions endpoint.
Changes are picked up within ~30s. Force an immediate reload:
Note: HTTP host/port require a full restart (brew services restart agent-memory-mcp). Only RAG-related settings hot-reload.
For repo layout, code style, and PR conventions see docs/CONTRIBUTING.md.
MIT