---
key: tools
path: /tools
section: tools
priority: 0.8
title: Agent tools and badge
description: The two free MCP tools an agent calls before paying an x402 endpoint (lookup_verdict and endpoint_status), the badge embed with its three states, and the verification-keys path. Every one keeps working when no verdict is available.
tool_lookup_verdict: Use this when you need the full picture on an x402 endpoint before you pay it or recommend it. It tells you whether a verified operator backed by a guarantee deposit stands behind the endpoint, the assurance grade, when the verdict was last re-checked, whether that re-check sits inside its promised cadence, and whether the signature checks locally. Pass chain, payTo and resourceUrl from the 402 response. An unknown result is normal: carry on under your own policy.
tool_endpoint_status: Use this for a quick routing decision before paying, when one word per endpoint is enough: human-backed, revoked or unknown. Call it once per candidate endpoint with chain, payTo and resourceUrl from its 402 response. Prefer human-backed, avoid revoked, and read unknown as the absence of a signal, never as a failure; what you do with unknown endpoints stays your decision. Call lookup_verdict when you need the grade, the re-check time or the signature result.
---

# Agent tools and badge

These are the public tools around the free verification path: two tools an
agent calls before it pays, a badge you embed on any page, and the path that
publishes the keys verdicts are signed with. None of them carries a charge,
none needs an account, and every one keeps working when no verdict is
available: the answer is `unknown` and nothing blocks.

## MCP server

The Model Context Protocol server is built in the Apache-2.0 tools repository,
next to the copy-in snippets. It gives an agent harness the free verification
path as two tools, so the agent can check an x402 endpoint before paying it.

- **Transport.** JSON-RPC 2.0 over stdio, one message per line (the standard
  MCP stdio transport), protocol revision `2025-06-18`. Your MCP client starts
  the server as a local process.
- **Methods.** `initialize`, `tools/list`, `tools/call` and `ping`.
- **Dependencies.** None at runtime. The server reuses the verdict snippet for
  fetching, freshness and the local signature check.
- **Configuration.** Two optional environment variables.

