place_order
Execute BUY or SELL orders for stocks with MARKET/LIMIT pricing and CNC/MIS/NRML product types on Groww trading platform.
Instructions
Place BUY/SELL order — supports MARKET/LIMIT, CNC/MIS/NRML product types
Input Schema
TableJSON Schema
| Name | Required | Description | Default |
|---|---|---|---|
| symbol | Yes | Stock symbol, e.g. RELIANCE | |
| exchange | No | Exchange | NSE |
| order_type | Yes | BUY or SELL | |
| product_type | No | CNC (delivery), MIS (intraday), NRML (F&O) | CNC |
| price_type | No | MARKET or LIMIT order | MARKET |
| quantity | Yes | Number of shares | |
| price | No | Limit price (required for LIMIT orders) | |
| trigger_price | No | Stop-loss trigger price |
Implementation Reference
- src/tools/orders.ts:16-68 (handler)The "place_order" tool is defined using server.tool, validating inputs with Zod, and calling the growwClient.placeOrder method.
server.tool( "place_order", "Place BUY/SELL order — supports MARKET/LIMIT, CNC/MIS/NRML product types", { symbol: z.string().describe("Stock symbol, e.g. RELIANCE"), exchange: z.enum(["NSE", "BSE"]).default("NSE").describe("Exchange"), order_type: z.enum(["BUY", "SELL"]).describe("BUY or SELL"), product_type: z.enum(["CNC", "MIS", "NRML"]).default("CNC").describe("CNC (delivery), MIS (intraday), NRML (F&O)"), price_type: z.enum(["MARKET", "LIMIT"]).default("MARKET").describe("MARKET or LIMIT order"), quantity: z.number().int().positive().describe("Number of shares"), price: z.number().positive().optional().describe("Limit price (required for LIMIT orders)"), trigger_price: z.number().positive().optional().describe("Stop-loss trigger price"), }, async ({ symbol, exchange, order_type, product_type, price_type, quantity, price, trigger_price }) => { try { if (price_type === "LIMIT" && !price) { return mcpError("Limit price is required for LIMIT orders"); } const sym = normalizeSymbol(symbol); const result = await growwClient.placeOrder({ symbol: sym, exchange, orderType: order_type, productType: product_type, priceType: price_type, quantity, price: price ?? 0, triggerPrice: trigger_price ?? 0, }); const emoji = order_type === "BUY" ? "🟢" : "🔴"; const text = [ `${emoji} ORDER PLACED`, `${"─".repeat(40)}`, `Order ID: ${result.orderId}`, `Status: ${result.status}`, `Action: ${order_type} ${sym}.${exchange}`, `Type: ${price_type} / ${product_type}`, `Quantity: ${quantity}`, price_type === "LIMIT" ? `Price: ${formatCurrencyExact(price!)}` : `Price: MARKET`, trigger_price ? `Trigger: ${formatCurrencyExact(trigger_price)}` : "", ``, `${result.message}`, ``, `⚠️ This is ${process.env.MOCK_MODE === "true" ? "a MOCK order (no real trade)" : "a REAL order with real money"}`, ].filter(Boolean).join("\n"); return mcpText(text); } catch (err) { return mcpError(normalizeError(err)); } } );