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

# MCP Integration

> Connect Anona Memory to Claude Code, Claude Desktop, and other MCP clients, with no integration code.

Anona exposes memory over the Model Context Protocol, so an MCP-capable assistant can
record and recall context directly.

## Tools

| Tool | What it does | Transport |
| - | - | - |
| `record` | Stores a memory in a space. Optional `user_id` / `agent_id` / `session_id` scope it. | All |
| `retrieve` | Semantically searches memories in a space. Pass the same scope keys to see only that user's memories, and `tag_groups` for a [boolean tag filter](https://docs.memory.anonalabs.com/api-reference/retrieve.md#compound-tag-filters). With `route: "auto"` it picks the space, and `max_targets` caps how many it may search — when more than one is searched each memory is labelled with the space it came from. | All |
| `list_spaces` | Lists the available memory spaces. | All |
| `reason` | Synthesizes an answer from accumulated memories. Takes `depth: "thorough"` to read past the space's [memory models](https://docs.memory.anonalabs.com/api-reference/models.md) — see [Depth](https://docs.memory.anonalabs.com/api-reference/reason.md#depth). | All |
| `get_profile` | Reads a space's standing profile and the [memory models](https://docs.memory.anonalabs.com/api-reference/models.md) it keeps current. | Remote and `anona mcp` (not `anona-mcp`) |
| `get_model` | Reads one memory model, the space's current answer to a standing question, such as how this user prefers to be communicated with. | Remote and `anona mcp` (not `anona-mcp`) |
| `get_user_profile` | Reads what a space knows about one end user, by their `user_id`. | Remote and `anona mcp` (not `anona-mcp`) |

