Skip to main content
Glama
code-rabi

Interactive Brokers MCP Server

by code-rabi

place_order

Execute buy or sell orders for stocks through Interactive Brokers trading accounts using market, limit, or stop order types.

Instructions

Place a trading order. Examples:

  • Market buy: { "accountId":"abc","symbol":"AAPL","action":"BUY","orderType":"MKT","quantity":1 }

  • Limit sell: { "accountId":"abc","symbol":"AAPL","action":"SELL","orderType":"LMT","quantity":1,"price":185.5 }

  • Stop sell: { "accountId":"abc","symbol":"AAPL","action":"SELL","orderType":"STP","quantity":1,"stopPrice":180 }

  • Suppress confirmations: { "accountId":"abc","symbol":"AAPL","action":"BUY","orderType":"MKT","quantity":1,"suppressConfirmations":true }

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
accountIdYes
symbolYes
actionYes
orderTypeYes
quantityYes
priceNo
stopPriceNo
suppressConfirmationsNo

Implementation Reference

  • Main MCP tool handler for place_order. Ensures prerequisites (gateway, auth) and delegates order placement to IBClient, returning formatted result or error.
    async placeOrder(input: PlaceOrderInput): Promise<ToolHandlerResult> { try { // Ensure Gateway is ready await this.ensureGatewayReady(); // Ensure authentication in headless mode if (this.context.config.IB_HEADLESS_MODE) { await this.ensureAuth(); } const result = await this.context.ibClient.placeOrder({ accountId: input.accountId, symbol: input.symbol, action: input.action, orderType: input.orderType, quantity: input.quantity, // Already converted by Zod schema price: input.price, stopPrice: input.stopPrice, suppressConfirmations: input.suppressConfirmations, }); return { content: [ { type: "text", text: JSON.stringify(result, null, 2), }, ], }; } catch (error) { return { content: [ { type: "text", text: this.formatError(error), }, ], }; } }
  • Zod schema for place_order input validation, including refinements to ensure required fields for order types (price for LMT, stopPrice for STP).
    export const PlaceOrderZodSchema = z.object(PlaceOrderZodShape).refine( (data) => { if (data.orderType === "LMT" && data.price === undefined) { return false; } if (data.orderType === "STP" && data.stopPrice === undefined) { return false; } return true; }, { message: "LMT orders require price, STP orders require stopPrice", path: ["price", "stopPrice"] } );
  • src/tools.ts:74-83 (registration)
    MCP server registration of the 'place_order' tool, including description, input shape, and handler reference.
    server.tool( "place_order", "Place a trading order. Examples:\n" + "- Market buy: `{ \"accountId\":\"abc\",\"symbol\":\"AAPL\",\"action\":\"BUY\",\"orderType\":\"MKT\",\"quantity\":1 }`\n" + "- Limit sell: `{ \"accountId\":\"abc\",\"symbol\":\"AAPL\",\"action\":\"SELL\",\"orderType\":\"LMT\",\"quantity\":1,\"price\":185.5 }`\n" + "- Stop sell: `{ \"accountId\":\"abc\",\"symbol\":\"AAPL\",\"action\":\"SELL\",\"orderType\":\"STP\",\"quantity\":1,\"stopPrice\":180 }`\n" + "- Suppress confirmations: `{ \"accountId\":\"abc\",\"symbol\":\"AAPL\",\"action\":\"BUY\",\"orderType\":\"MKT\",\"quantity\":1,\"suppressConfirmations\":true }`", PlaceOrderZodShape, async (args) => await handlers.placeOrder(args) );
  • Low-level IBClient method that performs symbol lookup, constructs the order payload, submits to IB Gateway API, and handles confirmations if suppressed.
    async placeOrder(orderRequest: OrderRequest): Promise<any> { try { // First, get the contract ID for the symbol const searchResponse = await this.client.get( `/iserver/secdef/search?symbol=${orderRequest.symbol}` ); if (!searchResponse.data || searchResponse.data.length === 0) { throw new Error(`Symbol ${orderRequest.symbol} not found`); } const contract = searchResponse.data[0]; const conid = contract.conid; // Prepare order object const order = { conid: Number(conid), // Ensure conid is number orderType: orderRequest.orderType, side: orderRequest.action, quantity: Number(orderRequest.quantity), // Ensure quantity is number tif: "DAY", // Time in force }; // Add price for limit orders if (orderRequest.orderType === "LMT" && orderRequest.price !== undefined) { (order as any).price = Number(orderRequest.price); } // Add stop price for stop orders if (orderRequest.orderType === "STP" && orderRequest.stopPrice !== undefined) { (order as any).auxPrice = Number(orderRequest.stopPrice); } // Place the order const response = await this.client.post( `/iserver/account/${orderRequest.accountId}/orders`, { orders: [order], } ); // Check if we received confirmation messages that need to be handled if (response.data && Array.isArray(response.data) && response.data.length > 0) { const firstResponse = response.data[0]; // Check if this is a confirmation message response if (firstResponse.id && firstResponse.message && firstResponse.messageIds && orderRequest.suppressConfirmations) { Logger.log("Order confirmation received, automatically confirming...", firstResponse); // Automatically confirm all messages const confirmResponse = await this.confirmOrder(firstResponse.id, firstResponse.messageIds); return confirmResponse; } } return response.data; } catch (error) { Logger.error("Failed to place order:", error); // Check if this is likely an authentication error if (this.isAuthenticationError(error)) { const authError = new Error("Authentication required to place orders. Please authenticate with Interactive Brokers first."); (authError as any).isAuthError = true; throw authError; } throw new Error("Failed to place order"); } }
  • Base Zod shape definition for place_order input parameters, used in tool registration and schema.
    export const PlaceOrderZodShape = { accountId: z.string(), symbol: z.string(), action: z.enum(["BUY", "SELL"]), orderType: z.enum(["MKT", "LMT", "STP"]), quantity: IntegerOrStringIntegerZod, price: z.number().optional(), stopPrice: z.number().optional(), suppressConfirmations: z.boolean().optional() };

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/code-rabi/interactive-brokers-mcp'

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