Skip to main content
Glama

Sato Hub: Build Onchain & Crypto Agents

Check a target before you install, connect, pay or trade

onchain_agent_preflight
Read-onlyIdempotent

USE WHEN you are about to install a package, clone a repo, connect to an MCP endpoint, pay an agent, or trade a token, and you want to know what is on record about it FIRST — every evidence line, with the field it was read from and its date. Pass exactly one of repo, package, endpoint, agent, token, skill, x402 or address; with none (or a template placeholder) nothing is checked and the answer is { needs_input: true, accepted_forms, example_calls }. NOT FOR a stack pick's summary (onchain_agent_recommend_stack and onchain_agent_get_deploy_spec already carry a records-only preflight_summary), whether an install command or MCP config takes your key (use onchain_agent_check_install instead), or a recipient-address reading on its own (use onchain_agent_scan_recipient). Call this for the full evidence, for any target that is not a pick (a repo, package, token, skill or ERC-8004 agent you were handed), or for a live handshake with an unlisted MCP endpoint.

RETURNS a verdict — go | caution | no | unknown — with one evidence line per check, each naming the field it was read from and when that field was written. The rules are written down in lib/preflight.ts and cited by id in rule.

RULE ENFORCED: a verdict names WHAT WAS CHECKED AND WHEN. It is never a security review, a quality judgment or a statement about returns, and unknown means Sato Hub holds no record — not that something is wrong. An unlisted endpoint gets ONE live handshake (initialize + tools/list, 8 s cap) and can never come back go: a handshake is not a record. For agent=: we confirm the ERC-8004 registration exists, fetch its registration file, and report the services it DECLARES; only a declared MCP service is probed.

TOKEN LANE (token + chain; the EVM chains listed, and Solana): keyless chain reads. EVM: bytecode presence and size, the ERC-20 views, the Clanker v4 factory's OWN deployment record, and the Uniswap v3 factory across the four standard fee tiers against wrapped native. Solana (token = the mint): token program (SPL or Token-2022), decimals, supply, mint and freeze authority (revoked is a known fact, distinct from unread), Token-2022 extensions (PermanentDelegate, TransferHook, transfer fee, NonTransferable), the ten largest token accounts as a share of supply, and pump.fun bonding-curve state. A PermanentDelegate, TransferHook or transfer fee is a caution; a NonTransferable mint is a no; there is no go for Solana. Every field is nullable and a null carries its reason. Holder concentration on EVM and Uniswap v4 pools are permanently null and said so. A pool existing is not depth. Nothing in this lane says safe, audited, rug or scam: those are not readings.

SKILL LANE (skill): a skill is a DOCUMENT an agent follows, which is why it is worth checking first. Evidence is the static disclosure the weekly sweep produced: hosts the text names, whether it generates or handles keys, asks for a credential, pipes a remote script into a shell or grants itself tools, each finding WITH the lines that produced it. Nothing is fetched from a registry and no skill is executed. A DISCLOSURE DESCRIBES: it never says safe or malicious, and an empty flag list is "nothing matched", not a pass.

RETURNS (json): { verdict, rule, target: { kind, value, slug, name, sato_url, verify_url }, evidence: [{ check, result, source_field, checked_at }], checked_at, caveat, rules, token?, skill?, solana_receipt? }. token and skill are the raw reports for those lanes; solana_receipt (present with a custody reading) is where that reading is recorded on Solana, or null. Read-only.

X402 LANE (x402): one unpaid request to the resource URL; reports whether it answered 402 and the payment terms it states (network, asset, amount, payTo), against its catalogue entry and our daily record when we hold one. It describes the payee — it is never a reputation score. CUSTODY: repo, package, endpoint and skill results carry custody (Sato Check: does it take your key, does the key leave, can it move funds, what changed) when a profile is on record; custody can only lower a verdict, never raise it.

