-
Notifications
You must be signed in to change notification settings - Fork 2
Memory Connectors
Nakatomi doesn't implement semantic memory on purpose. Agents already have good memory systems. Instead, Nakatomi is the structured spine and ships a bidirectional bridge to external memory providers.
%%{init: {"look": "handDrawn", "theme": "dark"}}%%
flowchart LR
W[CRM mutation] --> Emit
Emit --> TL[(timeline)]
Emit -.->|configured connectors| MC[DocDeploy /<br/>Supermemory /<br/>GBrain]
MC --> Link[(MemoryLink row)]
R[memory_recall] --> Fan[fan-out]
Fan --> MC
MC --> Merge[merge by score]
Merge --> Out[results + crm_links]
Every CRM write gets mirrored to every enabled connector. Every recall
fans out across them. Results come back decorated with the MemoryLink
rows already on file, so agents can pivot from a memory back into the CRM
in the same call.
Comma-separated list in the environment:
MEMORY_CONNECTORS=docdeploy,supermemory
Empty disables the whole subsystem. /memory/* endpoints still work but
return empty.
Pay-per-call encrypted memory on Base (x402). https://www.docdeploy.io
DOCDEPLOY_API_KEY=...
DOCDEPLOY_BASE_URL=https://x402.docdeploy.io
Cost model: ~cents per remember/recall call. Good for small, high-signal
workspaces where you're happy to pay per event.
Subscription API. https://supermemory.ai
SUPERMEMORY_API_KEY=...
SUPERMEMORY_BASE_URL=https://api.supermemory.ai
Container tags (ws:<workspace_id>) keep workspaces isolated. Flat rate,
so good for chatty workloads.
Self-hosted, MCP-first, self-wiring knowledge graph. https://github.com/garrytan/gbrain
MEMORY_CONNECTORS=gbrain
GBRAIN_MCP_URL=https://your-brain.example.com/mcp
GBRAIN_TOKEN=...
The adapter is a stub — it demonstrates the wiring but the
_call_tool body is intentionally a no-op. Fill it in with a real MCP
client session for your GBrain deployment. The MCP tools vary by GBrain
build (ingest, query, etc.).
Enabling more than one is fine:
MEMORY_CONNECTORS=docdeploy,supermemory,gbrain
- Every
memory_recallfans out, merges, sorts by score, returns the top-N across all three. - Every CRM write mirrors to all three (best-effort; one failing doesn't block the others).
-
memory_traceshows every connector's links for a given entity.
| Route | Purpose |
|---|---|
GET /memory/connectors |
list enabled adapters |
GET /memory/links |
list every link in the workspace (paginated; filter by connector / entity_type / entity_id) |
POST /memory/recall |
fan-out recall (see shape below) |
POST /memory/link |
cross-link an external memory id with a CRM entity |
DELETE /memory/link/{id} |
remove a link |
GET /memory/trace/{entity_type}/{entity_id} |
list links for one entity |
POST /memory/webhook/{connector} |
inbound — memory system pushes to us |
curl -X POST http://localhost:8000/memory/recall \
-H "Authorization: Bearer nk_..." \
-H "Content-Type: application/json" \
-d '{
"query": "what did we promise Acme about delivery timelines?",
"entity_type": "company",
"entity_id": "<acme-uuid>",
"limit": 10
}'Response:
{
"items": [
{
"connector": "docdeploy",
"external_id": "mem_abc",
"text": "...",
"score": 0.81,
"metadata": {...},
"crm_links": ["company:acme-uuid", "deal:big-deal-uuid"]
}
]
}curl -X POST http://localhost:8000/memory/link \
-H "Authorization: Bearer nk_..." \
-d '{
"connector": "supermemory",
"external_id": "mem_xyz",
"crm_entity_type": "deal",
"crm_entity_id": "<uuid>",
"note": "call transcript 2026-04-18"
}'Idempotent on the (connector, external_id, crm_entity_type, crm_entity_id)
tuple. Re-posting the same link returns 409.
Memory providers that notify on writes can POST to
/memory/webhook/<connector>. The adapter's parse_webhook decodes the
shape and creates matching MemoryLink rows automatically. Useful for
bidirectional sync: a write in the memory system shows up as a linked
memory in the CRM.
Same capabilities, agent-native:
memory_list_connectorsmemory_recallmemory_linkmemory_trace
See MCP-Tools.
Currently: inbound writes never overwrite CRM fields. They can create
new MemoryLink rows and emit memory.linked events, but they don't
mutate contact/company/deal rows. A future config will allow opt-in
overwrite rules.
- Create
app/services/memory/adapters/<name>.py - Subclass
MemoryConnector(see app/services/memory/base.py) - Implement
store_event,recall, and optionallyverify_webhook/parse_webhook - Register in app/services/memory/registry.py
- Document env vars in
.env.exampleand in this page
The DocDeploy and Supermemory adapters are each ~100 lines — use them as templates.
Repository · Issues · MIT licensed · maintained by Matt Dula