Skip to main content
Glama

ASPERN: counterparty checks for agents

Find agents by what the record shows

find_agents
Read-onlyIdempotent

Find agents to hire by what the chain records rather than what they claim: filter every address ever paid on x402, Virtuals ACP, the Olas mech marketplace or Masumi by independent payers, dealings, ACP completion, whether its declared service answers, whether it pays its own payers back, how spread its own SPENDING is (spreadSuppliers), and how recently it was paid. Free. An address absent from the result was never paid on a rail we read, which is not the same as never having worked. EVERY ROW CARRIES subject, WHICH IS WHAT WE CAN POSITIVELY SAY IT IS, with the evidence under it. agent means we saw agent-protocol work (ACP, Olas mech, Masumi) or saw it HIRE as well as be hired. marketplace means many paid it and it paid many, both above a stated floor. unknown is the largest bucket and is a real answer, not a failure: it means the evidence does not separate an agent from something that merely sells. READ THIS BEFORE FILTERING: a catalogue listing does NOT make a subject an API service, and api-service is in the vocabulary but currently UNREACHABLE; items says why and gives the measured mix. Nothing is inferred from a zero and no self-description is read, so a listing calling itself an autonomous agent moves nothing.

Input Schema

NameRequiredDescriptionDefault
qNoA name fragment from its registrations. A claim, matched as typed.
dirNoSort direction. Default desc.
railNox402, acp, mech or masumi.
sortNoOne named dimension: independent, dealings, usd, completion, recent, paidBack, largestShare, counterparties, serving, suppliers, largestSupplierShare or spent. The last three order by what an agent rests on rather than by who rests on it. There is no "best" — nothing here has earned the right to rank.
limitNoDefault 25, maximum 200.
minUsdNoFewest US dollars received on the rails we read, all time.
offsetNoWhere to start, for the next page: send the `nextOffset` of the previous answer. Default 0.
networkNoOnly agents seen on this network, e.g. base, ethereum, polygon, solana.
serviceNoWhat it was paid for, in the subject’s own words: a service name the protocol recorded or a description it published. Matched as typed.
servingNoOnly agents whose declared service answered our last probe. An agent that declares none is excluded, not failed.
callableNoOnly agents that declare a callable endpoint and answered our probe.
noTwoWayNoExclude agents that also pay their own payers, which can be one owner moving money between their own addresses.
activeDaysNoPaid within this many days.
registeredNoOnly agents holding a registration in a registry we read. A registration is a claim, never a verification.
minCameBackNo0 to 1, the least share of its payers who paid it more than once. Excludes every seller with too few payers to have a rate.
minDealingsNoFewest dealings on the rails we read, all time.
minCompletionNoACP jobs completed over those that ENDED, 0 to 1. It is a conditional rate: one agent reads 0.9776 on it while 38.8% of its 9,894 jobs carry no phase we could decode, so the rate describes a third of its work. Pair it with `minOutcomeCoverage` or you are ranking an agent with nearly complete evidence beside one without.
minIndependentNoFewest counterparties that paid it and were never paid back. The closest thing here to "has real custom".
supplierSpreadNoThe precise form of `spreadSuppliers`. That filter admits an agent with too few suppliers to have a share, deliberately — too few to measure is not evidence of concentration — but in a list it is indistinguishable from one that was measured and found spread, which is misleading to somebody deciding. Ask for `diversified` to get only the measured ones. `none` means it pays nobody on a rail we read; `insufficient-data` means it pays somebody and fewer than the floor. The share is null for both and the supplier COUNT is what tells them apart.
notConcentratedNoNo single counterparty above half of ten or more dealings.
spreadSuppliersNoOnly agents that PAY somebody and where no single party takes more than half of what the agent itself SPENDS. The other direction from the concentration of its custom: an agent with forty payers and one supplier looks diversified on every other figure here and is one supplier away from stopping. An agent with too few suppliers to have a share passes, because too few to measure is not evidence of concentration; an agent with NO suppliers does not, because nothing to measure is a different thing — that was 2,723 of the 3,121 rows this used to return. Use `supplierSpread=diversified` for the measured ones alone. It is the one filter here about what the agent rests on rather than who rests on it.
minOutcomeCoverageNoThe share of ALL this agent’s ACP jobs that reached an outcome at all, 0 to 1. What `minCompletion` COVERS. Filtering on it excludes every agent with no ACP jobs, which is correct and said rather than implied.
contractedSuppliersNoAt least one supplier the protocol names as a provider, not merely a payee.

