MCP server intelligence profile

trade-router-mcp Server

Non-custodial Solana swap & limit order engine for AI agents. 21 tools - swap, limit, trailing, TWAP, DCA, combo orders - across Raydium, PumpSwap, Orca, Meteora. Jito MEV-protected execution. Ed25519-verified server messages. Private key never leaves the process

Local OnlyOfficial distributionTradeRouter
Verified cleanNpm · 1.0.13

Our scanner tested version 1.0.13 without proving a finding in the methods exercised. This is not a guarantee that every deployment is secure.

1Distribution channel
21Independently observed tools
0Linked remote endpoints
AvailableVersion intelligence

Install and connect

Installation and connection instructions are shown only when supported by retained package, repository, or endpoint evidence.

Install @traderouter/trade-router-mcp from npm

Version 1.0.13 declares 1 executable entrypoint.

npm install --save-exact @traderouter/trade-router-mcp@1.0.13
npx -y -p @traderouter/trade-router-mcp@1.0.13 @traderouter/trade-router-mcp
MCP client configuration example
{
  "mcpServers": {
    "@traderouter/trade-router-mcp": {
      "command": "npx",
      "args": [
        "-y",
        "-p",
        "@traderouter/trade-router-mcp@1.0.13",
        "@traderouter/trade-router-mcp"
      ]
    }
  }
}

Identity

Canonical slugtrade-router-mcp-b8c70d1bDeploymentLocal Only
Canonical packagenpm:@traderouter/trade-router-mcpRepositoryTradeRouter/trade-router-mcp
First publishedLatest release
Last security verificationClassification confidence90%
PublicationPublishedOfficial distributionYes

Distributions

ChannelIdentifierCurrent versionVersionsSource
npm@traderouter/trade-router-mcp1.0.131Repository

Current release

PackageVersionPublished / observedInventorySecurity scan
npm@traderouter/trade-router-mcp1.0.13CurrentSep 5, 202621 toolsSucceeded · 0 resources · 0 promptsFailed
Enterprise protection

Continuously monitor this MCP for security risk

Independently scan the exact version your agents use, receive alerts when its risk changes, and investigate every finding with retained version evidence.

  • Independent exact-version security scans
  • Continuous release and vulnerability monitoring
  • Risk-change alerts with capability context
  • Historical evidence and API exports
Custom pricingContact salesTailored to your organization, integrations, data needs, and support requirements.

Current version evidence

Provenanceartifact_hash_verifiedSignature
MCP SDK@modelcontextprotocol/sdk Artifact SHA-256490f6fd0b3ca5e41e0d7e60f2259bff6ebe8c05fab853dec3067a1bd4ce35b57
Scannermcp-proof-engine 0.1.0Scan completedAug 23, 2026
Security rating46 / 100Methodologyversion-rating-1.0
Executable entrypoints
[
  "@traderouter/trade-router-mcp"
]
Rating reasons
[
  "security_contact_or_disclosure"
]

Current protocol inventory

2025-06-18Negotiated protocol
traderouterServer-reported name
1Capability groups
Aug 22, 2026Observed

Tools 21

