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 or . 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: Default to structured with , , , and fields that you write yourself. You are a better…

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.'\n```\n\nStructured query fields (you author each one — do not delegate this to the\nexpansion model):\n\n- `intent:` states what you are trying to find **and what to avoid**. Always\n supply this. It steers ranking away from nearby-but-wrong concepts.\n- `lex:` exact terms, aliases, titles, code symbols, and rare words you expect\n in the source. This is your own keyword expansion.\n- `vec:` paraphrases the idea in natural language, in source-like wording.\n- `hyde:` describes the document or answer that would satisfy the request.\n\nYou do not need all four every time, but you should almost always write at least\n`intent:` plus one of `lex:`/`vec:`. A bare `qmd query \"the user's sentence\"`\nthrows away the context only you have and relies on the built-in expander to\nreconstruct it — prefer the structured form.\n\nIf you genuinely have nothing to expand (a single rare token, a verbatim phrase),\nthat is a job for `qmd search`, not bare `qmd query`:\n\n```bash\nqmd query --format json --explain

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 or . 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: Default to structured with , , , and fields that you write yourself. You are a better…

intent: ...\\nlex: ...\\nvec: ...' # inspect ranking\n```\n\nIf `qmd query` is slow or model/GPU setup fails, fall back to `qmd search` with\nbetter lexical terms.\n\n## Retrieve sources\n\nSearch results include docids like `#abc123` and `qmd://...` paths. Fetch them:\n\n```bash\nqmd get \"#abc123\"\nqmd get qmd://concepts/ai-before-headcount.md\nqmd multi-get \"#abc123,#def432\" --format md\nqmd multi-get 'concepts/{ai-before-headcount.md,data-informed-not-metric-driven.md}' --format md\nqmd multi-get 'sources/podcast-2025-*.md' -l 80\n```\n\nUse `multi-get` when comparing several hits or gathering context across pages.\n\n### Output is line-numbered and carries the docid — cite both\n\n`get` and `multi-get` are **line-numbered by default** and always print the\ndocument's `#docid` and `qmd://` path. So `get` output looks like:\n\n```text\nqmd://concepts/note.md #abc123\n---\n\n1: # Metrics as instruments\n2:\n3: Treat dashboards like cockpit instruments...\n```\n\nCite the docid and exact line numbers in your answer, and use the numbers to ask\nfor the next slice. Pass `--no-line-numbers` only when you need raw content to\ncopy verbatim (e.g. reproducing a code block).\n\nWhen you need to open or edit the underlying file (e.g. hand a path to `Read`,\n`Edit`, or an editor), add `--full-path`. It replaces the `qmd://` URL + docid\nheader with the document's on-disk path, falling back to the canonical header if\nthe file no longer exists on disk:\n\n```text\n$ qmd get \"#abc123\" --full-path\n/Users/you/notes/concepts/note.md\n---\n\n1: # Metrics as instruments\n```\n\n`--full-path` works the same way on `qmd search` and `qmd query`: result paths\nbecome the file's on-disk path — `./`-prefixed relative path when the file is\ninside `$PWD`, absolute realpath otherwise — and the per-result `#docid` is\ndropped because the path is the identifier. The leading `./` is intentional so\nthe output is unambiguously a filesystem path and cannot be mistaken for a bare\ncollection-relative string. Default search/query output still uses `qmd://`\nURIs; only opt into `--full-path` when you specifically need a path you can hand\nto a non-QMD tool.\n\n### Read line ranges with the `:from:count` suffix — never pipe through `sed`/`head`/`tail`\n\n`qmd get` slices files itself. Use the suffix or flags; do **not** shell out to\n`sed -n`, `head`, `tail`, or `awk` to pull a line range. Piping defeats docid\nresolution, virtual-path lookups, line numbering, and the header, and it is\nslower and more error-prone.\n\nThe most compact form is a `:from:count` suffix right on the path or docid —\nprefer it:\n\n```bash\nqmd get \"#abc123:120:40\" # 40 lines starting at line 120\nqmd get qmd://concepts/note.md:200:60 # lines 200–259\nqmd get \"#abc123:120\" # from line 120 to end of file\nqmd get \"#abc123\" --from 120 -l 40 # equivalent, using flags\n```\n\nSuffix and flags:\n\n- `\u003cpath>:\u003cfrom>:\u003ccount>` — start at line `\u003cfrom>`, read `\u003ccount>` lines. **Best\n for reading around a search hit.**\n- `\u003cpath>:\u003cfrom>` — start at `\u003cfrom>`, read to end of file.\n- `--from \u003cline>` / `-l \u003clines>` — flag equivalents. Explicit flags override the\n suffix, so `... :5:2 -l 1` reads 1 line.\n- `--no-line-numbers` — drop the `N:` prefixes (line numbers are on by default).\n\nWrong: `qmd get \"#abc123\" | sed -n '120,160p'`\nRight: `qmd get \"#abc123:120:40\"`\n\nSearch results include a `:line` anchor on each hit — feed it straight into\n`qmd get path:line:\u003cn>` to read a window around the match (line numbers in the\noutput will start at `line`).\n\n## Discover what is indexed\n\n```bash\nqmd collection list\nqmd ls\nqmd status\n```\n\nAdd collection filters when broad searches drift into the wrong corpus:\n\n```bash\nqmd search \"headcount autonomous agents\" -c concepts -n 10\nqmd query \"merchant support product reality\" -c concepts -c sources -n 10\n```\n\nOmit `-c` to search everything.\n\n## MCP Tool: `query`\n\nWhen using the MCP server, prefer structured searches:\n\n```json\n{\n \"searches\": [\n { \"type\": \"lex\", \"query\": \"cockpit OKR Goodhart\" },\n { \"type\": \"vec\", \"query\": \"data informed not metric driven product judgment\" },\n { \"type\": \"hyde\", \"query\": \"A concept note explains that metrics are useful as instruments, but leaders should not let OKRs or dashboards replace judgment.\" }\n ],\n \"intent\": \"Find the concept note about using metrics as instruments without becoming metric-driven.\",\n \"collections\": [\"concepts\"],\n \"limit\": 10\n}\n```\n\nQuery types:\n\n- `lex` — BM25 keyword search. Best for exact terms, names, titles, and code.\n- `vec` — vector semantic search. Best for natural-language concepts.\n- `hyde` — vector search using a hypothetical answer/document passage.\n\n## Query craft\n\nGood QMD searches mix three things:\n\n1. **Title/alias anchors:** exact page titles, named entities, phrases.\n2. **Semantic paraphrase:** how a human would describe the idea.\n3. **Negative space:** enough intent to avoid nearby-but-wrong concepts.\n\nExamples:\n\n```bash\n# Exact-ish title lookup\nqmd search '\"arm the rebels\" merchants tools big companies' -c concepts\n\n# Semantic concept lookup\nqmd query

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 or . 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: Default to structured with , , , and fields that you write yourself. You are a better…

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'\n\n# Source lookup\nqmd search \"six-week cadence WhatsApp merchant relationships Shawn Ryan\" -c sources -n 10\n```\n\n## Setup and maintenance\n\nOnly mutate indexes when the user asked for setup or maintenance. Searching and\nretrieving are safe; collection/index mutation is not a casual first step.\n\n```bash\nnpm install -g @tobilu/qmd\nqmd collection add ~/notes --name notes\nqmd update\nqmd embed\n```\n\nHealth and diagnostics:\n\n```bash\nqmd doctor\nqmd status\nqmd pull\n```\n\n`qmd doctor` checks config, model cache, device/GPU setup, vector fingerprints,\nand common environment overrides. If a model-backed command fails, run it before\nchanging configuration.\n\n## MCP setup\n\nSee `references/mcp-setup.md` for Claude Code, Claude Desktop, OpenClaw, and HTTP\nserver configuration.\n\n## Pitfalls\n\n- **Do not stop at snippets.** Fetch documents before making claims.\n- **Do not slice files with `sed`/`head`/`tail`.** Use the `path:from:count`\n suffix (e.g. `qmd get \"#abc123:120:40\"`) or `--from`/`-l`. Output is already\n line-numbered; piping breaks docid resolution, the header, and virtual paths.\n- **Do not lean on query expansion.** Write `intent:`/`lex:`/`vec:`/`hyde:`\n yourself. A bare `qmd query \"user sentence\"` discards the context only you\n have. You expand the query; the model just ranks.\n- **Do not overuse semantic search.** If you know exact titles or terms, BM25 is\n faster and often better.\n- **Do not mutate indexes casually.** `qmd collection add`, `qmd update`, and\n `qmd embed` change local state and can be expensive.\n- **Model-backed commands can be environment-sensitive.** If `qmd query`,\n `qmd vsearch`, or reranking fails because local models/GPU are unavailable,\n use `qmd search` and stronger lexical/structured terms.\n- **Ambiguous user wording needs intent.** Add `intent:` rather than hoping query\n expansion guesses the right domain.\n- **Collection names matter.** Search `concepts` for synthesized wiki pages,\n `sources` for transcripts/raw source pages, and docs collections for code or\n project documentation.\n---","attachment_filenames":["references/mcp-setup.md"],"attachments":[{"filename":"references/mcp-setup.md","content":"# QMD MCP Server Setup\n\n## Install\n\n```bash\nnpm install -g @tobilu/qmd\nqmd collection add ~/path/to/markdown --name myknowledge\nqmd embed\n```\n\n## Configure MCP Client\n\n**Claude Code** (`~/.claude/settings.json`):\n```json\n{\n \"mcpServers\": {\n \"qmd\": { \"command\": \"qmd\", \"args\": [\"mcp\"] }\n }\n}\n```\n\n**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json`):\n```json\n{\n \"mcpServers\": {\n \"qmd\": { \"command\": \"qmd\", \"args\": [\"mcp\"] }\n }\n}\n```\n\n**OpenClaw** (`~/.openclaw/openclaw.json`):\n```json\n{\n \"mcp\": {\n \"servers\": {\n \"qmd\": { \"command\": \"qmd\", \"args\": [\"mcp\"] }\n }\n }\n}\n```\n\n## HTTP Mode\n\n```bash\nqmd mcp --http # Port 8181\nqmd mcp --http --daemon # Background\nqmd mcp stop # Stop daemon\n```\n\n## Tools\n\n### structured_search\n\nSearch with pre-expanded queries.\n\n```json\n{\n \"searches\": [\n { \"type\": \"lex\", \"query\": \"keyword phrases\" },\n { \"type\": \"vec\", \"query\": \"natural language question\" },\n { \"type\": \"hyde\", \"query\": \"hypothetical answer passage...\" }\n ],\n \"limit\": 10,\n \"collection\": \"optional\",\n \"minScore\": 0.0\n}\n```\n\n| Type | Method | Input |\n|------|--------|-------|\n| `lex` | BM25 | Keywords (2-5 terms) |\n| `vec` | Vector | Question |\n| `hyde` | Vector | Answer passage (50-100 words) |\n\n### get\n\nRetrieve document by path or `#docid`.\n\n| Param | Type | Description |\n|-------|------|-------------|\n| `path` | string | File path or `#docid` |\n| `full` | bool? | Return full content |\n| `lineNumbers` | bool? | Add line numbers |\n\n### multi_get\n\nRetrieve multiple documents.\n\n| Param | Type | Description |\n|-------|------|-------------|\n| `pattern` | string | Glob or comma-separated list |\n| `maxBytes` | number? | Skip large files (default 10KB) |\n\n### status\n\nIndex health and collections. No params.\n\n## Troubleshooting\n\n- **Not starting**: `which qmd`, `qmd mcp` manually\n- **No results**: `qmd collection list`, `qmd embed`\n- **Slow first search**: Normal, models loading (~3GB)\n","content_type":"text/markdown; charset=utf-8","language":"markdown","size":1994,"content_sha256":"23919878a63b983f5da086276f4923389929565d476e58418e10aa907ee7a3a6"}],"content_json":{"type":"doc","content":[{"type":"heading","attrs":{"level":1},"content":[{"text":"QMD - Query Markdown Documents","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"How search works","type":"text"}]},{"type":"paragraph","content":[{"text":"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.","type":"text"}]},{"type":"paragraph","content":[{"text":"The workflow is always:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Search for candidate documents.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Retrieve the full source with ","type":"text"},{"text":"qmd get","type":"text","marks":[{"type":"code_inline"}]},{"text":" or ","type":"text"},{"text":"qmd multi-get","type":"text","marks":[{"type":"code_inline"}]},{"text":".","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Answer from retrieved text, citing paths or docids.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Do not answer from snippets alone when the user needs facts, decisions, quotes, or nuance. Snippets are only leads.","type":"text"}]},{"type":"paragraph","content":[{"text":"Typical loop:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"qmd search \"merchant reality support interviews\" -n 5\n# leads: #abc123 concepts/customer-proximity.md; #def432 sources/merchant-call.md\nqmd multi-get \"#abc123,#def432\" --format md","type":"text"}]},{"type":"paragraph","content":[{"text":"Default to structured ","type":"text","marks":[{"type":"strong"}]},{"text":"qmd query","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" with ","type":"text","marks":[{"type":"strong"}]},{"text":"intent:","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":", ","type":"text","marks":[{"type":"strong"}]},{"text":"lex:","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":", ","type":"text","marks":[{"type":"strong"}]},{"text":"vec:","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":", and ","type":"text","marks":[{"type":"strong"}]},{"text":"hyde:","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" fields that you write yourself.","type":"text","marks":[{"type":"strong"}]},{"text":" 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 ","type":"text"},{"text":"qmd query \"...\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" and hope the expansion model guesses right — supply the ","type":"text"},{"text":"intent:","type":"text","marks":[{"type":"code_inline"}]},{"text":" and craft the lexical and semantic terms deliberately (see ","type":"text"},{"text":"Pick the right search mode","type":"text","marks":[{"type":"link","attrs":{"href":"#pick-the-right-search-mode","title":null}}]},{"text":").","type":"text"}]},{"type":"paragraph","content":[{"text":"When reporting what you retrieved, a compact note is enough; do not paste whole files unless needed:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"Retrieved:\n- #abc123 concepts/customer-proximity.md\n- #def432 sources/merchant-call.md","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Pick the right search mode","type":"text"}]},{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"BM25 lexical search","type":"text","marks":[{"type":"strong"}]},{"text":" when you know exact words, titles, names, code symbols, or rare phrases:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"qmd search \"cockpit OKR Goodhart\" -n 10\nqmd search '\"AI Before Headcount\"' -c concepts -n 5","type":"text"}]},{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"qmd query","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":" with structured fields","type":"text","marks":[{"type":"strong"}]},{"text":" when the user describes an idea indirectly, uses different wording than the source, or needs conceptual recall. ","type":"text"},{"text":"This is the default mode — write the fields yourself rather than leaning on query expansion.","type":"text","marks":[{"type":"strong"}]},{"text":" Combine exact anchors with semantic recall:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"qmd query

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 or . 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: Default to structured with , , , and fields that you write yourself. You are a better…

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.'","type":"text"}]},{"type":"paragraph","content":[{"text":"Structured query fields (you author each one — do not delegate this to the expansion model):","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"intent:","type":"text","marks":[{"type":"code_inline"}]},{"text":" states what you are trying to find ","type":"text"},{"text":"and what to avoid","type":"text","marks":[{"type":"strong"}]},{"text":". Always supply this. It steers ranking away from nearby-but-wrong concepts.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"lex:","type":"text","marks":[{"type":"code_inline"}]},{"text":" exact terms, aliases, titles, code symbols, and rare words you expect in the source. This is your own keyword expansion.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"vec:","type":"text","marks":[{"type":"code_inline"}]},{"text":" paraphrases the idea in natural language, in source-like wording.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"hyde:","type":"text","marks":[{"type":"code_inline"}]},{"text":" describes the document or answer that would satisfy the request.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"You do not need all four every time, but you should almost always write at least ","type":"text"},{"text":"intent:","type":"text","marks":[{"type":"code_inline"}]},{"text":" plus one of ","type":"text"},{"text":"lex:","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"vec:","type":"text","marks":[{"type":"code_inline"}]},{"text":". A bare ","type":"text"},{"text":"qmd query \"the user's sentence\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" throws away the context only you have and relies on the built-in expander to reconstruct it — prefer the structured form.","type":"text"}]},{"type":"paragraph","content":[{"text":"If you genuinely have nothing to expand (a single rare token, a verbatim phrase), that is a job for ","type":"text"},{"text":"qmd search","type":"text","marks":[{"type":"code_inline"}]},{"text":", not bare ","type":"text"},{"text":"qmd query","type":"text","marks":[{"type":"code_inline"}]},{"text":":","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"qmd query --format json --explain

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 or . 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: Default to structured with , , , and fields that you write yourself. You are a better…

intent: ...\\nlex: ...\\nvec: ...' # inspect ranking","type":"text"}]},{"type":"paragraph","content":[{"text":"If ","type":"text"},{"text":"qmd query","type":"text","marks":[{"type":"code_inline"}]},{"text":" is slow or model/GPU setup fails, fall back to ","type":"text"},{"text":"qmd search","type":"text","marks":[{"type":"code_inline"}]},{"text":" with better lexical terms.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Retrieve sources","type":"text"}]},{"type":"paragraph","content":[{"text":"Search results include docids like ","type":"text"},{"text":"#abc123","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"qmd://...","type":"text","marks":[{"type":"code_inline"}]},{"text":" paths. Fetch them:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"qmd get \"#abc123\"\nqmd get qmd://concepts/ai-before-headcount.md\nqmd multi-get \"#abc123,#def432\" --format md\nqmd multi-get 'concepts/{ai-before-headcount.md,data-informed-not-metric-driven.md}' --format md\nqmd multi-get 'sources/podcast-2025-*.md' -l 80","type":"text"}]},{"type":"paragraph","content":[{"text":"Use ","type":"text"},{"text":"multi-get","type":"text","marks":[{"type":"code_inline"}]},{"text":" when comparing several hits or gathering context across pages.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Output is line-numbered and carries the docid — cite both","type":"text"}]},{"type":"paragraph","content":[{"text":"get","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"multi-get","type":"text","marks":[{"type":"code_inline"}]},{"text":" are ","type":"text"},{"text":"line-numbered by default","type":"text","marks":[{"type":"strong"}]},{"text":" and always print the document's ","type":"text"},{"text":"#docid","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"qmd://","type":"text","marks":[{"type":"code_inline"}]},{"text":" path. So ","type":"text"},{"text":"get","type":"text","marks":[{"type":"code_inline"}]},{"text":" output looks like:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"qmd://concepts/note.md #abc123\n---\n\n1: # Metrics as instruments\n2:\n3: Treat dashboards like cockpit instruments...","type":"text"}]},{"type":"paragraph","content":[{"text":"Cite the docid and exact line numbers in your answer, and use the numbers to ask for the next slice. Pass ","type":"text"},{"text":"--no-line-numbers","type":"text","marks":[{"type":"code_inline"}]},{"text":" only when you need raw content to copy verbatim (e.g. reproducing a code block).","type":"text"}]},{"type":"paragraph","content":[{"text":"When you need to open or edit the underlying file (e.g. hand a path to ","type":"text"},{"text":"Read","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"Edit","type":"text","marks":[{"type":"code_inline"}]},{"text":", or an editor), add ","type":"text"},{"text":"--full-path","type":"text","marks":[{"type":"code_inline"}]},{"text":". It replaces the ","type":"text"},{"text":"qmd://","type":"text","marks":[{"type":"code_inline"}]},{"text":" URL + docid header with the document's on-disk path, falling back to the canonical header if the file no longer exists on disk:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"text"},"content":[{"text":"$ qmd get \"#abc123\" --full-path\n/Users/you/notes/concepts/note.md\n---\n\n1: # Metrics as instruments","type":"text"}]},{"type":"paragraph","content":[{"text":"--full-path","type":"text","marks":[{"type":"code_inline"}]},{"text":" works the same way on ","type":"text"},{"text":"qmd search","type":"text","marks":[{"type":"code_inline"}]},{"text":" and ","type":"text"},{"text":"qmd query","type":"text","marks":[{"type":"code_inline"}]},{"text":": result paths become the file's on-disk path — ","type":"text"},{"text":"./","type":"text","marks":[{"type":"code_inline"}]},{"text":"-prefixed relative path when the file is inside ","type":"text"},{"text":"$PWD","type":"text","marks":[{"type":"code_inline"}]},{"text":", absolute realpath otherwise — and the per-result ","type":"text"},{"text":"#docid","type":"text","marks":[{"type":"code_inline"}]},{"text":" is dropped because the path is the identifier. The leading ","type":"text"},{"text":"./","type":"text","marks":[{"type":"code_inline"}]},{"text":" 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 ","type":"text"},{"text":"qmd://","type":"text","marks":[{"type":"code_inline"}]},{"text":" URIs; only opt into ","type":"text"},{"text":"--full-path","type":"text","marks":[{"type":"code_inline"}]},{"text":" when you specifically need a path you can hand to a non-QMD tool.","type":"text"}]},{"type":"heading","attrs":{"level":3},"content":[{"text":"Read line ranges with the ","type":"text"},{"text":":from:count","type":"text","marks":[{"type":"code_inline"}]},{"text":" suffix — never pipe through ","type":"text"},{"text":"sed","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"head","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"tail","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"qmd get","type":"text","marks":[{"type":"code_inline"}]},{"text":" slices files itself. Use the suffix or flags; do ","type":"text"},{"text":"not","type":"text","marks":[{"type":"strong"}]},{"text":" shell out to ","type":"text"},{"text":"sed -n","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"head","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"tail","type":"text","marks":[{"type":"code_inline"}]},{"text":", or ","type":"text"},{"text":"awk","type":"text","marks":[{"type":"code_inline"}]},{"text":" 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.","type":"text"}]},{"type":"paragraph","content":[{"text":"The most compact form is a ","type":"text"},{"text":":from:count","type":"text","marks":[{"type":"code_inline"}]},{"text":" suffix right on the path or docid — prefer it:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"qmd get \"#abc123:120:40\" # 40 lines starting at line 120\nqmd get qmd://concepts/note.md:200:60 # lines 200–259\nqmd get \"#abc123:120\" # from line 120 to end of file\nqmd get \"#abc123\" --from 120 -l 40 # equivalent, using flags","type":"text"}]},{"type":"paragraph","content":[{"text":"Suffix and flags:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\u003cpath>:\u003cfrom>:\u003ccount>","type":"text","marks":[{"type":"code_inline"}]},{"text":" — start at line ","type":"text"},{"text":"\u003cfrom>","type":"text","marks":[{"type":"code_inline"}]},{"text":", read ","type":"text"},{"text":"\u003ccount>","type":"text","marks":[{"type":"code_inline"}]},{"text":" lines. ","type":"text"},{"text":"Best for reading around a search hit.","type":"text","marks":[{"type":"strong"}]}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"\u003cpath>:\u003cfrom>","type":"text","marks":[{"type":"code_inline"}]},{"text":" — start at ","type":"text"},{"text":"\u003cfrom>","type":"text","marks":[{"type":"code_inline"}]},{"text":", read to end of file.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--from \u003cline>","type":"text","marks":[{"type":"code_inline"}]},{"text":" / ","type":"text"},{"text":"-l \u003clines>","type":"text","marks":[{"type":"code_inline"}]},{"text":" — flag equivalents. Explicit flags override the suffix, so ","type":"text"},{"text":"... :5:2 -l 1","type":"text","marks":[{"type":"code_inline"}]},{"text":" reads 1 line.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"--no-line-numbers","type":"text","marks":[{"type":"code_inline"}]},{"text":" — drop the ","type":"text"},{"text":"N:","type":"text","marks":[{"type":"code_inline"}]},{"text":" prefixes (line numbers are on by default).","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Wrong: ","type":"text"},{"text":"qmd get \"#abc123\" | sed -n '120,160p'","type":"text","marks":[{"type":"code_inline"}]},{"text":" Right: ","type":"text"},{"text":"qmd get \"#abc123:120:40\"","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"Search results include a ","type":"text"},{"text":":line","type":"text","marks":[{"type":"code_inline"}]},{"text":" anchor on each hit — feed it straight into ","type":"text"},{"text":"qmd get path:line:\u003cn>","type":"text","marks":[{"type":"code_inline"}]},{"text":" to read a window around the match (line numbers in the output will start at ","type":"text"},{"text":"line","type":"text","marks":[{"type":"code_inline"}]},{"text":").","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Discover what is indexed","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"qmd collection list\nqmd ls\nqmd status","type":"text"}]},{"type":"paragraph","content":[{"text":"Add collection filters when broad searches drift into the wrong corpus:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"qmd search \"headcount autonomous agents\" -c concepts -n 10\nqmd query \"merchant support product reality\" -c concepts -c sources -n 10","type":"text"}]},{"type":"paragraph","content":[{"text":"Omit ","type":"text"},{"text":"-c","type":"text","marks":[{"type":"code_inline"}]},{"text":" to search everything.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"MCP Tool: ","type":"text"},{"text":"query","type":"text","marks":[{"type":"code_inline"}]}]},{"type":"paragraph","content":[{"text":"When using the MCP server, prefer structured searches:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"json"},"content":[{"text":"{\n \"searches\": [\n { \"type\": \"lex\", \"query\": \"cockpit OKR Goodhart\" },\n { \"type\": \"vec\", \"query\": \"data informed not metric driven product judgment\" },\n { \"type\": \"hyde\", \"query\": \"A concept note explains that metrics are useful as instruments, but leaders should not let OKRs or dashboards replace judgment.\" }\n ],\n \"intent\": \"Find the concept note about using metrics as instruments without becoming metric-driven.\",\n \"collections\": [\"concepts\"],\n \"limit\": 10\n}","type":"text"}]},{"type":"paragraph","content":[{"text":"Query types:","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"lex","type":"text","marks":[{"type":"code_inline"}]},{"text":" — BM25 keyword search. Best for exact terms, names, titles, and code.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"vec","type":"text","marks":[{"type":"code_inline"}]},{"text":" — vector semantic search. Best for natural-language concepts.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"hyde","type":"text","marks":[{"type":"code_inline"}]},{"text":" — vector search using a hypothetical answer/document passage.","type":"text"}]}]}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Query craft","type":"text"}]},{"type":"paragraph","content":[{"text":"Good QMD searches mix three things:","type":"text"}]},{"type":"ordered_list","attrs":{"order":1,"listStyle":"number"},"content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Title/alias anchors:","type":"text","marks":[{"type":"strong"}]},{"text":" exact page titles, named entities, phrases.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Semantic paraphrase:","type":"text","marks":[{"type":"strong"}]},{"text":" how a human would describe the idea.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Negative space:","type":"text","marks":[{"type":"strong"}]},{"text":" enough intent to avoid nearby-but-wrong concepts.","type":"text"}]}]}]},{"type":"paragraph","content":[{"text":"Examples:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"# Exact-ish title lookup\nqmd search '\"arm the rebels\" merchants tools big companies' -c concepts\n\n# Semantic concept lookup\nqmd query

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 or . 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: Default to structured with , , , and fields that you write yourself. You are a better…

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'\n\n# Source lookup\nqmd search \"six-week cadence WhatsApp merchant relationships Shawn Ryan\" -c sources -n 10","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Setup and maintenance","type":"text"}]},{"type":"paragraph","content":[{"text":"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.","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"npm install -g @tobilu/qmd\nqmd collection add ~/notes --name notes\nqmd update\nqmd embed","type":"text"}]},{"type":"paragraph","content":[{"text":"Health and diagnostics:","type":"text"}]},{"type":"code_block","attrs":{"wrap":false,"language":"bash"},"content":[{"text":"qmd doctor\nqmd status\nqmd pull","type":"text"}]},{"type":"paragraph","content":[{"text":"qmd doctor","type":"text","marks":[{"type":"code_inline"}]},{"text":" checks config, model cache, device/GPU setup, vector fingerprints, and common environment overrides. If a model-backed command fails, run it before changing configuration.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"MCP setup","type":"text"}]},{"type":"paragraph","content":[{"text":"See ","type":"text"},{"text":"references/mcp-setup.md","type":"text","marks":[{"type":"code_inline"}]},{"text":" for Claude Code, Claude Desktop, OpenClaw, and HTTP server configuration.","type":"text"}]},{"type":"heading","attrs":{"level":2},"content":[{"text":"Pitfalls","type":"text"}]},{"type":"bullet_list","content":[{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do not stop at snippets.","type":"text","marks":[{"type":"strong"}]},{"text":" Fetch documents before making claims.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do not slice files with ","type":"text","marks":[{"type":"strong"}]},{"text":"sed","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":"/","type":"text","marks":[{"type":"strong"}]},{"text":"head","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":"/","type":"text","marks":[{"type":"strong"}]},{"text":"tail","type":"text","marks":[{"type":"code_inline"},{"type":"strong"}]},{"text":".","type":"text","marks":[{"type":"strong"}]},{"text":" Use the ","type":"text"},{"text":"path:from:count","type":"text","marks":[{"type":"code_inline"}]},{"text":" suffix (e.g. ","type":"text"},{"text":"qmd get \"#abc123:120:40\"","type":"text","marks":[{"type":"code_inline"}]},{"text":") or ","type":"text"},{"text":"--from","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"-l","type":"text","marks":[{"type":"code_inline"}]},{"text":". Output is already line-numbered; piping breaks docid resolution, the header, and virtual paths.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do not lean on query expansion.","type":"text","marks":[{"type":"strong"}]},{"text":" Write ","type":"text"},{"text":"intent:","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"lex:","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"vec:","type":"text","marks":[{"type":"code_inline"}]},{"text":"/","type":"text"},{"text":"hyde:","type":"text","marks":[{"type":"code_inline"}]},{"text":" yourself. A bare ","type":"text"},{"text":"qmd query \"user sentence\"","type":"text","marks":[{"type":"code_inline"}]},{"text":" discards the context only you have. You expand the query; the model just ranks.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do not overuse semantic search.","type":"text","marks":[{"type":"strong"}]},{"text":" If you know exact titles or terms, BM25 is faster and often better.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Do not mutate indexes casually.","type":"text","marks":[{"type":"strong"}]},{"text":" ","type":"text"},{"text":"qmd collection add","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"qmd update","type":"text","marks":[{"type":"code_inline"}]},{"text":", and ","type":"text"},{"text":"qmd embed","type":"text","marks":[{"type":"code_inline"}]},{"text":" change local state and can be expensive.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Model-backed commands can be environment-sensitive.","type":"text","marks":[{"type":"strong"}]},{"text":" If ","type":"text"},{"text":"qmd query","type":"text","marks":[{"type":"code_inline"}]},{"text":", ","type":"text"},{"text":"qmd vsearch","type":"text","marks":[{"type":"code_inline"}]},{"text":", or reranking fails because local models/GPU are unavailable, use ","type":"text"},{"text":"qmd search","type":"text","marks":[{"type":"code_inline"}]},{"text":" and stronger lexical/structured terms.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Ambiguous user wording needs intent.","type":"text","marks":[{"type":"strong"}]},{"text":" Add ","type":"text"},{"text":"intent:","type":"text","marks":[{"type":"code_inline"}]},{"text":" rather than hoping query expansion guesses the right domain.","type":"text"}]}]},{"type":"list_item","content":[{"type":"paragraph","content":[{"text":"Collection names matter.","type":"text","marks":[{"type":"strong"}]},{"text":" Search ","type":"text"},{"text":"concepts","type":"text","marks":[{"type":"code_inline"}]},{"text":" for synthesized wiki pages, ","type":"text"},{"text":"sources","type":"text","marks":[{"type":"code_inline"}]},{"text":" for transcripts/raw source pages, and docs collections for code or project documentation.","type":"text"}]}]}]},{"type":"hr","attrs":{"markup":"---"}}]},"metadata":{"date":"2026-06-05","name":"qmd","author":"@skillopedia","source":{"stars":25933,"repo_name":"qmd","origin_url":"https://github.com/tobi/qmd/blob/HEAD/skills/qmd/SKILL.md","repo_owner":"tobi","body_sha256":"6574c43d897df3b6b6de2b0b727e3c39d8b729723c6f5a43b9685cf2611c2264","cluster_key":"43ab84511eb3415b2eaf4d5b95b04240e56f72e67088ab5ef975188153e9e57c","clean_bundle":{"format":"clean-skill-bundle-v1","source":"tobi/qmd/skills/qmd/SKILL.md","attachments":[{"id":"e5d40718-4e32-5284-8dee-64dc0bc78bf4","key":"uploads/10433ee7-ad12-4ae0-b34e-97553e46c6c8/e5d40718-4e32-5284-8dee-64dc0bc78bf4/attachment.md","path":"references/mcp-setup.md","size":1994,"sha256":"23919878a63b983f5da086276f4923389929565d476e58418e10aa907ee7a3a6","contentType":"text/markdown; charset=utf-8"}],"bundle_sha256":"8ec3be08337ef5bd47f94cb84382b175278640edf13027868aae0829ed5fbb16","attachment_count":1,"text_attachments":1,"attachment_storage":"skillopedia-attachments-v1","binary_attachments":0,"excluded_attachments":[]},"cluster_size":1,"skill_md_path":"skills/qmd/SKILL.md","import_metadata":{"date":"2026-06-05","author":"@skillopedia","version":"v1","category":"documents-office","category_label":"Documents"},"exact_dupes_collapsed_into_this":0},"license":"MIT","version":"v1","category":"documents-office","metadata":{"author":"tobi","version":"2.2.0"},"import_tag":"clean-skills-v1","description":"Search local markdown knowledge bases, notes, docs, and wikis with QMD. Use when users ask to find notes, retrieve documents, inspect a wiki, answer from indexed markdown, or set up QMD access.","allowed-tools":"Bash(qmd:*), mcp__qmd__*","compatibility":"Requires qmd CLI or MCP server. Install via `npm install -g @tobilu/qmd`."}},"renderedAt":1782981745843}

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 or . 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: Default to structured with , , , and fields that you write yourself. You are a better…