skill-tools CLI

CLI tool and library for validating, linting, and quality-scoring Agent Skills per the Agent Skills specification. The ESLint/Lighthouse equivalent for agent skills.

npm install -g skill-tools

Commands

skill-tools validate <path>

Checks SKILL.md files against the specification. Reports errors and warnings.

skill-tools validate ./my-skill/
skill-tools validate ./skills/ --format json

skill-tools lint <path>

Runs quality lint rules beyond basic spec compliance.

skill-tools lint ./my-skill/
skill-tools lint ./my-skill/ --fail-on warning

skill-tools score <path>

Computes a quality score (0-100) with dimension breakdowns and improvement suggestions.

skill-tools score ./my-skill/
skill-tools score ./my-skill/ --min-score 60

skill-tools check <path>

Runs validate + lint + score in one pass. Ideal for CI/CD.

skill-tools init <name>

Scaffold a new skill directory with a SKILL.md template.

skill-tools init my-skill
skill-tools init my-skill --with-scripts --with-references

skill-tools to-prompt <path>

Generate <available_skills> XML for system prompt context injection.

skill-tools to-prompt ./skills/
skill-tools to-prompt ./skills/ --format json --include-location

Lint Rules

All rules are deterministic pattern matching. No LLMs involved. Severity can be overridden via .skill-toolsrc.yml.

Rule Default What it catches
no-secrets error 11 token patterns: sk-* (OpenAI), sk_live_* / sk_test_* (Stripe), ghp_* / gho_* / github_pat_* (GitHub), xoxb-* / xoxp-* (Slack), AKIA* (AWS), -----BEGIN PRIVATE KEY-----, JWT patterns
no-hardcoded-paths error /Users/..., /home/..., C:\Users\..., /var/, /tmp/...
description-specificity warn Generic verbs in description: manage, handle, process, deal with, work with, do stuff, help with, assist with, take care of
description-length-optimal info Description outside 50–300 char sweet spot. Too short wastes routing accuracy; too long wastes metadata tier budget
description-trigger-keywords warn Needs a trigger phrase (use when, use for, invoke when, trigger when) OR an action verb (deploy, test, build, run, create, generate, analyze, review, format, lint, fix, check, commit, push, pull, fetch, install, configure, setup, search, find, list, delete, update, migrate, convert, export, import)
progressive-disclosure warn >500 lines without references/ or scripts/ file references
instructions-has-examples info No code blocks (```), inline code (`..`), or numbered steps (1. ...)
instructions-has-error-handling info No error handling heading or keywords (error, fail, troubleshoot, "if X fails", "common issues")
consistent-headings info Heading levels that skip (e.g. H1 directly to H4)

Score Dimensions

Scores are computed by deterministic code. No LLMs involved. Total: 100 points.

Dimension Max Breakdown
Description Quality 30 Length 50-300 chars (8) · Action verbs ≥2 (8) · Trigger phrase (8) · Name uniqueness <50% overlap (6)
Instruction Clarity 25 Code blocks ≥2 (7) · Numbered steps ≥3 (6) · Error handling section (6) · Body ≥100 words (6)
Spec Compliance 20 Has name (5) · Has description (5) · ≤5,000 tokens (5) · ≤500 lines (5)
Progressive Disclosure 15 ≤100 lines = 15 auto-pass · 100-500 with refs = 15 · >500 with refs = 10 · >500 without = 2
Security 10 Starts at 10. Secrets = 0 · Hardcoded paths −3 · rm -rf / −2 · curl|bash −2 · eval $ −2

Library API

import { validate, lint, score } from 'skill-tools';

const results = await validate('./my-skill/');
const lintResult = lint(parsedSkill);
const qualityScore = score(parsedSkill);

GitHub Action

Use the skill-tools GitHub Action to validate skills in CI. Runs skill-tools check with configurable thresholds.

Basic usage

- uses: skill-tools/skill-tools/action@main
  with:
    path: ./skills/
    min-score: 60

All inputs

Input Default Description
path . Path to skill directory or SKILL.md file
min-score 0 Minimum quality score (0–100). Fails if any skill scores below
fail-on error Minimum severity to fail on: error, warning, or info
format text Output format: text or json
node-version 18 Node.js version to use

CI workflow example

Gate pull requests on skill quality:

name: Skill Quality
on: [pull_request]
jobs:
  check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: skill-tools/skill-tools/action@main
        with:
          path: ./skills/
          min-score: 60
          fail-on: warning

Multiple directories

Check skills across your repo by running the action in a matrix:

strategy:
  matrix:
    skill-path: [./skills/deploy, ./skills/test, ./skills/lint]
steps:
  - uses: actions/checkout@v4
  - uses: skill-tools/skill-tools/action@main
    with:
      path: ${{ matrix.skill-path }}
      min-score: 50

JSON output for downstream tools

Parse the output with jq or downstream actions:

- uses: skill-tools/skill-tools/action@main
  with:
    path: ./skills/
    format: json

Test Coverage

14 tests across 3 suites. Run with npx vitest run from the package directory.

linter.test.ts (5 tests)

scorer.test.ts (5 tests)

validator.test.ts (4 tests)