Overview
The MongoDB Atlas Agent Engine memory service can run as a standalone service, separate from a full agent deployment. Use this guide to provision the memory server for a memory project and use the agent-engine-sdk-memory Python Software Development Kit (SDK) to record and retrieve conversation context from an external application.
You can run the memory service in one of the following modes:
Hosted: The memory server runs on the Atlas Agent Engine, and your application connects to it by using a service account access token. Use this mode for a deployed application.
Local: The memory server runs in local Docker containers managed by the
agentengineCLI, and your application connects to it directly. Use this mode to develop and test locally.
Hosted Memory Service
In hosted mode, the agent-engine-sdk-memory SDK connects to the hosted memory gateway by using a service account access token. The gateway reads the organization and project from the service account. For each conversation, you pass user_id and session_id values to the SDK to scope the conversation's memory to that user and session.
Tip
To learn more about memory, see the Agent Memory guide.
The following features are available in hosted mode:
record_turn(),build_context(), andsearch()SDK methods for recording and retrieving conversation contextSemantic, episodic, procedural, and taxonomic search
Direct create and read operations, in the form of
save_*,get_*orlist_*Custom memory types, by using the generic
save()andretrieve()methods
Local Memory Service
In local mode, the agent-engine-sdk-memory SDK connects directly to a local Orchestration Engine (oe) proxy that the agentengine dev up command starts on your machine. You must set the base_url value to the local oe URL. Do not set project_id or an access token for the connection.
The following features are available in local mode:
record_turn(),build_context(), andsearch()SDK methods for recording and retrieving conversation contextSemantic, episodic, procedural, and taxonomic search
Direct create and read operations, in the form of
save_*,get_*orlist_*
You cannot use custom memory types in local mode.
To learn more about the different memory types, see the Agent Memory guide.
Configure the Hosted Memory Service
This section shows how to create a memory-only project hosted on the Atlas Agent Engine by performing the following tasks:
Save the target project as a CLI context
Upload the required project secrets
Start the hosted memory runtime
Use the Python SDK to call the memory runtime from your application
Note
To create a memory-only project, you don't deploy an agent or create a workspace.
Prerequisites
Before you begin this tutorial, ensure that you have the following resources:
The
agentengineCLI installed and authenticated. Use version0.1.120or later. To learn more, see Install and Authenticate.Access to the Atlas Agent Engine by running
agentengine auth login.A Voyage AI API key for generating memory embeddings.
An API key for the LLM provider that you use for background extraction.
piporuvinstalled, which is required to install the Python SDK.Python 3.11 or later installed.
curlandjqinstalled.A provisioned Atlas cluster that meets the following requirements:
Your cluster is tier
M10or larger. Free and shared tiers are not supported, since they cannot hold the Atlas Search and Vector Search indexes that memory creates.Your connection string is percent-encoded and includes the database user's username and password. To learn how to retrieve your connection string, see the Connect to a Cluster guide.
Your Atlas user account has the Project Owner role on the Atlas project. Save the project ID and organization ID.
Your database user has the
readWriteAnyDatabaserole. Memory creates its own databases, so a user scoped to one database cannot authenticate to all required databases.
Note
If the linked Atlas cluster can't create the Search and Vector Search indexes that memory requires, the Atlas Agent Engine stops deployment at the Memory: waiting stage and might time out with an Error: context deadline exceeded error message.
Update Your IP Access List
Memory connects to your cluster from the Atlas Agent Engine network, not from your local machine. Before you provision memory, complete the following steps to add the Atlas Agent Engine Atlas addresses to your Atlas project's IP access list:
Add the required IP addresses.
Click the Add IP Address button on the top-right corner of the page. Add the following entries in the Access List Entry field, click Confirm, and wait until Atlas shows both as active in the Status column.
CIDR | Description |
|---|---|
| Atlas Agent Engine Atlas access |
| Atlas Agent Engine Atlas access |
If you skip these steps, memory never reaches a ready state and does not progress past the orchestration_engine status.
Important
These addresses are the production addresses that the Atlas Agent Engine uses for Atlas traffic. They differ from the egress addresses described in Manage Network Egress Policies, which cover traffic to external services other than Atlas. Do not add 0.0.0.0/0 to the IP access list.
Note
The agentengine atlas setup command adds these IP address entries for you. However, this command requires a workspace, which memory-only projects don't have.
Steps
Sign in and create a context.
To sign into the Atlas Agent Engine and create a context, complete the following steps:
Set the following values in your shell. Replace
<atlas-organization-id>and<atlas-project-id>with the IDs of the Atlas organization and project that contain your cluster:export PLATFORM_URL='https://agentengine.mongodb.com'export ORG_ID='<atlas-organization-id>'export PROJECT_ID='<atlas-project-id>'export MEMORY_CONTEXT='my-project'Run the following commands to sign in and confirm that the project is visible:
agentengine versionagentengine auth login --base-url "$PLATFORM_URL"agentengine project list --org-id "$ORG_ID" --base-url "$PLATFORM_URL"Run the following command to save the target project as a named context:
agentengine context create "$MEMORY_CONTEXT" \ --org-id "$ORG_ID" \ --project-id "$PROJECT_ID" \ --base-url "$PLATFORM_URL"A context names the platform, organization, and project. It doesn't require a workspace. Future steps pass
--context "$MEMORY_CONTEXT"to target this project.
Generate the memory configuration.
Scaffold a memory-only project, and choose the LLM that memory uses for background extraction.
To use a provider's public API, such as Anthropic with its default model, run the following command:
agentengine create --memory-only --name "My Project" --llm anthropic --yesTip
To choose a different provider, you can pass --llm openai or --llm gemini. To choose a different model, you can pass --llm-model <model>.
To use an OpenAI-compatible gateway, such as Azure AI Foundry, run the following command:
agentengine create --memory-only --name "My Project" \ --llm openai-compatible \ --llm-base-url '<https-base-url-ending-in-/v1>' \ --llm-model '<exact-model-or-deployment-name>' \ --llm-auth-header 'api-key' | 'authorization' \ --yesFor the --llm-auth-header flag, choose one of the following values based on the header your gateway expects:
api-key: Sends the key in anapi-keyheaderauthorization: SendsAuthorization: Bearer <key>
Verify your project-config.yaml file structure.
Either command from the preceding step creates a my-project directory that contains only a project-config.yaml file, with no agent.yaml file or workspace.
Navigate to the my-project directory and open the project-config.yaml file. Confirm that its memory: block resembles the following example:
memory_only: true
memory: voyage: model: "voyage-4-large" dimension: 1024
extraction_llm: provider: openai model: <exact-model-or-deployment-name> base_url: <https-base-url-ending-in-/v1> api_key_secret: LLM_API_KEY auth_header: api-key
background_extraction: snapshot: max_messages: 20 stale_minutes: 1
extraction: enabled: - semantic - episodic - taxonomic - proceduralIf you chose the public API option, the extraction_llm block omits the base_url and auth_header fields. When you pass --llm openai-compatible, the CLI stores it in the provider field as provider: openai.
Note
LLM Provider Keys
The extraction_llm block's api_key_secret field names the project secret that holds your LLM provider key. Both options set this field to LLM_API_KEY, so upload your key under that name in the next step, not as ANTHROPIC_API_KEY or OPENAI_API_KEY. This secret supplies only the key, and the extraction_llm block supplies the endpoint and model.
Upload project secrets.
Run the following commands to upload your project secrets and enter the corresponding values when prompted:
agentengine secret set MONGODB_URI --context "$MEMORY_CONTEXT" --project-scopeagentengine secret set VOYAGE_API_KEY --context "$MEMORY_CONTEXT" --project-scopeagentengine secret set LLM_API_KEY --context "$MEMORY_CONTEXT" --project-scopeThen, confirm that you successfully uploaded the secrets by running the following command:
agentengine secret list --context "$MEMORY_CONTEXT" --project-scopeImportant
The --project-scope flag is required when you pass the --context flag.
Don't pass secret values by using the --value flag or as a positional argument. Both are deprecated, because they can expose secrets to other processes on your machine. If you set the secret from a script, pipe the value to the command by using the --stdin flag.
Start memory.
From the my-project directory, run the following commands:
agentengine memory configure ./project-config.yaml --context "$MEMORY_CONTEXT"agentengine memory apply --wait --context "$MEMORY_CONTEXT"These commands perform the following actions:
agentengine memory configurestores the configuration.agentengine memory applyprovisions the memory runtime the first time, delivers the configuration, restarts memory, and waits until the runtime reports ready.
Monitor the memory status.
The memory runtime's own internal logs aren't visible. Instead, monitor the memory status in the following ways:
Run the
agentengine memory status --context "$MEMORY_CONTEXT"command.In the UI, open the project's Memory page from the Manage section. For a memory-only project, memory appears there, not on the Workspaces page.
Note
On a new project, the first agentengine memory apply command can fail with a memory-server deployment not found error. The runtime keeps provisioning in the background. Instead of re-running agentengine memory apply, continue to run the agentengine memory status command every minute and wait until the state value reads ready.
If the blocked_on field remains in your memory status output and your state value does not progress to ready, contact MongoDB Support and provide your output.
Create a service account and retrieve an access token.
Your application authenticates by using a service account access token, not your CLI login. To retrieve this access token, perform the following steps:
Run the following command to create a service account for the project:
agentengine service-account create memory-client \ --context "$MEMORY_CONTEXT" \ --role PROJECT_OWNER \ --enable-atlas-pairingSave the client ID and client secret from the command output. The Atlas Agent Engine shows the client secret only once.
Important
The
PROJECT_OWNERrole requires a paired Atlas service account. The--enable-atlas-pairingflag enables Atlas service-account pairing for the project, which allows theagentengine service-account createcommand to create this service account. Without the flag, non-interactive commands fail with a"Atlas service account pairing is disabled for this project"message.Export your client ID, and then run the following command to exchange the client ID and client secret for an access token.
curlprompts for the client secret without echoing it:export MEMORY_CLIENT_ID='<client-id>' export ACCESS_TOKEN=$(curl --fail-with-body --silent --show-error \ --user "$MEMORY_CLIENT_ID" \ --data grant_type=client_credentials \ "$PLATFORM_URL/api/v1/oauth/token" | jq -er .access_token)In a script or CI pipeline, read the client secret from your secret manager in code instead of relying on the interactive prompt. Don't pass the client secret as a command-line argument.
Tip
The access token is valid for one hour. Request a new token before the current one expires, and don't print it.
Install the Python SDK.
Run the following commands to install the agent-engine-sdk-memory package from PyPI, and pin the version:
python3 -m venv .venvsource .venv/bin/activatepython -m pip install 'agent-engine-sdk-memory==0.11.8'Important
Don't install the package from the Atlas Agent Engine package registry, because it currently serves an older SDK version.
Record and retrieve conversation context.
In your application, add the following code to create a client, bind a user identity, record turns, and retrieve relevant context for the same session:
import jsonimport osimport uuid
from agent_engine_sdk_memory import Memory, MemoryRequestContext
run_id = uuid.uuid4().hexsession_id = f"memory-setup-{run_id}"
with Memory( base_url=os.environ["PLATFORM_URL"], project_id=os.environ["PROJECT_ID"], service_account_token=os.environ["ACCESS_TOKEN"],) as memory: chat = memory.bind( MemoryRequestContext( user_id=f"memory-setup-user-{run_id}", session_id=session_id, ) )
# Record turns. chat.record_turn(role="user", content="My home airport is Boston Logan.") chat.record_turn(role="assistant", content="Understood, I noted your home airport as Boston Logan.")
# Retrieve context from the same session. context = chat.build_context( query="What is my home airport?", enabled_sources={"stm"}, max_tokens=2048, ) assert "Boston Logan" in json.dumps(context.formatted_context), ( "The recorded turn was not returned" ) print("PASS: turn recording and same-session context")To learn more about the SDK, including how identity and context retrieval work, see the agent-engine-sdk-memory reference.
Tip
This script retrieves only short-term memory, which is available immediately. Long-term memory, such as the semantic and episodic sources, is extracted asynchronously and can take a minute or two to appear. To learn how extraction works, see Memory Extraction.
A lone trailing user message is intentionally not consolidated or extracted to the memory service. To extract memories, record a user turn followed by an assistant turn.
Update Memory Configuration or Rotate a Key
To change the memory configuration, edit the memory: block in your project-config.yaml file, and then run the following commands:
agentengine memory configure ./project-config.yaml --context "$MEMORY_CONTEXT"agentengine memory apply --wait --context "$MEMORY_CONTEXT"The agentengine memory apply command does not reload secrets. It restarts memory by using the values memory already has stored. To rotate an existing secret, such as your LLM provider key, pass the --sync flag instead:
agentengine secret set LLM_API_KEY --context "$MEMORY_CONTEXT" --project-scope --syncIf you previously ran agentengine secret set without --sync, run the following command to apply the new value:
agentengine secret sync --context "$MEMORY_CONTEXT" --project-scopeFor a memory-only project, this command prints a message that there are no active deployments to sync, but it still refreshes the secrets that memory uses. Wait a few minutes, and then run agentengine memory status to confirm that the state field in your output still reads ready after the rotation.
To learn how to configure memory on the platform, see Configure Memory.
Configure the Local Memory Service
This section shows how to scaffold, start, and connect to a local memory stack.
Prerequisites
Before you begin this tutorial, ensure that you have the following resources:
The
agentengineCLI installed. To learn more, see Install and Authenticate.A Voyage AI API key for generating memory embeddings.
An API key for a large language model (LLM) provider, such as
ANTHROPIC_API_KEY, if you enable background extraction.piporuvinstalled to install the Python SDK.
Steps
Scaffold a local memory project.
Run the following command to scaffold a memory-only project for local development. Replace "My Project" with your project name:
agentengine create --memory-only --name "My Project"The command writes a project-config.yaml file that sets memory_only to true and specifies the memory configuration schema.
This command does not generate an agent.yaml file, an agents/ directory, or agent runtime code. You cannot combine the --memory-only flag with the --template, --memory, or --open-egress flags. To choose the extraction provider at scaffold time, you can combine the --memory-only flag with --llm.
Configure environment variables.
Create an .env file in your project directory, and then set the following variables in the file:
VOYAGE_API_KEY: Required for Voyage AI embeddingsLLM provider key, such as
ANTHROPIC_API_KEY: Required if background extraction is enabled inproject-config.yaml
You don't need to set the MONGODB_URI variable. The agentengine dev up command provisions and connects to the bundled local MongoDB container automatically. If you want to use an external MongoDB instance instead, set this variable.
Start the local stack.
From the project directory, run the following command to start the local memory stack:
agentengine dev upFor a memory-only project, this command starts only the following containers:
mongodb: A local Atlas-compatible MongoDB instancememory-server: The memory runtime serviceoe: The local Orchestration Engine proxy that the SDK connects through
The command output includes the URLs for the local oe and memory-server services. Copy the oe URL to use in a future step.
Use the following commands to manage the local stack:
Command | Description |
|---|---|
| Shows the status of the local stack. |
| Streams logs for all services. Pass |
| Stops the local stack without removing containers. |
| Stops the local stack and removes containers and volumes. |
Connect the SDK to the local stack.
Navigate to your Python application directory. This directory can be separate from the project directory that you created in the first step.
Then, connect to the local stack by adding the following code to your application. Replace http://localhost:<oe-port> with the URL that you copied from the agentengine dev up command output.
from agent_engine_sdk_memory import Memory, MemoryRequestContext
# Set the base_url to the local oe URL printed by "agentengine dev up".memory = Memory(base_url="http://localhost:<oe-port>")
# Bind conversation identity.session = memory.bind( MemoryRequestContext( user_id="user_123", session_id="session_456", ))
# Record a user turn and an assistant turn.session.record_turn(role="user", content="I prefer window seats on flights.")session.record_turn(role="assistant", content="Got it, I'll remember that you prefer window seats on flights.")
# Build context.context = session.build_context( query="What seat preferences are known?", enabled_sources={"stm", "semantic", "episodic"},)print(context.formatted_context)Troubleshoot Local Connection Errors
When running a local memory stack, you might see a MemoryRouteNotFoundError (404) error. To address this error, ensure that you do not set the project_id value.
The SDK uses your project_id value to identify the URL path that receives requests. When project_id is not set, as is the case for local connections, the SDK sends requests to a path that the local oe proxy serves. When project_id is set, the SDK sends requests to a project-scoped path that only the hosted Atlas Agent Engine serves. A local stack does not serve the project-scoped path, so a request sent to this path generates an error.
If a stale AGENTIC_MEMORY_PROJECT_ID environment variable is set in your shell from the hosted workflow, the SDK requests a project-scoped route, which returns a MemoryRouteNotFoundError against a local stack. Before connecting to a local stack, unset this variable by running the following command:
unset AGENTIC_MEMORY_PROJECT_IDNext Steps
To enable memory for an agent that runs on the Atlas Agent Engine, see the Add Memory to Your Agent guide.