Withdraw SOL (one-shot)
withdrawWithdraw SOL from deactivated stake accounts in one call. Send secret key via HTTPS for in-memory signing—never stored. Check readiness with check_withdraw_ready first. Omit amountSol to withdraw full balance.
Instructions
Withdraw SOL from a deactivated stake account in a single call. Secret key sent over HTTPS for in-memory signing, never stored. Use check_withdraw_ready first. Omit amountSol for full balance.
Input Schema
| Name | Required | Description | Default |
|---|---|---|---|
| walletAddress | Yes | Your Solana wallet address (withdraw authority) | |
| secretKey | Yes | Your base58-encoded secret key — sent to Blueprint server over HTTPS for in-memory signing, never stored or logged | |
| stakeAccountAddress | Yes | Deactivated stake account to withdraw from | |
| amountSol | No | Amount to withdraw in SOL (omit to withdraw full balance) |
Implementation Reference
- server.ts:110-130 (registration)Registration of the 'withdraw' tool on the MCP server, including its input schema (walletAddress, secretKey, stakeAccountAddress, amountSol), metadata (title, description, annotations), and the handler that calls POST /api/v1/withdraw on the Blueprint API.
mcp.registerTool( 'withdraw', { title: 'Withdraw SOL (one-shot)', description: 'Withdraw SOL from a deactivated stake account in a single call. Secret key sent over HTTPS for in-memory signing, never stored. Use check_withdraw_ready first. Omit amountSol for full balance.', inputSchema: { walletAddress: z.string().max(50).describe('Your Solana wallet address (withdraw authority)'), secretKey: z.string().min(80).max(100).describe('Your base58-encoded secret key — sent to Blueprint server over HTTPS for in-memory signing, never stored or logged'), stakeAccountAddress: z.string().max(50).describe('Deactivated stake account to withdraw from'), amountSol: z.number().finite().positive().max(9000000).nullish().describe('Amount to withdraw in SOL (omit to withdraw full balance)'), }, annotations: WRITE_TX, }, async ({ walletAddress, secretKey, stakeAccountAddress, amountSol }) => { const body: Record<string, unknown> = { walletAddress, secretKey, stakeAccountAddress }; if (amountSol != null) body.amountSol = amountSol; const { ok, data } = await api('POST', '/api/v1/withdraw', body); if (!ok) return error(`Withdraw failed: ${(data as any)?.message || JSON.stringify(data)}`, { retry: 'withdraw', withdrawReady: 'check_withdraw_ready', accounts: 'check_stake_accounts' }); return result(data, { relatedTools: { balance: 'check_balance', stake: 'stake' } }); } ); - server.ts:123-129 (handler)Handler function for the 'withdraw' tool. Builds a request body with walletAddress, secretKey, stakeAccountAddress, and optional amountSol, then POSTs to /api/v1/withdraw. Handles errors by returning a formatted error with related tool suggestions, or returns the API response with related tool references for follow-up actions.
async ({ walletAddress, secretKey, stakeAccountAddress, amountSol }) => { const body: Record<string, unknown> = { walletAddress, secretKey, stakeAccountAddress }; if (amountSol != null) body.amountSol = amountSol; const { ok, data } = await api('POST', '/api/v1/withdraw', body); if (!ok) return error(`Withdraw failed: ${(data as any)?.message || JSON.stringify(data)}`, { retry: 'withdraw', withdrawReady: 'check_withdraw_ready', accounts: 'check_stake_accounts' }); return result(data, { relatedTools: { balance: 'check_balance', stake: 'stake' } }); } - server.ts:115-119 (schema)Zod input schema defining the 'withdraw' tool's parameters: walletAddress (string, max 50), secretKey (string, min 80, max 100), stakeAccountAddress (string, max 50), and amountSol (optional positive number, max 9M SOL).
inputSchema: { walletAddress: z.string().max(50).describe('Your Solana wallet address (withdraw authority)'), secretKey: z.string().min(80).max(100).describe('Your base58-encoded secret key — sent to Blueprint server over HTTPS for in-memory signing, never stored or logged'), stakeAccountAddress: z.string().max(50).describe('Deactivated stake account to withdraw from'), amountSol: z.number().finite().positive().max(9000000).nullish().describe('Amount to withdraw in SOL (omit to withdraw full balance)'), - server.ts:15-30 (helper)The 'api' helper function used by the withdraw handler to make HTTP POST requests to the Blueprint backend (POST /api/v1/withdraw). Handles JSON serialization, timeout (30s), and error parsing.
async function api( method: 'GET' | 'POST' | 'DELETE', path: string, body?: Record<string, unknown> ): Promise<{ ok: boolean; status: number; data: unknown }> { const url = `${API_BASE}${path}`; const headers: Record<string, string> = { 'Content-Type': 'application/json' }; const res = await fetch(url, { method, headers, signal: AbortSignal.timeout(30_000), ...(body ? { body: JSON.stringify(body) } : {}), }); const data = await res.json().catch(() => ({ error: 'non_json_response', status: res.status })); return { ok: res.ok, status: res.status, data }; }