a2a-pulse
A live registry & health tracker for the A2A protocol ecosystem.
The Agent2Agent (A2A) protocol — donated by Google
to the Linux Foundation in early 2025 — is now in production at Google Cloud,
Microsoft, AWS, and 150+ other organisations. Public A2A agents publish a.well-known/agent-card.json describing their identity, skills, capabilities,
and endpoints, and several open registries already index dozens of them.
a2a-pulse is a third-party tracker that:
- Pulls the public a2aregistry.org catalog
- every 6 hours.
- Independently probes each agent's declared
.well-known/agent-card.json - on the same cadence to record live HTTP status, response latency, and
- content hash.
- Detects and timestamps changes — new agents appearing, version bumps,
- added or removed skills, agents going dead or coming back online.
- Exposes everything through a fast, no-auth SPA so you can search agents
- by skill tag, filter by capability, browse providers, and inspect any
- agent's full card + change history.
There is no signup, no API key, no admin login. All endpoints, including
writes (POST /api/refresh), are public — Arda wants to look at it
without typing a password.
Data sources (all public, all fetched live at runtime)
| Source | URL | Cadence |
|---|---|---|
| Public A2A registry | https://a2aregistry.org/api/agents | every 6h |
| Each agent's well-known card | <wellKnownURI> from the registry entry | every 6h, offset by 3h |
| A2A protocol releases | https://api.github.com/repos/a2aproject/A2A/releases | every 12h |
No seed data, no mock agents, no Math.random(). If the registry is
unreachable the previous snapshot is kept and the UI shows the
"last good fetch" timestamp transparently.
Quick start
npm install
cp .env.example .env
npm start
Then open http://localhost:4912/a2a-pulse/.
The first registry fetch happens in the background ~immediately after
boot; the UI populates within ~15 seconds on a working network.
Endpoints
All under BASE_PATH=/a2a-pulse (overrideable via env).
| Path | Description |
|---|---|
| GET /a2a-pulse/ | SPA shell |
| GET /a2a-pulse/health | { status, uptime_seconds, agents_indexed, last_*_at } |
| GET /a2a-pulse/api/stats | KPI numbers + protocol distribution + top skills |
| GET /a2a-pulse/api/agents?q&skill&protocol&streaming&push&live&provider&sort&limit&offset | paginated agent list |
| GET /a2a-pulse/api/agents/:id | full card + skills + last 50 probes + change history |
| GET /a2a-pulse/api/skills?q | aggregated skill tag cloud |
| GET /a2a-pulse/api/providers | one row per provider organisation |
| GET /a2a-pulse/api/changes?limit | reverse-chrono change feed |
| GET /a2a-pulse/api/probe-history/:id | uptime time-series for one agent |
| GET /a2a-pulse/api/protocol-versions | counts per protocolVersion |
| GET /a2a-pulse/api/spec | latest 10 A2A spec releases |
| POST /a2a-pulse/api/refresh?kind=registry\|probe\|spec\|all | trigger a refresh in background, returns 202 |
Stack
- Node.js 20+, Express 4
- better-sqlite3 (WAL mode) — single-file local DB
- node-cron — registry/probe/spec schedules
- helmet + compression
- Vanilla JS SPA, dark theme, no build step
Layout
server.js Express app, cron schedules, graceful shutdown
db.js SQLite schema + prepared statements + query helpers
fetchers/
registry.js Pulls a2aregistry.org/api/agents; upserts agents+skills; detects changes
probe.js Concurrent .well-known probes; records HTTP+latency+hash; detects went_dead / came_back
spec.js Pulls a2aproject/A2A GitHub releases for the dashboard sidebar
routes/
api.js JSON API
public/
index.html 5 tabs: Dashboard, Agents, Skills, Providers, Changes
app.js SPA logic + agent drawer + SVG probe sparkline
style.css Dark theme
Environment
| Key | Default |
|---|---|
| PORT | 4912 |
| NODE_ENV | production |
| BASE_PATH | /a2a-pulse |
| DB_PATH | ./a2a-pulse.db |
| REGISTRY_URL | https://a2aregistry.org/api/agents |
| PROBE_CONCURRENCY | 8 |
| PROBE_TIMEOUT_MS | 10000 |
| REGISTRY_CRON | 0 /6 |
| PROBE_CRON | 0 3,9,15,21 |
| SPEC_CRON | 0 /12 * |
License
MIT