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

# Realms

> Realm-first identity and storage model across CLI, RPC, REST, MCP, and SDK surfaces.

Meerkat is realm-first. A `realm_id` is the only identity key for sharing or isolating state across surfaces.

For task-oriented CLI behavior, filesystem layout, and troubleshooting, see the
[realm guide](/guides/realms).

## Core rules

1. Same `realm_id` means shared sessions, config, and runtime metadata.
2. Different `realm_id` means strict isolation, even from the same folder.
3. Persistent backends (`sqlite` or `jsonl`) are pinned once per realm via `realm_manifest.json`; `memory` is an explicit ephemeral backend for single-process runs.
4. Realm IDs are user-chosen stable identifiers with syntax constraints. Reuse the same value to collaborate across surfaces.

Realm IDs must be 1-64 characters, start with an ASCII alphanumeric character, and may contain only ASCII alphanumerics, `_`, and `-`. They cannot contain whitespace or `:`, and UUID-like opaque values are rejected for explicit user-facing realm IDs.

## Surface defaults

| Surface                                     | If `realm_id` is not provided                                                                |
| ------------------------------------------- | -------------------------------------------------------------------------------------------- |
| CLI (`rkat run`, `run --resume`, `session`) | Workspace-derived stable realm (`ws-...`)                                                    |
| RPC (`rkat-rpc`)                            | New opaque realm (`realm-...`)                                                               |
| REST (`rkat-rest`)                          | New opaque realm (`realm-...`)                                                               |
| MCP server (`rkat-mcp`)                     | New opaque realm (`realm-...`)                                                               |
| Python/TypeScript SDK                       | Whatever the spawned `rkat-rpc` process picks (new opaque realm unless `realm_id` is passed) |

This means CLI is workspace-friendly by default, while non-CLI surfaces are isolated by default.

The CLI workspace default uses the current directory as `context_root`, derives
identity from that path, and stores realm runtime state under
`<context-root>/.rkat/realms/` unless `--context-root` or `--state-root` is
provided.

## Explicit sharing

Use the same realm everywhere:

```bash theme={null}
rkat --realm team-alpha run "Draft release plan"
rkat --realm team-alpha session list
rkat-rpc --realm team-alpha
rkat-rest --realm team-alpha
rkat-mcp --realm team-alpha
```

SDKs pass the same value when connecting:

```python theme={null}
await client.connect(realm_id="team-alpha")
```

```ts theme={null}
await client.connect({ realmId: "team-alpha" })
```

## Backend pinning

On first use, a realm writes a manifest with backend choice. Later opens must honor it.

| First open               | Manifest pins                             |
| ------------------------ | ----------------------------------------- |
| `--realm-backend sqlite` | `sqlite`                                  |
| `--realm-backend jsonl`  | `jsonl`                                   |
| `--realm-backend memory` | `memory`                                  |
| No hint                  | `sqlite` when compiled, otherwise `jsonl` |

After pinning, all surfaces use the manifest backend for that realm.

## Default backend and same-realm sharing

When SQLite support is compiled in, new persistent realms default to `sqlite`.

* `sqlite` is the recommended backend for the normal Meerkat operating mode where multiple processes share one realm.
* `jsonl` remains explicitly selectable for inspectable file-based persistence.
* `memory` uses in-process session/blob/artifact stores and is useful for throwaway runs that should not persist conversation state.

Existing realms stay pinned to the backend recorded in their manifest. Changing the default does not migrate old realms.

## Config and CAS

Config is realm-scoped and generation-based.

* `config/get` returns the core envelope fields `config`, `generation`, `realm_id`, `instance_id`, and `backend`.
* Some surfaces may also include diagnostic fields such as `resolved_paths`, but those should be treated as optional.
* `config/set` and `config/patch` accept optional `expected_generation`.
* Stale writes fail deterministically with generation conflict.

`resolved_paths` should be treated as a diagnostic/admin field rather than a guaranteed universal field on every public config envelope.

## Why this solves multi-surface concurrency

1. 100 RPC servers from the same folder without `realm_id` do not collide.
2. 100 agents across RPC/REST/MCP/CLI with the same `realm_id` see the same state.
3. CLI workspace ergonomics remain simple without forcing filesystem identity onto non-CLI surfaces.

## See also

* [Sessions](/concepts/sessions)
* [Configuration](/concepts/configuration)
* [CLI commands](/cli/commands)
* [JSON-RPC](/api/rpc)
