Ava

Your coding agent can do everything except move money onchain.Ava is the part that can.

It ships the app, runs the research, books the flight, buys the thing. Ask it to supply 300 USDC to Morpho on Base and bridge the rest to Avalanche and you get an explanation, maybe some code, and no transaction. Ava takes one sentence and turns it into dependent actions across chains, carried out under authority you granted and bounded before anything runs.

“Supply 300 USDC to Morpho on Base, bridge no more than 200 to Avalanche, then supply what arrives to Aave”
Three actions, each waiting on the one before it. The third supplies the amount the bridge actually delivered, not 200, because a bridge delivers less than it accepts and a number picked at planning time is wrong by exactly the fee.

Works from Claude Code and Cursor over MCP, from an OpenClaw skill, or over plain REST.

The refusal is real, read from the live API when this was cut.

What an agent sees on first contact

No email, no CAPTCHA, no wallet popup. One unauthenticated POST returns an identity and a token, which is the whole of signup for something that has no hands and cannot click a confirmation link.

Onboarding, as an agent sees it1 REQUEST
$ curl -sX POST https://www.getava.xyz/v1/users/session \
    -H 'content-type: application/json' -d '{}'

{
  "ok": true,
  "user": {
    "userId": "usr_ff7f5cc6018c7a63",
    "createdAt": "2026-07-29T12:27:17.552Z"
  },
  "wallets": [], "agents": [],
  "token": "ava_st_…"  // shown once
}

No CAPTCHA, no wallet popup, no email confirmation. The id names the account, the token proves the agent holds it, and from here the agent creates its own instance, provisions a policy gated wallet, and files a mandate against it.

One sentence becomes a dependent plan

This is the plan returned by ava_plan_workflow. Three legs, with the bridge result carried into the action that follows it.

What the user types
“Supply 300 USDC to Morpho on Base, bridge no more than 200 to Avalanche, then supply what arrives to Aave”
What Ava returnsava_plan_workflow
leg_1  lend    base       morpho   USDC  300
leg_2  bridge  base -> avalanche   USDC  max 200
leg_3  lend    avalanche  aave     USDC  amount from leg_2
  • leg_3 waits for leg_2. Dependency, not a list.
  • leg_3 uses what the bridge delivered, not 200. A bridge delivers less than it accepts.
  • leg_2 has a 200 ceiling, not a spend target. Ava moves only what it needs.
“swap 100 USDC to WETH on Base then supply the WETH to Aave”
leg_1  swap  base  USDC -> WETH  100
leg_2  lend  base  aave  WETH  amount from leg_1
Same chain, same dependency. The second leg is denominated in WETH, the token the swap produced.

7 transactions, confirmed on 4 mainnets

Ava built the calldata, signed it with its own Turnkey key, broadcast it, and the chain confirmed it. Not a testnet, not a simulation. Every row below is re-read from that chain's own node before this page is allowed to build, so a wrong venue name fails the deploy rather than reaching you.

ChainVenueActionTransactionBlock
BaseMorpho gtUSDCpsupply USDC0x97b78540…36bbba49315911
BaseMorpho gtUSDCpwithdraw USDC0xce4109e4…6b0a7f49327027
AvalancheAave v3supply USDC0x12990c11…f4209f92231544
BNB ChainAave v3supply USDC0x7737cf5c…08b9de114508635
MonadAave v3supply USDC0x50940c95…8715cf92954146
MonadAave v3supply USDC0x1b23c35d…628af793291520
BNB ChainSushiSwap via LI.FIswap, no venue adapter0x14850931…de0542114518492

A block explorer proves the transaction happened. It does not prove the transaction was the one you authorised. For that, read Ava’s own re-read of the Monad row, which compares what settled against what was authorised and needs no credential to open. These are small amounts on purpose. They show the path executing, not a claim that it is ready for unattended capital.

callable today

  • Morpho Blue on Base
  • Aave v3 on Monad
  • Aave v3 on Avalanche
  • Aave v3 on BNB Chain

Four lending routes accept a live execution through the authenticated API. Every other venue in the registry carries a machine-readable reason it does not: no executor implemented, an executor no public route imports, operator disabled, or proven by direct script only. The registry is the same object the executor consults, so the list on this page and the answer at signing time cannot disagree.

The last transaction routed through SushiSwap. There is no SushiSwap code in this repository.

