Skip to content

Repository files navigation

Neo4j Agent Memory

A graph-native memory system for AI agents. Store conversations, build knowledge graphs, and record and retrieve application-supplied reasoning -- all backed by Neo4j.

Neo4j Labs Status: Beta Community Supported Python CI TypeScript CI PyPI version npm version Python versions License

Neo4j Labs project

This project is part of Neo4j Labs and is actively maintained, but not officially supported. There are no SLAs or guarantees around backwards compatibility and deprecation. For questions and support, please use the Neo4j Community Forum.

The Python and TypeScript packages in this repository are versioned and released independently; the status badge above reflects this package's own maturity, not the other SDK's.

What it does

Application context with backend-dependent conversations, entities and reasoning records

Short-Term Memory Long-Term Memory Reasoning Memory
Conversations & messages Entities, preferences, facts Reasoning traces & tool usage
Per-session history Knowledge graph (POLE+O model) Retrieve recorded decisions
Vector + text search Entity resolution & dedup Similar task retrieval

Configurable extraction stages and persistence

Plus: multi-stage entity extraction (spaCy / GLiNER / LLM), relationship extraction (GLiREL), background enrichment (Wikipedia / Diffbot), geospatial queries, MCP server with 16 extended-profile tools on Bolt (20 registered on NAMS; backend limitations apply), and integrations with LangChain, Pydantic AI, Google ADK, Strands, CrewAI, and more.

Bolt operational features: adopt an existing Neo4j graph as long-term memory (client.schema.adopt_existing_graph(...)), user associations on supported writes and explicitly scoped reads, fire-and-forget buffered writes (client.buffered.submit(...)), consolidation primitives (client.consolidation.dedupe_entities(...)), an eval harness (client.eval.run(suite)), and explicit :TOUCHED audit edges from reasoning steps to entities.

Bring your own model: MemorySettings.embedding and MemorySettings.llm accept a provider-string shorthand ("anthropic/claude-sonnet-4-6", "BAAI/bge-small-en-v1.5") or a Provider instance. Native adapters for OpenAI, Anthropic, Bedrock, Vertex AI, and sentence-transformers; LiteLLM universal fallback covers 100+ providers (Cohere, Voyage, Groq, Together, Mistral, Ollama, ...). See the provider migration guide. (These configure the self-hosted backend; on NAMS, embedding and extraction run server-side.)

SDKs

neo4j-labs/agent-memory ships two SDKs with the same memory model, both backed by the NAMS hosted service. Pick the one that matches your stack — mixed Python + TypeScript agents read and write the same memory.

Language Package Install Docs
Python neo4j-agent-memory pip install 'neo4j-agent-memory==0.6.0' Python SDK docs
TypeScript @neo4j-labs/agent-memory npm install @neo4j-labs/agent-memory@0.5.0 TypeScript SDK docs

Related package: @neo4j-labs/nams-ai-provider (npm, 0.3.0) wraps the TypeScript SDK for the Vercel AI SDK — a provider, middleware, tools and lifecycle hooks for NAMS-backed agents. Source: typescript/packages/vercel-ai-provider/.

The Python SDK lives at the repo root (src/neo4j_agent_memory/, examples/); the TypeScript SDK lives at typescript/. The two SDKs are versioned and released independently — python-v* tags publish to PyPI, typescript-v* tags publish to npm. Cross-language behavioral conformance is enforced by the agent-memory-tck spec suite, which consumes both SDKs as external dependencies.

Package releases: These Python instructions use the published neo4j-agent-memory==0.6.0 package. The Python tutorials show the complete example programs and helpers to copy into local files, so running them does not require a repository clone or code download. Application code installs the TypeScript SDK the same way, from the published @neo4j-labs/agent-memory@0.5.0 package on npm; the TypeScript tutorials instead run from the shared example-project checkout, which pins the SDK with file:../.. so lessons always exercise current source.

Quick start

The fastest path is the hosted NAMS service — sign up, set one API key, and there's no database to run. For direct Neo4j access, write Cypher or geospatial queries, use the Aura (bolt) path. Available methods, result shapes and retrieval scopes differ; see Bolt vs NAMS for the trade-offs.

Option A: Hosted (NAMS) — zero infrastructure

  1. Sign up at memory.neo4jlabs.com and copy your nams_... API key.
  2. Install the SDK and export the key:
pip install 'neo4j-agent-memory[nams]==0.6.0'
export MEMORY_API_KEY=nams_...
  1. The backend auto-selects NAMS when MEMORY_API_KEY is set — no Neo4j database to manage:
