Build a TON Trading Agent with MCP: Read, Quote, Swap
A TON trading agent on MCP: how an agent reads balances, gets a firm quote, and builds a non-custodial swap — get_balance, get_swap_quote, build_swap_tx.
The problem every TON trading agent runs into first
You ask an AI agent to "swap 50 USDT for GRAM when the price dips" — and it sends a transaction for 50,000 USDT instead of 50. That's because USDT on TON has decimals = 6 (50 USDT = 50,000,000 raw units), while the agent defaulted to the usual nine-zero jetton math — and inflated the amount by a factor of 1000. A 1000x error, real money, an irreversible transaction. The mirror-image bug has the same root cause: the agent sees a raw 1000000000 in the balance and confidently reports "you hold a billion USDT" when it's actually 1,000.
These aren't made-up horror stories — they're exactly the traps everyone walks into when wiring an LLM into TON DeFi through raw RPC: mixed-up decimals, no way to read a jetton balance without the jetton-wallet address, a private key leaking through the context. Below is how to build a TON trading agent that reads balances, gets a firm quote, and builds a swap — without ever touching your keys. The tool: TONNode, a hosted MCP server for TON.
What a TON trading agent is and why it needs MCP
A trading agent is an LLM (Claude, Cursor, Codex, or any other MCP client) that can read network state and prepare trades on request: "show my USDT balance", "how much GRAM do I get for 500 USDT", "build the swap". On its own, the model can't see the blockchain — it needs tools.
That's exactly what MCP (Model Context Protocol) does — the standard agents use to call external tools. Instead of teaching the model to hand-craft raw ADNL requests and parse BOC cells, you hand it a set of typed functions: "get balance", "get quote", "build transaction". TONNode plugs in as a source of those tools and gives the agent exactly 16 functions for working with the network: reads, swaps, cross-chain, wallet generation.
A trading agent needs five of them, and all five are available even on the free plan:
read (get_balance, get_jetton_balance)
-> pin down decimals (get_jetton_info)
-> quote (get_swap_quote)
-> build the swap (build_swap_tx)
-> the wallet signs via TonConnect
The key detail in that last step: it's the user's wallet that signs, not the server. TONNode returns unsigned messages — we'll get to why that's non-negotiable at the end.
Step 1: the agent reads balances (get_balance, get_jetton_balance)
Before swapping anything, the agent has to know what it's working with. Two tools:
get_balance— the GRAM balance of an address. GRAM is Toncoin, renamed in June 2026; the network itself is still called TON.get_jetton_balance— the balance of a jetton: USDT, NOT, anything else. The magic here is that the jetton wallet is derived on-chain. You pass the owner address and the jetton master address, and TONNode derives the jetton-wallet address itself and reads its balance. No need to know that address up front or store it anywhere.
The prompt to the agent is literally just this:
Check wallet UQAbc...xyz:
how much GRAM and how much USDT does it hold?
Under the hood the model calls get_balance for the native balance and get_jetton_balance for USDT. One catch: what comes back isn't "human" amounts yet — it's raw units. And this is where it gets important. For how to get a USDT balance in one call without wrestling with jetton-wallet addresses, there's a separate deep dive: /blog/usdt-balance-ton-one-call.
decimals decide everything: get_jetton_info and why USDT = 6
Balances and amounts on TON are stored in raw units — integers with no fractional part. To get a human-readable amount, you divide the raw number by 10^decimals. And here's the trap: different jettons have different decimals.
- USDT has
decimals = 6. So1 USDT = 1,000,000raw units. - Most jettons on TON have
decimals = 9(like GRAM). So1 token = 1,000,000,000raw units.
Mixing up 6 and 9 means being off by exactly 1000x. That's the "billion USDT" from the top of this article. For a trading agent this isn't cosmetic — it's the whole basis for trusting it: if it confuses orders of magnitude, it cannot be allowed to build trades.
That's why the pipeline has get_jetton_info built into it — it returns the jetton's metadata: name, symbol, supply, and — most importantly — decimals. The correct logic inside the agent:
raw = get_jetton_balance(...) // e.g. 1000000000
decimals = get_jetton_info(...) // for USDT → 6
human = raw / 10 ** decimals // 1000000000 / 1e6 = 1000 USDT
The same raw value at decimals = 9 would be 1 token — a wildly different answer. Don't hardcode decimals in the prompt and don't let the model "recall" them from memory: on a new jetton it will get them wrong. Have it pull them from get_jetton_info every single time and recompute from the actual value. A detailed breakdown of this trap and why it costs people money: /blog/jetton-decimals-ton.
Step 2: a firm quote via Omniston (get_swap_quote)
Balances are read and converted into the right units — now the agent needs a price. In DeFi, a "rough price from memory" doesn't work: liquidity is spread across several DEXes, the rate keeps moving, and the agent has to work from a live quote, not a guess.
get_swap_quote returns a firm quote for a GRAM ⇄ jetton swap via the Omniston protocol, which aggregates liquidity from TON's two largest DEXes — STON.fi and DeDust. The agent doesn't have to poll pools, compare prices, or compute slippage itself: Omniston returns the best route from the combined liquidity.
Get me a quote: how much GRAM do I get for 50 USDT right now?
The model calls get_swap_quote with the amount 50000000 (those raw units from the previous step) and gets concrete numbers back: how much goes in, how much comes out, over which route, with what slippage. This is the decision point: if the agent has a condition ("only swap if the rate beats X"), it compares the quote against the threshold and either moves forward or waits for the next iteration. Important: a quote is not a trade. No funds move, nothing gets signed. It's a pure market read.
Step 3: building the unsigned swap (build_swap_tx) and signing in the wallet
The user sees the quote and says "yes, let's swap." The agent calls build_swap_tx and gets back an unsigned transaction for the swap, ready for TonConnect.
Note the word "unsigned." The server assembles a correct message — recipient address, payload, amount, route parameters — and returns it as-is. The message then goes to the user's wallet (Tonkeeper, MyTonWallet, anything TonConnect-compatible), the user sees exactly what they're signing, and confirms it themselves. The signature comes from the user's private key, which lives in their wallet — not on the server.
get_balance / get_jetton_balance → read what you hold
↓
get_jetton_info → pin down decimals, convert
↓
get_swap_quote (Omniston) → firm quote
↓
build_swap_tx → unsigned transaction
↓
user's wallet (TonConnect) → sign and send
Every step is a separate, explicit tool call. The agent never takes liberties with money on its own initiative: it prepares, and the decision and the signature stay with the human. The full non-custodial swap walkthrough, from quote to signature, is laid out step by step here: /blog/agent-swap-ton-noncustodial.
Non-custodial by design: why the server never holds the agent's keys
This isn't marketing copy — it's an architectural boundary. TONNode's swap, cross-chain, and wallet-generation tools are strictly non-custodial:
- The server never signs transactions.
- The server never stores private keys or funds.
- Everything it hands out is unsigned TonConnect messages.
Why does this matter for a trading agent specifically? Because an agent by definition works with money and by definition can screw up — misread the request, mix up an amount, get stuck in a loop. If the keys lived on the server and it signed on its own, an agent's mistake would mean lost funds without you ever knowing. In the non-custodial scheme, you are the last line of defense: not a single transaction leaves until your wallet confirms it.
Compare that with the official @ton/mcp from the TON Foundation — a custodial agent wallet: it holds an operator key and signs on its own (a split-key scheme where the agent holds the operator key and the user holds the owner key). It has genuine strengths — autonomous spending with no human in the loop, NFT and DNS support, official Foundation status. But the trust model is different: there, the agent really can move funds. TONNode deliberately draws the opposite boundary: the server signs nothing, ever. A full comparison of the two approaches: /blog/custodial-vs-noncustodial-mcp.
How to hook it up and start in 5 minutes
Good news: building the trading pipeline costs nothing. But don't confuse the two free paths — they come with different tool sets.
The local public config gives you the full read set (8 tools: get_masterchain_info, get_balance, get_account_state, get_transactions, run_get_method, get_jetton_balance, parse_address, get_jetton_info). Installs via npx, no key required:
{
"mcpServers": {
"ton": {
"command": "npx",
"args": ["-y", "@tonnode/mcp"]
}
}
}
The @tonnode/mcp package is open source (MIT), lives on npm and GitHub (tonnode/mcp), and speaks TON's native ADNL protocol with no HTTP layers between the agent and the network. Drop the config into Claude Desktop, Cursor, or any MCP client — and your agent can already read balances and call get_jetton_info.
The quotes themselves, though — get_swap_quote and build_swap_tx — belong to the SWAP group and go through the hosted endpoint. Here's the key point: the free Hobby key unlocks all 16 tools, including quoting and swap building. So the entire trading pipeline (read → quote → swap) can be built for free — but through the hosted Hobby key, not the local public config. The hosted endpoint config:
{
"mcpServers": {
"ton": {
"type": "http",
"url": "https://mcp.tonnode.io/mcp",
"headers": { "Authorization": "Bearer tn_live_…" }
}
}
}
TONNode has exactly 16 tools, and every plan gets all 16 — you pay only for throughput, never for features:
- Hobby — free forever, 60 requests/min, no card.
- Pro — $29/mo, 300 requests/min.
- Scale — $199/mo, 1200 requests/min.
For getting started and putting the trading pipeline through its paces, the free Hobby key is more than enough: 60 requests per minute covers a lot of sequential agent calls. No card required, and the key is issued right after sign-in.
Get a free Hobby key (60 req/min, no card): tonnode.io/dashboard?plan=hobby
The full list of 16 tools: tonnode.io/mcp · Pricing: tonnode.io/pricing
Wire up the five-tool pipeline — get_balance, get_jetton_balance, get_jetton_info, get_swap_quote, build_swap_tx — keep decimals under control, and leave signing to the wallet. What you get is a trading agent that reads balances accurately, takes a firm quote, and prepares swaps for real amounts — without ever getting access to anyone's keys. That's exactly how a TON trading agent should work.
Give your agent TON access
16 MCP tools: reads, non-custodial swaps, cross-chain and wallets. Free tier — 60 req/min, no card required.