AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
MCP verified MIT Self-run

Picoqmd

mcp-altseneca-picoqmd · by altSeneca

Lightweight QMD alternative: fully local hybrid search engine (BM25 + vector + rerank) and MCP server in a single ~15MB Go binary. No Node.js. Runs on Raspberry Pi.

No reviews yet
0 installs
36 views
0.0% view→install

Install

$ agentstack add mcp-altseneca-picoqmd

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/mcp-altseneca-picoqmd)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
2mo ago

Declared compatibility

Claude CodeClaude DesktopCursorWindsurf

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Picoqmd? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

PicoQMD — a lightweight QMD alternative for low-resource computers

A fully local search engine and MCP server in a single ~15MB Go binary. PicoQMD is a from-scratch Go reimplementation of tobi's QMD built for machines where QMD's Node.js/Bun stack is too heavy: Raspberry Pi (including Pi Zero), old laptops, small VPSes, air-gapped boxes, and dev machines that just don't want another Node runtime.

Same search pipeline as QMD — SQLite FTS5 BM25, semantic vector search, hybrid query expansion + Reciprocal Rank Fusion + cross-encoder reranking, the same GGUF models — with no Node.js, no Bun, no Python, no npm install, no native-module ABI headaches. One static binary and a SQLite file.

Give any AI agent — Claude Code, OpenClaw, PicoClaw, MiniClaw, or your own — instant local search over code, docs, configs, and notes. No cloud, no telemetry, works offline.

PicoQMD vs QMD

If you're looking for "QMD but for a lower-spec computer", this is the trade-off table:

| | QMD | PicoQMD | |--|-----|---------| | Install | Node.js/Bun + npm package (native modules: better-sqlite3, sqlite-vec, node-llama-cpp) | one static Go binary (~15MB) | | Runtime | Node/Bun VM | none — measured ~29MB peak RSS for a BM25 search over a 10,800-doc index | | BM25 keyword search | SQLite FTS5 | SQLite FTS5 (pure-Go driver, contentless index — documents are not duplicated into the DB) | | Semantic vector search | sqlite-vec + node-llama-cpp | pure-Go brute-force cosine + llama.cpp via FFI (same EmbeddingGemma model) | | Hybrid pipeline | query expansion → fan-out → RRF → rerank | same design, same GGUF models | | MCP server | stdio + HTTP | stdio + HTTP | | Minimum hardware for keyword search | needs Node-capable box | Raspberry Pi Zero / ARM32 / RISC-V | | Vector/hybrid search | yes | yes, on arm64/amd64 (Linux, macOS) | | Line-numbered get with :from:count ranges | yes | yes (v0.4.0) | | Embedding fingerprints (stale-vector detection) | yes | yes (v0.4.0) | | AST/tree-sitter code chunking | yes | not yet ([roadmap](ROADMAP.md)) | | CJK trigram search | yes | no (kept out deliberately — doubles index size) |

PicoQMD is not a fork — it's an independent Go implementation that tracks QMD's retrieval design and ports its fixes (v0.4.0 covers the applicable QMD v2.1–v2.6.3 changes). If you have a beefy dev machine and live in the Node ecosystem, use QMD. If you want the same local search quality in a fraction of the footprint — or on hardware QMD can't run on at all — use PicoQMD.

Why PicoQMD?

Most search tools assume beefy hardware. PicoQMD is built for the other end of the spectrum:

  • ~15MB binary (~11MB with -ldflags="-s -w") — smaller than most npm installs
  • Minimal RAM — BM25 mode runs in tens of MB; fits alongside an agent on $10 hardware
  • Zero dependencies — no runtime, no interpreters, no containers, no C toolchain (pure-Go SQLite)
  • MCP native — stdio and HTTP transports, works with any MCP-compatible agent
  • Cross-compiles anywhere Go does — ARM32, ARM64, RISC-V, x86 in one command
  • Scales up — add semantic vector search and hybrid re-ranking when your hardware allows
  • Graceful degradation — without models, vector/hybrid tools are hidden from the agent; BM25, get, and observations still work
  • Safe under launchd/cron/systemd — auto-quiets progress output when stdout is not a TTY, so captured logs stay bounded

What's New in v0.4.0