import asyncio
from neo4j_agent_memory import MemoryClient

async def main():
    # Reads MEMORY_API_KEY from the environment; backend auto-selects NAMS.
    async with MemoryClient() as memory:
        conversation = await memory.short_term.create_conversation("quickstart")
        conversation_id = str(conversation.id)
        await memory.short_term.add_message(
            session_id=conversation_id, role="user",
            content="Hi, I'm John and I love Italian food!",
        )
        saved = await memory.short_term.get_conversation(conversation_id)
        print(saved.messages[-1].content)
        print("Save this conversation ID to resume it:", conversation_id)

asyncio.run(main())

On NAMS, entity extraction runs server-side and is asynchronous — call await memory.long_term.wait_for_extraction(...) before asserting on freshly-extracted entities. See Use NAMS.

Option B: MCP Server (zero code)

Give any MCP-compatible AI assistant (Claude Desktop, Claude Code, Cursor, VS Code Copilot) persistent memory backed by a dedicated AuraDB instance. Follow the Aura setup and copy its values:

export NEO4J_URI="neo4j+s://<instance-id>.databases.neo4j.io"
export NEO4J_USERNAME="neo4j"
export NEO4J_PASSWORD="replace-with-your-Aura-password"
export NEO4J_DATABASE="neo4j"
export OPENAI_API_KEY="replace-with-your-OpenAI-key"
# Run directly with uvx (no install needed)
uvx --from 'neo4j-agent-memory[mcp,openai]==0.6.0' --with 'httpx>=0.27' neo4j-agent-memory mcp serve --backend bolt --user "$NEO4J_USERNAME"

Self-hosted MCP profiles and backend-dependent support

Claude Code:

claude mcp add neo4j-agent-memory -- \
  uvx --from 'neo4j-agent-memory[mcp,openai]==0.6.0' --with 'httpx>=0.27' neo4j-agent-memory mcp serve --backend bolt --user "$NEO4J_USERNAME"

Claude Desktop (claude_desktop_config.json):

{
  "mcpServers": {
    "neo4j-agent-memory": {
      "command": "uvx",
      "args": ["--from", "neo4j-agent-memory[mcp,openai]==0.6.0", "--with", "httpx>=0.27",
               "neo4j-agent-memory", "mcp", "serve", "--backend", "bolt"],
      "env": {
        "NEO4J_URI": "neo4j+s://<instance-id>.databases.neo4j.io",
        "NEO4J_USER": "neo4j",
        "NEO4J_PASSWORD": "replace-with-your-Aura-password",
        "NEO4J_DATABASE": "neo4j",
        "OPENAI_API_KEY": "replace-with-your-OpenAI-key"
      }
    }
  }
}

Copy actual Aura values into the Desktop JSON; it does not evaluate shell variables. The CLI uses NEO4J_USER, so the JSON maps the exported NEO4J_USERNAME value to that key. Keep populated credential files out of version control.

Option C: Neo4j Aura (bolt)

Use a dedicated AuraDB instance for this example. The bolt backend connects directly to Aura over TLS and uses your client-side model providers. It supports write-Cypher, geospatial queries and adopt_existing_graph.

Copy the connection values from Aura and set the provider keys required by this example:

export NEO4J_URI="neo4j+s://<instance-id>.databases.neo4j.io"
export NEO4J_USERNAME="neo4j"
export NEO4J_PASSWORD="replace-with-your-Aura-password"
export NEO4J_DATABASE="neo4j"
export ANTHROPIC_API_KEY="replace-with-your-Anthropic-key"
export ANTHROPIC_MODEL="claude-sonnet-4-6"  # or any Claude API model ID your workspace can use
export OPENAI_API_KEY="replace-with-your-OpenAI-key"

Install both selected adapters with pip install 'neo4j-agent-memory[anthropic,openai]==0.6.0' 'httpx>=0.27'. Release 0.6.0 imports httpx when connecting over Bolt but declares it only in the nams extra, so every Bolt install without [nams] adds it.

Conversations, entities and application-recorded reasoning with backend-specific operations

neo4j-agent-memory is async-only. Every memory operation is a coroutine. From a script, wrap your entry point in asyncio.run(...) as shown below. From a notebook, prefix calls with await. From a framework that runs its own loop (FastAPI, PydanticAI, Google ADK), just use await inside your handler. There is no synchronous wrapper — by design.

import asyncio
import os
from neo4j_agent_memory import MemoryClient, MemorySettings