Output Schema

NameRequiredDescriptionDefault
asOfNoWhen the record behind these rows was last rebuilt. Null means nothing in the answer carries a date, which is a gap in our reading rather than a fact about the agents.
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.
itemsYesMatching agents, ordered by the ONE dimension asked for, never a composite score. Each row carries `subject`: { type, evidence[], alsoShows[], says }. `evidence` names each thing we SAW and, in `supports`, which type it is evidence for — or null where the observation is real and separates nothing, which is the case for a catalogue listing. So `unknown` WITH evidence is the normal shape here and means "we saw these things and they do not settle it", never "we saw nothing". `alsoShows` carries the types a subject also shows evidence for, because they are not exclusive and dropping one would make the label more confident than the evidence. Measured once and not refreshed since, over all 3,077 paid addresses: **1,377 agent, 38 marketplace, 1,662 unknown**. Those are a PAST reading kept because they are the point — this contract once claimed `unknown` would be commonest before anything had been measured, and the measurement found it at zero, which is how a defect in the classifier was caught. Read the answer’s own denominators for today’s mix; these say what KIND of mix to expect. A catalogue listing does NOT make a subject an API service. Agents sell priced endpoints too (this platform sells four), so a listing says it sells over HTTP and nothing about which kind of seller. `api-service` is therefore in the vocabulary and is currently UNREACHABLE: separating it would need evidence that a subject does NOT do agent work, and that is an absence, since 86% of these addresses pay nobody on a rail we read and paying from a second wallet looks identical to buying nothing.
filtersNoWhat was applied, read back, including what a floor excluded.
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.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed2 schema fields changed
    • changedInput schema / properties / spreadSuppliers / description
      Previous value: -"Only agents that PAY somebody and where no single party takes more than half of what the agent itself SPENDS. The other direction from the concentration of its custom: an agent with forty payers and one supplier looks diversified on every other figure here and is one supplier away from stopping. An agent with too few suppliers to have a share passes, because too few to measure is not evidence of concentration; an agent with NO suppliers does not, because nothing to measure is a different thing — that was 2,723 of the 3,121 rows this used to return. Use `supplierSpread=diversified` for the measured ones alone."New value: +"Only agents that PAY somebody and where no single party takes more than half of what the agent itself SPENDS. The other direction from the concentration of its custom: an agent with forty payers and one supplier looks diversified on every other figure here and is one supplier away from stopping. An agent with too few suppliers to have a share passes, because too few to measure is not evidence of concentration; an agent with NO suppliers does not, because nothing to measure is a different thing — that was 2,723 of the 3,121 rows this used to return. Use `supplierSpread=diversified` for the measured ones alone. It is the one filter here about what the agent rests on rather than who rests on it."
    • changedOutput schema / properties / items / description
      Previous value: -"Matching agents, ordered by the ONE dimension asked for, never a composite score. Each row carries `subject`: { type, evidence[], alsoShows[], says }. `evidence` names each thing we SAW and, in `supports`, which type it is evidence for — or null where the observation is real and separates nothing, which is the case for a catalogue listing. So `unknown` WITH evidence is the normal shape here and means \"we saw these things and they do not settle it\", never \"we saw nothing\". `alsoShows` carries the types a subject also shows evidence for, because they are not exclusive and dropping one would make the label more confident than the evidence."New value: +"Matching agents, ordered by the ONE dimension asked for, never a composite score. Each row carries `subject`: { type, evidence[], alsoShows[], says }. `evidence` names each thing we SAW and, in `supports`, which type it is evidence for — or null where the observation is real and separates nothing, which is the case for a catalogue listing. So `unknown` WITH evidence is the normal shape here and means \"we saw these things and they do not settle it\", never \"we saw nothing\". `alsoShows` carries the types a subject also shows evidence for, because they are not exclusive and dropping one would make the label more confident than the evidence. Measured once and not refreshed since, over all 3,077 paid addresses: **1,377 agent, 38 marketplace, 1,662 unknown**. Those are a PAST reading kept because they are the point — this contract once claimed `unknown` would be commonest before anything had been measured, and the measurement found it at zero, which is how a defect in the classifier was caught. Read the answer’s own denominators for today’s mix; these say what KIND of mix to expect. A catalogue listing does NOT make a subject an API service. Agents sell priced endpoints too (this platform sells four), so a listing says it sells over HTTP and nothing about which kind of seller. `api-service` is therefore in the vocabulary and is currently UNREACHABLE: separating it would need evidence that a subject does NOT do agent work, and that is an absence, since 86% of these addresses pay nobody on a rail we read and paying from a second wallet looks identical to buying nothing."
  2. Changed10 schema fields changed
    • addedInput schema / properties / callable
      Added value: +{
      +  "description": "Only agents that declare a callable endpoint and answered our probe.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / contractedSuppliers
      Added value: +{
      +  "description": "At least one supplier the protocol names as a provider, not merely a payee.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / dir
      Added value: +{
      +  "description": "Sort direction. Default desc.",
      +  "enum": [
      +    "asc",
      +    "desc"
      +  ],
      +  "type": "string"
      +}
    • addedInput schema / properties / minCameBack
      Added value: +{
      +  "description": "0 to 1, the least share of its payers who paid it more than once. Excludes every seller with too few payers to have a rate.",
      +  "type": "number"
      +}
    • addedInput schema / properties / minUsd
      Added value: +{
      +  "description": "Fewest US dollars received on the rails we read, all time.",
      +  "type": "number"
      +}
    • addedInput schema / properties / network
      Added value: +{
      +  "description": "Only agents seen on this network, e.g. base, ethereum, polygon, solana.",
      +  "type": "string"
      +}
    • addedInput schema / properties / notConcentrated
      Added value: +{
      +  "description": "No single counterparty above half of ten or more dealings.",
      +  "type": "boolean"
      +}
    • addedInput schema / properties / offset
      Added value: +{
      +  "description": "Where to start, for the next page: send the `nextOffset` of the previous answer. Default 0.",
      +  "type": "number"
      +}
    • addedInput schema / properties / q
      Added value: +{
      +  "description": "A name fragment from its registrations. A claim, matched as typed.",
      +  "type": "string"
      +}
    • addedInput schema / properties / service
      Added value: +{
      +  "description": "What it was paid for, in the subject’s own words: a service name the protocol recorded or a description it published. Matched as typed.",
      +  "type": "string"
      +}
  3. Changed2 schema fields changed
    • changedInput schema / properties / minCompletion / description
      Previous value: -"ACP jobs completed over those that ended, 0 to 1."New value: +"ACP jobs completed over those that ENDED, 0 to 1. It is a conditional rate: one agent reads 0.9776 on it while 38.8% of its 9,894 jobs carry no phase we could decode, so the rate describes a third of its work. Pair it with `minOutcomeCoverage` or you are ranking an agent with nearly complete evidence beside one without."
    • addedInput schema / properties / minOutcomeCoverage
      Added value: +{
      +  "description": "The share of ALL this agent’s ACP jobs that reached an outcome at all, 0 to 1. What `minCompletion` COVERS. Filtering on it excludes every agent with no ACP jobs, which is correct and said rather than implied.",
      +  "type": "number"
      +}
  4. 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"
      +}
  5. Changed1 schema field changed
    • changedInput schema / properties / spreadSuppliers / description
      Previous value: -"Only agents where no single party takes more than half of what the agent itself SPENDS. The other direction from the concentration of its custom: an agent with forty payers and one supplier looks diversified on every other figure here and is one supplier away from stopping. An agent with too few suppliers to have a share passes, because too few to measure is not evidence of concentration."New value: +"Only agents that PAY somebody and where no single party takes more than half of what the agent itself SPENDS. The other direction from the concentration of its custom: an agent with forty payers and one supplier looks diversified on every other figure here and is one supplier away from stopping. An agent with too few suppliers to have a share passes, because too few to measure is not evidence of concentration; an agent with NO suppliers does not, because nothing to measure is a different thing — that was 2,723 of the 3,121 rows this used to return. Use `supplierSpread=diversified` for the measured ones alone."
  6. Changed1 schema field changed
    • addedInput schema / properties / supplierSpread
      Added value: +{
      +  "description": "The precise form of `spreadSuppliers`. That filter admits an agent with too few suppliers to have a share, deliberately — too few to measure is not evidence of concentration — but in a list it is indistinguishable from one that was measured and found spread, which is misleading to somebody deciding. Ask for `diversified` to get only the measured ones. `none` means it pays nobody on a rail we read; `insufficient-data` means it pays somebody and fewer than the floor. The share is null for both and the supplier COUNT is what tells them apart.",
      +  "enum": [
      +    "diversified",
      +    "concentrated",
      +    "insufficient-data",
      +    "none"
      +  ],
      +  "type": "string"
      +}
  7. Changed1 schema field changed
    • changedOutput schema / properties / items / description
      Previous value: -"Matching agents, ordered by the ONE dimension asked for, never a composite score."New value: +"Matching agents, ordered by the ONE dimension asked for, never a composite score. Each row carries `subject`: { type, evidence[], alsoShows[], says }. `evidence` names each thing we SAW and, in `supports`, which type it is evidence for — or null where the observation is real and separates nothing, which is the case for a catalogue listing. So `unknown` WITH evidence is the normal shape here and means \"we saw these things and they do not settle it\", never \"we saw nothing\". `alsoShows` carries the types a subject also shows evidence for, because they are not exclusive and dropping one would make the label more confident than the evidence."
  8. Changed2 schema fields changed
    • changedInput schema / properties / sort / description
      Previous value: -"One named dimension: independent, dealings, usd, completion, recent, paidBack, largestShare or counterparties. There is no \"best\" — nothing here has earned the right to rank."New value: +"One named dimension: independent, dealings, usd, completion, recent, paidBack, largestShare, counterparties, serving, suppliers, largestSupplierShare or spent. The last three order by what an agent rests on rather than by who rests on it. There is no \"best\" — nothing here has earned the right to rank."
    • addedInput schema / properties / spreadSuppliers
      Added value: +{
      +  "description": "Only agents where no single party takes more than half of what the agent itself SPENDS. The other direction from the concentration of its custom: an agent with forty payers and one supplier looks diversified on every other figure here and is one supplier away from stopping. An agent with too few suppliers to have a share passes, because too few to measure is not evidence of concentration.",
      +  "type": "boolean"
      +}
  9. Changed1 schema field changed
    • addedOutput schema / properties / asOf / description
      Added value: +"When the record behind these rows was last rebuilt. Null means nothing in the answer carries a date, which is a gap in our reading rather than a fact about the agents."
  10. Changed7 schema fields changed
    • removedOutput schema / properties / agents
      Removed value: -{
      -  "description": "Matching agents, ordered by the ONE dimension asked for, never a composite score.",
      -  "items": {
      -    "type": "object"
      -  },
      -  "type": "array"
      -}
    • addedOutput schema / properties / asOf
      Added value: +{
      +  "format": "date-time",
      +  "type": [
      +    "string",
      +    "null"
      +  ]
      +}
    • addedOutput schema / properties / filters
      Added value: +{
      +  "description": "What was applied, read back, including what a floor excluded.",
      +  "type": "object"
      +}
    • addedOutput schema / properties / items
      Added value: +{
      +  "description": "Matching agents, ordered by the ONE dimension asked for, never a composite score.",
      +  "items": {
      +    "type": "object"
      +  },
      +  "type": "array"
      +}
    • removedOutput schema / properties / says
      Removed value: -{
      -  "description": "What the filter did, and that an absent address was never paid on a rail we read rather than never having worked.",
      -  "type": "string"
      -}
    • removedOutput schema / properties / total
      Removed value: -{
      -  "type": "integer"
      -}
    • changedOutput schema / required
      Previous value: -[
      -  "agents"
      -]New value: +[
      +  "items"
      +]
  11. Changed7 schema fields changed
    • addedInput schema / properties / minDealings / description
      Added value: +"Fewest dealings on the rails we read, all time."
    • addedInput schema / properties / minIndependent / description
      Added value: +"Fewest counterparties that paid it and were never paid back. The closest thing here to \"has real custom\"."
    • addedInput schema / properties / noTwoWay / description
      Added value: +"Exclude agents that also pay their own payers, which can be one owner moving money between their own addresses."
    • addedInput schema / properties / registered / description
      Added value: +"Only agents holding a registration in a registry we read. A registration is a claim, never a verification."
    • addedInput schema / properties / serving / description
      Added value: +"Only agents whose declared service answered our last probe. An agent that declares none is excluded, not failed."
    • addedInput schema / properties / sort / description
      Added value: +"One named dimension: independent, dealings, usd, completion, recent, paidBack, largestShare or counterparties. There is no \"best\" — nothing here has earned the right to rank."
    • changedOutput schema / (root)
      Previous value: -nullNew value: +{
      +  "properties": {
      +    "agents": {
      +      "description": "Matching agents, ordered by the ONE dimension asked for, never a composite score.",
      +      "items": {
      +        "type": "object"
      +      },
      +      "type": "array"
      +    },
      +    "says": {
      +      "description": "What the filter did, and that an absent address was never paid on a rail we read rather than never having worked.",
      +      "type": "string"
      +    },
      +    "total": {
      +      "type": "integer"
      +    }
      +  },
      +  "required": [
      +    "agents"
      +  ],
      +  "type": "object"
      +}
  12. First observed

TDQS

A4.6/5.0
Behavior5/5

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

Annotations already cover read-only/open-world/idempotent safety, but the description adds substantive behavior: free access, independent payment evidence across named rails, no inference from zero, no reading of self-description, and explicit subject confidence labels including 'unknown' as a real answer. This adds rich context without contradicting annotations.

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

Conciseness4/5

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

Given 23 parameters and non-obvious evidence semantics, most of the length is justified and the purpose/scope is front-loaded. However, the dense all-caps caveats and long second paragraph make it less scannable than ideal.

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?

For a complex 23-parameter, output-schema-backed search tool, the description supplies the needed conceptual model: rails read, positive evidence rule, subject labels, and filtering pitfalls. With annotations and output schema present, no critical invocation context is missing.

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?

Schema coverage is 100% and the schema itself describes every filter in detail, so the baseline is 3. The description adds cross-cutting filter caveats—positive evidence vs absence, no self-description, api-service unreachable, and subject/evidence semantics—that help interpret the 23 parameters, though it does not document individual parameters 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 opening sentence names a specific verb and resource ('Find agents to hire') and immediately states the distinguishing evidence basis: chain records rather than claims. It also scopes the rails covered and defines row labels, so an agent can distinguish this from generic agent discovery.

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 strong filtering context, including 'READ THIS BEFORE FILTERING', the unreachable api-service label, and the caveat that absence means never paid rather than never worked. It does not explicitly name a sibling alternative or say when another tool should be chosen, so it falls short of a 5.

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