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:
The SDK surface is the same for both — |
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
Install with extras
Choose the extras that match your needs:
| Extra | Description | Command |
|---|---|---|
|
OpenAI embeddings and LLM extraction |
|
|
spaCy NER extraction (local) |
|
|
GLiNER zero-shot NER (local) |
|
|
Full extraction pipeline (spaCy + GLiNER) |
|
|
Local embeddings with Sentence Transformers |
|
|
Command-line interface for extraction and schemas |
|
|
OpenTelemetry tracing for observability |
|
|
Opik LLM-focused observability |
|
|
Google Vertex AI embeddings |
|
|
Amazon Bedrock embeddings (Titan, Cohere) |
|
|
AWS cloud provider bundle (Bedrock) |
|
|
AWS Strands Agents SDK integration |
|
|
All features including local models |
|
Setting Up Neo4j
Option 1: Docker (Recommended for Development)
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 |
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}")