hvip-mcp-server 0.2.48 → 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.
- package/dist/index.js +376 -47
- 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 =
|
|
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
|
|
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(
|
|
3233
|
-
let input =
|
|
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 [
|
|
3486
|
-
wsComponent.path =
|
|
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
|
|
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,
|
|
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,
|
|
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:
|
|
11081
|
-
const fullPath = [...
|
|
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,
|
|
11197
|
+
constructor(parent, value, path3, key) {
|
|
11198
11198
|
this._cachedPath = [];
|
|
11199
11199
|
this.parent = parent;
|
|
11200
11200
|
this.data = value;
|
|
11201
|
-
this._path =
|
|
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,
|
|
14839
|
-
if (!
|
|
14838
|
+
function getElementAtPath(obj, path3) {
|
|
14839
|
+
if (!path3)
|
|
14840
14840
|
return obj;
|
|
14841
|
-
return
|
|
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(
|
|
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(
|
|
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((
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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(
|
|
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((
|
|
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((
|
|
24805
|
+
return new Promise((resolve2) => {
|
|
24806
24806
|
const json = serializeMessage(message);
|
|
24807
24807
|
if (this._stdout.write(json)) {
|
|
24808
|
-
|
|
24808
|
+
resolve2();
|
|
24809
24809
|
} else {
|
|
24810
|
-
this._stdout.once("drain",
|
|
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((
|
|
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((
|
|
25809
|
+
return new Promise((resolve2) => {
|
|
25810
25810
|
this._streamMapping.set(streamId, {
|
|
25811
|
-
resolveJson:
|
|
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,
|
|
26145
|
-
const msg = ts + method +
|
|
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,
|
|
26158
|
+
async function request(method, path3, options = {}) {
|
|
26159
26159
|
const query = options.params ? buildQuery(options.params) : "";
|
|
26160
|
-
const fullPath =
|
|
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(
|
|
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 +
|
|
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 = (
|
|
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((
|
|
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
|
-
|
|
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((
|
|
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((
|
|
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
|
-
|
|
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,6 +36451,7 @@ 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) {
|
|
@@ -36215,7 +36544,7 @@ async function startStdio(server, version2, auth, readOnly, skipped, skipLog) {
|
|
|
36215
36544
|
await server.connect(transport);
|
|
36216
36545
|
}
|
|
36217
36546
|
async function main() {
|
|
36218
|
-
const VERSION = "0.2.
|
|
36547
|
+
const VERSION = "0.2.49";
|
|
36219
36548
|
const auth = getAuth();
|
|
36220
36549
|
const mode = resolveTransportMode();
|
|
36221
36550
|
const exec = resolveExecutionMode();
|
|
@@ -36223,7 +36552,7 @@ async function main() {
|
|
|
36223
36552
|
const server = new McpServer({
|
|
36224
36553
|
name: "hvip-mcp",
|
|
36225
36554
|
version: VERSION,
|
|
36226
|
-
description: "hvip MCP Server \u2014
|
|
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"
|
|
36227
36556
|
});
|
|
36228
36557
|
const { skipped, skipLog } = registerAllTools(server, auth, readOnly);
|
|
36229
36558
|
if (mode === "http") {
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hvip-mcp-server",
|
|
3
|
-
"version": "0.2.
|
|
4
|
-
"description": "hvip MCP Server —
|
|
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",
|