Memory Configuration Reference for OpenClaw

This page lists every configuration knob for OpenClaw memory search. It is intended for developers and system administrators tuning memory providers, retrieval modes, QMD, and multimodal indexing.

Read this when

  • You want to configure memory search providers or embedding models
  • You want to set up the QMD backend
  • You want to enable hybrid search, MMR, or temporal decay
  • You want to enable multimodal memory indexing

This page lists every configuration knob for OpenClaw memory search. For conceptual overviews, see:

All shared memory settings live under top-level memory in openclaw.json. Search defaults use memory.search; per-agent search overrides use agents.entries.*.memory.search.

Note

For the recommended personal-agent workflow, use memory.search.rememberAcrossConversations. Advanced Active Memory targeting, model, prompt, and latency controls live under plugins.entries.active-memory.

See Active Memory for both activation paths, transcript persistence, and safe rollout guidance.


Remember across conversations

KeyTypeDefaultDescription
rememberAcrossConversationsbooleanOn for personal installs; off with configured DM isolationUse relevant context from this agent's other recognized private conversations.

Configure it per agent when only a trusted personal agent should use cross-conversation transcript recall:

{
  agents: {
    entries: {
      personal: {
        memory: {
          search: {
            rememberAcrossConversations: true,
          },
        },
      },
    },
  },
}

The value follows normal memory.search inheritance with a per-agent override. When unset, it defaults on only if global session.dmScope is unset or "main" and no binding has a session.dmScope override. Any configured DM isolation defaults it off. An explicit true or false always wins. Enabling it implies session transcript indexing and adds sessions to the agent's resolved memory sources. With QMD, it also enables that agent's session export; no separate memory.qmd.sessions.enabled setting is required for this mode.

OpenClaw's built-in memory provider supports this protected path with both the builtin and QMD backends. Alternate memory providers can keep using their own recall hooks and advanced Active Memory tools, but this setting is skipped unless the current provider supports protected private transcript recall. openclaw doctor reports an unsupported provider or an explicit Active Memory toolsAllow list that omits memory_search.

The retrieval boundary is narrower than general session search:

  • only the same agent's recognized private conversations are eligible
  • the conversation being answered is excluded
  • groups and channels are excluded as sources and destinations
  • unknown conversation kinds fail closed
  • sandboxed recall cannot use the special cross-conversation authorization

The setting does not change tools.sessions.visibility, session keys, transcript storage, delivery routing, or the permissions of sessions_list, sessions_history, and sessions_send. Active Memory performs a bounded read-only retrieval pass; unavailable or timed-out retrieval does not block the reply.


Provider selection

KeyTypeDefaultDescription
enabledbooleantrueEnable or disable memory search
providerstring"openai"Embedding adapter ID such as bedrock, deepinfra, gemini, github-copilot, local, mistral, ollama, openai, openai-compatible, or voyage; may also be a configured models.providers.<id> whose api points at a memory embedding adapter or OpenAI-compatible model API
modelstringprovider defaultEmbedding model name
fallbackstring"none"Fallback adapter ID when the primary fails

When provider is not set, OpenClaw uses OpenAI embeddings. Set provider explicitly to use Bedrock, DeepInfra, Gemini, GitHub Copilot, Mistral, Ollama, Voyage, a local GGUF model, or an OpenAI-compatible /v1/embeddings endpoint. Legacy configs that still say provider: "auto" resolve to openai.

Warning

Changing the embedding provider, model, provider settings, sources, scope, chunking, or tokenizer can make the existing SQLite vector index incompatible. OpenClaw pauses vector search and reports an index identity warning instead of automatically re-embedding everything. Rebuild when you are ready with openclaw memory status --index --agent <id> or openclaw memory index --force --agent <id>.

When provider is unset, legacy provider: "auto" is present, or provider: "none" intentionally selects FTS-only mode, memory recall can still use lexical FTS ranking when embeddings are unavailable.

Explicit non-local providers fail closed. If you set memory.search.provider to a concrete remote-backed provider such as Bedrock, DeepInfra, Gemini, GitHub Copilot, LM Studio, Mistral, Ollama, OpenAI, Voyage, or an OpenAI-compatible custom provider, and that provider is unavailable at runtime, memory_search returns an unavailable result instead of silently using FTS-only recall. Fix the provider/auth configuration, switch to a reachable provider, or set provider: "none" if you want deliberate FTS-only recall.

Custom provider ids

