Skip to main content

octop-memory-server

PyPI Python License: MIT upstream: octop-memory

English | 简体中文

A batteries-included, multi-tenant HTTP server wrapping octop-memory (Tencent Cloud's open-source long-term memory system for AI agents). One command gives you:

  • /mcp/ — an MCP service (streamable HTTP) exposing 6 memory tools to agents
  • /dashboard — a visual management console: browse / search / save memories
  • API key authentication — both entry points are protected by X-API-Key
  • Physical isolation — each API key maps to its own tenant directory and its own SQLite database file; tenants never touch each other's data
                       ┌────────────────────────────────────────────┐
  Agent (MCP client)──▶│ /mcp/        X-API-Key ──▶ tenant=alice   │
  Browser (console)──▶ │ /dashboard   X-API-Key ──▶ tenant=alice   │──┐
  Another agent    ──▶ │ /mcp/        X-API-Key ──▶ tenant=bob     │  │
                       └────────────────────────────────────────────┘  │
                                                                       ▼
                              data/tenants/
                              ├── alice/memory.sqlite   ← alice only
                              └── bob/memory.sqlite     ← bob only

1. Quick Start

1.1 Install

pip install octop-memory-server        # Python ≥ 3.12; dependencies (incl. octop-memory) pulled automatically

From source (development):

git clone <this-repo> octop-memory-server && cd octop-memory-server
pip install -e .

1.2 Configure API keys

Copy api_keys.json.example to api_keys.json and replace the keys:

{
  "keys": {
    "oag-paste-a-random-long-string-alice": { "tenant": "alice" },
    "oag-another-random-string-bob": {
      "tenant": "bob",
      "llm": { "base_url": "http://localhost:11434/v1", "model": "qwen3:8b" }
    }
  }
}

Generate a random key: python -c "import secrets; print('oag-' + secrets.token_urlsafe(24))"

Edits to this file take effect immediately (hot reload) — no restart needed.

1.3 Start (CLI)

octop-memory-server                              # defaults to 127.0.0.1:8600
octop-memory-server --host 0.0.0.0 --port 8600   # serve externally
octop-memory-server --data-dir /srv/mem --keys-file /srv/mem/api_keys.json
octop-memory-server --llm-endpoint http://localhost:11434/v1 --llm-model qwen3:8b
octop-memory-server --reload                     # dev hot reload
octop-memory-server --version / --help
Option Default Description
--host 127.0.0.1 Listen address
--port 8600 Listen port
--data-dir ./data Root directory for tenant data
--keys-file ./api_keys.json Path to the key manifest
--llm-endpoint / --llm-model from env Global default LLM (per-key config wins)

Prefer plain uvicorn? uvicorn octop_memory_server.app:app --host 0.0.0.0 --port 8600.

  • Dashboard: http://localhost:8600/dashboard (paste your API key on first open)
  • MCP endpoint: http://localhost:8600/mcp/
  • Health check (no auth): http://localhost:8600/health

2. Physical Isolation Design

Each API key maps 1:1 to a tenant, isolated at three layers:

Layer Mechanism Notes
Directory data/tenants/<tenant>/ Per-tenant directory; set OS permissions and back up independently
File Own memory.sqlite SQLite WAL mode — zero sharing, zero lock contention between tenants
In-database namespace t_<tenant> Table prefixes differ even if a db file were misconfigured — belt and suspenders

Hard security guarantees (enforced in code):

  1. The db path and namespace are resolved server-side only from the API key; no REST/MCP endpoint ever accepts them from the client;
  2. Dashboard list queries use read-only connections (file:...?mode=ro);
  3. Table names are built solely from the normalized namespace (re.sub(r"[^a-z0-9_]", "_", ns)), ruling out SQL injection;
  4. Keys are compared with hmac.compare_digest (timing-safe); logs only record a 12-char SHA-256 fingerprint of each key.

⚠️ api_keys.json currently stores keys in plain text. On multi-admin machines, consider storing SHA-256 hashes instead (KeyEntry already has fingerprint plumbing; the change to ApiKeyStore.reload_if_needed is under ten lines).


3. /mcp/ — MCP Service

3.1 Client setup

MCP client configuration (e.g. the mcp.json of WorkBuddy / Claude Desktop / Cursor):

{
  "mcpServers": {
    "octop-memory": {
      "url": "http://your-host:8600/mcp/",
      "headers": { "X-API-Key": "oag-xxxx-alice" }
    }
  }
}

Issue one key per agent / user and you get "agents can't see each other's memories" for free.

3.2 Tools

Tool Description Needs LLM
memory_save(content, topic?) Explicitly save a long-term memory (fact / preference / decision) No
memory_recall(query, thread_id?, limit?) Recall and return a markdown block ready to inject into a prompt No
memory_search(query, max_results?, corpus?) Multi-source search (incl. the raw conversation layer), structured hits No
memory_get(path) Read source by virtual path: atom/<id>.md, raw/<date>/<id>.md, page/<entity>.md No
memory_capture(user?, assistant?, session_id?) Capture one conversation turn as L0 raw events (privacy filtering applies) No
memory_extract(session_id) Distill a session's raw events into long-term memory (L0→L1→L2→L3) Yes

In the agent loop: call memory_capture (non-blocking) at the end of each turn, memory_extract on session end or when idle, and memory_recall while assembling the system prompt. No capture, no raw material for extract.


4. /dashboard — Visual Management Console

A dependency-free single-page app (static/index.html). Paste your API key on first open (stored in localStorage); it reconnects automatically afterwards.

Tab What it shows
Overview Tenant info, db size, per-layer counts (L0/L1/L2/entities/digests/journal), recent-memory timeline
Atoms Atom list with keyword search, deprecated filter, verbatim quotes, confidence/importance
Candidates Review view (filter by promoted / needs_review / conflict / duplicate)
Raw events L0 RawEvent browser, filterable by session
Tools Manual memory save / recall test (preview the injected block) / session extract (needs LLM)

REST API (all require X-API-Key, prefix /dashboard/api):

GET  /tenant                          tenant & db info
GET  /overview                        stats + recent memories
GET  /atoms?q&include_deprecated&limit&offset
GET  /atoms/{id}                      atom detail (source excerpt)
GET  /candidates?status&limit&offset
GET  /raw_events?session_id&event_type&limit&offset
POST /memory       {"content","topic"}            save
POST /recall       {"query","limit","thread_id"}  recall test
POST /extract      {"session_id"}                 session extract (needs LLM, else 409)

Review actions (candidate promote/reject, gc, db slim) are deliberately not exposed to the dashboard/MCP — they are destructive or decision-making operations. Use the upstream CLI on the host when needed (octop-memory --db data/tenants/<tenant>/memory.sqlite --namespace t_<tenant> candidate ...).


5. LLM Configuration (optional)

Where Priority Scope
Per-key llm field in api_keys.json High A single tenant
Env vars OCTOP_LLM_ENDPOINT / OCTOP_LLM_MODEL / OCTOP_LLM_MODEL_HEAVY Low All tenants without their own config

Without an LLM: save / recall / search / get / capture all work; only extract (automatic distillation) and page regeneration are unavailable. The endpoint can be any OpenAI-compatible API (OpenAI / Ollama / vLLM / etc.).

Other environment variables:

Variable Default Description
OCTOP_GW_DATA_DIR ./data Root directory for tenant data
OCTOP_GW_KEYS_FILE ./api_keys.json Path to the key manifest
OCTOP_GW_HOST octop-memory-server Host label written into RawEvents

6. Deployment Notes

  1. Process: single uvicorn process, --workers 1 (SQLite has a single-writer model; for multi-worker writes switch to the PostgreSQL backend — see octop-memory's postgres extra).
  2. HTTPS: API keys travel in plain headers; put the service behind a TLS reverse proxy (nginx/caddy) for anything public-facing.
  3. Backup: just back up the data/tenants/ directory, or use the upstream octop-memory export / portable (.hmpkg) for cross-host migration.
  4. Maintenance: run gc / consolidate / page regeneration via the upstream CLI on a scheduler during idle windows (aligns with upstream ADR-027):
octop-memory --db data/tenants/alice/memory.sqlite --namespace t_alice gc
octop-memory --db data/tenants/alice/memory.sqlite --namespace t_alice consolidate
  1. Monitoring: probe /health; every tenant operation is logged with its tenant id and can be aggregated per directory.

7. Known Limitations

  • Upstream octop-memory 1.0.0 is Alpha: the PostgreSQL backend and vector search (chroma/qdrant) are not verified with real integrations; this server uses the SQLite backend only (also the cleanest form of isolation).
  • MCP's memory_extract is synchronous; distilling a long session may exceed MCP client timeouts. Prefer running extraction from an external scheduler via the upstream CLI (candidate extract); keep MCP for reads/writes.
  • The dashboard shows candidates read-only; approve/reject actions require upstream promotion internals — extend dashboard_api.py as needed.

8. Testing

pip install -e .
python smoke_test.py     # 15 end-to-end checks: 401 auth, MCP handshake, cross-tenant isolation, dashboard REST

9. License & Acknowledgements

  • This project is released under the MIT License.
  • The core capability comes from Tencent Cloud's open-source octop-memory (MIT License). This project is a serving wrapper only (multi-tenant HTTP server / MCP / Dashboard) and does not modify upstream code. Report upstream issues to the original repository.

Metadata

Release files for octop-memory-server 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for octop-memory-server 0.1.0
File Size Uploaded
octop_memory_server-0.1.0.tar.gz 43.2 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for octop-memory-server 0.1.0
File Interpreter ABI Platform
octop_memory_server-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 83.4 kB

Release files / octop_memory_server-0.1.0.tar.gz

Download URL octop_memory_server-0.1.0.tar.gz
Size 43.2 kB
Tags Source
SHA-256 checksum
How to use checksums
a6ff50a273ffa3e862789f6b4814ead8dc65bc72da79e74e60a215d6fac6512c
BLAKE2b-256 checksum
How to use checksums
ab704a946a48f77a1f6f552ff54bd2fe6538147d0ce41c644702684dd093819d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release files / octop_memory_server-0.1.0-py3-none-any.whl

Download URL octop_memory_server-0.1.0-py3-none-any.whl
Size 40.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
04a32969aa88d1e64c184ba79cb90b655671f1d0d2c8ee39cba0e90bfc5a5f55
BLAKE2b-256 checksum
How to use checksums
b46ade12c77b0998dfc44ec1349beb6e5c92ba6b3915eab9f41e58eecbbe87f9
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.14

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page