# 8 Open Source Tools for Building AI Agents with Memory

> Source: <https://dev.to/statewave/8-open-source-tools-for-building-ai-agents-with-memory-4i47>
> Published: 2026-09-03 14:09:06+00:00

An agent that remembers needs four things: somewhere to put raw events, something that turns them into facts, a way to retrieve those facts under a token budget, and a framework to run the loop. No single tool does all four well, which is why this list is eight tools and not one.

We build [Statewave](https://github.com/smaramwbc/statewave), an open-source memory runtime, so treat the entry about us accordingly. Everything below is Apache-2.0, MIT, or the PostgreSQL License, verified from the LICENSE file rather than the badge, checked on 1 September 2026. MCP is mid-transition from MIT to Apache-2.0.

Grouping below is by what each tool owns, because the most common mistake in this category is picking two tools that own the same layer and none that own the missing one.

A memory runtime that sits behind your agents over HTTP. You send raw events as episodes; it compiles them into typed memories with confidence scores and validity windows, and you request a ranked, token-bounded bundle when you need context.

from statewave import StatewaveClient

| with StatewaveClient("
|
|---|

What it owns: storage, consolidation, ranked retrieval, conflict resolution, provenance. What it deliberately does not own: your agent loop. Storage is Postgres with pgvector and no separate vector service. **npx @statewavedev/statewave** boots the API, admin console, and Postgres locally. The server defaults to demo mode with stub hash-based embeddings and the heuristic compiler, which means no real semantic search but a working loop.

Determinism is the property we care most about. The same subject, task, and token budget return the same bytes, which is what makes retrieval regression-testable.

Where it costs you: cross-subject retrieval is two calls, and the default compiler is heuristic regex. Switch to **STATEWAVE_COMPILER_TYPE=llm** for better extraction from messy conversation, or keep the heuristic compiler deliberately if no customer text may leave your network.

[Mem0](https://github.com/mem0ai/mem0) is the shortest path from nothing to an assistant that remembers a user. Its API is four calls wide: add, search, update, delete. Apache-2.0 for the library, with a managed platform sold separately.

Pick it when time to first working result matters more than being able to explain a specific retrieval later. Composition of its vector store, graph layer, and reranker is not broken down in public docs, so auditability means reading source.

[Graphiti](https://github.com/getzep/graphiti) is a temporal knowledge graph that tracks when a fact became valid and when it stopped being true. That is a real answer to stale memory, which most fact stores handle by overwriting and hoping.

A note that saves evaluation time: many lists point to [getzep/zep](https://github.com/getzep/zep) for this project. That repo’s README describes itself as examples for the managed Zep Cloud rather than the product, checked 1 September 2026. Graphiti is the self-hostable piece.

[Cognee](https://github.com/topoteretes/cognee) builds a self-hosted knowledge graph with ontology grounding, combining embeddings with graph reasoning. Apache-2.0.

Reach for it when the relationships between entities carry the meaning, not just the facts about each one. It is more machinery than a preference store needs.

[LangGraph](https://github.com/langchain-ai/langgraph) models agents as state machines with explicit nodes and edges, which makes multi-step flows debuggable in a way that a while-loop over tool calls is not. MIT.

Its checkpointer handles per-thread state well. Worth being precise about the boundary: thread-level persistence is not the same as cross-session, cross-agent memory, and conflating them is how teams end up with an agent that remembers a conversation but not a customer.

[Letta](https://github.com/letta-ai/letta) carries the MemGPT lineage and is a stateful agent runtime rather than a memory layer. It owns the reasoning loop, tool calls, and context management. Apache-2.0.

Check what you are adopting before you commit to it. **letta-ai/letta** now describes itself as a landing page for the project, with the retired Letta V1 server preserved on an **archive** branch and marked unsupported and not for production use. The current path is the hosted platform and the Letta Agent SDK, so Letta is no longer the self-hostable “one decision instead of four” it used to be.

[MCP](https://github.com/modelcontextprotocol/modelcontextprotocol) is the piece people skip, then rebuild badly. It is an open protocol for exposing tools and data to LLM clients, built on JSON-RPC.

Why it belongs on a memory list: if four agents in three frameworks need the same memory, a protocol endpoint is what stops you writing three adapters. We expose Statewave over MCP for exactly this, so a Claude custom connector and a Python agent hit one memory service without either knowing about the other.

[pgvector](https://github.com/pgvector/pgvector) adds vector types and distance operators to Postgres. Not glamorous, and it removes an entire moving part from your architecture.

One detail worth knowing: use an HNSW index rather than IVFFlat for anything that grows. IVFFlat recall depends on lists and probes matching your row count, so a corpus that outgrows its tuning quietly returns worse neighbors. We migrated for that reason and wrote up the details in the Postgres post.

Stacks that work: pair one tool per layer:

● **Fast prototype:** LangGraph plus Mem0. Two decisions, working today.

● **Self-hosted with audit requirements:** [your framework plus Statewave on Postgres and pgvector, exposed over MCP](https://www.statewave.ai/blog/self-hosting-ai-memory).

● **Relationship-heavy domains:** Graphiti or Cognee for memory, LangGraph for orchestration.

A common anti-pattern is picking Letta and Mem0 together, or LangGraph checkpointers and expecting cross-session memory. Both are two tools fighting over one layer while a different layer stays empty.

If you want the working code rather than the list, we keep three runnable demos: [multi-agent memory](https://github.com/smaramwbc/statewave-multi-agent-memory) with conflicting sources and automatic supersession, [multi-agent shared context](https://github.com/smaramwbc/statewave-multi-agent-shared-context) where a planner and coder stop contradicting each other, and a [personal assistant](https://github.com/smaramwbc/statewave-personal-assistant) that boots in five minutes without an LLM key.

No neutral, third-party benchmark compares these on the same task with the same corpus. Ours covers a subset and we ran it, which is exactly why it is not the one to settle your decision. Run the eval on your own data before committing to any of them.