async def main():
    # Pass the model as a provider-prefixed string. Swap in
    # "openai/...", "bedrock/...", "vertex_ai/...", or any of the 100+
    # LiteLLM-supported providers. Defaults to a working OpenAI setup
    # when llm/embedding are omitted.
    settings = MemorySettings(
        backend="bolt",
        neo4j={
            "uri": os.environ["NEO4J_URI"],
            "username": os.environ["NEO4J_USERNAME"],
            "password": os.environ["NEO4J_PASSWORD"],
            "database": os.getenv("NEO4J_DATABASE", "neo4j"),
        },
        llm=f"anthropic/{os.environ['ANTHROPIC_MODEL']}",
        embedding="openai/text-embedding-3-small",
    )

    async with MemoryClient(settings) as memory:
        # Store a conversation message
        await memory.short_term.add_message(
            session_id="user-123", role="user",
            content="Hi, I'm John and I love Italian food!"
        )

        # Build the knowledge graph
        await memory.long_term.add_entity("John", "PERSON")
        await memory.long_term.add_preference(
            category="food", preference="Loves Italian cuisine"
        )

        # Get combined context for an LLM prompt
        context = await memory.get_context(
            "What restaurant should I recommend?",
            session_id="user-123"
        )
        print(context)

asyncio.run(main())

Already using EmbeddingConfig/LLMConfig? It still works — you'll just see a one-time DeprecationWarning at construction. See the provider migration guide.

Option D: Full-Stack App with create-context-graph

Scaffold a complete full-stack AI application with built-in context graph memory:

uvx create-context-graph

Create Context Graph full stack context graph application powered by Neo4j Agent Memory

This generates a ready-to-run project with a FastAPI backend, Next.js frontend, Neo4j knowledge graph, and neo4j-agent-memory pre-configured. See create-context-graph.dev for details.

Installation

pip install 'neo4j-agent-memory==0.6.0'                                 # Core
pip install 'neo4j-agent-memory[openai]==0.6.0'                         # + OpenAI native adapter
pip install 'neo4j-agent-memory[anthropic]==0.6.0'                      # + Anthropic native adapter
pip install 'neo4j-agent-memory[bedrock]==0.6.0'                        # + AWS Bedrock native adapter
pip install 'neo4j-agent-memory[sentence-transformers]==0.6.0'          # + local HF embeddings
pip install 'neo4j-agent-memory[litellm]==0.6.0'                        # + LiteLLM universal fallback (100+ providers)
pip install 'neo4j-agent-memory[mcp,openai]==0.6.0' 'httpx>=0.27'       # + MCP server
pip install 'neo4j-agent-memory[langchain]==0.6.0'                      # + LangChain
pip install 'neo4j-agent-memory[all]==0.6.0'                            # Everything except heavy local ML
pip install 'neo4j-agent-memory[full]==0.6.0'                           # Everything including spaCy, GLiNER, sentence-transformers, instructor

Release 0.6.0 imports httpx when connecting to Neo4j over Bolt but declares it only in the [nams] extra, so add 'httpx>=0.27' to any Bolt install whose extras do not include nams.

Provider extras follow native-first resolution: with both [openai] and [litellm] installed, an "openai/..." model uses the native adapter; an unsupported provider like "groq/..." falls through to LiteLLM. See Bring your own model for details.

Framework integrations

Framework Extra Import
LangChain [langchain] from neo4j_agent_memory.integrations.langchain import Neo4jAgentMemory
Pydantic AI [pydantic-ai] from neo4j_agent_memory.integrations.pydantic_ai import MemoryDependency
Google ADK [google-adk] from neo4j_agent_memory.integrations.google_adk import Neo4jMemoryService
Strands (AWS) [strands] from neo4j_agent_memory.integrations.strands import context_graph_tools
CrewAI [crewai] from neo4j_agent_memory.integrations.crewai import Neo4jCrewMemory
LlamaIndex [llamaindex] from neo4j_agent_memory.integrations.llamaindex import Neo4jLlamaIndexMemory
OpenAI Agents [openai-agents] from neo4j_agent_memory.integrations.openai_agents import ...
Microsoft Agent [microsoft-agent] from neo4j_agent_memory.integrations.microsoft_agent import Neo4jMicrosoftMemory

MCP Server

The MCP server exposes memory capabilities as tools for AI assistants. These commands reuse the Aura and provider environment variables configured in Option B.

# stdio transport (Claude Desktop, Claude Code)
neo4j-agent-memory mcp serve --backend bolt --user "$NEO4J_USERNAME"

