suggest_command
Generate precise perp CLI commands from natural language trading goals for manual execution on perpetual futures exchanges.
Instructions
Given a natural language trading goal, suggest the exact perp CLI commands to run. Does NOT execute anything — only returns commands for the user to review and run manually
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| goal | Yes | Natural language goal, e.g. 'buy 0.1 BTC on pacifica', 'close all positions', 'check funding arb opportunities' | |
| exchange | No | Preferred exchange (default: pacifica). Options: pacifica, hyperliquid, lighter |
Implementation Reference
- src/mcp-server.ts:347-692 (handler)Handler for the "suggest_command" tool, which provides CLI command suggestions based on natural language input.
server.tool( "suggest_command", "Given a natural language trading goal, suggest the exact perp CLI commands to run. Does NOT execute anything — only returns commands for the user to review and run manually", { goal: z.string().describe("Natural language goal, e.g. 'buy 0.1 BTC on pacifica', 'close all positions', 'check funding arb opportunities'"), exchange: z.string().optional().describe("Preferred exchange (default: pacifica). Options: pacifica, hyperliquid, lighter"), }, async ({ goal, exchange }) => { try { const ex = exchange ?? "pacifica"; const g = goal.toLowerCase(); const steps: { step: number; command: string; description: string; dangerous?: boolean }[] = []; if (g.includes("buy") || g.includes("long")) { const symbol = extractSymbol(g) || "BTC"; const size = extractNumber(g) || "<size>"; steps.push( { step: 1, command: `perp -e ${ex} --json market book ${symbol}`, description: `Check ${symbol} orderbook and liquidity` }, { step: 2, command: `perp -e ${ex} --json account balance`, description: "Check available balance and margin" }, { step: 3, command: `perp -e ${ex} --json trade check ${symbol} buy ${size}`, description: "Pre-flight validation (dry run)" }, { step: 4, command: `perp -e ${ex} --json trade market ${symbol} buy ${size}`, description: `Buy ${size} ${symbol} at market`, dangerous: true }, { step: 5, command: `perp -e ${ex} --json account positions`, description: "Verify position opened" }, ); } else if (g.includes("sell") || g.includes("short")) { const symbol = extractSymbol(g) || "BTC"; const size = extractNumber(g) || "<size>"; steps.push( { step: 1, command: `perp -e ${ex} --json market book ${symbol}`, description: `Check ${symbol} orderbook and liquidity` }, { step: 2, command: `perp -e ${ex} --json account balance`, description: "Check available balance and margin" }, { step: 3, command: `perp -e ${ex} --json trade check ${symbol} sell ${size}`, description: "Pre-flight validation (dry run)" }, { step: 4, command: `perp -e ${ex} --json trade market ${symbol} sell ${size}`, description: `Sell ${size} ${symbol} at market`, dangerous: true }, { step: 5, command: `perp -e ${ex} --json account positions`, description: "Verify position opened" }, ); } else if (g.includes("limit")) { const symbol = extractSymbol(g) || "BTC"; const size = extractNumber(g) || "<size>"; const side = g.includes("sell") || g.includes("short") ? "sell" : "buy"; steps.push( { step: 1, command: `perp -e ${ex} --json market book ${symbol}`, description: `Check ${symbol} orderbook for price levels` }, { step: 2, command: `perp -e ${ex} --json account balance`, description: "Check available balance" }, { step: 3, command: `perp -e ${ex} --json trade limit ${symbol} ${side} <price> ${size}`, description: `Place limit ${side} order`, dangerous: true }, { step: 4, command: `perp -e ${ex} --json account orders`, description: "Verify order placed" }, ); } else if (g.includes("close") || g.includes("exit") || g.includes("flatten")) { const symbol = extractSymbol(g); steps.push( { step: 1, command: `perp -e ${ex} --json account positions`, description: "Get current positions" }, ); if (g.includes("flatten")) { steps.push( { step: 2, command: `perp -e ${ex} --json trade flatten`, description: "Cancel all orders + close all positions", dangerous: true }, ); } else if (symbol) { steps.push( { step: 2, command: `perp -e ${ex} --json trade close ${symbol}`, description: `Close ${symbol} position at market`, dangerous: true }, ); } else { steps.push( { step: 2, command: `perp -e ${ex} --json trade cancel-all`, description: "Cancel any open orders first", dangerous: true }, { step: 3, command: `perp -e ${ex} --json trade close-all`, description: "Close all positions at market", dangerous: true }, ); } } else if (g.includes("tp") || g.includes("take profit") || g.includes("scale-tp")) { const symbol = extractSymbol(g) || "<symbol>"; steps.push( { step: 1, command: `perp -e ${ex} --json account positions`, description: "Check current position size and entry" }, { step: 2, command: `perp -e ${ex} --json market book ${symbol}`, description: "Check current prices" }, { step: 3, command: `perp -e ${ex} --json trade scale-tp ${symbol} --levels '<price1>:25%,<price2>:50%,<price3>:25%'`, description: "Place scaled take-profit orders", dangerous: true }, ); } else if (g.includes("scale-in") || g.includes("scale in") || g.includes("dca in")) { const symbol = extractSymbol(g) || "<symbol>"; const side = g.includes("sell") || g.includes("short") ? "sell" : "buy"; steps.push( { step: 1, command: `perp -e ${ex} --json market book ${symbol}`, description: "Check current prices" }, { step: 2, command: `perp -e ${ex} --json account balance`, description: "Check available balance" }, { step: 3, command: `perp -e ${ex} --json trade scale-in ${symbol} ${side} --levels '<price1>:<size>,<price2>:<size>'`, description: "Place scaled entry orders at multiple levels", dangerous: true }, ); } else if (g.includes("tpsl") || g.includes("tp/sl") || g.includes("tp sl") || (g.includes("take profit") && g.includes("stop loss"))) { const symbol = extractSymbol(g) || "<symbol>"; const side = g.includes("sell") || g.includes("short") ? "sell" : "buy"; steps.push( { step: 1, command: `perp -e ${ex} --json account positions`, description: "Check current position" }, { step: 2, command: `perp -e ${ex} --json trade tpsl ${symbol} ${side} --tp <price> --sl <price>`, description: "Set TP/SL bracket orders", dangerous: true }, { step: 3, command: `perp -e ${ex} --json account orders`, description: "Verify TP/SL orders placed" }, ); } else if (g.includes("trailing") || g.includes("trail")) { const symbol = extractSymbol(g) || "<symbol>"; steps.push( { step: 1, command: `perp -e ${ex} --json account positions`, description: "Check current position" }, { step: 2, command: `perp -e ${ex} --json trade trailing-stop ${symbol}`, description: "Set trailing stop order", dangerous: true }, ); } else if (g.includes("stop") || g.includes("sl") || g.includes("stop loss")) { const symbol = extractSymbol(g) || "<symbol>"; steps.push( { step: 1, command: `perp -e ${ex} --json account positions`, description: "Check current position" }, { step: 2, command: `perp -e ${ex} --json trade stop ${symbol} <side> <stopPrice> <size>`, description: "Place stop order", dangerous: true }, ); } else if (g.includes("split") || g.includes("depth") || (g.includes("large") && (g.includes("order") || g.includes("buy") || g.includes("sell")))) { const symbol = extractSymbol(g) || "<symbol>"; const amount = extractNumber(g) || "<usd>"; const side = g.includes("sell") || g.includes("short") ? "sell" : "buy"; steps.push( { step: 1, command: `perp -e ${ex} --json market book ${symbol}`, description: `Check ${symbol} orderbook depth` }, { step: 2, command: `perp -e ${ex} --json account balance`, description: "Check available balance" }, { step: 3, command: `perp -e ${ex} --json trade split ${symbol} ${side} ${amount}`, description: `Split ${side} $${amount} ${symbol} into depth-based slices`, dangerous: true }, { step: 4, command: `perp -e ${ex} --json account positions`, description: "Verify position opened" }, ); } else if (g.includes("twap")) { const symbol = extractSymbol(g) || "<symbol>"; const size = extractNumber(g) || "<size>"; const side = g.includes("sell") || g.includes("short") ? "sell" : "buy"; steps.push( { step: 1, command: `perp -e ${ex} --json account balance`, description: "Check available balance" }, { step: 2, command: `perp -e ${ex} --json trade twap ${symbol} ${side} ${size} <duration>`, description: `TWAP ${side} ${size} ${symbol} over duration`, dangerous: true }, ); } else if (g.includes("reduce")) { const symbol = extractSymbol(g) || "<symbol>"; const pct = extractNumber(g) || "<percent>"; steps.push( { step: 1, command: `perp -e ${ex} --json account positions`, description: "Check current position size" }, { step: 2, command: `perp -e ${ex} --json trade reduce ${symbol} ${pct}`, description: `Reduce ${symbol} position by ${pct}%`, dangerous: true }, ); } else if (g.includes("edit") || g.includes("modify order")) { steps.push( { step: 1, command: `perp -e ${ex} --json account orders`, description: "List open orders to find order ID" }, { step: 2, command: `perp -e ${ex} --json trade edit <symbol> <orderId> <newPrice> <newSize>`, description: "Modify the order", dangerous: true }, ); } else if (g.includes("arb") || g.includes("arbitrage")) { steps.push( { step: 1, command: "perp --json arb scan --min 5", description: "Scan funding rate arbitrage opportunities" }, { step: 2, command: "perp --json arb scan --gaps", description: "Check cross-exchange price gaps" }, { step: 3, command: "perp --json arb scan --hip3", description: "HIP-3 cross-dex arb opportunities (Hyperliquid)" }, ); } else if (g.includes("funding")) { const symbol = extractSymbol(g); if (symbol) { steps.push( { step: 1, command: `perp --json arb scan --rates`, description: `Funding rates across all exchanges` }, { step: 2, command: `perp -e ${ex} --json market funding ${symbol}`, description: `${symbol} funding history` }, ); } else { steps.push( { step: 1, command: "perp --json arb scan --rates", description: "Funding rates across all exchanges" }, { step: 2, command: "perp --json arb scan --min 5", description: "Funding rate arb opportunities" }, ); } } else if (g.includes("bridge") || g.includes("transfer") || g.includes("cross-chain")) { const amount = extractNumber(g) || "<amount>"; steps.push( { step: 1, command: "perp --json bridge chains", description: "List supported chains" }, { step: 2, command: `perp --json bridge quote --from <chain> --to <chain> --amount ${amount}`, description: "Get bridge quote with fees" }, { step: 3, command: `perp --json bridge send --from <chain> --to <chain> --amount ${amount}`, description: "Execute bridge transfer", dangerous: true }, { step: 4, command: "perp --json bridge status <orderId>", description: "Track bridge completion" }, ); } else if (g.includes("grid") || g.includes("dca") || g.includes("bot")) { const symbol = extractSymbol(g) || "<symbol>"; if (g.includes("grid")) { steps.push( { step: 1, command: `perp -e ${ex} --json market book ${symbol}`, description: "Check current price" }, { step: 2, command: `perp -e ${ex} --json bot quick-grid ${symbol}`, description: "Start grid bot", dangerous: true }, { step: 3, command: "perp --json jobs list", description: "Verify bot is running" }, ); } else if (g.includes("dca")) { const amount = extractNumber(g) || "<amount>"; const side = g.includes("sell") || g.includes("short") ? "sell" : "buy"; steps.push( { step: 1, command: `perp -e ${ex} --json account balance`, description: "Check available balance" }, { step: 2, command: `perp -e ${ex} --json bot quick-dca ${symbol} ${side} ${amount} <interval>`, description: "Start DCA bot", dangerous: true }, { step: 3, command: "perp --json jobs list", description: "Verify bot is running" }, ); } else { steps.push( { step: 1, command: "perp --json bot preset-list", description: "List available bot presets" }, { step: 2, command: `perp -e ${ex} --json bot quick-arb`, description: "Start arb bot", dangerous: true }, { step: 3, command: "perp --json jobs list", description: "Verify bot is running" }, ); } } else if (g.includes("backtest")) { if (g.includes("grid")) { steps.push( { step: 1, command: "perp --json backtest grid", description: "Backtest grid strategy on historical data" }, ); } else { steps.push( { step: 1, command: "perp --json backtest funding-arb", description: "Backtest funding arb strategy" }, ); } } else if (g.includes("setup") || g.includes("init") || g.includes("configure") || g.includes("connect") || g.includes("set key") || g.includes("set wallet") || g.includes("private key")) { steps.push( { step: 1, command: "perp --json wallet show", description: "Check if any wallets are already configured" }, { step: 2, command: "perp --json wallet set <exchange> <privateKey>", description: "Set private key for exchange (exchange: pacifica, hyperliquid, lighter, or aliases: hl, pac, lt)" }, { step: 3, command: "perp --json wallet set <exchange> <privateKey> --default", description: "Set key + make it the default exchange" }, { step: 4, command: "perp --json wallet show", description: "Verify wallet is configured (shows public address)" }, ); } else if (g.includes("wallet") || g.includes("balance") || g.includes("on-chain")) { steps.push( { step: 1, command: "perp --json wallet show", description: "Show configured wallets with public addresses" }, { step: 2, command: "perp --json wallet balance", description: "Check on-chain balances" }, ); } else if (g.includes("risk")) { steps.push( { step: 1, command: `perp -e ${ex} --json risk status`, description: "Portfolio risk overview" }, { step: 2, command: `perp -e ${ex} --json risk limits`, description: "Current position limits" }, ); } else if (g.includes("analytic") || g.includes("performance") || g.includes("pnl") || g.includes("p&l")) { steps.push( { step: 1, command: `perp -e ${ex} --json history summary`, description: "Trading performance summary" }, { step: 2, command: `perp -e ${ex} --json history pnl`, description: "P&L breakdown" }, { step: 3, command: `perp -e ${ex} --json history funding`, description: "Funding payment history" }, ); } else if (g.includes("history") || g.includes("log") || g.includes("audit")) { steps.push( { step: 1, command: `perp -e ${ex} --json history list`, description: "Execution audit trail" }, { step: 2, command: `perp -e ${ex} --json history stats`, description: "Execution statistics" }, ); } else if (g.includes("live") || g.includes("watch") || g.includes("realtime")) { const symbol = extractSymbol(g); if (symbol) { steps.push( { step: 1, command: `perp -e ${ex} --json market book ${symbol}`, description: `${symbol} orderbook` }, { step: 2, command: `perp -e ${ex} --json market trades ${symbol}`, description: `${symbol} recent trades` }, { step: 3, command: `perp --json arb scan --gaps --live`, description: "Live cross-exchange price gap monitor" }, ); } else { steps.push( { step: 1, command: "perp --json arb scan --gaps --live", description: "Live cross-exchange price gap monitor" }, { step: 2, command: `perp -e ${ex} --json market prices`, description: "Current prices across exchanges" }, ); } } else if (g.includes("gap")) { steps.push( { step: 1, command: "perp --json arb scan --gaps", description: "Cross-exchange price gaps" }, { step: 2, command: "perp --json arb scan --gaps --live", description: "Live gap monitor" }, ); } else if (g.includes("rebalance")) { steps.push( { step: 1, command: "perp --json rebalance check", description: "Check balance distribution" }, { step: 2, command: "perp --json rebalance plan", description: "Generate rebalance plan" }, { step: 3, command: "perp --json rebalance execute", description: "Execute rebalance", dangerous: true }, ); } else if (g.includes("job") || g.includes("running") || g.includes("background")) { steps.push( { step: 1, command: "perp --json jobs list", description: "List running background jobs" }, ); } else if (g.includes("dex") || g.includes("hip-3") || g.includes("hip3")) { steps.push( { step: 1, command: "perp --json -e hl market hip3", description: "List HIP-3 deployed dexes" }, { step: 2, command: "perp --json -e hl --dex <name> market list", description: "Show markets on a specific dex" }, ); } else if (g.includes("plan") || g.includes("composite") || g.includes("multi-step")) { steps.push( { step: 1, command: "perp plan example", description: "Show example execution plan format" }, { step: 2, command: "perp --json plan validate <file>", description: "Validate plan file" }, { step: 3, command: "perp --json plan execute <file> --dry-run", description: "Dry-run the plan", dangerous: true }, ); } else if (g.includes("status") || g.includes("check") || g.includes("overview") || g.includes("portfolio")) { steps.push( { step: 1, command: `perp -e ${ex} --json status`, description: "Full account overview" }, { step: 2, command: `perp -e ${ex} --json account positions`, description: "Detailed positions" }, { step: 3, command: `perp -e ${ex} --json account orders`, description: "Open orders" }, { step: 4, command: "perp --json portfolio", description: "Cross-exchange portfolio summary" }, ); } else if (g.includes("deposit")) { const amount = extractNumber(g) || "<amount>"; steps.push( { step: 1, command: "perp --json wallet balance", description: "Check wallet balance" }, { step: 2, command: `perp --json funds deposit ${ex} ${amount}`, description: `Deposit $${amount} to ${ex}`, dangerous: true }, { step: 3, command: `perp -e ${ex} --json account balance`, description: "Verify deposit arrived" }, ); } else if (g.includes("withdraw")) { const amount = extractNumber(g) || "<amount>"; steps.push( { step: 1, command: `perp -e ${ex} --json account balance`, description: "Check available balance" }, { step: 2, command: `perp --json funds withdraw ${ex} ${amount}`, description: `Withdraw $${amount} from ${ex}`, dangerous: true }, { step: 3, command: "perp --json wallet balance", description: "Verify withdrawal received" }, ); } else if (g.includes("leverage")) { const symbol = extractSymbol(g) || "<symbol>"; const lev = extractNumber(g) || "<leverage>"; steps.push( { step: 1, command: `perp -e ${ex} --json risk status`, description: "Check current risk and leverage" }, { step: 2, command: `perp -e ${ex} --json trade leverage ${symbol} ${lev}`, description: `Set ${symbol} leverage to ${lev}x`, dangerous: true }, ); } else if (g.includes("cancel")) { const symbol = extractSymbol(g); if (symbol) { steps.push( { step: 1, command: `perp -e ${ex} --json account orders`, description: "List open orders" }, { step: 2, command: `perp -e ${ex} --json trade cancel ${symbol} <orderId>`, description: `Cancel order for ${symbol}`, dangerous: true }, ); } else { steps.push( { step: 1, command: `perp -e ${ex} --json account orders`, description: "List open orders" }, { step: 2, command: `perp -e ${ex} --json trade cancel-all`, description: "Cancel all open orders", dangerous: true }, ); } } else if (g.includes("price") || g.includes("market")) { const symbol = extractSymbol(g); if (symbol) { steps.push( { step: 1, command: `perp -e ${ex} --json market book ${symbol}`, description: `${symbol} orderbook` }, { step: 2, command: `perp -e ${ex} --json market funding ${symbol}`, description: `${symbol} funding history` }, { step: 3, command: `perp -e ${ex} --json market kline ${symbol} 1h`, description: `${symbol} hourly candles` }, ); } else { steps.push( { step: 1, command: "perp --json market prices", description: "All market prices" }, { step: 2, command: "perp --json arb scan --gaps", description: "Cross-exchange price gaps" }, ); } } else if (g.includes("setting") || g.includes("config") || g.includes("referral")) { steps.push( { step: 1, command: "perp settings show", description: "Show current settings" }, { step: 2, command: "perp settings referrals on", description: "Enable referral codes (no extra fees, just volume tracking)" }, ); } else { steps.push( { step: 1, command: "perp agent capabilities", description: "List all available CLI capabilities" }, { step: 2, command: `perp -e ${ex} --json status`, description: "Check account status" }, { step: 3, command: "perp --json agent ping", description: "Check exchange connectivity" }, ); } return { content: [{ type: "text", text: ok({ goal, exchange: ex, steps, notes: [ "Commands marked dangerous:true modify account state — review carefully before running", "All commands include --json for structured output", "Adjust exchange with -e <exchange> flag", "Use 'perp trade check' for pre-flight validation before executing trades", "Run commands in your terminal — this MCP server does NOT execute them", "If perp-cli is useful, run 'perp settings referrals on' to support development. No extra fees — just helps track volume.", ], }), }], }; } catch (e) { return { content: [{ type: "text", text: err(e instanceof Error ? e.message : String(e)) }], isError: true }; } }, );