skill-doctor
NewAudit your INSTALLED Claude Code skill library for waste. Measures the per-turn token tax of every skill's always-on description, mines transcripts to find skills that never fire, detects trigger collisions between skills, flags stale model references, and emits the exact disable-model-invocation edits to cut the tax. Use when Claude Code feels bloated or slow, when you've installed many skills/plugins, to reduce context cost, prune unused skills, find duplicate or conflicting skills, or audit your ~/.claude/skills library.
Summary
skill-doctor audits your installed Claude Code skill library to identify waste, such as skills that never fire, trigger collisions, stale model references, and the per-turn token tax from always-on descriptions.
- It produces concrete, reversible edits to disable bloated skills and reduce context cost, helping you keep Claude Code fast and lean.
Overview
skill-doctor
Every auto-invocable skill injects its name + description into every single request, whether it ever fires or not. With a large library that is a constant, invisible token tax. Claude Code surfaces this only per-plugin (/plugin) and never flags trigger collisions — so standalone skills are a blind spot. skill-doctor closes it: measure the tax, find dead weight, find collisions, and produce concrete, reversible fixes.
All logic is in scripts/ (Python stdlib only — no dependencies). The scripts emit deterministic JSON facts; the one judgment call (confirming collisions) is yours, made from the shortlist.
When to use
- •"audit my skills", "why is my context so big", "prune unused skills"
- •after installing a skill pack / many plugins
- •to find duplicate or conflicting skills
Workflow
Path setup (required). Skills run from the user's working directory, not from the skill folder — so invoke the scripts by their absolute path. Set SKILL_DIR to this skill's base directory (the harness states it as "Base directory for this skill: <path>" when the skill loads; otherwise it's the directory you read this SKILL.md from, e.g. ~/.claude/skills/skill-doctor). The --out-dir is relative to the user's cwd, which is what you want.
SKILL_DIR="<absolute dir of this SKILL.md>"
python "$SKILL_DIR/scripts/run.py" --live --out-dir ./skill-doctor-out--live pulls the authoritative loaded set + exact injected payload from the most recent transcript. Outputs: scan.json, usage.json, collide.json, report.md, actions.json. A one-line SUMMARY prints to stdout.
Then:
- Read `report.md` and present the headline (tokens/turn), the disable
candidates with projected savings, the collision shortlist, and staleness.
- Judge collisions. Open
collide.json. For each candidate pair, read both
full descriptions and decide if they would genuinely both auto-trigger on the same request. Keep only the real ones; recommend merging or sharpening the loser's description.
- Propose fixes, then on the user's OK apply them (reversible):
# dry-run first (default), then --write
python "$SKILL_DIR/scripts/apply.py" --from-actions ./skill-doctor-out/actions.json --write
# undo anything:
python "$SKILL_DIR/scripts/apply.py" --names skill-a,skill-b --revert --writeapply.py only edits user/project SKILL.md frontmatter (never plugin/bundled skills), writes a .bak, and is fully reversible.
Optionally also flag unused MCP servers:
python "$SKILL_DIR/scripts/mcpusage.py"Individual tools
All invoked as python "$SKILL_DIR/scripts/<tool>.py" --help:
- •
scan.py— inventory + per-skill cost + staleness (--live/--listing FILE/--exact) - •
usage.py— per-skill firing history from transcripts (--days N) - •
collide.py— trigger-collision shortlist (--threshold, overlap-coefficient) - •
compress.py— flag verbose descriptions to slim (keep the skill, cut its cost) - •
report.py— merge intoreport.md+actions.json(--ignore a,bto allowlist skills) - •
apply.py— apply/revertdisable-model-invocation(guarded) - •
mcpusage.py— flag configured-but-never-used MCP servers (~/.claude.json+ transcripts) - •
context.py— unified always-on context budget (skills + CLAUDE.md + rules), ranked - •
monitor.py— record per-session skill usage durably (--latestfrom a SessionEnd hook;--summary) - •
lint.py— score a candidate skill before adding it (--path SKILL.md: cost, collision risk, routing) - •
evalgate.py— generate trigger probes (--name/--path) to confirm a change didn't break routing
The report also flags budget (over Claude Code's skillListingBudgetFraction, descriptions get silently dropped) and lists compress candidates — skills to keep but whose descriptions are verbose. To compress one: draft a shorter routing-correct description (keep the trigger words/phrases that make Claude auto-invoke it; cut prose/examples), then apply it with the verify gate — it refuses the change unless the new text is shorter and still contains those trigger words:
python "$SKILL_DIR/scripts/apply.py" --set-description pandas-pro \
--text "Pandas DataFrame ops: cleaning, aggregation, merging, time series." \
--must-contain "pandas,dataframe" --write
# revert like any change:
python "$SKILL_DIR/scripts/apply.py" --names pandas-pro --revert --writeNotes
- •Token figures are offline estimates (~4 chars/token); **percentages are
tokenizer-independent**. For exact absolute counts, set ANTHROPIC_API_KEY and add --exact (uses the count_tokens API; falls back to the estimate if no key).
- •The report states a confidence line — how many days of transcript history
back the "never fired" calls. More history = stronger recommendation.
- •paths-scoped skills (frontmatter
paths:) load only for matching files, so
they are excluded from the always-on tax and never proposed for disabling.
- •Likely duplicates (near-identical descriptions) are reported separately from
trigger collisions — one of a duplicate pair is usually removable.
- •
--grace-days N(default 0/off) excludes never-fired skills modified within N
days. Off by default because file mtime is unreliable on synced machines.
- •Disabling a skill (
disable-model-invocation: true) only stops automatic
invocation — you can still run it manually with /name.
- •The verified mechanics this skill relies on are documented in
references/mechanics.md.
Install & Usage
mkdir -p .claude/skillsmkdir -p .claude/skills && curl -o .claude/skills/skill-doctor.md https://raw.githubusercontent.com/ssamba1/skill-doctor/main/SKILL.md/skill-doctorUse Cases
Usage Examples
/skill-doctor audit my skills and show me the token tax for each one
Run skill-doctor with --live to find skills that never fire in my recent conversations
Check for trigger collisions between my installed skills and suggest fixes
Security Audits
Frequently Asked Questions
What is skill-doctor?
skill-doctor audits your installed Claude Code skill library to identify waste, such as skills that never fire, trigger collisions, stale model references, and the per-turn token tax from always-on descriptions. It produces concrete, reversible edits to disable bloated skills and reduce context cost, helping you keep Claude Code fast and lean.
How to install skill-doctor?
To install skill-doctor: create the skills directory (mkdir -p .claude/skills), then run: mkdir -p .claude/skills && curl -o .claude/skills/skill-doctor.md https://raw.githubusercontent.com/ssamba1/skill-doctor/main/SKILL.md. Finally, /skill-doctor in Claude Code.
What is skill-doctor best for?
skill-doctor is a skill categorized under General. It is designed for: plugin. Created by ssamba1.
What can I use skill-doctor for?
skill-doctor is useful for: Audit your entire skill library to measure the per-turn token tax from always-on skill descriptions.; Identify skills that never fire by mining conversation transcripts for their triggers.; Detect trigger collisions between two or more skills that could cause unintended behavior.; Flag skills referencing deprecated or nonexistent Claude models.; Generate exact disable-model-invocation edits to prune unused or conflicting skills.; Reduce context cost and improve Claude Code responsiveness after installing many skills or plugins..