ADDRESS LANE (address + chain, optional origin and from): the Sato Scan recipient check before a payment, five dated questions (look-alike, issuer's token contract, declared payee, structural mark, address poisoning), rules A1-A7. go is declared, canonical and nothing found within the stated limits, never a clearance. Nothing is stored. The reading on its own: onchain_agent_scan_recipient.

Example: { repo: "coinbase/agentkit" } · { endpoint: "https://mcp.example.com/v1" } · { x402: "https://api.example.com/paid" } · { agent: "base:42" } · { token: "0x1bc0c42215582d5A085795f4baDbaC3ff36d1Bcb", chain: "Base" } · { skill: "clawhub/solana-wallet" } · { address: "0x1bc0c42215582d5A085795f4baDbaC3ff36d1Bcb", chain: "Base" }

Input Schema

NameRequiredDescriptionDefault
fromNoWith `address`: the paying wallet. Lets the reading compare against its own history and say whether it is being targeted by address poisoning. Never stored.
repoNoA GitHub repository: a URL or bare owner/name, e.g. 'coinbase/agentkit'.
x402NoAn https x402 resource URL. ONE unpaid request reads its 402 payment terms (v1 body or v2 PAYMENT-REQUIRED header); no payment is ever sent or signed.
agentNoAn ERC-8004 agent reference, <chain>:<id>, e.g. 'base:42'. Chains: Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain, Avalanche, Gnosis, Robinhood Chain, Celo.
chainNoChain for `token`: Base, Ethereum, Arbitrum, Robinhood Chain, BNB Chain, Polygon, Solana. Anything else answers 'unknown' with the reason, never a guess. For `address` it is the chain the payment would settle on: Base, Solana, Tempo, Polygon, BNB Chain, Arbitrum, Avalanche, Optimism, Ethereum, SKALE Base, Sei, X Layer, Monad, Robinhood Chain, World Chain, Abstract.
skillNoAn agent skill: '<registry>/<id>' (registries: clawhub, skillssh, skills.sh, skills-sh, github), or the skill id alone when it is unique. Reads the static disclosure already on record — nothing is fetched from a registry and no skill is ever executed.
tokenNoAn ERC-20 token contract address, e.g. '0x1bc0c42215582d5A085795f4baDbaC3ff36d1Bcb', or with chain Solana a mint (base58). Needs `chain`.
originNoWith `address`: the https URL whose 402 response named the address (a public host; no credentials). Lets the reading say whether that origin declared it. Never stored.
addressNoA recipient address the caller is about to pay (Sato Scan): 0x + 40 hex on an EVM chain, or a Solana address. Needs `chain`. Never stored.
packageNoAn npm or PyPI package name, e.g. 'solana-agent-kit'. A trailing @version is ignored.
endpointNoAn https MCP endpoint URL. If it is not in the directory it gets a live initialize + tools/list handshake, capped at 8 seconds.
x402_methodNoWith x402: the method the paid request uses; the unpaid probe uses the same one (a body method sends an empty JSON body, never yours). Default: GET, then POST on a 405.
response_formatNoText format; structuredContent is JSON either way.markdown

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed1 schema field changed
    • changedInput schema / properties / chain / description
      Previous value: -"Chain for `token`: Base, Ethereum, Arbitrum, Robinhood Chain, Solana. Anything else answers 'unknown' with the reason, never a guess. For `address` it is the chain the payment would settle on: Base, Solana, Tempo, Polygon, BNB Chain, Arbitrum, Avalanche, Optimism, Ethereum, SKALE Base, Sei, X Layer, Monad, Robinhood Chain, World Chain, Abstract."New value: +"Chain for `token`: Base, Ethereum, Arbitrum, Robinhood Chain, BNB Chain, Polygon, Solana. Anything else answers 'unknown' with the reason, never a guess. For `address` it is the chain the payment would settle on: Base, Solana, Tempo, Polygon, BNB Chain, Arbitrum, Avalanche, Optimism, Ethereum, SKALE Base, Sei, X Layer, Monad, Robinhood Chain, World Chain, Abstract."
  2. Changed2 schema fields changed
    • changedInput schema / properties / chain / description
      Previous value: -"Chain for `token`: Base, Ethereum, Arbitrum, Robinhood Chain. Anything else (Solana included) answers 'unknown' with the reason, never a guess. For `address` it is the chain the payment would settle on: Base, Solana, Tempo, Polygon, BNB Chain, Arbitrum, Avalanche, Optimism, Ethereum, SKALE Base, Sei, X Layer, Monad, Robinhood Chain, World Chain, Abstract."New value: +"Chain for `token`: Base, Ethereum, Arbitrum, Robinhood Chain, Solana. Anything else answers 'unknown' with the reason, never a guess. For `address` it is the chain the payment would settle on: Base, Solana, Tempo, Polygon, BNB Chain, Arbitrum, Avalanche, Optimism, Ethereum, SKALE Base, Sei, X Layer, Monad, Robinhood Chain, World Chain, Abstract."
    • changedInput schema / properties / token / description
      Previous value: -"An ERC-20 token contract address, e.g. '0x1bc0c42215582d5A085795f4baDbaC3ff36d1Bcb'. Needs `chain`. EVM only in v1."New value: +"An ERC-20 token contract address, e.g. '0x1bc0c42215582d5A085795f4baDbaC3ff36d1Bcb', or with chain Solana a mint (base58). Needs `chain`."
  3. Changed1 schema field changed
    • addedInput schema / properties / x402_method
      Added value: +{
      +  "description": "With x402: the method the paid request uses; the unpaid probe uses the same one (a body method sends an empty JSON body, never yours). Default: GET, then POST on a 405.",
      +  "enum": [
      +    "GET",
      +    "POST",
      +    "PUT",
      +    "PATCH",
      +    "DELETE"
      +  ],
      +  "type": "string"
      +}
  4. Changed1 schema field changed
    • changedInput schema / $schema
      Previous value: -"http://json-schema.org/draft-07/schema#"New value: +"https://json-schema.org/draft/2020-12/schema"
  5. Changed1 schema field changed
    • changedInput schema / properties / agent / description
      Previous value: -"An ERC-8004 agent reference, <chain>:<id>, e.g. 'base:42'. Chains: Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain, Avalanche, Gnosis, Robinhood Chain."New value: +"An ERC-8004 agent reference, <chain>:<id>, e.g. 'base:42'. Chains: Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain, Avalanche, Gnosis, Robinhood Chain, Celo."
  6. Changed1 schema field changed
    • changedInput schema / properties / response_format / description
      Previous value: -"Output format: 'markdown' (default) or 'json'."New value: +"Text format; structuredContent is JSON either way."
  7. Changed4 schema fields changed
    • addedInput schema / properties / address
      Added value: +{
      +  "description": "A recipient address the caller is about to pay (Sato Scan): 0x + 40 hex on an EVM chain, or a Solana address. Needs `chain`. Never stored.",
      +  "maxLength": 120,
      +  "type": "string"
      +}
    • changedInput schema / properties / chain / description
      Previous value: -"Chain for `token`: Base, Ethereum, Arbitrum, Robinhood Chain. Anything else (Solana included) answers 'unknown' with the reason, never a guess."New value: +"Chain for `token`: Base, Ethereum, Arbitrum, Robinhood Chain. Anything else (Solana included) answers 'unknown' with the reason, never a guess. For `address` it is the chain the payment would settle on: Base, Solana, Tempo, Polygon, BNB Chain, Arbitrum, Avalanche, Optimism, Ethereum, SKALE Base, Sei, X Layer, Monad, Robinhood Chain, World Chain, Abstract."
    • addedInput schema / properties / from
      Added value: +{
      +  "description": "With `address`: the paying wallet. Lets the reading compare against its own history and say whether it is being targeted by address poisoning. Never stored.",
      +  "maxLength": 120,
      +  "type": "string"
      +}
    • addedInput schema / properties / origin
      Added value: +{
      +  "description": "With `address`: the https URL whose 402 response named the address (a public host; no credentials). Lets the reading say whether that origin declared it. Never stored.",
      +  "maxLength": 300,
      +  "type": "string"
      +}
  8. Changed1 schema field changed
    • addedInput schema / properties / x402
      Added value: +{
      +  "description": "An https x402 resource URL. ONE unpaid request reads its 402 payment terms (v1 body or v2 PAYMENT-REQUIRED header); no payment is ever sent or signed.",
      +  "maxLength": 300,
      +  "type": "string"
      +}
  9. Changed1 schema field changed
    • addedInput schema / properties / skill
      Added value: +{
      +  "description": "An agent skill: '<registry>/<id>' (registries: clawhub, skillssh, skills.sh, skills-sh, github), or the skill id alone when it is unique. Reads the static disclosure already on record — nothing is fetched from a registry and no skill is ever executed.",
      +  "maxLength": 300,
      +  "type": "string"
      +}
  10. Changed2 schema fields changed
    • changedInput schema / properties / agent / description
      Previous value: -"An ERC-8004 agent reference, <chain>:<id>, e.g. 'base:42'. Chains: Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain, Avalanche, Gnosis."New value: +"An ERC-8004 agent reference, <chain>:<id>, e.g. 'base:42'. Chains: Ethereum, Base, Arbitrum, Optimism, Polygon, BNB Chain, Avalanche, Gnosis, Robinhood Chain."
    • changedInput schema / properties / chain / description
      Previous value: -"Chain for `token`: Base, Ethereum, Arbitrum. Anything else (Solana included) answers 'unknown' with the reason, never a guess."New value: +"Chain for `token`: Base, Ethereum, Arbitrum, Robinhood Chain. Anything else (Solana included) answers 'unknown' with the reason, never a guess."
  11. Changed2 schema fields changed
    • addedInput schema / properties / chain
      Added value: +{
      +  "description": "Chain for `token`: Base, Ethereum, Arbitrum. Anything else (Solana included) answers 'unknown' with the reason, never a guess.",
      +  "maxLength": 40,
      +  "type": "string"
      +}
    • addedInput schema / properties / token
      Added value: +{
      +  "description": "An ERC-20 token contract address, e.g. '0x1bc0c42215582d5A085795f4baDbaC3ff36d1Bcb'. Needs `chain`. EVM only in v1.",
      +  "maxLength": 120,
      +  "type": "string"
      +}
  12. Added

TDQS

A4.8/5.0
Behavior5/5

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

Annotations already declare readOnlyHint/idempotentHint/destructiveHint=false, but the description goes well beyond them: it defines verdict semantics (go/caution/no/unknown), states that 'unknown' means no record rather than something being wrong, caps the live endpoint handshake at 8 s and forbids a 'go' result from it, explains that custody can only lower a verdict, notes that nothing is stored, and that nulls carry their reason. This is unusually rich behavioural disclosure for a read-only tool.

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?

Front-loaded with USE WHEN and NOT FOR, then lane-by-lane and return-shape sections, so an agent can skim. It is long and occasionally repetitive (the 'never a security review' caveat recurs across the token, skill and address lanes), but for a 13-parameter, five-lane tool the length is largely earned and the sectioning keeps it navigable.

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?

With no output schema present, the description carries the full return contract and does so: it enumerates the JSON shape (verdict, rule, target, evidence[], checked_at, caveat, rules, token?, skill?, solana_receipt?) and explains what each lane's evidence means. Combined with the lane definitions and the no-`go`-for-Solana rule, an agent has everything needed to call and interpret this tool.

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%, so the baseline is 3, but the description adds constraints the schema does not encode — 'Pass exactly one of repo, package, endpoint, agent, token, skill, x402 or address' (no oneOf in the schema) and the token+chain / address+chain lane pairings. It also explains that a null field carries its reason. That is genuine meaning beyond the per-parameter descriptions.

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?

Opens with a specific verb and a concrete set of triggers ('install a package, clone a repo, connect to an MCP endpoint, pay an agent, or trade a token') and states what it produces (every evidence line with source field and date). It explicitly names the siblings it is not — onchain_agent_recommend_stack, onchain_agent_get_deploy_spec, onchain_agent_check_install, onchain_agent_scan_recipient — so an agent can distinguish it without opening any schema.

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?

Contains an explicit USE WHEN block and an explicit NOT FOR block that routes each excluded case to a named alternative tool or lane. It also names the fallback behaviours: 'with none (or a template placeholder) nothing is checked' and the not-a-pick case. Nothing about when to select this tool versus its siblings is left to inference.

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.