Skip to main content
Glama
Habinar

MCP Paradex Server

by Habinar

paradex_create_order

Execute trades on Paradex with precise control over order parameters, including limit, stop-loss, and take-profit orders for risk management.

Instructions

Execute trades on Paradex with precise control over all order parameters.

Use this tool when you need to:
- Enter a new position based on your trading strategy
- Set limit orders at specific price levels
- Create stop-loss or take-profit orders for risk management
- Implement complex trading strategies with conditional orders

This is the primary tool for executing your trading decisions on Paradex,
with full control over order type, size, price, and execution parameters.

Example use cases:
- Setting limit orders at key support/resistance levels
- Placing stop-limit orders to manage risk on existing positions
- Executing market orders for immediate entry or exit
- Creating reduce-only orders to ensure you don't flip position direction

Succesful response indicates that orders were queued for execution.
Check order status using order id.

Input Schema

TableJSON Schema
NameRequiredDescriptionDefault
market_idYesMarket identifier.
order_sideYesOrder side.
order_typeYesOrder type.
sizeYesOrder size.
priceYesOrder price (required for LIMIT orders).
trigger_priceYesTrigger price for stop limit orders.
instructionNoInstruction for order execution.GTC
reduce_onlyNoReduce-only flag.
client_idYesClient-specified order ID.

Implementation Reference

  • The core handler function for the 'paradex_create_order' tool. Decorated with @server.tool for registration. Constructs and submits an Order to the Paradex client, returns formatted OrderState.
    @server.tool(name="paradex_create_order")
    async def create_order(
        market_id: Annotated[str, Field(description="Market identifier.")],
        order_side: Annotated[OrderSideEnum, Field(description="Order side.")],
        order_type: Annotated[OrderTypeEnum, Field(description="Order type.")],
        size: Annotated[float, Field(description="Order size.")],
        price: Annotated[float, Field(description="Order price (required for LIMIT orders).")],
        trigger_price: Annotated[float, Field(description="Trigger price for stop limit orders.")],
        instruction: Annotated[
            InstructionEnum, Field(default="GTC", description="Instruction for order execution.")
        ],
        reduce_only: Annotated[bool, Field(default=False, description="Reduce-only flag.")],
        client_id: Annotated[str, Field(description="Client-specified order ID.")],
        ctx: Context = None,
    ) -> dict:
        """
        Execute trades on Paradex with precise control over all order parameters.
    
        Use this tool when you need to:
        - Enter a new position based on your trading strategy
        - Set limit orders at specific price levels
        - Create stop-loss or take-profit orders for risk management
        - Implement complex trading strategies with conditional orders
    
        This is the primary tool for executing your trading decisions on Paradex,
        with full control over order type, size, price, and execution parameters.
    
        Example use cases:
        - Setting limit orders at key support/resistance levels
        - Placing stop-limit orders to manage risk on existing positions
        - Executing market orders for immediate entry or exit
        - Creating reduce-only orders to ensure you don't flip position direction
    
        Succesful response indicates that orders were queued for execution.
        Check order status using order id.
        """
        client = await get_authenticated_paradex_client()
        o = Order(
            market=market_id,
            order_side=OrderSide(order_side),
            order_type=OrderType(order_type),
            size=Decimal(str(size)),
            client_id=client_id,
            limit_price=Decimal(str(price)) if price else Decimal(0),
            reduce_only=reduce_only,
            instruction=instruction,
            trigger_price=Decimal(str(trigger_price)) if trigger_price else None,
        )
        response = client.submit_order(o)
        order: OrderState = OrderState(**response)
        result = {
            "description": OrderState.__doc__.strip() if OrderState.__doc__ else None,
            "fields": OrderState.model_json_schema(),
            "results": order,
        }
        return result
  • The @server.tool decorator registers the paradex_create_order tool with the FastMCP server.
    @server.tool(name="paradex_create_order")
  • Pydantic schemas used by the tool: OrderTypeEnum, InstructionEnum, OrderSideEnum for input parameters; OrderState BaseModel for output validation and schema generation.
    OrderTypeEnum = Literal[
        "MARKET",
        "LIMIT",
        "STOP_LIMIT",
        "STOP_MARKET",
        "TAKE_PROFIT_LIMIT",
        "TAKE_PROFIT_MARKET",
        "STOP_LOSS_MARKET",
        "STOP_LOSS_LIMIT",
    ]
    
    # Define allowed instruction types
    InstructionEnum = Literal["GTC", "IOC", "POST_ONLY"]
    OrderSideEnum = Literal["BUY", "SELL"]
    
    
    class OrderState(BaseModel):
        """Order state model representing the current state of an order on Paradex."""
    
        id: Annotated[str, Field(description="Unique order identifier generated by Paradex")]
        account: Annotated[str, Field(description="Paradex Account")]
        market: Annotated[str, Field(description="Market")]
        side: Annotated[str, Field(description="Order side")]
        type: Annotated[str, Field(description="Order type")]
        size: Annotated[float, Field(description="Order size")]
        remaining_size: Annotated[float, Field(description="Remaining size of the order")]
        price: Annotated[float, Field(description="Order price. 0 for MARKET orders")]
        status: Annotated[str, Field(description="Order status")]
        created_at: Annotated[int, Field(description="Order creation time")]
        last_updated_at: Annotated[
            int, Field(description="Order last update time. No changes once status=CLOSED")
        ]
        timestamp: Annotated[int, Field(description="Order signature timestamp")]
        cancel_reason: Annotated[
            str, Field(description="Reason for order cancellation if it was closed by cancel")
        ]
        client_id: Annotated[
            str, Field(description="Client order id provided by the client at order creation")
        ]
        seq_no: Annotated[
            int,
            Field(
                description="Unique increasing number that is assigned to this order update and changes on every order update"
            ),
        ]
        instruction: Annotated[str, Field(description="Execution instruction for order matching")]
        avg_fill_price: Annotated[str, Field(description="Average fill price of the order")]
        stp: Annotated[str, Field(description="Self Trade Prevention mode")]
        received_at: Annotated[
            int, Field(description="Timestamp in milliseconds when order was received by API service")
        ]
        published_at: Annotated[
            int, Field(description="Timestamp in milliseconds when order was sent to the client")
        ]
        flags: Annotated[list[str], Field(description="Order flags, allow flag: REDUCE_ONLY")]
        trigger_price: Annotated[str, Field(description="Trigger price for stop order")]
