Catalog PyPI
PACKAGE EXPLORERView in registry

a2a-lint

PyPI

Conformance linter for A2A agents — agent card validation, live message/send probes, CI-friendly exit codes.

a2aa2a-protocolagent2agentai-agentsconformancelinter
Versions collected1
Direct dependencies1From release 0.1.1
Last observed20 Oct, 16:26 UTC

README

Version 0.1.1 documentation

a2a-lint

Lint your A2A agents — validate agent cards against the spec, run live conformance probes in CI, and earn a conformance badge. Playground UI included.

Built for the A2A (Agent2Agent) protocol: the open standard (Google → Linux Foundation) that lets AI agents discover and delegate work to each other. Your agent speaks A2A the moment its card and endpoints conform — a2a-lint makes sure they do, and keep doing so on every push.

Why a2a-lint

Inspecting an agent once is easy (the official a2a-inspector does it well). Staying conformant is the hard part: a renamed skill, a card whose advertised url only resolves inside your compose network, a message/send that stopped returning Tasks — all invisible until another agent fails against yours. a2a-lint is built around continuous conformance:

  • CLI with CI-friendly exit codes — wire it into any pipeline
  • GitHub Action — every push checks the card and does a live round trip
  • Live badge — your README shows your current conformance grade
  • Playground — when something fails, debug it interactively with full wire-level detail

Quick start

docker compose up --build -d      # playground on http://localhost:8090

Paste any agent's base URL: you get its Agent Card rendered and graded (field-by-field findings with fix hints), an interactive JSON-RPC message/send console, tasks/get inspection, an SSE message/stream viewer, and shareable permalinks of inspection snapshots.

Inspecting agents that run on your host from inside the container? Use http://host.docker.internal:<port> (mapped via extra_hosts).

CLI

pip install git+https://github.com/vivek24290/a2a-lint@develop   # PyPI release coming
a2a-lint https://my-agent.example.com --live
✔ Weather Agent — card at https://my-agent.example.com/.well-known/agent-card.json (12 ms)
✔ live message/send round trip in 48 ms
GRADE B — 0 error(s), 1 warning(s)
  WARN  url: Endpoint URL is plain http.
        ↳ Use https in production; A2A messages can carry sensitive content.
FlagEffect
--livealso send a real message/send and verify the result is a Task/Message; if the card declares streaming: true, message/stream SSE conformance is checked too
--strictwarnings fail the lint too
--jsonmachine-readable output

Exit codes: 0 conformant · 1 findings · 2 unreachable/not A2A.

--live catches the classic deployment bug: a card that advertises a URL its consumers can't reach (e.g. a container-internal hostname on a public card).

GitHub Action

jobs:
  a2a-conformance:
    runs-on: ubuntu-latest
    steps:
      - uses: vivek24290/a2a-lint@v1
        with:
          url: https://my-agent.example.com
          live: "true"
          strict: "false"

Conformance badge

Live-graded SVG (5-minute cache) served by your playground instance:

![A2A conformance](https://<your-playground-host>/api/badge?url=https://my-agent.example.com)

What gets checked

Required card fields (name, description, url, version, capabilities, defaultInputModes/OutputModes, skills and per-skill fields), transport declarations, deprecated card paths, http-vs-https, missing tags/examples, undeclared auth — each finding carries a level (error/warn/info) and a concrete fix hint. Grades: A (clean) → F. See server/card_validator.py; the same core powers the CLI, the Action, the badge, and the playground.

a2a-watch monitor (MVP)

Open /status.html on your playground instance: register any agent and it gets probed on a schedule (card fetch + validation + live message/send — the same check the CLI runs). You get UP/DOWN state, 24h uptime, conformance grade, latency, and a webhook alert (JSON down/recovered events — point it at Slack/Discord/anything) the moment an agent breaks or recovers.

curl -X POST localhost:8090/api/monitor/agents -H 'Content-Type: application/json' \
  -d '{"url": "https://my-agent.example.com", "intervalSeconds": 300,
       "webhook": "https://hooks.slack.com/services/..."}'

History lives in data/monitor.db. If an agent's card advertises an unreachable url, the monitor falls back to the registered URL and reports the bad card instead of a false DOWN.

Architecture

a2a_lint/              the pip-installable package (shared core)
├── client.py          A2A client: card discovery, message/send, tasks/get, streaming
├── validator.py       spec checks -> structured findings
└── cli.py             the a2a-lint command (exit codes 0/1/2)
server/
├── main.py            FastAPI: playground API, SSE proxy, permalinks, badge, monitor API
├── monitor.py         a2a-watch core: scheduler, uptime history, webhook alerts
└── static/            playground UI (index.html) + monitor UI (status.html)
action.yml             GitHub Action wrapping the CLI

No LLM calls, no telemetry, no external services. Permalink snapshots and monitor history are SQLite files under ./data/.

Roadmap

  • pip install a2a-lint packaging (PyPI publish via .github/workflows/publish.yml)
  • message/stream conformance checks in the CLI
  • Security-scheme validation
  • a2a-watch monitor MVP: scheduled probes, uptime history, webhook alerts
  • Hosted a2a-watch: accounts, public status pages, e-mail alerts, paid tiers
  • Public playground instance (VPS + domain)

License

MIT

Downloads & popularity

Awaiting observations

No metric observations yet

Download counts and popularity will appear here as the collector receives them.

Versions 1

Collected releases
VersionPublishedDirect dependenciesOpen version
0.1.111 Jul 20261

Package advisories

0
No matching advisories collected

This describes our collected data; it is not a security assessment.

Repository

PENDING
vivek24290/a2a-lint

Shared repository data · GitHub

License detected in repository
Not collected

Metadata history

Meaningful changes
Current collected state Current

Observed since 20 Oct, 16:26 UTC

No superseded metadata states collected. Unchanged observations do not create new revisions.

Record identity

package:6964fc98f7573c3e863bdce887f1d70ae4186d001141624c62142931709af61c