← nohumans.directory

Check before you pay

Your agent is about to send USDC to a URL. One request first tells you whether that endpoint is live, whether it has ever been paid successfully, and whether it was listed here and later removed. Every snippet below does the same thing — only the syntax changes.

GET https://nohumans.directory/v1/resolve?url=<endpoint>

What you get back

Free, unauthenticated, cached 30s. No account, no key.

MCP clients

If your framework speaks MCP, connect once and the check becomes a tool your agent can call on its own — along with search and full listing detail.

claude mcp add --transport http nohumans https://nohumans.directory/mcp

Tools: find_paid_service (search by need), get_service_details (full record by id), resolve_endpoint (pre-spend check of a URL you already hold) and what_agents_are_asking_for (what agents searched for here, for sellers deciding what to build).

Connect from your client — one server, one URL

The MCP server is https://api.nohumans.directory/mcp: Streamable HTTP, stateless, no key, no session. Pick your client; the config below is exact for each. Nothing to translate.

Add to Cursor Add to VS Code Add to VS Code Insiders

Claude (desktop or web): Settings → Connectors → Add custom connector → paste the URL. Claude Code:

claude mcp add --transport http nohumans https://api.nohumans.directory/mcp

ChatGPT: Settings → Connectors → Developer mode → add MCP server → paste the URL.

Gemini CLI:

gemini mcp add --transport http nohumans https://api.nohumans.directory/mcp

Windsurf (~/.codeium/windsurf/mcp_config.json), Cline, Roo, and any client that reads a mcpServers block:

{ "mcpServers": { "nohumans": { "type": "http", "url": "https://api.nohumans.directory/mcp" } } }

OpenAI Agents SDK (Python):

from agents.mcp import MCPServerStreamableHttp nohumans = MCPServerStreamableHttp(name="nohumans", params={"url": "https://api.nohumans.directory/mcp"})

LangChain / LangGraph (langchain-mcp-adapters):

client = MultiServerMCPClient({"nohumans": {"url": "https://api.nohumans.directory/mcp", "transport": "streamable_http"}})

Not on MCP? Function-calling stacks read /openapi.json; A2A agents read the signed agent card; marketplaces (AgentCash, Poncho, x402scan) already carry the same routes. If your client isn’t here and needs a different line, hello@nohumans.directory — it will be added, not translated.

TypeScript — @x402/fetch (v2)

const check = await fetch(`https://nohumans.directory/v1/resolve?url=${encodeURIComponent(url)}`); const v = check.ok ? await check.json() : { match: "unknown" }; if (v.match === "delisted" || v.detail?.status === "failing") throw new Error("skip: " + v.match); const res = await fetchWithPayment(url); // your existing paid call

TypeScript — x402-fetch / x402-axios (v1)

The v1 client packages are deprecated upstream but still widely installed. One extra reason to check first: a v1 client reads payment terms from the 402 body, so a v2 endpoint that answers with a payment-required header will look broken to it. We record which version each endpoint actually used.

const v = await (await fetch(`https://nohumans.directory/v1/resolve?url=${encodeURIComponent(url)}`)).json().catch(() => ({ match: "unknown" })); if (v.detail?.x402_version === 2) console.warn("v2 endpoint — a v1-only client may not see its terms"); if (v.match === "delisted") return; const res = await fetchWithPay(url); // x402-fetch

Python

import requests, urllib.parse r = requests.get("https://nohumans.directory/v1/resolve", params={"url": target}) v = r.json() if r.ok else {"match": "unknown"} if v["match"] == "delisted" or v.get("detail", {}).get("status") == "failing": raise RuntimeError(f"skip {target}: {v['match']}")

Any language / curl

curl -sG https://nohumans.directory/v1/resolve --data-urlencode "url=$ENDPOINT" | jq '.match, .detail.status, .detail.score'

Paid verdict — one call, $0.005 USDC on Base

Everything above is free and stays free. For a listing you are about to spend real money on, GET /v1/listings/:id/verdict folds the whole record into one word — pay, caution or avoid — with the reasons, by the rule at /methodology#verdict. It is an x402 v2 route: the unpaid call answers 402 with its terms in both the payment-required header and the body, so any v2 client pays it exactly the way it pays the endpoint you are vetting.

import { x402Client, wrapFetchWithPayment } from "@x402/fetch"; import { registerExactEvmScheme } from "@x402/evm/exact/client"; const client = registerExactEvmScheme(new x402Client(), { signer }); // viem account const payFetch = wrapFetchWithPayment(fetch, client); const v = await (await payFetch(`https://nohumans.directory/v1/listings/${id}/verdict`)).json(); if (v.verdict === "avoid") throw new Error(v.reasons.join("; "));

A real answer, 2026-09-05, for a listing with status verified: {"verdict":"caution","reasons":["no successful paid delivery on record from our scout"]} — clean 402 history, stable payTo, price as declared, but we have not yet bought from it ourselves, and the verdict says exactly that. caution on a verified listing is the rule working, not a contradiction; the free record it summarises is the same /v1/listings/:id above. On Coinbase's hosted wallet, awal x402 pay <url> buys the same verdict. Settlement runs through the CDP facilitator; the transaction hash comes back in the payment-response header.

What this does not tell you

Everything here is endpoint behaviour: correct 402s, a live free sample, a stable payment address, real payment volume, and — where we have paid it ourselves — that a real purchase returned valid data at a point in time. None of it verifies who operates the software behind a URL today, and none of it guarantees the content you buy is accurate. A compromised domain that keeps its payment address and returns well-formed responses passes every check here. That is a structural limit of behavioural verification, not a gap we intend to close quietly.

Full field reference: /llms.txt. Questions or a framework we should cover: hello@nohumans.directory

state of the network · methodology · stats · sellers · integrate · terms · privacy