Dry-run Solana txs before agents sign: exact balance changes, intent match, token traps. 25 free/day
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Run before sending SOL or paying fees, to confirm the wallet has enough. Never trust a remembered balance. A wallet's SOL balance, read from the chain. Example: {"wallet": "<address>"}. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/balance.
The wallet to read the SOL balance of. The user's address (from their wallet app) or your agent's public key. Not a .sol name or ticker.
Default "mainnet-beta" (real money). "devnet" only for test wallets.
Run before sending SOL or paying fees, to confirm the wallet has enough. Never trust a remembered balance. A wallet's SOL balance, read from the chain. Example: {"wallet": "<address>"}. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/balance.
| Argument | Type | Description |
|---|---|---|
| wallet* | string | The wallet to read the SOL balance of. The user's address (from their wallet app) or your agent's public key. Not a .sol name or ticker. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"wallet"
],
"properties": {
"wallet": {
"type": "string",
"description": "The wallet to read the SOL balance of. The user's address (from their wallet app) or your agent's public key. Not a .sol name or ticker."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run just before building a transaction to sign. Blockhashes expire in about 60-90 seconds; this says how long is left. A fresh blockhash and how many blocks (and about how many seconds) are left before it expires. Example: {}. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/blockhash.
| Argument | Type | Description |
|---|---|---|
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run on every transaction before signing. Shows what each wallet gains and loses, blocks drainer tricks, and catches failures and expired blockhashes before you pay a fee. Decodes each step, dry-runs it on live mainnet, finds each wallet's SOL and token changes, and answers OK, REVIEW or BLOCK with reasons. Measured: no false BLOCK on 200 real mainnet transactions; with tx_matches it caught 9 of 9 attack cases (benchmark/ in the repo). Example: {"tx": "<base64, before signing>"}. Cost: 25 free calls a day, then $0.02 USDC per call (x402). Outputs explained: GET /api/tools/check_tx.
| Argument | Type | Description |
|---|---|---|
| tx* | string | Base64 transaction, signed or not, legacy, v0 or v1. Before signing: Buffer.from(tx.serialize({ requireAllSignatures: false })).toString('base64'), or an aggregator's swap tx. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"tx"
],
"properties": {
"tx": {
"type": "string",
"minLength": 20,
"description": "Base64 transaction, signed or not, legacy, v0 or v1. Before signing: Buffer.from(tx.serialize({ requireAllSignatures: false })).toString('base64'), or an aggregator's swap tx."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run before putting any token amount in a transaction. "5 USDC" is 5,000,000 raw units; wrong decimals send 1,000x too much or too little. Converts between normal amounts and raw units with the token's real on-chain decimals. Example: {"token": "SOL", "amount": "0.5"} gives 500000000. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/convert.
| Argument | Type | Description |
|---|---|---|
| to | string | Direction. "raw" turns 5 into 5000000 (for transactions); "readable" turns raw units back. Default "raw". "readable" for amounts read from chain data. |
| token* | string | The token, or "SOL" for SOL (9 decimals). From find_token or tokens. |
| amount* | string | The amount, as a string: "5" or "0.25". The user's amount. A string avoids rounding errors. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"token",
"amount"
],
"properties": {
"to": {
"enum": [
"raw",
"readable",
"to_base_units",
"to_ui"
],
"type": "string",
"default": "raw",
"description": "Direction. \"raw\" turns 5 into 5000000 (for transactions); \"readable\" turns raw units back. Default \"raw\". \"readable\" for amounts read from chain data."
},
"token": {
"type": "string",
"description": "The token, or \"SOL\" for SOL (9 decimals). From find_token or tokens."
},
"amount": {
"type": "string",
"description": "The amount, as a string: \"5\" or \"0.25\". The user's amount. A string avoids rounding errors."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run after a transaction lands or fails, to report what happened instead of guessing from logs. For failures it names the failing program and the fix. Reads a confirmed transaction: whether it worked, the fee, each wallet's SOL and token changes, the programs used, and why it failed. Example: {"tx_id": "<signature>"}. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/explain_tx.
| Argument | Type | Description |
|---|---|---|
| tx_id* | string | The transaction's signature. Returned when you send, or from history. Never make one up. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"tx_id"
],
"properties": {
"tx_id": {
"type": "string",
"maxLength": 100,
"minLength": 64,
"description": "The transaction's signature. Returned when you send, or from history. Never make one up."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run before setting a priority fee. Gives the price in the unit Compute Budget expects (micro-lamports per compute unit) and the total in SOL, so a unit mix-up never overpays. Turns recent priority fees into three prices: cheap, normal, fast. Pass your transaction to get its compute limit and exact cost at each. Example: {} for network prices, or {"tx": "<base64>"} for your own. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/fee.
| Argument | Type | Description |
|---|---|---|
| tx | string | Your transaction, so fees match its accounts and compute comes from a dry run. Before signing: Buffer.from(tx.serialize({ requireAllSignatures: false })).toString('base64'), or an aggregator's swap tx. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"properties": {
"tx": {
"type": "string",
"minLength": 20,
"description": "Your transaction, so fees match its accounts and compute comes from a dry run. Before signing: Buffer.from(tx.serialize({ requireAllSignatures: false })).toString('base64'), or an aggregator's swap tx."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run whenever a user names a token ("buy BONK"). Tickers aren't unique; copycats reuse them. Never take an address from memory. Finds the real address for a ticker or name, ranks matches by verification and liquidity, and warns when copycats share the ticker. Example: {"name": "BONK"}. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/find_token.
| Argument | Type | Description |
|---|---|---|
| name* | string | Ticker, name or address: "BONK", "Jupiter", "USDC". Exactly as the user wrote it. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 80,
"minLength": 1,
"description": "Ticker, name or address: \"BONK\", \"Jupiter\", \"USDC\". Exactly as the user wrote it."
}
}
}Run to see a wallet's recent activity or get a real transaction ID. Never make one up. Lists a wallet's latest transactions, newest first, whether each worked, and a plain error name for failures. Example: {"wallet": "<address>", "how_many": 5}. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/history.
| Argument | Type | Description |
|---|---|---|
| wallet* | string | The wallet to read the transactions of. The user's address (from their wallet app) or your agent's public key. Not a .sol name or ticker. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
| how_many | integer | How many transactions to return. Default 10. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"wallet"
],
"properties": {
"wallet": {
"type": "string",
"description": "The wallet to read the transactions of. The user's address (from their wallet app) or your agent's public key. Not a .sol name or ticker."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
},
"how_many": {
"type": "integer",
"default": 10,
"maximum": 50,
"minimum": 1,
"description": "How many transactions to return. Default 10."
}
}
}Run before sending a token. Tokens go to the recipient's token account, not their wallet, and models can't work that address out. Finds the token account (ATA) for a wallet and token with the token's real program, says if it exists, and prices creating it. Example: {"wallet": "<recipient>", "token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"} finds where their USDC goes. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/token_account.
| Argument | Type | Description |
|---|---|---|
| token* | string | The token's address. From find_token or tokens. Not a ticker. |
| wallet* | string | The wallet that will own it (usually the recipient). The recipient's wallet address. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"wallet",
"token"
],
"properties": {
"token": {
"type": "string",
"description": "The token's address. From find_token or tokens. Not a ticker."
},
"wallet": {
"type": "string",
"description": "The wallet that will own it (usually the recipient). The recipient's wallet address."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run before buying, accepting or recommending a token. Answers SAFE, CAUTION or AVOID with exact reasons from chain and market data. Simulates a real holder selling, then checks if liquidity can be pulled, the creator's record, insider wallet networks, issuer powers (mint, freeze, Token-2022 traps), verification, liquidity, holders and age, for one verdict. Example: {"token": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263"} checks BONK. Cost: 25 free calls a day, then $0.02 USDC per call (x402). Outputs explained: GET /api/tools/token_safety.
| Argument | Type | Description |
|---|---|---|
| token* | string | The token's address. From find_token (for a ticker) or tokens (for a wallet's tokens). |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"token"
],
"properties": {
"token": {
"type": "string",
"description": "The token's address. From find_token (for a ticker) or tokens (for a wallet's tokens)."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run to learn which tokens a wallet holds and how much. Ranked by USD value; unverified (often spam airdrop) tokens are flagged so you don't report fake holdings. Lists a wallet's tokens (SPL Token and Token-2022) with exact amounts, whether each is verified, and USD value where priced. Example: {"wallet": "<address>", "how_many": 10}. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/tokens.
| Argument | Type | Description |
|---|---|---|
| wallet* | string | The wallet to read the tokens of. The user's address (from their wallet app) or your agent's public key. Not a .sol name or ticker. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
| how_many | integer | How many tokens, highest USD value first, to return. Default 25. |
| include_empty | boolean | Include empty token accounts. True only to find empty accounts, e.g. to close them. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"wallet"
],
"properties": {
"wallet": {
"type": "string",
"description": "The wallet to read the tokens of. The user's address (from their wallet app) or your agent's public key. Not a .sol name or ticker."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
},
"how_many": {
"type": "integer",
"default": 25,
"maximum": 100,
"minimum": 1,
"description": "How many tokens, highest USD value first, to return. Default 25."
},
"include_empty": {
"type": "boolean",
"default": false,
"description": "Include empty token accounts. True only to find empty accounts, e.g. to close them."
}
}
}Run just before signing a transfer built from a request like "send 5 USDC to X", or a swap built for "swap 1 USDC for JUP". Confirms it moves exactly that token, amount and recipient, nothing more, or that the swap sells exactly that amount and pays the bought token back to you. Catches made-up amounts, wrong decimals, hidden steps and swaps that pay someone else. Compares the transaction with your request (token, exact amount, recipient, sender), flags every step that isn't the transfer, and checks dry-run balances so money moved any other way is caught. For a swap it reads the dry run: exactly the amount sold, the bought token reaching your wallet, and nothing else leaving it. Measured on 200 real mainnet transactions: 80 of 80 transfers and 26 of 27 swaps matched (the other paid a bot 1.54%). Example: "send 1 USDC to X" is {"tx": "<base64>", "expected": {"token": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", "amount": "1", "to": "X"}}. Cost: 25 free calls a day, then $0.02 USDC per call (x402). Outputs explained: GET /api/tools/tx_matches.
| Argument | Type | Description |
|---|---|---|
| tx* | string | Base64 transaction, signed or not, legacy, v0 or v1. Before signing: Buffer.from(tx.serialize({ requireAllSignatures: false })).toString('base64'), or an aggregator's swap tx. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
| expected* | any | action: Default "transfer". "swap" takes sell, amount, buy and from instead of token, amount and to. From the request you were given. token: The token to send. "SOL", or the token address from find_token. amount: Normal units (for a swap: the amount sold): "5" means 5 USDC. The user's amount, as a string. to: The person's wallet, not their token account. The address the user gave you. Never take it from the transaction. from: The wallet that pays (for a swap: sells and gets the bought token). Default: the fee payer. Your agent's wallet address. sell: Swaps only: the token sold. "SOL", or the token address from find_token. buy: Swaps only: the token bought. "SOL", or the token address from find_token. Never take it from the transaction. |
Run when asked what a wallet holds or is worth. One call instead of balance + tokens + history; spam is left out of the total. SOL balance, top tokens with USD values, estimated total, and recent activity in one answer. Example: {"wallet": "<address>"}. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/wallet.
| Argument | Type | Description |
|---|---|---|
| wallet* | string | The wallet to sum up. The user's wallet address. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"wallet"
],
"properties": {
"wallet": {
"type": "string",
"description": "The wallet to sum up. The user's wallet address."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run when unsure what an address is, before sending to it or passing it on. SOL sent to a token or program address can be lost for good. Says what any address is (wallet, token account, token, program, stake account and more) with its key facts. Example: {"address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"} is the USDC token, not a wallet. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/whats_this.
| Argument | Type | Description |
|---|---|---|
| address* | string | Any Solana address. The address you're about to use. |
| network | string | Default "mainnet-beta" (real money). "devnet" only for test wallets. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"address"
],
"properties": {
"address": {
"type": "string",
"description": "Any Solana address. The address you're about to use."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
}
}
}Run whenever a Solana transaction or dry run fails, before retrying. Retrying blind burns fees. Turns a Solana error (hex code, log line or RPC error) into the plain cause and fix. Offline, no chain call. Example: {"error": "custom program error: 0x1771", "program": "JUP6LkbZbjS1jKKwapdHNy74zcZ3tLUZoi5QNyVTaV4"}. Cost: 25 free calls a day, then $0.01 USDC per call (x402). Outputs explained: GET /api/tools/why_failed.
| Argument | Type | Description |
|---|---|---|
| error* | any | The error as you got it: "custom program error: 0x1771", "InsufficientFundsForRent", or the RPC error object. From your send or RPC error, a dry-run result, a wallet message, or history. |
| program | string | The failing program. Needed to read custom error codes right. From the log line "Program <address> failed", or from explain_tx. |
{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"error"
],
"properties": {
"error": {
"anyOf": [
{
"type": "string"
},
{
"type": "object",
"propertyNames": {
"type": "string"
},
"additionalProperties": {}
}
],
"description": "The error as you got it: \"custom program error: 0x1771\", \"InsufficientFundsForRent\", or the RPC error object. From your send or RPC error, a dry-run result, a wallet message, or history."
},
"program": {
"type": "string",
"description": "The failing program. Needed to read custom error codes right. From the log line \"Program <address> failed\", or from explain_tx."
}
}
}{
"type": "object",
"$schema": "http://json-schema.org/draft-07/schema#",
"required": [
"tx",
"expected"
],
"properties": {
"tx": {
"type": "string",
"minLength": 20,
"description": "Base64 transaction, signed or not, legacy, v0 or v1. Before signing: Buffer.from(tx.serialize({ requireAllSignatures: false })).toString('base64'), or an aggregator's swap tx."
},
"network": {
"enum": [
"mainnet-beta",
"devnet"
],
"type": "string",
"default": "mainnet-beta",
"description": "Default \"mainnet-beta\" (real money). \"devnet\" only for test wallets."
},
"expected": {
"anyOf": [
{
"type": "object",
"required": [
"action",
"sell",
"amount",
"buy"
],
"properties": {
"buy": {
"type": "string"
},
"from": {
"type": "string"
},
"sell": {
"type": "string"
},
"action": {
"type": "string",
"const": "swap"
},
"amount": {
"type": "string"
}
}
},
{
"type": "object",
"required": [
"token",
"amount",
"to"
],
"properties": {
"to": {
"type": "string"
},
"from": {
"type": "string"
},
"token": {
"type": "string"
},
"action": {
"type": "string",
"const": "transfer"
},
"amount": {
"type": "string"
}
}
}
],
"description": "action: Default \"transfer\". \"swap\" takes sell, amount, buy and from instead of token, amount and to. From the request you were given. token: The token to send. \"SOL\", or the token address from find_token. amount: Normal units (for a swap: the amount sold): \"5\" means 5 USDC. The user's amount, as a string. to: The person's wallet, not their token account. The address the user gave you. Never take it from the transaction. from: The wallet that pays (for a swap: sells and gets the bought token). Default: the fee payer. Your agent's wallet address. sell: Swaps only: the token sold. \"SOL\", or the token address from find_token. buy: Swaps only: the token bought. \"SOL\", or the token address from find_token. Never take it from the transaction."
}
}
}