Skip to content

skillsaw and claude plugin validate

Claude Code ships its own validator, claude plugin validate <dir>. It checks plugin and marketplace files against the schema and many of the loader's rules, so skillsaw treats it as the reference for what a file must look like. A clean result is not a load guarantee: some files pass validation and still fail at install or load time (see the entry hooks row below). skillsaw checks the same files, plus content, security, and other hosts. This page says where the two overlap and how skillsaw stays in agreement.

Run both if you can. The official validator knows the loader's exact behavior for the Claude Code version you run. skillsaw adds checks the validator does not make, runs without Claude Code installed, and covers repositories that also target Codex, Cursor, Grok and other hosts.

How the checks map

Measured against Claude Code 2.1.319.

Official validator check skillsaw rule Status
plugin.json is valid JSON with a string name and string version claude-plugin-json-valid Overlap
Missing description, author or version (warning) claude-plugin-json-valid recommended-fields Overlap
Plugin name not kebab-case (warning) claude-plugin-naming Overlap
Component paths (commands, agents, skills, hooks, mcpServers, outputStyles, lspServers) missing or climbing out with .. claude-plugin-json-valid Overlap
${user_config.KEY} in MCP config without userConfig.KEY claude-plugin-json-valid Overlap
marketplace.json schema: name, owner.name, plugins, string entry names claude-marketplace-json-valid Overlap
Entry source must start with ./; a bare name needs metadata.pluginRoot; no .. claude-marketplace-json-valid Overlap
Marketplace and entry names Claude Code cannot install claude-marketplace-json-valid Overlap
No plugin.json (note: the marketplace entry or directory name stands in) claude-plugin-json-required skips marketplace-registered plugins Overlap
.mcp.json syntax; server dropped for an empty or non-string command or non-array args mcp-valid-json Overlap
hooks.json syntax, unknown events and handler types, non-string matcher, onFailure values claude-hooks-valid Overlap
Agent, command and skill frontmatter parses; missing description (warning) claude-agent-frontmatter, claude-command-frontmatter, agentskill-valid Overlap
SKILL.md metadata that is not a mapping agentskill-valid Overlap
Plugin has a README (--profile directory) claude-plugin-readme Overlap
Reserved plugin names (claude-*, anthropic-*, ...) — Official only: a submission policy; claude plugin install accepts them
http:// MCP URL to a non-loopback host (warning) — Official only
Unquoted ${CLAUDE_PLUGIN_ROOT} in a shell-form hook (warning) — Official only
CLAUDE.md at the plugin root is not loaded (warning) — Official only
Plugin directory submission checks: LICENSE, icon, privacy policy URL — Official only
Project agent in .claude/agents with no name or description, which Claude Code skips claude-agent-frontmatter skillsaw only: the validator does not flag it
Entry hooks written as a path or array, which the validator accepts but the installed plugin fails to load claude-marketplace-json-valid skillsaw only: the validator does not flag it
Plugin directories the catalog does not list claude-marketplace-registration skillsaw only
Dangerous hooks, committed secrets, hidden instructions hooks-dangerous, content-embedded-secrets and the security rules skillsaw only
Content quality, context budget, cross-host checks content, context-budget and per-host rules skillsaw only

For the Claude format rules, severity follows the loader. A plugin agent or command with no frontmatter still loads under its filename, so skillsaw reports it as a warning. A project agent with no description is skipped, so skillsaw reports it as an error.

skillsaw keeps the overlapping checks for CI runs and editors without Claude Code. That includes some advisory warnings it already had, such as missing recommended fields, kebab-case names and a missing README. New skillsaw checks added to match the validator cover load failures only, and the conformance manifest below compares errors only.

Conformance check

tests/claude_conformance.json records, for every fixture under tests/fixtures/ that holds a .claude-plugin/ directory:

  • official: what the validator says will not load (its errors, and the warnings that say an entry or server is ignored or dropped at load time);
  • skillsaw: the rules skillsaw reports at error severity;
  • note: why they differ, required when only one side reports an error.

The pytest suite checks the skillsaw half on every run. The validator half runs in the claude-conformance CI job, which installs Claude Code from the lockfile in .github/claude-code/. Locally, with the pinned version installed:

.venv/bin/python3 scripts/claude-conformance.py           # compare; exit 1 on drift
.venv/bin/python3 scripts/claude-conformance.py --write   # re-record after an intended change

When Claude Code releases a version that changes the validator, install it and run --write, which moves the manifest's pin to that version. Set the same version in .github/claude-code/package.json and refresh its lockfile (npm install --package-lock-only in that directory). Review the diff, then fix any new disagreement in a skillsaw rule or fixture.