Skip to main content
Glama

ASPERN: counterparty checks for agents

Knock on an endpoint, with your own payment

knock_on_endpoint

KNOCK ON AN x402 ENDPOINT AND GET WHAT IT SERVED. test_purchase beside this walks a buy WITHOUT paying and stops at the quote; its own caveat has always said that only paying and reading the answer establishes what arrives, “which is the half that needs your own wallet”. This is that half, and it is the same capability the web and the plugin have. WITHOUT payment it reads the terms: accepts carries EVERY set of terms the seller published and signable the ones an EIP-3009 wallet can meet, and WHICH ONE TO PAY ON IS YOURS TO CHOOSE. WITH payment we forward the authorisation YOU signed and hand back what the seller served. WE NEVER HOLD YOUR KEY. A SERVED ANSWER MEANS THE SELLER ACCEPTED IT, NOT THAT MONEY SETTLED. A 402 on a knock that CARRIED a payment is reported as rejected, not as a fresh quote, and IT DOES NOT ESTABLISH THAT NOTHING WAS SPENT. settlementState and authorizationState are the fields to read: a presented authorisation stays usable until it expires or its nonce is spent, so signing again with a fresh nonce can be a SECOND payment. We knock only on endpoints already in the x402 catalogue we read, at most one UNPAID handshake a minute per endpoint shared by everybody, and never on our own host: what we sell has one set of terms and one door. The seller’s answer is yours and is not stored. FREE.

Input Schema

NameRequiredDescriptionDefault
fillNoValues for slots the SELLER’s own catalogue URL declares, e.g. `{"doi": "10.1000/xyz"}`. Only declared slots are accepted; a name the template does not contain is REFUSED rather than ignored. Values are percent-encoded and the filled URL is verified to reach the same origin and path shape as the catalogue entry, so a value can never choose the host.
sendNoA JSON body, for the many x402 endpoints that take POST rather than GET.
queryNoQuery parameters to add to the catalogue address, e.g. `{"txid": "4a5e…"}` for an endpoint whose 402 document declares `?txid=`. `inputs` on the unpaid answer names what the SELLER declares; a seller may need one it does not declare, so undeclared names are accepted too. The origin and path stay the catalogue’s and are verified unchanged, a parameter already in the catalogue address is never replaced, values are bounded and refused rather than trimmed, at most ten. Send the SAME values with the paid knock: paying for a call without its input usually buys an error.
paymentNoA finished x402 `exact` payment, base64, as YOUR wallet produced it. Sent to the seller under both `X-PAYMENT` and `PAYMENT-SIGNATURE`, because v1 and v2 sellers read different names. A v2 seller matches on the `accepted` field, which must echo the entry of `accepts` you chose VERBATIM — omit it and the answer is “No matching payment requirements”, which reads like a refusal and is an envelope fault. Omit `payment` entirely to read the terms first. WE NEVER HOLD YOUR KEY and this path cannot: it takes a finished authorisation and carries it, because a seller’s host sends no CORS headers and that failure is indistinguishable from the endpoint being down.
describeNoTrue to include `blocks`, the answer read as a person reads it: tiles, tables, pairs and charts where the shape allows one. Always read as a STRANGER’s payload — no unit is added, no tone inferred, and nothing drawn that would claim their numbers are parts of one whole.
resourceYesThe http(s) endpoint to knock on. It must be one the x402 catalogue already holds; `list_x402_endpoints` finds it. A URL with no scheme is accepted and resolved against the catalogue, so `example.com/api/x` works.

Output Schema

