The linter for Agent Skills.
npx skillcheck checks your SKILL.md files for the things that decide whether a
skill actually works: valid format, a description the model will trigger on,
and collisions between skills that confuse the model. Like ESLint — but for the
skills you hand to Claude Code, Cursor, Codex & friends.
npx skillcheckRun it in a repo, or point it at a skills folder.
The agent ecosystem has plenty of security scanners for skills (Snyk, Cisco, Sentry, Invariant…). They answer "is this skill malicious?"
Almost nothing answers the question you actually hit every day:
"Will my skill even fire when it's supposed to — and not collide with my others?"
A skill lives or dies by its description. That single line is what the model reads
to decide whether to use the skill at all. Write it vaguely and the skill silently
never triggers. Write two skills with overlapping descriptions and the model can't
tell them apart. There's no compiler error for this — your skill just quietly does
nothing, and you don't know why.
skillcheck is the linter that catches it.
1. Format — validates the SKILL.md frontmatter against the open format:
required name and description, correct name casing, sane lengths, unknown keys,
empty body.
2. Triggering quality (the part nobody else does) — scores whether the description will actually make the model fire the skill:
- no explicit "when to use" cue → the model has nothing to match a request against
- vague filler openers (
"A skill for data","Helps you with…") that carry no signal - too short / too long / too few distinctive words to disambiguate
3. Collisions — compares every pair of skills and warns when two descriptions overlap so much the model will struggle to choose between them.
Each skill gets a score out of 100 and concrete, actionable fixes.
$ npx skillcheck ./skills
skillcheck · linter for Agent Skills
data-tool skills/data-tool/SKILL.md score 24
✖ description is 17 chars — far too short to trigger reliably [description/too-short]
→ Describe WHAT it does and WHEN to use it, with concrete trigger words.
⚠ description never says WHEN to use the skill — the model has nothing to match against [trigger/no-when]
→ Add an explicit cue, e.g. "Use when the user asks to …"
⚠ description opens with vague filler that carries no trigger signal [trigger/generic-opener]
git-commit skills/git-commit/SKILL.md score 88
⚠ description overlaps 83% with "commit-helper" — the model may struggle to pick between them [collision/overlap]
→ Make each description name what is UNIQUE to that skill.
pdf-form-filler skills/pdf-form-filler/SKILL.md score 100
✓ clean
Summary: 3 skills · 1 error · 2 warnings · avg score 71/100npx skillcheck # scan ./ for any SKILL.md files
npx skillcheck ./skills # scan a folder
npx skillcheck path/to/SKILL.md
npx skillcheck --json # machine-readable output
npx skillcheck --strict # treat warnings as failures tooExit codes make it a drop-in CI gate: 0 when clean, 1 when there are errors
(or any warnings under --strict). Add it to your pipeline so a badly-written skill
never ships:
# .github/workflows/skills.yml
- run: npx skillcheck ./skills --strictAnything that uses the open SKILL.md format — Claude Code, Cursor, Codex, Gemini
CLI, and the skills generated by agentprep.
skillcheck is a heuristic linter, not an oracle. It reasons about your
description and structure with rules — it does not call a model, so:
- A high score means well-formed and well-targeted, not guaranteed to trigger. Real triggering depends on the model and the surrounding skill set.
- Collision detection is keyword-overlap based; it catches the obvious clashes, not every semantic near-duplicate.
- It checks quality, not security — for tool-poisoning / prompt-injection scanning, use a dedicated security scanner alongside it.
These are exactly where contributions help most.
Got a description that scored wrong, or a triggering rule you want added? Open an
issue with the SKILL.md and what you expected. Rules are small and isolated.