memory.search.provider can point at a custom models.providers.<id> entry for memory-specific provider adapters such as ollama, or for OpenAI-compatible model APIs such as openai-responses / openai-completions. OpenClaw resolves that provider's api owner for the embedding adapter while preserving the custom provider id for endpoint, auth, and model-prefix handling. This lets multi-GPU or multi-host setups dedicate memory embeddings to a specific local endpoint:

{
  models: {
    providers: {
      "ollama-5080": {
        api: "ollama",
        baseUrl: "http://gpu-box.local:11435",
        apiKey: "ollama-local",
        models: [{ id: "qwen3-embedding:0.6b", name: "Qwen3 Embedding 0.6B" }],
      },
    },
  },
  memory: {
    search: {
      provider: "ollama-5080",
      model: "qwen3-embedding:0.6b",
    },
  },
}

API key resolution

Remote embeddings require an API key. Bedrock uses the AWS SDK default credential chain instead (instance roles, SSO, access keys, or a Bedrock API key).

ProviderEnv varConfig key
BedrockAWS credential chain, or AWS_BEARER_TOKEN_BEDROCKNo API key needed
DeepInfraDEEPINFRA_API_KEYmodels.providers.deepinfra.apiKey
GeminiGEMINI_API_KEYmodels.providers.google.apiKey
GitHub CopilotCOPILOT_GITHUB_TOKEN, GH_TOKEN, GITHUB_TOKENAuth profile via device login
MistralMISTRAL_API_KEYmodels.providers.mistral.apiKey
OllamaOLLAMA_API_KEY (placeholder)--
OpenAIOPENAI_API_KEYmodels.providers.openai.apiKey
VoyageVOYAGE_API_KEYmodels.providers.voyage.apiKey

Note

Codex OAuth covers chat/completions only and does not satisfy embedding requests.


Remote endpoint config

Use provider: "openai-compatible" for a generic OpenAI-compatible /v1/embeddings server that should not inherit global OpenAI chat credentials.

  • remote.baseUrl (string), Custom API base URL.

  • remote.apiKey (string), Override API key.

  • remote.headers (object), Extra HTTP headers (merged with provider defaults).

{
  memory: {
    search: {
      provider: "openai-compatible",
      model: "text-embedding-3-small",
      remote: {
        baseUrl: "https://api.example.com/v1/",
        apiKey: "YOUR_KEY",
      },
    },
  },
}

Provider-specific config

Gemini

KeyTypeDefaultDescription
modelstringgemini-embedding-001Also supports gemini-embedding-2-preview
outputDimensionalitynumber3072For Embedding 2: 768, 1536, or 3072

Warning

Changing model or outputDimensionality changes the index identity. OpenClaw pauses vector search until you explicitly rebuild the memory index.

OpenAI-compatible input types

OpenAI-compatible embedding endpoints can opt into provider-specific input_type request fields. This is useful for asymmetric embedding models that require different labels for query and document embeddings.

KeyTypeDefaultDescription
inputTypestringunsetShared input_type for query and document embeddings
queryInputTypestringunsetQuery-time input_type; overrides inputType
documentInputTypestringunsetIndex/document input_type; overrides inputType
{
  memory: {
    search: {
      provider: "openai-compatible",
      remote: {
        baseUrl: "https://embeddings.example/v1",
        apiKey: "${EMBEDDINGS_API_KEY}",
      },
      model: "asymmetric-embedder",
      queryInputType: "query",
      documentInputType: "passage",
    },
  },
}

Changing these values affects embedding cache identity for provider batch indexing and should be followed by a memory reindex when the upstream model treats the labels differently.

Bedrock

Bedrock embedding config

Bedrock uses the AWS SDK default credential chain plus an OpenClaw-checked bearer token, so no API keys are stored in config. If OpenClaw runs on EC2 with a Bedrock-enabled instance role, just set the provider and model:

{
  memory: {
    search: {
      provider: "bedrock",
      model: "amazon.titan-embed-text-v2:0",
    },
  },
}
KeyTypeDefaultDescription
modelstringamazon.titan-embed-text-v2:0Any Bedrock embedding model ID
outputDimensionalitynumbermodel defaultFor Titan V2: 256, 512, or 1024

Supported models (with family detection and dimension defaults):

