Skip to main content
Glama

ASPERN: counterparty checks for agents

What the chain records about one address

counterparty_check
Read-onlyIdempotent

Before paying or hiring an agent: what the chain records about that address. Independent payers (counterparties that paid it and were never paid back), the ones it does pay back, how concentrated its custom is, WHETHER THOSE INDEPENDENT PAYERS ARE INDEPENDENT OF EACH OTHER under independence, WHAT IT ITSELF RESTS ON under restsOn (how many parties it pays and how much of its spending goes to the largest of them), how its ACP jobs ended, whether its advertised service answers, and when it was last paid. Free. Three limits to repeat whenever quoting it: independent means no payment BACK on the rails we read, NOT proof the payers are different parties, since one owner can fund many addresses that never pay each other; an all-time record says nothing about whether the agent still works — 44% of agents ever paid had not been paid in 90 days, measured on 29 September 2026; and restsOn counts every party this address has PAID rather than purchases from identified sellers, so a recipient there has not been shown to supply anything, and restsOn.suppliers of zero means it has paid nobody on a rail we read, never that it depends on nobody. Takes an EVM address, a Cardano payment address (addr1…) or a Solana address.

Input Schema

NameRequiredDescriptionDefault
addressYesThe address you are about to pay or hire.

Output Schema

