qmd
Skill1 starsChanged 40 days agoMITView on GitHub
Set up local markdown search with qmd as one global index that every Claude Code profile and project on the machine shares. Adds the folders the user picks, then wires the active profile with the qmd MCP server, an edit hook, a scheduled refresh, and CLAUDE.md search guidance. Use for /keel:qmd, "set up qmd", or "search my notes/vault across projects".
- Installs packages
23 other projects use a version of this.
Adopted by
Most recently taken up by
- droxey/skillstheir own version, first seen Nov 8, 2026
- Liang-MH/skillstheir own version, first seen Nov 8, 2026
- compozy/compozytheir own version, first seen Nov 7, 2026
- pankaj-mahaur/Agent-Daemontheir own version, first seen Nov 6, 2026
- gabrielkoerich/skillstheir own version, first seen Nov 1, 2026
- iagocavalcante/claude-turbo-searchtheir own version, first seen Oct 27, 2026
Used with
Projects with it also use defuddle, obsidian-bases and 6 more.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
HK-hubSkilldefuddle
Extract clean markdown content from web pages using Defuddle CLI, removing clutter and navigation to save tokens. Use instead of WebFetch when the user provides a URL to read or analyze, for online documentation, articles, blog posts, or any standard web page.
Also in 4 projects that use this
wangzhuofengSkillobsidian-bases
Create and edit Obsidian Bases (.base files) with views, filters, formulas, and summaries. Use when working with .base files, creating database-like views of notes, or when the user mentions Bases, table views, card views, filters, or formulas in Obsidian.
Also in 4 projects that use this
jykimSkillobsidian-cli
Interact with Obsidian using the official CLI to read, search, create, and manage notes, daily notes, tasks, properties, and more. Use when the user wants to query or manipulate vault content via the obsidian command.
Also in 4 projects that use this
wangzhuofengSkilljson-canvas
Create and edit JSON Canvas files (.canvas) with nodes, edges, groups, and connections. Use when working with .canvas files, creating visual canvases, mind maps, flowcharts, or when the user mentions Canvas files in Obsidian.
Also in 3 projects that use this
VercelSkillagent-browser
Automates browser interactions for web testing, form filling, screenshots, and data extraction. Use when the user needs to navigate websites, interact with web pages, fill forms, take screenshots, test web applications, or extract information from web pages.
Also in 4 projects that use this
VercelSkillvercel-react-best-practices
React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React/Next.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.
Also in 3 projects that use this
- +1 more from wangzhuofeng
Other versions23 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 23
- tobi/qmd★ 30ksame name
- breferrari/obsidian-mind★ 5.4ksame name
- compozy/compozy★ 2.9ksame name
- levineam/qmd-skill★ 703same name
- pedronauck/skills★ 649same name
- SAP/e-mobility-charging-stations-simulator★ 232same name
- benoror/obsidianos_work★ 166same name
- ckorhonen/claude-skills★ 17same name
- iagocavalcante/claude-turbo-search★ 16same name
- superuser-pal/awesome-second-brain★ 14same name
13 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository56 other files it gives its agents.
- architectSkill
- arenaSkill
- automate-meSkill
- benchmark-checklistSkill
- blast-radiusSkill
- broSkill
- correctSkill
- create-formal-verification-skillSkill
- create-verification-skillSkill
- figure-it-outSkill
- helpSkill
- howSkill
- interrogateSkill
- in-your-own-wordsSkill
- ketchupSkill
- ketchup-videoSkill
- leadSkill
- maintain-formal-verification-skillSkill
- maintain-verification-skillSkill
- no-commentsSkill
- principle-attack-the-premiseSkill
- principle-boundary-disciplineSkill
- principle-build-the-leverSkill
- principle-encode-lessons-in-structureSkill
- principle-exhaust-the-design-spaceSkill
- principle-experience-firstSkill
- principle-explain-the-numberSkill
- principle-fix-root-causesSkill
- principle-foundational-thinkingSkill
- principle-guard-the-context-windowSkill
- principle-laziness-protocolSkill
- principle-make-operations-idempotentSkill
- principle-migrate-callers-then-delete-legacy-apisSkill
- principle-minimize-reader-loadSkill
- principle-model-the-domainSkill
- principle-never-block-on-the-humanSkill
- principle-outcome-oriented-executionSkill
- principle-prove-it-worksSkill
- principle-redesign-from-first-principlesSkill
- principle-separate-before-serializing-shared-stateSkill
- principle-sequence-verifiable-unitsSkill
- principle-subtract-before-you-addSkill
- principle-test-behavior-not-implementationSkill
- principle-type-system-disciplineSkill
- recallSkill
- reflectSkill
- setupSkill
- sharpenSkill
- show-me-your-workSkill
- swarmSkill
- tddSkill
- teachSkill
- technical-writingSkill
- typescript-best-practicesSkill
- unslopSkill
- whySkill
The file
We split this skill into the rules it gives an agent
10 rules. 0 are common, 0 are distinctive, and 10 are very specific to this project.
0
Common
Most of the 22 edited versions we read keep these.
0
Distinctive
This author's own choices. Worth a look.
10
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 17
Run the script with --dry-run and no other flags.
- Very specific: line 20
Run <qmd> collection list with the absolute path the script printed, so the user sees what the index already holds.
- Very specific: line 27
Ask whether to index this profile's Claude Code auto-memory too (--memory).
- Very specific: line 32
Run with --dry-run and the chosen flags, then read the output.
- Very specific: line 76
Run these for each profile you wired, with P="${CLAUDE_CONFIG_DIR:-$HOME/.claude}".
- Very specific: line 78
Run claude mcp remove -s user qmd.
- Very specific: line 79
Delete the PostToolUse entry whose command runs on-edit-hook.sh from $P/settings.json.
- Very specific: line 80
Delete the block between the keel:qmd markers in $P/CLAUDE.md.
- Very specific: line 81
Delete the backups setup left next to those files: $P/settings.json.qmd-backup-*, $P/CLAUDE.md.qmd-backup-*, and, when the script merged …
- Very specific: line 86
Delete reconcile.sh, on-edit-hook.sh, and any *.qmd-backup-* files from ${XDG_CONFIG_HOME:-$HOME/.config}/qmd/, and the log folder, …
“Common” is measured: kept by at least 6 in 10 of the 22 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
qmd
Set up qmd so agents in every profile and project can search the user's markdown through one index. qmd keeps that index at its default locations, ${XDG_CONFIG_HOME:-$HOME/.config}/qmd/index.yml for the collection list and ~/.cache/qmd for the database and models. Nothing here sets QMD_CONFIG_DIR or makes a per-profile index.
scripts/setup-qmd.sh makes every change and is safe to re-run. Your job is to choose its inputs with the user, run it, check the result, and report. Call it as bash "${CLAUDE_SKILL_DIR}/scripts/setup-qmd.sh".
Steps
1. Detect
- Run the script with
--dry-runand no other flags. It finds qmd onPATH, then at~/.bun/bin/qmd, then under$(npm prefix -g)/bin. - Exit code 3 means qmd is missing. Ask the user before you install it. Offer
bun install -g @tobilu/qmdwhencommand -v bunsucceeds, elsenpm install -g @tobilu/qmd. Install only on a yes, then run step 1 again. - Tell the user which profile the run wires, from
echo "${CLAUDE_CONFIG_DIR:-$HOME/.claude}". Each profile needs its own run. The index is shared, so a second profile's run needs no--root. - Run
<qmd> collection listwith the absolute path the script printed, so the user sees what the index already holds. If it fails withnode: not foundorbun: not found, the runtime qmd was installed with is not onPATH. Fix that before you go on. - Look for an earlier qmd setup. List
~/Library/LaunchAgents/*qmd*on macOS orcrontab -l | grep qmdelsewhere, and grep the profile'ssettings.jsonforqmdandon-edit-hook. The dry run also warns about another LaunchAgent that mentions qmd, and keeps a hook that already runson-edit-hook.shinstead of adding a second one. If you find a scheduler or hook this script did not make, ask the user whether to remove it or keep it before the real run.
2. Pick what to index
- Run the script with
--discover. It counts*.mdunder each folder in$HOMEand one level below. It skipsnode_modules,.git,dist,build,vendor, and dot folders, and at the top level alsoLibrary,Applications,Movies,Music, andPictures. Folders it cannot read are left out of the counts. - Suggest roots from that list and ask with AskUserQuestion,
multiSelect: true, at most four options. Prefer one collection per root folder, such as a code folder with one subfolder per project, so a new project under it gets indexed without a re-run. The script skips a root that sits inside an existing collection. - Ask whether to index this profile's Claude Code auto-memory too (
--memory). It adds<profile>/projectswith the pattern*/memory/**/*.mdand ignores the-private-tmp-*and-tmp-*project folders that scratch sessions leave. - Offer a one-line description per root. qmd shows it to agents next to search results.
3. Run
Run with --dry-run and the chosen flags, then read the output. If it would change anything the user did not choose, stop and ask. Otherwise run the same command without --dry-run.
| Flag | Effect |
--root PATH[:NAME] | Add a collection of every *.md under PATH. NAME defaults to the folder name, lowercased, with each character outside a-z0-9_- turned into -. A PATH that is itself a folder is never split at a colon. Repeat per root. |
--context NAME:TEXT | Attach a description to collection NAME. Repeat per collection. Pass an explicit PATH:NAME on the matching --root, so the two names agree. |
--memory | Add this profile's auto-memory folders as <profile-dir-name>-memory. When another folder already holds that name, as with a second profile also named .claude, it uses <parent-dir-name>-<profile-dir-name>-memory. When both names are taken it warns and adds nothing. |
--no-schedule | Skip the scheduled refresh. QMD_SCHEDULE=0 does the same. |
--dry-run | Print what would change and write nothing. |
--discover | List folders under $HOME by markdown file count, then exit. |
QMD_LAUNCHD_LABEL overrides the LaunchAgent label, local.qmd.reconcile by default.
4. Verify
<qmd> collection listshows each chosen root, or the script printed why it skipped one.claude mcp get qmdfinds the server. Without theclaudeCLI, check thatmcpServers.qmdexists in the.claude.jsonpath the script printed.- The profile's
settings.jsonhas aPostToolUseentry whose command runson-edit-hook.sh, as the script'sPostToolUse hookline reported. tail -n 5on the log path the script printed shows astart (...)line. It may come from an earlier run whose embed is still going, since a run that finds another one holding the lock only leaves areconcile.rerunfile in the log folder and logs nothing. Either astartline without a laterdone, or that file, passes this check.<qmd> statusshows documents waiting for embeddings, and its Device section shows whether qmd found a GPU.
5. Report
Tell the user what each collection holds, which profile you wired, and that Claude Code needs a restart to load the MCP server and hook. Give the two commands the script printed for watching progress. On a CPU-only machine the first embed can take hours for about 1000 documents. Searches work before it ends, and lexical results come first.
What the script writes
| What | Where |
| Collections | index.yml, through qmd collection add and qmd context add only. collection add builds the keyword index for that root before it returns, which takes a while on a big root. It skips a name that exists and a path inside an existing collection. The one direct edit adds an ignore: list to the memory collection, since the CLI cannot set one. qmd keeps that list when it rewrites the file. |
reconcile.sh, on-edit-hook.sh | Next to index.yml. reconcile.sh runs qmd update then qmd embed at nice 15, one run at a time, with up to five passes while edits keep arriving. qmd's launcher runs under node or bun and launchd passes a bare PATH, so it puts qmd's own folder, the folders where setup found node and bun, ~/.bun/bin, /usr/local/bin, and /opt/homebrew/bin on PATH. It logs to ~/Library/Logs/qmd/reconcile.log on macOS, else ${XDG_STATE_HOME:-~/.local/state}/qmd/reconcile.log. The hook starts it in the background when a Write or Edit touches a .md file inside a collection, and returns at once. |
MCP server qmd | User scope, through claude mcp add -s user qmd -- <qmd> mcp. Claude Code keeps it in $CLAUDE_CONFIG_DIR/.claude.json when that variable is set, else ~/.claude.json. Without the claude CLI the script merges the entry into that file itself. |
| PostToolUse hook | <profile>/settings.json, matcher Write|Edit, timeout 10. |
| Search guidance | <profile>/CLAUDE.md, between <!-- keel:qmd start --> and <!-- keel:qmd end -->. A re-run replaces the block in place. |
| Scheduled refresh | macOS gets ~/Library/LaunchAgents/<label>.plist, every 1800 s, RunAtLoad, Nice 15, LowPriorityIO. The script loads it with launchctl bootstrap when launchctl print gui/$UID/<label> fails. When the agent is loaded and the plist content changed, it unloads it with launchctl bootout and loads it again. Other systems get a cron line to add by hand. |
The first reconcile.sh run starts in the background, from the LaunchAgent or from the script, so setup never waits for embeddings.
Before it rewrites settings.json, CLAUDE.md, .claude.json, index.yml, reconcile.sh, or on-edit-hook.sh, the script copies the old file next to it as <file>.qmd-backup-<timestamp>. The plist's backup goes next to reconcile.sh, because launchd may load any file in LaunchAgents. A rewrite follows a symlink to its target and keeps the file's mode. A config file that is not valid JSON stops the run with an error that names it, and nothing in that file changes.
The CLAUDE.md block's rerank line follows the Device section of qmd status, which takes under a second. With GPU: none it tells agents to always pass rerank: false, because on a CPU-only Intel i7 a reranked query took over 240 s, while lex took about 3 s and vec about 7 s. With a GPU it leaves the line out. When status names neither, as under --dry-run, the line says to pass rerank: false when qmd status shows no GPU. A re-run on new hardware rewrites the line.
Undo
Run these for each profile you wired, with P="${CLAUDE_CONFIG_DIR:-$HOME/.claude}".
- Run
claude mcp remove -s user qmd. Without theclaudeCLI, deletemcpServers.qmdfrom$CLAUDE_CONFIG_DIR/.claude.jsonwhen that variable is set, else from~/.claude.json. - Delete the
PostToolUseentry whose command runson-edit-hook.shfrom$P/settings.json. - Delete the block between the
keel:qmdmarkers in$P/CLAUDE.md. - Delete the backups setup left next to those files:
$P/settings.json.qmd-backup-*,$P/CLAUDE.md.qmd-backup-*, and, when the script merged the MCP entry itself,.claude.json.qmd-backup-*next to the.claude.jsonpath it printed. When one of these files is a symlink, its backup sits next to the link's target.
Then once per machine:
- On macOS, run
launchctl bootout gui/$(id -u)/<label>and delete~/Library/LaunchAgents/<label>.plist. The label islocal.qmd.reconcileunlessQMD_LAUNCHD_LABELset another at setup. Elsewhere, remove the cron line. - Delete
reconcile.sh,on-edit-hook.sh, and any*.qmd-backup-*files from${XDG_CONFIG_HOME:-$HOME/.config}/qmd/, and the log folder,~/Library/Logs/qmdon macOS or${XDG_STATE_HOME:-$HOME/.local/state}/qmdelsewhere. - To drop the index too, run
qmd collection remove <name>for each collection, or deleteindex.ymland~/.cache/qmd, which also holds the downloaded models.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

