How to Call Any TON Contract Get-Method Without an SDK
Call any TON contract get-method via run_get_method, no SDK needed: seqno, get_jetton_data, get_sale_data, arguments, exit_code and stack parsing.
You opened an explorer just to check a wallet's seqno before sending a transaction. Or you need a jetton's total_supply. Or the details behind an NFT listing on a marketplace. And here you go again: npm i @ton/ton, spin up a TonClient, hunt for a lite server endpoint that actually works, figure out how to pack an address with beginCell().storeAddress(), then parse the output BOC by hand. Thirty lines of code — for one number the contract hands out for free anyway.
The problem isn't TON. The problem is that between you and a simple read-only call sits an entire SDK layer you have to install, configure, and keep from breaking on the next update. And if you're wiring an AI agent (Claude, Cursor, ChatGPT/Codex) into TON, writing that layer by hand is outright absurd: the agent should just call the method.
Here's how to call any get-method of any TON contract via run_get_method, without a single line of SDK client code.
What a TON contract get-method is, and why people usually drag in an SDK
A get-method is a read-only function of a smart contract. A wallet exposes seqno, a jetton master contract exposes get_jetton_data, an NFT sale contract exposes get_sale_data, a STON.fi/DeDust pool exposes get_pool_data. The key word is read-only:
- the method changes nothing in the contract's state;
- it requires no signature and burns no user gas;
- it runs on a lite server or in the TVM emulator (TON Virtual Machine), not by sending a transaction.
In other words, calling a get-method is not a transaction. There's nothing to sign, nothing to pay for, nothing to wait for in a block. It's essentially a "read a value from a live contract" function.
But to call it "the old way", you need a whole rig: an SDK (ton, tonweb, tonutils), your own ADNL client talking to a lite server or an HTTP wrapper like toncenter, manual packing of input arguments into cells, and manual parsing of the output BOC. A lot of moving parts for a single read. And every one of them is a point of failure: the public lite servers from the global config are shared and rate-limited, and under load they respond with not ready or an ADNL timeout; public HTTP APIs return 429 Too Many Requests once you exceed the limit (roughly one request per second without a key).
run_get_method: one tool for any read-only method of any contract
run_get_method is an MCP tool that calls any read-only get-method of any TON contract. You pass the contract address, the method name, and a list of arguments — the tool executes the method on-chain via TVM and returns the output stack.
What you don't have to do:
- install and update an SDK (
ton/tonweb/tonutils); - write your own ADNL client;
- manually pack arguments into cells and parse the output BOC.
run_get_method is part of the read toolset of TONNode — a hosted MCP server for TON. MCP (Model Context Protocol) is the standard AI agents use to call tools. The entire read toolset is available for free, locally via npx -y @tonnode/mcp (public config, no card), or via the hosted endpoint https://mcp.tonnode.io/mcp with a Bearer key. You can try it right now without buying anything.
Arguments and the stack: passing input and parsing TVM output
The TVM works with a stack. Think of it this way: you lay a few "cards" with input values on the table, the method picks them up, does its work, and lays down new "cards" with the result.
Input is passed as values on the TVM stack. Typically that's:
int— integers (say, an index, an amount in raw units, a query id);- an address
slice— an address packed into a cell slice; cell— an arbitrary data cell.
Output comes back as a stack of values: int, slice, cell, tuple. The agent parses it by position — first value, second, third. For example, get_jetton_data returns, in order: total_supply (int), the mintable flag, admin (slice address), content (cell), and the wallet code (cell). Position determines meaning — that's part of the contract's own ABI convention.
Many useful methods (seqno, get_jetton_data) take no input at all — the argument stack is empty. Arguments show up where the method looks something up by key: computing a jetton wallet address from an owner address, for instance.
One important nuance: run_get_method returns the raw stack in raw units. Numbers arrive as-is, with no decimals conversion and no turning cells into readable strings. That's flexible, but it means you have to understand what you're reading — we'll come back to this in the get_jetton_info section.
exit_code: how to tell the method actually ran
Every get-method call has an exit_code — the TVM completion code. Parsing the output stack only makes sense if the call succeeded in the first place. The rule for get-methods is counterintuitive, and it's worth memorizing:
exit_code0 and 1 mean success (both count as normal completion, so don't be alarmed by a 1);exit_code> 1 means an error, and the output stack can't be trusted.
Common error codes:
| exit_code | What it means |
|---|---|
| 2 | stack underflow — fewer arguments were pushed than the method expects |
| 4 | integer overflow / division by zero |
| 11 | usually a call to a nonexistent method (typo in the name) |
| 13 | out of gas |
In practice: got a 2 — check that you passed all the arguments, in the right order. Got an 11 — you most likely misspelled the method name, or the contract doesn't implement it. Got a 13 — the method is heavy and hit the gas limit.
Examples through an agent: seqno, get_jetton_data, get_sale_data
The best part is when run_get_method gets called not by a human but by an agent. You state the task in plain words; the agent picks the address, the method name, and the arguments on its own, gets the stack back, and explains the fields.
seqno before sending. seqno is the wallet's outgoing transaction number, and you read it before assembling a transfer: without it, the message won't go through.
Prompt to the agent: "Call
seqnoon my walletUQD…and tell me the current number."
The agent calls run_get_method with no arguments, gets a single int on the output stack, and hands you the number.
get_jetton_data — jetton master metadata. The method returns total_supply, the mintable flag, the admin address, and content.
Prompt to the agent: "Call
get_jetton_dataon this USDT master and break down the fields."
The agent hits run_get_method with the master address and the name get_jetton_data, reads the stack, and explains the positions. There's an important catch here — more on it below.
get_sale_data — NFT listing data. This isn't a separate NFT tool — it's the same run_get_method: you're reading the marketplace sale contract's own get-method. get_sale_data returns the price, the seller, and the deal status — handy for figuring out whether the NFT has already sold or is still listed.
Prompt to the agent: "Read
get_sale_datafrom this sale contract and tell me the price in GRAM."
You don't write a client at all. The agent calls a single tool. Other everyday methods — get_wallet_data (jetton wallet data), get_pool_data (STON.fi/DeDust pools) — are called exactly the same way: method name, address, arguments if needed.
get_jetton_data or get_jetton_info: when you need a human-readable answer
Here's the main trap. run_get_method returns a raw stack: get_jetton_data will give you total_supply as a giant integer in raw units, and content as a cell you still have to dig the name and symbol out of. No "USDT", no "6 decimals", no pretty number — this is low-level TVM output. If low-level access to the master contract or a nonstandard field is exactly what you're after, this is your tool.
But if the task is simply getting a jetton's name, symbol, and decimals in ready-to-use form, don't wrestle with cell parsing. There's a separate tool for that — get_jetton_info: it returns the name, symbol, decimals, and supply already parsed.
Why this is critical: you need decimals to convert raw units into real amounts. USDT on TON has decimals = 6, while most jettons have 9. If you take total_supply from raw get_jetton_data and don't divide by 10^decimals, you get a number that's off from reality by a factor of a million or a billion. More on this trap in the deep dive on jetton decimals in TON.
The rule is simple:
- you need the raw contract fields (supply, admin, content, an arbitrary custom method) →
run_get_method+get_jetton_data; - you need a ready human-readable answer about a jetton (name, symbol, decimals) →
get_jetton_info.
Don't confuse the raw numbers from get_jetton_data with the parsed answer from get_jetton_info.
Two handy helpers: parse_address and get_account_state
Before calling a method, it pays to tidy up the address and make sure the contract is even alive:
parse_address— normalizes an address between theEQ/UQ/raw formats, offline, with no network access. TON has several address formats, and not every method accepts every one of them, so it's worth converting a user-suppliedEQ…into the right form before you drop it into your arguments.get_account_state— checks the contract's status, flags, and last transaction. If the account isn't deployed (uninit) or is frozen, any get-method will predictably fail — it's cheaper to check the state upfront than to puzzle over a crypticexit_code.
How to connect and call without a single line of client code
Two paths. The first is free and local: the whole read toolset via the public config, no card:
{
"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 middlemen. There's a separate write-up on the free path — free MCP for TON.
The second is the hosted endpoint, with guaranteed throughput and your own key:
{
"mcpServers": {
"ton": {
"type": "http",
"url": "https://mcp.tonnode.io/mcp",
"headers": { "Authorization": "Bearer tn_live_…" }
}
}
}
All 16 tools are available on every plan — you only pay for throughput. The free Hobby key (60 requests/min) is issued right after sign-in, no card required.
Once connected, the entire read toolset — including run_get_method, get_jetton_info, parse_address, get_account_state — is available to the agent as regular tools. A call looks like an ordinary sentence in chat: "call get_pool_data on this DeDust pool", "read the seqno of this wallet" — and the agent picks run_get_method and the arguments itself, then explains the fields. And if the task is checking a USDT balance, there's a ready-made one-command path: USDT balance on TON in one call.
Grab a free Hobby key and call run_get_method straight from your agent → tonnode.io/dashboard?plan=hobby. The key is issued right after sign-in, no card, 60 requests per minute — more than enough headroom for reading contracts.
Don't even want to sign up? Run it locally: npx -y @tonnode/mcp. The full tool list and parameters are on tonnode.io/mcp.
Reading blockchain state no longer means assembling a client. It means phrasing a request.
Give your agent TON access
16 MCP tools: reads, non-custodial swaps, cross-chain and wallets. Free tier — 60 req/min, no card required.