Ports of the applicable QMD v2.1.0–v2.6.3 improvements, plus fixes to PicoQMD's own retrieval path (full details in [CHANGELOG.md](CHANGELOG.md)):

  • Robust FTS5 queries — version strings (v3.9.7), hyphenated terms (real-time), and operator words (AND/OR/NOT) can no longer produce FTS5 syntax errors; every term is emitted as a quoted phrase with prefix matching.
  • Real document retrievalget/multi_get return content from disk with line-numbered output, qmd:// + #docid headers, and line-range refs: get notes.md:120:40 reads 40 lines from line 120. --full-path swaps in the on-disk path for piping into editors and file tools.
  • BM25 snippets with line citations — snippets are extracted from the source file (>>>term), which also feeds the reranker real text instead of bare titles.
  • Embedding fingerprints — vectors are stamped with the model + chunker identity; changing either marks documents pending for re-embed instead of silently searching stale vectors.
  • Honest embed tracking — a document only counts as embedded when every chunk has a current vector; interrupted embed runs resume instead of being forgotten.
  • Concurrency-safe SQLite — 120s busy timeout (override: PICOQMD_SQLITE_BUSY_TIMEOUT, ms) so a scheduled sync racing the MCP daemon queues instead of throwing database is locked.
  • Scoped embeddingpicoqmd embed -c embeds one collection without re-indexing, so huge collections are opt-in.
  • --no-rerank — skip the cross-encoder for faster hybrid results on constrained hardware.
  • First test suitego test ./... covers query sanitization, retrieval, and embed tracking against a real store.

Quick Start

# Install (or grab a prebuilt binary from Releases)
go install github.com/altSeneca/picoqmd@latest

# Index markdown docs (default)
picoqmd add ~/docs --no-embed

# Index a codebase — Go, Python, TypeScript, and markdown
picoqmd add ~/myproject --glob "**/*.{go,py,ts,md}" --no-embed

# Search — prefix matching built in
picoqmd search "kubernetes deployment"
picoqmd search "deploy"          # matches "deployment", "deployed", "deploying"

# Retrieve with line ranges
picoqmd get notes.md:120:40      # 40 lines starting at line 120

MCP Server

PicoQMD is an MCP server first. Point your agent at it and get search, get, multi_get, status — plus vector_search, deep_search, and research when models are available.

Claude Code

Add to ~/.claude/settings.json under mcpServers:

{
  "picoqmd": {
    "command": "picoqmd",
    "args": ["mcp"]
  }
}

OpenClaw / PicoClaw / MiniClaw / Any MCP Client

Stdio transport (default):

picoqmd mcp

HTTP transport for networked setups:

picoqmd mcp --http :8181

Any agent that speaks Model Context Protocol can connect. The MCP server exposes the same search tools whether you're on a Mac Studio or a Pi Zero.

MCP Tools Reference

| Tool | Description | Requires Models | |------|-------------|----------------| | search | BM25 keyword search via SQLite FTS5 with prefix matching, disk-extracted snippets, line citations | No | | vector_search | Semantic similarity using embeddings | Yes | | deep_search | Query expansion + fan-out + RRF + re-ranking (noExpand, noRerank to trim stages) | Yes | | research | Composite: BM25 + vector in parallel, deduplicated via RRF, one call | Yes | | get | Retrieve a document by path, #docid, or qmd:// URI, with :from:count line ranges, line-numbered | No | | multi_get | Batch retrieve by glob or comma-separated list; oversized files reported as skipped, never silently dropped | No | | status | Index health, embedding fingerprint, pending counts, stale observation count | No |

Common parameters across search tools:

| Parameter | Type | Description | |-----------|------|-------------| | query | string | Search query (required) | | intent | string | Optional disambiguation hint threaded through expansion, reranking, and snippets | | limit | int | Max results, default 10 | | collection | string | Filter to a specific collection | | minScore | float | Minimum relevance score 0–1 | | maxChars | int | Truncate response to this many characters (server-side token budget) | | note | string | Save an observation linked to the top result |

get / multi_get parameters: fromLine, maxLines, lineNumbers (default true), fullPath, maxBytes (multi_get skip threshold, default 64KB).

Two Modes

BM25 Only — For Edge and Constrained Devices

picoqmd add ~/notes --no-embed
picoqmd add ~/src --glob "**/*.{go,py,rs,ts,js}" --no-embed
picoqmd search "meeting notes"

No models, no llama.cpp, no downloads. Just Go + SQLite FTS5 with prefix matching. This is the mode for Pi-Zero-class devices where every megabyte counts: keyword search over ~10,000 documents runs in under 30MB of RAM.

