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()
      };
    }
Behavior2/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With no annotations provided, the description carries the full burden of behavioral disclosure. It mentions automatic detection of spot vs futures, which is useful context, but fails to describe critical traits: whether this is a read/write operation (implied write but not stated), potential side effects (e.g., fund deduction, position changes), error conditions, or rate limits. For a financial transaction tool, this is a significant gap.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness5/5

Is the description appropriately sized, front-loaded, and free of redundancy?

The description is a single, efficient sentence that front-loads the core purpose ('Place a new buy or sell order') and adds a key feature ('automatically detects spot vs futures'). There's no wasted verbiage, making it easy for an agent to parse quickly.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness2/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

Given the complexity of a financial order placement tool with 10 parameters, no annotations, and no output schema, the description is insufficient. It lacks details on behavioral traits (e.g., idempotency, error handling), usage context, and return values, leaving critical gaps for safe and effective tool invocation.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

The description adds no parameter-specific information beyond what's already in the schema (which has 100% coverage). It implies the tool handles both spot and futures orders, but doesn't explain how parameters like 'reduceOnly' or 'marginMode' apply differently. With high schema coverage, the baseline is 3, as the description doesn't compensate with additional semantic context.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose4/5

Does the description clearly state what the tool does and how it differs from similar tools?

The description clearly states the tool's purpose: 'Place a new buy or sell order' with the added detail of 'automatically detects spot vs futures'. This specifies the verb ('place'), resource ('order'), and a key capability (automatic detection). However, it doesn't explicitly differentiate from sibling tools like 'cancelOrder' or 'getOrders', which would require a 5.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines2/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

The description provides no guidance on when to use this tool versus alternatives. It doesn't mention prerequisites (e.g., authentication, account funding), when to choose spot vs futures, or compare to other order-related tools like 'cancelOrder'. This leaves the agent without context for appropriate tool selection.

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Install Server

Other Tools

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