---
title: "Mem0 Strands"
description: "The mem0-strands integration provides persistent long-term memory for Strands agents, bridging the framework's MemoryStore abstraction with Mem0 backend capabilities. By plugging directly into the ..."
last_updated: "2026-10-11T17:37:10.229915+00:00"
canonical_url: "https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/ecosystem-integrations/mem0-strands"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [integrations/mem0-strands/python/src/mem0_strands/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/__init__.py)
- [integrations/hermes-plugin-mem0/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/hermes-plugin-mem0/__init__.py)
- [integrations/mem0-strands/python/src/mem0_strands/store.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py)
- [integrations/mem0-agent-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-agent-plugin/core/memory_core.py)
- [integrations/antigravity-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/antigravity-plugin/core/memory_core.py)
- [integrations/opencode-plugin/opencode-mem0.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/opencode-plugin/opencode-mem0.ts)
- [integrations/codex-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/codex-plugin/core/memory_core.py)
- [integrations/cursor-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/cursor-plugin/core/memory_core.py)
- [integrations/agent-plugin-core/python/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/agent-plugin-core/python/memory_core.py)
- [integrations/mem0-strands/python/src/mem0_strands/client.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py)
- [integrations/kimi-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/kimi-plugin/core/memory_core.py)
- [integrations/claude-code-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/claude-code-plugin/core/memory_core.py)
- [mem0/memory/main.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/memory/main.py)
- [integrations/antigravity-plugin/core/memory_cli.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/antigravity-plugin/core/memory_cli.py)
- [integrations/cursor-plugin/core/memory_cli.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/cursor-plugin/core/memory_cli.py)
- [mem0-ts/src/community/src/integrations/langchain/mem0.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/community/src/integrations/langchain/mem0.ts)
- [mem0/embeddings/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/embeddings/__init__.py)
- [integrations/mem0-strands/python/src/mem0_strands/telemetry.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py)
- [mem0-ts/src/oss/src/prompts/index.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/prompts/index.ts)
- [mem0/memory/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/memory/__init__.py)
- [mem0/client/main.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/client/main.py)
- [integrations/mem0-strands/python/pyproject.toml](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/pyproject.toml)
- [mem0/configs/embeddings/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/embeddings/__init__.py)
- [mem0/vector_stores/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/vector_stores/__init__.py)
- [mem0/client/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/client/__init__.py)
- [mem0/configs/rerankers/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/__init__.py)
</details>

## Overview

The `mem0-strands` integration provides persistent long-term memory for Strands agents, bridging the framework's `MemoryStore` abstraction with Mem0 backend capabilities. By plugging directly into the agent loop via `MemoryManager`, it handles cross-session recall and automated memory injection and extraction without requiring explicit model-called tool invocations.