Model IDProviderDefault DimsConfigurable Dims
amazon.titan-embed-text-v2:0Amazon1024256, 512, 1024
amazon.titan-embed-text-v1Amazon1536--
amazon.titan-embed-g1-text-02Amazon1536--
amazon.titan-embed-image-v1Amazon1024--
amazon.nova-2-multimodal-embeddings-v1:0Amazon1024256, 384, 1024, 3072
cohere.embed-english-v3Cohere1024--
cohere.embed-multilingual-v3Cohere1024--
cohere.embed-v4:0Cohere1536256, 384, 512, 768, 1024, 1536
twelvelabs.marengo-embed-3-0-v1:0TwelveLabs512--
twelvelabs.marengo-embed-2-7-v1:0TwelveLabs1024--

Variants with throughput suffixes, like amazon.titan-embed-text-v1:2:8k, and inference profile IDs prefixed by region, such as us.amazon.titan-embed-text-v2:0, take on the base model's configuration.

Region: resolved in this order: the memory.search.remote.baseUrl override, the models.providers.amazon-bedrock.baseUrl config, AWS_REGION, AWS_DEFAULT_REGION, then a default of us-east-1.

Authentication: OpenClaw checks for AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY or AWS_BEARER_TOKEN_BEDROCK first, then falls through to the standard AWS SDK default credential provider chain:

  1. Environment variables (AWS_ACCESS_KEY_ID + AWS_SECRET_ACCESS_KEY), unless AWS_PROFILE is also set
  2. SSO (only when SSO fields are configured)
  3. Shared credentials and config files (fromIni, includes AWS_PROFILE)
  4. Credential process (credential_process in the AWS config file)
  5. Web identity token credentials
  6. ECS or EC2 instance metadata credentials

IAM permissions: the IAM role or user needs:

{
  "Effect": "Allow",
  "Action": "bedrock:InvokeModel",
  "Resource": "*"
}

For least-privilege, scope InvokeModel to the specific model:

arn:aws:bedrock:*::foundation-model/amazon.titan-embed-text-v2:0

Local (GGUF + llama.cpp)

KeyTypeDefaultDescription
local.modelPathstringauto-downloadedPath to GGUF model file
local.modelCacheDirstringnode-llama-cpp defaultCache dir for downloaded models
local.contextSizenumber | "auto"4096Context window size for the embedding context. 4096 covers typical chunks (128-512 tokens) while bounding non-weight VRAM. Lower to 1024-2048 on constrained hosts. "auto" uses the model's trained maximum -- not recommended for 8B+ models (Qwen3-Embedding-8B: up to 40 960 tokens can push VRAM to ~32 GB).

Install the official llama.cpp provider first: openclaw plugins install @openclaw/llama-cpp-provider. Default model: embeddinggemma-300m-qat-Q8_0.gguf (~0.6 GB, auto-downloaded). Source checkouts still require native build approval: pnpm approve-builds then pnpm rebuild node-llama-cpp.

Use the standalone CLI to verify the same provider path the Gateway uses:

openclaw memory status --deep --agent main
openclaw memory index --force --agent main

Numeric local.contextSize values also inform node-llama-cpp's automatic GPU-layer placement so model weights and the requested embedding context are fitted together. openclaw memory status --deep reports last-known llama.cpp backend, device, offload, requested-context, and timestamped memory facts after the runtime has loaded; passive status does not load a model.

