semantic-memory-mcp
semantic-memory-mcp is a local-first Model Context Protocol server for the
semantic-memory Rust library. It gives MCP clients
persistent semantic search, witnessed retrieval, durable receipts, governed
authority decisions, graph and lifecycle tools, and optional claim-ledger trust
enrichment over a store that remains on the operator's machine.
The default build uses SQLite/FTS5, the usearch vector backend, and an in-process Candle embedder. Ollama is an alternative embedder. The first Candle run downloads the configured Hugging Face model; after that, normal search and storage do not require a hosted database or API key.
Local-first storage. A hosted database is not required. Candle may download model artifacts from Hugging Face when its cache is empty; Ollama uses the configured endpoint. Optional integrations can have their own network paths, so review your feature/profile and endpoint configuration before sending private data.
Status at a glance
The current Rust source and Cargo.toml are authoritative. In particular:
- The binary serves MCP over stdio.
--http-portcan add a loopback-only warm HTTP surface;--http-onlydisables stdio. leanandstandardare aliases in behavior and expose four governed, read-only tools.stableexposes a bounded 10-tool read-only surface.agentexposes a bounded 12-tool surface; its only write is governed fact capture (sm_add_fact).fullexposes every tool compiled into that build. Its size can change with feature selection, so this README does not freeze a full-profile tool count.- MCP
tools/listis the source of truth for the tools available in a specific binary, profile, and build. - The
fullCargo feature is the default and is currently an alias forsearch; it is unrelated to the runtime--tool-profile fullswitch.
Install
Option 1: npx (recommended)
Run without installing:
npx -y @recursiveintell/semantic-memory-mcp --memory-dir ~/.local/share/semantic-memory --tool-profile agent
Or add to your MCP client config:
{
"mcpServers": {
"semantic-memory": {
"command": "npx",
"args": ["-y", "@recursiveintell/semantic-memory-mcp", "--memory-dir", "/absolute/path/to/semantic-memory", "--tool-profile", "agent"]
}
}
}
Option 2: Cargo install
Install the non-yanked 0.5.8 release from crates.io. This README describes the checked-in source; inspect the installed binary's --help when comparing release behavior with newer main-branch changes:
cargo install semantic-memory-mcp --locked --version '=0.5.8'
Then add to your MCP client config:
{
"mcpServers": {
"semantic-memory": {
"command": "semantic-memory-mcp",
"args": ["--memory-dir", "/absolute/path/to/semantic-memory", "--tool-profile", "agent"]
}
}
}
Option 3: Build from source
From a checkout with the sibling path dependencies present:
cargo build --release
./target/release/semantic-memory-mcp \
--memory-dir "$HOME/.local/share/semantic-memory" \
--tool-profile agent
Option 4: Docker
docker run -i --rm \
-v "$HOME/.local/share/semantic-memory:/data" \
ghcr.io/recursiveintell/semantic-memory-mcp:latest \
--memory-dir /data --tool-profile agent
Docker compose:
services:
semantic-memory-mcp:
image: ghcr.io/recursiveintell/semantic-memory-mcp:latest
volumes:
- ~/.local/share/semantic-memory:/data
command: --memory-dir /data --tool-profile agent
stdin_open: true
The Candle model defaults to nomic-ai/nomic-embed-text-v1.5 through the
nomic-embed-text alias. To use Ollama instead:
ollama pull nomic-embed-text
semantic-memory-mcp \
--memory-dir "$HOME/.local/share/semantic-memory" \
--embedder ollama \
--embedding-url http://localhost:11434 \
--tool-profile agent
--memory-dir names a directory, not a database file. The store creates
memory.db and its index sidecars below that directory.
CLI reference
The options below match src/main.rs and the generated --help surface.
The typed profile manifest in src/profile.rs supplies profile names, bounded
allowlists, effect classes, and HTTP effect capabilities. Use tools/list when
automating against a deployed binary.
Tool profiles
lean and standard
These autonomous profiles expose exactly:
sm_search_witnessedsm_replay_searchsm_decide_assertion_authoritysm_decide_action_authority
They do not expose raw search, mutation, maintenance, import, or administration.
stable
This bounded read-only profile exposes ten tools: ordinary and witnessed search, store statistics and namespace discovery, direct fact/neighbor lookup, graph paths, conversation retrieval, and separate assertion/action authority decisions. It excludes writes, imports, lifecycle administration, and maintenance.
agent
The daily coding-agent profile exposes these 12 tools:
sm_add_fact sm_decide_action_authority
sm_decide_assertion_authority
sm_get_fact sm_get_fact_neighbors
sm_get_search_receipt sm_graph_path
sm_list_namespaces sm_replay_search
sm_search_conversations sm_search_witnessed
sm_stats
sm_add_fact is the only write. It remains governed and fails closed without a
trusted authority issuer. The profile excludes deletion, raw/unwitnessed
search, imports, lifecycle administration, reconciliation, vacuuming, and
re-embedding. Use lean for the smallest autonomous recall/authority surface;
use full only for explicitly approved operator work.
Enable supported local fact capture
Some earlier deployments started without an in-process operator issuer. That
fail-closed configuration can look like an overly aggressive security policy:
even ordinary local sm_add_fact requests are rejected with no trusted issuer
instead of being appended. The supported recovery is not to remove all
admission controls. Start the MCP service with a private operator-token file,
which creates an in-process issuer only for its local governed capture path:
install -d -m 700 "$HOME/.config/semantic-memory"
umask 077
openssl rand -hex 32 > "$HOME/.config/semantic-memory/operator-authority.token"
semantic-memory-mcp \
--memory-dir "$HOME/.local/share/semantic-memory" \
--operator-authority-token-file "$HOME/.config/semantic-memory/operator-authority.token" \
--tool-profile agent
Use a non-empty token without whitespace and keep the file readable only by the
service owner. The token is read at startup and consumed to construct the
in-process issuer; it is not sent as an MCP tool parameter. When the process
starts, require the operator authority: enabled log line, then append one
ordinary fact with a non-blank idempotency key and read it back by ID. Removing
the flag and restarting is the rollback: supported writes again fail closed.
With the issuer present, ordinary public or internal durable facts without
source or evidence references and without entity extraction can be appended
through sm_add_fact and return a governed receipt. This does not admit
unresolved provenance, confidential or restricted data, ephemeral_inference,
entity extraction, deletion, or other operator tools. Keep the MCP process on
its normal local/loopback transport boundary and retain transport authentication
where applicable; write admission is not network-access policy.
full
This is the operator profile. It exposes every tool registered by the compiled
router, including mutating, destructive, experimental, and maintenance tools.
Tool annotations describe read-only, idempotent, and destructive intent, but an
MCP client must still enforce its own approval policy. Inspect tools/list
before granting this profile to an autonomous process.
Tool Reference
Tools exposed by the full router, grouped by function. lean/standard,
stable, and agent use the bounded manifests above; full exposes the
compiled router. Run tools/list against the deployed binary before automating
against any profile.
Search & Retrieval
| sm_route_query | Profile a query and get adaptive routing decision | full |
| sm_get_search_receipt | Load a durable search receipt by ID | agent+ |
| sm_replay_search | Replay a search using stored (opt-in) inputs | lean+ |
| sm_replay_search_receipt | Replay with caller-supplied query — compares results | full |
| sm_benchmark_trust | Benchmark trust quality distribution across searches | full |
| sm_get_routing_policy | Return current RL routing policy weights | full |
Facts & Memory
Knowledge Graph
Trust & Claims
Lifecycle & Maintenance
Import & Export
Utility Parsers
HTTP Sidecar Endpoints
With --http-port, the loopback server exposes:
GET /health — health check (all profiles)
GET /verify-integrity — integrity check across all surfaces
POST /search — hybrid search
POST /search-routed — adaptive search with routing
POST /rerank — exact f32 cosine rerank
POST /stats — store statistics
POST /add — add fact
POST /record-outcome — RL feedback
POST /discord — discord (second-order) search
POST /maintenance/check — maintenance health
POST /maintenance/vacuum — SQLite vacuum
POST /maintenance/reembed — re-embed all
POST /maintenance/reconcile — reconcile integrity
POST /maintenance/rebuild-hnsw — rebuild HNSW index
POST /maintenance/compact-hnsw — compact HNSW index
Lean/standard/agent profiles expose only /health. Full exposes all routes. All non-health endpoints require Bearer token auth.
Witnessed retrieval, replay, and authority
sm_search_witnessed is the safe autonomous retrieval surface. It bypasses the
cache, requires a durable receipt, defaults to current state, and only returns
persisted facts whose source provenance can be hydrated honestly. Its
retrieval_mode is hybrid, fts_only, or vector_only.
V35 complete replay is privacy-sensitive and opt-in. The default
replay_mode: "no_replay" stores receipt digests and result evidence without
retaining the query/filter inputs needed for complete replay. Set
replay_mode: "store_inputs" on witnessed search only when that retention is
acceptable, then call sm_replay_search with the original receipt ID.
sm_replay_search_receipt remains a full-profile alternative that requires the
caller to resupply the query and filters.
Recall authority never implies permission to assert a result as true or to act
on it. sm_decide_assertion_authority and sm_decide_action_authority make
separate, fixed-purpose decisions from caller, subject, audience, namespace
scope, and an optional delegation/elevation lease. They return a typed decision
receipt and intentionally omit memory content; neither tool performs the
assertion or action.
Trust architecture
The semantic store and the trust ledger have different jobs:
memory.db, FTS5, and vector/sparse indexes hold searchable memory.- Before first compaction,
claim_ledger.jsonlis the hash-chained trust authority. - After compaction, an atomically selected, digest-verified snapshot plus retained JSONL tail represents the same ledger history. The snapshot is a checkpoint, never an independent truth store.
- A process-local
ClaimTrustIndexis derived from the verified snapshot and tail (or the legacy JSONL) at startup. It is an acceleration structure and is never persisted as authority.
Search trust enrichment uses six quality states:
sm_search_proof_debt exposes debt-aware retrieval and a budget gate;
sm_benchmark_trust reports the distribution of the six states. Proof debt is
an obligation signal, not a replacement for source inspection.
If the legacy ledger, active manifest, snapshot, retained tail, or compaction receipt fails verification, the server disables claim trust enrichment and refuses ledger append/compaction. Ordinary semantic storage and search remain available. Results report trust enrichment as disabled where that path can surface it; corruption does not promote an unverified ledger or erase the semantic database.
Claim-ledger compaction
sm_compact_claim_ledger is a destructive-annotated, full-profile,
claim-integration tool. It defaults to a dry run:
{
"dry_run": true,
"max_entries": 10000,
"max_bytes": 16777216,
"retain_tail_entries": 256,
"max_backups": 3
}
No publication occurs unless a threshold is exceeded and dry_run is
explicitly false. A real compaction writes and fsyncs a temporary generation
containing snapshot.json, tail.jsonl, and receipt.json, renames that
generation into place, then atomically replaces
claim_ledger.active_compaction.json. That manifest rename is the publication
boundary: startup ignores incomplete temporary generations and accepts only the
manifest-selected generation after digest verification.
Search pipeline
The production search path is implemented by semantic-memory:
- Embed or tokenize the query.
- Retrieve FTS5/BM25 and usearch vector candidates.
- When configured and represented by the active embedder, retrieve V36 sparse dot-product candidates from SQLite.
- Fuse ranks with RRF and apply temporal/provenance policy.
- Filter superseded heads for the normal MCP search surfaces.
- Persist receipts and, for witnessed search, hydrate source provenance, authority state, and optional claim-ledger trust.
V36 sparse storage and ranking are inherited from semantic-memory; this MCP
crate does not define a separate sparse feature or CLI switch. The default
SearchConfig has sparse_weight = 0, so sparse retrieval is dormant unless a
library-level configuration enables it. The active embedder must also provide a
sparse representation, or explicit dense-to-sparse derivation must be enabled.
Advanced full-profile tools can additionally route queries, explain ranking, traverse stored graph edges, detect contradictions, run factor-graph analysis, inspect topology/communities, and perform lifecycle or maintenance work. Those surfaces are not implied by the four-tool autonomous profile.
Cargo features
These are the exact local features declared in Cargo.toml:
cargo build --no-default-features --features search compiles the composed
search feature without setting the local full cfg. It is not a minimal tool
surface. Builds assembled from narrower individual features are feature-gated
development configurations, not the documented production default.
Production-wired and experimental surfaces
Production-wired in the default build:
- stdio MCP, runtime tool-profile filtering, SQLite/FTS5, usearch, Candle and Ollama embedders;
- witnessed retrieval, V35 opt-in replay, governed assertion/action decisions, receipts, graph storage/traversal, claim-ledger verification and compaction;
- the composed
semantic-memoryrouting, provenance, temporal, decoder, lifecycle, orchestration, parser, and admin capabilities exposed by the full router.
Opt-in, feature-gated, or operationally experimental:
- the loopback HTTP server is an auxiliary API, not MCP and not authenticated;
mockembeddings are for tests;hnswis an optional alternative to the default usearch backend;- TurboQuant requires
--turbo-quantand the localfullcfg wiring; - LLM reranking, entity extraction, and community summaries call a local Ollama service and are opt-in per operation;
- V36 sparse retrieval is inherited and disabled by the default search weight;
- broad maintenance, deletion, import, training-feedback, and lifecycle tools are operator-only even when compiled.
HTTP sidecar
With --http-port, the process binds only to 127.0.0.1. Current routes are:
GET /health
GET /verify-integrity
POST /search
POST /search-routed
POST /rerank
POST /stats
POST /add
POST /record-outcome
POST /discord
POST /maintenance/check
POST /maintenance/vacuum
POST /maintenance/reembed
POST /maintenance/reconcile
POST /maintenance/rebuild-hnsw
POST /maintenance/compact-hnsw
The HTTP sidecar applies the selected profile below transport. Lean, standard,
and agent expose only /health; the explicit full operator profile exposes the
authenticated non-health surface. All non-health requests require a valid bearer
token. Mutation handlers without a trusted authority issuer fail closed. All
requests still require loopback Host/Origin validation.
Agent integrations
First-class packages live in integrations/:
- Hermes plugin — validates inputs and invokes the
current
hermes mcp add/list/test/configureCLI workflow without reimplementing any semantic-memory tools. - Claude Code plugin — manifest, plugin-scoped MCP launcher, semantic-memory skill, and useful commands.
- Codex integration — open Agent Skill layout plus stdio MCP installation/config examples.
- Install/test matrix — side-by-side setup and smoke checks.
Security and privacy
- Memory contents, sources, conversation messages, replay inputs, and claim evidence may be sensitive. Protect the entire memory directory with OS-level permissions and backups appropriate to its data classification.
- Candle's model download contacts Hugging Face on first use. Ollama mode sends text to the configured Ollama URL; a remote URL moves content off-host.
store_inputsretains query/filter material for complete replay. It is off by default for privacy.- The claim ledger is tamper-evident, not encrypted. Verification detects corruption; it does not stop a party with filesystem access from reading it.
- The
fullprofile and HTTP maintenance routes include mutation, permanent deletion, model-feedback, import, vacuum, and rebuild operations. Grant them only to an operator context with explicit approval controls. agentis the recommended profile for trusted coding agents. It is read-only until a trusted authority issuer is injected. Useleanfor autonomous read-only recall and authority decisions.- Do not place secrets in facts, sources, metadata, replay inputs, plugin config, or command-line arguments. Process lists and logs may expose arguments.
Integration quick starts
Hermes Agent
Use the current CLI rather than hand-editing legacy YAML as the primary path:
hermes mcp add semantic_memory \
--command semantic-memory-mcp \
--args --memory-dir "$HOME/.local/share/semantic-memory" --tool-profile agent
hermes mcp list
hermes mcp test semantic_memory
hermes mcp configure semantic_memory
--args consumes the remaining arguments, so it must come last. The configure
step is interactive and controls which server-native tools Hermes exposes. The
packaged Hermes plugin provides guarded wrappers for these commands; see its
README.
Claude Code
Test the local plugin directly:
SEMANTIC_MEMORY_MCP_BIN="$(command -v semantic-memory-mcp)" \
SEMANTIC_MEMORY_DIR="$HOME/.local/share/semantic-memory" \
SEMANTIC_MEMORY_TOOL_PROFILE=agent \
claude --plugin-dir ./integrations/claude-plugin
Inside Claude Code, run /mcp, then
/semantic-memory:semantic-memory-status. Use claude --debug --plugin-dir ./integrations/claude-plugin for startup diagnostics and claude plugin validate ./integrations/claude-plugin when supported by the installed Claude
Code version.
Codex
Install the stdio server with the CLI:
codex mcp add semantic_memory -- \
semantic-memory-mcp \
--memory-dir "$HOME/.local/share/semantic-memory" \
--tool-profile agent
codex mcp list
Copy or symlink integrations/codex/.agents/skills/semantic-memory into the
repository's .agents/skills/, or keep the supplied structure at the project
root. Codex discovers skills from .agents/skills between the working directory
and repository root. See the Codex integration README for a TOML alternative.
Development and validation
cargo fmt --check
cargo check
cargo test
Integration asset validation is read-only:
python3 integrations/tests/validate_integrations.py
License
Apache-2.0. See LICENSE.