Backend-agnostic, multi-tenant MCP memory server
Project description
memcp
Backend-agnostic, multi-tenant MCP memory server. AI clients connect and get persistent long-term memory over streamable HTTP.
Currently wraps mem0 as the first backend. Designed for backend agnosticism — additional backends (Cognee, etc.) planned.
Features
- Semantic search, list, add, update, delete memories
- Flat scope-based filtering (agent_id, run_id)
- Bearer token auth gate (ASGI middleware)
- Stateless HTTP transport — safe behind reverse proxies
- In-memory backend for dev/testing (no external deps)
Getting Started
1. Install and run
pip install memcp-server
MEMCP_BACKEND=in_memory python -m memcp
Or from source:
git clone https://github.com/Jartan-LLC/memcp.git
cd memcp
pip install -e ".[dev]"
MEMCP_BACKEND=in_memory python -m memcp
The server starts on http://localhost:8080. No external dependencies needed — the in-memory backend stores everything in-process (lost on restart).
2. Connect from Claude Code
Add to your MCP settings (Claude Code → Settings → MCP Servers):
{
"mcpServers": {
"memcp": {
"type": "streamable-http",
"url": "http://localhost:8080/mcp"
}
}
}
For authenticated deployments, add the headers field:
{
"mcpServers": {
"memcp": {
"type": "streamable-http",
"url": "https://your-host:8080/mcp",
"headers": {
"Authorization": "Bearer YOUR_TOKEN"
}
}
}
}
3. Try it
Ask Claude to remember something:
"Remember that I prefer Python 3.12 and use ruff for linting."
In a new conversation, ask:
"What linter do I use?"
Claude searches memory automatically and uses the stored context.
Configuration
Requirements
- Python 3.12+
- A running mem0 self-hosted instance (not needed for
MEMCP_BACKEND=in_memory)
Environment Variables
| Variable | Required | Description |
|---|---|---|
MEMCP_BACKEND |
No | Backend: mem0 (default) or in_memory |
MEM0_API_BASE |
mem0 | Base URL of your mem0 REST API |
MEM0_API_KEY |
mem0 | API key for the mem0 server |
MEMCP_AUTH_TOKENS |
No | Token-to-user mapping: tok1:alice,tok2:bob (unset or empty = unauthenticated) |
MEMCP_HOST |
No | Bind address (default: 0.0.0.0) |
MEMCP_PORT |
No | Bind port (default: 8080) |
MEMCP_LOG_LEVEL |
No | Log level (default: INFO) |
MEMCP_LOG_FORMAT |
No | Log format: json or plain (default: json) |
MCP Tools
Universal (always available)
| Tool | Description |
|---|---|
add_memory |
Store a fact/preference/decision. Extracts facts by default (may store nothing); infer=false for verbatim. Bulk: use import_memories |
search_memory |
Semantic search, ranked by relevance. threshold filters by minimum similarity (0-1). For browsing: list_memories |
delete_memory |
Delete one memory by ID. Confirm with user first |
delete_all_memories |
Bulk-delete by scope (e.g. agent_id, run_id), not content. Requires at least one scope key. Confirm first |
memory_status |
Returns server version, backend type, capabilities, valid scope keys. No memory content |
Optional (backend-dependent)
| Tool | Description |
|---|---|
get_memory |
Fetch one memory by ID. Returns full content, scope, and metadata |
update_memory |
Full-replace a memory's content (not a patch). Scope immutable — to change scope, add new + delete old |
list_memories |
Browse memories, optionally filtered by scope. Unranked, paginated. For semantic queries: search_memory |
export_memories |
Export memories as JSON (max 10k, truncates with flag). For backup/migration. Output compatible with import_memories (requires list_memories) |
import_memories |
Batch-import from JSON. Dedup via exact content match (scope-independent). on_conflict: skip, overwrite, duplicate (requires list_memories; overwrite requires update_memory) |
memory_history |
Change log for a memory: timestamps and previous/current content per create/update event |
memory_entities |
Knowledge graph: entities and relationships. Not a search tool — use search_memory for topics |
Docker
cp .env.example .env # fill in MEM0_API_BASE + MEM0_API_KEY
docker compose up -d
Development
ruff check memcp/ tests/
ruff format --check memcp/ tests/
pyright memcp/
python -c "import memcp"
pytest -x
Known Limitations
mem0 backend (upstream constraints):
- Nested boolean filters (AND/OR/NOT) return 502 — use flat scope keys
- List endpoint does not paginate server-side — full dataset loaded per request
- List endpoint does not filter by metadata
- Entities endpoint does not filter by user — post-filtered client-side
- Single-ID endpoints are globally scoped — ownership verified via fetch-then-verify
In-memory backend:
- Loses all data on restart
- Search uses keyword matching, not semantic/vector similarity
General:
- No date/time-based filtering on search or list
- No rate limiting (configure at reverse proxy layer)
delete_all_memoriesdeletes by scope structure, not content match
Status
v0.1.0 — API may change before v1.0. Suitable for development and early adoption.
License
AGPL-3.0 — see LICENSE.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file memcp_server-0.1.0.tar.gz.
File metadata
- Download URL: memcp_server-0.1.0.tar.gz
- Upload date:
- Size: 73.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
48d0035ce085e1df976c37d25877b922495106946173036e2fc46485f963882d
|
|
| MD5 |
32554d34c02c129a8b8be6c89452fef7
|
|
| BLAKE2b-256 |
a80bbaf0df30d0dbd180ea0a5f806f8ee0ace8e7fe42673eb64db535c6c885c8
|
Provenance
The following attestation bundles were made for memcp_server-0.1.0.tar.gz:
Publisher:
publish-pypi.yml on Jartan-LLC/memcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memcp_server-0.1.0.tar.gz -
Subject digest:
48d0035ce085e1df976c37d25877b922495106946173036e2fc46485f963882d - Sigstore transparency entry: 1820702521
- Sigstore integration time:
-
Permalink:
Jartan-LLC/memcp@6d1d7bda9efdc939d2437cd62cfe20f63002e089 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Jartan-LLC
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@6d1d7bda9efdc939d2437cd62cfe20f63002e089 -
Trigger Event:
push
-
Statement type:
File details
Details for the file memcp_server-0.1.0-py3-none-any.whl.
File metadata
- Download URL: memcp_server-0.1.0-py3-none-any.whl
- Upload date:
- Size: 35.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7064f125b6bb592cc4d3451bf13a9fc2f42c10b2df4c52fdc79f693b0b153c94
|
|
| MD5 |
c7b52661c809af34d35e1665652fa53c
|
|
| BLAKE2b-256 |
d25a99fd4244fe5888ea669e8ef70b54b2650a245967d09b10e849db249d7bf3
|
Provenance
The following attestation bundles were made for memcp_server-0.1.0-py3-none-any.whl:
Publisher:
publish-pypi.yml on Jartan-LLC/memcp
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
memcp_server-0.1.0-py3-none-any.whl -
Subject digest:
7064f125b6bb592cc4d3451bf13a9fc2f42c10b2df4c52fdc79f693b0b153c94 - Sigstore transparency entry: 1820702529
- Sigstore integration time:
-
Permalink:
Jartan-LLC/memcp@6d1d7bda9efdc939d2437cd62cfe20f63002e089 -
Branch / Tag:
refs/tags/v0.1.0 - Owner: https://github.com/Jartan-LLC
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish-pypi.yml@6d1d7bda9efdc939d2437cd62cfe20f63002e089 -
Trigger Event:
push
-
Statement type: