Skip to main content

OpenClaw QMD Install and Configuration Guide

· 8 min read

QMD is a local semantic search engine built for AI agents by Shopify founder Tobi Lütke. This guide covers the full install and configuration flow to enable the QMD memory backend in OpenClaw.

  • Last updated: 2026-03-06

About QMD

QMD is a local semantic search engine developed by Tobi Lütke (Shopify founder) for AI agents (GitHub - tobi/qmd). It uses a three-layer hybrid search: BM25 keyword matching + vector semantic search + LLM reranking.

With QMD enabled: No matter how long the history is, only the most relevant snippets are retrieved each time (typically cutting 95%+ of context).

  • ✅ 5–50× faster responses
  • ✅ 90–99% lower cost
  • ✅ Higher precision (less noise)
  • ✅ No more timeouts or freezes from oversized context

Prerequisites

  • OpenClaw version ≥ 2026.2.2
  • Bun (recommended) or Node.js 22+
  • SQLite with extension support (on macOS: brew install sqlite)
  • QMD is disabled by default; set memory.backend = "qmd" in config to enable
  • Ensure the qmd binary is on the PATH of the environment where OpenClaw Gateway runs (otherwise it falls back to built-in SQLite)

Overview

Pre-download models (optional) → Install QMD → Configure XDG dirs → Migrate models (optional)

Configure OpenClaw (openclaw.json, memory.backend = "qmd") and restart Gateway

Gateway creates collections (e.g. memory-root) and indexes on boot (e.g. onBoot)

Verify with qmd status / optional: qmd update && qmd embed / search test

1. Pre-download models (optional)

Before installing QMD, if you have limited network or want an offline setup, you can download the three GGUF models into the default cache directory (e.g. /root/.cache/qmd/models/ or ~/.cache/qmd/models/).

  • Models: embedding (embeddinggemma-300M), reranker (qwen3-reranker-0.6b), query expansion (qmd-query-expansion-1.7B).
  • Directory: Without XDG_CACHE_HOME, for root it is /root/.cache/qmd/models/.

Steps: Follow QMD GGUF models on CPU to download the three .gguf files (huggingface-cli or browser/wget) into that directory. Filenames may have an hf_ prefix or short names; QMD/node-llama-cpp will resolve them.

If you skip this, QMD will auto-download from HuggingFace on first qmd embed or first search.


2. Install QMD

2.1 Install Bun (if needed)

# macOS/Linux
curl -fsSL https://bun.sh/install | bash

# Windows (PowerShell as admin)
powershell -c "irm bun.sh/install.ps1 | iex"

2.2 CPU-only (no NVIDIA GPU or force CPU)

If the machine has no NVIDIA GPU or you want CPU only, set this before installing QMD:

export NODE_LLAMA_CPP_CUDA=false

To persist (e.g. in ~/.bashrc or ~/.zshrc):

echo 'export NODE_LLAMA_CPP_CUDA=false' >> ~/.bashrc
source ~/.bashrc

2.3 Install QMD CLI

Pick one:

Option A: Bun (recommended)

bun install -g https://github.com/tobi/qmd

Option B: npm

Requires Node.js 22+. Install the official npm package globally:

npm install -g @tobilu/qmd
  • The binary is usually under the parent of npm root -g in bin. If qmd is not found, add npm’s global bin to PATH:
    export PATH="$(npm config get prefix)/bin:$PATH"

Option C: Run without installing

npx @tobilu/qmd ...

2.4 Verify installation

# If using Bun, ensure Bun’s bin is on PATH
export PATH="$HOME/.bun/bin:$PATH"

# If using npm and qmd not found:
# export PATH="$(npm config get prefix)/bin:$PATH"

qmd --version
qmd --help

3. Configure XDG directories (OpenClaw paths)

When using QMD with OpenClaw, both manual qmd runs and the Gateway must use the same index and models. Point XDG to OpenClaw’s agent directory:

STATE_DIR="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}"
AGENT_ID="main" # replace with your agent ID

export XDG_CONFIG_HOME="$STATE_DIR/agents/$AGENT_ID/qmd/xdg-config"
export XDG_CACHE_HOME="$STATE_DIR/agents/$AGENT_ID/qmd/xdg-cache"
  • XDG_CONFIG_HOME: QMD collections and config (e.g. under qmd/).
  • XDG_CACHE_HOME: QMD index and model cache (qmd/index.sqlite, qmd/models/).

Run all subsequent qmd commands (status, collection, update, embed, query) in a shell where these two variables are set.


4. Migrate model files

If you pre-downloaded GGUF models into the default directory (e.g. /root/.cache/qmd/models/), copy them to the cache directory used by OpenClaw so the Gateway can find them:

TARGET="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/agents/$AGENT_ID/qmd/xdg-cache/qmd/models"
mkdir -p "$TARGET"
cp /root/.cache/qmd/models/*.gguf "$TARGET/"
# or symlink: ln -s /root/.cache/qmd/models/*.gguf "$TARGET/"

Ensure all three models (embedding, reranker, query expansion) .gguf files are under $TARGET.


5. Confirm model path (optional)

QMD uses XDG_CACHE_HOME for the model directory, defaulting to $XDG_CACHE_HOME/qmd/models/. No separate config.json is required. After completing sections 3 and 4, the path is correct.

If QMD later supports an explicit local model path in config, see QMD docs.


6. Verify (qmd status)

In a shell with XDG_CONFIG_HOME and XDG_CACHE_HOME set:

qmd status

Success: Output looks normal; if collections exist and are indexed, you’ll see Indexed > 0. To warm the index and load models once:

qmd update && qmd embed
qmd query "test" -c memory-root --json >/dev/null 2>&1

7. Collections (auto-created)

In practice, QMD collections are created automatically by OpenClaw from config, with fixed names, e.g.:

  • memory-root: default memory path memory/**/*.md, etc.
  • memory-long: workspace root MEMORY.md

