{
 "what": "Every A2A skill on this host as a complete request you can send unedited.",
 "protocol": "A2A (Agent2Agent) — JSON-RPC 2.0 over HTTP POST",
 "protocolVersions": [
  "1.0",
  "0.3"
 ],
 "specification": "https://a2a-protocol.org/latest/specification/",
 "howToUse": "Pick a skill, POST its `send` object to its `endpoint` with content-type: application/json. That is the whole procedure. There is no key, no signup, no quota and no session to open first.",
 "whatComesBack": "A Task already in state `completed`, in the same HTTP response. The answer is in status.message.parts (text, and JSON in a DataPart) and mirrored into one artifact. You do not have to poll, subscribe or send tasks/get — there is nothing left to wait for. If you do send tasks/get with the id you were given, you get the same task back: the id encodes the call, and this host keeps no task store.",
 "methodNames": {
  "message/send": "invokes a skill (A2A v0.3 name). This is the one you want.",
  "SendMessage": "the A2A v1.0 name for the same method; both are accepted here.",
  "tasks/get": "returns a task minted here, by re-running the call its id encodes. An id this host did not mint returns -32001, because no task was ever created for it — send message/send instead.",
  "message/stream": "refused with -32004. Nothing here streams; every answer is synchronous."
 },
 "ifYouHaveNothingToHand": "Send the `whoami` skill on any endpoint (16 of the skills below need no arguments at all). It answers about YOU: the user-agent you sent, the address you came from, the class this host's 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 — the subject of the call is the call.",
 "sameSkillsOverMcp": "Every skill below is also an MCP tool at the `mcpTwin` address, called with tools/call. Both doors run the same function: surfaces/pathwren-edge/test/a2a_two_doors_test.mjs compares them on every deploy.",
 "independent": "An independent, non-commercial automated project: it is run by software rather than by a person, and it says so wherever it introduces itself. It is not affiliated with, endorsed by or operated by any of the crawler operators it documents, nor by any other company. The category and cost-of-blocking fields are its own assessment and are labelled as such; every other field is cited to the operator's own documentation.",
 "endpoints": [
  {
   "endpoint": "https://www.pathwren.workers.dev/a2a",
   "agentCard": "https://www.pathwren.workers.dev/.well-known/agent-card.json",
   "mcpTwin": "https://www.pathwren.workers.dev/mcp",
   "title": "AI Crawler Index",
   "skills": [
    {
     "skill": "classify_user_agent",
     "needsNoArguments": false,
     "what": "Identify the crawler behind a raw User-Agent header: operator, category, robots.txt stance, how to verify it, and what blocking it costs. A user-agent is a claim, not proof — confirm with is_verified_crawler_ip",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"classify_user_agent\",\"user_agent\":\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\"}"
         }
        ]
       }
      }
     },
     "curl": "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\\\":\\\"classify_user_agent\\\",\\\"user_agent\\\":\\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\"}\"}]}}}'"
    },
    {
     "skill": "lookup_crawler",
     "needsNoArguments": false,
     "what": "The full index record for one crawler: operator, category, robots.txt token and stance, user-agent substring and example, verification method, mirrored IP-range endpoint, and what blocking it costs. An unknown slug returns near matches",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"lookup_crawler\",\"slug\":\"claudebot\"}"
         }
        ]
       }
      }
     },
     "curl": "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\\\":\\\"lookup_crawler\\\",\\\"slug\\\":\\\"claudebot\\\"}\"}]}}}'"
    },
    {
     "skill": "list_crawlers",
     "needsNoArguments": false,
     "what": "The index, filtered or whole: each row says what the crawler is and what blocking it costs, and the reply lists every valid filter value",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"list_crawlers\",\"category\":\"ai-training\",\"limit\":20}"
         }
        ]
       }
      }
     },
     "curl": "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\\\":\\\"list_crawlers\\\",\\\"category\\\":\\\"ai-training\\\",\\\"limit\\\":20}\"}]}}}'"
    },
    {
     "skill": "generate_robots_txt",
     "needsNoArguments": false,
     "what": "A ready-to-paste robots.txt block for one stance, with the reasoning and the crawlers it names. Omit the argument to get all eight stances described",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"generate_robots_txt\",\"stance\":\"block-ai-training\"}"
         }
        ]
       }
      }
     },
     "curl": "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\\\":\\\"generate_robots_txt\\\",\\\"stance\\\":\\\"block-ai-training\\\"}\"}]}}}'"
    },
    {
     "skill": "is_verified_crawler_ip",
     "needsNoArguments": false,
     "what": "Test an IPv4 or IPv6 address against every crawler prefix the operators themselves publish, remirrored every six hours. Returns the matching prefix, its source and the crawlers using it; a miss is reported as a miss, not as a forgery",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"is_verified_crawler_ip\",\"ip\":\"20.171.206.5\"}"
         }
        ]
       }
      }
     },
     "curl": "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\\\":\\\"is_verified_crawler_ip\\\",\\\"ip\\\":\\\"20.171.206.5\\\"}\"}]}}}'"
    },
    {
     "skill": "whats_changed",
     "needsNoArguments": false,
     "what": "Freshness and change state: when the index was built, when each operator source was last fetched, which changed, which are failing, and the dated changelog. The cron check before regenerating a config from this data",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"whats_changed\",\"since\":\"2026-08-01\"}"
         }
        ]
       }
      }
     },
     "curl": "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\\\":\\\"whats_changed\\\",\\\"since\\\":\\\"2026-08-01\\\"}\"}]}}}'"
    },
    {
     "skill": "changes_since",
     "needsNoArguments": false,
     "what": "Only what changed since your last call: prefixes added or removed, upstreams failed or recovered, records edited. Send back the `cursor` from the previous result; it advances only on a real change, and the data refreshes every 6h",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"changes_since\",\"since\":\"0\"}"
         }
        ]
       }
      }
     },
     "curl": "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\\\":\\\"changes_since\\\",\\\"since\\\":\\\"0\\\"}\"}]}}}'"
    },
    {
     "skill": "whoami",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Classifies the request you just sent: the user-agent you claim, the address you came from, the class this host's own instrument books you as, whether we have seen you here before and what you fetched, and what this host's robots policy says about you. Every fact comes from the headers on your own request or from a file this host already publishes — nothing is fetched, nothing about you is invented, no argument exists",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"whoami\"}"
         }
        ]
       }
      }
     },
     "curl": "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\\\"}\"}]}}}'"
    },
    {
     "skill": "example",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Runs this server's own worked example end to end — one of its real tools, on a canned input taken from this host's own published data — and returns exactly the structuredContent a real call returns, not a mock and not a description of one. Use it to see the shape of an answer before you decide what to send. No URL of yours is fetched and no third party is touched",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"example\"}"
         }
        ]
       }
      }
     },
     "curl": "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\\\":\\\"example\\\"}\"}]}}}'"
    }
   ]
  },
  {
   "endpoint": "https://www.pathwren.workers.dev/a2a/netcheck",
   "agentCard": "https://www.pathwren.workers.dev/a2a/netcheck/.well-known/agent-card.json",
   "mcpTwin": "https://www.pathwren.workers.dev/mcp/netcheck",
   "title": "Crawler IP Verifier",
   "skills": [
    {
     "skill": "verify_batch",
     "needsNoArguments": false,
     "what": "Check up to 500 addresses against every mirrored operator prefix list in one call. Returns, per address, the matching prefix, the source that published it and when it was mirrored, plus a rollup by operator. Accepts {ip, claim} pairs to test a claimed identity against the ranges, and says plainly that a miss is not evidence of a fake",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"verify_batch\",\"addresses\":[\"20.171.206.5\",\"66.249.66.1\",\"203.0.113.9\"]}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/netcheck -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"verify_batch\\\",\\\"addresses\\\":[\\\"20.171.206.5\\\",\\\"66.249.66.1\\\",\\\"203.0.113.9\\\"]}\"}]}}}'"
    },
    {
     "skill": "lookup_prefix",
     "needsNoArguments": false,
     "what": "Give a CIDR and get every published operator prefix that contains it, is contained by it, or partially overlaps it — the check for 'does my network collide with a crawler range' and for auditing an allowlist somebody handed you. Give an operator or source slug instead and get everything that source publishes",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"lookup_prefix\",\"cidr\":\"66.249.64.0/19\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/netcheck -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"lookup_prefix\\\",\\\"cidr\\\":\\\"66.249.64.0/19\\\"}\"}]}}}'"
    },
    {
     "skill": "export_ip_acl",
     "needsNoArguments": false,
     "what": "Turn a set of operators into a config you can paste: nginx geo, nginx allow/deny, Apache, HAProxy, a Cloudflare firewall expression, an ipset script, a Caddy matcher, or a plain CIDR list. Every export carries a provenance header naming each source URL and the mirror time, and reports the rule cost",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"export_ip_acl\",\"operators\":[\"openai\"],\"format\":\"nginx-allow-deny\",\"action\":\"allow\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/netcheck -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"export_ip_acl\\\",\\\"operators\\\":[\\\"openai\\\"],\\\"format\\\":\\\"nginx-allow-deny\\\",\\\"action\\\":\\\"allow\\\"}\"}]}}}'"
    },
    {
     "skill": "verification_methods",
     "needsNoArguments": false,
     "what": "Per crawler: whether the operator publishes IP ranges, documents reverse DNS, or publishes no verification method at all — with the exact source URL or the exact dig commands, and how fresh this mirror is. Call it before reading anything into an address that matched nothing. Reverse DNS is never run here; the command is handed back instead",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"verification_methods\",\"crawler\":\"gptbot\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/netcheck -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"verification_methods\\\",\\\"crawler\\\":\\\"gptbot\\\"}\"}]}}}'"
    },
    {
     "skill": "range_stats",
     "needsNoArguments": false,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Per source: prefix counts, total addresses and /24-equivalents, smallest and largest prefix, the publishing URL and when it was last fetched; plus prefixes published by more than one operator. This is the sizing and freshness information an allowlist decision needs",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"range_stats\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/netcheck -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"range_stats\\\"}\"}]}}}'"
    },
    {
     "skill": "whoami",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Classifies the request you just sent: the user-agent you claim, the address you came from, the class this host's own instrument books you as, whether we have seen you here before and what you fetched, and what this host's robots policy says about you. Every fact comes from the headers on your own request or from a file this host already publishes — nothing is fetched, nothing about you is invented, no argument exists",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"whoami\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/netcheck -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\\\"}\"}]}}}'"
    },
    {
     "skill": "example",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Runs this server's own worked example end to end — one of its real tools, on a canned input taken from this host's own published data — and returns exactly the structuredContent a real call returns, not a mock and not a description of one. Use it to see the shape of an answer before you decide what to send. No URL of yours is fetched and no third party is touched",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"example\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/netcheck -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"example\\\"}\"}]}}}'"
    }
   ]
  },
  {
   "endpoint": "https://www.pathwren.workers.dev/a2a/robots",
   "agentCard": "https://www.pathwren.workers.dev/a2a/robots/.well-known/agent-card.json",
   "mcpTwin": "https://www.pathwren.workers.dev/mcp/robots",
   "title": "robots.txt Policy Lint",
   "skills": [
    {
     "skill": "lint_robots_txt",
     "needsNoArguments": false,
     "what": "Parse a robots.txt you paste and report every fault that makes it do something other than what it looks like: misspelled directives, a full UA string where a product token belongs, rules before any User-agent line, duplicate groups, noindex (unsupported since 2019), relative Sitemap URLs, BOM. Each finding carries the line number and the fix",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"lint_robots_txt\",\"robots_txt\":\"User-agent: GPTBot\\nDisallow: /\\n\\nUser-agent: *\\nAllow: /\\n\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/robots -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"lint_robots_txt\\\",\\\"robots_txt\\\":\\\"User-agent: GPTBot\\\\nDisallow: /\\\\n\\\\nUser-agent: *\\\\nAllow: /\\\\n\\\"}\"}]}}}'"
    },
    {
     "skill": "check_path_allowed",
     "needsNoArguments": false,
     "what": "Evaluate a pasted robots.txt for one crawler and one or more paths under RFC 9309: longest token match for the group, longest path pattern for the rule, Allow breaking a tie, * and $ supported. Returns allowed/disallowed per path with the exact line that decided it, and flags the cases where a merge-groups parser and a first-group-wins parser would disagree",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"check_path_allowed\",\"robots_txt\":\"User-agent: GPTBot\\nDisallow: /\\n\\nUser-agent: *\\nAllow: /\\n\",\"user_agent\":\"GPTBot\",\"paths\":[\"/docs\",\"/\"]}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/robots -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"check_path_allowed\\\",\\\"robots_txt\\\":\\\"User-agent: GPTBot\\\\nDisallow: /\\\\n\\\\nUser-agent: *\\\\nAllow: /\\\\n\\\",\\\"user_agent\\\":\\\"GPTBot\\\",\\\"paths\\\":[\\\"/docs\\\",\\\"/\\\"]}\"}]}}}'"
    },
    {
     "skill": "audit_ai_access",
     "needsNoArguments": false,
     "what": "Evaluate a pasted robots.txt against every AI crawler in this index and return the two lists that matter: blocked and allowed, per operator and category. Also names the tokens in your file that match no known crawler (a typo blocks nothing) and separates the crawlers that document obedience from the ones observed ignoring robots.txt, which need an IP or WAF rule instead",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"audit_ai_access\",\"robots_txt\":\"User-agent: GPTBot\\nDisallow: /\\n\\nUser-agent: *\\nAllow: /\\n\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/robots -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"audit_ai_access\\\",\\\"robots_txt\\\":\\\"User-agent: GPTBot\\\\nDisallow: /\\\\n\\\\nUser-agent: *\\\\nAllow: /\\\\n\\\"}\"}]}}}'"
    },
    {
     "skill": "diff_robots_txt",
     "needsNoArguments": false,
     "what": "Compare two versions of a robots.txt and report only the crawlers whose verdict actually changes at a given path — not the text difference. Answers 'did my edit do what I meant, and did it do anything else', including sitemap additions and whether the parse errors went up or down",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"diff_robots_txt\",\"before\":\"User-agent: *\\nDisallow: /\",\"after\":\"User-agent: GPTBot\\nDisallow: /\\n\\nUser-agent: *\\nAllow: /\\n\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/robots -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"diff_robots_txt\\\",\\\"before\\\":\\\"User-agent: *\\\\nDisallow: /\\\",\\\"after\\\":\\\"User-agent: GPTBot\\\\nDisallow: /\\\\n\\\\nUser-agent: *\\\\nAllow: /\\\\n\\\"}\"}]}}}'"
    },
    {
     "skill": "merge_policy",
     "needsNoArguments": false,
     "what": "Merge one of eight maintained robots.txt stances (block-ai-training, allow-ai-search-only, block-all-ai, block-datasets, block-disputed, block-seo-tools, allow-all, maximum-ai-visibility) into a robots.txt you already have, without touching a single rule you wrote: a token you already name keeps your rules and the stance's version is reported instead of applied",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"merge_policy\",\"robots_txt\":\"User-agent: GPTBot\\nDisallow: /\\n\\nUser-agent: *\\nAllow: /\\n\",\"stance\":\"block-ai-training\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/robots -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"merge_policy\\\",\\\"robots_txt\\\":\\\"User-agent: GPTBot\\\\nDisallow: /\\\\n\\\\nUser-agent: *\\\\nAllow: /\\\\n\\\",\\\"stance\\\":\\\"block-ai-training\\\"}\"}]}}}'"
    },
    {
     "skill": "whoami",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Classifies the request you just sent: the user-agent you claim, the address you came from, the class this host's own instrument books you as, whether we have seen you here before and what you fetched, and what this host's robots policy says about you. Every fact comes from the headers on your own request or from a file this host already publishes — nothing is fetched, nothing about you is invented, no argument exists",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"whoami\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/robots -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\\\"}\"}]}}}'"
    },
    {
     "skill": "example",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Runs this server's own worked example end to end — one of its real tools, on a canned input taken from this host's own published data — and returns exactly the structuredContent a real call returns, not a mock and not a description of one. Use it to see the shape of an answer before you decide what to send. No URL of yours is fetched and no third party is touched",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"example\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/robots -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"example\\\"}\"}]}}}'"
    }
   ]
  },
  {
   "endpoint": "https://www.pathwren.workers.dev/a2a/triage",
   "agentCard": "https://www.pathwren.workers.dev/a2a/triage/.well-known/agent-card.json",
   "mcpTwin": "https://www.pathwren.workers.dev/mcp/triage",
   "title": "Crawler Log Triage",
   "skills": [
    {
     "skill": "triage_log",
     "needsNoArguments": false,
     "what": "Paste log lines — combined, JSON, `uniq -c`, `<ip> <ua>` or bare user-agents, auto-detected — for per-line crawler, operator, purpose and cost of blocking, a rollup by operator and category, and every line whose address contradicts its claim. Log text, never a URL",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"triage_log\",\"log\":\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\"GET /pricing HTTP/1.1\\\" 200 5120 \\\"-\\\" \\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\"\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\"GET /docs HTTP/1.1\\\" 200 1234 \\\"-\\\" \\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\"\",\"detail\":\"summary\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/triage -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"triage_log\\\",\\\"log\\\":\\\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\\\\\"GET /pricing HTTP/1.1\\\\\\\" 200 5120 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\\\\\"\\\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\\\\\"GET /docs HTTP/1.1\\\\\\\" 200 1234 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\\\\\"\\\",\\\"detail\\\":\\\"summary\\\"}\"}]}}}'"
    },
    {
     "skill": "find_impersonators",
     "needsNoArguments": false,
     "what": "Only the lines claiming a crawler whose operator publishes address ranges, from an address in none of to run: this server makes no outbound request",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"find_impersonators\",\"log\":\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\"GET /pricing HTTP/1.1\\\" 200 5120 \\\"-\\\" \\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\"\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\"GET /docs HTTP/1.1\\\" 200 1234 \\\"-\\\" \\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\"\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/triage -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"find_impersonators\\\",\\\"log\\\":\\\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\\\\\"GET /pricing HTTP/1.1\\\\\\\" 200 5120 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\\\\\"\\\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\\\\\"GET /docs HTTP/1.1\\\\\\\" 200 1234 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\\\\\"\\\"}\"}]}}}'"
    },
    {
     "skill": "summarize_by_operator",
     "needsNoArguments": false,
     "what": "Aggregate only: who crawled you, how many requests each, what share, which category, and what blocking each would cost. Eats a `uniq -c` table straight from a shell pipeline",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"summarize_by_operator\",\"log\":\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\"GET /pricing HTTP/1.1\\\" 200 5120 \\\"-\\\" \\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\"\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\"GET /docs HTTP/1.1\\\" 200 1234 \\\"-\\\" \\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\"\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/triage -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"summarize_by_operator\\\",\\\"log\\\":\\\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\\\\\"GET /pricing HTTP/1.1\\\\\\\" 200 5120 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\\\\\"\\\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\\\\\"GET /docs HTTP/1.1\\\\\\\" 200 1234 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\\\\\"\\\"}\"}]}}}'"
    },
    {
     "skill": "robots_from_log",
     "needsNoArguments": false,
     "what": "A robots.txt naming only the crawlers in your log, each with its request count and cost of blocking, plus a warning for any that do not documentably obey it — there the file is a request, not enforcement",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"robots_from_log\",\"log\":\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\"GET /pricing HTTP/1.1\\\" 200 5120 \\\"-\\\" \\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\"\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\"GET /docs HTTP/1.1\\\" 200 1234 \\\"-\\\" \\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\"\",\"stance\":\"block-ai-training\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/triage -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"robots_from_log\\\",\\\"log\\\":\\\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\\\\\"GET /pricing HTTP/1.1\\\\\\\" 200 5120 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\\\\\"\\\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\\\\\"GET /docs HTTP/1.1\\\\\\\" 200 1234 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\\\\\"\\\",\\\"stance\\\":\\\"block-ai-training\\\"}\"}]}}}'"
    },
    {
     "skill": "waf_ruleset_from_log",
     "needsNoArguments": false,
     "what": "nginx, Caddy, Cloudflare, HAProxy or Apache rules for only the crawlers in your log. The reply warns that a UA rule stops only an honest client, and that impersonation is an address problem needing the published prefixes as an allowlist",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"waf_ruleset_from_log\",\"log\":\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\"GET /pricing HTTP/1.1\\\" 200 5120 \\\"-\\\" \\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\"\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\"GET /docs HTTP/1.1\\\" 200 1234 \\\"-\\\" \\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\"\",\"target\":\"nginx\",\"action\":\"block\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/triage -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"waf_ruleset_from_log\\\",\\\"log\\\":\\\"66.249.66.1 - - [01/Sep/2026:06:12:44 +0000] \\\\\\\"GET /pricing HTTP/1.1\\\\\\\" 200 5120 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)\\\\\\\"\\\\n20.171.206.5 - - [01/Sep/2026:06:12:45 +0000] \\\\\\\"GET /docs HTTP/1.1\\\\\\\" 200 1234 \\\\\\\"-\\\\\\\" \\\\\\\"Mozilla/5.0 (compatible; GPTBot/1.2; +https://openai.com/gptbot)\\\\\\\"\\\",\\\"target\\\":\\\"nginx\\\",\\\"action\\\":\\\"block\\\"}\"}]}}}'"
    },
    {
     "skill": "whoami",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Classifies the request you just sent: the user-agent you claim, the address you came from, the class this host's own instrument books you as, whether we have seen you here before and what you fetched, and what this host's robots policy says about you. Every fact comes from the headers on your own request or from a file this host already publishes — nothing is fetched, nothing about you is invented, no argument exists",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"whoami\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/triage -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\\\"}\"}]}}}'"
    },
    {
     "skill": "example",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Runs this server's own worked example end to end — one of its real tools, on a canned input taken from this host's own published data — and returns exactly the structuredContent a real call returns, not a mock and not a description of one. Use it to see the shape of an answer before you decide what to send. No URL of yours is fetched and no third party is touched",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"example\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/triage -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"example\\\"}\"}]}}}'"
    }
   ]
  },
  {
   "endpoint": "https://www.pathwren.workers.dev/a2a/doctor",
   "agentCard": "https://www.pathwren.workers.dev/a2a/doctor/.well-known/agent-card.json",
   "mcpTwin": "https://www.pathwren.workers.dev/mcp/doctor",
   "title": "Agent Discovery Doctor",
   "skills": [
    {
     "skill": "check_discovery_documents",
     "needsNoArguments": false,
     "what": "Probes 22 documents agents and trust indexes ask for — llms.txt, agent card, owners.json, oauth metadata, mcp.json, apis.json, openapi, robots, sitemap — as served, missing, gated or 200-with-HTML soft-404, and says who asks for each missing one. Refuses private, ephemeral and its own hosts",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"check_discovery_documents\",\"host\":\"example.com\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/doctor -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"check_discovery_documents\\\",\\\"host\\\":\\\"example.com\\\"}\"}]}}}'"
    },
    {
     "skill": "explain_document",
     "needsNoArguments": false,
     "what": "One catalogue entry: what the document is for, the named clients observed asking this host for it with dates and the status they took, what a 404 costs, and the spec URL. No argument lists all 22",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"explain_document\",\"name\":\"llms.txt\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/doctor -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"explain_document\\\",\\\"name\\\":\\\"llms.txt\\\"}\"}]}}}'"
    },
    {
     "skill": "validate_llms_txt",
     "needsNoArguments": false,
     "what": "Checks pasted llms.txt against the format: one H1, a blockquote summary, H2 sections of `- [name](url): notes`. Errors and warnings with line numbers and fixes, plus the parsed links. Text in, nothing fetched",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"validate_llms_txt\",\"text\":\"# Example\\n\\n> One line about the site.\\n\\n## Docs\\n\\n- [API](https://example.com/api.md): the API\\n\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/doctor -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"validate_llms_txt\\\",\\\"text\\\":\\\"# Example\\\\n\\\\n> One line about the site.\\\\n\\\\n## Docs\\\\n\\\\n- [API](https://example.com/api.md): the API\\\\n\\\"}\"}]}}}'"
    },
    {
     "skill": "llms_txt_from_sitemap",
     "needsNoArguments": false,
     "what": "Paste sitemap.xml, or one URL per line, and get a draft llms.txt: URLs grouped into H2 sections by path, titles from slugs, lastmod kept, and a TODO wherever only you can write the sentence. A sitemap index is reported as one",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"llms_txt_from_sitemap\",\"xml\":\"<?xml version=\\\"1.0\\\"?><urlset><url><loc>https://example.com/</loc></url></urlset>\",\"title\":\"Example\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/doctor -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"llms_txt_from_sitemap\\\",\\\"xml\\\":\\\"<?xml version=\\\\\\\"1.0\\\\\\\"?><urlset><url><loc>https://example.com/</loc></url></urlset>\\\",\\\"title\\\":\\\"Example\\\"}\"}]}}}'"
    },
    {
     "skill": "validate_agent_card",
     "needsNoArguments": false,
     "what": "Validates a pasted /.well-known/agent-card.json against the nine fields A2A marks required and each skill's id/name/description/tags, and warns on capabilities declared true that a reader will then try",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"validate_agent_card\",\"json\":\"{\\\"name\\\":\\\"Demo\\\",\\\"description\\\":\\\"d\\\",\\\"url\\\":\\\"https://example.com/a2a\\\",\\\"version\\\":\\\"1.0.0\\\",\\\"skills\\\":[]}\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/doctor -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"validate_agent_card\\\",\\\"json\\\":\\\"{\\\\\\\"name\\\\\\\":\\\\\\\"Demo\\\\\\\",\\\\\\\"description\\\\\\\":\\\\\\\"d\\\\\\\",\\\\\\\"url\\\\\\\":\\\\\\\"https://example.com/a2a\\\\\\\",\\\\\\\"version\\\\\\\":\\\\\\\"1.0.0\\\\\\\",\\\\\\\"skills\\\\\\\":[]}\\\"}\"}]}}}'"
    },
    {
     "skill": "whoami",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Classifies the request you just sent: the user-agent you claim, the address you came from, the class this host's own instrument books you as, whether we have seen you here before and what you fetched, and what this host's robots policy says about you. Every fact comes from the headers on your own request or from a file this host already publishes — nothing is fetched, nothing about you is invented, no argument exists",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"whoami\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/doctor -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\\\"}\"}]}}}'"
    },
    {
     "skill": "example",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Runs this server's own worked example end to end — one of its real tools, on a canned input taken from this host's own published data — and returns exactly the structuredContent a real call returns, not a mock and not a description of one. Use it to see the shape of an answer before you decide what to send. No URL of yours is fetched and no third party is touched",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"example\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/doctor -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"example\\\"}\"}]}}}'"
    }
   ]
  },
  {
   "endpoint": "https://www.pathwren.workers.dev/a2a/lint",
   "agentCard": "https://www.pathwren.workers.dev/a2a/lint/.well-known/agent-card.json",
   "mcpTwin": "https://www.pathwren.workers.dev/mcp/lint",
   "title": "MCP Endpoint Conformance",
   "skills": [
    {
     "skill": "handshake_report",
     "needsNoArguments": false,
     "what": "POST initialize to an MCP endpoint you name and report what came back: the protocol version it negotiated against the one you asked for, the capabilities it advertises, serverInfo, timing, the transport shape (JSON or SSE frame, session id, content-type), and — sent a second time, byte for byte — whether the server answers an identical initialize the same way. Also asks for a version nobody publishes, to see whether it negotiates down or agrees to anything. Makes 3 requests, 6 s timeout each, user-agent",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"handshake_report\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/lint -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"handshake_report\\\"}\"}]}}}'"
    },
    {
     "skill": "tools_list_report",
     "needsNoArguments": false,
     "what": "Handshake, then tools/list, then check every tool it returns: a missing or empty description, a description too short to choose on, a missing inputSchema, an inputSchema that is not an object schema, JSON-Schema faults (an invalid type keyword, a `required` naming a property that is not in `properties`, a pattern that will not compile, an empty enum), names that break the character rule, and names that collide — exactly, or once case is ignored. Each finding names the tool and says what breaks. Makes 3 requests, 6 s timeout each",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"tools_list_report\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/lint -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"tools_list_report\\\"}\"}]}}}'"
    },
    {
     "skill": "error_conformance",
     "needsNoArguments": false,
     "what": "Send five things a real client eventually sends by accident and check what comes back: an unknown method (expects -32601), tools/call naming a tool that does not exist (expects -32602/-32601 or a result with isError), tools/call with no tool name (expects -32602), a body that is not JSON (expects -32700), and a body missing \"jsonrpc\":\"2.0\" (expects -32600). Reports the HTTP status and the error code side by side, and flags an HTML error page or a 5xx where a JSON-RPC error belongs — the failure that makes a client report the wrong cause. Makes 5 requests, 6 s each",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"error_conformance\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/lint -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"error_conformance\\\"}\"}]}}}'"
    },
    {
     "skill": "whoami",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Classifies the request you just sent: the user-agent you claim, the address you came from, the class this host's own instrument books you as, whether we have seen you here before and what you fetched, and what this host's robots policy says about you. Every fact comes from the headers on your own request or from a file this host already publishes — nothing is fetched, nothing about you is invented, no argument exists",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"whoami\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/lint -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\\\"}\"}]}}}'"
    },
    {
     "skill": "example",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Runs this server's own worked example end to end — one of its real tools, on a canned input taken from this host's own published data — and returns exactly the structuredContent a real call returns, not a mock and not a description of one. Use it to see the shape of an answer before you decide what to send. No URL of yours is fetched and no third party is touched",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"example\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/lint -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"example\\\"}\"}]}}}'"
    }
   ]
  },
  {
   "endpoint": "https://www.pathwren.workers.dev/a2a/discovery",
   "agentCard": "https://www.pathwren.workers.dev/a2a/discovery/.well-known/agent-card.json",
   "mcpTwin": "https://www.pathwren.workers.dev/mcp/lint",
   "title": "Discovery and Auth-Posture Probe",
   "skills": [
    {
     "skill": "discovery_report",
     "needsNoArguments": false,
     "what": "GET the documents an MCP client reads BEFORE the handshake and report what each one answered: /.well-known/oauth-protected-resource in BOTH forms — the root form everyone publishes and the RFC 9728 §3.1 insertion form a spec-following client actually requests for a resource served under a path — /.well-known/oauth-authorization-server, /.well-known/mcp, /.well-known/mcp.json, /mcp.json and /llms.txt. Each result carries the status, the verdict (served, missing, gated, soft-404 — a 200 carrying an HTML error page — or invalid JSON) and what a client does with that document. Makes one GET per document, 6 s each",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"discovery_report\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/discovery -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"discovery_report\\\"}\"}]}}}'"
    },
    {
     "skill": "whoami",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Classifies the request you just sent: the user-agent you claim, the address you came from, the class this host's own instrument books you as, whether we have seen you here before and what you fetched, and what this host's robots policy says about you. Every fact comes from the headers on your own request or from a file this host already publishes — nothing is fetched, nothing about you is invented, no argument exists",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"whoami\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/discovery -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\\\"}\"}]}}}'"
    },
    {
     "skill": "example",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Runs this server's own worked example end to end — one of its real tools, on a canned input taken from this host's own published data — and returns exactly the structuredContent a real call returns, not a mock and not a description of one. Use it to see the shape of an answer before you decide what to send. No URL of yours is fetched and no third party is touched",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"example\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/discovery -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"example\\\"}\"}]}}}'"
    }
   ]
  },
  {
   "endpoint": "https://www.pathwren.workers.dev/a2a/score",
   "agentCard": "https://www.pathwren.workers.dev/a2a/score/.well-known/agent-card.json",
   "mcpTwin": "https://www.pathwren.workers.dev/mcp/lint",
   "title": "MCP Endpoint Score Card",
   "skills": [
    {
     "skill": "score_card",
     "needsNoArguments": false,
     "what": "Run handshake_report, tools_list_report, error_conformance and discovery_report against one endpoint and return a single verdict: a score out of 100 (handshake 30, tool schemas 30, error conformance 25, discovery 15), a letter grade, every finding by severity with the section it came from, and the full detail of each section underneath. This is the tool to call from a monitor: the score is stable enough to alert on and the findings say what to fix. Makes up to 19 requests to the URL you give it, 6 s each, and is rate-limited per caller and per target host",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"score_card\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/score -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"score_card\\\"}\"}]}}}'"
    },
    {
     "skill": "whoami",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Classifies the request you just sent: the user-agent you claim, the address you came from, the class this host's own instrument books you as, whether we have seen you here before and what you fetched, and what this host's robots policy says about you. Every fact comes from the headers on your own request or from a file this host already publishes — nothing is fetched, nothing about you is invented, no argument exists",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"whoami\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/score -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\\\"}\"}]}}}'"
    },
    {
     "skill": "example",
     "needsNoArguments": true,
     "what": "Takes no arguments. Safe to call. Deterministic. Touches no third party. Runs this server's own worked example end to end — one of its real tools, on a canned input taken from this host's own published data — and returns exactly the structuredContent a real call returns, not a mock and not a description of one. Use it to see the shape of an answer before you decide what to send. No URL of yours is fetched and no third party is touched",
     "send": {
      "jsonrpc": "2.0",
      "id": 1,
      "method": "message/send",
      "params": {
       "message": {
        "role": "ROLE_USER",
        "messageId": "1",
        "parts": [
         {
          "text": "{\"skill\":\"example\"}"
         }
        ]
       }
      }
     },
     "curl": "curl -s https://www.pathwren.workers.dev/a2a/score -H 'content-type: application/json' -d '{\"jsonrpc\":\"2.0\",\"id\":1,\"method\":\"message/send\",\"params\":{\"message\":{\"role\":\"ROLE_USER\",\"messageId\":\"1\",\"parts\":[{\"text\":\"{\\\"skill\\\":\\\"example\\\"}\"}]}}}'"
    }
   ]
  }
 ]
}