# Streamable HTTP (network deployment; the MCP endpoint is /mcp)
# The endpoint has no authentication. --host 0.0.0.0 exposes it on every interface,
# so run it only on a private network or behind an authenticating proxy.
neo4j-agent-memory mcp serve --transport http --host 0.0.0.0 --port 8080 --backend bolt --user "$NEO4J_USERNAME"

# Core profile (fewer tools, less context overhead)
neo4j-agent-memory mcp serve --profile core --backend bolt --user "$NEO4J_USERNAME"

# Session continuity across conversations
neo4j-agent-memory mcp serve --session-strategy per_day --user-id alice --backend bolt --user "$NEO4J_USERNAME"

Tool Profiles:

Profile Tools Description
core 6 Essential read/write: memory_search, memory_get_context, memory_store_message, memory_add_entity, memory_add_preference, memory_add_fact
extended (default) 16 Full surface adding: conversation history, entity details, graph export, relationship creation, reasoning traces, observations, read-only Cypher

See the MCP tools reference for full details.

Examples

See examples/README.md for the full index. Highlights:

Full-stack reference apps

Example Framework Description
Lenny's Podcast Memory Explorer PydanticAI Flagship demo: 299 podcast episodes, knowledge graph, geospatial maps, Wikipedia enrichment
Full-Stack Chat Agent PydanticAI News research assistant with NVL graph visualization and auto-preference detection
AWS Financial Advisor Strands (AWS) Multi-agent KYC/AML compliance with Bedrock and reasoning trace audit trails
Google Cloud Financial Advisor Google ADK Multi-agent compliance with Vertex AI embeddings and real-time SSE streaming
Microsoft Retail Assistant Microsoft Agent Shopping recommendations with GDS algorithms, entity deduplication, and context providers

v0.2 feature demos (small, single-purpose, no LLM required)

Example Demonstrates
existing-graph/ client.schema.adopt_existing_graph(...) — layer the library over a graph you already have in production
buffered-writes/ write_mode="buffered", client.buffered.submit(...), client.flush() — agent responses unblocked from Neo4j round-trips
audit-trail/ Explicit :TOUCHED edges from reasoning steps to entities, plus TraceOutcome for indexable audit queries
eval-harness/ client.eval.run(EvalSuite(...)) — labelled regression tests for memory quality

Tooling & extraction

Example Framework Description
no_llm/ Standalone Run with llm=None plus local sentence-transformers + spaCy/GLiNER (local inference after models and dependencies are cached)
Domain Schema Examples Standalone 8 GLiNER2 extraction scripts with factory pattern, batch extraction, streaming, and GLiREL relations
Google Cloud Integration Google ADK Progressive tutorial: Vertex AI, ADK, MCP server, and MemoryIntegration with session strategies
Google ADK Demo Google ADK Standalone demo of Neo4jMemoryService with session storage, search, and preferences

Python examples with their own environment declare dependencies in requirements.txt or pyproject.toml (hello-memory/ uses PEP 723 script metadata); the others run from the repository environment named in their README. All ten TypeScript examples use the local SDK through file:../.., and nams-ai-provider and nextjs-memory-chat also link typescript/packages/vercel-ai-provider; build the SDK (and the provider for those two) before installing them. Follow each README's source bootstrap and selected-artifact requirements.

Documentation

Full documentation at neo4j.com/labs/agent-memory

  • Tutorials -- Build your first memory-enabled agent
  • How-To Guides -- Entity extraction, deduplication, enrichment, integrations
  • API Reference -- Configuration, CLI, MCP tools
  • Concepts -- POLE+O model, memory types, extraction pipeline

Development

git clone https://github.com/neo4j-labs/agent-memory.git
cd agent-memory
uv sync --group dev
make test-unit    # Run unit tests
make check        # Lint + format + typecheck

See CONTRIBUTING.md for the full development guide, CI pipeline, and documentation guidelines.

Requirements

  • Python 3.10+
  • Neo4j 5.26+ (including 2025.x) or Neo4j AuraDB for the bolt backend; merging duplicate entities uses CALL subquery syntax that needs 5.23+

License

Apache License 2.0


This is a Neo4j Labs project -- community supported, not officially backed by Neo4j. Community Forum | GitHub Issues | Documentation | TypeScript SDK

About

A graph-native memory system for AI agents and context graphs. Store conversations, build knowledge graphs, and let your agents learn from their own reasoning — all backed by Neo4j.

Topics

Resources

Contributing

Stars

572 stars

Watchers

9 watching

Forks

Releases

Used by

Contributors

Languages