Skip to main content
Glama
harshitdynamite

DhanHQ MCP Server

place_order

Execute buy or sell orders on DhanHQ trading platform using various order types including MARKET, LIMIT, STOP_LOSS, and STOP_LOSS_MARKET for different exchange segments and product types.

Instructions

Places a new order on DhanHQ. Requires authentication. Supports MARKET, LIMIT, STOP_LOSS, and STOP_LOSS_MARKET orders.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
dhanClientIdYesYour Dhan client ID
correlationIdYesUnique correlation ID for order tracking
transactionTypeYes
exchangeSegmentYese.g., NSE_EQ, BSE_EQ, NFO_FUT
productTypeYesCNC=Delivery, INTRADAY=Intraday, MARGIN=Margin, CO=Cover Order, BO=Bracket Order
orderTypeYes
validityYesDAY=Valid for today, IOC=Immediate or Cancel
securityIdYesSecurity ID for the instrument
quantityYesQuantity to order
priceYesPrice per share (required for LIMIT/STOP_LOSS)
triggerPriceNoTrigger price (required for STOP_LOSS/STOP_LOSS_MARKET)
disclosedQuantityNoQuantity visible in order book (min 30% of quantity)
afterMarketOrderNoFlag for after-market orders
amoTimeNoAMO timing
boProfitValueNoBO target price change
boStopLossValueNoBO stop loss price change