Vector + Hybrid — For Capable Hardware

picoqmd add ~/notes                    # downloads embedding model (~300MB)
picoqmd model download embedding       # or: reranker, expansion
picoqmd "semantic search query"        # auto-selects best pipeline
picoqmd embed -c big-collection        # embed one collection at a time

When you have the RAM, unlock semantic search with query expansion, RRF fusion, and cross-encoder re-ranking — all still local, all still offline. Same models QMD uses:

| Model | Size | Purpose | |-------|------|---------| | embeddinggemma-300M | ~300MB | Document & query embeddings | | qwen3-reranker-0.6b | ~600MB | Cross-encoder re-ranking | | qmd-query-expansion-1.7B | ~1GB | Query expansion |

Search Modes

| Mode | Command | What it does | |------|---------|--------------| | BM25 | picoqmd search "query" | Instant keyword search via SQLite FTS5 with prefix matching | | Vector | picoqmd vsearch "query" | Semantic similarity using embeddings | | Hybrid | picoqmd query "query" | Expansion + fan-out + RRF + re-ranking (--no-expand, --no-rerank to trim) | | Smart | picoqmd "query" | Auto-selects best pipeline for available models |

Platform Support

| Platform | BM25 | Vector/Hybrid | Binary | |----------|------|---------------|--------| | Linux arm32 (Pi Zero, Pi 1) | yes | — | ~9MB | | Linux riscv64 | yes | — | ~9MB | | Linux arm64 (Pi 3/4/5, SBCs) | yes | yes | ~11MB | | Linux amd64 | yes | yes | ~11MB | | macOS arm64 (Apple Silicon) | yes | yes | ~11MB | | macOS amd64 (Intel) | yes | yes | ~11MB |

Cross-compile for your target in one line:

GOOS=linux GOARCH=arm GOARM=7 go build -ldflags="-s -w" -o picoqmd .

Export / Import — Index Once, Search Anywhere

Build a full index (with embeddings) on a capable machine, then transfer it to a tiny device:

# On your workstation
picoqmd add ~/docs && picoqmd export -o docs.tar.gz

# On a Pi Zero / edge device
picoqmd import docs.tar.gz
picoqmd search "deployment guide"    # BM25 + precomputed embeddings, no models needed

The exported bundle contains the SQLite database with all embeddings baked in. The edge device gets semantic-quality ranking without downloading a single model.

Remote Search

Don't want to run search on the edge device at all? Forward to a remote instance:

# Server
picoqmd mcp --http :8181

# Edge device
picoqmd search "query" --remote server:8181

File Type Support

Index any text file — not just markdown. Use glob patterns with brace expansion:

picoqmd add . --glob "**/*.md"                        # markdown only (default)
picoqmd add . --glob "**/*.{go,py,ts,js,rs,md}"       # code + docs
picoqmd add . --glob "**/*.{yaml,yml,json,toml}"      # config files

PicoQMD automatically skips binary files, files over 1MB, and common noise directories (.git, node_modules, vendor, __pycache__, build, dist, target, etc.).

Use Cases

  • QMD alternative on low-spec hardware — same local hybrid search without the Node.js runtime, on machines from a Pi Zero up
  • Claude Code MCP server — fast, token-efficient search over large codebases without spinning up Elasticsearch
  • PicoClaw / MiniClaw search tool — give your $10 AI agent fast local search over project docs, wikis, and codebases
  • OpenClaw on Raspberry Pi — add document search to your self-hosted AI assistant without eating its RAM budget
  • Edge AI knowledge base — deploy searchable documentation to field devices, kiosks, or air-gapped environments
  • Offline dev search — index API docs, READMEs, and notes for airplane-mode development
  • Token-efficient MCP pipelines — use research to cut context window usage by ~50% vs separate search calls

Roadmap

See [ROADMAP.md](ROADMAP.md) — next up: Matryoshka 768→256 embedding truncation (3× smaller/faster vectors), chunk-level incremental re-embedding, recency-aware ranking, binary quantization with two-phase rescoring for very large corpora, and tree-sitter AST chunking for code.

Acknowledgments

PicoQMD is a Go reimplementation of QMD by @tobi, which provides the architecture, hybrid search pipeline, models, and design. Built with yzma (pure-Go llama.cpp bindings) and llama.cpp.

See [GUIDE.md](GUIDE.md) for the full user guide, output formats, and configuration.

License

[MIT](LICENSE)

Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.