Thanks to visit codestin.com
Credit goes to neo4j.com

Getting Started

This guide walks you through installing the Neo4j Agent Memory SDK, connecting to a backend, and performing your first memory operations.

Two ways to run. Pick the one that matches your goal:

  • Hosted (NAMS) — A managed REST service at memory.neo4jlabs.com. You provide an API key; Neo4j is operated for you. Fastest path to a working agent. Best for prototypes, demos, and multi-tenant SaaS deployments.

  • Self-hosted (Bolt) — Bring your own Neo4j (Aura, Desktop, or Docker). You get full schema control, write-Cypher access, geospatial features, and air-gapped operation. Best when you already operate Neo4j or need bolt-only features.

The SDK surface is the same for both — client.short_term, client.long_term, client.reasoning. See Bolt vs NAMS for the trade-offs and Migrate to NAMS for porting between them.

Path A: Hosted (NAMS) — fastest start

If you don’t already operate Neo4j, start here. There is nothing to install or run beyond the SDK and an API key.

1. Get an API key

Sign up at memory.neo4jlabs.com and copy your nams_…​ key.

2. Install the SDK

Python
pip install neo4j-agent-memory
export MEMORY_API_KEY=nams_...
TypeScript
npm install @neo4j-labs/agent-memory
export MEMORY_API_KEY=nams_...

3. First operations

Python
import asyncio, os
from neo4j_agent_memory import MemoryClient

async def main():
    # Reads MEMORY_API_KEY from env; backend auto-selects NAMS.
    async with MemoryClient() as memory:
        await memory.short_term.add_message(
            session_id="user-123", role="user",
            content="I love Italian food!",
        )
        await memory.long_term.add_preference(
            category="food", preference="Loves Italian cuisine",
        )
        ctx = await memory.get_context(
            "restaurant recommendation", session_id="user-123",
        )
        print(ctx)

asyncio.run(main())
TypeScript
import { MemoryClient } from "@neo4j-labs/agent-memory";

const memory = new MemoryClient();  // reads MEMORY_API_KEY

const conv = await memory.shortTerm.createConversation({ userId: "alice" });
await memory.shortTerm.addMessage(conv.id, "user", "I love Italian food!");

await memory.longTerm.addPreference("food", {
  preference: "Loves Italian cuisine",
});

const ctx = await memory.shortTerm.getContext(conv.id);
console.log(ctx.recentMessages, ctx.observations, ctx.reflections);

Then continue with NAMS Quickstart (Python) or Hosted Quickstart (TypeScript).

Path B: Self-hosted Neo4j (Bolt)

If you already run Neo4j or need bolt-only features (write-Cypher, geospatial, adopt_existing_graph), follow this path. Python only — the TypeScript SDK is NAMS-only.

Prerequisites

  • Python 3.10+

  • Neo4j 5.20+ (local or cloud)

  • Optional: OpenAI / Anthropic / Bedrock / Vertex key for embeddings and LLM extraction

Basic install

Install the core package with pip:

pip install neo4j-agent-memory

Install with extras

Choose the extras that match your needs:

Extra Description Command

openai

OpenAI embeddings and LLM extraction

pip install neo4j-agent-memory[openai]

spacy

spaCy NER extraction (local)

pip install neo4j-agent-memory[spacy]

gliner

GLiNER zero-shot NER (local)

pip install neo4j-agent-memory[gliner]

extraction

Full extraction pipeline (spaCy + GLiNER)

pip install neo4j-agent-memory[extraction]

sentence-transformers

Local embeddings with Sentence Transformers

pip install neo4j-agent-memory[sentence-transformers]

cli

Command-line interface for extraction and schemas

pip install neo4j-agent-memory[cli]

opentelemetry

OpenTelemetry tracing for observability

pip install neo4j-agent-memory[opentelemetry]

opik

Opik LLM-focused observability

pip install neo4j-agent-memory[opik]

vertex-ai

Google Vertex AI embeddings

pip install neo4j-agent-memory[vertex-ai]

bedrock

Amazon Bedrock embeddings (Titan, Cohere)

pip install neo4j-agent-memory[bedrock]

aws

AWS cloud provider bundle (Bedrock)

pip install neo4j-agent-memory[aws]

strands

AWS Strands Agents SDK integration

pip install neo4j-agent-memory[strands]

all

All features including local models

pip install neo4j-agent-memory[all]

Download spaCy Model

If using spaCy extraction, download a language model:

python -m spacy download en_core_web_sm

Setting Up Neo4j

docker run -d \
  --name neo4j \
  -p 7474:7474 -p 7687:7687 \
  -e NEO4J_AUTH=neo4j/password \
  -e NEO4J_PLUGINS='["apoc"]' \
  neo4j:5.26-community

Option 2: Neo4j Desktop

Download Neo4j Desktop and create a new database.

Option 3: Neo4j AuraDB (Cloud)

Create a free instance at Neo4j AuraDB.

Basic Usage

Connecting to Neo4j

import asyncio
from neo4j_agent_memory import MemoryClient, MemorySettings
from pydantic import SecretStr

