Skip to main content

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 toolsbefore 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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agenticlint-0.1.0.tar.gz (97.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agenticlint-0.1.0-py3-none-any.whl (45.2 kB view details)

Uploaded Python 3

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

Hashes for agenticlint-0.1.0.tar.gz
Algorithm Hash digest
SHA256 dc71898af30cdd83f1397ecf4164b569238846374c56379d828abe37b30387c5
MD5 1defa3e24a8d8dbc759b6aa0019a2667
BLAKE2b-256 6239cc4b98d3ec2cac006aea33f0bd111f8f57cb839a09eefe6f7cbce3922e8d

See more details on using hashes here.

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

Hashes for agenticlint-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 264825b3ac9102e5d111ea5481d59df7f3da46c6b259360156ce69f73acc90f5
MD5 ca78a22dea997765a755fc60dd3fcafc
BLAKE2b-256 dbdc47d56a1b94928d354aa4ec6e749a315b03b3856316cb5e3d0e3b4e73f2a9

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page