Implementation Reference

  • Core implementation of the placeOrder function that executes the API call to place an order on DhanHQ.
    export async function placeOrder(
      request: PlaceOrderRequest
    ): Promise<OrderResponse> {
      try {
        log(`Placing order: ${request.transactionType} ${request.quantity} shares`);
    
        const response = await axios.post<OrderResponse>(
          'https://api.dhan.co/v2/orders',
          request,
          {
            headers: getApiHeaders(),
          }
        );
    
        log(`✓ Order placed successfully. Order ID: ${response.data.orderId}`);
        return response.data;
      } catch (error) {
        const errorMessage =
          error instanceof axios.AxiosError
            ? `API Error: ${error.response?.status} - ${JSON.stringify(error.response?.data)}`
            : error instanceof Error
              ? error.message
              : 'Unknown error';
    
        log(`✗ Failed to place order: ${errorMessage}`);
        throw new Error(`Failed to place order: ${errorMessage}`);
      }
    }
  • TypeScript interface defining the structure and types for PlaceOrderRequest used in the handler.
    export interface PlaceOrderRequest {
      dhanClientId: string;
      correlationId: string;
      transactionType: 'BUY' | 'SELL';
      exchangeSegment: string;
      productType: 'CNC' | 'INTRADAY' | 'MARGIN' | 'MTF' | 'CO' | 'BO';
      orderType: 'LIMIT' | 'MARKET' | 'STOP_LOSS' | 'STOP_LOSS_MARKET';
      validity: 'DAY' | 'IOC';
      securityId: string;
      quantity: number;
      disclosedQuantity?: number;
      price?: number;
      triggerPrice?: number;
      afterMarketOrder?: boolean;
      amoTime?: 'PRE_OPEN' | 'OPEN' | 'OPEN_30' | 'OPEN_60';
      boProfitValue?: number;
      boStopLossValue?: number;
    }
  • src/index.ts:118-165 (registration)
    MCP tool registration in the tools list, including name, description, and detailed inputSchema for validation.
    {
      name: 'place_order',
      description:
        'Places a new order on DhanHQ. Requires authentication. Supports MARKET, LIMIT, STOP_LOSS, and STOP_LOSS_MARKET orders.',
      inputSchema: {
        type: 'object' as const,
        properties: {
          dhanClientId: { type: 'string', description: 'Your Dhan client ID' },
          correlationId: { type: 'string', description: 'Unique correlation ID for order tracking' },
          transactionType: { type: 'string', enum: ['BUY', 'SELL'] },
          exchangeSegment: { type: 'string', description: 'e.g., NSE_EQ, BSE_EQ, NFO_FUT' },
          productType: {
            type: 'string',
            enum: ['CNC', 'INTRADAY', 'MARGIN', 'MTF', 'CO', 'BO'],
            description: 'CNC=Delivery, INTRADAY=Intraday, MARGIN=Margin, CO=Cover Order, BO=Bracket Order',
          },
          orderType: {
            type: 'string',
            enum: ['MARKET', 'LIMIT', 'STOP_LOSS', 'STOP_LOSS_MARKET'],
          },
          validity: {
            type: 'string',
            enum: ['DAY', 'IOC'],
            description: 'DAY=Valid for today, IOC=Immediate or Cancel',
          },
          securityId: { type: 'string', description: 'Security ID for the instrument' },
          quantity: { type: 'number', description: 'Quantity to order' },
          price: { type: 'number', description: 'Price per share (required for LIMIT/STOP_LOSS)' },
          triggerPrice: { type: 'number', description: 'Trigger price (required for STOP_LOSS/STOP_LOSS_MARKET)' },
          disclosedQuantity: { type: 'number', description: 'Quantity visible in order book (min 30% of quantity)' },
          afterMarketOrder: { type: 'boolean', description: 'Flag for after-market orders' },
          amoTime: { type: 'string', enum: ['PRE_OPEN', 'OPEN', 'OPEN_30', 'OPEN_60'], description: 'AMO timing' },
          boProfitValue: { type: 'number', description: 'BO target price change' },
          boStopLossValue: { type: 'number', description: 'BO stop loss price change' },
        },
        required: [
          'dhanClientId',
          'correlationId',
          'transactionType',
          'exchangeSegment',
          'productType',
          'orderType',
          'validity',
          'securityId',
          'quantity',
          'price',
        ],
      },
  • MCP server dispatch handler for 'place_order' tool that maps arguments and invokes the core placeOrder function.
    case 'place_order': {
      console.error('[Tool] Executing: place_order');
      const orderArgs = args as Record<string, unknown>;
      const result = await placeOrder({
        dhanClientId: orderArgs.dhanClientId as string,
        correlationId: orderArgs.correlationId as string,
        transactionType: orderArgs.transactionType as 'BUY' | 'SELL',
        exchangeSegment: orderArgs.exchangeSegment as string,
        productType: orderArgs.productType as 'CNC' | 'INTRADAY' | 'MARGIN' | 'MTF' | 'CO' | 'BO',
        orderType: orderArgs.orderType as 'LIMIT' | 'MARKET' | 'STOP_LOSS' | 'STOP_LOSS_MARKET',
        validity: orderArgs.validity as 'DAY' | 'IOC',
        securityId: orderArgs.securityId as string,
        quantity: orderArgs.quantity as number,
        price: orderArgs.price as number | undefined,
        triggerPrice: orderArgs.triggerPrice as number | undefined,
        disclosedQuantity: orderArgs.disclosedQuantity as number | undefined,
        afterMarketOrder: orderArgs.afterMarketOrder as boolean | undefined,
        amoTime: orderArgs.amoTime as 'PRE_OPEN' | 'OPEN' | 'OPEN_30' | 'OPEN_60' | undefined,
        boProfitValue: orderArgs.boProfitValue as number | undefined,
        boStopLossValue: orderArgs.boStopLossValue as number | undefined,
      });
      return {
        content: [
          {
            type: 'text' as const,
            text: JSON.stringify(result, null, 2),
          },
        ],
      };
    }
Behavior2/5

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

With no annotations, the description carries full burden but only states authentication requirement and supported order types. It lacks critical behavioral details: whether this is a synchronous or asynchronous operation, error handling, rate limits, confirmation mechanisms, or what happens on success/failure.

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?

Two sentences with zero waste. First sentence states core purpose and authentication requirement. Second sentence efficiently lists supported order types. Perfectly front-loaded and appropriately sized.

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?

For a complex order placement tool with 16 parameters, 10 required, no annotations, and no output schema, the description is inadequate. It doesn't explain return values, error conditions, or the operational context needed to use this tool effectively.

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?

With 88% schema description coverage, the schema already documents most parameters well. The description adds minimal value by listing order types, but doesn't explain parameter interactions, dependencies, or business logic beyond what's in schema descriptions.

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 action ('Places a new order') and target resource ('on DhanHQ'), with specific order types listed. It distinguishes from siblings like 'modify_order' or 'cancel_order' by focusing on creation, though it doesn't explicitly contrast with 'place_super_order'.

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 mentions authentication requirement but provides no guidance on when to use this tool versus alternatives like 'place_super_order' or 'modify_order'. No context about prerequisites, timing, or trade-offs is given.

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/harshitdynamite/DhanMCP'

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