async def main():
    # Configure connection
    settings = MemorySettings(
        neo4j={
            "uri": "bolt://localhost:7687",
            "username": "neo4j",
            "password": SecretStr("password"),
        }
    )

    # Connect using async context manager
    async with MemoryClient(settings) as memory:
        print(f"Connected: {memory.is_connected}")

        # Your memory operations here
        stats = await memory.get_stats()
        print(f"Memory stats: {stats}")

asyncio.run(main())

Storing Conversation Messages

async with MemoryClient(settings) as memory:
    # Add a user message
    message = await memory.short_term.add_message(
        session_id="session-123",
        role="user",
        content="What's the best pizza place in New York?"
    )
    print(f"Stored message: {message.id}")

    # Add an assistant response
    await memory.short_term.add_message(
        session_id="session-123",
        role="assistant",
        content="I recommend Joe's Pizza in Greenwich Village!"
    )

    # Retrieve conversation history
    conversation = await memory.short_term.get_conversation(
        session_id="session-123"
    )
    for msg in conversation.messages:
        print(f"{msg.role}: {msg.content}")

Working with Entities

Entities are automatically extracted from messages when extract_entities=True (default):

async with MemoryClient(settings) as memory:
    # This message will have entities extracted automatically
    await memory.short_term.add_message(
        session_id="session-123",
        role="user",
        content="I work at Acme Corp in San Francisco with John Smith",
        extract_entities=True  # Default is True
    )

    # Search for entities
    entities = await memory.long_term.search_entities(
        query="companies in San Francisco",
        limit=5
    )
    for entity in entities:
        print(f"{entity.name} ({entity.type}): {entity.confidence}")

Storing Preferences

async with MemoryClient(settings) as memory:
    # Add a user preference
    pref = await memory.long_term.add_preference(
        category="food",
        preference="Prefers vegetarian options",
        confidence=0.8,
        metadata={"source": "user_profile"}
    )

    # Search preferences
    prefs = await memory.long_term.search_preferences(
        query="dietary restrictions",
        limit=5
    )

Getting Context for LLM Prompts

async with MemoryClient(settings) as memory:
    # Get combined context from all memory types
    context = await memory.get_context(
        query="restaurant recommendation",
        session_id="session-123",
    )

    # Use context in your LLM prompt
    prompt = f"""
    Based on the following context:
    {context}

    Please recommend a restaurant.
    """

Geocoding Locations (Optional)

Enable geocoding to automatically add coordinates to LOCATION entities, enabling geospatial queries:

from neo4j_agent_memory import (
    MemoryClient,
    MemorySettings,
    GeocodingConfig,
    GeocodingProvider,
)

settings = MemorySettings(
    geocoding=GeocodingConfig(
        enabled=True,
        provider=GeocodingProvider.NOMINATIM,  # Free, or GOOGLE for higher accuracy
    )
)

async with MemoryClient(settings) as memory:
    # LOCATION entities are automatically geocoded
    await memory.short_term.add_message(
        session_id="session-123",
        role="user",
        content="I'm visiting the Eiffel Tower in Paris",
    )

    # Find locations near a point
    nearby = await memory.long_term.search_locations_near(
        latitude=48.8584,
        longitude=2.2945,
        radius_km=5.0,
    )

See Geocoding Configuration for more details.

Configuration with Environment Variables

You can configure neo4j-agent-memory using environment variables with the NAM_ prefix:

# Neo4j connection
export NAM_NEO4J__URI=bolt://localhost:7687
export NAM_NEO4J__USERNAME=neo4j
export NAM_NEO4J__PASSWORD=your-password

# OpenAI configuration
export NAM_EMBEDDING__PROVIDER=openai
export NAM_EMBEDDING__MODEL=text-embedding-3-small
export OPENAI_API_KEY=sk-...

# Extraction configuration
export NAM_EXTRACTION__EXTRACTOR_TYPE=pipeline
export NAM_EXTRACTION__ENABLE_SPACY=true
export NAM_EXTRACTION__ENABLE_GLINER=true
export NAM_EXTRACTION__ENABLE_LLM_FALLBACK=true

Then create the client without explicit configuration:

from neo4j_agent_memory import MemoryClient, MemorySettings

# Settings loaded from environment variables
settings = MemorySettings()
async with MemoryClient(settings) as memory:
    # Your memory operations here
    pass

Other env vars in your .env (e.g. plain NEO4J_URI=…​, OPENAI_API_KEY=…​ for unrelated tools) are silently ignored by MemorySettings — only NAM_*-prefixed vars are loaded. If you see extra_forbidden errors, upgrade to the next 0.2.x patch release and see the FAQ entry.

Error Handling

from neo4j_agent_memory import (
    MemoryClient,
    MemorySettings,
    ConnectionError,
    NotConnectedError,
    ExtractionError,
)

try:
    async with MemoryClient(settings) as memory:
        await memory.short_term.add_message(...)
except ConnectionError as e:
    print(f"Failed to connect to Neo4j: {e}")
except ExtractionError as e:
    print(f"Entity extraction failed: {e}")
except NotConnectedError as e:
    print(f"Client not connected: {e}")