NameRequiredDescriptionDefault
jsonNoWhat was served, parsed, where it was JSON and whole. Theirs, not ours, and not stored by us.
metaNoHow current this answer is and what it was read from: `freshness` and the ages behind it. Present on every answer from this server, whatever the tool.
paidNoWhether an authorisation travelled with this knock. Stated rather than left to be inferred from the outcome.
saysYesWhat happened, in one sentence. On a `rejected` knock it says the seller refused the authorisation AND that this answer does not establish on-chain settlement either way; read `settlementState` for that.
textNoWhat was served as text, where it was not JSON or was cut short at 512 KB.
faultNo`not-evm`, `not-exact`, `no-token-domain` and the rest: why none of the offered terms can be signed. `not-evm` is a real offer on a chain an EVM wallet cannot sign for, which differs from a malformed one.
offerNoThe first signable leg, which is the SELLER’s preference and not a recommendation of ours. Null where none of the terms can be met.
blocksNoPresent only with `describe: true`.
inputsNoWHAT THE SELLER SAYS THE CALL TAKES, from their own 402 document (bazaar `info.input` and its schema in v2, `outputSchema.input` in v1): `method`, and `query` / `body` as `{ name, required, description, example }`. `required` is true only where they say so. NULL WHERE THEY DECLARE NOTHING, which is not “it needs nothing”: some sellers need a value they never declare. Theirs and a claim.
acceptsNoEVERY set of terms the seller offered, unchanged, including the ones no browser or EIP-3009 wallet can meet.
knockedYesFalse where the resource is not in the catalogue we read, which is OUR reach rather than a fault of theirs. Everything below is then absent.
outcomeNo`served` is an answer in hand. `quoting` is 402 with terms we could read and `charging` 402 without. `rejected` is 402 on a knock that CARRIED a payment, which is the seller refusing what you signed and a different fact from the first 402. `refused` is 401 or 403, where payment is not what is being asked for. On `rejected`, `sellerSays` carries their reason in their words, and the answer DOES NOT ESTABLISH THAT NOTHING WAS SPENT: the seller held your authorisation before answering, and a status code does not report what they did with it.
offeringNoWhat the SELLER says this endpoint is and returns: `name`, `description` and `example`, a specimen answer from their own bazaar extension. Theirs and a claim, not a promise of ours.
resourceYesThe endpoint, as the CATALOGUE holds it, read back. A scheme you left off is resolved here.
signableNoThe legs an `exact` EVM wallet can sign, in the seller’s own order, each flattened to what signing needs. `amountRaw` is a STRING in the asset’s smallest unit; `approxUsd` is present ONLY where the seller’s own catalogue entry publishes both figures for the SAME token, since nothing in a payment-requirements document names a token’s decimals. `terms` is their entry VERBATIM, to echo back as `accepted`. A real offer has several (agent402.tools publishes nine), and WHICH ONE TO PAY ON IS YOURS TO CHOOSE because the chain is inside the signed message and a signature made on a chain you hold nothing on is valid and fails at the transfer.
warningsNoAnything the server wants a caller to know about THIS answer before acting on it. Empty is the normal case and is not a guarantee.
faultSaysNoThe same thing in a sentence.
latencyMsNoHow long it took US, which is a fact about this request as much as about the host.
truncatedNoTRUE where the answer was cut at 512 KB, and then `json` is null EVEN IF the cut happens to parse: half a list read as a whole one is a figure nobody could stand behind.
httpStatusNoWhat the host answered, unchanged.
sellerSaysNoWhy the seller refused, IN THEIR WORDS, lifted from their 402 document. Null where they gave none, which is said rather than filled in.
settlementNoThe seller’s settlement receipt, verbatim. THEIR claim that the authorisation reached a chain, carried as theirs and never restated as a reading of ours. A served answer means the seller accepted the authorisation, not that money settled: somebody still has to submit it on chain, and this is the seller saying so rather than us.
askedWithQueryNoThe query parameters we added, read back. Null where you sent none.
settlementStateNoWHAT THIS ANSWER ESTABLISHES ABOUT THE MONEY, which is less than the status code suggests. `none-presented`: no authorisation was handed over, so there is nothing that could settle. `claimed-by-seller`: they returned a receipt — THEIR claim, carried, never verified by us. `unknown`: an authorisation WAS presented and this answer says nothing about its fate. A 402 or a timeout after a payment reads `unknown`: it does NOT establish that the money is safe.
authorizationStateNoWHAT MAY STILL BE DONE WITH WHAT THE CALLER SIGNED. `none-signed`: nothing was signed, so nothing can be submitted. `presented-may-still-be-usable`: it was handed over and a valid authorisation stays usable until it expires or its nonce is spent — so signing again with a fresh nonce can be a SECOND payment. Check the previous transaction before you do.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed3 schema fields changed
    • addedInput schema / properties / query
      Added value: +{
      +  "description": "Query parameters to add to the catalogue address, e.g. `{\"txid\": \"4a5e…\"}` for an endpoint whose 402 document declares `?txid=`. `inputs` on the unpaid answer names what the SELLER declares; a seller may need one it does not declare, so undeclared names are accepted too. The origin and path stay the catalogue’s and are verified unchanged, a parameter already in the catalogue address is never replaced, values are bounded and refused rather than trimmed, at most ten. Send the SAME values with the paid knock: paying for a call without its input usually buys an error.",
      +  "type": "object"
      +}
    • addedOutput schema / properties / askedWithQuery
      Added value: +{
      +  "description": "The query parameters we added, read back. Null where you sent none.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / inputs
      Added value: +{
      +  "description": "WHAT THE SELLER SAYS THE CALL TAKES, from their own 402 document (bazaar `info.input` and its schema in v2, `outputSchema.input` in v1): `method`, and `query` / `body` as `{ name, required, description, example }`. `required` is true only where they say so. NULL WHERE THEY DECLARE NOTHING, which is not “it needs nothing”: some sellers need a value they never declare. Theirs and a claim.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  2. Changed4 schema fields changed
    • changedInput schema / properties / payment / description
      Previous value: -"A finished x402 `exact` payment, base64, as YOUR wallet produced it. Sent to the seller under both `X-PAYMENT` and `PAYMENT-SIGNATURE`, because v1 and v2 sellers read different names. A v2 seller matches on the `accepted` field, which must echo the entry of `accepts` you chose VERBATIM — omit it and the answer is “No matching payment requirements”, which reads like a refusal and is an envelope fault. Omit `payment` entirely to read the terms first."New value: +"A finished x402 `exact` payment, base64, as YOUR wallet produced it. Sent to the seller under both `X-PAYMENT` and `PAYMENT-SIGNATURE`, because v1 and v2 sellers read different names. A v2 seller matches on the `accepted` field, which must echo the entry of `accepts` you chose VERBATIM — omit it and the answer is “No matching payment requirements”, which reads like a refusal and is an envelope fault. Omit `payment` entirely to read the terms first. WE NEVER HOLD YOUR KEY and this path cannot: it takes a finished authorisation and carries it, because a seller’s host sends no CORS headers and that failure is indistinguishable from the endpoint being down."
    • changedOutput schema / properties / outcome / description
      Previous value: -"`served` is an answer in hand. `quoting` is 402 with terms we could read and `charging` 402 without. `rejected` is 402 on a knock that CARRIED a payment, which is the seller refusing what you signed and a different fact from the first 402. `refused` is 401 or 403, where payment is not what is being asked for."New value: +"`served` is an answer in hand. `quoting` is 402 with terms we could read and `charging` 402 without. `rejected` is 402 on a knock that CARRIED a payment, which is the seller refusing what you signed and a different fact from the first 402. `refused` is 401 or 403, where payment is not what is being asked for. On `rejected`, `sellerSays` carries their reason in their words, and the answer DOES NOT ESTABLISH THAT NOTHING WAS SPENT: the seller held your authorisation before answering, and a status code does not report what they did with it."
    • changedOutput schema / properties / settlement / description
      Previous value: -"The seller’s settlement receipt, verbatim. THEIR claim that the authorisation reached a chain, carried as theirs and never restated as a reading of ours."New value: +"The seller’s settlement receipt, verbatim. THEIR claim that the authorisation reached a chain, carried as theirs and never restated as a reading of ours. A served answer means the seller accepted the authorisation, not that money settled: somebody still has to submit it on chain, and this is the seller saying so rather than us."
    • changedOutput schema / properties / signable / description
      Previous value: -"The legs an `exact` EVM wallet can sign, in the seller’s own order, each flattened to what signing needs. `amountRaw` is a STRING in the asset’s smallest unit; `approxUsd` is present ONLY where the seller’s own catalogue entry publishes both figures for the SAME token, since nothing in a payment-requirements document names a token’s decimals. `terms` is their entry VERBATIM, to echo back as `accepted`."New value: +"The legs an `exact` EVM wallet can sign, in the seller’s own order, each flattened to what signing needs. `amountRaw` is a STRING in the asset’s smallest unit; `approxUsd` is present ONLY where the seller’s own catalogue entry publishes both figures for the SAME token, since nothing in a payment-requirements document names a token’s decimals. `terms` is their entry VERBATIM, to echo back as `accepted`. A real offer has several (agent402.tools publishes nine), and WHICH ONE TO PAY ON IS YOURS TO CHOOSE because the chain is inside the signed message and a signature made on a chain you hold nothing on is valid and fails at the transfer."
  3. Changed3 schema fields changed
    • addedOutput schema / properties / authorizationState
      Added value: +{
      +  "description": "WHAT MAY STILL BE DONE WITH WHAT THE CALLER SIGNED. `none-signed`: nothing was signed, so nothing can be submitted. `presented-may-still-be-usable`: it was handed over and a valid authorisation stays usable until it expires or its nonce is spent — so signing again with a fresh nonce can be a SECOND payment. Check the previous transaction before you do.",
      +  "enum": [
      +    "none-signed",
      +    "presented-may-still-be-usable"
      +  ],
      +  "type": "string"
      +}
    • changedOutput schema / properties / says / description
      Previous value: -"What happened, in one sentence. On a `rejected` knock it states that nothing was spent, because an authorisation moves no money until somebody submits it."New value: +"What happened, in one sentence. On a `rejected` knock it says the seller refused the authorisation AND that this answer does not establish on-chain settlement either way; read `settlementState` for that."
    • addedOutput schema / properties / settlementState
      Added value: +{
      +  "description": "WHAT THIS ANSWER ESTABLISHES ABOUT THE MONEY, which is less than the status code suggests. `none-presented`: no authorisation was handed over, so there is nothing that could settle. `claimed-by-seller`: they returned a receipt — THEIR claim, carried, never verified by us. `unknown`: an authorisation WAS presented and this answer says nothing about its fate. A 402 or a timeout after a payment reads `unknown`: it does NOT establish that the money is safe.",
      +  "enum": [
      +    "none-presented",
      +    "claimed-by-seller",
      +    "unknown"
      +  ],
      +  "type": "string"
      +}
  4. Added

TDQS

A4.5/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

The description adds substantial safety-critical behavior beyond the annotations: it never holds keys, a served answer means seller acceptance rather than settlement, a 402 after payment is reported as `rejected`, and re-signing with a fresh nonce can cause a second payment. It also discloses rate limits, catalogue-only targeting, and that seller answers are not stored.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness3/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The first sentence is front-loaded and clear, but the body is a long, dense, all-caps block with meta commentary and repeated warnings. Much of the content is useful for a payment-bearing tool, but the formatting and verbosity make it harder to parse than necessary.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the output schema and the annotations, the description covers the remaining behavioral and usage context an agent needs: payment semantics, settlement caveats, rate limits, catalogue restrictions, and read-vs-pay modes. Nothing essential for correct invocation appears to be missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, so the schema already documents all six parameters thoroughly. The description reinforces key usage patterns such as omitting `payment` to read terms and sending the same `fill`/`query` values with a paid knock, but most parameter meaning is duplicated rather than added beyond the schema.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description states a specific verb and resource: knock on an x402 endpoint and get what it served. It explicitly distinguishes this from the sibling `test_purchase`, explaining that this tool is the paying half while `test_purchase` stops at the quote.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives clear when-to-use guidance: omit `payment` to read terms, include `payment` to forward a signed authorization and retrieve the seller's response. It also names alternatives and prerequisites, including using `list_x402_endpoints` to find a catalogue endpoint and avoiding unpaid knocks more than once a minute.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.

Resources