---
title: "A2A agents — AI Crawler Index"
description: "This host as eight A2A (Agent2Agent) v1.0 agents, one per capability: the index, robots.txt lint, crawler IP verification, log triage, discovery-document audit, MCP endpoint conformance, discovery and auth posture, and one score card. JSON-RPC, no key, a card each."
canonical: "https://www.pathwren.workers.dev/a2a.html"
url: "https://www.pathwren.workers.dev/a2a.md"
format: "markdown"
source: "the bytes of /a2a.html, in the build that wrote the page"
generator: "surfaces/ai-crawler-index/build.py"
generated: "2026-09-03T07:55:35+00:00"
license: "CC0-1.0"
---

# A2A agents

> This host as eight A2A (Agent2Agent) v1.0 agents, one per capability: the index, robots.txt lint, crawler IP verification, log triage, discovery-document audit, MCP endpoint conformance, discovery and auth posture, and one score card. JSON-RPC, no key, a card each.

The same work again, spoken as [A2A v1.0](https://a2a-protocol.org/latest/specification/) instead of as files or as MCP. JSON-RPC 2.0 over HTTP POST, no key, no signup,
no session. Every skill is read-only, and each one is executed by exactly the function
that answers the identically-named [MCP tool](https://www.pathwren.workers.dev/mcp.html) — two protocols, one
implementation.

```text
# nothing to hand? this needs no arguments and no editing, and the subject is you
curl -s https://www.pathwren.workers.dev/a2a -H 'content-type: application/json' -d '{
 "jsonrpc":"2.0","id":1,"method":"message/send",
 "params":{"message":{"role":"ROLE_USER","messageId":"1","parts":[
   {"text":"{\"skill\":\"whoami\"}"}]}}}'
```

That returns a `Task` already in state `completed`, in the same
HTTP response: the answer is in `status.message` and mirrored into one
artifact. There is nothing to poll, nothing to subscribe to and no second request to
make. **Every skill on every one of the eight agents, as a body you can send unedited, is in /a2a/example.json** — one document,
{} bodies and curl lines, no schema to read first.

**Five agents, not one.** This host publishes five agent cards, one per
capability, each at its own URL with its own endpoint and its own skills. No skill appears
on two cards. Point your client at whichever one does the job; nothing here requires the
others.

| Agent | Card | Endpoint | Skills |
| --- | --- | --- | --- |
| The index itself | [/.well-known/agent-card.json](https://www.pathwren.workers.dev/.well-known/agent-card.json) | `/a2a` | `classify_user_agent`, `lookup_crawler`, `list_crawlers`, `generate_robots_txt`, `is_verified_crawler_ip`, `whats_changed` |
| Crawler IP Verifier | [/a2a/netcheck/.well-known/agent-card.json](https://www.pathwren.workers.dev/a2a/netcheck/.well-known/agent-card.json) | `/a2a/netcheck` | `verify_batch`, `lookup_prefix`, `export_ip_acl`, `verification_methods`, `range_stats`, `whoami`, `example` |
| robots.txt Policy Lint | [/a2a/robots/.well-known/agent-card.json](https://www.pathwren.workers.dev/a2a/robots/.well-known/agent-card.json) | `/a2a/robots` | `lint_robots_txt`, `check_path_allowed`, `audit_ai_access`, `diff_robots_txt`, `merge_policy`, `whoami`, `example` |
| Crawler Log Triage | [/a2a/triage/.well-known/agent-card.json](https://www.pathwren.workers.dev/a2a/triage/.well-known/agent-card.json) | `/a2a/triage` | `triage_log`, `find_impersonators`, `summarize_by_operator`, `robots_from_log`, `waf_ruleset_from_log`, `whoami`, `example` |
| Agent Discovery Doctor | [/a2a/doctor/.well-known/agent-card.json](https://www.pathwren.workers.dev/a2a/doctor/.well-known/agent-card.json) | `/a2a/doctor` | `check_discovery_documents`, `explain_document`, `validate_llms_txt`, `llms_txt_from_sitemap`, `validate_agent_card`, `whoami`, `example` |
| MCP Endpoint Conformance | [/a2a/lint/.well-known/agent-card.json](https://www.pathwren.workers.dev/a2a/lint/.well-known/agent-card.json) | `/a2a/lint` | `handshake_report`, `tools_list_report`, `error_conformance`, `whoami`, `example` |
| Discovery and Auth-Posture Probe | [/a2a/discovery/.well-known/agent-card.json](https://www.pathwren.workers.dev/a2a/discovery/.well-known/agent-card.json) | `/a2a/discovery` | `discovery_report`, `whoami`, `example` |
| MCP Endpoint Score Card | [/a2a/score/.well-known/agent-card.json](https://www.pathwren.workers.dev/a2a/score/.well-known/agent-card.json) | `/a2a/score` | `score_card`, `whoami`, `example` |

```text
# a skill with arguments, on the root agent
curl -s https://www.pathwren.workers.dev/a2a -H 'content-type: application/json' -d '{
 "jsonrpc":"2.0","id":1,"method":"SendMessage",
 "params":{"message":{"messageId":"1","role":"ROLE_USER","parts":[
   {"data":{"skill":"classify_user_agent","user_agent":"GPTBot/1.2"}}]}}}'

# and so does each capability agent, same shape, its own skills
curl -s https://www.pathwren.workers.dev/a2a/robots -H 'content-type: application/json' -d '{
 "jsonrpc":"2.0","id":1,"method":"SendMessage",
 "params":{"message":{"messageId":"1","role":"ROLE_USER","parts":[
   {"data":{"skill":"audit_ai_access","robots_txt":"User-agent: *\\nDisallow: /"}}]}}}'
```

Each card is served at `<endpoint>/.well-known/agent-card.json`, with
identical bytes at the legacy `agent.json` name and from `GET` on the
endpoint itself. The root card is also at
[/.well-known/agent-card.json](https://www.pathwren.workers.dev/.well-known/agent-card.json), where a client that
knows only the host will look.

## Tasks, and what `tasks/get` does here

`message/send` (v1.0: `SendMessage`) is the method that invokes a
skill, and it is the only one you need. It returns a completed `Task`
synchronously — this host runs no long work, so no task is ever pending.

The task id is not a handle into a database: this worker keeps **no task store**. The id *encodes the call that produced it*, so
`tasks/get` answers by re-running that same deterministic, read-only call and
returning the identical task. An id this host did not mint returns
`-32001` — nothing was ever created for it — and that error carries the
`message/send` body that would create one, because a client asking after a task
it never created is a client that has not been shown the method that makes one.
`tasks/cancel` on a task that is already finished returns
`-32002`.

## Skills of the root agent

Named exactly as in the card. Send a `DataPart` naming one —
`{"data":{"skill":"lookup_crawler","slug":"claudebot"}}` — or plain text, which is
matched against a small set of rules and answered with the skill list when it does not
resolve. There is no model behind this endpoint: an unrecognised message gets told what to
send, never a guessed answer.

| Skill | Argument | What it answers |
| --- | --- | --- |
| `whoami` | *none* | What this host can see about the caller: the user-agent you sent, your address, the class our own instrument books you as, whether we have seen you before, and what our robots policy says about you. Nothing is fetched and nothing is invented. |
| `example` | *none* | This server's own worked example, run end to end, returning the real answer rather than a description of one. |
| `classify_user_agent` | `user_agent` | Which crawler is behind this raw User-Agent, who runs it, and what blocking it costs. |
| `lookup_crawler` | `slug` | The full record for one crawler by slug, name or robots.txt token. |
| `list_crawlers` | `q`, `category`, `operator`… | The 150 crawlers, filtered. |
| `generate_robots_txt` | `stance` | A ready-to-paste robots.txt for one of 8 stances. |
| `is_verified_crawler_ip` | `ip` | Is this address inside a range the operator itself publishes? 1984 IPv4 and 1062 IPv6 prefixes. |
| `whats_changed` | `since` | Build time, per-source freshness, and what changed. |

## What it does not do, and says so in the card

No streaming (`SendStreamingMessage` → `-32004`): there is nothing
to stream when the answer is already complete. No push notifications
(`-32003`), no task store (see above), no extended agent card
(`-32007`). Legacy v0.3 method names (`message/send`,
`tasks/get`) are accepted, and the `A2A-Version` header is honoured for
`1.0` and `0.3`.

Same data as [/data/agents.json](https://www.pathwren.workers.dev/data/agents.json),
[/openapi.json](https://www.pathwren.workers.dev/openapi.json) and [/mcp](https://www.pathwren.workers.dev/mcp.html) — pick whichever
your client speaks.

## Sitemap

- [Full sitemap (XML)](https://www.pathwren.workers.dev/sitemap.xml) — every page, with dates
- [Full sitemap (markdown)](https://www.pathwren.workers.dev/sitemap.md) — the same map, readable
- [llms.txt](https://www.pathwren.workers.dev/llms.txt) — the whole host in one text file
- [documents.json](https://www.pathwren.workers.dev/documents.json) — every document, with its ETag
- [A2A agents](https://www.pathwren.workers.dev/a2a.html)
- [About and method](https://www.pathwren.workers.dev/about.html)
- [API](https://www.pathwren.workers.dev/api.html)
- [Changelog](https://www.pathwren.workers.dev/changelog.html)
- [Compliance](https://www.pathwren.workers.dev/compliance)
- [Contact](https://www.pathwren.workers.dev/contact)
- [Impressum · Anbieterkennzeichnung](https://www.pathwren.workers.dev/impressum)
- [AI Crawler Index](https://www.pathwren.workers.dev/index.html)
- [No model runs here](https://www.pathwren.workers.dev/inference.html)
- [Legal](https://www.pathwren.workers.dev/legal)
- [MCP server](https://www.pathwren.workers.dev/mcp-doctor.html)
- [MCP server](https://www.pathwren.workers.dev/mcp-lint.html)
- [MCP server](https://www.pathwren.workers.dev/mcp-netcheck.html)
- [MCP server](https://www.pathwren.workers.dev/mcp-robots.html)
- [MCP transport: the GET and HEAD leg](https://www.pathwren.workers.dev/mcp-transport.html)
- [MCP server](https://www.pathwren.workers.dev/mcp-triage.html)
- [MCP server](https://www.pathwren.workers.dev/mcp.html)
- [Packages](https://www.pathwren.workers.dev/packages.html)
- [Pricing](https://www.pathwren.workers.dev/pricing)
- [Privacy](https://www.pathwren.workers.dev/privacy.html)
- [API reference](https://www.pathwren.workers.dev/reference)
- [Access, keys and sign-up](https://www.pathwren.workers.dev/register)
- [Security posture](https://www.pathwren.workers.dev/security.html)
- [Upstream status](https://www.pathwren.workers.dev/status.html)
- [Terms of use](https://www.pathwren.workers.dev/terms.html)
- [Trust](https://www.pathwren.workers.dev/trust)

## Machine copies of this page

- [HTML (canonical)](https://www.pathwren.workers.dev/a2a.html)
- [JSON](https://www.pathwren.workers.dev/a2a.json)
- [Markdown](https://www.pathwren.workers.dev/a2a.md) — this document

This document is a markdown rendering of [https://www.pathwren.workers.dev/a2a.html](https://www.pathwren.workers.dev/a2a.html), generated from that page's own bytes in the same build. The HTML page is canonical.
