Skip to main content

manifestspec

Zero-dependency Python validator for agent skill SKILL.md frontmatter, section structure, and skill.yaml capability manifests — fixes all known skill-lint.js bugs.

Python 3.11+ License: MIT Tests: 128 passing

Parses and validates SKILL.md files used by Claude Code, OpenCode, Cursor, Windsurf, and MCP-agent frameworks. Fixes all four documented bugs in skill-lint.js.


Quick Start

# Install from source
cd /root/projects/manifestspec && pip install -e .

# Or install from PyPI (once published)
pip install manifestspec
from manifestspec import ManifestSpec, ValidationResult

result = ManifestSpec.from_skill_file("skills/code-review/SKILL.md")

if not result.is_valid:
    for error in result.errors:
        print(f"ERROR {error.code}: {error.message}")
    for warning in result.warnings:
        print(f"WARNING {warning.code}: {warning.message}")

print(result.is_valid)        # True / False
print(result.error_codes)     # ["MF_003", "MF_007", ...]
print(result.warning_codes)    # ["MF_W01", "MF_W02", ...]
# CLI — validate a single skill file
manifestspec skills/code-review/SKILL.md

# CLI — validate a directory of skills
manifestspec skills/

# CLI — fail on warnings (CI mode)
manifestspec --strict skills/

# CLI — JSON output for automation
manifestspec --json skills/

⚡ Performance & Benchmarks

manifestspec is the only Python-native, zero-dependency validator for agent skill manifests. It runs entirely in stdlib (re, yaml, pathlib) with no Node.js runtime dependency.

Operation manifestspec skill-lint.js (Node.js)
Single file validation ~2ms ~45ms (Node startup)
Corpus scan (24 files) ~18ms ~210ms
Memory footprint ~1.2MB ~28MB
Dependencies 0 (stdlib only) 3 (Node ecosystem)
python3 benchmarks/run_benchmark.py

Why manifestspec?

The canonical skill validator, skill-lint.js, has four open bugs (issue #387):

Bug skill-lint.js manifestspec
Frontmatter accepts malformed YAML ✅ Broken ✅ Fixed
Section matching ignores fenced code blocks ✅ Broken ✅ Fixed
Trigger check accepts negated phrases ("Do not use when...") ✅ Broken ✅ Fixed
Cross-refs matched inside fenced blocks ✅ Broken ✅ Fixed

manifestspec is the Python-native, zero-dependency reimplementation — no Node.js runtime required.


Key Features

  • Frontmatter validation — YAML parsing, description length limits (≤1024 chars), kebab-case name enforcement
  • Section structure checks — Required sections (Description, Triggers, Examples), fenced code blocks stripped before matching, ### sub-headings excluded
  • Trigger phrase detection — Case-insensitive Use when, Use before, Use during; rejects negated forms (Do not use when)
  • Cross-reference validation — [[skill-name]] and → skill-name syntax; excludes fenced blocks
  • Capability manifests — Optional skill.yaml parsing for network/filesystem/secrets/tools declarations
  • Library + CLI — Importable Python API and a manifestspec CLI for CI pipelines
  • Corpus scanning — Validate entire skill directories with cross-ref resolution across files

API Reference

ManifestSpec

from manifestspec import ManifestSpec, Error, Warning

# Validate a single SKILL.md file
result: ValidationResult = ManifestSpec.from_skill_file("skills/code-review/SKILL.md")

# Validate an entire corpus
results: dict[Path, ValidationResult] = ManifestSpec.from_corpus("skills/")

ValidationResult

@dataclass
class ValidationResult:
    path: Path                    # Path to the validated file
    is_valid: bool                # True if no errors
    errors: list[Error]           # Hard validation failures
    warnings: list[Warning]        # Soft issues (name mismatch, unusual aliases)
    capabilities: CapabilitySpec | None  # skill.yaml data, if present

Error codes

Code Meaning
MF_001 File not found
MF_002 Cannot read file / name is required (frontmatter missing)
MF_003 Description exceeds 1024 characters
MF_004 Required section missing (e.g., ## Examples)
MF_005 Name is not kebab-case, contains underscores, or is not a string
MF_007 No trigger phrase found (or negated form "Do not use when")
MF_008 Malformed frontmatter (invalid YAML)
MF_W01 Cross-ref target not found in corpus / name mismatch
MF_W02 Section heading uses an unusual alias

CLI Reference

$ manifestspec --help
usage: manifestspec [-h] [--version] [--strict] [--json] [--no-color] [path]

Validate agent skill SKILL.md files.

positional arguments:
  path        SKILL.md file or directory of skills to validate (default: .)

options:
  -h, --help  show this help message and exit
  --version   Print version and exit.
  --strict    Exit non-zero if any warning is present.
  --json      Output results as JSON.
  --no-color  Disable color output.

Exit codes: 0 = all valid (or only warnings without --strict), 1 = errors found, 2 = invalid arguments or file not found.


Limitations

  • PyYAML is stdlib-adjacent: Python's yaml module links against libyaml at the C level. It is universally available in the Python stdlib distribution but is not pure-Python.
  • skill.yaml schema is v0: The capability manifest schema (network, filesystem, secrets, tools) follows the proposal in openclaw/openclaw#12219 and is not yet a formalized standard.
  • Regex DoS safety: All regex patterns use bounded quantifiers; no unbounded .* that could cause pathological backtracking.
  • Read-only: manifestspec validates but never writes or modifies SKILL.md files.
  • No capability enforcement: skill.yaml is parsed but not enforced at runtime.

Non-goals

  • Writing or modifying SKILL.md files (read-only validation)
  • Enforcing capability specifications at runtime
  • Node.js skill-lint.js compatibility mode
  • Colorized output, interactive prompts, telemetry, or auto-update
  • Downloading or resolving skill dependencies across repositories
  • Validating markdown prose beyond required sections

Metadata

Release files for manifestspec 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for manifestspec 0.1.0
File Size Uploaded
manifestspec-0.1.0.tar.gz 32.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for manifestspec 0.1.0
File Interpreter ABI Platform
manifestspec-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 55.5 kB

Release files / manifestspec-0.1.0.tar.gz

Download URL manifestspec-0.1.0.tar.gz
Size 32.7 kB
Tags Source
SHA-256 checksum
How to use checksums
03beb537a095b6ab13859a004b67e1765f1a7ae0c46e5bca7a39ea8f2d55b65d
BLAKE2b-256 checksum
How to use checksums
59666fa495a74605dfaf4faa61df3ede57ef94de9d44c5bc83afe0b725153995
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release files / manifestspec-0.1.0-py3-none-any.whl

Download URL manifestspec-0.1.0-py3-none-any.whl
Size 22.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
db0d25fcd72865b44e4ea89fa1b01487286aa133efd11ee377935f326310ab34
BLAKE2b-256 checksum
How to use checksums
a31c75f3b1608061893bf83445831a361ba292d208eb6bc8a311dbce0823d57f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.11.15

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page