
Qmd
- 3.6k installs
- 28.6k repo stars
- Updated June 24, 2026
- tobi/qmd
QMD is an agent skill that searches local markdown indexes with BM25 and structured semantic queries, then retrieves full documents so answers cite docids and line numbers instead of snippets alone.
About
QMD is an agent skill for searching indexed local markdown collections including notes, docs, wikis, and transcripts before reaching for web search. The documented loop is search candidates, retrieve full sources with qmd get or qmd multi-get, then answer citing docids and line numbers. Default mode is structured qmd query where the agent authors intent, lex, vec, and hyde fields rather than relying on built-in expansion. BM25 qmd search suits exact titles and rare phrases; structured query suits conceptual recall when wording differs from sources. Retrieval outputs are line-numbered with qmd paths and docids; slice with path:from:count instead of piping through sed or head. Collection filters narrow corpora; qmd doctor covers setup health. MCP query accepts lex, vec, and hyde objects plus intent. Maintenance commands mutate indexes and should run only on user request. Install via npm install -g @tobilu/qmd. Developers invoke it when answers may already live in local markdown and snippets alone would miss nuance or quotes.
- Three-step loop: search candidates, multi-get full documents, answer with docid and line citations.
- Structured qmd query expects agent-written intent, lex, vec, and hyde fields for ranking control.
- Line-numbered get output supports :from:count slices without sed, head, or tail piping.
- BM25 search for exact terms; structured query for conceptual recall across collections.
- MCP query tool accepts lex, vec, hyde searches plus intent and optional collection filters.
Qmd by the numbers
- 3,570 all-time installs (skills.sh)
- +127 installs in the week ending Aug 5, 2026 (Skillselion tracking)
- Ranked #111 of 1,879 Documentation skills by installs in the Skillselion catalog
- Security screen: LOW risk (skills.sh audit)
- Data as of Aug 5, 2026 (Skillselion catalog sync)
qmd capabilities & compatibility
- Capabilities
- bm25 lexical search across indexed collections · structured intent/lex/vec/hyde query authoring · line numbered get and multi get retrieval with d · mcp query tool with multi mode searches
- Works with
- notion · obsidian
- Use cases
- research · documentation · memory
- Runs
- Runs locally
- Pricing
- Free
What qmd says it does
Do not answer from snippets alone when the user needs facts, decisions, quotes
npx skills add https://github.com/tobi/qmd --skill qmdAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 3.6k |
|---|---|
| repo stars | ★ 28.6k |
| Security audit | 3 / 3 scanners passed |
| Last updated | June 24, 2026 |
| Repository | tobi/qmd ↗ |
How do I find and cite the right passage in my local notes or wiki without answering from search snippets or breaking docid resolution with shell pipes?
Search local markdown notes and wikis with QMD using BM25, structured query fields, and multi-get retrieval before answering from snippets.
Who is it for?
Developers with indexed markdown notes, concept wikis, or project docs who want agent-guided QMD search and retrieval.
Skip if: Skip when the answer requires live web data or the markdown corpus is not indexed with qmd update and qmd embed.
When should I use this skill?
User asks to find notes, retrieve a wiki page, answer from indexed markdown, or set up QMD collections and health checks.
What you get
Ranked document hits, full line-numbered retrievals, and answers grounded in cited qmd paths and docids.
- Cited answers from retrieved markdown
- Search hit lists with docids
By the numbers
- Version 2.2.0
- Install via npm package @tobilu/qmd
Files
QMD - Query Markdown Documents
How search works
QMD searches local markdown collections: notes, docs, wikis, transcripts, and project knowledge bases. Use it before web search when the answer may already be in indexed local files.
The workflow is always:
1. Search for candidate documents. 2. Retrieve the full source with qmd get or qmd multi-get. 3. Answer from retrieved text, citing paths or docids.
Do not answer from snippets alone when the user needs facts, decisions, quotes, or nuance. Snippets are only leads.
Typical loop:
qmd search "merchant reality support interviews" -n 5
# leads: #abc123 concepts/customer-proximity.md; #def432 sources/merchant-call.md
qmd multi-get "#abc123,#def432" --format mdDefault to structured `qmd query` with `intent:`, `lex:`, `vec:`, and `hyde:` fields that you write yourself. You are a better query expander than the built-in model: you know the user's actual goal, the domain vocabulary, and the nearby-but-wrong concepts to avoid. Do not just paste the user's words into qmd query "..." and hope the expansion model guesses right — supply the intent: and craft the lexical and semantic terms deliberately (see Pick the right search mode).
When reporting what you retrieved, a compact note is enough; do not paste whole files unless needed:
Retrieved:
- #abc123 concepts/customer-proximity.md
- #def432 sources/merchant-call.mdPick the right search mode
Use BM25 lexical search when you know exact words, titles, names, code symbols, or rare phrases:
qmd search "cockpit OKR Goodhart" -n 10
qmd search '"AI Before Headcount"' -c concepts -n 5Use `qmd query` with structured fields when the user describes an idea indirectly, uses different wording than the source, or needs conceptual recall. This is the default mode — write the fields yourself rather than leaning on query expansion. Combine exact anchors with semantic recall:
qmd query $'intent: Find the concept note about metrics as instruments without letting OKRs replace judgment.\nlex: cockpit instruments OKR Goodhart metrics judgment\nvec: data informed not metric driven product judgment\nhyde: A concept note says metrics are useful like cockpit instruments, but leaders should remain data-informed rather than metric-driven because OKRs and dashboards can Goodhart product judgment.'Structured query fields (you author each one — do not delegate this to the expansion model):
intent:states what you are trying to find and what to avoid. Always
supply this. It steers ranking away from nearby-but-wrong concepts.
lex:exact terms, aliases, titles, code symbols, and rare words you expect
in the source. This is your own keyword expansion.
vec:paraphrases the idea in natural language, in source-like wording.hyde:describes the document or answer that would satisfy the request.
You do not need all four every time, but you should almost always write at least intent: plus one of lex:/vec:. A bare qmd query "the user's sentence" throws away the context only you have and relies on the built-in expander to reconstruct it — prefer the structured form.
If you genuinely have nothing to expand (a single rare token, a verbatim phrase), that is a job for qmd search, not bare qmd query:
qmd query --format json --explain $'intent: ...\nlex: ...\nvec: ...' # inspect rankingIf qmd query is slow or model/GPU setup fails, fall back to qmd search with better lexical terms.
Retrieve sources
Search results include docids like #abc123 and qmd://... paths. Fetch them:
qmd get "#abc123"
qmd get qmd://concepts/ai-before-headcount.md
qmd multi-get "#abc123,#def432" --format md
qmd multi-get 'concepts/{ai-before-headcount.md,data-informed-not-metric-driven.md}' --format md
qmd multi-get 'sources/podcast-2025-*.md' -l 80Use multi-get when comparing several hits or gathering context across pages.
Output is line-numbered and carries the docid — cite both
get and multi-get are line-numbered by default and always print the document's #docid and qmd:// path. So get output looks like:
qmd://concepts/note.md #abc123
---
1: # Metrics as instruments
2:
3: Treat dashboards like cockpit instruments...Cite the docid and exact line numbers in your answer, and use the numbers to ask for the next slice. Pass --no-line-numbers only when you need raw content to copy verbatim (e.g. reproducing a code block).
When you need to open or edit the underlying file (e.g. hand a path to Read, Edit, or an editor), add --full-path. It replaces the qmd:// URL + docid header with the document's on-disk path, falling back to the canonical header if the file no longer exists on disk:
$ qmd get "#abc123" --full-path
/Users/you/notes/concepts/note.md
---
1: # Metrics as instruments--full-path works the same way on qmd search and qmd query: result paths become the file's on-disk path — ./-prefixed relative path when the file is inside $PWD, absolute realpath otherwise — and the per-result #docid is dropped because the path is the identifier. The leading ./ is intentional so the output is unambiguously a filesystem path and cannot be mistaken for a bare collection-relative string. Default search/query output still uses qmd:// URIs; only opt into --full-path when you specifically need a path you can hand to a non-QMD tool.
Read line ranges with the :from:count suffix — never pipe through sed/head/tail
qmd get slices files itself. Use the suffix or flags; do not shell out to sed -n, head, tail, or awk to pull a line range. Piping defeats docid resolution, virtual-path lookups, line numbering, and the header, and it is slower and more error-prone.
The most compact form is a :from:count suffix right on the path or docid — prefer it:
qmd get "#abc123:120:40" # 40 lines starting at line 120
qmd get qmd://concepts/note.md:200:60 # lines 200–259
qmd get "#abc123:120" # from line 120 to end of file
qmd get "#abc123" --from 120 -l 40 # equivalent, using flagsSuffix and flags:
<path>:<from>:<count>— start at line<from>, read<count>lines. **Best
for reading around a search hit.**
<path>:<from>— start at<from>, read to end of file.--from <line>/-l <lines>— flag equivalents. Explicit flags override the
suffix, so ... :5:2 -l 1 reads 1 line.
--no-line-numbers— drop theN:prefixes (line numbers are on by default).
Wrong: qmd get "#abc123" | sed -n '120,160p' Right: qmd get "#abc123:120:40"
Search results include a :line anchor on each hit — feed it straight into qmd get path:line:<n> to read a window around the match (line numbers in the output will start at line).
Discover what is indexed
qmd collection list
qmd ls
qmd statusAdd collection filters when broad searches drift into the wrong corpus:
qmd search "headcount autonomous agents" -c concepts -n 10
qmd query "merchant support product reality" -c concepts -c sources -n 10Omit -c to search everything.
MCP Tool: query
When using the MCP server, prefer structured searches:
{
"searches": [
{ "type": "lex", "query": "cockpit OKR Goodhart" },
{ "type": "vec", "query": "data informed not metric driven product judgment" },
{ "type": "hyde", "query": "A concept note explains that metrics are useful as instruments, but leaders should not let OKRs or dashboards replace judgment." }
],
"intent": "Find the concept note about using metrics as instruments without becoming metric-driven.",
"collections": ["concepts"],
"limit": 10
}Query types:
lex— BM25 keyword search. Best for exact terms, names, titles, and code.vec— vector semantic search. Best for natural-language concepts.hyde— vector search using a hypothetical answer/document passage.
Query craft
Good QMD searches mix three things:
1. Title/alias anchors: exact page titles, named entities, phrases. 2. Semantic paraphrase: how a human would describe the idea. 3. Negative space: enough intent to avoid nearby-but-wrong concepts.
Examples:
# Exact-ish title lookup
qmd search '"arm the rebels" merchants tools big companies' -c concepts
# Semantic concept lookup
qmd query $'intent: Find the customer proximity concept, not generic customer delight.\nlex: support pseudonymous merchant customer interviews\nvec: founder stays close to merchant reality through support and product use'
# Source lookup
qmd search "six-week cadence WhatsApp merchant relationships Shawn Ryan" -c sources -n 10Setup and maintenance
Only mutate indexes when the user asked for setup or maintenance. Searching and retrieving are safe; collection/index mutation is not a casual first step.
npm install -g @tobilu/qmd
qmd collection add ~/notes --name notes
qmd update
qmd embedHealth and diagnostics:
qmd doctor
qmd status
qmd pullqmd doctor checks config, model cache, device/GPU setup, vector fingerprints, and common environment overrides. If a model-backed command fails, run it before changing configuration.
MCP setup
See references/mcp-setup.md for Claude Code, Claude Desktop, OpenClaw, and HTTP server configuration.
Pitfalls
- Do not stop at snippets. Fetch documents before making claims.
- Do not slice files with `sed`/`head`/`tail`. Use the
path:from:count
suffix (e.g. qmd get "#abc123:120:40") or --from/-l. Output is already line-numbered; piping breaks docid resolution, the header, and virtual paths.
- Do not lean on query expansion. Write
intent:/lex:/vec:/hyde:
yourself. A bare qmd query "user sentence" discards the context only you have. You expand the query; the model just ranks.
- Do not overuse semantic search. If you know exact titles or terms, BM25 is
faster and often better.
- Do not mutate indexes casually.
qmd collection add,qmd update, and
qmd embed change local state and can be expensive.
- Model-backed commands can be environment-sensitive. If
qmd query,
qmd vsearch, or reranking fails because local models/GPU are unavailable, use qmd search and stronger lexical/structured terms.
- Ambiguous user wording needs intent. Add
intent:rather than hoping query
expansion guesses the right domain.
- Collection names matter. Search
conceptsfor synthesized wiki pages,
sources for transcripts/raw source pages, and docs collections for code or project documentation.
QMD MCP Server Setup
Install
npm install -g @tobilu/qmd
qmd collection add ~/path/to/markdown --name myknowledge
qmd embedConfigure MCP Client
Claude Code (~/.claude/settings.json):
{
"mcpServers": {
"qmd": { "command": "qmd", "args": ["mcp"] }
}
}Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json):
{
"mcpServers": {
"qmd": { "command": "qmd", "args": ["mcp"] }
}
}OpenClaw (~/.openclaw/openclaw.json):
{
"mcp": {
"servers": {
"qmd": { "command": "qmd", "args": ["mcp"] }
}
}
}HTTP Mode
qmd mcp --http # Port 8181
qmd mcp --http --daemon # Background
qmd mcp stop # Stop daemonTools
structured_search
Search with pre-expanded queries.
{
"searches": [
{ "type": "lex", "query": "keyword phrases" },
{ "type": "vec", "query": "natural language question" },
{ "type": "hyde", "query": "hypothetical answer passage..." }
],
"limit": 10,
"collection": "optional",
"minScore": 0.0
}| Type | Method | Input |
|---|---|---|
lex | BM25 | Keywords (2-5 terms) |
vec | Vector | Question |
hyde | Vector | Answer passage (50-100 words) |
get
Retrieve document by path or #docid.
| Param | Type | Description |
|---|---|---|
path | string | File path or #docid |
full | bool? | Return full content |
lineNumbers | bool? | Add line numbers |
multi_get
Retrieve multiple documents.
| Param | Type | Description |
|---|---|---|
pattern | string | Glob or comma-separated list |
maxBytes | number? | Skip large files (default 10KB) |
status
Index health and collections. No params.
Troubleshooting
- Not starting:
which qmd,qmd mcpmanually - No results:
qmd collection list,qmd embed - Slow first search: Normal, models loading (~3GB)
Related skills
How it compares
Use qmd for private markdown corpora on disk when you do not need vector databases or cloud knowledge bases.
FAQ
When should I use qmd search versus qmd query?
Use qmd search for exact terms and titles; use structured qmd query with intent, lex, vec, and hyde when the idea is described indirectly.
Why avoid piping qmd get through sed or head?
Piping breaks docid resolution, virtual paths, line numbering, and headers; use the :from:count suffix or --from and -l flags instead.
How do I install and index collections?
Run npm install -g @tobilu/qmd, then qmd collection add, qmd update, and qmd embed when the user requests setup.
Is Qmd safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.