Agent Skill Linter
Checks agent skills for spec compliance and publishing readiness.
Expected Layout
A well-structured skill repo separates agent-facing files (installed by
) from repo artifacts:
my-skill/
├── skill/ ← only this dir is installed by npx
│ ├── SKILL.md
│ ├── references/
│ │ └── fix-templates.md
│ └── scripts/ ← skill-invoked scripts (optional)
│ └── main.py
├── src/ ← linter/library source (not installed)
├── tests/
├── README.md
├── LICENSE
├── pyproject.toml
└── .github/
└── workflows/
The
lint target is the
subdirectory (or repo root for older repos with no
dir).
Triage Workflow
Target: the skill directory to lint — current directory (
) or a path provided by the user.
Step 1 — Get the full picture
bash
./scripts/skill-lint.py check <target>
Review the output for errors and warnings; confirm the full picture before proceeding to Step 2.
Step 2 — Fix Errors first
Rule 1 (SKILL.md spec compliance) blocks publishing. Fix before anything else.
Step 3 — Auto-fix Warnings
bash
./scripts/skill-lint.py check <target> --fix
For fixable rules without CLI, use the templates in
references/fix-templates.md
.
Confirm no auto-fixable warnings remain before continuing to Step 4.
Step 4 — Resolve remaining Warnings manually
CSO description prefix (Rule 11), Python invocations (Rule 13), README-tier sections in SKILL.md (Rule 19) — see the rule table below.
Step 5 — Semantic review: CSO signal
Rule 11 catches structural patterns but not meaning. Read the
and
frontmatter and ask:
do they function purely as routing signals?
See
references/semantic-rules.md
— Rules 12 and 18 for examples.
Flag the description if it:
- Enumerates what the skill checks, handles, or supports
- Reads as a feature summary or workflow overview
- Contains elaboration labels (, , ) or multiple sentences
- Could be trimmed to one clause without losing routing precision
Flag the name if it reads as a noun phrase rather than an action — prefer gerunds (
,
) over noun forms (
,
). Short well-known names (
,
) are fine.
A good description names the trigger condition only. Everything else belongs in the skill body.
Confirm the description and name function as pure routing signals before moving to Step 6.
Step 6 — Semantic review: starter prompts
Rule 7 detects whether prompts exist, not whether they're useful. Read the Usage section starter prompts and ask: do they reflect genuine, distinct trigger scenarios?
Flag them if they:
- Are vague or generic (e.g. , )
- All describe the same scenario with minor wording variation
- Don't reflect the range of contexts a real user would encounter
Confirm starter prompts cover genuinely distinct use cases before proceeding to Step 7.
Step 7 — Semantic review: content overlap
The linter does not check this. Ask: is the same information conveyed in different words across SKILL.md and README?
See
references/semantic-rules.md
— Rule 8 for examples.
Flag paraphrased repetition. SKILL.md should be agent-focused (triage workflow, rules); README should be human-focused (installation, usage examples).
Confirm no paraphrased repetition remains before moving to Step 8.
Step 8 — Semantic review: progressive disclosure
Rule 15 flags known reference-tier keywords, but not all reactive content has a recognizable heading. Ask: would an agent look up this section reactively rather than read it upfront?
See
references/semantic-rules.md
— Rule 16 for examples.
Flag sections for
if they:
- Are reference material regardless of their heading name (e.g. "Background", "How It Works")
- Are dense or conditional — even if short and not caught by Rule 15
- Are step-specific detail blocks that bulk up the main workflow without being needed upfront
Confirm all reactive content has been moved to
before proceeding to Step 9.
Step 9 — Semantic review: multi-step workflow quality
Only apply this step when the skill has a multi-step workflow (3+
headings).
Read each step body and ask: does every substantive step state how the agent knows it is done?
See
references/semantic-rules.md
— Rule 22 for examples.
Flag a step if its body describes only what to do with no exit condition, no gate phrase, no "proceed only when" signal. Trivially short steps (a single line) need no explicit gate.
Also ask: does the workflow include at least one step that checks actual tool output, not just verbal claims?
See
references/semantic-rules.md
— Rule 23 for examples.
Flag the workflow if every step prescribes actions but none tells the agent to read what the tool actually returned.
Confirm both questions are satisfied before proceeding to Step 10.
Step 10 — Address Info items as polish
Body length (Rule 9), non-standard dirs (Rule 10), skill isolation (Rule 17).
What It Checks
| # | Rule | Severity | Auto-fix |
|---|
| 1 | SKILL.md spec compliance (via skills-ref) | Error | — |
| 2 | LICENSE exists, Apache-2.0 or MIT, current year | Warning | Partial |
| 3 | in SKILL.md frontmatter | Warning | Yes |
| 4 | README badges (CI, license, Agent Skills) | Warning | Yes |
| 5 | has CI workflow | Warning | Yes |
| 6 | README has Installation section | Warning | Yes |
| 7 | README has Usage section with starter prompts + CLI subsection | Warning | Partial + Step 6 |
| 9 | SKILL.md body < 500 lines | Info | — |
| 10 | Non-standard directories flagged | Info | — |
| 11 | CSO: description starts with "Use when..." | Warning | Step 5 |
| 13 | Python invocation consistency ( in uv projects) | Warning | — |
| 14 | Progressive disclosure: embedded templates (4-backtick fences) → | Warning | Yes |
| 15 | Progressive disclosure: reference-tier headings (Troubleshooting, FAQ, Advanced…) → | Warning | Yes + Step 8 |
| 17 | Skill isolation: SKILL.md at repo root alongside non-skill artifacts | Info | — |
| 19 | Division of labor: README-tier sections (Installation, Features, Getting Started…) in SKILL.md | Warning | — |
| 20 | Triage workflow has 3+ steps but no semantic review step (e.g. "Ask: does it…") | Info | Step 5–9 |
| 21 | Python entry-point scripts in lack PEP 723 inline dependency metadata | Warning | — |
CLI Reference
bash
./scripts/skill-lint.py check . # Lint repo-root skill
./scripts/skill-lint.py check ./my-skill --fix # Auto-fix fixable issues
./scripts/skill-lint.py check ./my-skill --format json # JSON output for CI
Exit code 1 on errors, 0 otherwise.