hvip-mcp-server 0.2.47 → 0.2.49

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 +382 -51
  2. package/package.json +2 -2
package/dist/index.js CHANGED
@@ -2984,7 +2984,7 @@ var require_compile = __commonJS({
2984
2984
  const schOrFunc = root.refs[ref];
2985
2985
  if (schOrFunc)
2986
2986
  return schOrFunc;
2987
- let _sch = resolve.call(this, root, ref);
2987
+ let _sch = resolve2.call(this, root, ref);
2988
2988
  if (_sch === void 0) {
2989
2989
  const schema = (_a = root.localRefs) === null || _a === void 0 ? void 0 : _a[ref];
2990
2990
  const { schemaId } = this.opts;
@@ -3011,7 +3011,7 @@ var require_compile = __commonJS({
3011
3011
  function sameSchemaEnv(s1, s2) {
3012
3012
  return s1.schema === s2.schema && s1.root === s2.root && s1.baseId === s2.baseId;
3013
3013
  }
3014
- function resolve(root, ref) {
3014
+ function resolve2(root, ref) {
3015
3015
  let sch;
3016
3016
  while (typeof (sch = this.refs[ref]) == "string")
3017
3017
  ref = sch;
@@ -3229,8 +3229,8 @@ var require_utils = __commonJS({
3229
3229
  }
3230
3230
  return ind;
3231
3231
  }
3232
- function removeDotSegments(path2) {
3233
- let input = path2;
3232
+ function removeDotSegments(path3) {
3233
+ let input = path3;
3234
3234
  const output = [];
3235
3235
  let nextSlash = -1;
3236
3236
  let len = 0;
@@ -3482,8 +3482,8 @@ var require_schemes = __commonJS({
3482
3482
  wsComponent.secure = void 0;
3483
3483
  }
3484
3484
  if (wsComponent.resourceName) {
3485
- const [path2, query] = wsComponent.resourceName.split("?");
3486
- wsComponent.path = path2 && path2 !== "/" ? path2 : void 0;
3485
+ const [path3, query] = wsComponent.resourceName.split("?");
3486
+ wsComponent.path = path3 && path3 !== "/" ? path3 : void 0;
3487
3487
  wsComponent.query = query;
3488
3488
  wsComponent.resourceName = void 0;
3489
3489
  }
@@ -3642,7 +3642,7 @@ var require_fast_uri = __commonJS({
3642
3642
  }
3643
3643
  return uri;
3644
3644
  }
3645
- function resolve(baseURI, relativeURI, options) {
3645
+ function resolve2(baseURI, relativeURI, options) {
3646
3646
  const schemelessOptions = options ? Object.assign({ scheme: "null" }, options) : { scheme: "null" };
3647
3647
  const resolved = resolveComponent(parse3(baseURI, schemelessOptions), parse3(relativeURI, schemelessOptions), schemelessOptions, true);
3648
3648
  schemelessOptions.skipEscape = true;
@@ -3900,7 +3900,7 @@ var require_fast_uri = __commonJS({
3900
3900
  var fastUri = {
3901
3901
  SCHEMES,
3902
3902
  normalize,
3903
- resolve,
3903
+ resolve: resolve2,
3904
3904
  resolveComponent,
3905
3905
  equal,
3906
3906
  serialize,
@@ -6876,12 +6876,12 @@ var require_dist = __commonJS({
6876
6876
  throw new Error(`Unknown format "${name}"`);
6877
6877
  return f;
6878
6878
  };
6879
- function addFormats(ajv, list, fs2, exportName) {
6879
+ function addFormats(ajv, list, fs3, exportName) {
6880
6880
  var _a;
6881
6881
  var _b;
6882
6882
  (_a = (_b = ajv.opts.code).formats) !== null && _a !== void 0 ? _a : _b.formats = (0, codegen_1._)`require("ajv-formats/dist/formats").${exportName}`;
6883
6883
  for (const f of list)
6884
- ajv.addFormat(f, fs2[f]);
6884
+ ajv.addFormat(f, fs3[f]);
6885
6885
  }
6886
6886
  module2.exports = exports2 = formatsPlugin;
6887
6887
  Object.defineProperty(exports2, "__esModule", { value: true });
@@ -11077,8 +11077,8 @@ function getErrorMap() {
11077
11077
 
11078
11078
  // node_modules/zod/v3/helpers/parseUtil.js
11079
11079
  var makeIssue = (params) => {
11080
- const { data, path: path2, errorMaps, issueData } = params;
11081
- const fullPath = [...path2, ...issueData.path || []];
11080
+ const { data, path: path3, errorMaps, issueData } = params;
11081
+ const fullPath = [...path3, ...issueData.path || []];
11082
11082
  const fullIssue = {
11083
11083
  ...issueData,
11084
11084
  path: fullPath
@@ -11194,11 +11194,11 @@ var errorUtil;
11194
11194
 
11195
11195
  // node_modules/zod/v3/types.js
11196
11196
  var ParseInputLazyPath = class {
11197
- constructor(parent, value, path2, key) {
11197
+ constructor(parent, value, path3, key) {
11198
11198
  this._cachedPath = [];
11199
11199
  this.parent = parent;
11200
11200
  this.data = value;
11201
- this._path = path2;
11201
+ this._path = path3;
11202
11202
  this._key = key;
11203
11203
  }
11204
11204
  get path() {
@@ -14835,10 +14835,10 @@ function assignProp(target, prop, value) {
14835
14835
  configurable: true
14836
14836
  });
14837
14837
  }
14838
- function getElementAtPath(obj, path2) {
14839
- if (!path2)
14838
+ function getElementAtPath(obj, path3) {
14839
+ if (!path3)
14840
14840
  return obj;
14841
- return path2.reduce((acc, key) => acc?.[key], obj);
14841
+ return path3.reduce((acc, key) => acc?.[key], obj);
14842
14842
  }
14843
14843
  function promiseAllObject(promisesObj) {
14844
14844
  const keys = Object.keys(promisesObj);
@@ -15158,11 +15158,11 @@ function aborted(x, startIndex = 0) {
15158
15158
  }
15159
15159
  return false;
15160
15160
  }
15161
- function prefixIssues(path2, issues) {
15161
+ function prefixIssues(path3, issues) {
15162
15162
  return issues.map((iss) => {
15163
15163
  var _a;
15164
15164
  (_a = iss).path ?? (_a.path = []);
15165
- iss.path.unshift(path2);
15165
+ iss.path.unshift(path3);
15166
15166
  return iss;
15167
15167
  });
15168
15168
  }
@@ -22692,7 +22692,7 @@ var Protocol = class {
22692
22692
  return;
22693
22693
  }
22694
22694
  const pollInterval = task2.pollInterval ?? this._options?.defaultTaskPollInterval ?? 1e3;
22695
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
22695
+ await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
22696
22696
  options?.signal?.throwIfAborted();
22697
22697
  }
22698
22698
  } catch (error2) {
@@ -22709,7 +22709,7 @@ var Protocol = class {
22709
22709
  */
22710
22710
  request(request3, resultSchema, options) {
22711
22711
  const { relatedRequestId, resumptionToken, onresumptiontoken, task, relatedTask } = options ?? {};
22712
- return new Promise((resolve, reject) => {
22712
+ return new Promise((resolve2, reject) => {
22713
22713
  const earlyReject = (error2) => {
22714
22714
  reject(error2);
22715
22715
  };
@@ -22787,7 +22787,7 @@ var Protocol = class {
22787
22787
  if (!parseResult.success) {
22788
22788
  reject(parseResult.error);
22789
22789
  } else {
22790
- resolve(parseResult.data);
22790
+ resolve2(parseResult.data);
22791
22791
  }
22792
22792
  } catch (error2) {
22793
22793
  reject(error2);
@@ -23048,12 +23048,12 @@ var Protocol = class {
23048
23048
  }
23049
23049
  } catch {
23050
23050
  }
23051
- return new Promise((resolve, reject) => {
23051
+ return new Promise((resolve2, reject) => {
23052
23052
  if (signal.aborted) {
23053
23053
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
23054
23054
  return;
23055
23055
  }
23056
- const timeoutId = setTimeout(resolve, interval);
23056
+ const timeoutId = setTimeout(resolve2, interval);
23057
23057
  signal.addEventListener("abort", () => {
23058
23058
  clearTimeout(timeoutId);
23059
23059
  reject(new McpError(ErrorCode.InvalidRequest, "Request cancelled"));
@@ -24153,7 +24153,7 @@ var McpServer = class {
24153
24153
  let task = createTaskResult.task;
24154
24154
  const pollInterval = task.pollInterval ?? 5e3;
24155
24155
  while (task.status !== "completed" && task.status !== "failed" && task.status !== "cancelled") {
24156
- await new Promise((resolve) => setTimeout(resolve, pollInterval));
24156
+ await new Promise((resolve2) => setTimeout(resolve2, pollInterval));
24157
24157
  const updatedTask = await extra.taskStore.getTask(taskId);
24158
24158
  if (!updatedTask) {
24159
24159
  throw new McpError(ErrorCode.InternalError, `Task ${taskId} not found during polling`);
@@ -24802,12 +24802,12 @@ var StdioServerTransport = class {
24802
24802
  this.onclose?.();
24803
24803
  }
24804
24804
  send(message) {
24805
- return new Promise((resolve) => {
24805
+ return new Promise((resolve2) => {
24806
24806
  const json = serializeMessage(message);
24807
24807
  if (this._stdout.write(json)) {
24808
- resolve();
24808
+ resolve2();
24809
24809
  } else {
24810
- this._stdout.once("drain", resolve);
24810
+ this._stdout.once("drain", resolve2);
24811
24811
  }
24812
24812
  });
24813
24813
  }
@@ -25306,7 +25306,7 @@ var responseViaResponseObject = async (res, outgoing, options = {}) => {
25306
25306
  });
25307
25307
  if (!chunk) {
25308
25308
  if (i === 1) {
25309
- await new Promise((resolve) => setTimeout(resolve));
25309
+ await new Promise((resolve2) => setTimeout(resolve2));
25310
25310
  maxReadCount = 3;
25311
25311
  continue;
25312
25312
  }
@@ -25806,9 +25806,9 @@ data:
25806
25806
  const initRequest = messages.find((m) => isInitializeRequest(m));
25807
25807
  const clientProtocolVersion = initRequest ? initRequest.params.protocolVersion : req.headers.get("mcp-protocol-version") ?? DEFAULT_NEGOTIATED_PROTOCOL_VERSION;
25808
25808
  if (this._enableJsonResponse) {
25809
- return new Promise((resolve) => {
25809
+ return new Promise((resolve2) => {
25810
25810
  this._streamMapping.set(streamId, {
25811
- resolveJson: resolve,
25811
+ resolveJson: resolve2,
25812
25812
  cleanup: () => {
25813
25813
  this._streamMapping.delete(streamId);
25814
25814
  }
@@ -26141,8 +26141,8 @@ var StreamableHTTPServerTransport = class {
26141
26141
  // src/adapters/okx.ts
26142
26142
  var import_node_crypto = __toESM(require("node:crypto"));
26143
26143
  var BASE = "https://www.okx.com";
26144
- function sign(ts, method, path2, body, secret) {
26145
- const msg = ts + method + path2 + body;
26144
+ function sign(ts, method, path3, body, secret) {
26145
+ const msg = ts + method + path3 + body;
26146
26146
  return import_node_crypto.default.createHmac("sha256", secret).update(msg).digest("base64");
26147
26147
  }
26148
26148
  function timestamp() {
@@ -26155,9 +26155,9 @@ function buildQuery(params) {
26155
26155
  }
26156
26156
  return p.size ? "?" + p.toString() : "";
26157
26157
  }
26158
- async function request(method, path2, options = {}) {
26158
+ async function request(method, path3, options = {}) {
26159
26159
  const query = options.params ? buildQuery(options.params) : "";
26160
- const fullPath = path2 + query;
26160
+ const fullPath = path3 + query;
26161
26161
  const bodyStr = options.body ? JSON.stringify(options.body) : "";
26162
26162
  const headers = {
26163
26163
  "Content-Type": "application/json",
@@ -26546,12 +26546,12 @@ var privateApi = {
26546
26546
 
26547
26547
  // src/adapters/hrails.ts
26548
26548
  var DEFAULT_BASE = "https://api-staging.hwallet.vip";
26549
- async function request2(path2, params = {}, apiKey, base) {
26549
+ async function request2(path3, params = {}, apiKey, base) {
26550
26550
  const filtered = Object.entries(params).filter(([, v]) => v !== void 0 && v !== "");
26551
26551
  const p = new URLSearchParams();
26552
26552
  for (const [k, v] of filtered) p.append(k, String(v));
26553
26553
  const query = p.size ? "?" + p.toString() : "";
26554
- const res = await fetch(base + path2 + query, {
26554
+ const res = await fetch(base + path3 + query, {
26555
26555
  headers: {
26556
26556
  "Accept": "application/json",
26557
26557
  "Authorization": `Bearer ${apiKey}`
@@ -26563,7 +26563,7 @@ async function request2(path2, params = {}, apiKey, base) {
26563
26563
  return json.data ?? json;
26564
26564
  }
26565
26565
  function createHRailsClient(apiKey, baseUrl = DEFAULT_BASE) {
26566
- const get = (path2, params) => request2(path2, params, apiKey, baseUrl);
26566
+ const get = (path3, params) => request2(path3, params, apiKey, baseUrl);
26567
26567
  return {
26568
26568
  health: () => fetch(baseUrl + "/health").then((r) => r.json()),
26569
26569
  listEvents: (params) => {
@@ -33779,6 +33779,16 @@ function registerAgentUtils(server, auth) {
33779
33779
  ],
33780
33780
  risk: "READ"
33781
33781
  },
33782
+ {
33783
+ domain: "\u4EE3\u7801\u667A\u80FD",
33784
+ what: "\u67E5\u8BE2 hvip-mcp \u81EA\u8EAB\u4EE3\u7801\u7ED3\u6784\uFF1A\u51FD\u6570\u8C03\u7528\u94FE\u3001\u6A21\u5757\u4F9D\u8D56\u3001\u7B26\u53F7\u641C\u7D22",
33785
+ when: ["\u4EE3\u7801\u7ED3\u6784", "\u8C03\u7528\u94FE", "\u8C01\u8C03\u7528\u4E86", "\u8C01\u88AB\u8C03\u7528", "\u4F9D\u8D56\u5173\u7CFB", "\u4E0A\u4E0B\u6E38", "\u4EE3\u7801\u641C\u7D22"],
33786
+ go_to: "codegraph_status",
33787
+ also: [
33788
+ "codegraph_query \u2014 \u8C03\u7528\u94FE\u8FFD\u8E2A (callers/callees/explore/files)"
33789
+ ],
33790
+ risk: "READ"
33791
+ },
33782
33792
  {
33783
33793
  domain: "\u7CFB\u7EDF\u5DE5\u5177",
33784
33794
  what: "\u504F\u597D\u8BBE\u7F6E\u3001\u53CD\u9988\u7559\u8A00\u3001Agent\u96C6\u7FA4\u7BA1\u7406",
@@ -34061,6 +34071,13 @@ function registerAgentUtils(server, auth) {
34061
34071
  { name: "okx_position_builder", auth: "API Key (\u4EA4\u6613)", params: "body(JSON)", what: "\u7EC4\u5408\u4FDD\u8BC1\u91D1\u8BD5\u7B97 \u2014 WRITE" }
34062
34072
  ]
34063
34073
  },
34074
+ "\u4EE3\u7801\u667A\u80FD": {
34075
+ workflow: "codegraph_status \u770B\u72B6\u6001 \u2192 codegraph_query \u8FFD\u8E2A\u8C03\u7528\u94FE/\u641C\u7D22\u7B26\u53F7 \u2192 \u7528 Read \u770B\u6E90\u7801\u7EC6\u8282",
34076
+ tools: [
34077
+ { name: "codegraph_status", auth: "\u516C\u5F00", params: "\u65E0", what: "\u77E5\u8BC6\u56FE\u8C31\u72B6\u6001\uFF1A\u8282\u70B9\u6570/\u8FB9\u6570/\u8986\u76D6\u6587\u4EF6/\u6700\u540E\u7D22\u5F15" },
34078
+ { name: "codegraph_query", auth: "\u516C\u5F00", params: "mode (callers|callees|explore|files), symbol?, question?, limit?", what: "\u67E5\u8BE2\u8C03\u7528\u94FE / \u7B26\u53F7\u641C\u7D22 / \u6A21\u5757\u4F9D\u8D56 / \u6309\u6587\u4EF6\u67E5" }
34079
+ ]
34080
+ },
34064
34081
  "\u7CFB\u7EDF\u5DE5\u5177": {
34065
34082
  workflow: "\u6309\u9700\u8C03\u7528\uFF0C\u5404\u5DE5\u5177\u72EC\u7ACB",
34066
34083
  tools: [
@@ -34086,7 +34103,7 @@ function registerAgentUtils(server, auth) {
34086
34103
  "agent_catalog_detail",
34087
34104
  "CAT:[\u7CFB\u7EDF] | ## \u529F\u80FD\uFF1A\u67E5\u770B\u67D0\u4E2A\u4E1A\u52A1\u57DF\u7684\u8BE6\u7EC6\u5DE5\u5177\u6E05\u5355\u2014\u2014\u542B\u6BCF\u4E2A\u5DE5\u5177\u7684\u53C2\u6570\u63D0\u793A\u3001\u9274\u6743\u8981\u6C42\u3001\u63A8\u8350\u8C03\u7528\u987A\u5E8F\n## \u573A\u666F\uFF1AAgent \u5728 agent_catalog \u786E\u5B9A\u57DF\u540E\uFF0C\u8C03\u7528\u6B64\u5DE5\u5177\u83B7\u53D6\u8BE5\u57DF\u6240\u6709\u5DE5\u5177\u7684\u7CBE\u51C6\u4FE1\u606F\u3001\u53C2\u6570\u63D0\u793A\u548C\u5178\u578B workflow\n## \u5173\u952E\u8BCD\uFF1A\u76EE\u5F55\u8BE6\u60C5, catalog detail, \u5DE5\u5177\u6E05\u5355, \u57DF\u8BE6\u60C5, workflow\n## \u53C2\u6570\uFF1A\n## - domain: \u57DF\u540D\u79F0\u3002\u53EF\u53D6\u503C: \u8D26\u6237\u8D44\u4EA7 | \u884C\u60C5\u770B\u76D8 | \u4E0B\u5355\u4EA4\u6613 | \u98CE\u9669\u98CE\u63A7 | \u5E02\u573A\u626B\u63CF | \u76C8\u4E8F\u590D\u76D8 | \u8D44\u91D1\u7BA1\u7406 | \u7B56\u7565\u4EA4\u6613 | \u9884\u6D4B\u5E02\u573A | WebSocket \u5B9E\u65F6 | \u6A21\u62DF\u4F30\u7B97 | \u7CFB\u7EDF\u5DE5\u5177\n## \u9274\u6743\uFF1APUBLIC \u2014 \u7EAF\u7D22\u5F15\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~2KB \u2014 \u5355\u57DF\u8BE6\u60C5\n## \u5173\u8054\uFF1Aagent_catalog \u9009\u57DF \u2192 \u672C\u5DE5\u5177\u83B7\u53D6\u8BE6\u60C5 \u2192 \u76F4\u63A5\u8C03\u7528\u76EE\u6807\u5DE5\u5177",
34088
34105
  {
34089
- domain: external_exports.string().describe("\u57DF\u540D\u79F0\u3002\u53EF\u9009: \u8D26\u6237\u8D44\u4EA7, \u884C\u60C5\u770B\u76D8, \u6280\u672F\u6307\u6807, \u4E0B\u5355\u4EA4\u6613, \u98CE\u9669\u98CE\u63A7, \u5E02\u573A\u626B\u63CF, \u806A\u660E\u94B1, \u76C8\u4E8F\u590D\u76D8, \u8D44\u91D1\u7BA1\u7406, \u7B56\u7565\u4EA4\u6613, \u9884\u6D4B\u5E02\u573A, WebSocket \u5B9E\u65F6, \u6A21\u62DF\u4F30\u7B97, \u7CFB\u7EDF\u5DE5\u5177")
34106
+ domain: external_exports.string().describe("\u57DF\u540D\u79F0\u3002\u53EF\u9009: \u8D26\u6237\u8D44\u4EA7, \u884C\u60C5\u770B\u76D8, \u6280\u672F\u6307\u6807, \u4E0B\u5355\u4EA4\u6613, \u98CE\u9669\u98CE\u63A7, \u5E02\u573A\u626B\u63CF, \u806A\u660E\u94B1, \u76C8\u4E8F\u590D\u76D8, \u8D44\u91D1\u7BA1\u7406, \u7B56\u7565\u4EA4\u6613, \u9884\u6D4B\u5E02\u573A, \u4EE3\u7801\u667A\u80FD, WebSocket \u5B9E\u65F6, \u6A21\u62DF\u4F30\u7B97, \u7CFB\u7EDF\u5DE5\u5177")
34090
34107
  },
34091
34108
  async ({ domain }) => {
34092
34109
  try {
@@ -35007,7 +35024,7 @@ var XLayerWSManager = class {
35007
35024
  async connect() {
35008
35025
  if (this.ws?.readyState === wrapper_default.OPEN) return;
35009
35026
  if (this.connectPromise) return this.connectPromise;
35010
- this.connectPromise = new Promise((resolve, reject) => {
35027
+ this.connectPromise = new Promise((resolve2, reject) => {
35011
35028
  const ws = new wrapper_default(WS_URL);
35012
35029
  ws.on("open", () => {
35013
35030
  this.ws = ws;
@@ -35015,7 +35032,7 @@ var XLayerWSManager = class {
35015
35032
  this.pingTimer = setInterval(() => {
35016
35033
  if (ws.readyState === wrapper_default.OPEN) ws.ping();
35017
35034
  }, 3e4);
35018
- resolve();
35035
+ resolve2();
35019
35036
  });
35020
35037
  ws.on("message", (raw) => {
35021
35038
  try {
@@ -35068,12 +35085,12 @@ var XLayerWSManager = class {
35068
35085
  await this.connect();
35069
35086
  const ws = this.ws;
35070
35087
  const id = ++this.idCounter;
35071
- return new Promise((resolve, reject) => {
35088
+ return new Promise((resolve2, reject) => {
35072
35089
  const timer = setTimeout(() => {
35073
35090
  this.pending.delete(id);
35074
35091
  reject(new Error(`RPC \u8C03\u7528\u8D85\u65F6: ${method}`));
35075
35092
  }, 3e4);
35076
- this.pending.set(id, { resolve, reject, timer });
35093
+ this.pending.set(id, { resolve: resolve2, reject, timer });
35077
35094
  ws.send(JSON.stringify({ jsonrpc: "2.0", id, method, params }));
35078
35095
  });
35079
35096
  }
@@ -35334,7 +35351,7 @@ var WsManager = class {
35334
35351
  return count;
35335
35352
  }
35336
35353
  connect(wsModule, url, auth) {
35337
- return new Promise((resolve, reject) => {
35354
+ return new Promise((resolve2, reject) => {
35338
35355
  const ws = new wsModule.WebSocket(url);
35339
35356
  const timeout = setTimeout(() => {
35340
35357
  ws.close();
@@ -35359,7 +35376,7 @@ var WsManager = class {
35359
35376
  if (ws.readyState === wsModule.WebSocket.OPEN) ws.send("ping");
35360
35377
  }, 25e3);
35361
35378
  this.ws = ws;
35362
- resolve();
35379
+ resolve2();
35363
35380
  });
35364
35381
  ws.on("message", (raw) => {
35365
35382
  try {
@@ -36068,6 +36085,317 @@ function registerAgentHubTools(server) {
36068
36085
  );
36069
36086
  }
36070
36087
 
36088
+ // src/tools/codegraph.ts
36089
+ var path2 = __toESM(require("node:path"));
36090
+ var fs2 = __toESM(require("node:fs"));
36091
+ var DatabaseSync = null;
36092
+ function getDB() {
36093
+ if (DatabaseSync === null) {
36094
+ try {
36095
+ const sqlite = require("node:sqlite");
36096
+ DatabaseSync = sqlite.DatabaseSync;
36097
+ } catch {
36098
+ return null;
36099
+ }
36100
+ }
36101
+ const dbPath = path2.resolve(".codegraph", "codegraph.db");
36102
+ if (!fs2.existsSync(dbPath)) {
36103
+ return null;
36104
+ }
36105
+ try {
36106
+ const db = new DatabaseSync(dbPath, { readonly: true });
36107
+ db.prepare("SELECT 1").get();
36108
+ return { db };
36109
+ } catch (e) {
36110
+ return null;
36111
+ }
36112
+ }
36113
+ function registerCodeGraphTools(server) {
36114
+ server.tool(
36115
+ "codegraph_status",
36116
+ "CAT:[\u4EE3\u7801\u667A\u80FD] | ## \u529F\u80FD\uFF1A\u68C0\u67E5\u4EE3\u7801\u77E5\u8BC6\u56FE\u8C31\u72B6\u6001\u2014\u2014\u8282\u70B9\u6570\u3001\u8FB9\u6570\u3001\u8986\u76D6\u6587\u4EF6\u3001\u6700\u540E\u7D22\u5F15\u65F6\u95F4\n## \u573A\u666F\uFF1AAgent \u9996\u6B21\u8FDE\u63A5\u65F6\u8C03\u7528\uFF0C\u4E86\u89E3\u4EE3\u7801\u56FE\u8C31\u662F\u5426\u5C31\u7EEA\uFF1B\u6216\u7528\u6237\u95EE\u300C\u4EE3\u7801\u7ED3\u6784\u80FD\u67E5\u5417\u300D\u65F6\u786E\u8BA4\u72B6\u6001\n## \u5173\u952E\u8BCD\uFF1A\u4EE3\u7801\u56FE\u8C31, codegraph, \u77E5\u8BC6\u56FE\u8C31, \u4EE3\u7801\u7ED3\u6784, \u7D22\u5F15\u72B6\u6001\n## \u53C2\u6570\uFF1A\u65E0\n## \u9274\u6743\uFF1APUBLIC \u2014 \u672C\u5730\u53EA\u8BFB\uFF0C\u4E0D\u67E5\u5916\u90E8 API\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\u672C\u5730\u6587\u4EF6\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~500B\n## \u5173\u8054\uFF1A\u672C\u5DE5\u5177\u786E\u8BA4\u72B6\u6001 \u2192 codegraph_query \u67E5\u8BE2 \u2192 \u83B7\u53D6\u8C03\u7528\u94FE/\u4F9D\u8D56/\u7ED3\u6784",
36117
+ {},
36118
+ async () => {
36119
+ try {
36120
+ const conn = getDB();
36121
+ if (!conn) {
36122
+ const nodeVersion = process.versions.node;
36123
+ const nodeMajor = parseInt(nodeVersion.split(".")[0]);
36124
+ const needsUpgrade = nodeMajor < 22 || nodeMajor === 22 && parseInt(nodeVersion.split(".")[1]) < 5;
36125
+ return toResult({
36126
+ status: "unavailable",
36127
+ reason: needsUpgrade ? `Node.js ${nodeVersion} \u4E0D\u652F\u6301\u5185\u7F6E sqlite\uFF0C\u9700\u8981 Node >= 22.5.0` : "\u4EE3\u7801\u77E5\u8BC6\u56FE\u8C31\u6570\u636E\u5E93\u672A\u627E\u5230",
36128
+ how_to_setup: [
36129
+ "1. npm i -g @colbymchenry/codegraph",
36130
+ "2. cd \u5230\u9879\u76EE\u6839\u76EE\u5F55",
36131
+ "3. codegraph index # \u751F\u6210 .codegraph/codegraph.db",
36132
+ "4. \u91CD\u542F MCP Server"
36133
+ ].join("\n"),
36134
+ nodeVersion,
36135
+ tsIso: (/* @__PURE__ */ new Date()).toISOString(),
36136
+ _summary: needsUpgrade ? `\u4EE3\u7801\u56FE\u8C31\u4E0D\u53EF\u7528\uFF1ANode ${nodeVersion} \u9700 >= 22.5.0` : "\u4EE3\u7801\u56FE\u8C31\u672A\u521D\u59CB\u5316\u3002\u8BF7\u8FD0\u884C codegraph index \u751F\u6210\u6570\u636E\u5E93\u3002"
36137
+ });
36138
+ }
36139
+ const { db } = conn;
36140
+ const nodeCount = db.prepare("SELECT count(*) as n FROM nodes").get().n;
36141
+ const edgeCount = db.prepare("SELECT count(*) as n FROM edges").get().n;
36142
+ const fileCount = db.prepare("SELECT count(*) as n FROM files").get().n;
36143
+ const langRows = db.prepare(
36144
+ "SELECT language, count(*) as n FROM files GROUP BY language ORDER BY n DESC"
36145
+ ).all();
36146
+ const kindRows = db.prepare(
36147
+ "SELECT kind, count(*) as n FROM nodes GROUP BY kind ORDER BY n DESC LIMIT 10"
36148
+ ).all();
36149
+ const lastIndexed = db.prepare(
36150
+ "SELECT max(indexed_at) as ts FROM files"
36151
+ ).get().ts;
36152
+ const topCalled = db.prepare(`
36153
+ SELECT n.name, n.kind, n.file_path, count(e.id) as caller_count
36154
+ FROM edges e
36155
+ JOIN nodes n ON e.target = n.id
36156
+ WHERE e.kind = 'calls'
36157
+ GROUP BY e.target
36158
+ ORDER BY caller_count DESC
36159
+ LIMIT 10
36160
+ `).all();
36161
+ const status = {
36162
+ status: "ready",
36163
+ database: {
36164
+ path: ".codegraph/codegraph.db",
36165
+ nodeCount,
36166
+ edgeCount,
36167
+ fileCount,
36168
+ languages: langRows.reduce((acc, r) => ({ ...acc, [r.language]: r.n }), {})
36169
+ },
36170
+ nodesByKind: kindRows.reduce((acc, r) => ({ ...acc, [r.kind]: r.n }), {}),
36171
+ lastIndexed: lastIndexed ? new Date(lastIndexed).toISOString() : "unknown",
36172
+ topCalledFunctions: topCalled.map((r) => ({
36173
+ name: r.name,
36174
+ kind: r.kind,
36175
+ file: r.file_path,
36176
+ callers: r.caller_count
36177
+ })).slice(0, 5),
36178
+ queryHint: "\u7528 codegraph_query \u67E5\u8BE2\u5177\u4F53\u7B26\u53F7\u7684\u8C03\u7528\u94FE\u6216\u63A2\u7D22\u4EE3\u7801\u7ED3\u6784\u3002\u4F8B\u5982: codegraph_query({ mode: 'callers', symbol: 'toResult' })",
36179
+ tsIso: (/* @__PURE__ */ new Date()).toISOString(),
36180
+ _summary: `\u4EE3\u7801\u77E5\u8BC6\u56FE\u8C31\u5C31\u7EEA\u3002${nodeCount} \u4E2A\u8282\u70B9\uFF0C${edgeCount} \u6761\u5173\u7CFB\uFF0C\u8986\u76D6 ${fileCount} \u4E2A\u6587\u4EF6\u3002\u88AB\u8C03\u7528\u6700\u591A\u7684\u51FD\u6570: ${topCalled.slice(0, 3).map((r) => r.name).join("\u3001") || "\u65E0"}\u3002`
36181
+ };
36182
+ return toResult(status);
36183
+ } catch (e) {
36184
+ return toError(e);
36185
+ }
36186
+ }
36187
+ );
36188
+ server.tool(
36189
+ "codegraph_query",
36190
+ "CAT:[\u4EE3\u7801\u667A\u80FD] | ## \u529F\u80FD\uFF1A\u67E5\u8BE2\u4EE3\u7801\u77E5\u8BC6\u56FE\u8C31\u2014\u2014\u8FFD\u8E2A\u51FD\u6570\u8C03\u7528\u94FE\uFF08\u8C01\u8C03\u4E86\u8C01/\u88AB\u8C01\u8C03\uFF09\u3001\u641C\u7D22\u7B26\u53F7\u3001\u63A2\u7D22\u6A21\u5757\u4F9D\u8D56\n## \u573A\u666F\uFF1AAgent \u56DE\u7B54\u300CtoResult \u88AB\u54EA\u4E9B\u5DE5\u5177\u8C03\u7528\u300D\u300CregisterMarketTools \u7684\u8C03\u7528\u94FE\u300D\u300Cindex.ts \u4F9D\u8D56\u54EA\u4E9B\u6A21\u5757\u300D\u65F6\u8C03\u7528\n## \u5173\u952E\u8BCD\uFF1Acodegraph, \u8C03\u7528\u94FE, callers, callees, \u4F9D\u8D56, \u4EE3\u7801\u641C\u7D22, \u7B26\u53F7\u67E5\u8BE2, \u4E0A\u4E0B\u6E38\n## \u53C2\u6570\uFF1A\n## - mode: \u67E5\u8BE2\u6A21\u5F0F\u3002callers=\u8C01\u8C03\u7528\u5B83, callees=\u5B83\u8C03\u7528\u8C01, explore=\u81EA\u7136\u8BED\u8A00\u641C\u7D22, files=\u6309\u6587\u4EF6\u67E5\u8BE2\n## - symbol: \u7B26\u53F7\u540D\uFF08mode=callers/callees \u65F6\u5FC5\u586B\uFF09\u6216\u6587\u4EF6\u540D\uFF08mode=files\uFF09\n## - question: \u81EA\u7136\u8BED\u8A00\u641C\u7D22\uFF08mode=explore \u65F6\u4F7F\u7528\uFF09\n## - limit: \u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA4 15\n## \u9274\u6743\uFF1APUBLIC \u2014 \u672C\u5730\u6570\u636E\u5E93\n## \u98CE\u9669\uFF1AREAD \u2014 \u53EA\u8BFB\n## \u8FD4\u56DE\u91CF\uFF1A\u5FAE\u5C0F ~2KB\n## \u5173\u8054\uFF1Acodegraph_status \u770B\u72B6\u6001 \u2192 \u672C\u5DE5\u5177\u67E5\u8BE2 \u2192 \u5B9A\u4F4D\u6E90\u7801 \u2192 Agent \u7528 Read \u67E5\u770B\u7EC6\u8282",
36191
+ {
36192
+ mode: external_exports.enum(["callers", "callees", "explore", "files"]).describe("\u67E5\u8BE2\u6A21\u5F0F\u3002callers=\u8C01\u8C03\u7528\u5B83, callees=\u5B83\u8C03\u7528\u8C01, explore=\u81EA\u7136\u8BED\u8A00\u641C\u7D22, files=\u6309\u6587\u4EF6\u67E5\u8282\u70B9"),
36193
+ symbol: external_exports.string().optional().describe("\u7B26\u53F7\u540D\uFF08\u5982 toResult, registerMarketTools\uFF09\u6216\u6587\u4EF6\u540D\uFF08\u5982 agent-utils.ts\uFF09"),
36194
+ question: external_exports.string().optional().describe("\u81EA\u7136\u8BED\u8A00\u641C\u7D22\uFF08mode=explore \u65F6\u4F7F\u7528\uFF09\uFF0C\u5982 'HTTP \u8BF7\u6C42\u7B7E\u540D' 'WebSocket \u8FDE\u63A5'"),
36195
+ limit: external_exports.number().int().min(1).max(100).optional().describe("\u8FD4\u56DE\u6761\u6570\uFF0C\u9ED8\u8BA4 15")
36196
+ },
36197
+ async ({ mode, symbol, question, limit }) => {
36198
+ try {
36199
+ const conn = getDB();
36200
+ if (!conn) {
36201
+ return toError("\u4EE3\u7801\u77E5\u8BC6\u56FE\u8C31\u4E0D\u53EF\u7528\u3002\u8BF7\u5148\u8C03 codegraph_status \u68C0\u67E5\u72B6\u6001\u3002");
36202
+ }
36203
+ const { db } = conn;
36204
+ const n = limit || 15;
36205
+ if (mode === "callers") {
36206
+ if (!symbol) return toError("callers \u6A21\u5F0F\u9700\u8981 symbol \u53C2\u6570\uFF0CAgent \u8BF7\u63D0\u4F9B\u51FD\u6570\u540D");
36207
+ const nodes = db.prepare(
36208
+ "SELECT id, name, kind, file_path, start_line, signature, qualified_name FROM nodes WHERE name = ? OR name LIKE ? LIMIT 5"
36209
+ ).all(symbol, `%${symbol}%`);
36210
+ if (nodes.length === 0) {
36211
+ return toResult({
36212
+ mode: "callers",
36213
+ symbol,
36214
+ found: false,
36215
+ hint: `\u672A\u627E\u5230\u7B26\u53F7 "${symbol}"\u3002\u8BD5\u8BD5 codegraph_query({ mode: 'explore', question: '${symbol}' }) \u5168\u6587\u641C\u7D22`,
36216
+ tsIso: (/* @__PURE__ */ new Date()).toISOString()
36217
+ });
36218
+ }
36219
+ const results = [];
36220
+ for (const node of nodes) {
36221
+ const callers = db.prepare(`
36222
+ SELECT n.name as caller_name, n.kind, n.file_path, e.line, e.kind as edge_kind
36223
+ FROM edges e
36224
+ JOIN nodes n ON e.source = n.id
36225
+ WHERE e.target = ?
36226
+ ORDER BY n.name
36227
+ LIMIT ?
36228
+ `).all(node.id, n);
36229
+ results.push({
36230
+ target: { name: node.name, kind: node.kind, file: node.file_path, line: node.start_line },
36231
+ callers: callers.map((c) => ({
36232
+ name: c.caller_name,
36233
+ kind: c.kind,
36234
+ file: c.file_path,
36235
+ atLine: c.line,
36236
+ relation: c.edge_kind
36237
+ })),
36238
+ totalCallers: callers.length
36239
+ });
36240
+ }
36241
+ const total = results.reduce((s, r) => s + r.totalCallers, 0);
36242
+ return toResult({
36243
+ mode: "callers",
36244
+ symbol,
36245
+ matched: nodes.length,
36246
+ results,
36247
+ _summary: `"${symbol}" \u5339\u914D ${nodes.length} \u4E2A\u7B26\u53F7\uFF0C\u5171 ${total} \u4E2A\u8C03\u7528\u8005\u3002${results.slice(0, 3).map((r) => `${r.target.name}: ${r.callers.slice(0, 3).map((c) => c.name).join("\u3001")}`).join(" | ")}`,
36248
+ tsIso: (/* @__PURE__ */ new Date()).toISOString()
36249
+ });
36250
+ }
36251
+ if (mode === "callees") {
36252
+ if (!symbol) return toError("callees \u6A21\u5F0F\u9700\u8981 symbol \u53C2\u6570");
36253
+ const nodes = db.prepare(
36254
+ "SELECT id, name, kind, file_path, start_line FROM nodes WHERE name = ? OR name LIKE ? LIMIT 5"
36255
+ ).all(symbol, `%${symbol}%`);
36256
+ if (nodes.length === 0) {
36257
+ return toResult({
36258
+ mode: "callees",
36259
+ symbol,
36260
+ found: false,
36261
+ hint: `\u672A\u627E\u5230 "${symbol}"\uFF0C\u8BD5\u8BD5 mode='explore' \u5168\u6587\u641C\u7D22`,
36262
+ tsIso: (/* @__PURE__ */ new Date()).toISOString()
36263
+ });
36264
+ }
36265
+ const results = [];
36266
+ for (const node of nodes) {
36267
+ const callees = db.prepare(`
36268
+ SELECT n.name as callee_name, n.kind, n.file_path, e.line
36269
+ FROM edges e
36270
+ JOIN nodes n ON e.target = n.id
36271
+ WHERE e.source = ?
36272
+ ORDER BY e.kind, n.name
36273
+ LIMIT ?
36274
+ `).all(node.id, n);
36275
+ const byKind = {};
36276
+ for (const c of callees) {
36277
+ (byKind[c.kind] || (byKind[c.kind] = [])).push(c);
36278
+ }
36279
+ results.push({
36280
+ source: { name: node.name, kind: node.kind, file: node.file_path, line: node.start_line },
36281
+ callees: Object.entries(byKind).map(([kind, items]) => ({
36282
+ relation: kind,
36283
+ count: items.length,
36284
+ top: items.slice(0, 10).map((c) => ({ name: c.callee_name, kind: c.kind, file: c.file_path, atLine: c.line }))
36285
+ })),
36286
+ totalCallees: callees.length
36287
+ });
36288
+ }
36289
+ const total = results.reduce((s, r) => s + r.totalCallees, 0);
36290
+ return toResult({
36291
+ mode: "callees",
36292
+ symbol,
36293
+ matched: nodes.length,
36294
+ results,
36295
+ _summary: `"${symbol}" \u5339\u914D ${nodes.length} \u4E2A\u7B26\u53F7\uFF0C\u5171\u8C03\u7528 ${total} \u4E2A\u4E0B\u6E38\u3002`,
36296
+ tsIso: (/* @__PURE__ */ new Date()).toISOString()
36297
+ });
36298
+ }
36299
+ if (mode === "explore") {
36300
+ const q = question || symbol || "";
36301
+ if (!q) return toError("explore \u6A21\u5F0F\u9700\u8981 question \u6216 symbol \u53C2\u6570");
36302
+ let rows = db.prepare(`
36303
+ SELECT n.id, n.name, n.kind, n.file_path, n.start_line, n.signature, n.docstring, n.qualified_name
36304
+ FROM nodes_fts f
36305
+ JOIN nodes n ON f.id = n.id
36306
+ WHERE nodes_fts MATCH ?
36307
+ ORDER BY rank
36308
+ LIMIT ?
36309
+ `).all(q, n);
36310
+ if (rows.length === 0) {
36311
+ rows = db.prepare(`
36312
+ SELECT id, name, kind, file_path, start_line, signature, docstring, qualified_name
36313
+ FROM nodes
36314
+ WHERE name LIKE ? OR qualified_name LIKE ? OR docstring LIKE ?
36315
+ ORDER BY name
36316
+ LIMIT ?
36317
+ `).all(`%${q}%`, `%${q}%`, `%${q}%`, n);
36318
+ }
36319
+ if (rows.length === 0) {
36320
+ return toResult({
36321
+ mode: "explore",
36322
+ question: q,
36323
+ found: false,
36324
+ hint: `\u672A\u627E\u5230\u4E0E "${q}" \u76F8\u5173\u7684\u7B26\u53F7\u3002\u8BD5\u8BD5\u66F4\u77ED\u7684\u5173\u952E\u8BCD\u6216\u76F4\u63A5\u641C\u51FD\u6570\u540D\u3002`,
36325
+ tsIso: (/* @__PURE__ */ new Date()).toISOString()
36326
+ });
36327
+ }
36328
+ const top = rows.slice(0, 5);
36329
+ const enriched = top.map((r) => {
36330
+ const callers = db.prepare(
36331
+ "SELECT count(*) as n FROM edges WHERE target = ? AND kind = 'calls'"
36332
+ ).get(r.id).n;
36333
+ const callees = db.prepare(
36334
+ "SELECT count(*) as n FROM edges WHERE source = ? AND kind = 'calls'"
36335
+ ).get(r.id).n;
36336
+ return {
36337
+ name: r.name,
36338
+ kind: r.kind,
36339
+ file: r.file_path,
36340
+ line: r.start_line,
36341
+ signature: r.signature,
36342
+ docstring: r.docstring?.slice(0, 120),
36343
+ stats: { callers, callees }
36344
+ };
36345
+ });
36346
+ return toResult({
36347
+ mode: "explore",
36348
+ question: q,
36349
+ found: true,
36350
+ total: rows.length,
36351
+ results: enriched,
36352
+ _summary: `\u641C\u7D22 "${q}" \u627E\u5230 ${rows.length} \u4E2A\u7B26\u53F7\u3002${enriched.slice(0, 3).map((r) => `${r.name}(${r.kind}) in ${r.file}`).join(" | ")}`,
36353
+ hint: `\u627E\u5230\u5177\u4F53\u7B26\u53F7\u540E\u7528 codegraph_query({ mode: 'callers', symbol: '<name>' }) \u770B\u5B8C\u6574\u8C03\u7528\u94FE\u3002`,
36354
+ tsIso: (/* @__PURE__ */ new Date()).toISOString()
36355
+ });
36356
+ }
36357
+ if (mode === "files") {
36358
+ const file = symbol || "";
36359
+ if (!file) return toError("files \u6A21\u5F0F\u9700\u8981 symbol \u53C2\u6570\uFF08\u6587\u4EF6\u540D\uFF09");
36360
+ const fileInfo = db.prepare(
36361
+ "SELECT * FROM files WHERE path LIKE ? LIMIT 1"
36362
+ ).get(`%${file}%`);
36363
+ const nodes = db.prepare(`
36364
+ SELECT name, kind, start_line, signature, is_exported
36365
+ FROM nodes
36366
+ WHERE file_path LIKE ?
36367
+ ORDER BY start_line
36368
+ LIMIT ?
36369
+ `).all(`%${file}%`, n);
36370
+ return toResult({
36371
+ mode: "files",
36372
+ file,
36373
+ fileInfo: fileInfo ? {
36374
+ path: fileInfo.path,
36375
+ language: fileInfo.language,
36376
+ size: fileInfo.size,
36377
+ nodeCount: fileInfo.node_count,
36378
+ indexedAt: fileInfo.indexed_at ? new Date(fileInfo.indexed_at).toISOString() : void 0
36379
+ } : null,
36380
+ symbols: nodes.map((r) => ({
36381
+ name: r.name,
36382
+ kind: r.kind,
36383
+ line: r.start_line,
36384
+ signature: r.signature,
36385
+ exported: r.is_exported === 1
36386
+ })),
36387
+ _summary: `\u6587\u4EF6 "${file}" \u5305\u542B ${nodes.length} \u4E2A\u7B26\u53F7\u3002${nodes.filter((r) => r.is_exported).length} \u4E2A\u5BFC\u51FA\u3002`,
36388
+ tsIso: (/* @__PURE__ */ new Date()).toISOString()
36389
+ });
36390
+ }
36391
+ return toError(`\u672A\u77E5\u6A21\u5F0F: ${mode}`);
36392
+ } catch (e) {
36393
+ return toError(e);
36394
+ }
36395
+ }
36396
+ );
36397
+ }
36398
+
36071
36399
  // src/index.ts
36072
36400
  function resolveExecutionMode() {
36073
36401
  if (process.env.MCP_EXECUTION_ENABLED === "false") {
@@ -36123,10 +36451,12 @@ function registerAllTools(server, auth, readOnly) {
36123
36451
  registerXLayerWSTools(server);
36124
36452
  registerWsTools(server);
36125
36453
  registerAgentHubTools(server);
36454
+ registerCodeGraphTools(server);
36126
36455
  return { skipped, skipLog };
36127
36456
  }
36128
36457
  async function startHttp(server, version2, auth, readOnly, skipped) {
36129
36458
  const port = parseInt(process.env.PORT || "3000", 10);
36459
+ const host = process.env.HOST || "127.0.0.1";
36130
36460
  const transport = new StreamableHTTPServerTransport({
36131
36461
  sessionIdGenerator: void 0
36132
36462
  // stateless
@@ -36173,12 +36503,12 @@ async function startHttp(server, version2, auth, readOnly, skipped) {
36173
36503
  res.writeHead(404, { "Content-Type": "application/json" });
36174
36504
  res.end(JSON.stringify({ error: "Not Found" }));
36175
36505
  });
36176
- httpServer.listen(port, "0.2.47.0", () => {
36506
+ httpServer.listen(port, host, () => {
36177
36507
  process.stderr.write([
36178
36508
  `\u2554\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557`,
36179
36509
  `\u2551 hvip-mcp v${version2} HTTP \u6A21\u5F0F \u2551`,
36180
- `\u2551 POST http://0.2.47.0:${port}/mcp \u2551`,
36181
- `\u2551 GET http://0.2.47.0:${port}/health \u2551`,
36510
+ `\u2551 POST http://${host}:${port}/mcp \u2551`,
36511
+ `\u2551 GET http://${host}:${port}/health \u2551`,
36182
36512
  `\u2551 \u6A21\u5F0F: ${readOnly ? "\u53EA\u8BFB" : "\u5B8C\u6574"} | \u5DE5\u5177: ${readOnly ? "READ only" : "\u5168\u90E8"} \u2551`,
36183
36513
  `\u255A\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D`
36184
36514
  ].join("\n") + "\n");
@@ -36208,12 +36538,13 @@ async function startStdio(server, version2, auth, readOnly, skipped, skipLog) {
36208
36538
  process.stderr.write(`[hvip] \u672A\u914D\u7F6E API Key | \u4EC5\u516C\u5F00\u5DE5\u5177\u53EF\u7528 (v${version2})
36209
36539
  `);
36210
36540
  }
36211
- startAgentHub(parseInt(process.env.WS_AGENT_PORT || "9321"), "0.2.47.0", version2);
36541
+ const wsHost = process.env.WS_BIND_HOST || "127.0.0.1";
36542
+ startAgentHub(parseInt(process.env.WS_AGENT_PORT || "9321"), wsHost, version2);
36212
36543
  const transport = new StdioServerTransport();
36213
36544
  await server.connect(transport);
36214
36545
  }
36215
36546
  async function main() {
36216
- const VERSION = "0.2.47";
36547
+ const VERSION = "0.2.49";
36217
36548
  const auth = getAuth();
36218
36549
  const mode = resolveTransportMode();
36219
36550
  const exec = resolveExecutionMode();
@@ -36221,7 +36552,7 @@ async function main() {
36221
36552
  const server = new McpServer({
36222
36553
  name: "hvip-mcp",
36223
36554
  version: VERSION,
36224
- description: "hvip MCP Server \u2014 362 \u5DE5\u5177\u8986\u76D6 97.7% OKX REST API\uFF0C\u542B\u4EA4\u6613/\u884C\u60C5/\u8D44\u91D1/\u7B56\u7565/\u9884\u6D4B\u5E02\u573A/\u6280\u672F\u6307\u6807/Smart Money\uFF08\u975E OKX \u5B98\u65B9\u4EA7\u54C1\uFF09\u3002\u4ED3\u5E93: https://github.com/okx-wallet-H/hvip-mcp"
36555
+ description: "hvip MCP Server \u2014 364 \u5DE5\u5177\u8986\u76D6 97.7% OKX REST API\uFF0C\u542B\u4EA4\u6613/\u884C\u60C5/\u8D44\u91D1/\u7B56\u7565/\u9884\u6D4B\u5E02\u573A/\u6280\u672F\u6307\u6807/Smart Money\uFF08\u975E OKX \u5B98\u65B9\u4EA7\u54C1\uFF09\u3002\u4ED3\u5E93: https://github.com/okx-wallet-H/hvip-mcp"
36225
36556
  });
36226
36557
  const { skipped, skipLog } = registerAllTools(server, auth, readOnly);
36227
36558
  if (mode === "http") {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "hvip-mcp-server",
3
- "version": "0.2.47",
4
- "description": "hvip MCP Server — 362 工具覆盖 97.7% OKX REST API,含交易/行情/资金/策略/预测市场/技术指标/Smart Money(非 OKX 官方产品)",
3
+ "version": "0.2.49",
4
+ "description": "hvip MCP Server — 364 工具覆盖 97.7% OKX REST API,含交易/行情/资金/策略/预测市场/技术指标/Smart Money(非 OKX 官方产品)",
5
5
  "homepage": "https://github.com/okx-wallet-H/hvip-mcp",
6
6
  "repository": {
7
7
  "type": "git",