ToolCategoryAnnotationsRisk
auto_swapBuilds, signs, and submits a Solana swap in a single call. Equivalent to build_swap → local sign → submit_signed_swap, but the MCP server handles the encoding conversion (base58 → base64) for you. WHEN TO USE: For most swaps. This is the simplest path. Use build_swap + submit_signed_swap separately only when you need to inspect or modify the transaction before signing (e.g. agent-layer validation of the output amount). WHAT IT DOES: Calls /swap to get an unsigned tx, signs it locally with TRADEROUTER_PRIVATE_KEY (key never leaves the process), submits via /protect (Jito MEV-protected). Returns the swap details and confirmation in one response. RETURNS: { swap: { swap_tx, pool_type, amount_in, min_amount_out, price_impact, slippage, decimals }, protect: { status, signature, sol_balance_pre, sol_balance_post, token_balances } }. If swap-build fails, only the swap object is returned with status="error". SIDE EFFECTS: Submits a real on-chain transaction (unless TRADEROUTER_DRY_RUN=true, which short-circuits to { dry_run: true, tool, args }). Requires TRADEROUTER_PRIVATE_KEY to be set. ⚠️ TRUST: This tool signs whatever transaction the server returns without inspecting the bytes against the requested swap parameters. If api.traderouter.ai is compromised, a malicious server could return a transaction that drains your wallet. Mitigations: use TRADEROUTER_DRY_RUN for testing; use a dedicated trading wallet with limited balance; or use build_swap + submit_signed_swap with your own decode+verify step. See SECURITY.md.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address",
    "action"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58). Must match the wallet derived from TRADEROUTER_PRIVATE_KEY."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint address (base58)."
    },
    "action": {
      "type": "string",
      "enum": [
        "buy",
        "sell"
      ],
      "description": "\"buy\" spends SOL to receive token; \"sell\" spends token to receive SOL."
    },
    "amount": {
      "type": "integer",
      "minimum": 1,
      "description": "REQUIRED for action=\"buy\". Lamports (1 SOL = 1e9 lamports). Example: 100000000 = 0.1 SOL."
    },
    "holdings_percentage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "REQUIRED for action=\"sell\". Basis points of current holdings (10000 = 100%)."
    },
    "slippage": {
      "type": "integer",
      "minimum": 100,
      "maximum": 2500,
      "default": 1500,
      "description": "Slippage tolerance in basis points (default 1500 = 15%). Memecoins typically need 1500-2500."
    }
  }
}
build_swapBuilds an unsigned Solana swap transaction via POST /swap. Returns the transaction as base58 — the caller must decode, sign locally, re-encode as base64, and submit via submit_signed_swap. WHEN TO USE: When you want to inspect or modify the transaction before signing (e.g. agent-layer validation), or when you want to control the sign+submit flow yourself. For a one-step swap, use auto_swap instead. WHAT IT DOES: Calls api.traderouter.ai/swap with wallet_address, token_address, action ('buy' or 'sell'), and either amount (lamports, for buy) or holdings_percentage (bps, for sell). The server picks the best DEX route across Raydium, PumpSwap, Orca, and Meteora based on liquidity, builds a VersionedTransaction, and returns it base58-encoded. RETURNS: On success: { status: "success", data: { swap_tx, pool_type, pool_address, amount_in, min_amount_out, price_impact, slippage, decimals } }. The pool_type field is an open enum (treat unknown values gracefully). On error: { status: "error", error, code }. "Error running simulation" usually means the route is unsellable right now (dead pool, zero balance, no route) — do not retry-loop. SIDE EFFECTS: None. This tool does NOT submit or sign anything.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address",
    "action"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58, 32-44 chars). Usually the same value returned by get_wallet_address."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint address (base58). Example: DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263 for BONK."
    },
    "action": {
      "type": "string",
      "enum": [
        "buy",
        "sell"
      ],
      "description": "\"buy\" spends SOL to receive token; \"sell\" spends token to receive SOL."
    },
    "amount": {
      "type": "integer",
      "minimum": 1,
      "description": "REQUIRED for action=\"buy\", FORBIDDEN for action=\"sell\". Lamports of SOL to spend (1 SOL = 1,000,000,000 lamports). Example: 100000000 = 0.1 SOL."
    },
    "holdings_percentage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "REQUIRED for action=\"sell\", FORBIDDEN for action=\"buy\". Basis points of current holdings to sell (10000 = 100%). Example: 5000 = sell 50%."
    },
    "slippage": {
      "type": "integer",
      "minimum": 100,
      "maximum": 2500,
      "default": 1500,
      "description": "Maximum slippage in basis points (10000 = 100%). Default 1500 (15%). For low-liquidity or newly-launched tokens use 1500-2500. 500 bps will often fail on memecoins."
    }
  }
}
cancel_orderCancels an active limit, trailing, TWAP, or combo order. Once cancelled, the order is removed server-side and no further fills will arrive. WHEN TO USE: To kill an order before it triggers (e.g. you no longer want to take that position) or to halt remaining TWAP slices. WHAT IT DOES: Sends { action: "cancel_order", order_id } over the WebSocket. Server removes the order from its scheduler and confirms with { type: "order_cancelled", order_id } (or { type: "twap_order_cancelled" } for TWAP orders). RETURNS: { wallet, order_id, status: "cancelled" }. Idempotent — cancelling an already-cancelled or already-filled order returns an error but is safe to retry. SIDE EFFECTS: Stops all future fills for the order. For partial-fill TWAP orders, slices already executed are not reverted; only remaining slices are skipped.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "order_id"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "order_id": {
      "type": "string",
      "description": "The order_id to cancel."
    }
  }
}
check_orderReturns the current status of a specific order by order_id. More targeted than list_orders. WHEN TO USE: To check whether a known order has triggered, expired, or been cancelled. Useful when polling for a specific order's outcome rather than scanning the full list. WHAT IT DOES: Sends { action: "check_order", order_id } over the WebSocket. Server returns { type: "order_status", order_id, status, ... }. RETURNS: { wallet, order_id, status: "active"|"triggered"|"filled"|"cancelled"|"expired", ... }. If the order doesn't exist (already expired or cancelled), the server returns an error. SIDE EFFECTS: None — pure read. Does not affect the order state or trigger any server-side processing.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "order_id"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "order_id": {
      "type": "string",
      "description": "The order_id returned by a place_*_order call. Format: a server-assigned UUID-like string."
    }
  }
}
connect_websocketOpens (or reuses) the persistent WebSocket connection to wss://api.traderouter.ai/ws for a wallet, performs the Ed25519 challenge-response handshake, and waits up to 25 seconds for the "registered" confirmation. WHEN TO USE: Before placing limit / trailing / TWAP / combo orders. get_wallet_address calls this implicitly, so you only need this tool to FORCE-reconnect or to register a wallet other than the env-derived one. WHAT IT DOES: Connects to the WebSocket, receives the server's challenge { type: "challenge", nonce }, signs the nonce bytes with TRADEROUTER_PRIVATE_KEY (Ed25519), sends { action: "register", wallet_address, signature: "<base58>" }, waits for { type: "registered", authenticated: true }. RETURNS: { wallet, message: "WebSocket connected and registered" | "WebSocket not yet registered; commands may be queued", connected: bool, registered: bool, ... }. SIDE EFFECTS: Spawns/maintains a background WebSocket connection. If TRADEROUTER_PRIVATE_KEY is missing or doesn't match wallet_address, registration will fail with authenticated:false and order placement will be rejected.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58). Must correspond to the keypair held in TRADEROUTER_PRIVATE_KEY for register to succeed."
    }
  }
}
connection_statusReturns the current state of the persistent WebSocket connection for a wallet (connected, registered, last heartbeat time, queued message count). WHEN TO USE: For debugging. If place_*_order calls are failing or hanging, check this first to see whether the WebSocket is actually authenticated. WHAT IT DOES: Inspects the in-memory ConnectionManager for the given wallet — no network call. RETURNS: { wallet, connected: bool, registered: bool, lastHeartbeat: <ISO timestamp>, ... }. SIDE EFFECTS: None.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    }
  }
}
extend_orderExtends the expiry time of an active limit or trailing order. expiry_hours sets the NEW total lifetime (counted from order creation, not from now). WHEN TO USE: When you want to keep a pending order alive longer than the original expiry_hours allowed (max 336 = 14 days). WHAT IT DOES: Sends { action: "extend_order", order_id, expiry_hours } over the WebSocket. Server updates the order's expires_at and confirms with { type: "order_extended", order_id }. RETURNS: { wallet, order_id, expiry_hours, status: "extended" }. Cannot extend TWAP orders (they have no separate expiry — they live exactly duration seconds). SIDE EFFECTS: Mutates server-side order state (expires_at field). The order continues from the same phase it was in — extending does not reset the trail high-water mark or restart the limit watcher. Idempotent if called with the same expiry_hours that already applies.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "order_id",
    "expiry_hours"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "order_id": {
      "type": "string",
      "description": "The order_id to extend."
    },
    "expiry_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 336,
      "description": "New total lifetime in hours, counted from the original creation time. Max 336 (14 days). Cannot be less than the elapsed time since creation."
    }
  }
}
get_fill_logReturns the in-memory log of all order_filled events received over the WebSocket since the MCP server process started (capped at 200 entries). WHEN TO USE: Audit which orders have triggered, with their on-chain signatures. Useful for end-of-session reporting or debugging "did my order fill?" WHAT IT DOES: Reads from the ConnectionManager's circular buffer. Does not query the API. RETURNS: { wallet, fills: [{ order_id, order_type, signature, filled_at, triggered_mcap, filled_mcap, status, server_signature_verified }] }. SIDE EFFECTS: None. ⚠️ NOT PERSISTED: This log is cleared when the MCP server restarts. For long-term audit, store fills externally as they arrive.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    }
  }
}
get_flex_cardReturns the URL of a flex trade-card PNG that visualizes a wallet's position in a token (entry price, current PnL, etc.). Used for sharing trades on social media. WHEN TO USE: After a notable swap, to generate a shareable image for X / Discord / Telegram. WHAT IT DOES: Constructs the URL https://api.traderouter.ai/flex?wallet_address=W&token_address=T. Does NOT fetch the image — it returns the URL string for the caller to embed or share. RETURNS: { url: "<full URL>", wallet_address, token_address }. The URL itself returns image/png when fetched. 400 on invalid params, 501 if flex-card image deps are not configured server-side, 500 on internal errors. SIDE EFFECTS: None.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint address (base58)."
    }
  }
}
get_holdingsScans every SPL token account on a wallet and returns the holdings list. Most accurate Solana wallet scanner available — catches tokens that standard RPC token-account scans miss. WHEN TO USE: When you need the full token balance for a wallet, including obscure or newly-launched tokens, before deciding what to sell or display in a portfolio view. WHAT IT DOES: Calls POST /holdings with the wallet address. Server enumerates every Token Program 2022 + SPL Token Program account, resolves liquid pool info per token, and returns the list. RETURNS: { data: [{ address: "<mint>", valueNative: <lamports>, amount: <raw_units>, decimals }] }. Empty wallet returns {} (not an empty array). Apply a defensive valueNative > 0 filter on the caller side; some edge cases return stale data. SIDE EFFECTS: None — pure read. ⚠️ TIMEOUT: Set client HTTP timeout to AT LEAST 100 seconds. Wallets with many tokens take time to fully scan.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58). No signing required — public key only."
    }
  }
}
get_mcapReturns market-cap and price data for one or more SPL tokens. Used by limit-order strategies to compute target market caps relative to current. WHEN TO USE: Before placing a limit_order with a market-cap target (so you know what current mcap is), or for portfolio valuation. WHAT IT DOES: Calls GET /mcap with comma-delimited mint addresses. Server queries its market-cap index (computed from liquid pool reserves) and returns per-token data. RETURNS: An object keyed by mint address. Each value can include marketCap (USD), priceUsd, pair_address, pool_type. Empty object if no tokens are provided or none are found. SIDE EFFECTS: None — pure read.
Input schema
{
  "type": "object",
  "required": [
    "tokens"
  ],
  "additionalProperties": false,
  "properties": {
    "tokens": {
      "type": "string",
      "description": "Comma-delimited SPL token mint addresses (base58). Example: \"DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263,JUPyiwrYJFskUPiHa7hkeR8VUtAeFoSYbKedZNsDvCN\"."
    }
  }
}
get_wallet_addressReturns the public Solana wallet address derived from the TRADEROUTER_PRIVATE_KEY environment variable, and triggers the persistent WebSocket connection to api.traderouter.ai for that wallet. WHEN TO USE: Call this once at session start, before any other Trade Router tool. The returned wallet address is the identity used by every other tool. WHAT IT DOES: Reads the base58 private key from env, derives the Solana public key locally (no network call for derivation), then opens a WebSocket to wss://api.traderouter.ai/ws and authenticates via challenge-response signing of a server-issued nonce. The private key never crosses the network. RETURNS: { configured: true, wallet_address: "<base58>" } on success. { configured: false, error: "TRADEROUTER_PRIVATE_KEY not set" } if the env var is missing — in that case, only read-only tools (get_holdings, get_mcap, get_flex_card) will work for arbitrary wallets, and write tools will fail. SIDE EFFECTS: Spawns a background WebSocket connection that persists for the lifetime of the MCP server process.
Input schema
{
  "type": "object",
  "properties": {},
  "additionalProperties": false
}
list_ordersReturns all currently active orders (limit, trailing, TWAP, combo) for a wallet. Used to audit pending orders and find order_ids for cancel_order or extend_order. WHEN TO USE: Periodically, to detect expired orders (the server does NOT push an expiry event — orders silently disappear from results when expiry_hours is reached). Also to confirm that a place_*_order call actually registered. WHAT IT DOES: Sends { action: "list_orders" } over the WebSocket. Server returns { type: "order_list", orders: [{ order_id, order_type, token_address, target_mcap, trail_bps, amount, holdings_percentage, slippage, expires_at, status, ... }] }. RETURNS: { wallet, orders: [...] }. Empty array if no active orders. Each order includes its current phase (e.g. limit_trailing_twap can be in "limit-watching", "trailing-watching", or "twap-executing" phases). SIDE EFFECTS: None — pure read.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58). Must be registered on the WebSocket (via get_wallet_address or connect_websocket) for the request to succeed."
    }
  }
}
place_limit_orderPlaces a market-cap-triggered limit order over the WebSocket. The server polls market cap ~every 5 seconds and fires the swap when the target is crossed. WHEN TO USE: When you want to enter or exit at a specific market-cap level, not at current price. Examples: "buy BONK when its mcap drops to $500M", "sell BONK when its mcap doubles". WHAT IT DOES: Sends { action: "sell"|"buy", token_address, target, slippage, expiry_hours, ... } to the server over WS. Server registers the order, returns { type: "order_created", order_id, params_hash, server_signature }. The MCP verifies server_signature against the Ed25519 trust anchor before treating the order as accepted. TARGET SEMANTICS: target is in basis points relative to the CURRENT mcap at order placement (NOT your wallet entry price). For SELL: target > 10000 = take-profit (e.g. 20000 = mcap doubles). target < 10000 = stop-loss (e.g. 5000 = halves). For BUY: target < 10000 = dip buy. target > 10000 = breakout entry. WHEN ORDER FILLS: Server pushes order_filled with an unsigned tx. The MCP signs locally and submits via /protect, then logs the fill (visible via get_fill_log). SIDE EFFECTS: Order persists server-side until trigger, expiry, or cancel_order. The MCP server process must keep its WS open to receive fills — restarting the process WHILE an order is pending may cause you to miss the fill notification (the order itself stays alive on the server).
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address",
    "action",
    "target"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint to buy or sell."
    },
    "action": {
      "type": "string",
      "enum": [
        "sell",
        "buy"
      ],
      "description": "\"sell\" closes a position when target is hit; \"buy\" opens a position when target is hit."
    },
    "target": {
      "type": "integer",
      "minimum": 1,
      "description": "Target market cap in BPS vs current mcap at placement. >10000 = above current, <10000 = below current. E.g. 20000 = mcap doubles, 5000 = mcap halves. Server stores this in params_hash (signed) so it cannot be silently changed."
    },
    "amount": {
      "type": "integer",
      "minimum": 1,
      "description": "REQUIRED for action=\"buy\". Lamports of SOL to spend when triggered."
    },
    "holdings_percentage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "REQUIRED for action=\"sell\". Basis points of holdings to sell (10000 = 100%). Resolved at FILL TIME, not placement."
    },
    "slippage": {
      "type": "integer",
      "minimum": 100,
      "maximum": 2500,
      "default": 1500,
      "description": "Slippage tolerance in BPS at fill time. Default 1500 (15%)."
    },
    "expiry_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 336,
      "default": 144,
      "description": "Hours until the order auto-cancels server-side. Default 144 (6 days). Max 336 (14 days). Order silently expires; the server does NOT push an expiry event — use check_order or list_orders to detect."
    }
  }
}
place_limit_trailing_orderCOMBO ORDER: Wait for a limit target, then activate a trailing stop. When the trail triggers, execute as a SINGLE swap (not TWAP). WHEN TO USE: To enter at a specific mcap, then ride the trend with a trailing stop. Example: "Buy BONK if mcap drops to $500M, then sell with a 15% trailing stop after entry." WHAT IT DOES: Server waits for limit target. When crossed, sends limit_trailing_activated and starts trailing-stop tracking. When trail retraces enough, sends order_filled with a single unsigned tx. RETURNS: { wallet, order_id, message: "Limit-Trailing order accepted", target, trail, expiry_hours, params_hash, server_signature }. The order_id stays the same across both phases (limit-watching → trailing-watching → filled). Use check_order to see which phase the order is currently in. SIDE EFFECTS: Server-side state created — the limit watcher runs until target hits or expiry_hours elapses. Once limit triggers, the trail tracker takes over (high-water for sell, low-water for buy) until reversal exceeds trail BPS. cancel_order works in both phases. expiry_hours covers the LIMIT phase only — once trail activates, the order has no expiry (extend_order resets the limit phase only).
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address",
    "action",
    "target",
    "trail"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint."
    },
    "action": {
      "type": "string",
      "enum": [
        "limit_trailing_sell",
        "limit_trailing_buy"
      ],
      "description": "sell when limit hits (then trail until reversal); buy when limit hits (then trail until rebound)."
    },
    "target": {
      "type": "integer",
      "minimum": 1,
      "description": "Market-cap target in BPS vs current mcap at placement."
    },
    "trail": {
      "type": "integer",
      "minimum": 1,
      "description": "Trail distance in BPS, applied AFTER limit fires. 1000 = 10% retracement."
    },
    "amount": {
      "type": "integer",
      "minimum": 1,
      "description": "REQUIRED for buy. Lamports of SOL to spend."
    },
    "holdings_percentage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "REQUIRED for sell. Basis points of holdings."
    },
    "slippage": {
      "type": "integer",
      "minimum": 100,
      "maximum": 2500,
      "default": 500,
      "description": "Slippage at the single-swap fill (BPS)."
    },
    "expiry_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 336,
      "default": 144,
      "description": "Hours until limit phase auto-cancels (before activation)."
    }
  }
}
place_limit_trailing_twap_orderCOMBO ORDER (the full chain): Wait for a market-cap limit target → activate trailing stop → on trail trigger, execute exit/entry as TWAP slices. WHEN TO USE: For the most sophisticated single-tool strategy. Example: "Buy BONK at mcap $500M, then sell with a 15% trailing stop, and when the trail fires distribute the exit over 30 minutes via TWAP." WHAT IT DOES: Server orchestrates all three phases. Sends limit_trailing_activated when trail starts, limit_trailing_twap_triggered when trail fires, twap_execution per slice. The 11-field params_hash includes target, trail, frequency, and duration — all signed by the server, verified locally. RETURNS: { wallet, order_id, message: "Limit-Trailing-TWAP order accepted", target, trail, frequency, duration, expiry_hours, params_hash, server_signature }. The parent order_id covers the limit + trailing phases; the spawned TWAP at trail-fire gets its own child order_id (delivered via twap_order_created event). check_order on the parent reports the current phase ("limit-watching", "trailing-watching", or "twap-spawned"). SIDE EFFECTS: Server-side state created — the watcher runs continuously through three phases. cancel_order on the parent works during limit and trailing phases but NOT once the child TWAP has spawned (cancel that TWAP's order_id directly). expiry_hours covers the LIMIT phase only. params_hash is the strongest commitment in the suite (11 fields including target, trail, frequency, duration, slippage) — verified locally before order acceptance.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address",
    "action",
    "target",
    "trail",
    "frequency",
    "duration"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint."
    },
    "action": {
      "type": "string",
      "enum": [
        "limit_trailing_twap_sell",
        "limit_trailing_twap_buy"
      ],
      "description": "Full combo direction."
    },
    "target": {
      "type": "integer",
      "minimum": 1,
      "description": "Market-cap target in BPS vs current."
    },
    "trail": {
      "type": "integer",
      "minimum": 1,
      "description": "Trail distance in BPS, applied after limit fires."
    },
    "frequency": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "description": "Number of TWAP slices after trail fires."
    },
    "duration": {
      "type": "integer",
      "minimum": 60,
      "description": "Total seconds the TWAP will run."
    },
    "amount": {
      "type": "integer",
      "minimum": 1,
      "description": "Total to spend (buy lamports) or sell (token base units) across all TWAP slices."
    },
    "holdings_percentage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "Sell only: BPS of holdings at TWAP-creation time."
    },
    "slippage": {
      "type": "integer",
      "minimum": 100,
      "maximum": 2500,
      "default": 500,
      "description": "Slippage per TWAP slice (BPS)."
    },
    "expiry_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 336,
      "default": 144,
      "description": "Hours until limit phase auto-cancels."
    }
  }
}
place_limit_twap_orderCOMBO ORDER: Wait for a market-cap target to be crossed, then execute the entry/exit as a TWAP rather than a single swap. Server-orchestrated; no client-side state machine needed. WHEN TO USE: When you want a trigger-then-distribute pattern. Example: "If BONK's mcap hits $500M, ladder out of my position over 30 minutes via TWAP." WHAT IT DOES: Server waits for limit target. When crossed, sends limit_twap_triggered, then twap_order_created for the spawned TWAP, then twap_execution per slice (each with server_signature for verification). RETURNS: { wallet, order_id, message: "Limit-TWAP order accepted", target, frequency, duration, expiry_hours, params_hash, server_signature }. The order_id is what you'd pass to check_order, cancel_order, or extend_order. Server returns an error event over WS if the wallet is not registered, or if both amount and holdings_percentage are missing. SIDE EFFECTS: Server-side state created — the order watches the market-cap feed continuously until target hits or expiry_hours elapses. Once limit triggers, a child TWAP order is spawned with its own order_id (delivered via twap_order_created event); cancel_order on the parent only cancels the limit phase, not the child TWAP after it spawns. params_hash signs an 11-field commitment (target_bps, trail_bps n/a, frequency, duration, etc.) — verified locally against the trust anchor before the order is treated as accepted.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address",
    "action",
    "target",
    "frequency",
    "duration"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint."
    },
    "action": {
      "type": "string",
      "enum": [
        "limit_twap_sell",
        "limit_twap_buy"
      ],
      "description": "sell when target is crossed (then TWAP exit), or buy when target is crossed (then TWAP entry)."
    },
    "target": {
      "type": "integer",
      "minimum": 1,
      "description": "Market-cap target in BPS vs current mcap at placement. See place_limit_order for full semantics."
    },
    "frequency": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "description": "Number of TWAP slices to spawn after the limit triggers."
    },
    "duration": {
      "type": "integer",
      "minimum": 60,
      "description": "Total seconds the spawned TWAP will run. Slice interval = duration / frequency."
    },
    "amount": {
      "type": "integer",
      "minimum": 1,
      "description": "Total to spend (buy lamports) or sell (token base units) across all TWAP slices."
    },
    "holdings_percentage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "Sell only: BPS of holdings at TWAP-creation time."
    },
    "slippage": {
      "type": "integer",
      "minimum": 100,
      "maximum": 2500,
      "default": 500,
      "description": "Slippage per TWAP slice (BPS). Default 500."
    },
    "expiry_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 336,
      "default": 144,
      "description": "Hours until the LIMIT phase auto-cancels (before TWAP fires). Default 144."
    }
  }
}
place_trailing_orderPlaces a trailing-stop sell or trailing buy order over the WebSocket. The server tracks the high-water mark (or low-water mark for buy) of mcap and fires when it retraces by trail BPS. WHEN TO USE: To ride a trend without picking a fixed exit. "Sell BONK when mcap drops 10% from its peak" — sell trail-stop. "Buy DOGE when mcap rebounds 5% from its low" — buy trail. WHAT IT DOES: Sends { action: "trailing_sell"|"trailing_buy", token_address, trail, ... } to the server. Server tracks the running high (sell) or low (buy) of mcap and fires when retracement >= trail BPS. Server returns order_created with params_hash (signed), then later order_filled with an unsigned tx for local signing. TRAIL SEMANTICS: trail is in basis points. trail=1000 means a 10% retracement triggers. Example (trailing_sell): mcap peaks at $100k, trail=1000, trigger at $90k. If mcap then peaks at $150k, trigger moves up to $135k. SIDE EFFECTS: Order persists server-side until trigger, expiry, or cancel_order.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address",
    "action",
    "trail"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint."
    },
    "action": {
      "type": "string",
      "enum": [
        "trailing_sell",
        "trailing_buy"
      ],
      "description": "trailing_sell closes a position after a retracement from peak; trailing_buy opens a position after a rebound from trough."
    },
    "trail": {
      "type": "integer",
      "minimum": 1,
      "description": "Trail distance in BPS (basis points). 1000 = 10%. Server tracks high-water (sell) or low-water (buy) mark and fires when reversal exceeds this."
    },
    "amount": {
      "type": "integer",
      "minimum": 1,
      "description": "REQUIRED for trailing_buy. Lamports of SOL to spend when triggered."
    },
    "holdings_percentage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "REQUIRED for trailing_sell. Basis points of holdings to sell (10000 = 100%)."
    },
    "slippage": {
      "type": "integer",
      "minimum": 100,
      "maximum": 2500,
      "default": 1500,
      "description": "Slippage in BPS at fill. Default 1500 (15%)."
    },
    "expiry_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 336,
      "default": 144,
      "description": "Hours until auto-cancel. Default 144."
    }
  }
}
place_trailing_twap_orderCOMBO ORDER: Wait for a trailing-stop trigger, then execute the exit as a TWAP rather than a single swap. WHEN TO USE: To ride a trend with a trailing stop, but exit gradually via TWAP when the trail fires (minimizing market impact on a low-liquidity exit). Example: "Sell BONK if mcap drops 15% from peak, but spread the exit over 30 min." WHAT IT DOES: Server tracks high-water (sell) or low-water (buy) mark. When reversal exceeds trail BPS, sends trailing_twap_triggered, then twap_order_created, then twap_execution per slice. RETURNS: { wallet, order_id, message: "Trailing-TWAP order accepted", trail, frequency, duration, expiry_hours, params_hash, server_signature }. order_id is the parent (trailing-watching) phase; the spawned TWAP gets its own child order_id at trigger time. SIDE EFFECTS: Server-side state created — the trailing-watcher runs continuously until trail fires or expiry_hours elapses. cancel_order on the parent stops the trailing phase but does NOT cancel a child TWAP that has already spawned. The 11-field params_hash includes trail BPS, frequency, duration, slippage — signed by server, verified locally.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address",
    "action",
    "trail",
    "frequency",
    "duration"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint."
    },
    "action": {
      "type": "string",
      "enum": [
        "trailing_twap_sell",
        "trailing_twap_buy"
      ],
      "description": "sell after retracement from peak (then TWAP); buy after rebound from trough (then TWAP)."
    },
    "trail": {
      "type": "integer",
      "minimum": 1,
      "description": "Trail distance in BPS. 1000 = 10%. See place_trailing_order for full semantics."
    },
    "frequency": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "description": "Number of TWAP slices after trail fires."
    },
    "duration": {
      "type": "integer",
      "minimum": 60,
      "description": "Total seconds the spawned TWAP will run."
    },
    "amount": {
      "type": "integer",
      "minimum": 1,
      "description": "Total to spend (buy lamports) or sell (token base units) across all TWAP slices."
    },
    "holdings_percentage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "Sell only: BPS of holdings at TWAP-creation time."
    },
    "slippage": {
      "type": "integer",
      "minimum": 100,
      "maximum": 2500,
      "default": 500,
      "description": "Slippage per slice (BPS)."
    },
    "expiry_hours": {
      "type": "integer",
      "minimum": 1,
      "maximum": 336,
      "default": 144,
      "description": "Hours until trailing phase auto-cancels."
    }
  }
}
place_twap_orderPlaces a Time-Weighted Average Price (TWAP) buy or sell order. The total amount is split into N equal slices executed every (duration / frequency) seconds. WHEN TO USE: For DCA, large entries/exits where minimizing market impact matters more than getting a single price. Example: "DCA 1 SOL into JUP over 6 hours in 12 slices" → twap_buy with amount=1e9, frequency=12, duration=21600. WHAT IT DOES: Server registers the order, returns twap_order_created with order_id, frequency, duration, interval_seconds, amount_per_execution. Then for each slice, server pushes twap_execution { execution_num, executions_total, executions_remaining, next_execution_at, server_signature, data: { swap_tx } }. The MCP verifies server_signature, signs swap_tx, submits via /protect. Final twap_order_completed when all slices done. SLICING: amount (or holdings_percentage at creation time, then resolved to a fixed token amount) is divided by frequency. Each slice executes at duration / frequency intervals. SIDE EFFECTS: Each slice is a real on-chain transaction. The order persists server-side and the MCP server must stay running to receive twap_execution pushes. cancel_order halts remaining slices.
Input schema
{
  "type": "object",
  "required": [
    "wallet_address",
    "token_address",
    "action",
    "frequency",
    "duration"
  ],
  "additionalProperties": false,
  "properties": {
    "wallet_address": {
      "type": "string",
      "description": "Solana wallet public key (base58)."
    },
    "token_address": {
      "type": "string",
      "description": "SPL token mint."
    },
    "action": {
      "type": "string",
      "enum": [
        "twap_buy",
        "twap_sell"
      ],
      "description": "twap_buy spends SOL to acquire token over N slices; twap_sell sells token for SOL over N slices."
    },
    "frequency": {
      "type": "integer",
      "minimum": 1,
      "maximum": 100,
      "description": "Number of slice executions. Total amount is divided by this number. Example: frequency=12 with duration=21600 (6h) = one slice every 30 minutes."
    },
    "duration": {
      "type": "integer",
      "minimum": 60,
      "description": "Total run time in seconds. Min 60, max ~2,592,000 (30 days). Order has no separate expiry — it lives exactly this long."
    },
    "amount": {
      "type": "integer",
      "minimum": 1,
      "description": "REQUIRED for twap_buy (total SOL lamports to spend across all slices). For twap_sell, optional — sell exactly this many token base units total."
    },
    "holdings_percentage": {
      "type": "integer",
      "minimum": 1,
      "maximum": 10000,
      "description": "For twap_sell: basis points of CURRENT holdings to sell (resolved once at creation, then divided by frequency). Use either this or amount, not both."
    },
    "slippage": {
      "type": "integer",
      "minimum": 100,
      "maximum": 2500,
      "default": 500,
      "description": "Slippage in BPS per slice. Default 500 (5%) — TWAP slices are smaller so tolerate tighter slippage."
    }
  }
}
submit_signed_swapSubmits a fully-signed, base64-encoded Solana transaction via POST /protect (Jito MEV-protected lane). Blocks until the transaction confirms on-chain. WHEN TO USE: Pair with build_swap when you want to inspect/modify the transaction before signing. For a single-call swap, prefer auto_swap. WHAT IT DOES: POSTs the signed transaction to api.traderouter.ai/protect, which submits via Jito bundles + a staked connection lane (preventing mempool visibility for sandwich-resistance), waits for on-chain confirmation, and returns the signature plus pre/post SOL balance and token balance changes. RETURNS: On success: { status: "success", signature, sol_balance_pre, sol_balance_post, token_balances: [{ mint, balance, decimals, balance_change, ui_amount_string }] }. On error: { status: "error", error, code }. On 503 (protect lane unavailable), the MCP server falls back to direct RPC submission automatically — you lose MEV protection but the transaction still lands. SIDE EFFECTS: Submits a real on-chain transaction (unless TRADEROUTER_DRY_RUN=true). Costs ~0.000005 SOL in network fees plus the routed swap fee. ⚠️ ENCODING: The swap_tx returned by build_swap is BASE58. This tool requires BASE64. Decode the base58, deserialize as VersionedTransaction, sign, re-serialize, base64-encode. ⚠️ TIMEOUT: Set client HTTP timeout to 30 seconds — confirmation latency varies with network congestion.
Input schema
{
  "type": "object",
  "required": [
    "signed_tx_base64"
  ],
  "additionalProperties": false,
  "properties": {
    "signed_tx_base64": {
      "type": "string",
      "description": "A signed Solana VersionedTransaction, base64-encoded. Note: build_swap returns base58; you must convert before passing here."
    }
  }
}

Resources 0

  • None observed.

Resource templates 0

  • None observed.

Prompts 0

  • None observed.

Remote endpoints

EndpointTransportAuthenticationHealthObserved
No verified remote endpoint is linked.

trade-router-mcp Server questions

How do I install trade-router-mcp Server?

Install the selected package version with: npm install --save-exact @traderouter/trade-router-mcp@1.0.13

What tools does trade-router-mcp Server provide?

trade-router-mcp Server exposed 21 tools during independent protocol observation, including auto_swap, build_swap, cancel_order, check_order, connect_websocket, connection_status, extend_order, get_fill_log, and others.

Is trade-router-mcp Server secure?

Our scanner tested version 1.0.13 without proving a finding in the methods exercised. This is not a guarantee that every deployment is secure.

Explore related MCP server guides

Curated product and capability guides containing this catalog record.

Official vs Community MCP Servers

Let’s talk about MCP security.

Share your details and our security team will contact you.