@michaleffffff/mcp-trading-server 2.3.4 → 2.3.5

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.
package/README.md CHANGED
@@ -187,25 +187,32 @@ Add to `~/Library/Application Support/Claude/claude_desktop_config.json`:
187
187
 
188
188
  # Tools
189
189
 
190
- The server exposes 28 precise tools categorized for AI:
190
+ The server exposes 37 tools categorized for AI:
191
191
 
192
192
  ### Trading Operations
193
193
  * **execute_trade**: Execute a new trade or add to an existing position.
194
194
  * **close_position**: Close an open position.
195
195
  * **close_all_positions**: Emergency: close ALL open positions in a pool at once.
196
196
  * **cancel_order**: Cancel an open order by its order ID.
197
+ * **cancel_all_orders**: Cancel all open orders at once (or a provided order ID list).
197
198
  * **set_tp_sl**: Set take profit and stop loss prices for an open position.
198
199
  * **adjust_margin**: Adjust the margin (collateral) of an open position.
200
+ * **get_user_trading_fee_rate**: Query current maker/taker fee rates by asset class and risk tier.
201
+ * **get_network_fee**: Query estimated network fee requirements for a market.
199
202
 
200
203
  ### Market Data
201
204
  * **search_market**: Search for an active market (e.g., "BTC") to retrieve its unique `poolId` (Crucial prerequisite).
202
205
  * **get_market_price**: Get the current ticker market price for a specific pool.
203
206
  * **get_oracle_price**: Get the current EVM oracle price for a specific pool.
204
- * **get_market_list**, **get_kline**, **get_pool_info**...
207
+ * **get_kline_latest_bar**: Get only the latest bar for an interval.
208
+ * **get_all_tickers**: Get all ticker snapshots in one request.
209
+ * **get_market_list**, **get_market_list_raw**, **get_kline**, **get_pool_info**...
210
+ * **get_pool_symbol_all**, **get_base_detail**, **get_pool_level_config**...
205
211
 
206
212
  ### Account & Portfolio
207
213
  * **get_positions**: Get all open positions for the current account.
208
214
  * **get_balances**: Get the account balances for different tokens.
215
+ * **get_account_vip_info**: Query account VIP tier details.
209
216
  * **position_history**, **open_orders**...
210
217
 
211
218
  ### Liquidity Provision (LP)
@@ -269,7 +276,8 @@ npm run dev
269
276
  Run tests:
270
277
 
271
278
  ```bash
272
- npx tsx tests/test_bsc.ts
279
+ npm test
280
+ npm run test:new-tools
273
281
  ```
274
282
 
275
283
  ---
package/dist/server.js CHANGED
@@ -81,7 +81,7 @@ function zodSchemaToJsonSchema(zodSchema) {
81
81
  };
82
82
  }
83
83
  // ─── MCP Server ───
