@michaleffffff/mcp-trading-server 2.4.1 → 2.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -23,6 +23,15 @@ export async function openPosition(client, address, args) {
23
23
  const chainId = getChainId();
24
24
  const dir = resolveDirection(args.direction);
25
25
  const executionFeeToken = normalizeAddress(args.executionFeeToken, "executionFeeToken");
26
+ // Fetch pool detail to get decimals
27
+ const poolResponse = await client.markets.getMarketDetail({ chainId, poolId: args.poolId });
28
+ const poolData = poolResponse?.data || (poolResponse?.marketId ? poolResponse : null);
29
+ if (!poolData) {
30
+ console.error(`[ERROR] poolResponse for ${args.poolId}:`, JSON.stringify(poolResponse, null, 2));
31
+ throw new Error(`Could not find pool metadata for ID: ${args.poolId}`);
32
+ }
33
+ const baseDecimals = poolData.baseDecimals || 18;
34
+ const quoteDecimals = poolData.quoteDecimals || 6;
26
35
  const orderParams = {
27
36
  chainId,
28
37
  address,
@@ -31,23 +40,23 @@ export async function openPosition(client, address, args) {
31
40
  orderType: args.orderType,
32
41
  triggerType: args.triggerType,
33
42
  direction: dir,
34
- collateralAmount: args.collateralAmount,
35
- size: args.size,
36
- price: args.price,
43
+ collateralAmount: ensureUnits(args.collateralAmount, quoteDecimals, "collateralAmount"),
44
+ size: ensureUnits(args.size, baseDecimals, "size"),
45
+ price: ensureUnits(args.price, 30, "price"),
37
46
  timeInForce: args.timeInForce,
38
47
  postOnly: args.postOnly,
39
- slippagePct: args.slippagePct,
48
+ slippagePct: String(args.slippagePct),
40
49
  executionFeeToken,
41
50
  leverage: args.leverage,
42
51
  };
43
52
  if (args.tpSize)
44
- orderParams.tpSize = args.tpSize;
53
+ orderParams.tpSize = ensureUnits(args.tpSize, baseDecimals, "tpSize");
45
54
  if (args.tpPrice)
46
- orderParams.tpPrice = args.tpPrice;
55
+ orderParams.tpPrice = ensureUnits(args.tpPrice, 30, "tpPrice");
47
56
  if (args.slSize)
48
- orderParams.slSize = args.slSize;
57
+ orderParams.slSize = ensureUnits(args.slSize, baseDecimals, "slSize");
49
58
  if (args.slPrice)
50
- orderParams.slPrice = args.slPrice;
59
+ orderParams.slPrice = ensureUnits(args.slPrice, 30, "slPrice");
51
60
  return client.order.createIncreaseOrder(orderParams, args.tradingFee, args.marketId);
52
61
  }
53
62
  /**
@@ -60,6 +69,15 @@ export async function closePosition(client, address, args) {
60
69
  throw new Error("direction is required (0=LONG, 1=SHORT), must match position direction.");
61
70
  }
62
71
  const dir = resolveDirection(args.direction);
72
+ // Fetch pool detail to get decimals
73
+ const poolResponse = await client.markets.getMarketDetail({ chainId, poolId: args.poolId });
74
+ const poolData = poolResponse?.data || (poolResponse?.marketId ? poolResponse : null);
75
+ if (!poolData) {
76
+ console.error(`[ERROR] poolResponse for ${args.poolId}:`, JSON.stringify(poolResponse, null, 2));
77
+ throw new Error(`Could not find pool metadata for ID: ${args.poolId}`);
78
+ }
79
+ const baseDecimals = poolData.baseDecimals || 18;
80
+ const quoteDecimals = poolData.quoteDecimals || 6;
63
81
  return client.order.createDecreaseOrder({
64
82
  chainId,
65
83
  address,
@@ -68,12 +86,12 @@ export async function closePosition(client, address, args) {
68
86
  orderType: args.orderType,
69
87
  triggerType: args.triggerType,
70
88
  direction: dir,
71
- collateralAmount: args.collateralAmount,
72
- size: args.size,
73
- price: args.price,
89
+ collateralAmount: ensureUnits(args.collateralAmount, quoteDecimals, "collateralAmount"),
90
+ size: ensureUnits(args.size, baseDecimals, "size"),
91
+ price: ensureUnits(args.price, 30, "price"),
74
92
  timeInForce: args.timeInForce,
75
93
  postOnly: args.postOnly,
76
- slippagePct: args.slippagePct,
94
+ slippagePct: String(args.slippagePct),
77
95
  executionFeeToken,
78
96
  leverage: args.leverage,
79
97
  });
@@ -120,14 +138,18 @@ export async function adjustMargin(client, address, args) {
120
138
  if (!/^-?\d+$/.test(adjustAmount)) {
121
139
  throw new Error("adjustAmount must be an integer string in quote token raw units.");
122
140
  }
123
- return client.position.adjustCollateral({
141
+ const params = {
124
142
  poolId: args.poolId,
125
143
  positionId: args.positionId,
126
144
  adjustAmount,
127
145
  quoteToken,
128
146
  chainId,
129
147
  address,
130
- });
148
+ };
149
+ if (args.poolOracleType !== undefined) {
150
+ params.poolOracleType = Number(args.poolOracleType);
151
+ }
152
+ return client.position.adjustCollateral(params);
131
153
  }
132
154
  /**
133
155
  * 平掉所有仓位
@@ -9,6 +9,7 @@ export const adjustMarginTool = {
9
9
  positionId: z.string().describe("Position ID"),
10
10
  adjustAmount: z.string().regex(/^-?\d+$/).describe("Quote token raw units. Positive = add, negative = remove."),
11
11
  quoteToken: z.string().optional().describe("Quote token address"),
12
+ poolOracleType: z.number().optional().describe("Oracle type: 1 for Chainlink, 2 for Pyth"),
12
13
  },
13
14
  handler: async (args) => {
14
15
  try {
@@ -10,12 +10,12 @@ export const closePositionTool = {
10
10
  orderType: z.number().int().min(0).max(3).describe("OrderType enum value"),
11
11
  triggerType: z.number().int().min(0).max(2).describe("TriggerType enum value"),
12
12
  direction: z.union([z.literal(0), z.literal(1)]).describe("0 = LONG, 1 = SHORT"),
13
- collateralAmount: z.string().regex(/^\d+$/).describe("Collateral raw units"),
14
- size: z.string().regex(/^\d+$/).describe("Position size raw units"),
15
- price: z.string().regex(/^\d+$/).describe("Price raw units (30 decimals)"),
13
+ collateralAmount: z.union([z.string(), z.number()]).describe("Collateral amount (human-readable or raw units)"),
14
+ size: z.union([z.string(), z.number()]).describe("Position size (human-readable or raw units)"),
15
+ price: z.union([z.string(), z.number()]).describe("Price (human-readable or 30-dec raw units)"),
16
16
  timeInForce: z.number().int().describe("TimeInForce enum value"),
17
17
  postOnly: z.boolean().describe("Post-only flag"),
18
- slippagePct: z.string().regex(/^\d+$/).describe("Slippage with 4-dec precision raw units"),
18
+ slippagePct: z.union([z.string(), z.number()]).describe("Slippage in BPS (e.g. 100 = 1%)"),
19
19
  executionFeeToken: z.string().describe("Execution fee token address"),
20
20
  leverage: z.number().describe("Leverage"),
21
21
  },
@@ -10,18 +10,18 @@ export const executeTradeTool = {
10
10
  orderType: z.number().int().min(0).max(3).describe("OrderType enum value"),
11
11
  triggerType: z.number().int().min(0).max(2).describe("TriggerType enum value"),
12
12
  direction: z.union([z.literal(0), z.literal(1)]).describe("0 = LONG, 1 = SHORT"),
13
- collateralAmount: z.string().regex(/^\d+$/).describe("Quote token raw units"),
14
- size: z.string().regex(/^\d+$/).describe("Position size raw units"),
15
- price: z.string().regex(/^\d+$/).describe("Price raw units (30 decimals)"),
13
+ collateralAmount: z.union([z.string(), z.number()]).describe("Collateral amount (human-readable or raw units)"),
14
+ size: z.union([z.string(), z.number()]).describe("Position size (human-readable or raw units)"),
15
+ price: z.union([z.string(), z.number()]).describe("Price (human-readable or 30-dec raw units)"),
16
16
  timeInForce: z.number().int().describe("TimeInForce enum value"),
17
17
  postOnly: z.boolean().describe("Post-only flag"),
18
- slippagePct: z.string().regex(/^\d+$/).describe("Slippage with 4-dec precision raw units"),
18
+ slippagePct: z.union([z.string(), z.number()]).describe("Slippage in BPS (e.g. 100 = 1%)"),
19
19
  executionFeeToken: z.string().describe("Execution fee token address"),
20
20
  leverage: z.number().describe("Leverage"),
21
- tpSize: z.string().regex(/^\d+$/).optional().describe("TP size raw units"),
22
- tpPrice: z.string().regex(/^\d+$/).optional().describe("TP price raw units (30 decimals)"),
23
- slSize: z.string().regex(/^\d+$/).optional().describe("SL size raw units"),
24
- slPrice: z.string().regex(/^\d+$/).optional().describe("SL price raw units (30 decimals)"),
21
+ tpSize: z.union([z.string(), z.number()]).optional().describe("TP size (human-readable or raw units)"),
22
+ tpPrice: z.union([z.string(), z.number()]).optional().describe("TP price (human-readable or 30-dec raw units)"),
23
+ slSize: z.union([z.string(), z.number()]).optional().describe("SL size (human-readable or raw units)"),
24
+ slPrice: z.union([z.string(), z.number()]).optional().describe("SL price (human-readable or 30-dec raw units)"),
25
25
  tradingFee: z.string().regex(/^\d+$/).describe("Trading fee raw units"),
26
26
  marketId: z.string().describe("Market ID"),
27
27
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michaleffffff/mcp-trading-server",
3
- "version": "2.4.1",
3
+ "version": "2.4.2",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "myx-mcp": "dist/server.js"