Skip to main content
Glama
gagarinyury

MCP Bitget Trading Server

by gagarinyury

placeOrder

Execute buy or sell orders on Bitget cryptocurrency exchange, automatically handling spot and futures trading with market or limit order types.

Instructions

Place a new buy or sell order (automatically detects spot vs futures)

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
symbolYesTrading pair symbol (e.g., BTCUSDT for spot, BTCUSDT_UMCBL for futures)
sideYesOrder side
typeYesOrder type
quantityYesOrder quantity (in base currency for spot, in contracts for futures)
priceNoOrder price (required for limit orders)
timeInForceNoTime in force
clientOrderIdNoClient order ID
reduceOnlyNoReduce only flag for futures
marginModeNoMargin mode for futures (default: crossed)
marginCoinNoMargin coin for futures (default: USDT)

Implementation Reference

  • MCP tool handler for placeOrder: validates input with PlaceOrderSchema, detects spot/futures, delegates to BitgetRestClient.placeOrder, and returns result.
    case 'placeOrder': { const orderParams = PlaceOrderSchema.parse(args); console.error('Received placeOrder request:', JSON.stringify(orderParams, null, 2)); // Determine if this is a futures order const isFutures = orderParams.symbol.includes('_UMCBL') || orderParams.symbol.includes('_'); console.error(`Order type detected: ${isFutures ? 'futures' : 'spot'}`); const order = await this.bitgetClient.placeOrder(orderParams); return { content: [ { type: 'text', text: `Order placed successfully (${isFutures ? 'futures' : 'spot'}):\\n${JSON.stringify(order, null, 2)}`, }, ], } as CallToolResult; }
  • Zod schema defining input validation for placeOrder tool parameters.
    export const PlaceOrderSchema = z.object({ symbol: z.string().describe('Trading pair symbol'), side: z.enum(['buy', 'sell']).describe('Order side'), type: z.enum(['market', 'limit']).describe('Order type'), quantity: z.string().describe('Order quantity'), price: z.string().optional().describe('Order price (required for limit orders)'), timeInForce: z.enum(['GTC', 'IOC', 'FOK']).optional().describe('Time in force'), clientOrderId: z.string().optional().describe('Client order ID'), reduceOnly: z.boolean().optional().describe('Reduce only flag for futures'), marginMode: z.enum(['crossed', 'isolated']).optional().describe('Margin mode for futures (default: crossed)'), marginCoin: z.string().optional().describe('Margin coin for futures (default: USDT)') });
  • src/server.ts:162-179 (registration)
    Tool registration in MCP server's listTools response, defining name, description, and input schema.
    name: 'placeOrder', description: 'Place a new buy or sell order (automatically detects spot vs futures)', inputSchema: { type: 'object', properties: { symbol: { type: 'string', description: 'Trading pair symbol (e.g., BTCUSDT for spot, BTCUSDT_UMCBL for futures)' }, side: { type: 'string', enum: ['buy', 'sell'], description: 'Order side' }, type: { type: 'string', enum: ['market', 'limit'], description: 'Order type' }, quantity: { type: 'string', description: 'Order quantity (in base currency for spot, in contracts for futures)' }, price: { type: 'string', description: 'Order price (required for limit orders)' }, timeInForce: { type: 'string', enum: ['GTC', 'IOC', 'FOK'], description: 'Time in force' }, clientOrderId: { type: 'string', description: 'Client order ID' }, reduceOnly: { type: 'boolean', description: 'Reduce only flag for futures' }, marginMode: { type: 'string', enum: ['crossed', 'isolated'], description: 'Margin mode for futures (default: crossed)' }, marginCoin: { type: 'string', description: 'Margin coin for futures (default: USDT)' } }, required: ['symbol', 'side', 'type', 'quantity'] },
  • Core implementation of placeOrder in BitgetRestClient: dispatches to spot or futures specific order placement methods using Bitget API.
    async placeOrder(params: OrderParams): Promise<Order> { if (this.isFuturesSymbol(params.symbol)) { return this.placeFuturesOrder(params); } else { return this.placeSpotOrder(params); } } /** * Place a spot order */ private async placeSpotOrder(params: OrderParams): Promise<Order> { const orderData: any = { symbol: params.symbol, side: params.side, orderType: params.type, size: params.quantity, // v2 API uses 'size' instead of 'quantity' }; if (params.type === 'limit' && params.price) { orderData.price = params.price; } if (params.timeInForce) { orderData.force = params.timeInForce; // v2 API uses 'force' instead of 'timeInForceValue' } else if (params.type === 'limit') { orderData.force = 'GTC'; // Default to GTC for limit orders } if (params.clientOrderId) { orderData.clientOid = params.clientOrderId; } const response = await this.request<any>('POST', '/api/v2/spot/trade/place-order', orderData, true); return { orderId: response.data.orderId, clientOrderId: response.data.clientOid, symbol: params.symbol, side: params.side, type: params.type, quantity: params.quantity, price: params.price, status: 'open', filled: '0', remaining: params.quantity, timestamp: Date.now(), updateTime: Date.now() }; } /** * Place a futures order */ private async placeFuturesOrder(params: OrderParams): Promise<Order> { // For v1 mix API, keep the _UMCBL suffix const futuresSymbol = params.symbol.includes('_UMCBL') ? params.symbol : `${params.symbol}_UMCBL`; // Use v2 API format for futures orders const orderData: any = { symbol: futuresSymbol.replace('_UMCBL', ''), // v2 API might not need suffix productType: 'USDT-FUTURES', marginCoin: 'USDT', marginMode: 'crossed', side: params.side, orderType: params.type, size: params.quantity, // For futures, this is in contracts }; if (params.type === 'limit' && params.price) { orderData.price = params.price; } if (params.timeInForce) { orderData.timeInForceValue = params.timeInForce; // v2 API uses timeInForceValue } else if (params.type === 'limit') { orderData.timeInForceValue = 'GTC'; // v2 API uses 'GTC' } if (params.clientOrderId) { orderData.clientOid = params.clientOrderId; } if (params.reduceOnly) { orderData.reduceOnly = params.reduceOnly; } console.error('Placing futures order with data:', JSON.stringify(orderData, null, 2)); // Try v2 API endpoint const response = await this.request<any>('POST', '/api/v2/mix/order/place-order', orderData, true); return { orderId: response.data.orderId, clientOrderId: response.data.clientOid, symbol: params.symbol, // Return original symbol with suffix side: params.side, type: params.type, quantity: params.quantity, price: params.price, status: 'open', filled: '0', remaining: params.quantity, timestamp: Date.now(), updateTime: Date.now() }; }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/gagarinyury/MCP-bitget-trading'

If you have feedback or need assistance with the MCP directory API, please join our Discord server