Linter for AI coding agent harness files. Validates agents, skills, commands, hooks, settings, MCP config, and docs frontmatter across the major coding agent platforms.
$ agentlint
.claude/agents/debugger.md:1:1: error: missing required field 'name'
.claude/commands/deploy.md:3:1: error: missing required field 'description'
.claude/settings.json:1:1: error: unknown top-level key 'theme'
.mcp.json:1:1: error: mcpServers.my-server: server entry must have 'command' or 'url' transport
3 errors, 1 warning
| Platform | Files validated |
|---|---|
| Claude Code | .claude/agents/**/*.md, .claude/skills/**/*.md, .claude/commands/**/*.md, .claude/hooks/**, .claude/settings.json, .mcp.json, CLAUDE.md |
| Cursor | .cursor/rules/**/*.mdc, .cursor/rules/**/*.md, .cursorrules |
| Codex | AGENTS.md |
| OpenCode | AGENTS.md, opencode.json |
| Gemini | GEMINI.md |
| Pi | AGENTS.md, SYSTEM.md |
| Docs | docs/**/*.md (frontmatter schema) |
cargo install agentlint
# Validate all agent harness files in the current directory
agentlint
# Validate specific files or directories
agentlint .claude/agents/ AGENTS.md
# JSON output for CI tooling
agentlint --format json
# Audit mode — report issues but always exit 0
agentlint --exit-zero
| Code | Meaning |
|---|---|
0 |
All files valid |
1 |
One or more validation errors |
2 |
Internal error (I/O, permission failure) |
Agents, skills, commands (.claude/agents/, .claude/skills/, .claude/commands/):
namefield present and non-emptydescriptionfield present and non-empty- Frontmatter fence is well-formed (
---…---) - Duplicate
name:values across all agent files (cross-file check)
Hooks (.claude/hooks/):
- First line is a shebang (
#!) - File has execute permission
Settings (.claude/settings.json, .claude/settings.local.json):
- Valid JSON
- No unknown top-level keys
permissions.allow/permissions.denyare arrays of strings if presenthooksentries have acommandstring field if present
MCP config (.mcp.json):
- Valid JSON with a top-level
mcpServersobject - Each server entry has
command(stdio) orurl(HTTP/SSE) transport commandis non-empty and not a relative path (relative paths break when Claude Code is launched from a different directory)envvalues are not hardcoded secrets — must use$ENV_VARorop://referencesop://URIs inenvare flagged: they do not resolve in Claude's shell context- Duplicate server names (last entry silently wins)
- Unconstrained HTTP fetch servers flagged as a security warning
- No unknown fields inside server entries
CLAUDE.md (CLAUDE.md, **/CLAUDE.md):
- File has at least one markdown heading
- File does not exceed 500 lines
Rules (.cursor/rules/, .cursorrules):
- Frontmatter is well-formed if present (unclosed fence is an error)
descriptionis a non-empty string if presentglobsis a string or list of strings if presentalwaysApplyis a boolean if present
- File is non-empty and not whitespace-only
opencode.jsonis valid JSON
Files without a frontmatter fence are skipped. Files with frontmatter are validated against the project doc schema:
Required fields: title, doctype, project, status, created, updated
Enum values:
status:draft,active,archived,supersededdoctype:idea,spec,plan,adr,roadmap,guide,reference,runbook,architecture,capability-matrix,testing,development,readme
Date fields: created and updated must be YYYY-MM-DD
meta field — optional; if present, must be a YAML mapping. Two syntaxes accepted:
# Inline JSON (single line)
meta: {"spec": "docs/specs/2026-05-15-agentlint.spec.md", "author": "Joe"}
# Indented YAML keys (multiline)
meta:
spec: docs/specs/2026-05-15-agentlint.spec.md
author: JoePlan docs must include a meta.spec key linking to the upstream spec.
Filename conventions — two layouts are recognised:
- Repo doc:
docs/{doctype}.{project}.md—title,doctype, andprojectmust match the filename components - Research doc:
docs/{ideas|specs|plans}/{ref}-{topic}.{doctype}.md— doctype inferred from directory if no explicit suffix; plan docs must include ametablock withspec
Add to .github/workflows/:
- name: agentlint
run: agentlintOr with cargo:
- uses: actions/checkout@v4
- uses: dtolnay/rust-toolchain@stable
- run: cargo install agentlint
- run: agentlint# First-time setup (configures git hooks, installs cargo tools)
./scripts/dev-setup.sh
cargo check --workspace
cargo nextest run --workspace
cargo clippy --workspace -- -D warningsSee docs/plans/2026-05-15-agentlint.md for the
full design document and docs/roadmap.agentlint.md for
shipped milestones and planned work.
MIT OR Apache-2.0