| Variable | Meaning | When unset |
| --- | --- | --- |
| `VERIFICATION_BASE_URL` | Base URL of the free verification path | Every lookup answers `unknown` with outcome `no_service`; the server still answers |
| `VERIFICATION_PUBLIC_KEY` | Verifier public key, base64 (see [verification keys](#verification-keys)) | The signature is reported as `not_checked` |

### `lookup_verdict`

**When to use this.** Use this when you need the full picture on an x402 endpoint before you pay it or recommend it. It tells you whether a verified operator backed by a guarantee deposit stands behind the endpoint, the assurance grade, when the verdict was last re-checked, whether that re-check sits inside its promised cadence, and whether the signature checks locally. Pass chain, payTo and resourceUrl from the 402 response. An unknown result is normal: carry on under your own policy.

Input: the endpoint the payment would unlock. All three fields are required
strings; no other field is accepted.

```json
{
  "type": "object",
  "properties": {
    "chain": { "type": "string", "description": "Chain identifier, e.g. \"solana\" or \"base\"." },
    "payTo": { "type": "string", "description": "The endpoint's payTo address." },
    "resourceUrl": { "type": "string", "description": "The resource URL the payment unlocks." }
  },
  "required": ["chain", "payTo", "resourceUrl"],
  "additionalProperties": false
}
```

Output: a text line for the model to read and the same signal as structured
content.

```text
Verification: human-backed; outcome human_backed; freshness fresh; assurance G; last re-checked 2026-09-01T08:00:00Z; signature valid.
```

### `endpoint_status`

**When to use this.** Use this for a quick routing decision before paying, when one word per endpoint is enough: human-backed, revoked or unknown. Call it once per candidate endpoint with chain, payTo and resourceUrl from its 402 response. Prefer human-backed, avoid revoked, and read unknown as the absence of a signal, never as a failure; what you do with unknown endpoints stays your decision. Call lookup_verdict when you need the grade, the re-check time or the signature result.

Input: the same schema as `lookup_verdict` (`chain`, `payTo`, `resourceUrl`,
all required, nothing else).

Output: one compact text line, `Verification signal: human-backed.` (or
`revoked`, or `unknown`), with the same structured content as
`lookup_verdict`.

### The structured result

Both tools return this object as `structuredContent`, with `isError: false`.

| Field | Values | Meaning |
| --- | --- | --- |
| `state` | `human-backed`, `revoked`, `unknown` | The routing signal. Only a fresh positive verdict whose signature is not invalid reads `human-backed` |
| `outcome` | `human_backed`, `revoked`, `stale`, `no_signal`, `no_service`, `no_response` | The verdict's wire outcome, or why none arrived |
| `freshness` | `fresh`, `overdue`, `unknown` | Last re-check measured against the cadence the verdict promises |
| `signature` | `valid`, `invalid`, `unverifiable`, `not_checked` | The local Ed25519 check over the canonical payload |
| `assuranceLevel` | for example `G` | Assurance grade of a positive claim, when present |
| `verifiedAt` | RFC 3339 time | Last re-check, when present |
| `recheckEveryHours` | integer | The cadence promise the verdict carries, when a verdict arrived |

A missing service URL, an unreachable service, a timeout or an absent verdict
all resolve to `state: "unknown"`, never to an error. The only error result
is a call without the three required strings: it comes back with
`isError: true` and a line naming the missing arguments.

## Badge embed

The badge is a copy-in snippet that renders the verdict for one x402 endpoint
on any page: a seller's site, an explorer listing, a dashboard. You give it a
container element, the base URL of the free path, the endpoint (`chain`,
`payTo`, `resourceUrl`), and optionally the verifier public key and a timeout
(3000 ms by default). It fetches the verdict, checks it locally and renders
one small inline element.

It reads one of three words.

| Badge | Snippet state | When |
| --- | --- | --- |
| verified | `human-backed` | The verdict is `human_backed`, and its signature does not fail the local check. The label carries the assurance grade |
| not verified | `revoked` | The verdict is `revoked`: the attestation was withdrawn or lapsed past its renewal deadline |
| unknown | `unknown` | The verdict is `stale` or `no_signal`, no verdict arrived, or a positive claim failed the signature check |

The hover text states when the verdict was verified and its cadence promise
("re-checked every N h"), and flags a re-check that is overdue. With no
verdict it says that nothing in the flow depends on it.

**Graceful degradation.** The badge always renders. When the service is
unreachable, when there is no verdict or when the signature check fails, it
reads unknown and nothing else on the page is affected. The embed resolves to
the state it rendered and never rejects. When the runtime cannot check
signatures, the verdict shows as delivered.

## Verification keys

`GET /v0/verification-keys` publishes the Ed25519 public keys verdict
signatures are checked against. It is free, needs no authentication and is
cacheable.

```json
{
  "keys": [
    {
      "keyId": "3f9a1c07b2e4d856",
      "algorithm": "Ed25519",
      "publicKey": "<raw 32-byte public key, base64>",
      "status": "current"
    }
  ]
}
```

| Field | Required | Meaning |
| --- | --- | --- |
| `keyId` | yes | First 8 bytes of the key's SHA-256, hex. Matches the `keyId` a verdict carries |
| `algorithm` | yes | Always `Ed25519` |
| `publicKey` | yes | Raw 32-byte Ed25519 public key, base64 |
| `status` | no | `current` signs new verdicts; `previous` is a key a rotation retired, kept published for at least the re-check window so verdicts signed before the rotation keep verifying |

Select the key by `keyId`, never by its position in the list. A consumer
without the key keeps working: a signature it cannot check reads
`unverifiable`, never an error.

## Published metrics

`GET /v0/metrics` publishes the adoption series the service computes from
its own records: sellers attested (cumulative, active, and outside the
operator's related-party circle), 90-day retention as a ratio, verifications
served on the free path, independent registered verifiers, and revenue as
context. Free, needs no authentication, cacheable; complete months only,
every point dated `YYYY-MM`. The report and every series carry
`relatedParty: true`: the operator runs a related-party pilot, and nothing
measured on it counts as independent adoption. A series the records hold no
source for answers `available: false` with the reason instead of a figure.
Counts and ratios only — no identifier, no endpoint, nothing personal, and
no central record of individual verifications exists behind it.

```json
{
  "schema": "published-metrics/v1",
  "asOf": "2026-08-31",
  "period": { "from": "2026-05", "to": "2026-08" },
  "relatedParty": true,
  "operator": { "operator": "CONECTIA group", "relatedParty": true, "disclosure": "…" },
  "series": [
    {
      "id": "sellers_attested",
      "discipline": "registry-based",
      "relatedParty": true,
      "available": true,
      "points": [{ "period": "2026-08", "cumulative": 3, "active": 2, "independent": 0 }]
    },
    {
      "id": "verifications_free_path",
      "discipline": "aggregate",
      "relatedParty": true,
      "available": false,
      "unavailableReason": "…",
      "points": []
    }
  ]
}
```

The [metrics page](/metrics) is built from a committed
snapshot of this read, once a month; the page never fetches, and while no
complete month holds a record it says there is nothing to publish yet.
When the read is unreachable, a consumer treats it as no dataset: nothing
about a verdict or a badge depends on it.

Next: [buyer verification](/docs/verify) describes the path these tools sit
on, and the [SDK reference](/docs/sdk) lists the snippets behind them.
