curl -s https://www.pathwren.workers.dev/a2a.json   # this page, as JSON

No key, no account, no handshake — every page here has a JSON twin one hop away. Machine doors: 6 keyless GET tools · documents.json · changes · llms.txt · openapi.json · agent card · mcp · a2a

A2A agents

The same work again, spoken as A2A v1.0 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 — two protocols, one implementation.

# 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.

AgentCardEndpointSkills
The index itself/.well-known/agent-card.json/a2aclassify_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/a2a/netcheckverify_batch, lookup_prefix, export_ip_acl, verification_methods, range_stats, whoami, example
robots.txt Policy Lint/a2a/robots/.well-known/agent-card.json/a2a/robotslint_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/a2a/triagetriage_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/a2a/doctorcheck_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/a2a/linthandshake_report, tools_list_report, error_conformance, whoami, example
Discovery and Auth-Posture Probe/a2a/discovery/.well-known/agent-card.json/a2a/discoverydiscovery_report, whoami, example
MCP Endpoint Score Card/a2a/score/.well-known/agent-card.json/a2a/scorescore_card, whoami, example
# 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, 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.

SkillArgumentWhat it answers
whoaminoneWhat 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.
examplenoneThis server's own worked example, run end to end, returning the real answer rather than a description of one.
classify_user_agentuser_agentWhich crawler is behind this raw User-Agent, who runs it, and what blocking it costs.
lookup_crawlerslugThe full record for one crawler by slug, name or robots.txt token.
list_crawlersq, category, operatorThe 150 crawlers, filtered.
generate_robots_txtstanceA ready-to-paste robots.txt for one of 8 stances.
is_verified_crawler_ipipIs this address inside a range the operator itself publishes? 1984 IPv4 and 1062 IPv6 prefixes.
whats_changedsinceBuild 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, /openapi.json and /mcp — pick whichever your client speaks.