84
- const server = new Server({ name: "myx-mcp-trading-server", version: "2.3.4" }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
84
+ const server = new Server({ name: "myx-mcp-trading-server", version: "2.3.5" }, { capabilities: { tools: {}, resources: {}, prompts: {} } });
85
85
  // List tools
86
86
  server.setRequestHandler(ListToolsRequestSchema, async () => {
87
87
  return {
@@ -181,7 +181,7 @@ server.setRequestHandler(GetPromptRequestSchema, async (request) => {
181
181
  async function main() {
182
182
  const transport = new StdioServerTransport();
183
183
  await server.connect(transport);
184
- logger.info("🚀 MYX Trading MCP Server v2.3.1 running (stdio, pure on-chain, prod ready)");
184
+ logger.info("🚀 MYX Trading MCP Server v2.3.5 running (stdio, pure on-chain, prod ready)");
185
185
  }
186
186
  main().catch((err) => {
187
187
  logger.error("Fatal Server Startup Error", err);
@@ -0,0 +1,36 @@
1
+ import { z } from "zod";
2
+ import { resolveClient, getChainId } from "../auth/resolveClient.js";
3
+ export const cancelAllOrdersTool = {
4
+ name: "cancel_all_orders",
5
+ description: "Cancel all open orders, or cancel the provided orderIds in one call.",
6
+ schema: {
7
+ orderIds: z.array(z.string()).optional().describe("Optional explicit order IDs. If omitted, all open orders will be cancelled."),
8
+ },
9
+ handler: async (args) => {
10
+ try {
11
+ const { client, address } = await resolveClient();
12
+ const chainId = getChainId();
13
+ let orderIds = Array.isArray(args.orderIds) ? args.orderIds : [];
14
+ if (orderIds.length === 0) {
15
+ const openOrders = await client.order.getOrders(address);
16
+ const rows = Array.isArray(openOrders?.data) ? openOrders.data : [];
17
+ orderIds = rows
18
+ .map((o) => o.orderId ?? o.id ?? o.order_id)
19
+ .filter((id) => id !== undefined && id !== null)
20
+ .map((id) => String(id));
21
+ }
22
+ if (orderIds.length === 0) {
23
+ return {
24
+ content: [{ type: "text", text: JSON.stringify({ status: "success", data: { message: "No open orders to cancel.", cancelled: 0 } }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }],
25
+ };
26
+ }
27
+ const result = await client.order.cancelAllOrders(orderIds, chainId);
28
+ return {
29
+ content: [{ type: "text", text: JSON.stringify({ status: "success", data: { cancelled: orderIds.length, orderIds, result } }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }],
30
+ };
31
+ }
32
+ catch (error) {
33
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
34
+ }
35
+ },
36
+ };
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ import { resolveClient, getChainId } from "../auth/resolveClient.js";
3
+ export const getAccountVipInfoTool = {
4
+ name: "get_account_vip_info",
5
+ description: "Get account VIP/fee-tier information.",
6
+ schema: {
7
+ chainId: z.number().optional().describe("Optional chainId override"),
8
+ },
9
+ handler: async (args) => {
10
+ try {
11
+ const { client, address } = await resolveClient();
12
+ const chainId = args.chainId ?? getChainId();
13
+ const result = await client.account.getAccountVipInfo(chainId, address);
14
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", data: result }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }] };
15
+ }
16
+ catch (error) {
17
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
18
+ }
19
+ },
20
+ };
@@ -0,0 +1,35 @@
1
+ import { resolveClient, getChainId } from "../auth/resolveClient.js";
2
+ export const getAllTickersTool = {
3
+ name: "get_all_tickers",
4
+ description: "Get ticker snapshots for all markets.",
5
+ schema: {},
6
+ handler: async () => {
7
+ try {
8
+ const { client } = await resolveClient();
9
+ try {
10
+ const result = await client.api.getAllTickers();
11
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", data: result }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }] };
12
+ }
13
+ catch {
14
+ // Fallback for networks/environments where getAllTickers endpoint is unavailable.
15
+ const chainId = getChainId();
16
+ const poolList = await client.api.getPoolList();
17
+ const pools = Array.isArray(poolList?.data) ? poolList.data : [];
18
+ const poolIds = pools.map((p) => p.poolId).filter((id) => !!id);
19
+ if (poolIds.length === 0) {
20
+ throw new Error("Failed to fetch all tickers and no pools were available for fallback query.");
21
+ }
22
+ const tickerRows = await client.markets.getTickerList({ chainId, poolIds });
23
+ return {
24
+ content: [{
25
+ type: "text",
26
+ text: JSON.stringify({ status: "success", data: { source: "markets.getTickerList_fallback", rows: tickerRows } }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2),
27
+ }],
28
+ };
29
+ }
30
+ }
31
+ catch (error) {
32
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
33
+ }
34
+ },
35
+ };
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ import { resolveClient, getChainId } from "../auth/resolveClient.js";
3
+ export const getBaseDetailTool = {
4
+ name: "get_base_detail",
5
+ description: "Get base asset detail metrics for a pool.",
6
+ schema: {
7
+ poolId: z.string().describe("Pool ID"),
8
+ chainId: z.number().optional().describe("Optional chainId override"),
9
+ },
10
+ handler: async (args) => {
11
+ try {
12
+ const { client } = await resolveClient();
13
+ const chainId = args.chainId ?? getChainId();
14
+ const result = await client.markets.getBaseDetail({ chainId, poolId: args.poolId });
15
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", data: result }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }] };
16
+ }
17
+ catch (error) {
18
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
19
+ }
20
+ },
21
+ };
@@ -0,0 +1,27 @@
1
+ import { z } from "zod";
2
+ import { resolveClient, getChainId } from "../auth/resolveClient.js";
3
+ export const getKlineLatestBarTool = {
4
+ name: "get_kline_latest_bar",
5
+ description: "Get the latest single K-line/candlestick bar for a pool.",
6
+ schema: {
7
+ poolId: z.string().describe("Pool ID"),
8
+ interval: z.string().describe("K-line interval: '1m','5m','15m','30m','1h','4h','1d','1w','1M'"),
9
+ },
10
+ handler: async (args) => {
11
+ try {
12
+ const { client } = await resolveClient();
13
+ const chainId = getChainId();
14
+ const result = await client.markets.getKlineLatestBar({
15
+ poolId: args.poolId,
16
+ chainId,
17
+ interval: args.interval,
18
+ limit: 1,
19
+ endTime: Date.now(),
20
+ });
21
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", data: result }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }] };
22
+ }
23
+ catch (error) {
24
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
25
+ }
26
+ },
27
+ };
@@ -0,0 +1,16 @@
1
+ import { resolveClient } from "../auth/resolveClient.js";
2
+ export const getMarketListRawTool = {
3
+ name: "get_market_list_raw",
4
+ description: "Get raw market list directly from MYX API without MCP-side filtering.",
5
+ schema: {},
6
+ handler: async () => {
7
+ try {
8
+ const { client } = await resolveClient();
9
+ const result = await client.api.getMarketList();
10
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", data: result }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }] };
11
+ }
12
+ catch (error) {
13
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
14
+ }
15
+ },
16
+ };
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ import { resolveClient, getChainId } from "../auth/resolveClient.js";
3
+ export const getNetworkFeeTool = {
4
+ name: "get_network_fee",
5
+ description: "Estimate network fee requirements for a market.",
6
+ schema: {
7
+ marketId: z.string().describe("Market ID"),
8
+ chainId: z.number().optional().describe("Optional chainId override"),
9
+ },
10
+ handler: async (args) => {
11
+ try {
12
+ const { client } = await resolveClient();
13
+ const chainId = args.chainId ?? getChainId();
14
+ const result = await client.utils.getNetworkFee(args.marketId, chainId);
15
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", data: result }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }] };
16
+ }
17
+ catch (error) {
18
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
19
+ }
20
+ },
21
+ };
@@ -0,0 +1,16 @@
1
+ import { resolveClient } from "../auth/resolveClient.js";
2
+ export const getPoolSymbolAllTool = {
3
+ name: "get_pool_symbol_all",
4
+ description: "Get symbol/icon metadata for all pools.",
5
+ schema: {},
6
+ handler: async () => {
7
+ try {
8
+ const { client } = await resolveClient();
9
+ const result = await client.markets.getPoolSymbolAll();
10
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", data: result }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }] };
11
+ }
12
+ catch (error) {
13
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
14
+ }
15
+ },
16
+ };
@@ -0,0 +1,22 @@
1
+ import { z } from "zod";
2
+ import { resolveClient, getChainId } from "../auth/resolveClient.js";
3
+ export const getUserTradingFeeRateTool = {
4
+ name: "get_user_trading_fee_rate",
5
+ description: "Get maker/taker fee rates for a given assetClass and riskTier.",
6
+ schema: {
7
+ assetClass: z.number().describe("Asset class ID"),
8
+ riskTier: z.number().describe("Risk tier"),
9
+ chainId: z.number().optional().describe("Optional chainId override"),
10
+ },
11
+ handler: async (args) => {
12
+ try {
13
+ const { client } = await resolveClient();
14
+ const chainId = args.chainId ?? getChainId();
15
+ const result = await client.utils.getUserTradingFeeRate(args.assetClass, args.riskTier, chainId);
16
+ return { content: [{ type: "text", text: JSON.stringify({ status: "success", data: result }, (_, v) => typeof v === "bigint" ? v.toString() : v, 2) }] };
17
+ }
18
+ catch (error) {
19
+ return { content: [{ type: "text", text: `Error: ${error.message}` }], isError: true };
20
+ }
21
+ },
22
+ };
@@ -1,20 +1,27 @@
1
1
  // Tools — 交易
2
2
  export { executeTradeTool } from "./executeTrade.js";
3
3
  export { cancelOrderTool } from "./cancelOrder.js";
4
+ export { cancelAllOrdersTool } from "./cancelAllOrders.js";
4
5
  export { closePositionTool } from "./closePosition.js";
5
6
  export { setTpSlTool } from "./setTpSl.js";
6
7
  export { updateOrderTpSlTool } from "./updateOrderTpSl.js";
7
8
  export { adjustMarginTool } from "./adjustMargin.js";
8
9
  export { closeAllPositionsTool } from "./closeAllPositions.js";
9
10
  export { checkApprovalTool } from "./checkApproval.js";
11
+ export { getUserTradingFeeRateTool } from "./getUserTradingFeeRate.js";
12
+ export { getNetworkFeeTool } from "./getNetworkFee.js";
10
13
  // Tools — 市场数据
11
14
  export { getMarketPriceTool } from "./getMarketPrice.js";
12
15
  export { getOraclePriceTool } from "./getOraclePrice.js";
13
16
  export { searchMarketTool } from "./searchMarket.js";
14
17
  export { getKlineTool } from "./getKline.js";
18
+ export { getKlineLatestBarTool } from "./getKlineLatestBar.js";
19
+ export { getAllTickersTool } from "./getAllTickers.js";
15
20
  export { getMarketDetailTool, getPoolInfoTool, getLiquidityInfoTool } from "./marketInfo.js";
16
21
  export { getPoolListTool } from "./getPoolList.js";
22
+ export { getPoolSymbolAllTool } from "./getPoolSymbolAll.js";
17
23
  export { getPoolLevelConfigTool } from "./poolConfig.js";
24
+ export { getBaseDetailTool } from "./getBaseDetail.js";
18
25
  // Tools — 池子 & 流动性
19
26
  export { createPerpMarketTool } from "./createPerpMarket.js";
20
27
  export { manageLiquidityTool, getLpPriceTool } from "./manageLiquidity.js";
@@ -24,5 +31,7 @@ export { getBalancesTool } from "./getBalances.js";
24
31
  export { getOpenOrdersTool, getOrderHistoryTool } from "./orderQueries.js";
25
32
  export { getPositionHistoryTool } from "./positionHistory.js";
26
33
  export { getAccountInfoTool, getTradeFlowTool, getMarginBalanceTool } from "./accountInfo.js";
34
+ export { getAccountVipInfoTool } from "./getAccountVipInfo.js";
27
35
  export { accountDepositTool, accountWithdrawTool } from "./accountTransfer.js";
28
36
  export { getMarketListTool } from "./getMarketList.js";
37
+ export { getMarketListRawTool } from "./getMarketListRaw.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@michaleffffff/mcp-trading-server",
3
- "version": "2.3.4",
3
+ "version": "2.3.5",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "myx-mcp": "dist/server.js"
@@ -12,7 +12,8 @@
12
12
  "build": "rm -rf dist && tsc",
13
13
  "start": "node dist/server.js",
14
14
  "dev": "tsx src/server.ts",
15
- "test": "tsx tests/test_sepolia.ts"
15
+ "test": "tsx tests/test_sepolia.ts",
16
+ "test:new-tools": "tsx tests/test_new_tools_p0_p1.ts"
16
17
  },
17
18
  "dependencies": {
18
19
  "@modelcontextprotocol/sdk": "^1.27.1",