hvip-mcp-server 0.2.34 → 0.2.38

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 (3) hide show
  1. package/README.md +3 -3
  2. package/dist/index.js +304 -41
  3. package/package.json +41 -41
package/README.md CHANGED
@@ -1,3 +1,3 @@
1
- # OKX MCP Server
2
-
3
- OKX API 全景图 —— 让任何 AI Agent 都能使用 OKX 的全部能力。
1
+ # OKX MCP Server
2
+
3
+ OKX API 全景图 —— 让任何 AI Agent 都能使用 OKX 的全部能力。
package/dist/index.js CHANGED
@@ -3226,8 +3226,8 @@ var require_utils = __commonJS({
3226
3226
  }
3227
3227
  return ind;
3228
3228
  }
3229
- function removeDotSegments(path) {
3230
- let input = path;
3229
+ function removeDotSegments(path2) {
3230
+ let input = path2;
3231
3231
  const output = [];
3232
3232
  let nextSlash = -1;
3233
3233
  let len = 0;
@@ -3479,8 +3479,8 @@ var require_schemes = __commonJS({
3479
3479
  wsComponent.secure = void 0;
3480
3480
  }
3481
3481
  if (wsComponent.resourceName) {
3482
- const [path, query] = wsComponent.resourceName.split("?");
3483
- wsComponent.path = path && path !== "/" ? path : void 0;
3482
+ const [path2, query] = wsComponent.resourceName.split("?");
3483
+ wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
3484
3484
  wsComponent.query = query;
3485
3485
  wsComponent.resourceName = void 0;
3486
3486
  }
@@ -6873,12 +6873,12 @@ var require_dist = __commonJS({
6873
6873
  throw new Error(`Unknown format "${name}"`);
6874
6874
  return f;
6875
6875
  };
6876
- function addFormats(ajv, list, fs, exportName) {
6876
+ function addFormats(ajv, list, fs2, exportName) {
6877
6877
  var _a;
6878
6878
  var _b;
6879
6879
  (_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6880
6880
  for (const f of list)
6881
- ajv.addFormat(f, fs[f]);
6881
+ ajv.addFormat(f, fs2[f]);
6882
6882
  }
6883
6883
  module2.exports = exports2 = formatsPlugin;
6884
6884
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -7364,8 +7364,8 @@ function getErrorMap() {
7364
7364
 
7365
7365
  // node_modules/zod/v3/helpers/parseUtil.js
7366
7366
  var makeIssue = (params) => {
7367
- const { data, path, errorMaps, issueData } = params;
7368
- const fullPath = [...path, ...issueData.path || []];
7367
+ const { data, path: path2, errorMaps, issueData } = params;
7368
+ const fullPath = [...path2, ...issueData.path || []];
7369
7369
  const fullIssue = {
7370
7370
  ...issueData,
7371
7371
  path: fullPath
@@ -7481,11 +7481,11 @@ var errorUtil;
7481
7481
 
7482
7482
  // node_modules/zod/v3/types.js
7483
7483
  var ParseInputLazyPath = class {
7484
- constructor(parent, value, path, key) {
7484
+ constructor(parent, value, path2, key) {
7485
7485
  this._cachedPath = [];
7486
7486
  this.parent = parent;
7487
7487
  this.data = value;
7488
- this._path = path;
7488
+ this._path = path2;
7489
7489
  this._key = key;
7490
7490
  }
7491
7491
  get path() {
@@ -11122,10 +11122,10 @@ function assignProp(target, prop, value) {
11122
11122
  configurable: true
11123
11123
  });
11124
11124
  }
11125
- function getElementAtPath(obj, path) {
11126
- if (!path)
11125
+ function getElementAtPath(obj, path2) {
11126
+ if (!path2)
11127
11127
  return obj;
11128
- return path.reduce((acc, key) => acc?.[key], obj);
11128
+ return path2.reduce((acc, key) => acc?.[key], obj);
11129
11129
  }
11130
11130
  function promiseAllObject(promisesObj) {
11131
11131
  const keys = Object.keys(promisesObj);
@@ -11445,11 +11445,11 @@ function aborted(x, startIndex = 0) {
11445
11445
  }
11446
11446
  return false;
11447
11447
  }
11448
- function prefixIssues(path, issues) {
11448
+ function prefixIssues(path2, issues) {
11449
11449
  return issues.map((iss) => {
11450
11450
  var _a;
11451
11451
  (_a = iss).path ?? (_a.path = []);
11452
- iss.path.unshift(path);
11452
+ iss.path.unshift(path2);
11453
11453
  return iss;
11454
11454
  });
11455
11455
  }
@@ -21101,8 +21101,8 @@ var StdioServerTransport = class {
21101
21101
  // src/adapters/okx.ts
21102
21102
  var import_node_crypto = __toESM(require("node:crypto"));
21103
21103
  var BASE = "https://www.okx.com";
21104
- function sign(ts, method, path, body, secret) {
21105
- const msg = ts + method + path + body;
21104
+ function sign(ts, method, path2, body, secret) {
21105
+ const msg = ts + method + path2 + body;
21106
21106
  return import_node_crypto.default.createHmac("sha256", secret).update(msg).digest("base64");
21107
21107
  }
21108
21108
  function timestamp() {
@@ -21115,9 +21115,9 @@ function buildQuery(params) {
21115
21115
  }
21116
21116
  return p.size ? "?" + p.toString() : "";
21117
21117
  }
21118
- async function request(method, path, options = {}) {
21118
+ async function request(method, path2, options = {}) {
21119
21119
  const query = options.params ? buildQuery(options.params) : "";
21120
- const fullPath = path + query;
21120
+ const fullPath = path2 + query;
21121
21121
  const bodyStr = options.body ? JSON.stringify(options.body) : "";
21122
21122
  const headers = {
21123
21123
  "Content-Type": "application/json",
@@ -21484,12 +21484,12 @@ var privateApi = {
21484
21484
 
21485
21485
  // src/adapters/hrails.ts
21486
21486
  var DEFAULT_BASE = "https://api-staging.hwallet.vip";
21487
- async function request2(path, params = {}, apiKey, base) {
21487
+ async function request2(path2, params = {}, apiKey, base) {
21488
21488
  const filtered = Object.entries(params).filter(([, v]) => v !== void 0 && v !== "");
21489
21489
  const p = new URLSearchParams();
21490
21490
  for (const [k, v] of filtered) p.append(k, String(v));
21491
21491
  const query = p.size ? "?" + p.toString() : "";
21492
- const res = await fetch(base + path + query, {
21492
+ const res = await fetch(base + path2 + query, {
21493
21493
  headers: {
21494
21494
  "Accept": "application/json",
21495
21495
  "Authorization": `Bearer ${apiKey}`
@@ -21501,7 +21501,7 @@ async function request2(path, params = {}, apiKey, base) {
21501
21501
  return json.data ?? json;
21502
21502
  }
21503
21503
  function createHRailsClient(apiKey, baseUrl = DEFAULT_BASE) {
21504
- const get = (path, params) => request2(path, params, apiKey, baseUrl);
21504
+ const get = (path2, params) => request2(path2, params, apiKey, baseUrl);
21505
21505
  return {
21506
21506
  health: () => fetch(baseUrl + "/health").then((r) => r.json()),
21507
21507
  listEvents: (params) => {
@@ -22054,7 +22054,7 @@ function registerPublicTools(server, auth) {
22054
22054
  );
22055
22055
  server.tool(
22056
22056
  "okx_get_mark_price",
22057
- "\u83B7\u53D6\u6807\u8BB0\u4EF7\u683C\u3002\u6807\u8BB0\u4EF7\u683C\u7528\u4E8E\u8BA1\u7B97\u6D6E\u52A8\u76C8\u4E8F\u548C\u5F3A\u5E73\u4EF7\u683C\uFF0C\u4E0E\u6307\u6570\u4EF7\u683C\u504F\u5DEE\u8FC7\u5927\u65F6\u5B58\u5728\u5957\u5229\u7A7A\u95F4\u3002\u4E0D\u4F20instId\u8FD4\u56DE\u5168\u91CF(~30KB)\uFF0C\u5DF2\u81EA\u52A8\u622A\u65ADtop20\u3002",
22057
+ "## \u529F\u80FD\uFF1A\u83B7\u53D6\u5408\u7EA6\u6807\u8BB0\u4EF7\u683C\uFF0C\u7528\u4E8E\u8BA1\u7B97\u6D6E\u52A8\u76C8\u4E8F\u548C\u5F3A\u5E73\u4EF7\u683C\n## \u573A\u666F\uFF1A\u7528\u4E8E\u67E5\u770B\u5408\u7EA6\u5F53\u524D\u6807\u8BB0\u4EF7\u3001\u5224\u65AD\u4E0E\u6307\u6570\u4EF7\u683C\u504F\u5DEE\u3001\u53D1\u73B0\u5957\u5229\u7A7A\u95F4\u3001\u6279\u91CF\u76D1\u63A7\u6807\u8BB0\u4EF7\u683C\n## \u5173\u952E\u8BCD\uFF1A\u6807\u8BB0\u4EF7\u683C, mark price, \u6807\u8BB0\u4EF7, \u5F3A\u5E73\u4EF7\u683C, \u6D6E\u52A8\u76C8\u4E8F, \u5957\u5229\u7A7A\u95F4\n## \u53C2\u6570\uFF1A\n## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743\n## - instId: \u4EA7\u54C1ID\uFF0C\u4E0D\u586B\u5219\u8FD4\u56DE\u8BE5\u7C7B\u578B\u5168\u91CF\uFF08~30KB\uFF0C\u5DF2\u81EA\u52A8\u622A\u65ADtop20\uFF09\n## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u5355\u4EA7\u54C1 ~500B\uFF0C\u5168\u91CF ~30KB\uFF08\u5DF2\u81EA\u52A8\u622A\u65AD top 20\uFF09\n## \u5173\u8054\uFF1Aokx_get_index_price \u770B\u6307\u6570\u4EF7 \u2192 \u672C\u5DE5\u5177\u770B\u6807\u8BB0\u4EF7 \u2192 \u5BF9\u6BD4\u57FA\u5DEE \u2192 okx_get_ticker \u770B\u6700\u65B0\u4EF7",
22058
22058
  {
22059
22059
  instType: external_exports.enum(INST_TYPE_PUBLIC).describe("\u4EA7\u54C1\u7C7B\u578B\u3002MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743"),
22060
22060
  instId: external_exports.string().optional().describe("\u4EA7\u54C1ID\uFF0C\u4E0D\u586B\u5219\u8FD4\u56DE\u8BE5\u7C7B\u578B\u5168\u91CF")
@@ -22075,7 +22075,7 @@ function registerPublicTools(server, auth) {
22075
22075
  );
22076
22076
  server.tool(
22077
22077
  "okx_get_index_price",
22078
- "\u83B7\u53D6\u6307\u6570\u4EF7\u683C\uFF08\u591A\u4EA4\u6613\u6240\u52A0\u6743\u5747\u4EF7\uFF09\u3002\u7528\u4E8E\u5224\u65AD\u73B0\u8D27\u5E02\u573A\u6574\u4F53\u4EF7\u683C\u57FA\u51C6\uFF0C\u4E0E\u6807\u8BB0\u4EF7\u683C\u5BF9\u6BD4\u53EF\u53D1\u73B0\u504F\u5DEE\u3002",
22078
+ "## \u529F\u80FD\uFF1A\u83B7\u53D6\u6307\u6570\u4EF7\u683C\uFF08\u591A\u4EA4\u6613\u6240\u52A0\u6743\u5747\u4EF7\uFF09\uFF0C\u53CD\u6620\u73B0\u8D27\u5E02\u573A\u6574\u4F53\u4EF7\u683C\u57FA\u51C6\n## \u573A\u666F\uFF1A\u7528\u4E8E\u5224\u65AD\u73B0\u8D27\u5E02\u573A\u6574\u4F53\u4EF7\u683C\u3001\u4E0E\u6807\u8BB0\u4EF7\u683C\u5BF9\u6BD4\u53D1\u73B0\u504F\u5DEE\u3001\u8BC4\u4F30\u5408\u7EA6\u6EA2\u4EF7/\u6298\u4EF7\n## \u5173\u952E\u8BCD\uFF1A\u6307\u6570\u4EF7\u683C, index price, \u52A0\u6743\u5747\u4EF7, \u73B0\u8D27\u57FA\u51C6, \u6307\u6570\u4EF7, \u591A\u4EA4\u6613\u6240\u5747\u4EF7\n## \u53C2\u6570\uFF1A\n## - instId: \u6307\u6570\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT\n## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~500B\n## \u5173\u8054\uFF1A\u672C\u5DE5\u5177\u770B\u6307\u6570\u4EF7 \u2192 okx_get_mark_price \u770B\u6807\u8BB0\u4EF7 \u2192 \u5BF9\u6BD4\u504F\u5DEE \u2192 \u5224\u65AD\u5957\u5229\u7A7A\u95F4",
22079
22079
  { instId: external_exports.string().describe("\u6307\u6570\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT") },
22080
22080
  async ({ instId }) => {
22081
22081
  try {
@@ -22092,7 +22092,7 @@ function registerPublicTools(server, auth) {
22092
22092
  );
22093
22093
  server.tool(
22094
22094
  "okx_get_open_interest",
22095
- "\u83B7\u53D6\u5408\u7EA6\u6301\u4ED3\u91CF\u3002\u6301\u4ED3\u91CF\u5FEB\u901F\u589E\u52A0\u901A\u5E38\u610F\u5473\u7740\u65B0\u8D44\u91D1\u5165\u573A\uFF0C\u7ED3\u5408\u4EF7\u683C\u65B9\u5411\u53EF\u5224\u65AD\u8D8B\u52BF\u5F3A\u5EA6\u3002\u4E0D\u4F20instId\u8FD4\u56DE\u5168\u91CF(~77KB)\uFF0C\u5DF2\u81EA\u52A8\u622A\u65ADtop20\u3002",
22095
+ "## \u529F\u80FD\uFF1A\u83B7\u53D6\u5408\u7EA6\u6301\u4ED3\u91CF\u6570\u636E\uFF0C\u53CD\u6620\u5E02\u573A\u53C2\u4E0E\u5EA6\u548C\u8D44\u91D1\u6D41\u5411\n## \u573A\u666F\uFF1A\u7528\u4E8E\u5224\u65AD\u65B0\u8D44\u91D1\u5165\u573A\uFF08\u6301\u4ED3\u91CF\u5FEB\u901F\u589E\u52A0\uFF09\u3001\u5206\u6790\u8D8B\u52BF\u5F3A\u5EA6\u3001\u6279\u91CF\u76D1\u63A7\u5408\u7EA6\u6301\u4ED3\n## \u5173\u952E\u8BCD\uFF1A\u6301\u4ED3\u91CF, open interest, OI, \u672A\u5E73\u4ED3\u91CF, \u8D44\u91D1\u6D41\u5165, \u5E02\u573A\u53C2\u4E0E\u5EA6, \u5408\u7EA6\u6301\u4ED3\n## \u53C2\u6570\uFF1A\n## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743\n## - instId: \u4EA7\u54C1ID\uFF0C\u4E0D\u586B\u5219\u8FD4\u56DE\u5168\u91CF\uFF08~77KB\uFF0C\u5DF2\u81EA\u52A8\u622A\u65ADtop20\uFF09\n## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u5355\u4EA7\u54C1 ~500B\uFF0C\u5168\u91CF ~77KB\uFF08\u5DF2\u81EA\u52A8\u622A\u65AD top 20\uFF09\n## \u5173\u8054\uFF1Aokx_get_ticker \u770B\u4EF7\u683C\u65B9\u5411 \u2192 \u672C\u5DE5\u5177\u770B\u6301\u4ED3\u91CF\u53D8\u5316 \u2192 \u91CF\u4EF7\u7ED3\u5408\u5224\u65AD\u8D8B\u52BF",
22096
22096
  {
22097
22097
  instType: external_exports.enum(INST_TYPE_CONTRACTS).describe("\u4EA7\u54C1\u7C7B\u578B\u3002SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743"),
22098
22098
  instId: external_exports.string().optional().describe("\u4EA7\u54C1ID\uFF0C\u4E0D\u586B\u5219\u8FD4\u56DE\u5168\u91CF")
@@ -22113,7 +22113,7 @@ function registerPublicTools(server, auth) {
22113
22113
  );
22114
22114
  server.tool(
22115
22115
  "okx_get_system_time",
22116
- "\u83B7\u53D6OKX\u670D\u52A1\u5668\u5F53\u524D\u65F6\u95F4\u6233\u3002\u7528\u4E8E\u6821\u51C6\u672C\u5730\u65F6\u95F4\u504F\u5DEE\uFF0C\u786E\u4FDD\u7B7E\u540D\u8BF7\u6C42\u7684\u65F6\u95F4\u6233\u5728\u6709\u6548\u8303\u56F4\u5185\uFF08\xB130\u79D2\uFF09\u3002",
22116
+ "## \u529F\u80FD\uFF1A\u83B7\u53D6OKX\u670D\u52A1\u5668\u5F53\u524D\u65F6\u95F4\u6233\n## \u573A\u666F\uFF1A\u7528\u4E8E\u6821\u51C6\u672C\u5730\u65F6\u95F4\u504F\u5DEE\u3001\u786E\u4FDD\u7B7E\u540D\u8BF7\u6C42\u7684\u65F6\u95F4\u6233\u5728\u6709\u6548\u8303\u56F4\u5185\uFF08\xB130\u79D2\uFF09\u3001\u6392\u67E5\u9274\u6743\u5931\u8D25\n## \u5173\u952E\u8BCD\uFF1A\u670D\u52A1\u5668\u65F6\u95F4, system time, \u65F6\u95F4\u6233, \u65F6\u95F4\u6821\u51C6, \u7B7E\u540D\u65F6\u95F4, \u9274\u6743\u65F6\u95F4\n## \u53C2\u6570\uFF1A\u65E0\n## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~200B\n## \u5173\u8054\uFF1A\u672C\u5DE5\u5177\u6821\u51C6\u65F6\u95F4 \u2192 \u6240\u6709\u9274\u6743\u63A5\u53E3\u4F9D\u8D56\u6B63\u786E\u65F6\u95F4\u6233 \u2192 okx_place_order \u7B49\u4E0B\u5355",
22117
22117
  {},
22118
22118
  async () => {
22119
22119
  try {
@@ -22126,7 +22126,7 @@ function registerPublicTools(server, auth) {
22126
22126
  );
22127
22127
  server.tool(
22128
22128
  "okx_get_opt_summary",
22129
- "\u83B7\u53D6\u671F\u6743\u5E02\u573A\u6458\u8981\u6570\u636E\uFF0C\u542B\u5404\u5230\u671F\u65E5\u7684\u9690\u542B\u6CE2\u52A8\u7387\uFF08IV\uFF09\u3001\u672A\u5E73\u4ED3\u91CF\u548C\u6210\u4EA4\u91CF\u5206\u5E03\u3002\u7528\u4E8E\u671F\u6743\u4EA4\u6613\u524D\u7684\u6574\u4F53\u5E02\u573A\u626B\u63CF\u3002",
22129
+ "## \u529F\u80FD\uFF1A\u83B7\u53D6\u671F\u6743\u5E02\u573A\u6458\u8981\u6570\u636E\uFF0C\u542B\u5404\u5230\u671F\u65E5\u7684\u9690\u542B\u6CE2\u52A8\u7387\uFF08IV\uFF09\u3001\u672A\u5E73\u4ED3\u91CF\u548C\u6210\u4EA4\u91CF\u5206\u5E03\n## \u573A\u666F\uFF1A\u7528\u4E8E\u671F\u6743\u4EA4\u6613\u524D\u5E02\u573A\u626B\u63CF\u3001\u5206\u6790\u6CE2\u52A8\u7387\u671F\u9650\u7ED3\u6784\u3001\u53D1\u73B0\u5F02\u5E38IV\u3001\u6309\u5230\u671F\u65E5\u7B5B\u9009\n## \u5173\u952E\u8BCD\uFF1A\u671F\u6743\u6458\u8981, opt summary, \u9690\u542B\u6CE2\u52A8\u7387, IV, \u671F\u6743\u672A\u5E73\u4ED3, \u6CE2\u52A8\u7387\u66F2\u7EBF, \u671F\u6743\u5E02\u573A\n## \u53C2\u6570\uFF1A\n## - uly: \u6807\u7684\u6307\u6570\uFF0C\u5982 BTC-USD\u3001ETH-USD\n## - expTime: \u5230\u671F\u65E5\u7B5B\u9009\uFF0C\u683C\u5F0F YYYYMMDD\uFF0C\u5982 20250101\n## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u4E2D\u7B49 ~10KB\n## \u5173\u8054\uFF1A\u672C\u5DE5\u5177\u626B\u63CF\u671F\u6743\u5E02\u573A \u2192 okx_get_instruments(instType=OPTION) \u83B7\u53D6\u5177\u4F53\u5408\u7EA6 \u2192 okx_get_ticker \u67E5\u671F\u6743\u884C\u60C5",
22130
22130
  {
22131
22131
  uly: external_exports.string().describe("\u6807\u7684\u6307\u6570\uFF0C\u5982 BTC-USD\u3001ETH-USD"),
22132
22132
  expTime: external_exports.string().optional().describe("\u5230\u671F\u65E5\u7B5B\u9009\uFF0C\u683C\u5F0F YYYYMMDD\uFF0C\u5982 20250101")
@@ -22146,7 +22146,7 @@ function registerPublicTools(server, auth) {
22146
22146
  );
22147
22147
  server.tool(
22148
22148
  "okx_get_insurance_fund",
22149
- "\u83B7\u53D6OKX\u4FDD\u9669\u57FA\u91D1\u4F59\u989D\u53D8\u52A8\u5386\u53F2\u3002\u4FDD\u9669\u57FA\u91D1\u89C4\u6A21\u53CD\u6620\u4EA4\u6613\u6240\u62B5\u5FA1\u6781\u7AEF\u884C\u60C5\u7684\u80FD\u529B\uFF0C\u4E5F\u662F\u8861\u91CF\u5E73\u53F0\u98CE\u9669\u7684\u6307\u6807\u3002",
22149
+ "## \u529F\u80FD\uFF1A\u83B7\u53D6OKX\u4FDD\u9669\u57FA\u91D1\u4F59\u989D\u53D8\u52A8\u5386\u53F2\uFF0C\u53CD\u6620\u4EA4\u6613\u6240\u62B5\u5FA1\u6781\u7AEF\u884C\u60C5\u7684\u80FD\u529B\n## \u573A\u666F\uFF1A\u7528\u4E8E\u8BC4\u4F30\u5E73\u53F0\u98CE\u9669\u3001\u76D1\u63A7\u4FDD\u9669\u57FA\u91D1\u89C4\u6A21\u53D8\u5316\u3001\u6781\u7AEF\u884C\u60C5\u524D\u540E\u5BF9\u6BD4\u57FA\u91D1\u6D88\u8017\n## \u5173\u952E\u8BCD\uFF1A\u4FDD\u9669\u57FA\u91D1, insurance fund, \u5E73\u53F0\u98CE\u9669, \u6781\u7AEF\u884C\u60C5, \u4EA4\u6613\u6240\u4FDD\u969C, \u98CE\u9669\u6307\u6807\n## \u53C2\u6570\uFF1A\n## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743\n## - uly: \u6807\u7684\u6307\u6570\uFF0C\u5982 BTC-USD\uFF08SWAP/FUTURES/OPTION\u5FC5\u586B\uFF09\n## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u4E2D\u7B49 ~5KB\n## \u5173\u8054\uFF1Aokx_get_instruments \u83B7\u53D6\u4EA7\u54C1 \u2192 \u672C\u5DE5\u5177\u770B\u4FDD\u9669\u57FA\u91D1 \u2192 \u8BC4\u4F30\u5E73\u53F0\u5065\u5EB7\u5EA6",
22150
22150
  {
22151
22151
  instType: external_exports.enum(INST_TYPE_MARGIN_PUB).describe("\u4EA7\u54C1\u7C7B\u578B\u3002MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743"),
22152
22152
  uly: external_exports.string().optional().describe("\u6807\u7684\u6307\u6570\uFF0C\u5982 BTC-USD\uFF08SWAP/FUTURES/OPTION\u5FC5\u586B\uFF09")
@@ -22166,7 +22166,7 @@ function registerPublicTools(server, auth) {
22166
22166
  );
22167
22167
  server.tool(
22168
22168
  "okx_convert_contract_coin",
22169
- "\u5408\u7EA6\u5F20\u6570\u4E0E\u5E01\u6570\u4E92\u6362\u8BA1\u7B97\u3002\u4E0B\u5408\u7EA6\u5355\u65F6\u5148\u7528\u6B64\u63A5\u53E3\u6362\u7B97\u5F20\u6570\uFF0C\u907F\u514D\u6570\u91CF\u586B\u9519\u3002",
22169
+ "## \u529F\u80FD\uFF1A\u5408\u7EA6\u5F20\u6570\u4E0E\u5E01\u6570\u4E92\u6362\u8BA1\u7B97\uFF0C\u4E0B\u5408\u7EA6\u5355\u524D\u6362\u7B97\u6570\u91CF\n## \u573A\u666F\uFF1A\u7528\u4E8E\u4E0B\u5355\u524D\u5C06\u5E01\u6570\u6362\u7B97\u4E3A\u5408\u7EA6\u5F20\u6570\u3001\u5F20\u6570\u6362\u5E01\u6570\u3001\u907F\u514D\u6570\u91CF\u586B\u9519\u5BFC\u81F4\u8BA2\u5355\u5931\u8D25\n## \u5173\u952E\u8BCD\uFF1A\u5F20\u6570\u6362\u7B97, \u5E01\u6570\u6362\u7B97, convert contract, \u5408\u7EA6\u6362\u7B97, \u5F20\u6570\u8BA1\u7B97, \u4E0B\u5355\u51C6\u5907\n## \u53C2\u6570\uFF1A\n## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\n## - sz: \u6570\u91CF\uFF08\u5F20\u6570\u6216\u5E01\u6570\uFF0C\u53D6\u51B3\u4E8Eunit\u53C2\u6570\u7684\u8BBE\u7F6E\uFF09\n## - unit: sz\u7684\u5355\u4F4D\u3002coin=\u5E01\uFF0Ccontracts=\u5F20\n## - opType: \u5F00\u4ED3\u6216\u5E73\u4ED3\u3002open=\u5F00\u4ED3, close=\u5E73\u4ED3\n## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~300B\n## \u5173\u8054\uFF1A\u4E0B\u5355\u524D\u5FC5\u8C03 \u2192 \u672C\u5DE5\u5177\u6362\u7B97\u6570\u91CF \u2192 okx_place_order \u4E0B\u5355",
22170
22170
  {
22171
22171
  instId: external_exports.string().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP"),
22172
22172
  sz: external_exports.string().describe("\u6570\u91CF\uFF08\u5F20\u6570\u6216\u5E01\u6570\uFF0C\u53D6\u51B3\u4E8Eunit\uFF09"),
@@ -22184,7 +22184,7 @@ function registerPublicTools(server, auth) {
22184
22184
  );
22185
22185
  server.tool(
22186
22186
  "okx_get_announcements",
22187
- "\u83B7\u53D6OKX\u5B98\u65B9\u516C\u544A\u5217\u8868\uFF08\u7EF4\u62A4\u901A\u77E5\u3001\u65B0\u5E01\u4E0A\u7EBF\u3001\u6D3B\u52A8\u7B49\uFF09\u3002\u5B9A\u671F\u67E5\u8BE2\u53EF\u53CA\u65F6\u4E86\u89E3\u5E73\u53F0\u53D8\u5316\uFF0C\u63D0\u524D\u505A\u597D\u98CE\u9669\u51C6\u5907\u3002",
22187
+ "## \u529F\u80FD\uFF1A\u83B7\u53D6OKX\u5B98\u65B9\u516C\u544A\u5217\u8868\uFF08\u7EF4\u62A4\u901A\u77E5\u3001\u65B0\u5E01\u4E0A\u7EBF\u3001\u6D3B\u52A8\u7B49\uFF09\n## \u573A\u666F\uFF1A\u7528\u4E8E\u53CA\u65F6\u4E86\u89E3\u5E73\u53F0\u7EF4\u62A4\u8BA1\u5212\u3001\u8DDF\u8E2A\u65B0\u5E01\u4E0A\u7EBF\u4FE1\u606F\u3001\u63D0\u524D\u505A\u597D\u98CE\u9669\u51C6\u5907\n## \u5173\u952E\u8BCD\uFF1A\u516C\u544A, announcements, \u7EF4\u62A4\u901A\u77E5, \u65B0\u5E01\u4E0A\u7EBF, \u5E73\u53F0\u516C\u544A, \u6D3B\u52A8\u901A\u77E5\n## \u53C2\u6570\uFF1A\n## - annType: \u516C\u544A\u7C7B\u578BID\uFF0C\u4E0D\u586B\u8FD4\u56DE\u5168\u90E8\u3002\u53EF\u5148\u8C03\u7528 okx_get_announcement_types \u67E5\u8BE2\u53EF\u7528\u7C7B\u578B\n## - lang: \u8BED\u8A00\u3002zh-Hans=\u4E2D\u6587, en-US=\u82F1\u6587\u3002\u9ED8\u8BA4\u4E2D\u6587\n## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u4E2D\u7B49 ~5KB\n## \u5173\u8054\uFF1Aokx_get_announcement_types \u83B7\u53D6\u7C7B\u578B\u5217\u8868 \u2192 \u672C\u5DE5\u5177\u6309\u7C7B\u578B\u7B5B\u9009\u516C\u544A \u2192 \u8BC4\u4F30\u5BF9\u4EA4\u6613\u7684\u5F71\u54CD",
22188
22188
  {
22189
22189
  annType: external_exports.string().optional().describe("\u516C\u544A\u7C7B\u578BID\uFF0C\u4E0D\u586B\u8FD4\u56DE\u5168\u90E8\u3002\u53EF\u5148\u8C03\u7528 okx_get_announcement_types \u67E5\u8BE2\u53EF\u7528\u7C7B\u578B"),
22190
22190
  lang: external_exports.enum(["zh-Hans", "en-US"]).optional().describe("\u8BED\u8A00\uFF0C\u9ED8\u8BA4\u4E2D\u6587")
@@ -23382,7 +23382,7 @@ function registerAccountTools(server, auth) {
23382
23382
  function registerTradingTools(server, auth) {
23383
23383
  server.tool(
23384
23384
  "okx_place_order",
23385
- "\u5728OKX\u4E0B\u5355\u3002\u26A0\uFE0F \u6B64\u64CD\u4F5C\u4F1A\u4EA7\u751F\u771F\u5B9E\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u660E\u786E\u786E\u8BA4\u4EA7\u54C1\u3001\u65B9\u5411\u3001\u6570\u91CF\u548C\u4EF7\u683C\u3002\u9700\u8981API Key\u9274\u6743\u3002",
23385
+ "## \u529F\u80FD\uFF1A\u5728OKX\u4E0B\u5355\uFF08\u5E02\u4EF7/\u9650\u4EF7/\u53EA\u6302/\u5168\u90E8\u6210\u4EA4\u6216\u53D6\u6D88/\u7ACB\u5373\u6210\u4EA4\u5E76\u53D6\u6D88\u5269\u4F59\uFF09\n## \u573A\u666F\uFF1A\u7528\u4E8E\u5F00\u4ED3\u505A\u591A/\u505A\u7A7A\u3001\u9650\u4EF7\u6302\u5355\u3001\u5E02\u4EF7\u5FEB\u901F\u6210\u4EA4\u3001\u53EA\u6302\u5355\u4E0D\u6210\u4EA4\uFF08post_only\uFF09\n## \u5173\u952E\u8BCD\uFF1A\u4E0B\u5355, place order, \u5E02\u4EF7\u5355, \u9650\u4EF7\u5355, \u5F00\u4ED3, \u5E73\u4ED3, \u4E70\u5165, \u5356\u51FA\n## \u53C2\u6570\uFF1A\n## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT\n## - tdMode: \u4EA4\u6613\u6A21\u5F0F\u3002cash=\u73B0\u8D27, isolated=\u9010\u4ED3, cross=\u5168\u4ED3\n## - side: \u4E70\u5356\u65B9\u5411\u3002buy=\u4E70\u5165, sell=\u5356\u51FA\n## - ordType: \u8BA2\u5355\u7C7B\u578B\u3002market=\u5E02\u4EF7, limit=\u9650\u4EF7, post_only=\u53EA\u6302, fok=\u5168\u6210\u6216\u53D6\u6D88, ioc=\u7ACB\u5373\u6210\u4EA4\u5E76\u53D6\u6D88\n## - sz: \u59D4\u6258\u6570\u91CF\uFF08\u6839\u636E\u4EA7\u54C1\u4E0D\u540C\u53EF\u4E3A\u5F20\u6570\u6216\u5E01\u6570\uFF0C\u4E0B\u5355\u524D\u5EFA\u8BAE\u5148\u7528 okx_convert_contract_coin \u6362\u7B97\uFF09\n## - px: \u59D4\u6258\u4EF7\u683C\uFF08\u9650\u4EF7\u5355\u5FC5\u586B\uFF09\n## \u9274\u6743\uFF1A\u{1F534} \u9700\u8981 API Key\uFF08\u4EA4\u6613\uFF09- \u4F1A\u4EA7\u751F\u771F\u5B9E\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u660E\u786E\u786E\u8BA4\n## \u98CE\u9669\uFF1AWRITE \u2014 \u521B\u5EFA\u771F\u5B9E\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u786E\u8BA4\u4EA7\u54C1\u3001\u65B9\u5411\u3001\u6570\u91CF\u548C\u4EF7\u683C\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~500B\n## \u5173\u8054\uFF1Aokx_get_ticker \u770B\u4EF7\u683C \u2192 okx_get_balance \u786E\u8BA4\u4F59\u989D \u2192 \u672C\u5DE5\u5177\u4E0B\u5355 \u2192 okx_get_order \u786E\u8BA4\u6210\u4EA4",
23386
23386
  {
23387
23387
  instId: external_exports.string().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT"),
23388
23388
  tdMode: external_exports.enum(["cash", "isolated", "cross"]).describe("\u4EA4\u6613\u6A21\u5F0F\uFF1Acash=\u73B0\u8D27\uFF0Cisolated=\u9010\u4ED3\uFF0Ccross=\u5168\u4ED3"),
@@ -23405,7 +23405,7 @@ function registerTradingTools(server, auth) {
23405
23405
  );
23406
23406
  server.tool(
23407
23407
  "okx_cancel_order",
23408
- "\u64A4\u9500\u6307\u5B9A\u8BA2\u5355\u3002\u26A0\uFE0F \u9700\u8981API Key\u9274\u6743\u3002",
23408
+ "## \u529F\u80FD\uFF1A\u64A4\u9500\u6307\u5B9A\u8BA2\u5355\n## \u573A\u666F\uFF1A\u7528\u4E8E\u53D6\u6D88\u672A\u6210\u4EA4\u7684\u9650\u4EF7\u5355\u3001\u7EA0\u6B63\u8BEF\u4E0B\u5355\u3001\u6E05\u7A7A\u67D0\u4EA7\u54C1\u6302\u5355\n## \u5173\u952E\u8BCD\uFF1A\u64A4\u5355, cancel order, \u64A4\u9500\u8BA2\u5355, \u53D6\u6D88\u6302\u5355, \u53D6\u6D88\u59D4\u6258\n## \u53C2\u6570\uFF1A\n## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT\n## - ordId: \u8BA2\u5355ID\uFF0C\u7531 okx_place_order \u8FD4\u56DE\n## \u9274\u6743\uFF1A\u{1F534} \u9700\u8981 API Key\uFF08\u4EA4\u6613\uFF09- \u8C03\u7528\u524D\u987B\u5411\u7528\u6237\u786E\u8BA4\n## \u98CE\u9669\uFF1AWRITE \u2014 \u64A4\u9500\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u786E\u8BA4\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~300B\n## \u5173\u8054\uFF1Aokx_place_order \u4E0B\u5355 \u2192 okx_get_orders_pending \u67E5\u770B\u6302\u5355 \u2192 \u672C\u5DE5\u5177\u64A4\u5355 \u2192 okx_get_order \u786E\u8BA4\u64A4\u9500",
23409
23409
  {
23410
23410
  instId: external_exports.string().describe("\u4EA7\u54C1ID"),
23411
23411
  ordId: external_exports.string().describe("\u8BA2\u5355ID")
@@ -23422,7 +23422,7 @@ function registerTradingTools(server, auth) {
23422
23422
  );
23423
23423
  server.tool(
23424
23424
  "okx_amend_order",
23425
- "\u4FEE\u6539\u672A\u6210\u4EA4\u8BA2\u5355\u7684\u4EF7\u683C\u6216\u6570\u91CF\u3002\u26A0\uFE0F \u9700\u8981API Key\u9274\u6743\u3002",
23425
+ "## \u529F\u80FD\uFF1A\u4FEE\u6539\u672A\u6210\u4EA4\u8BA2\u5355\u7684\u4EF7\u683C\u6216\u6570\u91CF\n## \u573A\u666F\uFF1A\u7528\u4E8E\u8C03\u6574\u9650\u4EF7\u5355\u4EF7\u683C\u8DDF\u8FDB\u5E02\u573A\u3001\u51CF\u5C11\u59D4\u6258\u6570\u91CF\u3001\u4FEE\u6539\u6302\u5355\u53C2\u6570\n## \u5173\u952E\u8BCD\uFF1A\u6539\u5355, amend order, \u4FEE\u6539\u8BA2\u5355, \u6539\u4EF7, \u6539\u91CF, \u8C03\u6574\u59D4\u6258\n## \u53C2\u6570\uFF1A\n## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT\n## - ordId: \u8BA2\u5355ID\n## - newSz: \u65B0\u59D4\u6258\u6570\u91CF\uFF08\u53EF\u9009\uFF09\n## - newPx: \u65B0\u59D4\u6258\u4EF7\u683C\uFF08\u53EF\u9009\uFF09\n## \u9274\u6743\uFF1A\u{1F534} \u9700\u8981 API Key\uFF08\u4EA4\u6613\uFF09- \u8C03\u7528\u524D\u987B\u5411\u7528\u6237\u786E\u8BA4\n## \u98CE\u9669\uFF1AWRITE \u2014 \u4FEE\u6539\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u786E\u8BA4\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~300B\n## \u5173\u8054\uFF1Aokx_get_orders_pending \u67E5\u770B\u6302\u5355 \u2192 \u672C\u5DE5\u5177\u6539\u5355 \u2192 okx_get_order \u786E\u8BA4\u4FEE\u6539",
23426
23426
  {
23427
23427
  instId: external_exports.string().describe("\u4EA7\u54C1ID"),
23428
23428
  ordId: external_exports.string().describe("\u8BA2\u5355ID"),
@@ -23444,7 +23444,7 @@ function registerTradingTools(server, auth) {
23444
23444
  );
23445
23445
  server.tool(
23446
23446
  "okx_get_orders_pending",
23447
- "\u67E5\u8BE2\u5F53\u524D\u6240\u6709\u672A\u6210\u4EA4\u6302\u5355\u5217\u8868\u3002\u7528\u4E8E\u76D1\u63A7\u672A\u6210\u4EA4\u8BA2\u5355\u3001\u68C0\u67E5\u9650\u4EF7\u5355\u662F\u5426\u4ECD\u5728\u961F\u5217\u4E2D\u3002\u26A0\uFE0F \u9700\u8981API Key\u9274\u6743\u3002",
23447
+ "## \u529F\u80FD\uFF1A\u67E5\u8BE2\u5F53\u524D\u6240\u6709\u672A\u6210\u4EA4\u6302\u5355\u5217\u8868\n## \u573A\u666F\uFF1A\u7528\u4E8E\u76D1\u63A7\u672A\u6210\u4EA4\u8BA2\u5355\u3001\u68C0\u67E5\u9650\u4EF7\u5355\u662F\u5426\u4ECD\u5728\u961F\u5217\u4E2D\u3001\u6279\u91CF\u67E5\u770B\u6302\u5355\u72B6\u6001\n## \u5173\u952E\u8BCD\uFF1A\u6302\u5355\u67E5\u8BE2, orders pending, \u672A\u6210\u4EA4\u8BA2\u5355, \u9650\u4EF7\u5355\u72B6\u6001, \u59D4\u6258\u5217\u8868, \u5F53\u524D\u6302\u5355\n## \u53C2\u6570\uFF1A\n## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743\u3002\u4E0D\u586B\u8FD4\u56DE\u5168\u90E8\n## - instId: \u4EA7\u54C1ID\uFF0C\u7CBE\u786E\u7B5B\u9009\n## - ordType: \u8BA2\u5355\u7C7B\u578B\u7B5B\u9009\u3002market/limit/post_only/fok/ioc\n## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u4E2D\u7B49 ~10KB\n## \u5173\u8054\uFF1Aokx_place_order \u4E0B\u5355 \u2192 \u672C\u5DE5\u5177\u67E5\u770B\u6302\u5355 \u2192 okx_cancel_order \u64A4\u5355 / okx_amend_order \u6539\u5355",
23448
23448
  {
23449
23449
  instType: external_exports.enum(INST_TYPE_TRADE).optional().describe("\u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743\u3002\u4E0D\u586B\u8FD4\u56DE\u5168\u90E8"),
23450
23450
  instId: external_exports.string().optional().describe("\u4EA7\u54C1ID\uFF0C\u7CBE\u786E\u7B5B\u9009"),
@@ -23462,7 +23462,7 @@ function registerTradingTools(server, auth) {
23462
23462
  );
23463
23463
  server.tool(
23464
23464
  "okx_get_fills",
23465
- "\u67E5\u8BE2\u6700\u8FD1\u7684\u6210\u4EA4\u660E\u7EC6\uFF08\u9010\u7B14\u6210\u4EA4\uFF09\uFF0C\u542B\u6210\u4EA4\u4EF7\u3001\u6210\u4EA4\u91CF\u548C\u624B\u7EED\u8D39\u3002\u6BD4\u8BA2\u5355\u5386\u53F2\u66F4\u7EC6\u7C92\u5EA6\uFF0C\u53EF\u7528\u4E8E\u7CBE\u786E\u8BA1\u7B97\u5747\u4EF7\u3002\u26A0\uFE0F \u9700\u8981API Key\u9274\u6743\u3002",
23465
+ "## \u529F\u80FD\uFF1A\u67E5\u8BE2\u6700\u8FD1\u7684\u6210\u4EA4\u660E\u7EC6\uFF08\u9010\u7B14\u6210\u4EA4\uFF09\uFF0C\u542B\u6210\u4EA4\u4EF7\u3001\u6210\u4EA4\u91CF\u548C\u624B\u7EED\u8D39\n## \u573A\u666F\uFF1A\u7528\u4E8E\u7CBE\u786E\u8BA1\u7B97\u6210\u4EA4\u5747\u4EF7\u3001\u6838\u5BF9\u6BCF\u7B14\u6210\u4EA4\u624B\u7EED\u8D39\u3001\u6BD4\u8BA2\u5355\u5386\u53F2\u66F4\u7EC6\u7C92\u5EA6\u5730\u590D\u76D8\n## \u5173\u952E\u8BCD\uFF1A\u6210\u4EA4\u660E\u7EC6, fills, \u9010\u7B14\u6210\u4EA4, \u6210\u4EA4\u8BB0\u5F55, \u624B\u7EED\u8D39\u660E\u7EC6, \u5747\u4EF7\u8BA1\u7B97\n## \u53C2\u6570\uFF1A\n## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743\n## - instId: \u4EA7\u54C1ID\n## - limit: \u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA4100\uFF0C\u6700\u5927100\n## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A100\u6761 ~10KB \u2014 \u4E2D\u7B49\n## \u5173\u8054\uFF1Aokx_place_order \u4E0B\u5355 \u2192 \u672C\u5DE5\u5177\u770B\u6210\u4EA4\u660E\u7EC6 \u2192 okx_get_fills_history \u67E5\u5386\u53F2\u6210\u4EA4",
23466
23466
  {
23467
23467
  instType: external_exports.enum(INST_TYPE_TRADE).optional().describe("\u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743"),
23468
23468
  instId: external_exports.string().optional().describe("\u4EA7\u54C1ID"),
@@ -23480,7 +23480,7 @@ function registerTradingTools(server, auth) {
23480
23480
  );
23481
23481
  server.tool(
23482
23482
  "okx_get_orders_history_archive",
23483
- "\u67E5\u8BE23\u4E2A\u6708\u4EE5\u524D\u7684\u5B8C\u6574\u5386\u53F2\u8BA2\u5355\uFF08\u5F52\u6863\u6570\u636E\uFF09\u3002\u7528\u4E8E\u957F\u671F\u4EA4\u6613\u8BB0\u5F55\u5206\u6790\u3002\u26A0\uFE0F \u9700\u8981API Key\u9274\u6743\u3002",
23483
+ "## \u529F\u80FD\uFF1A\u67E5\u8BE23\u4E2A\u6708\u4EE5\u524D\u7684\u5B8C\u6574\u5386\u53F2\u8BA2\u5355\uFF08\u5F52\u6863\u6570\u636E\uFF09\n## \u573A\u666F\uFF1A\u7528\u4E8E\u957F\u671F\u4EA4\u6613\u8BB0\u5F55\u5206\u6790\u3001\u5E74\u5EA6\u4EA4\u6613\u590D\u76D8\u3001\u5BA1\u8BA1\u5F52\u6863\u6570\u636E\n## \u5173\u952E\u8BCD\uFF1A\u5F52\u6863\u8BA2\u5355, orders history archive, \u5386\u53F2\u5F52\u6863, \u957F\u671F\u8BB0\u5F55, \u8BA2\u5355\u5B58\u6863\n## \u53C2\u6570\uFF1A\n## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743\n## - limit: \u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA450\uFF0C\u6700\u5927100\n## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u4E2D\u7B49 ~10KB\n## \u5173\u8054\uFF1Aokx_get_orders_history \u67E5\u8FD1\u671F\u8BA2\u5355 \u2192 \u672C\u5DE5\u5177\u67E5\u5F52\u6863 \u2192 \u5B8C\u6574\u4EA4\u6613\u590D\u76D8",
23484
23484
  {
23485
23485
  instType: external_exports.enum(INST_TYPE_TRADE).describe("\u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743"),
23486
23486
  limit: external_exports.number().int().min(1).max(100).optional().describe("\u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA450")
@@ -23913,7 +23913,7 @@ function registerTradingTools(server, auth) {
23913
23913
  function registerAlgoTools(server, auth) {
23914
23914
  server.tool(
23915
23915
  "okx_get_algo_orders",
23916
- "\u67E5\u8BE2\u5F53\u524D\u6302\u5355\u4E2D\u7684\u7B56\u7565\u59D4\u6258\u5355\uFF08\u6B62\u76C8\u6B62\u635F\u3001\u51B0\u5C71\u3001\u65F6\u95F4\u52A0\u6743\u7B49\uFF09\u3002\u26A0\uFE0F \u9700\u8981API Key\u9274\u6743\u3002",
23916
+ "## \u529F\u80FD\uFF1A\u67E5\u8BE2\u5F53\u524D\u6302\u5355\u4E2D\u7684\u7B56\u7565\u59D4\u6258\u5355\uFF08\u6B62\u76C8\u6B62\u635F\u3001\u51B0\u5C71\u3001\u65F6\u95F4\u52A0\u6743\u7B49\uFF09\n## \u573A\u666F\uFF1A\u7528\u4E8E\u67E5\u770B\u5F53\u524D\u751F\u6548\u7684\u7B56\u7565\u5355\u3001\u76D1\u63A7\u6B62\u76C8\u6B62\u635F\u6302\u5355\u3001\u68C0\u67E5\u51B0\u5C71/TWAP\u6267\u884C\u72B6\u6001\n## \u5173\u952E\u8BCD\uFF1A\u7B56\u7565\u59D4\u6258, algo orders, \u6B62\u76C8\u6B62\u635F, \u6761\u4EF6\u5355, \u51B0\u5C71\u59D4\u6258, TWAP, \u7B56\u7565\u5355\u67E5\u8BE2\n## \u53C2\u6570\uFF1A\n## - ordType: \u7B56\u7565\u7C7B\u578B\u3002conditional=\u6761\u4EF6\u5355, oco=OCO\u8BA2\u5355, trigger=\u89E6\u53D1\u5355, move_order_stop=\u79FB\u52A8\u6B62\u635F, iceberg=\u51B0\u5C71, twap=\u65F6\u95F4\u52A0\u6743\n## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743\n## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u4E2D\u7B49 ~5KB\n## \u5173\u8054\uFF1Aokx_place_algo_order \u4E0B\u7B56\u7565\u5355 \u2192 \u672C\u5DE5\u5177\u67E5\u770B\u6302\u5355 \u2192 okx_cancel_algo_order \u64A4\u9500",
23917
23917
  {
23918
23918
  ordType: external_exports.enum(["conditional", "oco", "trigger", "move_order_stop", "iceberg", "twap"]).describe("\u7B56\u7565\u7C7B\u578B"),
23919
23919
  instType: external_exports.enum(INST_TYPE_TRADE).optional().describe("\u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743")
@@ -23930,7 +23930,7 @@ function registerAlgoTools(server, auth) {
23930
23930
  );
23931
23931
  server.tool(
23932
23932
  "okx_get_algo_orders_history",
23933
- "\u67E5\u8BE2\u5386\u53F2\u7B56\u7565\u59D4\u6258\u5355\u8BB0\u5F55\u3002\u26A0\uFE0F \u9700\u8981API Key\u9274\u6743\u3002",
23933
+ "## \u529F\u80FD\uFF1A\u67E5\u8BE2\u5386\u53F2\u7B56\u7565\u59D4\u6258\u5355\u8BB0\u5F55\uFF08\u5DF2\u89E6\u53D1/\u5DF2\u64A4\u9500/\u5931\u8D25\u7684\u7B56\u7565\u5355\uFF09\n## \u573A\u666F\uFF1A\u7528\u4E8E\u590D\u76D8\u7B56\u7565\u5355\u6267\u884C\u60C5\u51B5\u3001\u5206\u6790\u6B62\u76C8\u6B62\u635F\u89E6\u53D1\u5386\u53F2\u3001\u6392\u67E5\u7B56\u7565\u5931\u8D25\u539F\u56E0\n## \u5173\u952E\u8BCD\uFF1A\u7B56\u7565\u5386\u53F2, algo orders history, \u7B56\u7565\u8BB0\u5F55, \u5386\u53F2\u6761\u4EF6\u5355, \u6B62\u76C8\u6B62\u635F\u5386\u53F2, \u7B56\u7565\u590D\u76D8\n## \u53C2\u6570\uFF1A\n## - ordType: \u7B56\u7565\u7C7B\u578B\u3002conditional=\u6761\u4EF6\u5355, oco=OCO, trigger=\u89E6\u53D1\u5355, move_order_stop=\u79FB\u52A8\u6B62\u635F, iceberg=\u51B0\u5C71, twap=\u65F6\u95F4\u52A0\u6743\n## - state: \u8BA2\u5355\u72B6\u6001\u3002effective=\u5DF2\u751F\u6548, canceled=\u5DF2\u64A4\u9500, order_failed=\u5931\u8D25\n## - instType: \u4EA7\u54C1\u7C7B\u578B\u3002SPOT=\u73B0\u8D27, MARGIN=\u6760\u6746, SWAP=\u6C38\u7EED, FUTURES=\u4EA4\u5272, OPTION=\u671F\u6743\n## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u4E2D\u7B49 ~10KB\n## \u5173\u8054\uFF1Aokx_get_algo_orders \u67E5\u770B\u5F53\u524D\u6302\u5355 \u2192 \u672C\u5DE5\u5177\u67E5\u5386\u53F2 \u2192 \u5206\u6790\u7B56\u7565\u6548\u679C",
23934
23934
  {
23935
23935
  ordType: external_exports.enum(["conditional", "oco", "trigger", "move_order_stop", "iceberg", "twap"]).describe("\u7B56\u7565\u7C7B\u578B"),
23936
23936
  state: external_exports.enum(["effective", "canceled", "order_failed"]).describe("\u8BA2\u5355\u72B6\u6001"),
@@ -23948,7 +23948,7 @@ function registerAlgoTools(server, auth) {
23948
23948
  );
23949
23949
  server.tool(
23950
23950
  "okx_place_algo_order",
23951
- "\u4E0B\u7B56\u7565\u59D4\u6258\u5355\uFF08\u6B62\u76C8\u6B62\u635F\u3001\u6761\u4EF6\u5355\u7B49\uFF09\u3002\u26A0\uFE0F \u6B64\u64CD\u4F5C\u4F1A\u4EA7\u751F\u771F\u5B9E\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u786E\u8BA4\u3002\u9700\u8981API Key\u9274\u6743\u3002",
23951
+ "## \u529F\u80FD\uFF1A\u4E0B\u7B56\u7565\u59D4\u6258\u5355\uFF08\u6B62\u76C8\u6B62\u635F\u3001\u6761\u4EF6\u5355\u3001OCO\u7B49\uFF09\uFF0C\u5728\u6EE1\u8DB3\u6761\u4EF6\u65F6\u81EA\u52A8\u89E6\u53D1\u4E0B\u5355\n## \u573A\u666F\uFF1A\u7528\u4E8E\u8BBE\u7F6E\u6B62\u76C8\u6B62\u635F\u81EA\u52A8\u5E73\u4ED3\u3001\u5728\u4EF7\u683C\u7A81\u7834\u65F6\u81EA\u52A8\u5F00\u4ED3\u3001\u8BBE\u7F6EOCO\u4E8C\u9009\u4E00\u8BA2\u5355\n## \u5173\u952E\u8BCD\uFF1A\u4E0B\u7B56\u7565\u5355, place algo, \u6B62\u76C8\u6B62\u635F\u4E0B\u5355, \u6761\u4EF6\u5355, OCO\u4E0B\u5355, \u81EA\u52A8\u89E6\u53D1\n## \u53C2\u6570\uFF1A\n## - params: \u8BA2\u5355\u53C2\u6570\uFF08JSON\u5BF9\u8C61\uFF09\uFF0C\u53C2\u8003OKX\u6587\u6863\u3002\u542B instId/tdMode/side/ordType/sz/px \u53CA\u7B56\u7565\u53C2\u6570\u5982 slTriggerPx/tpTriggerPx\n## \u9274\u6743\uFF1A\u{1F534} \u9700\u8981 API Key\uFF08\u4EA4\u6613\uFF09- \u4F1A\u4EA7\u751F\u771F\u5B9E\u7B56\u7565\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u786E\u8BA4\n## \u98CE\u9669\uFF1AWRITE \u2014 \u521B\u5EFA\u7B56\u7565\u8BA2\u5355\uFF0C\u53EF\u80FD\u81EA\u52A8\u89E6\u53D1\u771F\u5B9E\u4EA4\u6613\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u786E\u8BA4\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~500B\n## \u5173\u8054\uFF1Aokx_get_algo_orders \u67E5\u770B\u5F53\u524D\u7B56\u7565 \u2192 \u672C\u5DE5\u5177\u4E0B\u7B56\u7565\u5355 \u2192 okx_get_algo_orders \u786E\u8BA4",
23952
23952
  { params: external_exports.record(external_exports.unknown()).describe("\u8BA2\u5355\u53C2\u6570\uFF0C\u53C2\u8003OKX\u6587\u6863") },
23953
23953
  async ({ params }) => {
23954
23954
  if (!auth) return toError(AUTH_REQUIRED);
@@ -23962,7 +23962,7 @@ function registerAlgoTools(server, auth) {
23962
23962
  );
23963
23963
  server.tool(
23964
23964
  "okx_cancel_algo_order",
23965
- "\u64A4\u9500\u7B56\u7565\u59D4\u6258\u5355\u3002\u26A0\uFE0F \u9700\u8981API Key\u9274\u6743\u3002",
23965
+ "## \u529F\u80FD\uFF1A\u64A4\u9500\u6307\u5B9A\u7684\u7B56\u7565\u59D4\u6258\u5355\n## \u573A\u666F\uFF1A\u7528\u4E8E\u53D6\u6D88\u4E0D\u518D\u9700\u8981\u7684\u6B62\u76C8\u6B62\u635F\u3001\u5173\u95ED\u6761\u4EF6\u5355\u3001\u8C03\u6574\u7B56\u7565\u524D\u5148\u64A4\u65E7\u5355\n## \u5173\u952E\u8BCD\uFF1A\u64A4\u9500\u7B56\u7565, cancel algo, \u53D6\u6D88\u6B62\u76C8\u6B62\u635F, \u64A4\u7B56\u7565\u5355, \u53D6\u6D88\u6761\u4EF6\u5355\n## \u53C2\u6570\uFF1A\n## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT\n## - algoId: \u7B56\u7565\u8BA2\u5355ID\uFF0C\u7531 okx_place_algo_order \u8FD4\u56DE\n## \u9274\u6743\uFF1A\u{1F534} \u9700\u8981 API Key\uFF08\u4EA4\u6613\uFF09- \u8C03\u7528\u524D\u987B\u5411\u7528\u6237\u786E\u8BA4\n## \u98CE\u9669\uFF1AWRITE \u2014 \u64A4\u9500\u7B56\u7565\u8BA2\u5355\uFF0C\u8C03\u7528\u524D\u5FC5\u987B\u5411\u7528\u6237\u786E\u8BA4\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~300B\n## \u5173\u8054\uFF1Aokx_get_algo_orders \u67E5\u770B\u7B56\u7565\u5217\u8868 \u2192 \u672C\u5DE5\u5177\u64A4\u9500 \u2192 okx_get_algo_orders_history \u786E\u8BA4\u64A4\u9500",
23966
23966
  {
23967
23967
  instId: external_exports.string().describe("\u4EA7\u54C1ID"),
23968
23968
  algoId: external_exports.string().describe("\u7B56\u7565\u8BA2\u5355ID")
@@ -27145,9 +27145,271 @@ function registerFiatTools(server, auth) {
27145
27145
  );
27146
27146
  }
27147
27147
 
27148
+ // src/tools/agent-utils.ts
27149
+ var fs = __toESM(require("node:fs"));
27150
+ var path = __toESM(require("node:path"));
27151
+ var os = __toESM(require("node:os"));
27152
+ function registerAgentUtils(server, auth) {
27153
+ server.tool(
27154
+ "okx_account_overview",
27155
+ '## \u529F\u80FD\uFF1A\u4E00\u952E\u83B7\u53D6\u8D26\u6237\u5168\u666F\uFF1A\u4F59\u989D\u3001\u6301\u4ED3\u3001\u914D\u7F6E\u3001\u603B\u4F30\u503C\uFF0C\u66FF\u4EE3\u4E32\u884C\u8C03\u7528 4 \u4E2A\u5DE5\u5177\n## \u573A\u666F\uFF1A\u7528\u4E8EAgent\u9996\u6B21\u4E86\u89E3\u7528\u6237\u8D26\u6237\u5168\u8C8C\u3001\u56DE\u7B54"\u6211\u8D26\u6237\u73B0\u5728\u4EC0\u4E48\u60C5\u51B5"\u3001\u6BCF\u65E5\u8D44\u4EA7\u6982\u89C8\n## \u5173\u952E\u8BCD\uFF1A\u8D26\u6237\u5168\u666F, \u8D26\u6237\u6982\u89C8, account overview, \u8D44\u4EA7\u5FEB\u7167, \u6301\u4ED3\u6C47\u603B, \u4E00\u952E\u67E5\u8D26\n## \u53C2\u6570\uFF1A\u65E0\n## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~3KB \u2014 \u7ED3\u6784\u5316\u6458\u8981\uFF0C\u975E\u539F\u59CBJSON\u5806\u780C\n## \u5173\u8054\uFF1A\u672C\u5DE5\u5177\u5168\u666F \u2192 okx_get_positions \u6DF1\u5165\u5355\u4ED3\u4F4D \u2192 okx_get_balance \u770B\u5404\u5E01\u79CD \u2192 okx_place_order \u4EA4\u6613',
27156
+ {},
27157
+ async () => {
27158
+ if (!auth) return toError(AUTH_REQUIRED);
27159
+ try {
27160
+ const [balance, positions, config2, valuation] = await Promise.allSettled([
27161
+ privateApi.getBalance(auth),
27162
+ privateApi.getPositions(auth),
27163
+ privateApi.getAccountConfig(auth),
27164
+ privateApi.getAssetValuation(auth)
27165
+ ]);
27166
+ const balanceData = balance.status === "fulfilled" ? balance.value : [];
27167
+ const totalEq = balanceData.length > 0 ? balanceData[0]?.totalEq : "N/A";
27168
+ const details = balanceData.length > 0 ? balanceData[0]?.details ?? [] : [];
27169
+ const nonZero = details.filter((d) => parseFloat(d.availBal || d.cashBal || "0") > 0);
27170
+ const balanceSummary = nonZero.map((d) => ({
27171
+ ccy: d.ccy,
27172
+ equity: d.eq ?? d.cashBal,
27173
+ avail: d.availBal ?? d.cashBal,
27174
+ frozen: d.frozenBal ?? "0",
27175
+ upl: d.upl
27176
+ }));
27177
+ const posData = positions.status === "fulfilled" ? positions.value : [];
27178
+ const activePositions = posData.filter(
27179
+ (p) => parseFloat(p.avgPx || "0") > 0 || parseFloat(p.pos || "0") !== 0
27180
+ );
27181
+ const posSummary = activePositions.map((p) => ({
27182
+ instId: p.instId,
27183
+ posSide: p.posSide,
27184
+ pos: p.pos,
27185
+ avgPx: p.avgPx,
27186
+ markPx: p.markPx,
27187
+ upl: p.upl,
27188
+ uplRatio: p.uplRatio,
27189
+ lever: p.lever,
27190
+ margin: p.margin,
27191
+ liqPx: p.liqPx
27192
+ }));
27193
+ const cfg = config2.status === "fulfilled" ? config2.value?.[0] ?? {} : {};
27194
+ const val = valuation.status === "fulfilled" ? valuation.value?.[0] ?? {} : {};
27195
+ const overview = {
27196
+ totalEquity: totalEq,
27197
+ totalValue: val.totalBal ?? "N/A",
27198
+ valuationCurrency: val.ccy ?? "USD",
27199
+ balance: {
27200
+ currencyCount: balanceSummary.length,
27201
+ currencies: balanceSummary.slice(0, 10)
27202
+ // top 10 非零币种
27203
+ },
27204
+ positions: {
27205
+ activeCount: posSummary.length,
27206
+ list: posSummary.slice(0, 20)
27207
+ // top 20
27208
+ },
27209
+ config: {
27210
+ acctLv: cfg.acctLv,
27211
+ posMode: cfg.posMode,
27212
+ autoLoan: cfg.autoLoan
27213
+ },
27214
+ errors: [
27215
+ balance.status === "rejected" ? `\u4F59\u989D\u67E5\u8BE2\u5931\u8D25: ${balance.reason?.message}` : null,
27216
+ positions.status === "rejected" ? `\u6301\u4ED3\u67E5\u8BE2\u5931\u8D25: ${positions.reason?.message}` : null,
27217
+ config2.status === "rejected" ? `\u914D\u7F6E\u67E5\u8BE2\u5931\u8D25: ${config2.reason?.message}` : null,
27218
+ valuation.status === "rejected" ? `\u4F30\u503C\u67E5\u8BE2\u5931\u8D25: ${valuation.reason?.message}` : null
27219
+ ].filter(Boolean)
27220
+ };
27221
+ return toResult(overview);
27222
+ } catch (e) {
27223
+ return toError(e);
27224
+ }
27225
+ }
27226
+ );
27227
+ server.tool(
27228
+ "okx_quick_market",
27229
+ '## \u529F\u80FD\uFF1A\u5355\u6B21\u8C03\u7528\u8FD4\u56DE\u6307\u5B9A\u4EA7\u54C1\u7684\u884C\u60C5+5\u6863\u6DF1\u5EA6+\u8D44\u91D1\u8D39\u7387+\u4EA7\u54C1\u89C4\u683C\u7684\u7ED3\u6784\u5316\u6458\u8981\n## \u573A\u666F\uFF1A\u7528\u4E8EAgent\u56DE\u7B54"\u73B0\u5728BTC\u4EC0\u4E48\u60C5\u51B5"\u65F6\u4E00\u6B21\u62FF\u5230\u5168\u90E8\u4FE1\u606F\u3001\u5FEB\u901F\u5224\u65AD\u4EA4\u6613\u65F6\u673A\n## \u5173\u952E\u8BCD\uFF1A\u5E02\u573A\u901F\u89C8, quick market, \u884C\u60C5+\u6DF1\u5EA6, \u4E00\u952E\u770B\u76D8, \u7EFC\u5408\u884C\u60C5, \u5E02\u573A\u6982\u51B5\n## \u53C2\u6570\uFF1A\n## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT\u3001ETH-USDT-SWAP\n## \u9274\u6743\uFF1APUBLIC \u2014 \u516C\u5F00\u63A5\u53E3\uFF0C\u4E0D\u9700\u8981 API Key\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~2KB \u2014 \u7CBE\u7B805\u6863\u6DF1\u5EA6\uFF0C\u975E\u5168\u91CF\u8BA2\u5355\u7C3F\n## \u5173\u8054\uFF1A\u672C\u5DE5\u5177\u901F\u89C8 \u2192 okx_get_candles \u6DF1\u5165K\u7EBF\u5206\u6790 \u2192 okx_get_orderbook \u770B\u5168\u6DF1\u5EA6 \u2192 okx_place_order \u4E0B\u5355',
27230
+ {
27231
+ instId: external_exports.string().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT\u3001ETH-USDT-SWAP")
27232
+ },
27233
+ async ({ instId }) => {
27234
+ try {
27235
+ const isSwap = instId.toUpperCase().includes("-SWAP");
27236
+ const isMargin = instId.toUpperCase().includes("MARGIN");
27237
+ const fetchers = [
27238
+ ["ticker", publicApi.getTicker(instId)],
27239
+ ["orderbook", publicApi.getOrderbook(instId, 5)]
27240
+ ];
27241
+ if (isSwap) {
27242
+ fetchers.push(["fundingRate", publicApi.getFundingRate(instId)]);
27243
+ }
27244
+ const keys = fetchers.map((f) => f[0]);
27245
+ const results = await Promise.allSettled(fetchers.map((f) => f[1]));
27246
+ const tickerIdx = keys.indexOf("ticker");
27247
+ const tickerRaw = results[tickerIdx]?.status === "fulfilled" ? results[tickerIdx].value : [];
27248
+ const tk = tickerRaw.length > 0 ? tickerRaw[0] : {};
27249
+ const obIdx = keys.indexOf("orderbook");
27250
+ const obRaw = results[obIdx]?.status === "fulfilled" ? results[obIdx].value : null;
27251
+ const obData = obRaw?.data?.[0] ?? obRaw;
27252
+ const asks = (obData?.asks ?? []).slice(0, 5);
27253
+ const bids = (obData?.bids ?? []).slice(0, 5);
27254
+ const spread = asks.length > 0 && bids.length > 0 ? (parseFloat(asks[0]?.[0] ?? "0") - parseFloat(bids[0]?.[0] ?? "0")).toFixed(2) : "N/A";
27255
+ let fundingRate = null;
27256
+ if (isSwap) {
27257
+ const frIdx = keys.indexOf("fundingRate");
27258
+ const frRaw = results[frIdx]?.status === "fulfilled" ? results[frIdx].value : [];
27259
+ const fr = frRaw.length > 0 ? frRaw[0] : {};
27260
+ fundingRate = {
27261
+ fundingRate: fr.fundingRate,
27262
+ nextFundingTime: fr.nextFundingTime ? new Date(parseInt(fr.nextFundingTime)).toISOString() : void 0
27263
+ };
27264
+ }
27265
+ const summary = {
27266
+ instId,
27267
+ productType: isSwap ? "\u6C38\u7EED\u5408\u7EA6" : isMargin ? "\u6760\u6746" : "\u73B0\u8D27/\u5176\u4ED6",
27268
+ ticker: {
27269
+ last: tk.last,
27270
+ bid: tk.bidPx,
27271
+ ask: tk.askPx,
27272
+ high24h: tk.high24h,
27273
+ low24h: tk.low24h,
27274
+ vol24h: tk.vol24h,
27275
+ change24h: tk.sodUtc8 ? `${tk.sodUtc8} (${tk.sodUtc0 ?? "-"}%)` : void 0
27276
+ },
27277
+ depth: {
27278
+ spread,
27279
+ top5Asks: asks.map((a) => ({ px: a[0], sz: a[1], orders: a[3] })),
27280
+ top5Bids: bids.map((b) => ({ px: b[0], sz: b[1], orders: b[3] }))
27281
+ },
27282
+ fundingRate,
27283
+ errors: results.map((r, i) => r.status === "rejected" ? `${keys[i]}\u5931\u8D25: ${r.reason?.message}` : null).filter(Boolean)
27284
+ };
27285
+ return toResult(summary);
27286
+ } catch (e) {
27287
+ return toError(e);
27288
+ }
27289
+ }
27290
+ );
27291
+ server.tool(
27292
+ "okx_preflight_check",
27293
+ "## \u529F\u80FD\uFF1A\u4E0B\u5355\u524D\u4E00\u6B21\u6027\u68C0\u67E5\uFF1A\u6700\u5927\u53EF\u5F00\u6570\u91CF\u3001\u9650\u4EF7\u8303\u56F4\u3001\u5408\u7EA6\u5F20\u6570\u6362\u7B97\u3001\u5F53\u524D\u4EF7\u683C\uFF0C\u907F\u514D\u4E0B\u5355\u540E\u62A5\u9519\n## \u573A\u666F\uFF1A\u7528\u4E8EAgent\u4E0B\u5355\u524D\u5FC5\u8C03\u3001\u9A8C\u8BC1\u7528\u6237\u8F93\u5165\u7684\u6570\u91CF\u548C\u4EF7\u683C\u662F\u5426\u5408\u6CD5\u3001\u907F\u514D\u56E0\u53C2\u6570\u9519\u8BEF\u88AB\u62D2\n## \u5173\u952E\u8BCD\uFF1A\u4E0B\u5355\u9884\u68C0, preflight, \u4E0B\u5355\u524D\u68C0\u67E5, \u6570\u91CF\u6362\u7B97, \u9650\u4EF7\u68C0\u67E5, \u53EF\u5F00\u68C0\u67E5\n## \u53C2\u6570\uFF1A\n## - instId: \u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B\n## - tdMode: \u4EA4\u6613\u6A21\u5F0F\u3002cash=\u73B0\u8D27, cross=\u5168\u4ED3, isolated=\u9010\u4ED3\u3002\u5FC5\u586B\n## - sz: \u7528\u6237\u60F3\u4E0B\u5355\u7684\u6570\u91CF\u3002\u5FC5\u586B\uFF08\u5E01\u6570\uFF0C\u4F1A\u81EA\u52A8\u6362\u7B97\u4E3A\u5F20\u6570\uFF09\n## - px: \u7528\u6237\u60F3\u4E0B\u5355\u7684\u4EF7\u683C\uFF08\u9009\u586B\uFF0C\u586B\u4E86\u4F1A\u68C0\u67E5\u662F\u5426\u5728\u9650\u4EF7\u8303\u56F4\u5185\uFF09\n## - side: \u4E70\u5356\u65B9\u5411\u3002buy=\u4E70\u5165, sell=\u5356\u51FA\u3002\u586B\u4E86\u4F1A\u67E5\u5BF9\u5E94\u65B9\u5411\u7684\u6700\u5927\u53EF\u5F00\n## - ordType: \u8BA2\u5355\u7C7B\u578B\u3002\u586B\u4E86\u4F1A\u68C0\u67E5\u662F\u5426\u5728\u9650\u4EF7\u8303\u56F4\u5185\uFF08\u9650\u4EF7\u5355\u624D\u9700\u8981\uFF09\n## \u9274\u6743\uFF1A\u26A0\uFE0F \u9700\u8981 API Key\uFF08\u53EA\u8BFB\uFF09- \u53EA\u67E5\u8BE2\u4E0D\u4EA7\u751F\u8BA2\u5355\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u67E5\u8BE2\uFF0CAgent \u53EF\u81EA\u52A8\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~1KB\n## \u5173\u8054\uFF1A\u672C\u5DE5\u5177\u9884\u68C0\u901A\u8FC7 \u2192 okx_place_order \u4E0B\u5355 \u2192 okx_get_order \u786E\u8BA4\u6210\u4EA4",
27294
+ {
27295
+ instId: external_exports.string().describe("\u4EA7\u54C1ID\uFF0C\u5982 BTC-USDT-SWAP\u3002\u5FC5\u586B"),
27296
+ tdMode: external_exports.enum(["cash", "cross", "isolated"]).describe("\u4EA4\u6613\u6A21\u5F0F\u3002cash=\u73B0\u8D27, cross=\u5168\u4ED3, isolated=\u9010\u4ED3"),
27297
+ sz: external_exports.string().describe("\u7528\u6237\u60F3\u4E0B\u5355\u7684\u6570\u91CF\uFF08\u5E01\u6570\uFF0C\u4F1A\u81EA\u52A8\u6362\u7B97\uFF09"),
27298
+ px: external_exports.string().optional().describe("\u7528\u6237\u60F3\u4E0B\u5355\u7684\u4EF7\u683C\uFF08\u9009\u586B\uFF09"),
27299
+ side: external_exports.enum(["buy", "sell"]).optional().describe("\u4E70\u5356\u65B9\u5411"),
27300
+ ordType: external_exports.enum(["market", "limit", "post_only", "fok", "ioc"]).optional().describe("\u8BA2\u5355\u7C7B\u578B")
27301
+ },
27302
+ async ({ instId, tdMode, sz, px, side, ordType }) => {
27303
+ if (!auth) return toError(AUTH_REQUIRED);
27304
+ try {
27305
+ const calls = [
27306
+ ["maxSize", privateApi.getMaxSize(auth, instId, tdMode)],
27307
+ ["priceLimit", publicApi.getPriceLimitBatch("", void 0, instId)],
27308
+ ["convertCoin", publicApi.convertContractCoin(instId, sz, "coin", "open")],
27309
+ ["ticker", publicApi.getTicker(instId)]
27310
+ ];
27311
+ const keys = calls.map((c) => c[0]);
27312
+ const results = await Promise.allSettled(calls.map((c) => c[1]));
27313
+ const get = (name) => {
27314
+ const idx = keys.indexOf(name);
27315
+ if (idx < 0) return null;
27316
+ return results[idx].status === "fulfilled" ? results[idx].value : null;
27317
+ };
27318
+ const maxSizeData = get("maxSize");
27319
+ const maxSz = maxSizeData?.[0];
27320
+ const limitData = get("priceLimit");
27321
+ const limit = limitData?.[0];
27322
+ const convertData = get("convertCoin");
27323
+ const converted = convertData?.[0];
27324
+ const tickerData = get("ticker");
27325
+ const tk = tickerData?.[0] ?? {};
27326
+ const checks = {
27327
+ instId,
27328
+ tdMode,
27329
+ userInput: { sz, px, side, ordType },
27330
+ currentPrice: {
27331
+ last: tk.last,
27332
+ bid: tk.bidPx,
27333
+ ask: tk.askPx
27334
+ },
27335
+ maxSize: maxSz ? {
27336
+ maxBuy: maxSz.maxBuy,
27337
+ maxSell: maxSz.maxSell,
27338
+ ccy: maxSz.ccy
27339
+ } : null,
27340
+ priceLimit: limit ? {
27341
+ highest: limit.highest,
27342
+ lowest: limit.lowest,
27343
+ pxWithinLimit: px ? parseFloat(px) >= parseFloat(limit.lowest ?? "0") && parseFloat(px) <= parseFloat(limit.highest ?? "Infinity") : null
27344
+ } : null,
27345
+ contractConversion: converted ? {
27346
+ fromCoin: sz,
27347
+ toContracts: converted.sz,
27348
+ unit: "contracts"
27349
+ } : null,
27350
+ warnings: [],
27351
+ errors: results.map((r, i) => r.status === "rejected" ? `${keys[i]}\u67E5\u8BE2\u5931\u8D25: ${r.reason?.message}` : null).filter(Boolean)
27352
+ };
27353
+ if (limit && px) {
27354
+ const lowest = parseFloat(limit.lowest ?? "0");
27355
+ const highest = parseFloat(limit.highest ?? "Infinity");
27356
+ const price = parseFloat(px);
27357
+ if (price < lowest) checks.warnings.push(`\u4EF7\u683C ${px} \u4F4E\u4E8E\u4E0B\u9650 ${limit.lowest}`);
27358
+ if (price > highest) checks.warnings.push(`\u4EF7\u683C ${px} \u9AD8\u4E8E\u4E0A\u9650 ${limit.highest}`);
27359
+ }
27360
+ if (maxSz && side) {
27361
+ const maxBuy = parseFloat(maxSz.maxBuy ?? "0");
27362
+ const maxSell = parseFloat(maxSz.maxSell ?? "0");
27363
+ const qty = parseFloat(sz);
27364
+ if (side === "buy" && qty > maxBuy) checks.warnings.push(`\u6570\u91CF ${sz} \u8D85\u8FC7\u6700\u5927\u53EF\u4E70 ${maxSz.maxBuy}`);
27365
+ if (side === "sell" && qty > maxSell) checks.warnings.push(`\u6570\u91CF ${sz} \u8D85\u8FC7\u6700\u5927\u53EF\u5356 ${maxSz.maxSell}`);
27366
+ }
27367
+ if (converted) {
27368
+ const contractSz = converted.sz;
27369
+ if (parseFloat(contractSz ?? "0") < 1) checks.warnings.push(`\u6362\u7B97\u540E\u5F20\u6570 ${contractSz} < 1\uFF0C\u53EF\u80FD\u65E0\u6CD5\u4E0B\u5355`);
27370
+ }
27371
+ checks.passed = checks.warnings.length === 0 && checks.errors.length === 0;
27372
+ return toResult(checks);
27373
+ } catch (e) {
27374
+ return toError(e);
27375
+ }
27376
+ }
27377
+ );
27378
+ server.tool(
27379
+ "okx_agent_feedback",
27380
+ "## \u529F\u80FD\uFF1A\u63D0\u4EA4\u4F7F\u7528\u53CD\u9988\u2014\u2014\u5F53\u4F60\u9047\u5230\u591A\u6B65\u64CD\u4F5C\u70E6\u7410\u3001\u53C2\u6570\u8BD5\u9519\u3001\u4E0D\u77E5\u9053\u8C03\u7528\u987A\u5E8F\u3001\u641C\u7D22\u4E0D\u5230\u5DE5\u5177\u3001\u6216\u9700\u8981\u4F7F\u7528\u624B\u5DE5\u8BA1\u7B97\u5F25\u8865\u4E0D\u8DB3\u65F6\uFF0C\u8C03\u7528\u6B64\u5DE5\u5177\u8BB0\u5F55\u4E0B\u6765\n## \u573A\u666F\uFF1A\u7528\u4E8EAgent\u6C47\u62A5MCP\u5DE5\u5177\u7684\u4F7F\u7528\u75DB\u70B9\uFF0C\u53CD\u9988\u5C06\u76F4\u63A5\u8FDB\u5165\u5F00\u53D1\u56E2\u961F\u7684\u5F85\u529E\u5217\u8868\uFF0C\u63A8\u52A8Skill\u7EC4\u5408\u548C\u5DE5\u5177\u4F18\u5316\n## \u5173\u952E\u8BCD\uFF1A\u53CD\u9988, feedback, \u7559\u8A00, \u5EFA\u8BAE, \u75DB\u70B9, \u6539\u5584\u5EFA\u8BAE\n## \u53C2\u6570\uFF1A\n## - title: \u4E00\u53E5\u8BDD\u6807\u9898\n## - what: \u4F60\u505A\u4E86\u4EC0\u4E48\u64CD\u4F5C\n## - tools: \u8C03\u7528\u4E86\u54EA\u4E9B\u5DE5\u5177\uFF08\u7528\u9017\u53F7\u5206\u9694\uFF09\n## - pain: \u75DB\u70B9\u662F\u4EC0\u4E48\n## - suggestion: \u4F60\u5EFA\u8BAE\u600E\u4E48\u6539\u5584\uFF08\u60F3\u8981\u4EC0\u4E48Skill\uFF09\n## \u9274\u6743\uFF1APUBLIC \u2014 \u65E0\u9700 API Key\uFF0C\u8C01\u90FD\u53EF\u4EE5\u53CD\u9988\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u5199\u65E5\u5FD7\uFF0CAgent \u53EF\u968F\u65F6\u8C03\u7528\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~200B\n## \u5173\u8054\uFF1A\u4EFB\u4F55\u5DE5\u5177\u7EC4\u5408\u9047\u5230\u963B\u788D\u65F6\u8C03\u7528 \u2192 \u5F00\u53D1\u8005\u5BA1\u67E5\u53CD\u9988 \u2192 \u521B\u5EFA Skill \u6216\u4F18\u5316\u5DE5\u5177",
27381
+ {
27382
+ title: external_exports.string().describe("\u4E00\u53E5\u8BDD\u6807\u9898"),
27383
+ what: external_exports.string().describe("\u4F60\u505A\u4E86\u4EC0\u4E48\u64CD\u4F5C"),
27384
+ tools: external_exports.string().describe("\u8C03\u7528\u4E86\u54EA\u4E9B\u5DE5\u5177\uFF0C\u7528\u9017\u53F7\u5206\u9694"),
27385
+ pain: external_exports.string().describe("\u75DB\u70B9\u662F\u4EC0\u4E48"),
27386
+ suggestion: external_exports.string().describe("\u4F60\u5EFA\u8BAE\u600E\u4E48\u6539\u5584\uFF0C\u60F3\u8981\u4EC0\u4E48 Skill")
27387
+ },
27388
+ async ({ title, what, tools, pain, suggestion }) => {
27389
+ try {
27390
+ const logDir = process.env.OKX_FEEDBACK_DIR || os.homedir();
27391
+ const logFile = path.join(logDir, "hvip-mcp-feedback.log");
27392
+ const entry = JSON.stringify({
27393
+ time: (/* @__PURE__ */ new Date()).toISOString(),
27394
+ title,
27395
+ what,
27396
+ tools,
27397
+ pain,
27398
+ suggestion,
27399
+ host: os.hostname()
27400
+ }) + "\n";
27401
+ fs.appendFileSync(logFile, entry, "utf-8");
27402
+ return toResult({ ok: true, saved: logFile, message: "\u53CD\u9988\u5DF2\u8BB0\u5F55\uFF0C\u611F\u8C22\uFF01" });
27403
+ } catch (e) {
27404
+ return toError(e);
27405
+ }
27406
+ }
27407
+ );
27408
+ }
27409
+
27148
27410
  // src/index.ts
27149
27411
  async function main() {
27150
- const server = new McpServer({ name: "hvip", version: "0.2.1" });
27412
+ const server = new McpServer({ name: "hvip", version: "0.2.35" });
27151
27413
  const auth = getAuth();
27152
27414
  registerMarketTools(server);
27153
27415
  registerPublicTools(server, auth);
@@ -27166,6 +27428,7 @@ async function main() {
27166
27428
  registerAffiliateTools(server, auth);
27167
27429
  registerFiatTools(server, auth);
27168
27430
  registerRfqTools(server, auth);
27431
+ registerAgentUtils(server, auth);
27169
27432
  const transport = new StdioServerTransport();
27170
27433
  await server.connect(transport);
27171
27434
  }
package/package.json CHANGED
@@ -1,41 +1,41 @@
1
- {
2
- "name": "hvip-mcp-server",
3
- "version": "0.2.34",
4
- "description": "OKX ecosystem MCP server - full API coverage for AI agents",
5
- "homepage": "https://hvip.one",
6
- "license": "MIT",
7
- "bin": {
8
- "hvip-mcp": "dist/index.js"
9
- },
10
- "files": [
11
- "dist/index.js"
12
- ],
13
- "scripts": {
14
- "build": "node build.mjs",
15
- "dev": "tsx watch src/index.ts",
16
- "start": "node dist/index.js",
17
- "verify": "tsx tests/verify.mts",
18
- "test": "vitest run",
19
- "test:watch": "vitest",
20
- "lint": "eslint src",
21
- "typecheck": "tsc --noEmit"
22
- },
23
- "dependencies": {
24
- "@modelcontextprotocol/sdk": "^1.12.0",
25
- "dotenv": "^16.4.0",
26
- "zod": "^3.23.0"
27
- },
28
- "devDependencies": {
29
- "@types/node": "^22.0.0",
30
- "@typescript-eslint/eslint-plugin": "^8.0.0",
31
- "@typescript-eslint/parser": "^8.0.0",
32
- "esbuild": "^0.28.0",
33
- "eslint": "^9.0.0",
34
- "tsx": "^4.16.0",
35
- "typescript": "^5.5.0",
36
- "vitest": "^2.0.0"
37
- },
38
- "engines": {
39
- "node": ">=20"
40
- }
41
- }
1
+ {
2
+ "name": "hvip-mcp-server",
3
+ "version": "0.2.38",
4
+ "description": "OKX ecosystem MCP server - full API coverage for AI agents",
5
+ "homepage": "https://hvip.one",
6
+ "license": "MIT",
7
+ "bin": {
8
+ "hvip-mcp": "dist/index.js"
9
+ },
10
+ "files": [
11
+ "dist/index.js"
12
+ ],
13
+ "scripts": {
14
+ "build": "node build.mjs",
15
+ "dev": "tsx watch src/index.ts",
16
+ "start": "node dist/index.js",
17
+ "verify": "tsx tests/verify.mts",
18
+ "test": "vitest run",
19
+ "test:watch": "vitest",
20
+ "lint": "eslint src",
21
+ "typecheck": "tsc --noEmit"
22
+ },
23
+ "dependencies": {
24
+ "@modelcontextprotocol/sdk": "^1.12.0",
25
+ "dotenv": "^16.4.0",
26
+ "zod": "^3.23.0"
27
+ },
28
+ "devDependencies": {
29
+ "@types/node": "^22.0.0",
30
+ "@typescript-eslint/eslint-plugin": "^8.0.0",
31
+ "@typescript-eslint/parser": "^8.0.0",
32
+ "esbuild": "^0.28.0",
33
+ "eslint": "^9.0.0",
34
+ "tsx": "^4.16.0",
35
+ "typescript": "^5.5.0",
36
+ "vitest": "^2.0.0"
37
+ },
38
+ "engines": {
39
+ "node": ">=20"
40
+ }
41
+ }