Behavior4/5

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

With no annotations provided, the description carries full burden. It effectively discloses key behavioral traits: that this is an execution tool (implying write/mutative operations), that successful response means 'orders were queued for execution' (not necessarily filled), and that users should check order status separately. It doesn't mention rate limits, authentication requirements, or error conditions, but provides substantial operational context.

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 well-structured and appropriately sized. It begins with a clear purpose statement, follows with usage guidelines in bullet points, provides context about being the primary execution tool, gives concrete example use cases, and ends with important behavioral information about response interpretation. Every sentence earns its place with no wasted words.

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

Completeness4/5

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

For a complex trading execution tool with 9 parameters (7 required) and no annotations or output schema, the description does an excellent job. It covers purpose, usage scenarios, behavioral expectations, and references follow-up actions. The main gap is lack of information about authentication requirements, rate limits, or error handling, which would be valuable for a financial trading tool.

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?

Schema description coverage is 100%, so the schema already documents all 9 parameters thoroughly. The description adds minimal parameter semantics beyond the schema - it mentions 'full control over order type, size, price, and execution parameters' and references 'reduce-only orders' in an example, but doesn't provide additional meaning or clarification beyond what's in the parameter descriptions.

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

Purpose5/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 as executing trades on Paradex with precise control over order parameters. It specifies the verb 'execute trades' and resource 'Paradex', distinguishing it from sibling tools that focus on account information, market data, or order management rather than order creation.

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

Usage Guidelines5/5

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

The description provides explicit guidance on when to use this tool through a bulleted list of specific scenarios (entering new positions, setting limit orders, creating stop-loss/take-profit orders, implementing complex strategies). It distinguishes this as the 'primary tool for executing your trading decisions' and references checking order status with another tool (order_status), though it doesn't explicitly name alternative tools for different use cases.

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/Habinar/mcp-paradex-py'

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