Skip to content

[langgraph]: Long-term memory with MongoDB Atlas (Python) #4890

Description

Type of issue

request for content

Language

Python

Description

Add a Python long-term memory integration guide using MongoDBStore with Atlas, covering setup, storage/search operations, and tool-based read/write examples.

Proposed Changes

Long-term memory lets your agent store and recall information across different conversations and sessions. This guide shows how to use MongoDB Atlas as the persistent store backend.

MongoDB Atlas stores memories as documents in a collection, supports vector search for semantic recall, and can serve as both the long-term memory store and the vector store in a single deployment.

For a deeper dive into memory types and strategies for writing memories, see the [Memory conceptual guide](/oss/concepts/memory#long-term-memory).

Setup

Installation

pip install langgraph-checkpoint-mongodb

Credentials

Set your Atlas connection string as an environment variable:

import os

os.environ["MONGODB_ATLAS_URI"] = "your-atlas-connection-string"

If you want automated tracing from individual queries, set your LangSmith API key:

os.environ["LANGSMITH_API_KEY"] = "your-langsmith-api-key"
os.environ["LANGSMITH_TRACING"] = "true"

Usage

Create a MongoDBStore and pass it to create_agent. Call store.setup() once on first use — it creates the necessary indexes and collections on your Atlas cluster.

from langchain.agents import create_agent
from langchain_core.runnables import Runnable
from langgraph.store.mongodb import MongoDBStore  # type: ignore[import-not-found]

MONGODB_ATLAS_URI = "mongodb://localhost:27017"

with MongoDBStore.from_conn_string(MONGODB_ATLAS_URI) as store:
    store.setup()
    agent: Runnable = create_agent(
        "claude-sonnet-4-6",
        tools=[],
        store=store,
    )

Memory storage

LangGraph stores memories as JSON documents organized by namespace and key. Namespaces typically include a user or org ID to keep memories scoped.

The example below also configures vector indexing, which enables semantic search over stored memories.

from collections.abc import Sequence

from langgraph.store.base import IndexConfig
from langgraph.store.mongodb import MongoDBStore  # type: ignore[import-not-found]


def embed(texts: Sequence[str]) -> list[list[float]]:
    # Replace with an actual embedding function or LangChain embeddings object
    return [[1.0, 2.0] for _ in texts]


MONGODB_ATLAS_URI = "mongodb://localhost:27017"

with MongoDBStore.from_conn_string(
    MONGODB_ATLAS_URI,
    index=IndexConfig(embed=embed, dims=2),  # type: ignore[arg-type]
) as store:
    store.setup()
    user_id = "my-user"
    application_context = "chitchat"
    namespace = (user_id, application_context)
    store.put(
        namespace,
        "a-memory",
        {
            "rules": [
                "User likes short, direct language",
                "User only speaks English & Python",
            ],
            "my-key": "my-value",
        },
    )
    item = store.get(namespace, "a-memory")
    items = store.search(
        namespace, filter={"my-key": "my-value"}, query="language preferences"
    )

For more information about store operations, see the Stores guide.

Read long-term memory in tools

Tools can read from the store using the runtime parameter, which LangGraph injects automatically.

from dataclasses import dataclass

from langchain.agents import create_agent
from langchain.tools import ToolRuntime, tool
from langchain_core.runnables import Runnable
from langgraph.store.mongodb import MongoDBStore  # type: ignore[import-not-found]


@dataclass
class Context:
    user_id: str


MONGODB_ATLAS_URI = "mongodb://localhost:27017"

with MongoDBStore.from_conn_string(MONGODB_ATLAS_URI) as store:
    store.setup()
    store.put(("users",), "user_123", {"name": "John Smith", "language": "English"})

    @tool
    def get_user_info(runtime: ToolRuntime[Context]) -> str:
        """Look up user info."""
        assert runtime.store is not None
        user_info = runtime.store.get(("users",), runtime.context.user_id)
        return str(user_info.value) if user_info else "Unknown user"

    agent: Runnable = create_agent(
        "claude-sonnet-4-6",
        tools=[get_user_info],
        store=store,
        context_schema=Context,
    )

    result = agent.invoke(
        {"messages": [{"role": "user", "content": "look up user information"}]},
        context=Context(user_id="user_123"),
    )

Write long-term memory from tools

Tools can also write to the store using runtime.store.put, persisting data that survives across threads.

from dataclasses import dataclass

from langchain.agents import create_agent
from langchain.tools import ToolRuntime, tool
from langchain_core.runnables import Runnable
from langgraph.store.mongodb import MongoDBStore  # type: ignore[import-not-found]
from typing_extensions import TypedDict


@dataclass
class Context:
    user_id: str


class UserInfo(TypedDict):
    name: str


@tool
def save_user_info(user_info: UserInfo, runtime: ToolRuntime[Context]) -> str:
    """Save user info."""
    assert runtime.store is not None
    runtime.store.put(("users",), runtime.context.user_id, dict(user_info))
    return "Successfully saved user info."


MONGODB_ATLAS_URI = "mongodb://localhost:27017"

with MongoDBStore.from_conn_string(MONGODB_ATLAS_URI) as store:
    store.setup()
    agent: Runnable = create_agent(
        "claude-sonnet-4-6",
        tools=[save_user_info],
        store=store,
        context_schema=Context,
    )

    agent.invoke(
        {"messages": [{"role": "user", "content": "My name is John Smith"}]},
        context=Context(user_id="user_123"),
    )

Metadata

Metadata

Assignees

No one assigned

    Labels

    externalUser is not a member of langchain-ailanggraphFor docs changes to LangGraph

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions