█████╗ ██████╗ ███████╗███╗ ██╗████████╗██╗ ██╗███╗ ██╗████████╗
██╔══██╗██╔════╝ ██╔════╝████╗ ██║╚══██╔══╝██║ ██║████╗ ██║╚══██╔══╝
███████║██║ ███╗█████╗ ██╔██╗ ██║ ██║ ██║ ██║██╔██╗ ██║ ██║
██╔══██║██║ ██║██╔══╝ ██║╚██╗██║ ██║ ██║ ██║██║╚██╗██║ ██║
██║ ██║╚██████╔╝███████╗██║ ╚████║ ██║ ███████╗██║██║ ╚████║ ██║
╚═╝ ╚═╝ ╚═════╝ ╚══════╝╚═╝ ╚═══╝ ╚═╝ ╚══════╝╚═╝╚═╝ ╚═══╝ ╚═╝
linter for AI-agent config files
A linter for AI-agent config. Catches secrets, dangerous permission grants, and risky hook commands in your
CLAUDE.md,settings.json, and skill files — before you push them.
The skills ecosystem now has 4,000+ public skill packs and 15,000+ plugin repos. None of them validate the config you wrote. agentlint does.
$ agentlint .
.claude/settings.json:14 HIGH PERM-001 Bash allowed with no scope ('Bash(*)') — narrow this to specific commands.
.claude/hooks/post-edit.sh:8 HIGH HOOK-001 Hook contains dangerous pattern: rm -rf
CLAUDE.md:8 HIGH SECRET-001 Possible OpenAI key embedded in file: sk-xxxxx…
CLAUDE.md:42 MEDIUM BYPASS-001 Doc references `--no-verify` — remove unless explicitly required.
.claude/settings.json:1 LOW DENY-001 No `permissions.deny` block. Recommend a baseline.
5 issue(s) across 6 file(s).
agentlint . # lint current dir
agentlint ./my-project # lint a project
agentlint . --json # machine-readable
agentlint . --fail-on high # CI-friendly exit codeIt walks your project, finds every file an AI agent reads or trusts — CLAUDE.md, AGENTS.md, .cursor/rules/*, .claude/settings.json, .claude/hooks/*, .claude/skills/**/SKILL.md — and runs each through the rule set.
| Rule | Severity | What it flags |
|---|---|---|
SECRET-001 |
high | API-key-shaped strings (OpenAI, Anthropic, AWS, GitHub, Slack, Google) embedded in config or markdown |
PERM-001 |
high | Bash(*) or any unscoped Bash(...) in permissions.allow |
HOOK-001 |
high | Hook commands containing rm -rf, curl ... | sh, wget ... | bash, or eval $(...) |
HOOK-002 |
medium | Hooks fetching un-pinned remote scripts |
BYPASS-001 |
medium | --no-verify, --no-gpg-sign, force-push documented in CLAUDE.md |
DENY-MISSING-001 |
low | No permissions.deny block at all — recommend a baseline |
Adding a rule is one entry in src/agentlint/rules.py.
pip install -e .Zero third-party runtime dependencies.
Default is the human-readable report above. With --json:
[
{ "file": ".claude/settings.json", "line": 14, "severity": "high", "rule": "PERM-001", "message": "..." }
]# .github/workflows/agentlint.yml
on: [pull_request]
jobs:
agentlint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with: { python-version: "3.12" }
- run: pip install -e .
- run: agentlint . --fail-on high--fail-on <severity> returns non-zero if any issue at or above that level was found.
The capability of these tools is growing faster than the safety posture of their configs. A misconfigured CLAUDE.md is a worse vulnerability than a misconfigured firewall — it gives autonomous tool-use to anyone reading the README. agentlint makes config review trivial.
vibe-init — vibe-init writes safe configs, agentlint keeps them safe as they drift.
- pentern — Autonomous code-writing recon agent
- orbital — Passive subdomain-takeover scanner
- brief — Daily CVE/advisory digest agent
- secmcp — MCP server for passive security tools
- vibe-init — One-command scaffolder for AI-coder configs
MIT. See LICENSE.