Metadata-Version: 2.5
Name: memcp-server
Version: 0.2.0
Summary: Backend-agnostic, multi-tenant MCP memory server
License-Expression: AGPL-3.0-only
License-File: LICENSE
License-File: LICENSE-ICU
Requires-Python: >=3.12
Requires-Dist: httpx<1,>=0.27
Requires-Dist: icu4py<2,>=1.1
Requires-Dist: mcp<3,>=2.0
Requires-Dist: pydantic-settings<3,>=2.14.1
Requires-Dist: pydantic<3,>=2.13.4
Requires-Dist: starlette<2,>=0.27
Requires-Dist: uvicorn<1,>=0.49.0
Provides-Extra: dev
Requires-Dist: asgi-lifespan<3,>=2.1; extra == 'dev'
Requires-Dist: pyright==1.1.414; extra == 'dev'
Requires-Dist: pytest-asyncio<2,>=1.4.0; extra == 'dev'
Requires-Dist: pytest<10,>=9.0.3; extra == 'dev'
Requires-Dist: respx<1,>=0.22; extra == 'dev'
Description-Content-Type: text/markdown

# memcp

[![PyPI](https://img.shields.io/pypi/v/memcp-server)](https://pypi.org/project/memcp-server/)
[![CI](https://github.com/Jartan-LLC/memcp/actions/workflows/ci.yml/badge.svg)](https://github.com/Jartan-LLC/memcp/actions/workflows/ci.yml)
[![OpenSSF Scorecard](https://api.scorecard.dev/projects/github.com/Jartan-LLC/memcp/badge)](https://scorecard.dev/viewer/?uri=github.com/Jartan-LLC/memcp)
[![License](https://img.shields.io/badge/license-AGPL--3.0-blue)](https://github.com/Jartan-LLC/memcp/blob/main/LICENSE)

Backend-agnostic, multi-tenant MCP memory server. AI clients connect and get
persistent long-term memory over streamable HTTP.

## Quickstart

Start memcp on `127.0.0.1:8080` with the `sqlite` backend, using Docker or pip. For
search by meaning and fact extraction, [use mem0](https://github.com/Jartan-LLC/memcp/blob/main/docs/deployment.md#use-mem0) instead.

### With Docker

Needs Docker. The command names your key and its space after your login, `$USER`. A key
name holds only letters, digits, `_`, `.` and `-`: if your login has anything else, or
`USER` is unset, replace `$USER` with such a name.

```bash
mkdir memcp && cd memcp &&
  curl -fsSLO https://raw.githubusercontent.com/Jartan-LLC/memcp/main/docker-compose.yml &&
  curl -fsSL -o .env https://raw.githubusercontent.com/Jartan-LLC/memcp/main/.env.example &&
  chmod 600 .env &&
  TOKEN=$(openssl rand -hex 32) && echo "$TOKEN" &&
  printf '[[keys]]\nname = "%s"\nsecrets = ["sha256:%s"]\ngrants = [{ space = "%s", relation = "writer" }]\n' \
    "$USER" "$(printf %s "$TOKEN" | sha256sum | cut -d' ' -f1)" "$USER" > keys.toml
```

Keep the token that printed; `keys.toml` holds only its hash (on macOS, use
`shasum -a 256` in place of `sha256sum`). Then start it:

```bash
docker compose up -d --wait
```

### With pip

Needs Python 3.12 or later.

```bash
pip install memcp-server
MEMCP_BACKEND=sqlite MEMCP_SQLITE_PATH="$HOME/.memcp/memcp.sqlite3" MEMCP_HOST=127.0.0.1 memcp
```

Where the system Python refuses `pip install` (an "externally managed" environment),
use `pipx install memcp-server`. With no `MEMCP_KEYS_FILE`, memcp serves one key on
loopback and clients connect without a token.

## Connect from Claude Code

With the token you generated:

```bash
claude mcp add --scope user --transport http memcp http://localhost:8080/mcp \
  --header "Authorization: Bearer YOUR_TOKEN"
```

Behind a reverse proxy, the URL is `https://<your-host>/mcp`. A server started with
`memcp` on loopback and no `MEMCP_KEYS_FILE` takes no `--header`.

## 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. On the quickstart's
`sqlite` backend this works because `linter` and `linting` share a stem — matching is
lexical, so a question phrased in words that do not appear in the memory will not
find it. `mem0` is the backend that matches on meaning.

## What it does

- Durable, keyless local storage (`sqlite`), or mem0 on pgvector for semantic search and a knowledge graph
- Add, search, list, update and delete memories over MCP — 12 tools, frozen surface
- Flat scope-based filtering (`agent_id`, `run_id`)
- Bearer-token keys, each read-only or read-write on one space, stored as hashes
- Stateless HTTP transport — safe behind reverse proxies

## Documentation

| Document | What it covers |
|---|---|
| [deployment.md](https://github.com/Jartan-LLC/memcp/blob/main/docs/deployment.md) | Running memcp with Docker Compose — backends, keys, reverse proxies, and running the server without Docker |
| [reference.md](https://github.com/Jartan-LLC/memcp/blob/main/docs/reference.md) | Environment variables, the 12 MCP tools, and known limitations per backend |
| [architecture.md](https://github.com/Jartan-LLC/memcp/blob/main/docs/architecture.md) | How memcp is divided into packages, how it keeps spaces apart, and what a backend must guarantee |
| [CONTRIBUTING.md](https://github.com/Jartan-LLC/memcp/blob/main/CONTRIBUTING.md) | Working on memcp itself — setup and the check loop |
| [tests/mem0/README.md](https://github.com/Jartan-LLC/memcp/blob/main/tests/mem0/README.md) | Running the conformance suite against a real mem0 |
| [CHANGELOG.md](https://github.com/Jartan-LLC/memcp/blob/main/CHANGELOG.md) | What changed, per release |

## Status

v0.2.0 — API may change before v1.0. Suitable for development and early adoption.

## License

AGPL-3.0 — see [LICENSE](https://github.com/Jartan-LLC/memcp/blob/main/LICENSE).
