> ## 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. Backend (`sqlite` or `jsonl`) is pinned once per realm via `realm_manifest.json`.
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/resume/sessions`) | 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 sessions 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`                                   |
| 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.

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)
