hvip-mcp-server 0.1.8 → 0.2.0

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.
Files changed (2) hide show
  1. package/dist/index.js +353 -7
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -21157,11 +21157,13 @@ var publicApi = {
21157
21157
  getLongShortRatio: (ccy, begin, end) => request("GET", "/api/v5/rubik/stat/contracts/long-short-account-ratio", { params: { ccy, begin, end } }),
21158
21158
  getTakerVolume: (ccy, instType, begin, end) => request("GET", "/api/v5/rubik/stat/taker-volume", { params: { ccy, instType, begin, end } }),
21159
21159
  getOpenInterestVolume: (ccy, begin, end) => request("GET", "/api/v5/rubik/stat/contracts/open-interest-volume", { params: { ccy, begin, end } }),
21160
+ getOpenInterestHistory: (instId, period, limit) => request("GET", "/api/v5/rubik/stat/contracts/open-interest-history", { params: { instId, period, limit } }),
21160
21161
  getLendingRateHistory: (ccy) => request("GET", "/api/v5/rubik/stat/margin/loan-ratio", { params: { ccy } }),
21161
21162
  getHistoryCandles: (instId, bar, after, before, limit) => request("GET", "/api/v5/market/history-candles", { params: { instId, bar, after, before, limit } }),
21162
21163
  getHistoryTrades: (instId, limit) => request("GET", "/api/v5/market/history-trades", { params: { instId, limit } }),
21163
21164
  getSystemStatus: () => request("GET", "/api/v5/system/status"),
21164
21165
  getPriceLimitBatch: (instType, uly, instId) => request("GET", "/api/v5/public/price-limit", { params: { instType, uly, instId } }),
21166
+ getPositionTiers: (instType, tdMode, instFamily, uly) => request("GET", "/api/v5/public/position-tiers", { params: { instType, tdMode, instFamily, uly } }),
21165
21167
  getOptSummary: (uly, expTime) => request("GET", "/api/v5/public/opt-summary", { params: { uly, expTime } }),
21166
21168
  getInsuranceFund: (instType, uly) => request("GET", "/api/v5/public/insurance-fund", { params: { instType, uly } }),
21167
21169
  convertContractCoin: (instId, sz, unit, opType) => request("GET", "/api/v5/public/convert-contract-coin", { params: { instId, sz, unit, opType } }),
@@ -21202,6 +21204,13 @@ var privateApi = {
21202
21204
  getAccountBills: (auth, instType, ccy, limit) => request("GET", "/api/v5/account/bills", { params: { instType, ccy, limit }, auth }),
21203
21205
  getAccountConfig: (auth) => request("GET", "/api/v5/account/config", { auth }),
21204
21206
  getLeverageInfo: (auth, instId, mgnMode) => request("GET", "/api/v5/account/leverage-info", { params: { instId, mgnMode }, auth }),
21207
+ getMaxSize: (auth, instId, tdMode, ccy) => request("GET", "/api/v5/account/max-size", { params: { instId, tdMode, ccy }, auth }),
21208
+ getFeeRates: (auth, instType, instId, uly) => request("GET", "/api/v5/account/trade-fee", { params: { instType, instId, uly }, auth }),
21209
+ getPositionsHistory: (auth, instType, instId, limit) => request("GET", "/api/v5/account/positions-history", { params: { instType, instId, limit }, auth }),
21210
+ setLeverage: (auth, body) => request("POST", "/api/v5/account/set-leverage", { body, auth }),
21211
+ batchOrders: (auth, body) => request("POST", "/api/v5/trade/batch-orders", { body, auth }),
21212
+ cancelBatchOrders: (auth, body) => request("POST", "/api/v5/trade/cancel-batch-orders", { body, auth }),
21213
+ closePosition: (auth, body) => request("POST", "/api/v5/trade/close-position", { body, auth }),
21205
21214
  getOrdersPending: (auth, instType, instId, ordType) => request("GET", "/api/v5/trade/orders-pending", { params: { instType, instId, ordType }, auth }),
21206
21215
  getFills: (auth, instType, instId, limit) => request("GET", "/api/v5/trade/fills", { params: { instType, instId, limit }, auth }),
21207
21216
  getOrdersHistoryArchive: (auth, instType, limit) => request("GET", "/api/v5/trade/orders-history-archive", { params: { instType, limit }, auth }),
@@ -21327,9 +21336,34 @@ API Key \u5728 OKX \u5B98\u7F51\u300C\u4E2A\u4EBA\u4E2D\u5FC3 \u2192 API\u300D\u
21327
21336
  function toResult(data) {
21328
21337
  return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
21329
21338
  }
21330
- function toError(e, _source) {
21339
+ function classifyError(msg) {
21340
+ const okxMatch = msg.match(/OKX (\d+):/);
21341
+ if (okxMatch && okxMatch[1]) {
21342
+ const code = parseInt(okxMatch[1]);
21343
+ if (code >= 5e4 && code < 50100) return { errorCode: `OKX_${code}`, errorCategory: "AUTH" };
21344
+ if (code >= 51e3) return { errorCode: `OKX_${code}`, errorCategory: "BUSINESS" };
21345
+ if (code >= 50004 && code <= 50014) return { errorCode: `OKX_${code}`, errorCategory: "VALIDATION" };
21346
+ return { errorCode: `OKX_${code}`, errorCategory: "BUSINESS" };
21347
+ }
21348
+ if (msg.startsWith("HTTP ")) {
21349
+ const httpMatch = msg.match(/HTTP (\d+)/);
21350
+ const status = httpMatch && httpMatch[1] ? parseInt(httpMatch[1]) : 0;
21351
+ if (status === 401 || status === 403) return { errorCode: "HTTP_401", errorCategory: "AUTH" };
21352
+ if (status === 429) return { errorCode: "HTTP_429", errorCategory: "RATE_LIMIT" };
21353
+ return { errorCode: "NETWORK_ERROR", errorCategory: "NETWORK" };
21354
+ }
21355
+ if (msg.includes("API Key")) return { errorCode: "AUTH_REQUIRED", errorCategory: "AUTH" };
21356
+ return { errorCode: "UNKNOWN_ERROR", errorCategory: "BUSINESS" };
21357
+ }
21358
+ function toError(e) {
21331
21359
  const msg = e instanceof Error ? e.message : String(e);
21332
- return { content: [{ type: "text", text: msg }], isError: true };
21360
+ const { errorCode, errorCategory } = classifyError(msg);
21361
+ return {
21362
+ content: [{ type: "text", text: msg }],
21363
+ isError: true,
21364
+ errorCode,
21365
+ errorCategory
21366
+ };
21333
21367
  }
21334
21368
 
21335
21369
  // src/tools/market.ts
@@ -21354,7 +21388,9 @@ function registerMarketTools(server) {
21354
21388
  async ({ instType }) => {
21355
21389
  try {
21356
21390
  const data = await publicApi.getTickers(instType);
21357
- return toResult(data);
21391
+ const arr = data;
21392
+ const top = arr.length > 20 ? arr.slice(0, 20) : arr;
21393
+ return toResult({ total: arr.length, returned: top.length, data: top });
21358
21394
  } catch (e) {
21359
21395
  return toError(e);
21360
21396
  }
@@ -21387,7 +21423,17 @@ function registerMarketTools(server) {
21387
21423
  async ({ instId, bar, limit }) => {
21388
21424
  try {
21389
21425
  const data = await publicApi.getCandles(instId, bar, limit);
21390
- return toResult(data);
21426
+ const enriched = data.map((row) => ({
21427
+ ts: row[0],
21428
+ tsIso: row[0] ? new Date(parseInt(row[0])).toISOString() : void 0,
21429
+ open: row[1],
21430
+ high: row[2],
21431
+ low: row[3],
21432
+ close: row[4],
21433
+ vol: row[5],
21434
+ volCcy: row[6]
21435
+ }));
21436
+ return toResult(enriched);
21391
21437
  } catch (e) {
21392
21438
  return toError(e);
21393
21439
  }
@@ -21422,7 +21468,17 @@ function registerMarketTools(server) {
21422
21468
  async ({ instId, bar, after, before, limit }) => {
21423
21469
  try {
21424
21470
  const data = await publicApi.getHistoryCandles(instId, bar, after, before, limit);
21425
- return toResult(data);
21471
+ const enriched = data.map((row) => ({
21472
+ ts: row[0],
21473
+ tsIso: row[0] ? new Date(parseInt(row[0])).toISOString() : void 0,
21474
+ open: row[1],
21475
+ high: row[2],
21476
+ low: row[3],
21477
+ close: row[4],
21478
+ vol: row[5],
21479
+ volCcy: row[6]
21480
+ }));
21481
+ return toResult(enriched);
21426
21482
  } catch (e) {
21427
21483
  return toError(e);
21428
21484
  }
@@ -21466,7 +21522,9 @@ function registerMarketTools(server) {
21466
21522
  async ({ instType }) => {
21467
21523
  try {
21468
21524
  const data = await publicApi.getBlockTickers(instType);
21469
- return toResult(data);
21525
+ const arr = data;
21526
+ const top = arr.length > 20 ? arr.slice(0, 20) : arr;
21527
+ return toResult({ total: arr.length, returned: top.length, data: top });
21470
21528
  } catch (e) {
21471
21529
  return toError(e);
21472
21530
  }
@@ -21642,6 +21700,96 @@ function registerPublicTools(server) {
21642
21700
  }
21643
21701
  }
21644
21702
  );
21703
+ server.tool(
21704
+ "okx_get_price_limit",
21705
+ `## \u529F\u80FD\uFF1A\u67E5\u8BE2\u4EA7\u54C1\u7684\u9650\u4EF7\u4E0A\u4E0B\u9650\uFF08\u6DA8\u8DCC\u505C\u4EF7\u683C\uFF09
21706
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u5224\u65AD\u67D0\u4EA7\u54C1\u5F53\u524D\u662F\u5426\u63A5\u8FD1\u9650\u4EF7\u3001\u8BA1\u7B97\u53EF\u7528\u4E0B\u5355\u4EF7\u683C\u533A\u95F4\u3001\u6781\u7AEF\u884C\u60C5\u4E0B\u9650\u4EF7\u9884\u8B66
21707
+ ## \u5173\u952E\u8BCD\uFF1A\u9650\u4EF7, \u6DA8\u8DCC\u505C, price limit, \u4E0A\u4E0B\u9650, \u4EF7\u683C\u4FDD\u62A4, \u9650\u4EF7\u5355\u8303\u56F4
21708
+ ## \u53C2\u6570\uFF1A
21709
+ ## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B\uFF0C\u4E0D\u652F\u6301\u5168\u91CF\u67E5\u8BE2
21710
+ ## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key
21711
+ ## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528
21712
+ ## \u8FD4\u56DE\u91CF\uFF1A\u5355\u4EA7\u54C1 ~200B \u2014 \u5FAE\u5C0F
21713
+ ## \u5173\u8054\uFF1A\u5148\u8C03 okx_get_instruments \u83B7\u53D6\u53EF\u4EA4\u6613\u4EA7\u54C1\u5217\u8868 \u2192 \u672C\u5DE5\u5177\u67E5\u9650\u4EF7\u8303\u56F4 \u2192 \u7ED3\u5408 okx_get_ticker \u5224\u65AD\u5F53\u524D\u4EF7\u662F\u5426\u63A5\u8FD1\u9650\u4EF7`,
21714
+ {
21715
+ instId: external_exports.string().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B\uFF0C\u4E0D\u652F\u6301\u5168\u91CF\u67E5\u8BE2")
21716
+ },
21717
+ async ({ instId }) => {
21718
+ try {
21719
+ const data = await publicApi.getPriceLimitBatch("", void 0, instId);
21720
+ const enriched = data.map((item) => ({
21721
+ ...item,
21722
+ tsIso: item.ts ? new Date(parseInt(item.ts)).toISOString() : void 0
21723
+ }));
21724
+ return toResult(enriched);
21725
+ } catch (e) {
21726
+ return toError(e);
21727
+ }
21728
+ }
21729
+ );
21730
+ server.tool(
21731
+ "okx_get_position_tiers",
21732
+ `## \u529F\u80FD\uFF1A\u67E5\u8BE2\u6301\u4ED3\u6863\u4F4D\u8868\uFF08\u51B3\u5B9A\u6760\u6746\u4E0A\u9650\u548C\u4FDD\u8BC1\u91D1\u7387\uFF09
21733
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u5224\u65AD\u4E0D\u540C\u6301\u4ED3\u91CF\u5BF9\u5E94\u7684\u6700\u5927\u6760\u6746\u3001\u8BA1\u7B97\u4FDD\u8BC1\u91D1\u9700\u6C42\u3001\u8BC4\u4F30\u5927\u4ED3\u4F4D\u7206\u4ED3\u98CE\u9669\u3001\u8BBE\u7F6E\u6760\u6746\u524D\u786E\u8BA4\u6863\u4F4D\u9650\u5236
21734
+ ## \u5173\u952E\u8BCD\uFF1A\u4ED3\u4F4D\u6863\u4F4D, \u6760\u6746\u9650\u5236, position tiers, \u4FDD\u8BC1\u91D1\u7387, \u6301\u4ED3\u4E0A\u9650, \u6863\u4F4D\u8868, \u6760\u6746\u500D\u6570
21735
+ ## \u53C2\u6570\uFF1A
21736
+ ## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002SWAP=\u6C38\u7EED\u5408\u7EA6, FUTURES=\u4EA4\u5272\u5408\u7EA6\u3002\u5FC5\u586B
21737
+ ## - tdMode: \u4FDD\u8BC1\u91D1\u6A21\u5F0F\u3002cross=\u5168\u4ED3, isolated=\u9010\u4ED3\u3002\u5FC5\u586B
21738
+ ## - instFamily: \u4EA7\u54C1\u65CF\uFF0C\u5982 BTC-USDT\u3002\u4E0E uly \u4E8C\u9009\u4E00\u5FC5\u586B
21739
+ ## - uly: \u6807\u7684\u6307\u6570\uFF0C\u5982 BTC-USDT\u3002\u4E0E instFamily \u4E8C\u9009\u4E00\u5FC5\u586B
21740
+ ## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key
21741
+ ## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528
21742
+ ## \u8FD4\u56DE\u91CF\uFF1A\u5927\u578B ~30KB \u2014 \u5355\u4E2A\u4EA7\u54C1\u65CF\u542B\u6570\u5341\u4E2A\u6863\u4F4D\uFF0C\u6570\u636E\u91CF\u5927
21743
+ ## \u5173\u8054\uFF1A\u5148\u8C03 okx_get_instruments \u83B7\u53D6 instFamily \u2192 \u672C\u5DE5\u5177\u67E5\u6863\u4F4D \u2192 okx_get_leverage_info \u8BBE\u7F6E\u6760\u6746`,
21744
+ {
21745
+ instType: external_exports.enum(["SWAP", "FUTURES"]).describe("\u4EA7\u54C1\u7C7B\u578B\u3002SWAP=\u6C38\u7EED\u5408\u7EA6, FUTURES=\u4EA4\u5272\u5408\u7EA6"),
21746
+ tdMode: external_exports.enum(["cross", "isolated"]).describe("\u4FDD\u8BC1\u91D1\u6A21\u5F0F\u3002cross=\u5168\u4ED3, isolated=\u9010\u4ED3"),
21747
+ instFamily: external_exports.string().optional().describe("\u4EA7\u54C1\u65CF\uFF0C\u5982 BTC-USDT\u3002\u4E0E uly \u4E8C\u9009\u4E00\u5FC5\u586B"),
21748
+ uly: external_exports.string().optional().describe("\u6807\u7684\u6307\u6570\uFF0C\u5982 BTC-USDT\u3002\u4E0E instFamily \u4E8C\u9009\u4E00\u5FC5\u586B")
21749
+ },
21750
+ async ({ instType, tdMode, instFamily, uly }) => {
21751
+ try {
21752
+ const data = await publicApi.getPositionTiers(instType, tdMode, instFamily, uly);
21753
+ return toResult(data);
21754
+ } catch (e) {
21755
+ return toError(e);
21756
+ }
21757
+ }
21758
+ );
21759
+ server.tool(
21760
+ "okx_get_open_interest_history",
21761
+ `## \u529F\u80FD\uFF1A\u83B7\u53D6\u5408\u7EA6\u6301\u4ED3\u91CF\u5386\u53F2\u8D70\u52BF\u6570\u636E
21762
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u5206\u6790\u6301\u4ED3\u91CF\u8D8B\u52BF\uFF08\u589E\u4ED3/\u51CF\u4ED3\u65B9\u5411\uFF09\u3001\u5224\u65AD\u8D44\u91D1\u6D41\u5165\u6D41\u51FA\u3001\u7ED3\u5408\u4EF7\u683C\u8D70\u52BF\u5224\u65AD\u8D8B\u52BF\u5F3A\u5EA6
21763
+ ## \u5173\u952E\u8BCD\uFF1A\u6301\u4ED3\u91CF\u5386\u53F2, \u6301\u4ED3\u8D70\u52BF, open interest history, OI\u53D8\u52A8, \u6301\u4ED3\u8D8B\u52BF, \u8D44\u91D1\u6D41\u5165
21764
+ ## \u53C2\u6570\uFF1A
21765
+ ## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B
21766
+ ## - period: \u65F6\u95F4\u7C92\u5EA6\u30025m/15m/30m/1H/2H/4H/6H/12H/1D/1W\u3002\u9ED8\u8BA45m
21767
+ ## - limit: \u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA4100\uFF0C\u6700\u592714400
21768
+ ## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key
21769
+ ## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528
21770
+ ## \u8FD4\u56DE\u91CF\uFF1A\u5355\u4EA7\u54C1 ~5KB \u2014 \u5FAE\u5C0F
21771
+ ## \u5173\u8054\uFF1A\u5148\u8C03 okx_get_instruments(instType=SWAP) \u83B7\u53D6\u5408\u7EA6\u4EA7\u54C1 \u2192 \u672C\u5DE5\u5177\u67E5\u6301\u4ED3\u8D8B\u52BF \u2192 \u7ED3\u5408 okx_get_ticker \u5224\u65AD\u91CF\u4EF7\u5173\u7CFB`,
21772
+ {
21773
+ instId: external_exports.string().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B"),
21774
+ period: external_exports.enum(["5m", "15m", "30m", "1H", "2H", "4H", "6H", "12H", "1D", "1W"]).optional().describe("\u65F6\u95F4\u7C92\u5EA6\uFF0C\u9ED8\u8BA45m"),
21775
+ limit: external_exports.string().optional().describe("\u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA4100\uFF0C\u6700\u592714400")
21776
+ },
21777
+ async ({ instId, period, limit }) => {
21778
+ try {
21779
+ const data = await publicApi.getOpenInterestHistory(instId, period, limit);
21780
+ const enriched = data.map((row) => ({
21781
+ ts: row[0],
21782
+ tsIso: row[0] ? new Date(parseInt(row[0])).toISOString() : void 0,
21783
+ oi: row[1],
21784
+ oiCcy: row[2],
21785
+ vol: row[3]
21786
+ }));
21787
+ return toResult(enriched);
21788
+ } catch (e) {
21789
+ return toError(e);
21790
+ }
21791
+ }
21792
+ );
21645
21793
  }
21646
21794
 
21647
21795
  // src/tools/account.ts
@@ -21757,6 +21905,120 @@ function registerAccountTools(server, auth) {
21757
21905
  }
21758
21906
  }
21759
21907
  );
21908
+ server.tool(
21909
+ "okx_get_max_size",
21910
+ `## \u529F\u80FD\uFF1A\u67E5\u8BE2\u67D0\u4EA7\u54C1\u6700\u5927\u53EF\u5F00\u4ED3\u6570\u91CF
21911
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u4E0B\u5355\u524D\u5224\u65AD\u6700\u5927\u53EF\u4E70\u5356\u6570\u91CF\u3001\u9A8C\u8BC1\u7528\u6237\u8F93\u5165\u7684\u6570\u91CF\u662F\u5426\u8D85\u9650
21912
+ ## \u5173\u952E\u8BCD\uFF1A\u6700\u5927\u53EF\u5F00, \u6700\u5927\u4E0B\u5355\u91CF, max size, \u53EF\u5F00\u6570\u91CF, \u4E0B\u5355\u4E0A\u9650
21913
+ ## \u53C2\u6570\uFF1A
21914
+ ## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B
21915
+ ## - tdMode: \u4FDD\u8BC1\u91D1\u6A21\u5F0F\u3002cross=\u5168\u4ED3, isolated=\u9010\u4ED3, cash=\u975E\u4FDD\u8BC1\u91D1\u3002\u5FC5\u586B
21916
+ ## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09
21917
+ ## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528
21918
+ ## \u8FD4\u56DE\u91CF\uFF1A\u5355\u4EA7\u54C1 ~200B \u2014 \u5FAE\u5C0F
21919
+ ## \u5173\u8054\uFF1A\u5148\u8C03 okx_get_instruments \u83B7\u53D6\u4EA7\u54C1 \u2192 \u672C\u5DE5\u5177\u67E5\u6700\u5927\u53EF\u5F00 \u2192 okx_place_order \u4E0B\u5355`,
21920
+ {
21921
+ instId: external_exports.string().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B"),
21922
+ tdMode: external_exports.enum(["cross", "isolated", "cash"]).describe("\u4FDD\u8BC1\u91D1\u6A21\u5F0F\u3002cross=\u5168\u4ED3, isolated=\u9010\u4ED3, cash=\u975E\u4FDD\u8BC1\u91D1"),
21923
+ ccy: external_exports.string().optional().describe("\u5E01\u79CD\uFF08\u4EC5MARGIN\u5168\u4ED3\u65F6\u9700\u8981\uFF09\uFF0C\u5982 USDT")
21924
+ },
21925
+ async ({ instId, tdMode, ccy }) => {
21926
+ if (!auth) return toError(AUTH_REQUIRED);
21927
+ try {
21928
+ const data = await privateApi.getMaxSize(auth, instId, tdMode, ccy);
21929
+ return toResult(data);
21930
+ } catch (e) {
21931
+ return toError(e);
21932
+ }
21933
+ }
21934
+ );
21935
+ server.tool(
21936
+ "okx_get_fee_rates",
21937
+ `## \u529F\u80FD\uFF1A\u67E5\u8BE2\u8D26\u6237\u5F53\u524D\u624B\u7EED\u8D39\u7387
21938
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u8BA1\u7B97\u4EA4\u6613\u6210\u672C\u3001\u6BD4\u8F83\u4E0D\u540C\u7B49\u7EA7\u8D39\u7387\u5DEE\u5F02\u3001\u4E0B\u5355\u524D\u4F30\u7B97\u624B\u7EED\u8D39
21939
+ ## \u5173\u952E\u8BCD\uFF1A\u624B\u7EED\u8D39, \u8D39\u7387, fee rate, \u4EA4\u6613\u8D39, maker, taker
21940
+ ## \u53C2\u6570\uFF1A
21941
+ ## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, SWAP=\u6C38\u7EED\u5408\u7EA6\u3002\u4E0D\u586B\u8FD4\u56DE\u5168\u90E8
21942
+ ## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT\u3002\u53EF\u9009
21943
+ ## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09
21944
+ ## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528
21945
+ ## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~1KB
21946
+ ## \u5173\u8054\uFF1Aokx_get_account_config \u67E5\u8D26\u6237\u914D\u7F6E \u2192 \u672C\u5DE5\u5177\u67E5\u8D39\u7387 \u2192 okx_place_order \u4E0B\u5355\u8BA1\u7B97\u6210\u672C`,
21947
+ {
21948
+ instType: external_exports.enum(["SPOT", "MARGIN", "SWAP", "FUTURES", "OPTION"]).optional().describe("\u4EA7\u54C1\u7C7B\u578B\uFF0C\u4E0D\u586B\u8FD4\u56DE\u5168\u90E8"),
21949
+ instId: external_exports.string().optional().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT"),
21950
+ uly: external_exports.string().optional().describe("\u6807\u7684\u6307\u6570\uFF0C\u5982 BTC-USDT")
21951
+ },
21952
+ async ({ instType, instId, uly }) => {
21953
+ if (!auth) return toError(AUTH_REQUIRED);
21954
+ try {
21955
+ const data = await privateApi.getFeeRates(auth, instType, instId, uly);
21956
+ return toResult(data);
21957
+ } catch (e) {
21958
+ return toError(e);
21959
+ }
21960
+ }
21961
+ );
21962
+ server.tool(
21963
+ "okx_get_positions_history",
21964
+ `## \u529F\u80FD\uFF1A\u67E5\u8BE2\u5386\u53F2\u6301\u4ED3\u8BB0\u5F55\uFF08\u5DF2\u5E73\u4ED3\u4ED3\u4F4D\uFF09
21965
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u590D\u76D8\u5386\u53F2\u4EA4\u6613\u3001\u5206\u6790\u5E73\u4ED3\u76C8\u4E8F\u3001\u7EDF\u8BA1\u80DC\u7387\u3001\u5BA1\u8BA1\u4EA4\u6613\u8BB0\u5F55
21966
+ ## \u5173\u952E\u8BCD\uFF1A\u5386\u53F2\u6301\u4ED3, \u5E73\u4ED3\u8BB0\u5F55, positions history, \u5DF2\u5E73\u4ED3, \u5E73\u4ED3\u76C8\u4E8F, \u4EA4\u6613\u590D\u76D8
21967
+ ## \u53C2\u6570\uFF1A
21968
+ ## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002\u53EF\u9009\uFF0C\u4E0D\u586B\u8FD4\u56DE\u5168\u90E8
21969
+ ## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u53EF\u9009
21970
+ ## - limit: \u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA4100
21971
+ ## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09
21972
+ ## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528
21973
+ ## \u8FD4\u56DE\u91CF\uFF1A\u4E2D\u7B49 ~10KB
21974
+ ## \u5173\u8054\uFF1Aokx_get_positions \u67E5\u5F53\u524D\u6301\u4ED3 \u2192 \u672C\u5DE5\u5177\u67E5\u5386\u53F2\u5E73\u4ED3 \u2192 okx_get_order_history \u6838\u5BF9\u8BA2\u5355`,
21975
+ {
21976
+ instType: external_exports.enum(["MARGIN", "SWAP", "FUTURES", "OPTION"]).optional().describe("\u4EA7\u54C1\u7C7B\u578B\uFF0C\u4E0D\u586B\u8FD4\u56DE\u5168\u90E8"),
21977
+ instId: external_exports.string().optional().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP"),
21978
+ limit: external_exports.number().optional().describe("\u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA4100")
21979
+ },
21980
+ async ({ instType, instId, limit }) => {
21981
+ if (!auth) return toError(AUTH_REQUIRED);
21982
+ try {
21983
+ const data = await privateApi.getPositionsHistory(auth, instType, instId, limit);
21984
+ return toResult(data);
21985
+ } catch (e) {
21986
+ return toError(e);
21987
+ }
21988
+ }
21989
+ );
21990
+ server.tool(
21991
+ "okx_set_leverage",
21992
+ `## \u529F\u80FD\uFF1A\u8BBE\u7F6E\u67D0\u4EA7\u54C1\u7684\u6760\u6746\u500D\u6570
21993
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u8C03\u6574\u6760\u6746\uFF08\u4E0D\u540C\u6301\u4ED3\u91CF\u6863\u4F4D\u5BF9\u5E94\u4E0D\u540C\u6700\u5927\u6760\u6746\uFF09\u3001\u5728\u884C\u60C5\u6CE2\u52A8\u5927\u65F6\u964D\u4F4E\u6760\u6746\u63A7\u5236\u98CE\u9669
21994
+ ## \u5173\u952E\u8BCD\uFF1A\u8BBE\u7F6E\u6760\u6746, \u8C03\u6574\u6760\u6746, set leverage, \u6760\u6746\u500D\u6570, \u5168\u4ED3\u9010\u4ED3
21995
+ ## \u53C2\u6570\uFF1A
21996
+ ## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B
21997
+ ## - lever: \u6760\u6746\u500D\u6570\uFF0C\u5982 10\u3002\u5FC5\u586B\uFF08\u9700\u5728 okx_get_position_tiers \u8FD4\u56DE\u7684\u8303\u56F4\u5185\uFF09
21998
+ ## - mgnMode: \u4FDD\u8BC1\u91D1\u6A21\u5F0F\u3002cross=\u5168\u4ED3, isolated=\u9010\u4ED3\u3002\u5FC5\u586B
21999
+ ## - posSide: \u6301\u4ED3\u65B9\u5411\u3002\u4E0D\u586B\u5219\u53CC\u5411\u751F\u6548
22000
+ ## \u9274\u6743\uFF1A\u{1F534} \u9700\u8981 API Key\uFF08\u4EA4\u6613\uFF09- \u8C03\u7528\u524D\u987B\u5411\u7528\u6237\u786E\u8BA4
22001
+ ## \u98CE\u9669\uFF1AADMIN \u2014 \u4FEE\u6539\u8D26\u6237\u914D\u7F6E\uFF0C\u987B\u5411\u7528\u6237\u89E3\u91CA\u6760\u6746\u500D\u6570\u548C\u7206\u4ED3\u98CE\u9669\u540E\u518D\u786E\u8BA4
22002
+ ## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~200B
22003
+ ## \u5173\u8054\uFF1A\u5148\u8C03 okx_get_position_tiers \u786E\u8BA4\u6760\u6746\u4E0A\u9650 \u2192 \u672C\u5DE5\u5177\u8BBE\u7F6E\u6760\u6746 \u2192 okx_place_order \u4E0B\u5355`,
22004
+ {
22005
+ instId: external_exports.string().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B"),
22006
+ lever: external_exports.string().describe("\u6760\u6746\u500D\u6570\uFF0C\u5982 10\u3002\u5FC5\u987B\u5728\u4ED3\u4F4D\u6863\u4F4D\u5141\u8BB8\u8303\u56F4\u5185"),
22007
+ mgnMode: external_exports.enum(["cross", "isolated"]).describe("\u4FDD\u8BC1\u91D1\u6A21\u5F0F\u3002cross=\u5168\u4ED3, isolated=\u9010\u4ED3"),
22008
+ posSide: external_exports.enum(["long", "short"]).optional().describe("\u6301\u4ED3\u65B9\u5411\u3002\u4E0D\u586B\u5219\u53CC\u5411\u751F\u6548")
22009
+ },
22010
+ async ({ instId, lever, mgnMode, posSide }) => {
22011
+ if (!auth) return toError(AUTH_REQUIRED);
22012
+ try {
22013
+ const body = { instId, lever, mgnMode };
22014
+ if (posSide) body.posSide = posSide;
22015
+ const data = await privateApi.setLeverage(auth, body);
22016
+ return toResult(data);
22017
+ } catch (e) {
22018
+ return toError(e);
22019
+ }
22020
+ }
22021
+ );
21760
22022
  }
21761
22023
 
21762
22024
  // src/tools/trading.ts
@@ -21876,6 +22138,90 @@ function registerTradingTools(server, auth) {
21876
22138
  }
21877
22139
  }
21878
22140
  );
22141
+ server.tool(
22142
+ "okx_batch_orders",
22143
+ `## \u529F\u80FD\uFF1A\u6279\u91CF\u4E0B\u5355\uFF08\u6700\u591A20\u7B14\uFF09
22144
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u9700\u8981\u540C\u65F6\u4E0B\u591A\u4E2A\u8BA2\u5355\u7684\u7B56\u7565\uFF08\u5982\u4E00\u7BEE\u5B50\u5EFA\u4ED3\u3001\u591A\u4EA7\u54C1\u5957\u5229\u5E03\u5C40\uFF09
22145
+ ## \u5173\u952E\u8BCD\uFF1A\u6279\u91CF\u4E0B\u5355, \u6279\u91CF\u59D4\u6258, batch orders, \u4E00\u7BEE\u5B50\u8BA2\u5355, \u7EC4\u5408\u4E0B\u5355
22146
+ ## \u53C2\u6570\uFF1A
22147
+ ## - orders: \u8BA2\u5355\u6570\u7EC4\uFF08JSON\u6570\u7EC4\u5B57\u7B26\u4E32\uFF09\uFF0C\u6BCF\u9879\u542B instId/tdMode/side/ordType/sz/px \u7B49\u5B57\u6BB5\u3002\u6700\u591A20\u7B14
22148
+ ## \u9274\u6743\uFF1A\u{1F534} \u9700\u8981 API Key\uFF08\u4EA4\u6613\uFF09- \u8C03\u7528\u524D\u987B\u5411\u7528\u6237\u786E\u8BA4\u6BCF\u7B14\u8BA2\u5355\u5185\u5BB9
22149
+ ## \u98CE\u9669\uFF1AWRITE \u2014 \u521B\u5EFA\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u9010\u7B14\u786E\u8BA4
22150
+ ## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~2KB
22151
+ ## \u5173\u8054\uFF1Aokx_get_instruments \u83B7\u53D6\u4EA7\u54C1\u5217\u8868 \u2192 \u672C\u5DE5\u5177\u6279\u91CF\u4E0B\u5355 \u2192 okx_batch_cancel_orders \u64A4\u9500`,
22152
+ {
22153
+ orders: external_exports.string().describe(`\u8BA2\u5355\u6570\u7EC4JSON\u5B57\u7B26\u4E32\uFF0C\u5982 '[{"instId":"BTC-USDT","tdMode":"cash","side":"buy","ordType":"limit","sz":"0.001","px":"60000"}]'\u3002\u6700\u591A20\u7B14`)
22154
+ },
22155
+ async ({ orders }) => {
22156
+ if (!auth) return toError(AUTH_REQUIRED);
22157
+ try {
22158
+ const parsed = JSON.parse(orders);
22159
+ const data = await privateApi.batchOrders(auth, parsed);
22160
+ return toResult(data);
22161
+ } catch (e) {
22162
+ return toError(e);
22163
+ }
22164
+ }
22165
+ );
22166
+ server.tool(
22167
+ "okx_batch_cancel_orders",
22168
+ `## \u529F\u80FD\uFF1A\u6279\u91CF\u64A4\u9500\u8BA2\u5355
22169
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u4E00\u952E\u64A4\u9500\u6240\u6709\u672A\u6210\u4EA4\u6302\u5355\u3001\u6E05\u7A7A\u7279\u5B9A\u4EA7\u54C1\u7684\u8BA2\u5355\u961F\u5217
22170
+ ## \u5173\u952E\u8BCD\uFF1A\u6279\u91CF\u64A4\u5355, \u6279\u91CF\u64A4\u9500, batch cancel, \u4E00\u952E\u64A4\u5355, \u6E05\u7A7A\u6302\u5355
22171
+ ## \u53C2\u6570\uFF1A
22172
+ ## - orders: \u64A4\u5355\u6570\u7EC4\uFF08JSON\u6570\u7EC4\u5B57\u7B26\u4E32\uFF09\uFF0C\u6BCF\u9879\u542B instId/ordId\u3002\u4E0D\u586BinstId\u5219\u64A4\u9500\u8BE5\u4EA7\u54C1\u6240\u6709\u6302\u5355
22173
+ ## \u9274\u6743\uFF1A\u{1F534} \u9700\u8981 API Key\uFF08\u4EA4\u6613\uFF09- \u8C03\u7528\u524D\u987B\u5411\u7528\u6237\u786E\u8BA4
22174
+ ## \u98CE\u9669\uFF1AWRITE \u2014 \u64A4\u9500\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u786E\u8BA4
22175
+ ## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~2KB
22176
+ ## \u5173\u8054\uFF1Aokx_get_orders_pending \u67E5\u770B\u6302\u5355 \u2192 \u672C\u5DE5\u5177\u6279\u91CF\u64A4\u9500 \u2192 okx_get_orders_history \u786E\u8BA4\u64A4\u9500`,
22177
+ {
22178
+ orders: external_exports.string().describe(`\u64A4\u5355\u6570\u7EC4JSON\u5B57\u7B26\u4E32\uFF0C\u5982 '[{"instId":"BTC-USDT","ordId":"123456"}]'`)
22179
+ },
22180
+ async ({ orders }) => {
22181
+ if (!auth) return toError(AUTH_REQUIRED);
22182
+ try {
22183
+ const parsed = JSON.parse(orders);
22184
+ const data = await privateApi.cancelBatchOrders(auth, parsed);
22185
+ return toResult(data);
22186
+ } catch (e) {
22187
+ return toError(e);
22188
+ }
22189
+ }
22190
+ );
22191
+ server.tool(
22192
+ "okx_close_position",
22193
+ `## \u529F\u80FD\uFF1A\u5E02\u4EF7\u5168\u5E73\u67D0\u4ED3\u4F4D
22194
+ ## \u573A\u666F\uFF1A\u7528\u4E8E\u7D27\u6025\u5E73\u4ED3\u6B62\u635F/\u6B62\u76C8\u3001\u6E05\u7A7A\u67D0\u65B9\u5411\u5168\u90E8\u6301\u4ED3
22195
+ ## \u5173\u952E\u8BCD\uFF1A\u5E73\u4ED3, \u5E02\u4EF7\u5168\u5E73, close position, \u6B62\u635F\u5E73\u4ED3, \u6E05\u4ED3, \u7D27\u6025\u5E73\u4ED3
22196
+ ## \u53C2\u6570\uFF1A
22197
+ ## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B
22198
+ ## - posSide: \u6301\u4ED3\u65B9\u5411\u3002long=\u5E73\u591A\u5934, short=\u5E73\u7A7A\u5934\u3002\u4E0D\u586B\u5219\u6309mgnMode\u81EA\u52A8\u5224\u65AD
22199
+ ## - mgnMode: \u4FDD\u8BC1\u91D1\u6A21\u5F0F\u3002cross=\u5168\u4ED3, isolated=\u9010\u4ED3
22200
+ ## - ccy: \u4FDD\u8BC1\u91D1\u5E01\u79CD\uFF08\u5168\u4ED3\u65F6\u9009\u586B\uFF09
22201
+ ## \u9274\u6743\uFF1A\u{1F534} \u9700\u8981 API Key\uFF08\u4EA4\u6613\uFF09- \u98CE\u63A7\u6838\u5FC3\u5DE5\u5177\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u4E8C\u6B21\u786E\u8BA4
22202
+ ## \u98CE\u9669\uFF1AFUND_TRANSFER \u2014 \u5E73\u4ED3\u64CD\u4F5C\u76F4\u63A5\u5F71\u54CD\u6301\u4ED3\u548C\u8D44\u91D1\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u786E\u8BA4
22203
+ ## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~300B
22204
+ ## \u5173\u8054\uFF1Aokx_get_positions \u786E\u8BA4\u6301\u4ED3 \u2192 \u672C\u5DE5\u5177\u5E02\u4EF7\u5168\u5E73 \u2192 okx_get_orders_history \u786E\u8BA4\u6210\u4EA4`,
22205
+ {
22206
+ instId: external_exports.string().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B"),
22207
+ posSide: external_exports.enum(["long", "short"]).optional().describe("\u6301\u4ED3\u65B9\u5411\u3002long=\u5E73\u591A\u5934, short=\u5E73\u7A7A\u5934\u3002\u5168\u4ED3\u5FC5\u586B"),
22208
+ mgnMode: external_exports.enum(["cross", "isolated"]).optional().describe("\u4FDD\u8BC1\u91D1\u6A21\u5F0F"),
22209
+ ccy: external_exports.string().optional().describe("\u4FDD\u8BC1\u91D1\u5E01\u79CD\uFF08\u5168\u4ED3\u53EF\u9009\u586B\uFF09")
22210
+ },
22211
+ async ({ instId, posSide, mgnMode, ccy }) => {
22212
+ if (!auth) return toError(AUTH_REQUIRED);
22213
+ try {
22214
+ const body = { instId };
22215
+ if (posSide) body.posSide = posSide;
22216
+ if (mgnMode) body.mgnMode = mgnMode;
22217
+ if (ccy) body.ccy = ccy;
22218
+ const data = await privateApi.closePosition(auth, body);
22219
+ return toResult(data);
22220
+ } catch (e) {
22221
+ return toError(e);
22222
+ }
22223
+ }
22224
+ );
21879
22225
  }
21880
22226
 
21881
22227
  // src/tools/algo.ts
@@ -22879,7 +23225,7 @@ function registerSignalTools(server, auth) {
22879
23225
 
22880
23226
  // src/index.ts
22881
23227
  async function main() {
22882
- const server = new McpServer({ name: "hvip", version: "0.1.8" });
23228
+ const server = new McpServer({ name: "hvip", version: "0.2.0" });
22883
23229
  const auth = getAuth();
22884
23230
  registerMarketTools(server);
22885
23231
  registerPublicTools(server);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hvip-mcp-server",
3
- "version": "0.1.8",
3
+ "version": "0.2.0",
4
4
  "description": "OKX ecosystem MCP server — full API coverage for AI agents",
5
5
  "homepage": "https://hvip.one",
6
6
  "license": "MIT",