So you usually don’t need to run qmd collection add. After section 3 and starting/configuring OpenClaw, collections are ready.

List collections:

qmd collection list

Once you see the above names, you can index and search; use the collection name (e.g. memory-root) with -c memory-root.

Optional: add collections manually (extra paths or if OpenClaw didn’t create them):

# Ensure STATE_DIR, AGENT_ID, XDG_* are set (see section 3)
WORKSPACE="${OPENCLAW_STATE_DIR:-$HOME/.openclaw}/workspace" # or your workspace path

qmd collection add "$WORKSPACE/memory" --name memory-root --mask "**/*.md"
qmd collection add "$WORKSPACE" --name memory-long --mask "MEMORY.md"

8. Indexing

After collections exist, in the same XDG environment update the file index and generate embeddings:

qmd update
qmd embed

On first qmd embed, if models aren’t present, GGUF models are downloaded from HuggingFace. After that, qmd status should show a higher index count.


Test retrieval in the same XDG environment:

# Hybrid search (BM25 + vector + rerank, recommended)
qmd query "open issues" -c memory-root

# Keyword search (fastest)
qmd search "open issues" -c memory-root

# Semantic search
qmd vsearch "open issues" -c memory-root

If you get relevant snippets back, QMD and the index are working.


10. Configure OpenClaw to use QMD

10.1 Config file location

OSConfig path
macOS/Linux~/.openclaw/openclaw.json
WindowsC:\Users\<username>\.openclaw\openclaw.json
Docker/home/node/.openclaw/openclaw.json

10.2 Edit config

Minimal:

{
"memory": {
"backend": "qmd",
"qmd": {
"limits": {
"timeoutMs": 8000
}
}
}
}

Full (recommended):

{
"memory": {
"backend": "qmd",
"citations": "auto",
"qmd": {
"includeDefaultMemory": true,
"command": "qmd",
"searchMode": "search",
"update": {
"interval": "5m",
"debounceMs": 15000,
"onBoot": true,
"waitForBootSync": false
},
"limits": {
"maxResults": 6,
"timeoutMs": 4000
},
"scope": {
"default": "deny",
"rules": [
{ "action": "allow", "match": { "chatType": "direct" } }
]
}
}
}
}

Options:

  • backend: Switch to QMD memory backend
  • citations: Add citation sources (file path and line); works with both QMD and SQLite
  • command: Executable path, default qmd, must be on Gateway PATH
  • searchMode: Default search (i.e. qmd search --json); can use vsearch, query. If a mode isn’t supported, OpenClaw falls back to qmd query
  • includeDefaultMemory: When true, index MEMORY.md and memory/**/*.md (default true)
  • maxResults: Max memory snippets to return (3–6 recommended)
  • timeoutMs: Search timeout (default 4000ms; 8000ms suggested for first run)
  • interval: Auto re-index interval (default 5m)
  • waitForBootSync: Default false (index refresh in background on boot); set true to block until index is ready

10.3 Restart OpenClaw

openclaw gateway restart

Docker:

docker compose restart

11. Verify on OpenClaw side

  1. Logs: openclaw logs --follow; seeing Using QMD memory backend means QMD is enabled.
  2. QMD status: In a shell with XDG set, run qmd status and confirm Indexed > 0.
  3. Chat: In OpenClaw, ask “Confirm QMD is enabled and give a test report,” or ask about indexed memory to check recall.

12. Troubleshooting

IssueFix
better-sqlite3 build failsInstall build tools: sudo apt install build-essential cmake (Linux) or Visual Studio + Windows SDK (Windows)
qmd not foundBun: export PATH="$HOME/.bun/bin:$PATH"; npm: export PATH="$(npm config get prefix)/bin:$PATH"
Indexed = 0Check XDG dirs match; ensure OpenClaw and manual QMD use same XDG_CONFIG_HOME/XDG_CACHE_HOME; run qmd collection add, qmd update, qmd embed
Search timeoutIncrease timeoutMs to 8000 or more
First search slowNormal: first run downloads/loads GGUF models; warm with qmd query "test" -c memory-root --json in same XDG env
WindowsOfficial recommendation: use WSL2; Bun + SQLite work out of the box on macOS/Linux

13. Rollback

To revert to built-in SQLite memory: edit openclaw.json, remove or comment memory.backend (or set to "sqlite"), then openclaw gateway restart.

Note: If the QMD subprocess fails or JSON parsing fails, OpenClaw falls back to the built-in SQLite manager; memory tools still work. Check status().backend (when "qmd", QMD is active).


14. References

  • Last updated: 2026-03-06
DescriptionLink
QMD repohttps://github.com/tobi/qmd
QMD GGUF models on CPU (manual/offline)QMD GGUF models on CPU
OpenClaw Memory (vector memory and QMD backend)https://docs.openclaw.ai/concepts/memory#vector-memory-search

Related posts