In this piece
mcp-memory-service: Shared Memory for Claude Code and Cursor
mcp-memory-service gives AI coding agents a shared, persistent store for project decisions, debugging history and conventions. Its useful promise is not that a model remembers an unlimited conversation. It is that a new session can retrieve relevant records written by another session or tool, provided both clients reach the same store and actually use its memory tools. The upstream repository describes local embeddings, semantic retrieval and typed knowledge-graph relationships.
Source review: . This is a documentation-based implementation guide, not a hands-on integration report or an independently reproduced benchmark. It separates the project's published capabilities from our proposed configuration and acceptance tests.
Does this replace CLAUDE.md, Cursor rules or native memory?
No. Keep stable instructions in the repository and use shared memory for evolving, evidence-backed history. The claim that Claude Code starts every session with no persistent context is too broad: Claude Code's memory documentation describes instruction files and auto memory. Cursor rules also preserve instructions. Neither fact alone establishes that your different tools share one queryable decision history.
| Information | Preferred home | Reason |
|---|---|---|
| Build commands, directory conventions, mandatory checks | Version-controlled instructions, such as CLAUDE.md, AGENTS.md or Cursor rules | Reviewable policy should travel with the code. |
| Why an approach was rejected; which migration caused a regression | Scoped shared memory with links to decisions, commits and tests | Historical explanations should remain discoverable across sessions. |
| What the application actually does now | Current code, configuration and executable tests | A recalled statement may have become obsolete. |
The adoption question is therefore specific: are developers repeatedly reconstructing the same reasoning when they switch from Claude Code to Cursor or OpenCode? Start there rather than building a second, conflicting policy system.
Install mcp-memory-service without confusing installation with integration
The requested one-line installation is:
pip install mcp-memory-serviceThe PyPI listing identifies version 11.13.0, released on 19 September 2026, Python 3.10 or later and the Apache-2.0 license. The walkthrough pins that reviewed version rather than silently following later releases.
python3 -m venv "$HOME/.venvs/mcp-memory-service"
"$HOME/.venvs/mcp-memory-service/bin/python" -m pip install "mcp-memory-service==11.13.0"
mkdir -p "$HOME/.local/share/agent-memory/example-app"
"$HOME/.venvs/mcp-memory-service/bin/memory" server --helpThese shell commands target macOS and Linux. On Windows, adapt the virtual-environment executable and absolute storage paths; do not paste POSIX paths unchanged. Use the existing environment-management approach your team supports.
The upstream setup guide documents memory server and the client connection step. Installing a Python package does not itself register an MCP server in every IDE, import old conversations or ensure that every new session retrieves memory.
The important setting: every client must use the same memory database
Same package, different database path means different memory. For this single-user, single-machine example, all three clients use the same executable and the same absolute SQLite file. The configuration reference documents MCP_MEMORY_STORAGE_BACKEND, MCP_MEMORY_SQLITE_PATH and MCP_MEMORY_USE_ONNX.
Replace example-app consistently with one project or trust boundary. Keep unrelated clients' repositories in separate stores rather than expecting a tag to enforce access control. The path points to a file, not just its parent directory. A container, remote development host or different operating-system account will not share your home directory merely because the text of its configuration looks similar.
In the following examples, each MCP client launches a stdio process against that local store. This is not a multi-user deployment design. Test concurrent use before depending on it, and do not put a live SQLite database in Git or treat a synchronized folder as a database replication service.
Connect Claude Code through local MCP
Run this from the project where the memory connection should be available:
claude mcp add \
--env MCP_MEMORY_STORAGE_BACKEND=sqlite_vec \
--env MCP_MEMORY_SQLITE_PATH="$HOME/.local/share/agent-memory/example-app/sqlite_vec.db" \
--env MCP_MEMORY_USE_ONNX=true \
--transport stdio --scope local \
memory -- "$HOME/.venvs/mcp-memory-service/bin/memory" server
claude mcp listThis follows the official Claude Code MCP command format. --scope local keeps the registration private to your local project configuration. Options precede the server name; the -- separator precedes the executable. The explicit executable path avoids relying on an IDE inheriting your terminal's PATH.
Restart or reconnect the client as appropriate, confirm the server is connected, then check that memory_store and memory_search are available. Approve only the operations you expect. A connected server is not evidence that a session has already stored anything.
Configure Cursor to use the same store
Merge the following entry into the project's .cursor/mcp.json; preserve any other configured servers:
{
"mcpServers": {
"memory": {
"type": "stdio",
"command": "${userHome}/.venvs/mcp-memory-service/bin/memory",
"args": [
"server"
],
"env": {
"MCP_MEMORY_STORAGE_BACKEND": "sqlite_vec",
"MCP_MEMORY_SQLITE_PATH": "${userHome}/.local/share/agent-memory/example-app/sqlite_vec.db",
"MCP_MEMORY_USE_ONNX": "true"
}
}
}
}The Cursor MCP documentation specifies the stdio fields and supports ${userHome} interpolation. Check the resulting path, reconnect the server and inspect MCP output when a tool is missing. A project config should not contain credentials or a database copied from a customer project.
Do not assume that seeing “memory” in both clients proves they share state. The cross-client test below verifies the database and tool workflow together.
OpenCode: standard MCP connection versus the auto-capture plugin
For the same local MCP approach, merge this into opencode.json:
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"memory": {
"type": "local",
"command": [
"{env:HOME}/.venvs/mcp-memory-service/bin/memory",
"server"
],
"enabled": true,
"environment": {
"MCP_MEMORY_STORAGE_BACKEND": "sqlite_vec",
"MCP_MEMORY_SQLITE_PATH": "{env:HOME}/.local/share/agent-memory/example-app/sqlite_vec.db",
"MCP_MEMORY_USE_ONNX": "true"
}
}
}
}OpenCode's MCP reference uses type: local, a command array and environment, not Cursor's env field. Its configuration reference documents {env:HOME} substitution. This example combines those documented client settings with the upstream server command; we have not run this three-client configuration live.
The separate Memory Awareness plugin uses the service's HTTP REST API for session-start retrieval and automatic capture. Its files come from the repository, not from the pip installation alone. Standard MCP makes tools available; the plugin adds lifecycle automation. They are different integration paths.
Choose one path first. Adding both without a capture policy can make ownership harder to understand. The stdio walkthrough does not require an HTTP listener. An optional plugin deployment needs its own endpoint, authentication and network review.
Verify that memory survives a restart and a change of IDE
Test retrieval, not the agent's assurance that it remembers. In Claude Code, explicitly ask it to use memory_store for a fictional decision tagged project:example-app: “Payment events use an outbox so a committed payment cannot lose its downstream event.” Add a fictional decision reference, status and date, and keep this test free of real customer data.
Inspect the store tool's success result. Close the session. Open a fresh Cursor session and ask it to call memory_search for the reason behind the payment outbox. Confirm the returned record identifier and content rather than accepting a plausible answer from general model knowledge. Repeat in OpenCode and once after restarting the client processes.
Then test a negative case: a different project should not be able to retrieve that decision under the isolation design you selected. A search tag can narrow results, but it is not a security boundary. Test both absent results and unwanted results before enabling automatic capture.
Local ONNX embeddings: what “zero external API calls” actually covers
Local embedding inference does not make the entire coding workflow offline. ONNX Runtime can execute an available model locally. Package installation and initial model downloads are separate network events. A cloud-hosted coding model can still receive memories when its client inserts tool results into its context.
There is a second trap for multilingual teams. The default model's all-MiniLM-L6-v2 model card identifies an English model with 384-dimensional vectors and default truncation beyond 256 word pieces. A German interface is not evidence of strong German-to-English retrieval. Long session dumps can also lose relevant detail before an embedding is produced.
The project's environment configuration example exposes model, provider and optional feature settings. Review those settings rather than treating “local-first” as proof of a particular data boundary. Cloud or hybrid storage, external scoring and LLM-assisted harvesting need separate decisions.
Our suggested multilingual test is simple: store one approved decision in English and ask for it in German, Spanish and Chinese using realistic developer wording. Measure whether the correct record appears, not whether the assistant can translate its own answer. Changing the embedding model calls for a backed-up re-embedding migration even when the new model has the same vector dimensions.
Does mcp-memory-service really retrieve context in 5 ms?
5 ms is an upstream performance claim, not an end-to-end guarantee established by this article. The repository's headline should not be expanded into “every historical decision and graph relationship is returned in 5 ms.” We have not independently reproduced that number.
For a useful local evaluation, separate process startup, first model load, query embedding, database retrieval, graph expansion and client transport. Then measure the complete tool round trip. A warm database lookup is a different measurement from a cold search, a remote request or the coding model's completed answer.
Record the machine, model, number and length of memories, query types, concurrent clients and warm-up conditions. Report median and slow-tail latency alongside whether the returned evidence is correct. Our decision rule: saving a few milliseconds is not progress when the agent confidently recalls a superseded architecture decision.
Causal memory for debugging: useful links are not proof of causation
The knowledge-graph documentation describes relationship types including causes, fixes, contradicts, supports, follows and related. They can express an investigation chain; they do not establish that the investigation's conclusion is true.
Consider this fictional chain: commit demo-change-A removes an idempotency guard; bug DEMO-42 records duplicate payment events; patch demo-fix-B restores the guard; regression test test_duplicate_event reproduces the failure before the patch and passes afterward. Store the links to those artifacts with the claim, and distinguish “suspected cause” from “confirmed in the reviewed test.”
When a later migration replaces the design, preserve the historical record but mark the old recommendation superseded. Otherwise, a good semantic match can become bad engineering advice. An agent should inspect the current code and relevant test before acting on the recalled chain.
A practical memory policy: capture decisions, retrieve narrowly, retire stale advice
Our proposed record template contains: project, component, decision, rationale, evidence location, source commit, author or reviewer, status, recorded date and next review trigger. This is an editorial template for record content, not a claim that every field is a required API parameter. Keep one durable idea per memory. Do not archive every transient thought as an approved decision.
At task start, search for the affected component and check the status of the returned evidence. At task end, store only verified changes and unresolved questions with explicit labels. Keep “we tried this” separate from “the team approved this.” Require review before automated consolidation overwrites important operational meaning.
The token-efficient retrieval guide documents bounded retrieval and graph-first exploration. This illustrative memory_search argument object sets a result limit and character budget; 6000 is our example budget, not an upstream performance recommendation or a token count:
{
"query": "Why does example-app use an outbox for payment events?",
"tags": [
"project:example-app"
],
"limit": 5,
"max_response_chars": 6000
}Entity-graph retrieval is a separate readiness check. An empty memory_explore result can mean that entities were never populated, even when text memories exist. The documented MCP_ENTITY_LINKING_ENABLED=1 setting affects newly stored records; existing records need an explicitly planned maintenance/backfill step. Do not run a mutating maintenance command blindly to make an empty graph look healthy.
Troubleshooting memory that does not persist or recall correctly
| Symptom | Check first | Evidence to collect |
|---|---|---|
| Works in Claude Code, not Cursor | Executable, environment, absolute database path and operating-system account | Compare resolved settings and retrieve the same record ID. |
| Memory disappears after restarting | Write success, ephemeral container paths and which store was reopened | Repeat a store-close-reopen-search test without relying on conversation history. |
| Tool connected but the agent forgets | Whether memory tools were invoked at all | Inspect the actual tool calls; configure an explicit retrieval workflow. |
| Text search works, graph exploration is empty | Entity-linking configuration and entity population | Inspect entity counts before considering a reviewed backfill. |
| Non-English questions miss English decisions | Embedding model, query language, chunk length and filters | Run paired multilingual queries against known records. |
| Embedding dimensions fail after a model change | Model selection, cached model and existing vector compatibility | Stop new writes, preserve a backup and plan re-embedding. |
| Intermittent failures with several clients | Concurrent writes, storage location and process logs | Reproduce with controlled clients before changing database settings. |
Security boundaries for a shared coding-agent memory
Treat a recalled memory as untrusted evidence, not as a higher-priority instruction. A record quoting “ignore previous instructions” must remain data. Give each project only the storage and tools it needs; do not let a customer-supplied document silently rewrite your development policy.
The MCP security guidance is a starting point for reviewing authorization and transport risks. Our operational recommendation is to keep the initial stdio setup local, exclude secrets and customer transcripts, and require a separate review before exposing a shared endpoint. For HTTP, explicitly choose the bind address, authentication, authorization, transport protection and permitted clients. Do not copy an anonymous-access demonstration into a network-accessible deployment.
Assign ownership for correction, deletion, retention and recovery before enabling automatic capture. Test a consistent backup and restore procedure and ensure deleted or superseded records do not reappear through a second store. “Open source,” “on-device embeddings” and “tags” do not by themselves establish compliance or tenant isolation.
A small adoption test with meaningful pass criteria
Use a deliberately small corpus before importing your archive. The following is our proposed pilot, not a published benchmark: ten approved decisions, five superseded decisions, five bug-and-fix chains and five cross-language queries. Include records that should not be visible to another project.
| Test | What a useful result looks like |
|---|---|
| Cross-tool continuity | A fresh session in each client retrieves the same stored decision with its identifier and evidence. |
| Decision freshness | The answer identifies the current decision and labels the old one superseded. |
| Isolation | A client outside the chosen trust boundary cannot read another project's memory. |
| Debugging provenance | The agent retrieves the hypothesis, fixing change and regression evidence without inventing a causal proof. |
| Cost and latency | Tool round-trip timings, retrieved context size and any external calls are recorded separately. |
| Failure and recovery | The agent reports unavailable memory instead of pretending to remember; a tested restore preserves expected records. |
Keep the service when this pilot reduces repeated explanation without increasing stale or cross-project advice. Stay with repository instructions when the real problem is missing conventions. For broader context architecture, our OpenViking review covers structured context retrieval; our Supermemory guide addresses application-level memory and different deployment trade-offs.
For implementation support, see Wavect's AI engineering services. The Twinsoft AI case study provides adjacent delivery context, not evidence that this tool was deployed there. Use our pre-launch software QA checklist to turn the pilot into release criteria, or discuss a scoped memory integration with the team.