Sources: [integrations/mem0-strands/python/src/mem0_strands/__init__.py:1-11](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/__init__.py#L1-L11), [integrations/mem0-strands/python/src/mem0_strands/store.py:1-10](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L1-L10)

## Strands Package Architecture and Package Setup

### Package Structure and Build Configuration

The `mem0-strands` package is structured around the `hatchling` build backend, defining its core metadata, dependencies, and development environments inside `pyproject.toml`. The package requires Python `>=3.10` and licenses under Apache-2.0.

| Project Metadata Key | Value | Sources |
| :--- | :--- | :--- |
| `name` | `mem0-strands` | [integrations/mem0-strands/python/pyproject.toml:6-6](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/pyproject.toml#L6-L6) |
| `version` | `0.1.1` | [integrations/mem0-strands/python/pyproject.toml:7-7](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/pyproject.toml#L7-L7) |
| `requires-python` | `>=3.10` | [integrations/mem0-strands/python/pyproject.toml:10-10](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/pyproject.toml#L10-L10) |
| `license` | `Apache-2.0` | [integrations/mem0-strands/python/pyproject.toml:11-11](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/pyproject.toml#L11-L11) |

Sources: [integrations/mem0-strands/python/pyproject.toml:1-25](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/pyproject.toml#L1-L25)

The package relies on `strands-agents>=1.45.0` for the `strands.memory` module, which introduces the `MemoryStore` and `MemoryManager` abstractions, alongside `mem0ai>=2.0.11` for memory management functionality.

```
# strands-agents>=1.45.0: first release shipping the `strands.memory` module
# (MemoryStore / MemoryManager) that Mem0MemoryStore implements.
dependencies = [
    "strands-agents>=1.45.0",
    "mem0ai>=2.0.11",
]
```
Sources: [integrations/mem0-strands/python/pyproject.toml:27-32](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/pyproject.toml#L27-L32)

> [!NOTE]
> `strands-agents>=1.45.0` is a strict dependency because it is the first release shipping the `strands.memory` module that `Mem0MemoryStore` implements.

Sources: [integrations/mem0-strands/python/pyproject.toml:27-28](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/pyproject.toml#L27-L28)

### High-Level Module Exports

The package root exposes key integration classes through `__all__`, allowing direct imports from `mem0_strands`. Version resolution is handled dynamically using `importlib.metadata`, falling back to `0.0.0+unknown` if the package metadata is missing in source tree executions.

```python
from importlib.metadata import PackageNotFoundError, version

from mem0_strands.client import Mem0ServiceClient
from mem0_strands.store import Mem0MemoryStore

__all__ = [
    "Mem0MemoryStore",
    "Mem0ServiceClient",
]

try:
    __version__ = version("mem0-strands")
except PackageNotFoundError:  # pragma: no cover - only when running from a source tree
    __version__ = "0.0.0+unknown"
```
Sources: [integrations/mem0-strands/python/src/mem0_strands/__init__.py:13-26](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/__init__.py#L13-L26)

## Mem0 Memory Store Implementation

### Initialization and Entity Scoping

`Mem0MemoryStore` extends the Strands `MemoryStore` abstraction to provide cross-session recall and automated memory synchronization. During instantiation, the store validates that at least one entity scope field is provided among `user_id`, `agent_id`, `run_id`, or `app_id`. 

| Scope Field | Description | Sources |
| :--- | :--- | :--- |
| `user_id` | Mem0 user namespace that owns the memories | [integrations/mem0-strands/python/src/mem0_strands/store.py:66-84](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L66-L84) |
| `agent_id` | Mem0 agent namespace | [integrations/mem0-strands/python/src/mem0_strands/store.py:67-85](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L67-L85) |
| `run_id` | Mem0 run/session namespace | [integrations/mem0-strands/python/src/mem0_strands/store.py:68-86](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L68-L86) |
| `app_id` | Mem0 app namespace (platform only) | [integrations/mem0-strands/python/src/mem0_strands/store.py:69-87](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L69-L87) |

Sources: [integrations/mem0-strands/python/src/mem0_strands/store.py:50-124](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L50-L124)

> [!CAUTION]
> The `app_id` scope is restricted to the Mem0 platform. Attempting to combine `app_id` with a self-hosted configuration dictionary via `config` triggers a `ValueError` during initialization because self-hosted Mem0 instances do not support app-level scoping on write operations.

Sources: [integrations/mem0-strands/python/src/mem0_strands/store.py:115-123](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L115-L123)

### Client Management and Search Execution

The underlying `Mem0ServiceClient` is constructed lazily on first access. Because initializing the client can block the event loop—such as validating platform API keys over HTTP or building vector stores and embedders for self-hosted instances—client resolution and initial telemetry recording execute inside worker threads via `asyncio.to_thread`.

```python
@property
def client(self) -> Mem0ServiceClient:
    """The Mem0 service client, constructed lazily on first use.

    Note: constructing the underlying SDK client can block (the platform client
    validates the API key over HTTP; the OSS client builds embedders / vector
    stores), so first use is deferred and always happens inside a worker thread
    via :func:`asyncio.to_thread`, never on the event loop.
    """
    client_injected = self._client is not None
    if self._client is None:
        self._client = Mem0ServiceClient(api_key=self._api_key, host=self._host, config=self._config)
    if not self._recorded_init:
        self._recorded_init = True
        telemetry.record(
            "store.init",
            self._client,
            scopes=sorted(self.scope),
            writable=self.writable,
            extraction_enabled=bool(self.extraction),
            has_default_metadata=bool(self.metadata),
            max_search_results=self.max_search_results,
            host_overridden=bool(self._host),
            client_injected=client_injected,
        )
    return self._client
```
Sources: [integrations/mem0-strands/python/src/mem0_strands/store.py:141-166](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L141-L166)

Semantic search queries retrieve matching entries ordered by relevance. The search method resolves the maximum result limit by checking search options, falling back to the store's default configuration, or defaulting to `5` (`DEFAULT_MAX_SEARCH_RESULTS`).

```python
DEFAULT_MAX_SEARCH_RESULTS = 5
```
Sources: [integrations/mem0-strands/python/src/mem0_strands/store.py:48-48](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L48-L48)

```python
async def search(self, query: str, options: SearchOptions | None = None) -> list[MemoryEntry]:
    """Search Mem0 for entries matching ``query``, ordered by relevance."""
    top_k = options.get("max_search_results") if options is not None else None
    if top_k is None:
        top_k = self.max_search_results
    if top_k is None:
        top_k = DEFAULT_MAX_SEARCH_RESULTS

    # ``self.client`` is resolved inside the thread so lazy construction (a
    # blocking call) does not run on the event loop.
    started = time.perf_counter()
    try:
        memories = await asyncio.to_thread(lambda: self.client.search_memories(query, self.scope, top_k))
    except Exception as exc:
        self._record("store.search", started, False, top_k=top_k, error_kind=telemetry.error_kind(exc))
        raise
    self._record("store.search", started, True, top_k=top_k, result_count=len(memories))
    return [self._to_entry(memory) for memory in memories]

```
Sources: [integrations/mem0-strands/python/src/mem0_strands/store.py:168-186](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L168-L186)

## Service Client Wrapper and Client Abstractions

### Backend Initialization and Resolution Strategy

The `Mem0ServiceClient` class acts as an adaptation layer bridging `Mem0MemoryStore` to either the hosted Mem0 platform client (`mem0.MemoryClient`) or the self-hosted OSS client (`mem0.Memory`). Instantiation follows a strict priority order based on the parameters passed by callers:

- Pre-built `client`: Uses the provided client instance directly. Asynchronous client types are explicitly rejected during initialization, raising a `ValueError` because the store executes synchronous SDK operations inside worker threads via `asyncio.to_thread`.
- Configuration `config`: Imports `Memory` from `mem0` and constructs a self-hosted backend via `Memory.from_config(config)`, setting `is_platform` to `False`.
- Default hosted platform: Imports `MemoryClient` from `mem0`, resolves the API key from the explicit `api_key` argument or the `MEM0_API_KEY` environment variable, and initializes the platform client with an optional custom `host`.

```python
def __init__(
    self,
    api_key: str | None = None,
    host: str | None = None,
    config: dict[str, Any] | None = None,
    client: Any | None = None,
) -> None:
    """Initialize the Mem0 client.

    Args:
        api_key: Mem0 platform API key. Falls back to ``$MEM0_API_KEY``.
        host: Mem0 platform base URL. Defaults to the SDK default
            (``https://api.mem0.ai``).
        config: A Mem0 OSS config dict; when given, a self-hosted
            :class:`mem0.Memory` is built instead of the platform client.
        client: A pre-built Mem0 client to use directly (platform or OSS).

    Raises:
        ValueError: If ``client`` is an async Mem0 client (its coroutines
            would never be awaited off the worker thread).
    """
    if client is not None:
        if _is_async_client(client):
            raise ValueError(
                "Async Mem0 clients are not supported. Pass a synchronous "
                "mem0.MemoryClient (or a mem0.Memory / config): the store runs the "
                "SDK in a worker thread, so an async client's coroutines would "
                "never be awaited and every write would silently no-op."
            )
        self.mem0 = client
        self.is_platform = _is_platform_client(client)
        return

    if config is not None:
        try:
            from mem0 import Memory
        except ImportError as err:  # pragma: no cover - exercised via install docs
            raise ImportError(
                "The mem0ai package is required. Install it with: pip install 'mem0-strands'"
            ) from err
        self.mem0 = Memory.from_config(config)
        self.is_platform = False
        return

    try:
        from mem0 import MemoryClient
    except ImportError as err:  # pragma: no cover - exercised via install docs
        raise ImportError("The mem0ai package is required. Install it with: pip install 'mem0-strands'") from err
    api_key = api_key or os.environ.get("MEM0_API_KEY")
    # MemoryClient(host=None) would override the SDK default with None, so only
    # pass host when the caller actually set one.
    self.mem0 = MemoryClient(api_key=api_key, host=host) if host else MemoryClient(api_key=api_key)
    self.is_platform = True

```
Sources: [integrations/mem0-strands/python/src/mem0_strands/client.py:60-113](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L60-L113)

> [!WARNING]
> Passing an asynchronous Mem0 client such as `AsyncMemoryClient` triggers a `ValueError` during initialization. Because `add` and `search` on async clients are coroutine functions, running them inside `asyncio.to_thread` would return un-awaited coroutine objects, causing every memory write and search query to silently no-op.

Sources: [integrations/mem0-strands/python/src/mem0_strands/client.py:24-28](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L24-L28), [integrations/mem0-strands/python/src/mem0_strands/client.py:81-89](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L81-L89)

### Scope Validation and Write Adapters

`Mem0ServiceClient` validates entity scopes prior to executing storage or search requests against the underlying SDK. Specifically, the `_check_scope` method enforces backend capabilities by rejecting `app_id` usage when interacting with self-hosted OSS instances, as OSS `Memory` implementations lack support for app-level namespaces.

```python
def _check_scope(self, scope: dict[str, str]) -> None:
    """Reject scope the selected backend cannot honor.

    ``app_id`` exists only on the platform; the OSS ``Memory`` API has no
    ``app_id`` parameter, so we fail loudly here rather than let it surface as
    a ``TypeError`` on ``add`` or silently miss on ``search``.
    """
    if not self.is_platform and "app_id" in scope:
        raise ValueError(
            "app_id is a Mem0 platform-only scope. The OSS backend supports "
            "user_id, agent_id, and run_id; drop app_id or use the platform client."
        )

```
Sources: [integrations/mem0-strands/python/src/mem0_strands/client.py:114-126](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L114-L126)

Platform write operations automatically attach a telemetry source tag via `_write_extras`, appending `{"source": "STRANDS"}` to attribute generated memories correctly within the Mem0 backend allowlist. Self-hosted OSS writes omit this tag to prevent signature validation errors from unknown keyword arguments.

```python
# Tags platform writes so Mem0's backend attributes the memory to this integration
# in telemetry (recognized values live in the backend's KNOWN_EVENT_SOURCES
# allowlist; unknown ones bucket into "OTHERS"). Platform only.
_SOURCE = "STRANDS"

```
Sources: [integrations/mem0-strands/python/src/mem0_strands/client.py:30-34](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L30-L34)

```python
def _write_extras(self) -> dict[str, str]:
    """Extra kwargs attached to platform writes: the telemetry ``source`` tag."""
    return {"source": _SOURCE} if self.is_platform else {}
```
Sources: [integrations/mem0-strands/python/src/mem0_strands/client.py:127-129](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L127-L129)

The client exposes three core methods for data manipulation and retrieval:

| Method | Parameters | Description | Sources |
| :--- | :--- | :--- | :--- |
| `store_memory` | `content`, `scope`, `metadata` | Stores a single discrete fact verbatim with `infer=False` and merged write extras | [integrations/mem0-strands/python/src/mem0_strands/client.py:131-144](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L131-L144) |
| `store_messages` | `messages`, `scope` | Submits rendered conversation turns for server-side extraction with `infer=True` | [integrations/mem0-strands/python/src/mem0_strands/client.py:146-154](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L146-L154) |
| `search_memories` | `query`, `scope`, `top_k` | Performs semantic search wrapping scope filters and normalizes the payload via `_extract_results` | [integrations/mem0-strands/python/src/mem0_strands/client.py:155-163](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L155-L163) |

Sources: [integrations/mem0-strands/python/src/mem0_strands/client.py:131-164](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L131-L164)

Search responses handle structural variations across Mem0 API versions by inspecting result payloads. The helper function `_extract_results` checks whether the response is a dictionary containing a `"results"` key or a bare list, returning a safe list of memory dictionaries in both cases.

```python
def _extract_results(response: Any) -> list[dict[str, Any]]:
    """Normalize a Mem0 search response to a list of memory dicts.

    Mem0 returns ``{"results": [...]}`` (v1.1) or, on older paths, a bare list.
    """
    if isinstance(response, dict):
        results = response.get("results", [])
        return list(results) if isinstance(results, list) else []
    if isinstance(response, list):
        return response
    return []
```
Sources: [integrations/mem0-strands/python/src/mem0_strands/client.py:166-176](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/client.py#L166-L176)

## Strands Memory Ingestion and Message Serialization

### Message Ingestion and Extraction Sinks

`Mem0MemoryStore` provides dual write mechanisms for capturing conversation history: single-fact ingestion via `add` and batch message processing via `add_messages`. The `add` method writes a single distilled fact verbatim by passing `infer=False` to the underlying client, serving as the storage sink for explicit tools like `add_memory`. Conversely, `add_messages` takes raw conversation turns and routes them directly to Mem0 for server-side extraction with `infer=True`, eliminating client-side model overhead while leveraging server-side deduplication.

```python
``Mem0MemoryStore`` implements both write sinks, which is what sets it apart from a
vector-DB-style store:

- :meth:`add` writes a single distilled fact verbatim (``infer=False``). This is
  the sink for the ``add_memory`` tool and for a client-side extractor.
- :meth:`add_messages` renders raw conversation turns to text and hands them to
  Mem0 for **server-side extraction** (``infer=True``). Because this sink exists,
  enabling ``extraction`` routes messages straight to Mem0's own extraction
  pipeline -- no extra client-side model call, and Mem0's de-duplication applies.

```
Sources: [integrations/mem0-strands/python/src/mem0_strands/store.py:10-19](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L10-L19)

> [!NOTE]
> Extraction writes using `add_messages` operate with at-least-once semantics, safely tolerating duplicate content submissions because Mem0 handles de-duplication natively on the server side.

Sources: [integrations/mem0-strands/python/src/mem0_strands/store.py:187-191](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/store.py#L187-L191)

## Telemetry Integration and Usage Diagnostics

### Anonymous Event Dispatch and Privacy Controls

The telemetry subsystem records anonymous usage diagnostics for the Strands memory store without introducing extra dependencies by leveraging the Mem0 SDK's built-in PostHog client. Events are dispatched via `client_telemetry.capture_event` under the namespace `strands.*` and include standard properties such as language, integration source, package version, and backend type.

```python
def record(event: str, client: Mem0ServiceClient, **properties: Any) -> None:
    """Send one strands.* usage event. Never raises."""
    try:
        client_telemetry.capture_event(
            f"strands.{event}",
            {
                "source": SOURCE,
                "language": "python",
                "strands_store_version": _VERSION,
                "backend": "platform" if client.is_platform else "oss",
                **properties,
            },
            _distinct_id(client),
        )
```
Sources: [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:55-68](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L55-L68)

> [!WARNING]
> Telemetry collection strictly omits sensitive data. Captured properties never include queries, memory text, message content, entity identifiers, metadata dictionaries, or API keys.

Sources: [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:9-13](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L9-L13)

Users can completely opt out of anonymous usage tracking by setting the environment variable `MEM0_TELEMETRY=false`. Additionally, all telemetry dispatch calls are wrapped in exception-suppressing blocks so that telemetry failures never interrupt agent execution.

```python
Opt out with MEM0_TELEMETRY=false.
```
Sources: [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:12-12](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L12-L12)

```python
except Exception:
    pass
```
Sources: [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:69-70](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L69-L70)

### Distinct Identity and Error Classification

Identity attribution adapts dynamically depending on whether the store connects to the hosted platform or a self-hosted backend. The helper function `_distinct_id` inspects the underlying client instance for a `user_email` attribute, falling back to `None` so the SDK automatically uses its machine-local anonymous identifier for OSS deployments.

Sources: [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:49-53](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L49-L53)

Failures encountered during operations are categorized into content-free error kinds before being recorded in telemetry properties. The classifier inspects exception type names and string representations to map errors into standard diagnostic labels:

| Condition / Match String | Error Kind Label | Sources |
| :--- | :--- | :--- |
| `"timeout"` or `"timed out"` | `"timeout"` | [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:36-37](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L36-L37) |
| `"401"`, `"403"`, `"unauthor"`, or `"forbidden"` | `"auth"` | [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:38-39](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L38-L39) |
| `"429"` or `"rate limit"` | `"rate-limited"` | [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:40-41](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L40-L41) |
| `"500"`, `"502"`, `"503"`, or `"504"` | `"server-error"` | [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:42-43](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L42-L43) |
| `"400"` or `"422"` | `"bad-request"` | [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:44-45](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L44-L45) |
| Unmatched exceptions | `type(exc).__name__` | [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:46-46](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L46-L46) |

Sources: [integrations/mem0-strands/python/src/mem0_strands/telemetry.py:33-46](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/mem0-strands/python/src/mem0_strands/telemetry.py#L33-L46)

## Related

- [Memory Lifecycle](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/python-core/memory-lifecycle)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/llms.txt) for all pages in this wiki.