There are three ways in: the remote `/mcp` endpoint, `anona mcp` (the local server in
the [CLI](https://docs.memory.anonalabs.com/cli/overview.md), in both the Python and npm packages), and `anona-mcp` (the
Python SDK's local server, under the Local tab below). `anona mcp` forwards every call
to the remote endpoint, so it exposes all seven tools. `anona-mcp` ships the first four.

### Parameters by transport

The two servers are not the same surface. The four shared tools take the same
*required* argument on both, but the hosted gateway accepts a good deal more besides.
`anona-mcp`, the Python SDK's local stdio server, declares only the arguments listed
here — one it does not declare is not passed on, so asking for it there is not a
slower version of the hosted behaviour, it is nothing at all.

| Tool | Argument | `anona-mcp` (stdio) | Remote `/mcp` |
| - | - | - | - |
| `record` | `content` (required) | Yes | Yes |
| | `space_id` | Yes | Yes |
| | `user_id`, `agent_id`, `session_id` | Yes | Yes |
| | `tags` | No | Yes |
| | `timestamp` | No | Yes |
| | `route: "auto"`, `fallback_space_id`, `max_targets` | No | Yes |
| | `org_id` | No | Yes |
| `retrieve` | `query` (required) | Yes | Yes |
| | `space_id` | Yes | Yes |
| | `limit` | Yes | Yes |
| | `user_id`, `agent_id`, `session_id` | Yes | Yes |
| | `mode: "fast"` | No | Yes |
| | `as_of`, `occurred_after`, `occurred_before` | No | Yes |
| | `tag_groups` | No | Yes |
| | `route: "auto"`, `fallback_space_id`, `max_targets` | No | Yes |
| | `org_id` | No | Yes |
| `list_spaces` | `org_id` | No | Yes |
| `reason` | `query` (required) | Yes | Yes |
| | `space_id` | Yes | Yes |
| | `model` | Yes | Yes |
| | `user_id`, `agent_id`, `session_id` | Yes | Yes |
| | `depth: "thorough"` | No | Yes |
| | `org_id` | No | Yes |

What the remote-only arguments do:

* `tags` and `tag_groups` — visibility-scope tags on a write, and a
  [boolean tag filter](https://docs.memory.anonalabs.com/api-reference/retrieve.md#compound-tag-filters) on a read.
* `timestamp`, `as_of`, `occurred_after`, `occurred_before` — event time, so a memory can
  be recorded after the fact and found by when it happened rather than when it was
  stored.
* `mode: "fast"` — skips the reranker for much lower latency, at a real cost in recall
  quality.
* `route: "auto"` — the gateway picks the space, on `record` and on `retrieve` alike.
  `fallback_space_id` says where to go when nothing fits, and on `retrieve`
  `max_targets` caps how many spaces may be searched; when more than one is searched,
  each memory is labelled with the space it came from. Note that a routed request sends
  text to a [third-party decision model](https://docs.memory.anonalabs.com/legal/subprocessors.md).
* `depth: "thorough"` — makes `reason` read past the space's
  [memory models](https://docs.memory.anonalabs.com/api-reference/models.md). See [Depth](https://docs.memory.anonalabs.com/api-reference/reason.md#depth).

**Organization argument.** On the hosted gateway every tool takes an optional `org_id`,
and the `/mcp` endpoint accepts the `X-Anona-Org` header. A signed-in (OAuth) client
starts in your personal organization; naming a shared organization selects your
membership there (`not_an_org_member` if you hold none). An API key belongs to one
organization, so naming another is `org_mismatch`. If both header and argument are sent
they must agree. See
[Choosing an organization](https://docs.memory.anonalabs.com/api-reference/organization.md#choosing-an-organization-per-request).
The `anona-mcp` stdio server has no `org_id` argument and no header: it acts in whichever
organization owns the `ANONA_API_KEY` it was given.

**Space argument.** On the hosted gateway, on a signed-in account, the tools that act on
a space need a `space_id` (or `route: "auto"` on `record` and `retrieve`), because an
account may hold several spaces. On a [temporary profile](https://docs.memory.anonalabs.com/agents/temp-profiles.md) they do
not: leave it out and the call uses the profile's only space, `default`. On `anona-mcp`
a space must always be named, either as `space_id` or through `ANONA_SPACE_ID`;
omitting both is an error that tells you to call `list_spaces`.

Per-tool failures, such as a denied space or exhausted credits, come back as structured
tool errors rather than broken connections. The MCP session stays alive.

## Choosing a transport

| | Local (stdio) | Remote (Streamable HTTP) |
| - | - | - |
| **Runs** | On your machine, via `uvx` | On the hosted gateway |
| **Install** | Python SDK required | Nothing to install |
| **Auth** | `ANONA_API_KEY` environment variable | API key header, or OAuth sign-in |
| **Best for** | Local development, scripted setups | Everyday use, and teams |

**Remote (recommended)**

Connect directly to the hosted gateway. There is no local process to run.

```bash theme={null}
claude mcp add --transport http anona https://memory.anonalabs.com/mcp \
  --header "Authorization: Bearer anona_live_YOUR_KEY"
```

Authentication uses the same API key as the REST API, so there is no separate credential
to manage.

**Hermes Agent:** add a `mcp_servers` entry to `~/.hermes/config.yaml`:

```yaml theme={null}
mcp_servers:
  anona:
    url: "https://memory.anonalabs.com/mcp"
    headers:
      Authorization: "Bearer ${env:ANONA_API_KEY}"
```

Hermes also supports `auth: oauth` in place of a static header, the same OAuth flow
described below for Claude Code.

**OpenClaw:** add the server under `nodeHost.mcp.servers` in `openclaw.json` on the
node machine. See [OpenClaw](#openclaw) below for the full block. That path takes an
API key only, not OAuth.

**Connecting without a key.** Leave off `--header` and an OAuth-capable client such as
Claude Code, Claude Desktop, or Cursor signs you in instead.

```bash theme={null}
claude mcp add --transport http anona-oauth https://memory.anonalabs.com/mcp
```

> [!NOTE]
>
> `add` does not open a browser, and that is expected. It only writes the server to your
> config file. OAuth sign-in does not run until the client actually connects, which
> happens at session start or when you run `/mcp`. After `add` you are not signed in yet.

> [!NOTE]
>
> **No API key is needed for this path.** An organization that has never created
> one works from its first tool call: the gateway proves your tenancy to the
> memory service itself. This was not true before 2026-10-01, when a keyless
> organization got `403 No active API key for this organization` and had to
> create a key once to work around it. If you still see that error, something is
> wrong on our side rather than with your setup, so please report it instead of
> minting a key.
>
> One deliberate exception: an organization that created keys and then revoked
> all of them is refused, because revoking every key is how you cut off access.
> Create a new key to restore it.

To trigger sign-in:

1. Run `/mcp` in Claude Code, or restart it. This connects to the server for the first time.
2. Your browser opens the Anona consent screen. Sign in with email and password, or with Google, GitHub, or Microsoft, whichever your account uses.
3. Approve, and the client stores the token. No API key ever touches its config.

Manage or revoke authorized apps at any time from the dashboard, under
**MCP → Connected apps**. Tokens refresh automatically, and revoking cuts an app's
access immediately.

**Connecting with a temporary profile.** A token starting `anona_tmp_`, created by
`anona start`, authenticates `/mcp` the same way an API key does, so no account or
sign-in is needed. On such a profile no tool needs a `space_id`. See
[Temporary profiles](https://docs.memory.anonalabs.com/agents/temp-profiles.md) for the limits and how to claim one.

> [!WARNING]
>
> Opening `https://memory.anonalabs.com/mcp` in a browser returns `Method Not Allowed`.
> That endpoint speaks the MCP protocol over POST and is not a web page. Point an MCP
> client at it rather than visiting it.

**Local (stdio)**

Runs on your machine via `uvx`, and ships with the Python SDK.

```bash theme={null}
uvx --from 'anona[mcp]' anona-mcp
```

Set the environment before starting your client:

```bash theme={null}
export ANONA_API_KEY="anona_live_YOUR_KEY"
export ANONA_SPACE_ID="customer-support-bot"   # optional, scopes the server to one space
```

Or install the extra explicitly:

```bash theme={null}
pip install "anona[mcp]"
```

**Register with Claude Code:**

```bash theme={null}
claude mcp add --transport stdio anona -- uvx --from 'anona[mcp]' anona-mcp
```

Set `ANONA_API_KEY`, and optionally `ANONA_SPACE_ID`, in your shell environment before
starting Claude Code.

## Things worth knowing

| Behavior | Detail |
| - | - |
| **Tools only load at session start.** | Adding or changing an MCP server mid-session will not expose its tools until you restart the client. |
| **`ANONA_SPACE_ID` is the stdio server's default space.** | Set it and the local tools use it whenever a call leaves `space_id` out; leave it unset and such a call fails, telling you to run `list_spaces`. It is not read by the remote server. A temporary profile on the remote server is the one case where no space need ever be named: it has exactly one. |
| **Same quota, same billing.** | MCP calls consume credits and count against your usage exactly as REST calls do. |

## Example session

Once registered, talk naturally:

> Remember that the user prefers dark mode and uses VS Code.

> What do we know about this user's editor preferences?

Claude Code calls `record` and `retrieve` behind the scenes.

> [!NOTE]
>
> Serving several people through one MCP connection? Pass `user_id` on `record` and
> `retrieve` so each person's memories stay separate inside the shared space. See
> [Scoping](https://docs.memory.anonalabs.com/api-reference/retrieve.md#scoping-within-a-space).

## Client setup guides

### Claude Code

1. Get a key from the dashboard, under **API keys**.
2. Register the server:
   ```bash theme={null}
   claude mcp add --transport http anona https://memory.anonalabs.com/mcp \
     --header "Authorization: Bearer anona_live_YOUR_KEY"
   ```
3. Run `/mcp` in Claude Code, or restart it, to connect.
4. Try it: "Remember that I prefer dark mode and use VS Code."

### Hermes Agent

1. Get a key from the dashboard, under **API keys**.
2. Add to `~/.hermes/config.yaml`:
   ```yaml theme={null}
   mcp_servers:
     anona:
       url: "https://memory.anonalabs.com/mcp"
       headers:
         Authorization: "Bearer ${env:ANONA_API_KEY}"
   ```
3. Set `ANONA_API_KEY` in `~/.hermes/.env` or your shell environment.
4. If Hermes is already running, it auto-reloads the config within 30s, or run
   `/reload-mcp` in-session. Otherwise the server picks it up on next start.
5. Try it: "Remember that I prefer dark mode and use VS Code."

### OpenClaw

1. Get a key from the dashboard, under **API keys**.
2. On the node machine (not the OpenClaw gateway), add to `openclaw.json`.
   `openclaw config file` prints its path.
   ```json5 theme={null}
   {
     nodeHost: {
       mcp: {
         servers: {
           anona: {
             url: "https://memory.anonalabs.com/mcp",
             transport: "streamable-http",
             headers: { Authorization: "Bearer ${ANONA_API_KEY}" },
           },
         },
       },
     },
   }
   ```
3. Set `ANONA_API_KEY` in the node's environment, then `openclaw node restart`.
   The node host does not watch this file.
4. This path takes an API key only, not OAuth.
5. Try it: "Remember that I prefer dark mode and use VS Code."

Without the MCP server, the [Agent Skill](https://docs.memory.anonalabs.com/integrations/skills.md) still works in
OpenClaw: it calls the API with `curl` and the key in `~/.anona/config.env`.

## Next steps

> **[Agent Skills](https://docs.memory.anonalabs.com/integrations/skills.md)**
>
> Make the client use these tools by itself, instead of waiting to be told.

> **[Python SDK](https://docs.memory.anonalabs.com/sdk/python.md)**
>
> The programmatic client library.

> **[API overview](https://docs.memory.anonalabs.com/api-reference/overview.md)**
>
> The full REST surface.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.