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