Set provider: "local" explicitly for local GGUF embeddings. hf: and HTTP(S) model references are supported for explicit local configs (via node-llama-cpp's model resolution), but they do not change the default provider.

Indexing behavior

Memory engines own synchronization, batching, watch, and post-compaction indexing heuristics. OpenClaw keeps these behaviors enabled with maintained defaults rather than exposing per-install timing switches.

Hybrid search config

All under memory.search.query:

KeyTypeDefaultDescription
maxResultsnumber6Max memory hits returned before injection
minScorenumber0.35Minimum relevance score to include a hit

Hybrid retrieval remains enabled; MMR and temporal decay remain disabled by the built-in engine policy.

Full example

{
  memory: {
    search: {
      query: {
        maxResults: 6,
        minScore: 0.35,
      },
    },
  },
}

Additional memory paths

KeyTypeDescription
extraPathsstring[]Additional directories or files to index
{
  memory: {
    search: {
      extraPaths: ["../team-docs", "/srv/shared-notes"],
    },
  },
}

Paths can be absolute or workspace-relative. Directories are scanned recursively for .md files. Symlink handling depends on the active backend: the builtin engine skips symlinks, while QMD follows the underlying QMD scanner behavior.

For agent-scoped cross-agent transcript search, use agents.entries.*.memory.search.qmd.extraCollections instead of memory.qmd.paths. Those extra collections follow the same { path, name, pattern? } shape, but they are merged per agent and can preserve explicit shared names when the path points outside the current workspace. If the same resolved path appears in both memory.qmd.paths and memory.search.qmd.extraCollections, QMD keeps the first entry and skips the duplicate.


Multimodal memory (Gemini)

Index images and audio alongside Markdown using Gemini Embedding 2:

KeyTypeDefaultDescription
multimodal.enabledbooleanfalseEnable multimodal indexing
multimodal.modalitiesstring[]--["image"], ["audio"], or ["all"]
multimodal.maxFileBytesnumber10485760Max file size for indexing (10 MiB)

Note

Only applies to files in extraPaths. Default memory roots stay Markdown-only. Requires gemini-embedding-2-preview. fallback must be "none".

Supported formats: .jpg, .jpeg, .png, .webp, .gif, .heic, .heif (images); .mp3, .wav, .ogg, .opus, .m4a, .aac, .flac (audio).


Embedding cache

KeyTypeDefaultDescription
cache.enabledbooleantrueCache chunk embeddings in SQLite

Prevents re-embedding unchanged text during reindex or transcript updates.


Batch indexing

KeyTypeDefaultDescription
remote.nonBatchConcurrencynumber4Parallel inline embeddings
remote.batch.enabledbooleanfalseEnable batch embedding API

Available for gemini, openai, and voyage. OpenAI batch is typically fastest and cheapest for large backfills.

Concurrency, polling, and timeout behavior are provider-owned.


Index session transcripts and surface them via memory_search:

KeyTypeDefaultDescription
rememberAcrossConversationsbooleanfalsePermit private cross-conversation recall
sourcesstring[]["memory"]Add "sessions" to include transcripts

Warning

Session indexing is opt-in and runs asynchronously. Results can be slightly stale. Session logs live on disk, so treat filesystem access as the trust boundary.

Ordinary model-invoked session transcript search obeys tools.sessions.visibility. The default tree visibility exposes the current session, sessions it spawned, and same-agent group sessions watched through ambient group awareness. Other unrelated sessions require agent visibility (or all only when cross-agent recall is also required and agent-to-agent policy allows it).

rememberAcrossConversations does not widen that setting. It supplies a separate runtime-only authorization limited to same-agent private transcripts during the bounded Active Memory pass.

The examples below place these settings under top-level memory.search. You can also apply equivalent settings in a per-agent memory.search override when only one agent should index and search session transcripts.

For same-agent gateway-to-DM recall:

Builtin backend

{
  memory: {
    search: {
      experimental: { sessionMemory: true },
      sources: ["memory", "sessions"],
    },
  },
  tools: {
    sessions: { visibility: "agent" },
  },
}

QMD backend

{
  memory: {
    backend: "qmd",
    search: {
      experimental: { sessionMemory: true },
      sources: ["memory", "sessions"],
    },
    qmd: {
      sessions: { enabled: true },
    },
  },
  tools: {
    sessions: { visibility: "agent" },
  },
}

When using QMD, sources: ["sessions"] does not by itself export transcripts into QMD. Set memory.qmd.sessions.enabled: true as well. The higher-level rememberAcrossConversations: true setting is the exception: it implies the required QMD session export for that agent. Implied exports stay private: they always use the default internal export location (a configured sessions.exportDir applies only to explicit exports), they are searched only during that agent's cross-conversation recall, and ordinary memory_get cannot read them. Explicit memory.qmd.sessions.enabled: true keeps its existing behavior and makes exported transcripts part of the ordinary memory corpus.


SQLite vector acceleration (sqlite-vec)

KeyTypeDefaultDescription
store.vector.enabledbooleantrueUse sqlite-vec for vector queries
store.vector.extensionPathstringbundledOverride sqlite-vec path

When sqlite-vec is not available, OpenClaw automatically falls back to in-process cosine similarity.


Index storage

Built-in memory indexes are stored in each agent's OpenClaw SQLite database at agents/<agentId>/agent/openclaw-agent.sqlite.

KeyTypeDefaultDescription
store.fts.tokenizerstringunicode61FTS5 tokenizer (unicode61 or trigram)

QMD backend config

Set memory.backend = "qmd" to enable. All QMD settings are under memory.qmd:

KeyTypeDefaultDescription
commandstringqmdQMD executable path; use an absolute path when service PATH differs from your shell
searchModestringsearchSearch command: search, vsearch, query
rerankboolean--Set to false with searchMode: "query" and QMD 2.1+ to skip QMD reranking
includeDefaultMemorybooleantrueAuto-index MEMORY.md + memory/**/*.md
paths[]array--Extra paths: { name, path, pattern? }
sessions.enabledbooleanfalseExport session transcripts into QMD
sessions.retentionDaysnumber--Transcript retention
sessions.exportDirstring--Export directory

searchMode: "search" is lexical/BM25-only. OpenClaw does not run semantic vector readiness probes or QMD embedding maintenance for that mode, including during memory status --deep; vsearch and query still need QMD vector readiness and embeddings.

rerank: false only changes QMD query mode and requires QMD 2.1 or newer. In direct CLI mode OpenClaw passes --no-rerank; in mcporter-backed MCP mode it passes rerank: false to QMD's unified query tool. Leave it unset to use QMD's default query reranking behavior.

OpenClaw prefers current QMD collection and MCP query shapes, but keeps older QMD releases working by trying compatible collection pattern flags and older MCP tool names when needed. When QMD advertises support for multiple collection filters, same-source collections are searched with one QMD process; older QMD builds keep the per-collection compatibility path. Same-source means durable memory collections (default memory files plus custom paths) are grouped together, while session transcript collections remain a separate group so source diversification still has both inputs.

Note

QMD model overrides stay on the QMD side, not OpenClaw config. If you need to override QMD's models globally, set environment variables such as QMD_EMBED_MODEL, QMD_RERANK_MODEL, and QMD_GENERATE_MODEL in the gateway runtime environment.

Limits

KeyTypeDefaultDescription
limits.maxResultsnumber4Max search results
limits.maxSnippetCharsnumber450Clamp snippet length
limits.maxInjectedCharsnumber2200Clamp total injected chars
limits.timeoutMsnumber4000QMD command timeout during QMD-backed search, including memory_search; setup, sync, builtin fallback, and supplemental work keep the default tool deadline

Scope

Controls which sessions can receive QMD search results. Same schema as session.sendPolicy:

{
  memory: {
    qmd: {
      scope: {
        default: "deny",
        rules: [{ action: "allow", match: { chatType: "direct" } }],
      },
    },
  },
}

The shipped default is DM/direct-only, denying groups and other channel types. match.keyPrefix matches the normalized session key; match.rawKeyPrefix matches the raw key including agent:<id>:.

Citations

memory.citations applies to all backends:

ValueBehavior
auto (default)Include Source: <path#line> footer in snippets
onAlways include footer
offOmit footer (path still passed to agent internally)

QMD initializes lazily when memory is first used; its adapter owns refresh and embedding schedules.

Full QMD example

{
  memory: {
    backend: "qmd",
    citations: "auto",
    qmd: {
      includeDefaultMemory: true,
      update: { interval: "5m", debounceMs: 15000 },
      limits: { maxResults: 4, timeoutMs: 4000 },
      scope: {
        default: "deny",
        rules: [{ action: "allow", match: { chatType: "direct" } }],
      },
      paths: [{ name: "docs", path: "~/notes", pattern: "**/*.md" }],
    },
  },
}

Dreaming

Dreaming is configured under plugins.entries.memory-core.config.dreaming, not under memory.search.

Dreaming runs as one scheduled sweep and uses internal light/deep/REM phases as an implementation detail.

For conceptual behavior and slash commands, see Dreaming.

User settings

KeyTypeDefaultDescription
enabledbooleanfalseEnable or disable dreaming entirely
frequencystring0 3 * * *Optional cron cadence for the full dreaming sweep
modelstringdefault modelOptional Dream Diary subagent model override
phases.deep.maxPromotedSnippetTokensnumber160Maximum estimated tokens kept from each short-term recall snippet promoted into MEMORY.md; provenance metadata remains visible

Example

{
  plugins: {
    entries: {
      "memory-core": {
        subagent: {
          allowModelOverride: true,
          allowedModels: ["anthropic/claude-sonnet-4-6"],
        },
        config: {
          dreaming: {
            enabled: true,
            frequency: "0 3 * * *",
            model: "anthropic/claude-sonnet-4-6",
          },
        },
      },
    },
  },
}

Note

  • Dreaming writes machine state to memory/.dreams/.
  • Dreaming writes human-readable narrative output to DREAMS.md (or existing dreams.md).
  • dreaming.model uses the existing plugin subagent trust gate; set plugins.entries.memory-core.subagent.allowModelOverride: true before enabling it.
  • Dream Diary retries once with the session default model when the configured model is unavailable. Trust or allowlist failures are logged and are not silently retried.
  • The light/deep/REM phase policy and thresholds are internal behavior, not user-facing config.