No adapter, no address book, no ABI. It touched six contracts across seventeen logs, none of which Ava can decode. It executed inside its mandate and was verified against the chain anyway, because the gate reads what the bytes will move rather than which protocol wrote them.

27

adapters written the venue-by-venue way

4

live venues those 27 adapters actually produced

1

generic integration, reaching every venue an aggregator can route to

An adapter is a bet that a venue will not change. Every new protocol costs another one, every upgrade breaks the last one, and the list of things an agent may safely do stays pinned to the size of an engineering team. Bounding the calldata removes that ceiling: the work is done once, and a venue nobody has heard of yet is already covered on the day an aggregator learns to route to it.

This is also the part that does not commoditise. Routing is already free and getting cheaper. Proof that the money did what was authorised is the thing that has to be built once and stays built.

the transaction in question
0x14850931…de0542
chain
BNB Chain
routed by
LI.FI
filled at
SushiSwap
adapter in repo
none
callable from the API
not yet

This one settled through a direct script. The generic route is registered prepare-only until the API path is wired, because a registry that advertises a route the API cannot execute is worse than one that admits the gap.

A mandate is not a spend limit

A spend limit answers one question: how much can leave. It has no opinion about whether the agent is doing the job you hired it for, and nothing to say when the agent quietly starts doing something else.

How much capital
SPEND LIMITAn allowance per period, shared by everything the key can do.
AVA MANDATEAsset, amount and chain, scoped to one agent instance. Two agents under the same person cannot spend each other's budget.capital
What it may do with it
SPEND LIMITAny call the key is permitted to make.
AVA MANDATEAn explicit list of kinds. A swap submitted under a lend mandate is refused, even when the swap itself is a perfectly safe transaction.constraints.allowedKinds
How much may be lost
SPEND LIMITNot represented. A limit cannot tell a good fill from a bad one.
AVA MANDATEA drawdown ceiling and a notional ceiling, enforced against whichever binds tighter, the explicit cap or the capital actually funded.constraints.maxDrawdownPct
At what execution quality
SPEND LIMITNot represented.
AVA MANDATEA slippage ceiling in basis points and an optional venue preference, carried into the plan before a quote is accepted.constraints.maxSlippageBps
When it should act
SPEND LIMITWhenever it is asked.
AVA MANDATEConditions evaluated continuously against live prices, so the agent acts on the market rather than on a prompt.conditions
Who can widen it
SPEND LIMITWhoever holds the key.
AVA MANDATENobody at runtime. Not the model, not the user message, not a tool call. The terms are fixed at creation and hashed.mandateHash

Where a mandate can operate

A mandate names its own chain, and Ava refuses an action on any venue it cannot settle. These are the venues with a mainnet settlement behind them today.

  • BaseMorpho gtUSDCp
  • AvalancheAave v3
  • BNB ChainAave v3
  • MonadAave v3
  • BNB ChainSushiSwap via LI.FI

Ava fails closed

When an action falls outside the mandate, or a venue is missing, or a signature never arrives, Ava stops and records the refusal. It does not invent a fill, and there is no path that turns a refused execution into a success receipt. Refusals are counted in the track record next to the wins, because an agent that never refuses anything is not being held to anything.

Typed refusal codes

  • MANDATE_KIND_NOT_ALLOWED
  • MANDATE_NOTIONAL_EXCEEDED
  • MANDATE_DRAWDOWN_BREACH
  • MANDATE_PAUSED
  • MANDATE_CANCELLED
  • MANDATE_COMPLETED

Your agent branches on the code. It never has to parse an apology.

Every agent session getsits own wallet.

Three Claude Code windows, a Cursor tab and a Grok agent are five different actors, not one user. Ava gives each session its own Turnkey wallet and its own mandate, so a limit you set for the agent refactoring your billing code does not travel to the one reading your inbox.

When one of them spends, the receipt names which session did it. That is the difference between an audit trail and a shrug.

Scoped, not shared
A mandate binds to one agent instance. Revoking it stops that session and leaves the others running.
Attributable by default
Every receipt carries the agent that requested it, so “which one did this” is a lookup, not an investigation.
ava_session -> usr_ff7f… / agent_a3f1
ava_provision_wallet -> 0x340340…F1db active
ava_create_mandate -> 250 USDC on Base, lend only
$ cursor # session B, same human
ava_session -> usr_ff7f… / agent_b7c2
ava_provision_wallet -> 0x9c1b22…7ae0 active
session B tries session A's mandate
MANDATE_NOT_FOUND refused. not yours.

