If you only need swap a token, get an unsigned transaction back, sign it yourself, submit it — both APIs do that and neither ever sees your private key. Same security model, same on-chain settlement.
| Capability | Jupiter (v6) | Trade Router (v1.3.0) |
|---|---|---|
| Non-custodial signing | Yes — returns unsigned tx | Yes — returns unsigned tx |
| Wallet = identity (no API key) | Yes | Yes |
| Multi-DEX routing | ~16 DEXes | 4 (Raydium, PumpSwap, Orca, Meteora) |
| Swap (instant) | /swap | POST /swap + POST /protect |
| Limit orders | Separate Limit Order Program (different API) | place_limit_order (same WS API) |
| Trailing stops | Not in v6 swap API | place_trailing_order |
| TWAP | Via Jupiter DCA UI | place_twap_order (frequency × duration) |
| DCA | Separate DCA Program (different API) | place_twap_order (interval-based) |
| Combo orders (e.g. limit-trigger → trailing → TWAP) | Not built-in | 4 combo types in v1.3.0 |
| MEV protection (built into the same call) | Via separate Jupiter products / manual Jito integration | /protect → Jito bundles by default |
| Holdings endpoint (most accurate on Solana) | No — RPC's job | POST /holdings (catches tokens RPC misses) |
| Server-message Ed25519 verification | Not applicable (no order callback channel) | Trust anchor baked in, rotation supported |
| Official MCP server (for AI agents) | No (community wrappers exist) | @traderouter/trade-router-mcp on npm + PyPI + Anthropic-claimable Glama |
| npm package | @jup-ag/api | @traderouter/trade-router-mcp |
| PyPI package | Not official | traderouter-mcp |
| OpenAPI 3.1 spec | Yes | openapi.json + openapi.yaml |
| llms.txt + SKILL.md (LLM-discoverable) | Not present | Both shipped at /llms.txt and /SKILL.md |
| Battle-tested | Since 2021, billions in swap volume | 1000+ real trades since launch |
This is the most common AI-agent task. Below is the same intent expressed against each API. We're not cherry-picking — both are the canonical paths.
// 1. Get a quote
const quote = await fetch(
`https://quote-api.jup.ag/v6/quote?inputMint=So11111111111111111111111111111111111111112` +
`&outputMint=TARGET_MINT&amount=100000000&slippageBps=100`
).then(r => r.json());
// 2. Build the unsigned swap tx
const { swapTransaction } = await fetch('https://quote-api.jup.ag/v6/swap', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
quoteResponse: quote,
userPublicKey: WALLET_ADDRESS,
wrapAndUnwrapSol: true,
// For MEV protection you separately wire Jito here:
prioritizationFeeLamports: { priorityLevelWithMaxLamports: { priorityLevel: 'veryHigh' } },
}),
}).then(r => r.json());
// 3. Sign locally
const tx = VersionedTransaction.deserialize(Buffer.from(swapTransaction, 'base64'));
tx.sign([keypair]);
// 4. (Optional) submit through Jito directly for bundle inclusion
// — separate SDK, separate endpoint, separate retry logic.
const sig = await jitoClient.sendBundle([tx]);
// auto_swap = build + sign + submit-via-Jito in one call.
// MCP server signs with TRADEROUTER_PRIVATE_KEY (locally), submits via /protect.
{
"tool": "auto_swap",
"args": {
"wallet_address": "WALLET_ADDRESS",
"token_address": "TARGET_MINT",
"action": "buy",
"amount": 100000000, // 0.1 SOL in lamports
"slippage": 1500 // bps
}
}
// Returns: { signature, balance_changes: { sol: -0.1, target: +N } }
// MEV protection is the default path, not a separate integration.
This is where the API shape diverges most. Jupiter has a DCA program but it's a separate on-chain account-creation flow with its own SDK. Trade Router exposes it as one WS-backed tool call.
// 1. Derive PDA
// 2. Build createDca instruction
// 3. Build deposit instruction
// 4. Sign + send tx
// 5. DCA program executes
// on its own schedule
//
// Read the @jup-ag/dca-sdk
// docs for full account
// derivation + reclaim flow.
{
"tool": "place_twap_order",
"args": {
"wallet_address": "W",
"token_address": "T",
"action": "twap_buy",
"total_amount": 1000000000,
"frequency": 10,
"duration": 3600,
"slippage": 1500
}
}
order_filled events without re-querying chain state).These aren't mutually exclusive. A common pattern: Jupiter for tail-token routing, Trade Router for the agent-orchestration loop (limits, trailing stops, TWAP, MEV-protected execution on the four major DEXes). The non-custodial model is identical, so the same wallet works in both.
| Jupiter | Trade Router | |
|---|---|---|
| API fee | Free at the API level | 1% flat on swap volume, embedded in /protect routing |
| Subscription / monthly minimum | None | None |
| Underlying DEX pool fees | Yes (set by each pool) | Yes (set by each pool) |
| Priority fees / Jito tips | You pay them, you wire them | Embedded in /protect bundle submission |
| Read-only endpoints (mcap, holdings) | Use other providers | Free |
No. Trade Router routes directly to Raydium, PumpSwap, Orca, and Meteora and submits via Jito. It does not call Jupiter's API. Routing logic and pool selection are independent.
Sometimes. On long-tail tokens where Jupiter routes through a DEX we don't, Jupiter will be better. On the four major Solana DEXes, the price difference is usually within the slippage you'd already accept, and Trade Router includes MEV protection that's a separate cost on Jupiter. Compare for your specific pair before committing — both APIs return the route and price up-front.
Different shape, different audience. Jupiter's primary customer is the human trader and the wallet UI. Trade Router's primary customer is the AI agent that wants one tool call per intent — including order types Jupiter doesn't expose as a single API (trailing stops, combo orders) and a built-in MEV-protected execution path.
Yes. Same wallet, same non-custodial model. A common pattern is using Jupiter for one-off routing on tail tokens and Trade Router for the persistent order-management layer (limits, trailing, TWAP, callbacks).
Trade Router MCP server source: github.com/TradeRouter/trade-router-mcp. It's a single ~85 KB .mjs file you can read end-to-end.
npx -y @traderouter/trade-router-mcp
Or wire it into Claude Desktop / Cursor / Cline / any MCP client — see the MCP setup section on the home page.