Skip to main content
Glama
gKrishii

mcp-memory-gateway

by gKrishii
README.md
![CI](https://github.com/gKrishii/mcp-memory-gateway/actions/workflows/ci.yml/badge.svg)

# mcp-memory-gateway

A FastAPI + [FastMCP](https://github.com/jlowin/fastmcp) shared-memory gateway in front of [Honcho](https://github.com/plastic-labs/honcho) v3 — a single shared brain that multiple AI agents read from and write to. It exposes a small, curated, bearer-authenticated surface so every agent can recall context and log changes against one learning memory and stay in sync.

## What it does

Endpoints / MCP tools (all bearer-authenticated):

- `recall(query)` — dialectic / similarity recall over the shared representation in Honcho
- `remember(text, agent, tags)` — store a durable observation
- `log_change(summary, agent, area, …)` — append a change to the shared, git-versioned ledger
- `profile_card()` — a compact profile/context card for session priming
- `recent_changes(n)` — the latest entries from the change ledger

The MCP server is mounted at `/mcp`; equivalent JSON routes are exposed for headless callers (shell scripts, other agent runtimes).

## Design notes

- **One curated front door over Honcho.** The underlying Honcho v3 instance stays untouched and private; this gateway is the only thing agents talk to, which keeps the surface small and auditable.
- **Two write paths, one source of truth.** A change is written to Honcho *and* appended to a git-versioned Markdown ledger (`EXTERNAL-CHANGES.md`), so logging stays reliable even if the memory backend is slow — and the ledger is human-readable history.
- **Auth that is SSE-safe.** The `/mcp` mount is guarded by a raw-ASGI bearer middleware (not `BaseHTTPMiddleware`) so it authenticates without buffering the Server-Sent-Events stream.
- **Structured, leak-free logging.** Every request emits one compact JSON log line with a request id; payload text and the bearer token are never logged (there are tests that assert this).

## Layout

- `app/` — the service
  - `app.py` — FastAPI + FastMCP app, the 5 tools/routes, and bearer auth
  - `honcho_client.py` — thin client for a local Honcho v3 instance
  - `ledger.py` — git-versioned change-ledger writer
  - `memory_mirror.py` — mirrors recent changes into a delimited block of a memory file
  - `structured_logging.py` — JSON request/audit logging with a request-id context var
- `bin/memory` — a small `memory` CLI for headless callers (`recall | card | recent | log`)
- `tests/` — pytest suite (`test_app.py`, `test_honcho_client.py`, `test_ledger.py`)
- `.github/workflows/ci.yml` — the CI pipeline
- `requirements.txt`, `conftest.py` — deps and test config
- `.env.example` — the environment variables the service reads

## Running it

```bash
python -m venv .venv && . .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env          # then set MEMORY_GATEWAY_TOKEN
export MEMORY_GATEWAY_TOKEN=...
uvicorn app.app:app --host 127.0.0.1 --port 8910
```

Run the tests:

```bash
pip install -r requirements.txt
python -m pytest -q
```

## Configuration

All configuration is via environment variables (see `.env.example`).

The gateway centers on a single configurable **primary peer** — the Honcho peer
whose profile card and recall it focuses on (set `PRIMARY_PEER`, default `user`).
Point it at whichever identity your agents share context about.

| Variable | Purpose | Default |
|---|---|---|
| `MEMORY_GATEWAY_TOKEN` | Bearer token required on every authed route and on `/mcp` | *(required)* |
| `HONCHO_BASE` | Base URL of the local Honcho v3 instance | `http://127.0.0.1:8000` |
| `HONCHO_WORKSPACE` | Honcho workspace id | `agents` |
| `HONCHO_API_KEY` | Optional bearer for Honcho | *(unset)* |
| `PRIMARY_PEER` | The Honcho peer the gateway centers on (profile card + recall) | `user` |
| `FACTS_SESSION` | Honcho session holding observations about the primary peer | `facts` |
| `AGENT_MEMORY_MD` | Plain-text memory file recent changes are mirrored into | `data/MEMORY.md` |
| `BRAIN_DIR` | Directory holding the `EXTERNAL-CHANGES.md` ledger | `data` |

## What's excluded & why (secrets never enter the repo)

Secrets, virtualenvs, and local runtime data are kept out of the repo by `.gitignore` and never committed:

- `.env` / `*.env` (except `.env.example`) — the bearer token lives only in an environment file (mode `0600`) on the host and is never committed
- `.venv/`, `__pycache__/`, `*.pyc` — environment / build artifacts
- `*.log`, `*.db` — runtime logs and local data
- `*.bak*` — local backup files

This is a clean, self-contained extract of a larger private deployment: the business-specific modules and the production host details are intentionally not part of this public repo. What remains is the reusable core — the MCP/HTTP gateway, the Honcho client, the ledger, and their tests.

## CI

CI runs on **every push and pull request** and performs:

1. **Secret scan** — gitleaks over the full git history
2. **Lint + compile** — `ruff check` and `compileall`
3. **Tests** — `pytest`

## License

MIT — see [LICENSE](LICENSE).