Receipts that state how much they can prove

Most agent tooling logs what it meant to do. A receipt with no standing attached quietly turns a ledger of evidence into a ledger of claims, and by the time anyone checks, the two look identical.

GET /v1/receipts/exe_5f1c0a7d94b2NO PROOF
receiptVersion
"ava.exec.v1"
executionId
"exe_5f1c0a7d94b2"
mandateId
"mdt_fc3dfbf28fc74945"
mandateHash
"4bd430490ee29e38811275c3c4689e573fed2e435ef57f965d5852b452d2b44f"
venue
"morpho"
status
"rejected"
venueOrderId
null
txHash
null
llmUsedInHotPath
false
timestamps.createdAt
"2026-07-29T12:28:16.555Z"

MANDATE_KIND_NOT_ALLOWED Intent kind "swap" is not in the mandate's allowedKinds [lend, strategy]. The execution stopped at the gate, so the receipt carries no order id and no transaction hash, and it does not pretend to.

Three standings, never collapsed into one

  • chain confirmed

    A public RPC confirmed the transaction. This is the only standing that counts as proven anywhere in Ava.

  • unconfirmed

    An identifier exists, supplied by an external signer, and nothing independent has checked it yet. A claim, not a proof.

  • no proof

    Nothing was ever submitted to a venue or a chain. The receipt says so rather than going quiet.

"receiptsProven counts only receipts whose proofStanding is chain-confirmed"

Served verbatim in the verification block of every agent record. The rule ships with the data so a reader does not have to take Ava's word for how the number was counted.

Recompute the digest yourself over the canonical unsigned receipt, or ask the API to do it at GET /v1/receipts/:executionId/verify.

Ava runs inside the agent you already use

It is an MCP server and a REST API, so the agent does not install a wallet, a browser extension, or a new app. It points at one URL and gets a session, a mandate, and a receipt.

Claude Code

claude mcp add --transport http ava

one command

Cursor

~/.cursor/mcp.json

workspace or global

Codex

~/.codex/config.toml

verified config

Grok

~/.grok/mcp.json

verified config

OpenCode

opencode mcp add

MCP client

Anything else

plain REST

no MCP client required

https://getava.xyz/mcp

What an agent can reach through it today, across 4 mainnets:

  • BaseMorpho gtUSDCp
  • AvalancheAave v3
  • BNB ChainAave v3
  • MonadAave v3
  • BNB ChainSushiSwap via LI.FI

The agent brings no key. Ava provisions a policy-gated wallet held in a Turnkey enclave, files the mandate against it, and refuses anything the mandate does not cover.

Who this is for

Two people meet at the same sentence. One is giving an agent the one thing it cannot do on its own, one is putting up the money, and both need the plan to say what it will really do before it does it.

You are giving an agent onchain reach

Your agent already writes the code and does the research. What it cannot do is name a venue, build the calldata for that venue on that chain, and carry a runtime amount from one leg into the next. It hands Ava a sentence and gets back dependent actions with the venue, the chain and the dependency filled in.

One POST gets a session, and from there the agent provisions its own wallet and files its own mandate on the same public API. Twenty one tools are exposed over MCP, so an agent in Claude Code or Cursor reaches them without you writing a client, and the OpenClaw skill and plain REST hit the same surface. What Ava cannot execute comes back as a typed refusal with the offending values attached, never as a plausible substitute action.

Install the MCP server

It is your capital moving

You type what you want in one sentence. Ava reads back the plan leg by leg, with the amount, the venue and the chain on each one, and a missing chain is a question it asks rather than a detail it invents. Nothing moves until you approve that plan, or until it fits inside bounds you signed earlier.

Run several agents at once and each gets its own wallet and its own isolated risk budget, so a bad week from one of them cannot reach the others. Pause any of them, or all of them, in one call.

Write your first mandate

One sentence in. Dependent actions across chains out.

Give your agent the piece it is missing, and give it under terms you set first and a record someone other than you can check. Start with a session and a plan on the public API. No key, no signup.

Check that any of this is live before you write a line of code.

$ curl -s https://www.getava.xyz/health
{ "ok": true, "productionMode": true }