{"name":"tokens","oldName":"get_token_accounts","title":"Tokens held","category":"wallets","useWhen":"Run when you need to know which tokens a wallet holds and how much. Ranked by USD value, with unverified (often spam airdrop) tokens flagged so you don't report fake holdings.","benefit":{"kind":"accuracy","text":"Ranks holdings by USD value and flags unverified tokens, so an agent doesn't report a wallet's spam airdrops as real money."},"description":"Lists a wallet's tokens (SPL Token and Token-2022) with exact amounts, whether each is verified, and its USD value where there's a price.","price":"$0.01","priceText":"25 free calls a day, then $0.01 USDC per call (x402)","http":{"method":"POST","path":"/api/tools/tokens","body":"JSON object with the inputs below"},"mcp":{"method":"tools/call","name":"tokens"},"inputs":[{"name":"wallet","type":"string (base58 address)","required":true,"lookingFor":"The wallet address to read the tokens of.","whereToGet":"The user's wallet address (from their wallet app, or your agent's own public key). Not a .sol name or a ticker."},{"name":"how_many","type":"integer 1-100","required":false,"lookingFor":"How many tokens, highest USD value first, to return. Default 25.","whereToGet":"Leave it out for 25."},{"name":"include_empty","type":"boolean","required":false,"lookingFor":"Whether to include empty token accounts. Default false.","whereToGet":"Set true only to find empty accounts (for example to close them)."},{"name":"network","type":"\"mainnet-beta\" | \"devnet\"","required":false,"lookingFor":"Which Solana network to read. Default \"mainnet-beta\" (real money).","whereToGet":"Leave it out for mainnet. Use \"devnet\" only for test wallets."}],"outputs":[{"field":"wallet","type":"string","is":"The wallet that was read.","howWorkedOut":"Your input, cleaned up."},{"field":"accounts_total","type":"number","is":"Every token account the wallet owns, empty ones included.","howWorkedOut":"Token accounts across the SPL Token and Token-2022 programs."},{"field":"accounts_with_balance","type":"number","is":"Token accounts holding more than zero.","howWorkedOut":"Accounts with a raw amount above 0."},{"field":"returned","type":"number","is":"How many tokens are in this answer.","howWorkedOut":"Up to how_many, after sorting."},{"field":"unverified_count","type":"number","is":"Returned tokens Jupiter doesn't mark verified. A big number usually means spam airdrops.","howWorkedOut":"Tokens without Jupiter's verified flag, or that Jupiter doesn't know."},{"field":"total_usd","type":"number","is":"USD value of the returned tokens that are verified and priced. Spam often has a price from a tiny pool, so unverified tokens are left out.","howWorkedOut":"Sum of tokens[].usd_value for verified tokens. Unpriced tokens add nothing, so this can be low."},{"field":"unverified_usd","type":"number","is":"The claimed USD value of the unverified tokens, kept apart. Don't trust it.","howWorkedOut":"Sum of tokens[].usd_value for unverified tokens."},{"field":"tokens[].address","type":"string","is":"The token's address, its unique identity. Tickers aren't unique; addresses are.","howWorkedOut":"From the token account."},{"field":"tokens[].symbol / name","type":"string | null","is":"Ticker and name from Jupiter. Copycats can share a ticker, so trust the address, not the symbol.","howWorkedOut":"Jupiter token search by address."},{"field":"tokens[].verified","type":"boolean","is":"Whether Jupiter lists the token as verified.","howWorkedOut":"Jupiter's isVerified flag. false when unknown."},{"field":"tokens[].amount","type":"string (decimal)","is":"The balance in normal units.","howWorkedOut":"raw_amount / 10^decimals with exact integer math."},{"field":"tokens[].raw_amount","type":"string (integer)","is":"The balance in raw units, the number that goes into transfers.","howWorkedOut":"From the token account."},{"field":"tokens[].decimals","type":"number","is":"How many decimal places the token uses.","howWorkedOut":"From the token account."},{"field":"tokens[].holding_account","type":"string","is":"The account that holds this balance (not the wallet itself).","howWorkedOut":"The token account's address."},{"field":"tokens[].token_program","type":"\"spl-token\" | \"token-2022\"","is":"Which token program owns the account. Transfers must use the same one.","howWorkedOut":"Which program's lookup found it."},{"field":"tokens[].frozen","type":"boolean","is":"True if the issuer froze this account. Frozen tokens can't move.","howWorkedOut":"The account state is \"frozen\"."},{"field":"tokens[].usd_price","type":"number | null","is":"Price of one token in USD.","howWorkedOut":"Jupiter usdPrice. null when Jupiter has no price."},{"field":"tokens[].usd_value","type":"number | null","is":"USD value of this holding.","howWorkedOut":"amount x usd_price, rounded to cents. null without a price."}],"notes":["Prices come from Jupiter and can lag, or be missing for thinly traded tokens.","Very large wallets are capped: prices are looked up for at most 300 tokens."],"inputSchema":{"$schema":"https://json-schema.org/draft/2020-12/schema","type":"object","properties":{"wallet":{"type":"string"},"how_many":{"default":25,"type":"integer","minimum":1,"maximum":100},"include_empty":{"default":false,"type":"boolean"},"network":{"default":"mainnet-beta","type":"string","enum":["mainnet-beta","devnet"]}},"required":["wallet"]}}