NameRequiredDescriptionDefault
acpNoHow its jobs ended, where it has any.
mechNoDeliveries on the Olas mech marketplace, and what was paid for them where we hold it. A rail many agents never touch; zero here is not a mark against an address.
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.
x402NoSales and payers on the x402 rail. Payers are counted as parties, not payments: one buyer paying fifty times is one payer.
partsNoWhich parts of the check answered inside their budget: `complete`, `ran` and `failed`. A part in `failed` is MISSING from this answer, not absent for the address: read its fields as unknown. If the record itself does not answer, the route returns 503 with Retry-After instead.
formatYesWhat kind of address this is and what we read for it.
limitsYesWhat this answer cannot tell you. Quote it with the numbers.
masumiNoEscrows on the Masumi rail. Null where we hold no reading for this address at all, which is not the same as zero escrows.
addressYesThe address as we read it, normalised. Compare it with what you sent before acting on the answer.
paidForNoWhat it was paid for, in the subject’s own words.
restsOnNosuppliers, payments, spentUsd, largestShare and recent.{suppliers90,largestShare90}: every party this address has PAID. NOT the mirror of `dealings` — a dealing is a sale and needs a seller on the other end, while a payment out counts whoever receives it, so a recipient here may be a relayer, a settlement route or a customer being paid back. `largestShare` is null below three suppliers, where it could only be a half or a whole. Zero suppliers means it has paid nobody on a rail we read, never that it depends on nobody: a model, an endpoint, a host and a key are dependencies no payment rail shows.
alsoHereNoThe same address on the capital side — a vault or an operator — with the check to call. A match on the address, never an identification of the party.
dealingsNoA DEALING IS A PAYMENT RELATIONSHIP WE OBSERVED, AND NOT WORK PERFORMED. On the Olas mech rail a subject can show more than 330,000 DELIVERIES beside `dealings: 0`, and both figures are true: a delivery is work the mech returned, a dealing is money we watched move. Never read one as the other and never rank a mech subject against an ACP one on this field. What each rail can and cannot witness is fixed and published: x402 records payment and NO outcome; ACP records both, because a job carries its own payment and reaches a phase; Masumi records both through escrow release or refund; the mech rail records deliveries and no payment we see. rails, chains, counterparties, independent, largestShare, firstPaid, lastPaid. `independent` means no payment BACK on the rails we read — NOT proof the payers are different parties, since one owner can fund many addresses.
identityNoRegistrations it holds. Claims, never verification.
servicesNoCallable services it declares, and how many answered our probe.
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.
independenceNopayers, linked, viaParties, largestGroup: payers of this address that share an OBSCURE third party with another of its payers. This is the test of `dealings.independent`, which counts payers that never paid it back and has never been proof they are different parties. A party paid by two to ten addresses in all counts; a hub paid by more does not, because two agents both paying a hub have shown only that the hub is popular. EVIDENCE OF A LINK, NEVER PROOF OF ONE OPERATOR — two payers paying one small service are two customers of that service. `groups` names which payers and through what and needs the `independence.test` capability; where it is withheld, `capability` says so. A linked count of zero is not proof they are unrelated: one owner funding addresses that never touch each other again leaves nothing for this to find. `differentPopulation` IS PRESENT WHEN THIS BLOCK AND THE RECORD ABOVE IT COUNT DIFFERENT NUMBERS OF PAYERS, which happens because they are two jobs on two schedules: it carries `why: "different_population_snapshots"`, both counts and both dates. Neither figure is wrong, and the linkage here describes the population in THIS block, not the larger one. It is null when they agree, so its presence means something.
observationsYesThe findings, each with its evidence class and its own words. Read these first.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • addedOutput schema / properties / parts
      Added value: +{
      +  "description": "Which parts of the check answered inside their budget: `complete`, `ran` and `failed`. A part in `failed` is MISSING from this answer, not absent for the address: read its fields as unknown. If the record itself does not answer, the route returns 503 with Retry-After instead.",
      +  "type": "object"
      +}
  2. Changed1 schema field changed
    • changedOutput schema / properties / dealings / description
      Previous value: -"rails, chains, counterparties, independent, largestShare, firstPaid, lastPaid. `independent` means no payment BACK on the rails we read — NOT proof the payers are different parties, since one owner can fund many addresses."New value: +"A DEALING IS A PAYMENT RELATIONSHIP WE OBSERVED, AND NOT WORK PERFORMED. On the Olas mech rail a subject can show more than 330,000 DELIVERIES beside `dealings: 0`, and both figures are true: a delivery is work the mech returned, a dealing is money we watched move. Never read one as the other and never rank a mech subject against an ACP one on this field. What each rail can and cannot witness is fixed and published: x402 records payment and NO outcome; ACP records both, because a job carries its own payment and reaches a phase; Masumi records both through escrow release or refund; the mech rail records deliveries and no payment we see. rails, chains, counterparties, independent, largestShare, firstPaid, lastPaid. `independent` means no payment BACK on the rails we read — NOT proof the payers are different parties, since one owner can fund many addresses."
  3. Changed2 schema fields changed
    • addedOutput schema / properties / meta
      Added value: +{
      +  "description": "How 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.",
      +  "type": "object"
      +}
    • addedOutput schema / properties / warnings
      Added value: +{
      +  "description": "Anything the server wants a caller to know about THIS answer before acting on it. Empty is the normal case and is not a guarantee.",
      +  "items": {
      +    "type": "string"
      +  },
      +  "type": "array"
      +}
  4. Changed1 schema field changed
    • changedOutput schema / properties / independence / description
      Previous value: -"payers, linked, viaParties, largestGroup: payers of this address that share an OBSCURE third party with another of its payers. This is the test of `dealings.independent`, which counts payers that never paid it back and has never been proof they are different parties. A party paid by two to ten addresses in all counts; a hub paid by more does not, because two agents both paying a hub have shown only that the hub is popular. EVIDENCE OF A LINK, NEVER PROOF OF ONE OPERATOR — two payers paying one small service are two customers of that service. `groups` names which payers and through what and needs the `independence.test` capability; where it is withheld, `capability` says so. A linked count of zero is not proof they are unrelated: one owner funding addresses that never touch each other again leaves nothing for this to find."New value: +"payers, linked, viaParties, largestGroup: payers of this address that share an OBSCURE third party with another of its payers. This is the test of `dealings.independent`, which counts payers that never paid it back and has never been proof they are different parties. A party paid by two to ten addresses in all counts; a hub paid by more does not, because two agents both paying a hub have shown only that the hub is popular. EVIDENCE OF A LINK, NEVER PROOF OF ONE OPERATOR — two payers paying one small service are two customers of that service. `groups` names which payers and through what and needs the `independence.test` capability; where it is withheld, `capability` says so. A linked count of zero is not proof they are unrelated: one owner funding addresses that never touch each other again leaves nothing for this to find. `differentPopulation` IS PRESENT WHEN THIS BLOCK AND THE RECORD ABOVE IT COUNT DIFFERENT NUMBERS OF PAYERS, which happens because they are two jobs on two schedules: it carries `why: \"different_population_snapshots\"`, both counts and both dates. Neither figure is wrong, and the linkage here describes the population in THIS block, not the larger one. It is null when they agree, so its presence means something."
  5. Changed1 schema field changed
    • addedOutput schema / properties / independence
      Added value: +{
      +  "description": "payers, linked, viaParties, largestGroup: payers of this address that share an OBSCURE third party with another of its payers. This is the test of `dealings.independent`, which counts payers that never paid it back and has never been proof they are different parties. A party paid by two to ten addresses in all counts; a hub paid by more does not, because two agents both paying a hub have shown only that the hub is popular. EVIDENCE OF A LINK, NEVER PROOF OF ONE OPERATOR — two payers paying one small service are two customers of that service. `groups` names which payers and through what and needs the `independence.test` capability; where it is withheld, `capability` says so. A linked count of zero is not proof they are unrelated: one owner funding addresses that never touch each other again leaves nothing for this to find.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  6. Changed1 schema field changed
    • addedOutput schema / properties / restsOn
      Added value: +{
      +  "description": "suppliers, payments, spentUsd, largestShare and recent.{suppliers90,largestShare90}: every party this address has PAID. NOT the mirror of `dealings` — a dealing is a sale and needs a seller on the other end, while a payment out counts whoever receives it, so a recipient here may be a relayer, a settlement route or a customer being paid back. `largestShare` is null below three suppliers, where it could only be a half or a whole. Zero suppliers means it has paid nobody on a rail we read, never that it depends on nobody: a model, an endpoint, a host and a key are dependencies no payment rail shows.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
  7. Changed4 schema fields changed
    • addedOutput schema / properties / address / description
      Added value: +"The address as we read it, normalised. Compare it with what you sent before acting on the answer."
    • addedOutput schema / properties / masumi / description
      Added value: +"Escrows on the Masumi rail. Null where we hold no reading for this address at all, which is not the same as zero escrows."
    • addedOutput schema / properties / mech / description
      Added value: +"Deliveries on the Olas mech marketplace, and what was paid for them where we hold it. A rail many agents never touch; zero here is not a mark against an address."
    • addedOutput schema / properties / x402 / description
      Added value: +"Sales and payers on the x402 rail. Payers are counted as parties, not payments: one buyer paying fifty times is one payer."
  8. Changed20 schema fields changed
    • changedOutput schema / properties / acp / description
      Previous value: -"How its ACP jobs ended, where it has any."New value: +"How its jobs ended, where it has any."
    • changedOutput schema / properties / acp / type
      Previous value: -[
      -  "object",
      -  "null"
      -]New value: +"object"
    • addedOutput schema / properties / alsoHere
      Added value: +{
      +  "description": "The same address on the capital side — a vault or an operator — with the check to call. A match on the address, never an identification of the party.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / dealings / description
      Added value: +"rails, chains, counterparties, independent, largestShare, firstPaid, lastPaid. `independent` means no payment BACK on the rails we read — NOT proof the payers are different parties, since one owner can fund many addresses."
    • changedOutput schema / properties / dealings / type
      Previous value: -"integer"New value: +"object"
    • addedOutput schema / properties / format
      Added value: +{
      +  "description": "What kind of address this is and what we read for it.",
      +  "type": "object"
      +}
    • addedOutput schema / properties / identity
      Added value: +{
      +  "description": "Registrations it holds. Claims, never verification.",
      +  "type": "object"
      +}
    • removedOutput schema / properties / independent
      Removed value: -{
      -  "description": "Counterparties that paid it and were never paid back. NOT proof they are different parties: one owner can fund many addresses.",
      -  "type": "integer"
      -}
    • removedOutput schema / properties / largestShare
      Removed value: -{
      -  "description": "How concentrated its custom is, 0 to 1.",
      -  "type": [
      -    "number",
      -    "null"
      -  ]
      -}
    • removedOutput schema / properties / lastPaid
      Removed value: -{
      -  "description": "An all-time record says nothing about whether the agent still works.",
      -  "format": "date-time",
      -  "type": [
      -    "string",
      -    "null"
      -  ]
      -}
    • addedOutput schema / properties / limits
      Added value: +{
      +  "description": "What this answer cannot tell you. Quote it with the numbers.",
      +  "type": "string"
      +}
    • addedOutput schema / properties / masumi
      Added value: +{
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / mech
      Added value: +{
      +  "type": "object"
      +}
    • addedOutput schema / properties / observations
      Added value: +{
      +  "description": "The findings, each with its evidence class and its own words. Read these first.",
      +  "items": {
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • addedOutput schema / properties / paidFor
      Added value: +{
      +  "description": "What it was paid for, in the subject’s own words.",
      +  "type": [
      +    "object",
      +    "null"
      +  ]
      +}
    • removedOutput schema / properties / says
      Removed value: -{
      -  "type": "string"
      -}
    • addedOutput schema / properties / services
      Added value: +{
      +  "description": "Callable services it declares, and how many answered our probe.",
      +  "type": "object"
      +}
    • removedOutput schema / properties / serving
      Removed value: -{
      -  "description": "Whether its advertised service answered our probe. Null where it advertises none.",
      -  "type": [
      -    "boolean",
      -    "null"
      -  ]
      -}
    • addedOutput schema / properties / x402
      Added value: +{
      +  "type": "object"
      +}
    • changedOutput schema / required
      Previous value: -[
      -  "address",
      -  "says"
      -]New value: +[
      +  "address",
      +  "format",
      +  "observations",
      +  "limits"
      +]
  9. Changed1 schema field changed
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "acp": {
      +      "description": "How its ACP jobs ended, where it has any.",
      +      "type": [
      +        "object",
      +        "null"
      +      ]
      +    },
      +    "address": {
      +      "type": "string"
      +    },
      +    "dealings": {
      +      "type": "integer"
      +    },
      +    "independent": {
      +      "description": "Counterparties that paid it and were never paid back. NOT proof they are different parties: one owner can fund many addresses.",
      +      "type": "integer"
      +    },
      +    "largestShare": {
      +      "description": "How concentrated its custom is, 0 to 1.",
      +      "type": [
      +        "number",
      +        "null"
      +      ]
      +    },
      +    "lastPaid": {
      +      "description": "An all-time record says nothing about whether the agent still works.",
      +      "format": "date-time",
      +      "type": [
      +        "string",
      +        "null"
      +      ]
      +    },
      +    "says": {
      +      "type": "string"
      +    },
      +    "serving": {
      +      "description": "Whether its advertised service answered our probe. Null where it advertises none.",
      +      "type": [
      +        "boolean",
      +        "null"
      +      ]
      +    }
      +  },
      +  "required": [
      +    "address",
      +    "says"
      +  ],
      +  "type": "object"
      +}
  10. First observed

TDQS

A4.1/5.0
Behavior5/5

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

Annotations already establish read-only, idempotent, open-world, non-destructive behavior. The description adds substantial interpretive behavior: independence only means no payment back on the rails read, an all-time record does not prove the agent still operates (with a measured 44% stale rate), and restsOn counts paid parties rather than identified suppliers. These caveats materially change how an agent should present and trust the output.

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 purpose is front-loaded and the caveats are worth including for a due-diligence tool, but the paragraph is dense and hard to scan. All-caps emphasis and long semicolon-chained clauses ('WHETHER THOSE INDEPENDENT PAYERS ARE INDEPENDENT OF EACH OTHER', 'WHAT IT ITSELF RESTS ON') make it read like a warning label rather than a structured definition.

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

Completeness4/5

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

Given a single-parameter, read-only tool with an output schema, the description is largely complete: it explains the decision context, enumerates the report areas, states cost, covers accepted address types, and supplies critical interpretation limits. What remains thin is sibling differentiation and precise definitions for fields such as 'how concentrated its custom is' and 'how its ACP jobs ended', which the output schema may cover but the prose does not.

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

Parameters4/5

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

The schema covers the single address parameter at 100%, including the phrase 'the address you are about to pay or hire'. The description adds accepted address families — EVM, Cardano addr1..., and Solana — which is meaningful routing information not present in the schema. It stops short of validation rules, but the added format guidance is useful.

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

Purpose4/5

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

The description states a specific resource — what the chain records about one address — and frames the decision context ('Before paying or hiring an agent'), so an agent knows this is a due-diligence lookup. It enumerates the report areas (independent payers, repayment behavior, concentration, independence, restsOn, ACP outcomes, service responsiveness, last payment), making the scope concrete. It does not distinguish itself from siblings such as counterparty_history or preflight_payment, which keeps it from a 5.

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

Usage Guidelines4/5

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

It gives a clear when-to-use trigger: before paying or hiring an agent, and notes that the call is free. It does not name when-not-to-use conditions or point to alternative sibling tools for related checks, so an agent must infer routing among counterparty_history, payment_evidence, and preflight_payment.

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