Skip to content
ALL SYSTEMS

AI ENGINEERING

SELF-HOSTED

Memory layer across agents

A local memory layer Claude Code and Kiro both speak to over MCP. Three defects in it failed silently — tools reporting success while storing nothing.

  • Python
  • mem0
  • Qdrant
  • MCP
github.com/mohitpant05/agent-memory
Silent failures found
3

Silent failures found

Network egress
0

Network egress

MCP tools
11

MCP tools

The problem

Coding agents working the same codebases shared nothing. Claude Code kept its transcripts, Kiro kept its own, and neither could answer a question the other had already resolved. Re-explaining architecture at the start of every session was the tax, and it scaled with every agent added.

The approach

A local memory layer every agent speaks to over MCP: mem0 extracts facts, a local model embeds them, Qdrant stores the vectors. Everything runs on the machine — no API key, no cloud, no egress. It is strictly additive: transcripts and --resume are independent and keep working if the layer is down.

MEMORY PATH

Engineering work happening in Claude Code and Kiro.

What broke — and how it was caught

Every one of these failed silently. The tools returned success while storing nothing, which is the worst failure mode a memory layer can have: you only find out weeks later, when the thing you told it is gone.

  1. DEFECT 01

    Reasoning models returned empty content

    SYMPTOM
    Tools reported success while storing nothing. Zero facts extracted, no error anywhere.
    CAUSE
    mem0 sends num_predict=2000. Reasoning models spend the whole budget in their thinking channel, which Ollama strips from message.content — the response arrives done_reason="length" with an empty string. The upstream fix appends /no_think to the prompt text, which stopped working on Ollama 0.21+.
    FIX
    Set think=False at the API level, and prefer a non-thinking instruct model.
    EVIDENCE
    Against mem0's real fact-retrieval prompt, 3 inputs: qwen2.5:3b-instruct returned valid JSON 3/3, qwen3:4b 1/3.
  2. DEFECT 02

    The default prompt discarded every technical fact

    SYMPTOM
    A memory layer built for engineering context stored coffee preferences and dropped engineering statements.
    CAUSE
    mem0's FACT_RETRIEVAL_PROMPT opens "You are a Personal Information Organizer". Measured: "I prefer dark roast coffee, I work as a software engineer" extracted two facts; "The batch scheduler fix raised successfully placed jobs from 232 to 247" extracted an empty list.
    FIX
    A replacement extraction prompt written for engineering statements, wired in through custom_fact_extraction_prompt.
    EVIDENCE
    Silent total failure for the layer's actual purpose — success responses, empty store.
  3. DEFECT 03

    delete_all_memories ignored its own guard

    SYMPTOM
    A no-argument call wiped the entire default user scope, despite a docstring promising at least one filter is required.
    CAUSE
    The scope check ran against a value that had already been defaulted, so the guard could never be true — dead code. The sibling delete_entities checks the raw parameters and is correct; the two disagreeing is what makes it a bug rather than a design choice.
    FIX
    Wrap the registered tool and restore the documented behaviour, with an explicit environment-variable opt-out.
    EVIDENCE
    Test discriminates: guard on with no args refuses and 2 memories survive; guard off with no args deletes 2, reproducing the bug; guard on with explicit scope deletes 6, so the intended path still works.

Design notes

WHY ONLY QDRANT IS CONTAINERISED
Ollama stays on the host so it can reach the GPU. Docker Desktop on macOS has no Metal access, and on Linux this removes the nvidia-container-toolkit dependency entirely.
WHY PATCHES LOAD AT RUNTIME
Fixes are dropped into site-packages via a .pth file rather than editing the package, so the pinned commit stays byte-identical to what was reviewed and a reinstall cannot lose them.
SECURITY POSTURE
The HTTP transport has no inbound authentication, so the installer refuses to bind 0.0.0.0. Kiro is configured with the two destructive tools disabled.
DEPENDENCY CEILINGS
mcp and mem0ai both shipped breaking 2.x releases after the pinned commit; unpinned installs do not import. CI asserts the ceilings are still in place.