OpenClaw QMD Install and Configuration Guide
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
qmdbinary 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 -ginbin. Ifqmdis 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.
9. Search
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
| OS | Config path |
|---|---|
| macOS/Linux | ~/.openclaw/openclaw.json |
| Windows | C:\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 backendcitations: Add citation sources (file path and line); works with both QMD and SQLitecommand: Executable path, defaultqmd, must be on Gateway PATHsearchMode: Defaultsearch(i.e.qmd search --json); can usevsearch,query. If a mode isn’t supported, OpenClaw falls back toqmd queryincludeDefaultMemory: When true, indexMEMORY.mdandmemory/**/*.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
- Logs:
openclaw logs --follow; seeingUsing QMD memory backendmeans QMD is enabled. - QMD status: In a shell with XDG set, run
qmd statusand confirmIndexed > 0. - Chat: In OpenClaw, ask “Confirm QMD is enabled and give a test report,” or ask about indexed memory to check recall.
12. Troubleshooting
| Issue | Fix |
|---|---|
better-sqlite3 build fails | Install build tools: sudo apt install build-essential cmake (Linux) or Visual Studio + Windows SDK (Windows) |
qmd not found | Bun: export PATH="$HOME/.bun/bin:$PATH"; npm: export PATH="$(npm config get prefix)/bin:$PATH" |
| Indexed = 0 | Check 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 timeout | Increase timeoutMs to 8000 or more |
| First search slow | Normal: first run downloads/loads GGUF models; warm with qmd query "test" -c memory-root --json in same XDG env |
| Windows | Official 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
| Description | Link |
|---|---|
| QMD repo | https://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 |