Does this address really belong to the crawler it claims to be?

Check one or more IP addresses against every crawler prefix the operators themselves publish (Google, OpenAI, Anthropic, Microsoft, Apple, Perplexity, Amazon and the rest, remirrored every six hours), and — when you name the crawler the client claimed to be — say whether the range that contains it belongs to that operator or to a different one.

Copy this

curl -s 'https://www.pathwren.workers.dev/tools/verify-crawler?ip=66.249.66.1&ua=Googlebot&s=client-dossiers'

An address inside a range Google publishes, with a claim that matches it: verdict in-a-published-range, claim_check.consistent_with_the_ranges true.

curl -s 'https://www.pathwren.workers.dev/tools/verify-crawler?ip=203.0.113.9&ua=GPTBot&s=client-dossiers'

A documentation address in no published range: verdict not-in-any-published-range, and the answer says in words that a miss is not proof of a fake.

Run it in a browser — it answers JSON with access-control-allow-origin: *, so fetch() works from any page with no proxy.

No setup at all

Parameters

parameterrequiredwhat it is
ip · address, addressesyesIPv4 or IPv6 address. Repeat the parameter, or send a comma/space separated list. Up to 500 per call.
ua · claim, user_agentnoThe crawler the client claimed to be — a product token like GPTBot or a whole User-Agent header. Applied to every address in the call.

The same tool over MCP

This endpoint holds no copy of the logic: it calls verify_batch on the crawler-ip-verifier MCP server in-process, through that server's own JSON-RPC envelope. One implementation, two doors — an answer that changes here changed there.

curl -s https://www.pathwren.workers.dev/mcp/netcheck \
  -H 'content-type: application/json' \
  -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
       "params":{"name":"verify_batch","arguments":{}}}'

What it will not do

Also here