Skip to main content
Glama

Hyperliquid MCP Server

by t3rmed
trading.ts6.31 kB
import { Tool } from '@modelcontextprotocol/sdk/types.js'; import { HyperliquidClient } from '../utils/hyperliquid-client.js'; import { OrderRequest, PlaceOrderAction, CancelOrderAction } from '../types/hyperliquid.js'; export const placeOrderTool: Tool = { name: 'place_order', description: 'Place a limit or trigger order on Hyperliquid', inputSchema: { type: 'object', properties: { assetIndex: { type: 'number', description: 'Asset index for the coin (0 for BTC, 1 for ETH, etc.)' }, isBuy: { type: 'boolean', description: 'True for buy order, false for sell order' }, price: { type: 'string', description: 'Order price as string' }, size: { type: 'string', description: 'Order size as string' }, reduceOnly: { type: 'boolean', description: 'Whether this is a reduce-only order (optional, default false)' }, timeInForce: { type: 'string', description: 'Time in force', enum: ['Gtc', 'Ioc', 'Alo'] }, clientOrderId: { type: 'string', description: 'Client order ID (optional)' } }, required: ['assetIndex', 'isBuy', 'price', 'size', 'timeInForce'] } }; export const placeTriggerOrderTool: Tool = { name: 'place_trigger_order', description: 'Place a trigger order (stop-loss or take-profit) on Hyperliquid', inputSchema: { type: 'object', properties: { assetIndex: { type: 'number', description: 'Asset index for the coin (0 for BTC, 1 for ETH, etc.)' }, isBuy: { type: 'boolean', description: 'True for buy order, false for sell order' }, size: { type: 'string', description: 'Order size as string' }, triggerPrice: { type: 'string', description: 'Trigger price as string' }, isMarket: { type: 'boolean', description: 'Whether to execute as market order when triggered' }, triggerType: { type: 'string', description: 'Trigger type', enum: ['tp', 'sl'] }, reduceOnly: { type: 'boolean', description: 'Whether this is a reduce-only order (optional, default false)' }, clientOrderId: { type: 'string', description: 'Client order ID (optional)' } }, required: ['assetIndex', 'isBuy', 'size', 'triggerPrice', 'isMarket', 'triggerType'] } }; export const cancelOrderTool: Tool = { name: 'cancel_order', description: 'Cancel a specific order by order ID or client order ID', inputSchema: { type: 'object', properties: { assetIndex: { type: 'number', description: 'Asset index for the coin' }, orderId: { type: 'number', description: 'Order ID to cancel (use either orderId or clientOrderId)' }, clientOrderId: { type: 'string', description: 'Client order ID to cancel (use either orderId or clientOrderId)' } }, required: ['assetIndex'] } }; export const cancelAllOrdersTool: Tool = { name: 'cancel_all_orders', description: 'Cancel all open orders', inputSchema: { type: 'object', properties: {}, required: [] } }; export async function handlePlaceOrder(client: HyperliquidClient, args: any) { const { assetIndex, isBuy, price, size, reduceOnly = false, timeInForce, clientOrderId } = args; const order: OrderRequest = { a: assetIndex, b: isBuy, p: price, s: size, r: reduceOnly, t: { limit: { tif: timeInForce } } }; if (clientOrderId) { order.c = clientOrderId; } const action: PlaceOrderAction = { type: 'order', orders: [order] }; const result = await client.placeOrder(action); if (!result.success) { throw new Error(`Failed to place order: ${result.error}`); } return { content: [ { type: 'text', text: `Order placed successfully!\n\n${JSON.stringify(result.data, null, 2)}` } ] }; } export async function handlePlaceTriggerOrder(client: HyperliquidClient, args: any) { const { assetIndex, isBuy, size, triggerPrice, isMarket, triggerType, reduceOnly = false, clientOrderId } = args; const order: OrderRequest = { a: assetIndex, b: isBuy, p: '0', // Not used for trigger orders s: size, r: reduceOnly, t: { trigger: { triggerPx: triggerPrice, isMarket, tpsl: triggerType } } }; if (clientOrderId) { order.c = clientOrderId; } const action: PlaceOrderAction = { type: 'order', orders: [order] }; const result = await client.placeOrder(action); if (!result.success) { throw new Error(`Failed to place trigger order: ${result.error}`); } return { content: [ { type: 'text', text: `Trigger order placed successfully!\n\n${JSON.stringify(result.data, null, 2)}` } ] }; } export async function handleCancelOrder(client: HyperliquidClient, args: any) { const { assetIndex, orderId, clientOrderId } = args; if (!orderId && !clientOrderId) { throw new Error('Either orderId or clientOrderId must be provided'); } const cancel: any = { a: assetIndex }; if (orderId) { cancel.o = orderId; } else { cancel.c = clientOrderId; } const action: CancelOrderAction = { type: 'cancel', cancels: [cancel] }; const result = await client.cancelOrder(action); if (!result.success) { throw new Error(`Failed to cancel order: ${result.error}`); } return { content: [ { type: 'text', text: `Order cancelled successfully!\n\n${JSON.stringify(result.data, null, 2)}` } ] }; } export async function handleCancelAllOrders(client: HyperliquidClient, args: any) { const result = await client.cancelAllOrders(); if (!result.success) { throw new Error(`Failed to cancel all orders: ${result.error}`); } return { content: [ { type: 'text', text: `All orders cancelled successfully!\n\n${JSON.stringify(result.data, null, 2)}` } ] }; }

Implementation Reference

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/t3rmed/hyperliquid-mcp'

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