Self-hosting guide

Self-hosting an MCP memory server

Remnic can run as its own process that exposes memory over HTTP and MCP to any number of clients. This guide covers installing the CLI, starting the daemon, securing it with bearer tokens, isolating users with namespaces, and running it in Docker.

Updated July 2026

Short answer: install @remnic/cli, generate a bearer token, and run remnic daemon start (or @remnic/server) to expose memory over HTTP and MCP. Namespaces isolate users, and the Docker image ships with QMD bundled.

When to self-host

Remnic can run embedded in a single OpenClaw process, or as its own standalone server. Self-host the standalone server when you run more than one agent harness and want them to share one memory backend, when you need to isolate projects or clients into separate namespaces, or when you want to feed conversation data from custom scripts into the extraction pipeline. If you only use one harness on one machine, embedded mode is simpler and needs no setup.

Install the remnic CLI

The server ships in the same package family as the CLI. Install the CLI globally:

npm install -g @remnic/cli

This installs the remnic command, plus a legacy engram forwarder. Canonical command and tool names use remnic; the older engram names remain as aliases through v1.x. The project was renamed from engram, and the rename note covers the details.

Generate a bearer token

The server authenticates every request with a bearer token. Generate a strong random one and keep it in an environment variable.

export REMNIC_AUTH_TOKEN="$(openssl rand -hex 32)"

Never commit the token. Treat it like any other secret, and keep it out of shell history where you can.

Start the daemon

With the token set, start the background server and confirm it is up.

remnic daemon start
remnic status

remnic daemon start runs the standalone server and, when a service is installed, hands off to launchd on macOS or systemd on Linux so the daemon starts with the operating system. remnic status reports whether it is running.

If you want to run the server process directly without the daemon wrapper, use the server binary:

npx remnic-server --host 127.0.0.1 --port 4318 --auth-token "$REMNIC_AUTH_TOKEN"

@remnic/server is the standalone HTTP and MCP server that wraps the memory core. It serves the same tool surface that hosted clients get over MCP.

Verify it is running

Check health with the token:

curl -s http://localhost:4318/engram/v1/health \
  -H "Authorization: Bearer $REMNIC_AUTH_TOKEN" | jq .

You should see ok: true and a qmd object. In a full standalone or Docker deployment, qmd.active should be true and qmd.mode should be cli or daemon. If qmd.active is false while qmd.enabled is true, the server is in filesystem fallback mode; use qmd.debugStatus, qmd.installedVersion, and qmd.collectionState to find the missing binary or collection problem. REST paths keep the /engram/v1/ prefix during the v1.x window.

To reach the server from other machines, bind to all interfaces with --host 0.0.0.0. Only do that on a trusted network or behind a reverse proxy.

Connect agent harnesses

The server exposes MCP over HTTP at /mcp. Point each client at it with the bearer token.

Codex CLI, in ~/.codex/config.toml:

[mcp_servers.remnic]
url = "http://127.0.0.1:4318/mcp"
bearer_token_env_var = "REMNIC_AUTH_TOKEN"

Claude Code, in ~/.claude.json:

{
  "mcpServers": {
    "remnic": {
      "url": "http://localhost:4318/mcp",
      "headers": {
        "Authorization": "Bearer ${REMNIC_AUTH_TOKEN}"
      }
    }
  }
}

Claude Code discovers Remnic’s tools on its own. Custom agents can skip MCP and post conversation turns straight to POST /engram/v1/observe.

Isolate users with namespaces

Namespaces keep each user or tenant’s memory separate while allowing a shared namespace for common context. They are opt-in; namespacesEnabled defaults to false. Enable them and define read and write policies per namespace:

{
  "namespacesEnabled": true,
  "sharedNamespace": "shared",
  "defaultRecallNamespaces": ["shared"],
  "namespacePolicies": {
    "default": { "read": ["*"], "write": ["default-principal"] },
    "client-a": { "read": ["client-a-agent", "admin"], "write": ["client-a-agent"] },
    "client-b": { "read": ["client-b-agent", "admin"], "write": ["client-b-agent"] },
    "shared": { "read": ["*"], "write": ["admin"] }
  },
  "principalFromSessionKeyMode": "prefix",
  "principalFromSessionKeyRules": {
    "client-a:": "client-a-agent",
    "client-b:": "client-b-agent"
  }
}

Each tenant’s agents use a session key prefix like client-a:session-123. The prefix rule maps that to a principal, and the principal decides which namespaces the caller can read and write. In this setup, client-a can read and write its own namespace and read the shared namespace, but cannot touch client-b’s namespace. Only the admin principal writes to shared. Turn namespaces on before you add a second user, not after.

Run the server in Docker

The repo ships a Dockerfile that bundles QMD, the search index binary, so recall works without a separate install. The build stage installs @tobilu/qmd where the native build tools are available, then the runtime stage keeps the binary. The image runs as a non-root user, stores memory under the /data volume, listens on port 4318, and ships a health check that hits /engram/v1/health.

Build the image from the repo, then run it:

docker build -t remnic-server .

docker run -d \
  -e REMNIC_AUTH_TOKEN="$(openssl rand -hex 32)" \
  -p 4318:4318 \
  -v remnic-data:/data \
  remnic-server

Mount /data on a persistent volume so memory survives container restarts. Set REMNIC_AUTH_TOKEN so the health check and every client request authenticate. The container already binds to 0.0.0.0:4318, so keep it behind a reverse proxy or a private network.

Hand off to systemd or launchd

For a long-running deployment, let the process manager own the lifecycle. remnic daemon start performs the handoff to launchd or systemd when a service is installed, so the daemon starts on boot. On a server, systemd is the usual choice; on a Mac workstation, launchd. Keep the token in the service environment rather than a shell profile, and point REMNIC_MEMORY_DIR at the directory you back up. The memory store is plain files with structured metadata, so a file-level backup of that directory is enough.