> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mirage.strukto.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Mem0

> Mount a Mem0 memory scope as a read-only virtual filesystem.

The Mem0 resource exposes the memories of a single scope — a `user_id`,
`agent_id`, or `run_id` — as JSON files mounted at a prefix such as `/memory/`.
Each memory is one file named `<memory_id>.json`.

For API key setup, see [Mem0 Setup](/python/setup/mem0).

## Config

```python theme={null}
import os

from mirage import MountMode, Workspace
from mirage.resource.mem0 import Mem0Config, Mem0Resource

config = Mem0Config(
    api_key=os.environ["MEM0_API_KEY"],
    user_id=os.environ.get("MEM0_USER_ID"),
)
resource = Mem0Resource(config=config)
ws = Workspace({"/memory/": resource}, mode=MountMode.READ)
```

The resource is read-only and does not support snapshots. Set exactly one of
`user_id`, `agent_id`, or `run_id` (see [Setup](/home/setup/mem0)).

## Filesystem Layout

The tree is flat: the mount root lists one `<memory_id>.json` file per memory in
the configured scope.

```text theme={null}
/memory/
  6d1ba0fc-1f0c-495b-b5b1-9141b2674b37.json
  4d221f85-b200-4cf1-8eff-05e0ba71d145.json
```

`cat` returns the full memory JSON, including `memory`, `categories`,
`metadata`, `created_at`, `updated_at`, and `structured_attributes`:

```json theme={null}
{
  "id": "6d1ba0fc-1f0c-495b-b5b1-9141b2674b37",
  "memory": "User's name is Alex, follows a vegetarian diet, allergic to nuts",
  "categories": ["personal_details"],
  "created_at": "2026-06-15T00:34:18-07:00",
  "updated_at": "2026-06-15T00:34:22-07:00"
}
```

`stat` reports `updated_at` (falling back to `created_at`) as the modified time
and exposes both timestamps.

## Reading Memories

```bash theme={null}
ls /memory/
find /memory/ -type f
cat /memory/6d1ba0fc-1f0c-495b-b5b1-9141b2674b37.json
jq '.memory' /memory/6d1ba0fc-1f0c-495b-b5b1-9141b2674b37.json
wc /memory/6d1ba0fc-1f0c-495b-b5b1-9141b2674b37.json
```

### grep and rg search the JSON files

`grep` and `rg` follow normal filesystem semantics and search the same JSON
bytes that `cat` returns. A match can therefore come from the memory text or
from metadata such as categories and timestamps. Because the mount is a
directory, plain `grep` needs `-r` (or a glob); `rg` recurses by default:

```bash theme={null}
grep -r "banana" /memory/
grep "banana" /memory/*.json
rg "banana" /memory/
```

## Search

The `search` command calls Mem0's semantic search API within the configured
scope. Use it when meaning matters more than exact text.

```bash theme={null}
search "what does the user eat for breakfast" /memory/
search --top-k 5 "morning routine" /memory/
search --threshold 0.4 "movie preferences" /memory/
```

`top-k` defaults to `default_search_limit` (10). `threshold` must be between `0`
and `1`. Results are emitted one hit per block, ranked by score:

```text theme={null}
/memory/6d1ba0fc-1f0c-495b-b5b1-9141b2674b37.json:0.91
User asked for food recommendations to stay full in the morning
```

## Cache

The resource uses Mirage's index cache for the virtual tree. The first `ls`
fetches the scope's memories (following Mem0 pagination) and primes the cache;
read commands reuse the cached metadata and rendered bytes until the cache
expires or the workspace is recreated. `search` always calls the Mem0 API
directly and is not cached.

## Example

```python theme={null}
import asyncio
import os

from dotenv import load_dotenv

from mirage import MountMode, Workspace
from mirage.resource.mem0 import Mem0Config, Mem0Resource

load_dotenv(".env.development")

config = Mem0Config(
    api_key=os.environ["MEM0_API_KEY"],
    user_id=os.environ.get("MEM0_USER_ID"),
)
resource = Mem0Resource(config=config)


async def main() -> None:
    ws = Workspace({"/memory/": resource}, mode=MountMode.READ)

    r = await ws.execute("ls /memory/")
    print(await r.stdout_str())

    r = await ws.execute("grep -r -i 'allergic' /memory/")
    print(await r.stdout_str())

    r = await ws.execute('search --top-k 5 "morning routine" /memory/')
    print(await r.stdout_str())


if __name__ == "__main__":
    asyncio.run(main())
```

## Shell Commands

| Command         | Notes                                                      |
| --------------- | ---------------------------------------------------------- |
| `ls`            | List the memory files in the scope                         |
| `cat`           | Read a memory's full JSON                                  |
| `jq`            | Query a memory's JSON fields                               |
| `head` / `tail` | Read the first or last lines/bytes of a memory JSON        |
| `grep`          | Search rendered JSON (use `-r` on a directory)             |
| `rg`            | Search rendered JSON, recursive by default                 |
| `find`          | Search the virtual tree by name, type, depth, and size     |
| `wc`            | Count lines, words, bytes, characters, and max line length |
| `stat`          | Show a memory's size and timestamps                        |
| `search`        | Semantic search through Mem0, ranked by score              |
