Static linter that checks whether an OpenAPI spec is safe and clear enough to expose as MCP/AI-agent tools.
Project description
agenticlint
English | 한국어
An OpenAPI spec being machine-readable does not make it agent-ready.
agenticlint is a static linter that checks whether an OpenAPI/Swagger document is
safe and clear enough to expose as MCP / AI-agent tools — before you convert it.
It flags ambiguous names, unclassified risk, missing approval policy, data-exfiltration
surfaces, and tool-poisoning vectors. No LLM in the judgment path: every finding is
deterministic and reproducible, so it works as a CI gate.
Docs: English guide · 한국어 가이드 · Rule reference
Install
pip install "agenticlint[cli]" # library + full CLI
pip install agenticlint # library only (a minimal built-in CLI still works)
pipx run agenticlint scan openapi.yaml
Not yet published to PyPI; until then install from source:
pip install -e ".[cli]".
Use
CLI
agenticlint scan openapi.yaml
agenticlint scan https://api.example.com/openapi.json
agenticlint scan openapi.yaml --fail-on high --format markdown --output report.md
agenticlint baseline openapi.yaml # freeze the legacy backlog
agenticlint scan openapi.yaml --baseline .agenticlint-baseline.json # only NEW findings fail
Exit codes: 0 pass · 1 findings at/above --fail-on · 2 load/config error.
Behavior is configurable via ./.agenticlint.yaml (presets, rule on/off, thresholds,
lexicon extension, ignorePaths) — see the guide.
Library (the core is the product; the CLI is a thin wrapper)
from agenticlint import scan
report = scan("openapi.yaml") # path, http(s) URL, or a parsed dict
print(report.summary())
if not report.passed("high"):
raise SystemExit(1)
report.to_json() # versioned JSON contract — the cross-language interface
report.to_markdown()
GitHub Actions
- run: pipx run agenticlint scan openapi.yaml --fail-on high
What it checks (49 rules across 7 families)
| Family | Concern | Examples |
|---|---|---|
| S structure | fields missing → can't interpret/construct | S007 risky op with no auth |
| A ambiguity | vague names/descriptions → wrong tool/payload | A001 generic id param |
| X cross-op | duplicate / conflicting tools across the spec | X001 near-identical descriptions |
| R risk | HTTP-semantics contradictions, dangerous surfaces | R001 side-effect GET · R003 collection-wide delete |
| P policy | declared x-agent-policy vs observed risk |
P001 destructive with no policy |
| I integrity | tool poisoning in descriptions | I001 prompt injection · I002 hidden chars |
| M MCP compat | conversion loss / degradation | M001 invalid tool name · M003 too many tools |
Full judgment logic and the lexicons live in the rule reference; the reasoning for why static analysis can do this is in the "How it works" section of the guide.
How it works
OpenAPI (YAML/JSON) → parse ($ref) → IR (tokenized) → risk classifier
→ rule engine (pure functions) → report + exit code
The risk classifier is a weighted signal table (HTTP method baseline + lexical override), not a model. Ambiguity is measured by proxy signals (short descriptions, generic names, near-duplicate descriptions) — the same principle ESLint uses for "bad code". See the guide for what static analysis covers vs. what stays with a human reviewer, and its Evidence & prior art section for the research (Hermes, AutoMCP, MetaTool, Anthropic/OpenAI tool guidance) grounding the rules.
x-agent-policy
Findings suggest an OpenAPI vendor extension you attach per operation:
x-agent-policy:
risk: destructive # read | write | destructive | financial | external | privilege
requireConfirmation: true
confirmationMessage: "Cancel order {orderId}? This cannot be undone."
sensitiveData: false
exposeToAgent: true
These map cleanly onto MCP tool annotations (readOnlyHint, destructiveHint, …),
so the same policy drives the eventual MCP conversion.
Development
pip install -e ".[dev]"
pytest
The demo/ specs are the test oracle: shop-api-bad.yaml must reproduce
expected-findings.yaml exactly, and shop-api-good.yaml must produce zero findings
(it embeds false-positive traps). See demo/README.md.
License
Apache-2.0
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file agenticlint-0.1.0.tar.gz.
File metadata
- Download URL: agenticlint-0.1.0.tar.gz
- Upload date:
- Size: 97.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc71898af30cdd83f1397ecf4164b569238846374c56379d828abe37b30387c5
|
|
| MD5 |
1defa3e24a8d8dbc759b6aa0019a2667
|
|
| BLAKE2b-256 |
6239cc4b98d3ec2cac006aea33f0bd111f8f57cb839a09eefe6f7cbce3922e8d
|
File details
Details for the file agenticlint-0.1.0-py3-none-any.whl.
File metadata
- Download URL: agenticlint-0.1.0-py3-none-any.whl
- Upload date:
- Size: 45.2 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
264825b3ac9102e5d111ea5481d59df7f3da46c6b259360156ce69f73acc90f5
|
|
| MD5 |
ca78a22dea997765a755fc60dd3fcafc
|
|
| BLAKE2b-256 |
dbdc47d56a1b94928d354aa4ec6e749a315b03b3856316cb5e3d0e3b4e73f2a9
|