hvip-mcp-server 0.2.55 → 0.2.57

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 +98 -44
  2. package/dist/index.js +80 -11
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -1,101 +1,155 @@
1
1
  # hvip MCP Server
2
2
 
3
- > OKX API 全景图 —— 让任何 AI Agent 都能使用 OKX 的全部能力。
3
+ > OKX 全部能力接入 AI —— 365 MCP 工具,覆盖 97.7% OKX REST API
4
4
 
5
5
  [![npm version](https://img.shields.io/npm/v/hvip-mcp-server)](https://www.npmjs.com/package/hvip-mcp-server)
6
6
  [![License](https://img.shields.io/npm/l/hvip-mcp-server)](https://github.com/okx-wallet-H/hvip-mcp/blob/master/LICENSE)
7
- [![GitHub stars](https://img.shields.io/github/stars/okx-wallet-H/hvip-mcp)](https://github.com/okx-wallet-H/hvip-mcp)
8
7
 
9
- 📦 **仓库**: [github.com/okx-wallet-H/hvip-mcp](https://github.com/okx-wallet-H/hvip-mcp)
10
- 🐛 **Issue**: [提交反馈](https://github.com/okx-wallet-H/hvip-mcp/issues/new)
11
- 📖 **贡献**: [CONTRIBUTING.md](./CONTRIBUTING.md)
8
+ 📦 [github.com/okx-wallet-H/hvip-mcp](https://github.com/okx-wallet-H/hvip-mcp) · 🐛 [提交反馈](https://github.com/okx-wallet-H/hvip-mcp/issues/new)
12
9
 
13
10
  ---
14
11
 
15
- ## 快速开始
12
+ ## 安装
16
13
 
17
- ### 1. Claude Desktop 接入
14
+ **这不是命令行工具**——hvip-mcp MCP (Model Context Protocol) 服务器,由 AI 客户端在后台自动运行。你只需要在配置文件中加一行 JSON,AI 自己会启动它。
18
15
 
19
- Claude Desktop 配置中添加:
16
+ ### Claude Desktop
17
+
18
+ Claude Desktop → 设置 → Developer → Edit Config:
19
+
20
+ ```json
21
+ {
22
+ "mcpServers": {
23
+ "hvip": {
24
+ "command": "npx",
25
+ "args": ["-y", "hvip-mcp-server"]
26
+ }
27
+ }
28
+ }
29
+ ```
30
+
31
+ ### Claude Code
32
+
33
+ 在项目根目录或全局 `.claude/settings.json`:
34
+
35
+ ```json
36
+ {
37
+ "mcpServers": {
38
+ "hvip": {
39
+ "command": "npx",
40
+ "args": ["-y", "hvip-mcp-server@latest"]
41
+ }
42
+ }
43
+ }
44
+ ```
45
+
46
+ ### VS Code / Cline / 其他 MCP 客户端
47
+
48
+ 在 MCP 配置中添加同样的 JSON。
49
+
50
+ > **配置完需要完全退出并重启客户端**,重开后 AI 自动连接 hvip。
51
+
52
+ ### 需要 API Key?
53
+
54
+ 行情、技术指标、市场扫描等公开数据无需 Key。查看账户、下单交易需要 OKX API Key:
20
55
 
21
56
  ```json
22
57
  {
23
58
  "mcpServers": {
24
- "hvip-mcp": {
59
+ "hvip": {
25
60
  "command": "npx",
26
61
  "args": ["-y", "hvip-mcp-server"],
27
62
  "env": {
28
- "OKX_API_KEY": "<你的API Key>",
29
- "OKX_SECRET_KEY": "<你的Secret Key>",
30
- "OKX_PASSPHRASE": "<你的Passphrase>"
63
+ "OKX_API_KEY": "<你的 API Key>",
64
+ "OKX_SECRET_KEY": "<你的 Secret Key>",
65
+ "OKX_PASSPHRASE": "<你的 Passphrase>"
31
66
  }
32
67
  }
33
68
  }
34
69
  }
35
70
  ```
36
71
 
37
- ### 2. 直接运行
72
+ > API Key 在 [OKX 官网](https://www.okx.com) → 个人中心 → API 中创建,开通「读取」权限即可查账户,「交易」权限可下单。
38
73
 
39
- ```bash
40
- npx hvip-mcp-server
41
- ```
74
+ ---
42
75
 
43
- ### 3. 本地开发
76
+ ## 工作流
44
77
 
45
- ```bash
46
- git clone https://github.com/okx-wallet-H/hvip-mcp.git
47
- cd hvip-mcp
48
- npm install
49
- npm run build
50
- npm start
78
+ AI 连接 hvip 后自动执行:
79
+
80
+ ```
81
+ 1. tools/list → 365 个工具,但只有 agent_catalog 带完整描述
82
+ 2. agent_catalog → 15 个域的地图(7 公开 + 8 需 Key),按需直达
83
+ 3. 用户说 "BTC 怎么样" → AI 调 okx_quick_market
84
+ 4. 用户说 "买 0.1 BTC" → AI 先预检再下单
51
85
  ```
52
86
 
87
+ **无需手动操作,全程 AI 自己来。**
88
+
53
89
  ---
54
90
 
55
91
  ## 工具覆盖
56
92
 
57
93
  | 模块 | 工具数 | 说明 |
58
94
  |------|--------|------|
59
- | 🔹 **交易类** | 40+ | 下单/撤单/改单/批量/策略委托 |
60
- | 🔹 **行情类** | 30+ | Ticker/K线/深度/资金费率/标记价 |
61
- | 🔹 **数据类** | 50+ | 产品信息/多空比/买卖量/PCR/统计数据 |
62
- | 🔹 **资金类** | 40+ | 划转/提现/充值/余额/持仓/杠杆 |
63
- | 🔹 **策略类** | 20+ | 网格/信号/跟单/价差/RFQ |
64
- | 🔹 **金融类** | 15+ | 赚币/质押/借贷/法币 |
65
- | 🔹 **预测市场** | 9+ | 事件/市场/深度/套利检测 |
66
- | 🔹 **Skill 组合** | 4 | 账户全景/市场速览/下单预检/反馈 |
95
+ | 🔹 账户 | 40+ | 余额/持仓/配置/杠杆/估值 |
96
+ | 🔹 行情 | 17 | Ticker/K线/深度/成交 |
97
+ | 🔹 交易 | 27 | 下单/撤单/改单/批量/平仓 |
98
+ | 🔹 公共数据 | 34 | 产品规格/资金费率/标记价 |
99
+ | 🔹 资金 | 18 | 划转/提现/充值/兑换 |
100
+ | 🔹 策略委托 | 6 | 止损止盈/冰山/移动止盈 |
101
+ | 🔹 网格 | 13 | 现货网格/合约网格/定投 |
102
+ | 🔹 跟单 | 23 | 交易员/跟单/带单 |
103
+ | 🔹 信号 | 10 | 信号订阅/历史信号 |
104
+ | 🔹 价差 | 16 | 跨品种/跨期价差 |
105
+ | 🔹 RFQ | 12 | 大宗询价/报价/成交 |
106
+ | 🔹 金融 | 27 | 赚币/质押/借贷 |
107
+ | 🔹 预测市场 | 36 | 事件合约/预测交易 |
108
+ | 🔹 技术指标 | 2 | RSI/MACD/布林带等 17 种 |
109
+ | 🔹 聪明钱 | 3 | 交易员排行榜/市场情绪 |
110
+ | 🔹 WebSocket | 5 | 55 频道实时推送 |
111
+ | 🔹 代码图谱 | 2 | 函数调用链/符号搜索 |
112
+ | 🔹 系统工具 | 19 | 导航/偏好/反馈/Agent 协作 |
113
+
114
+ **365 个 MCP 工具 · 覆盖 97.7% OKX REST API**
67
115
 
68
- **304 个 MCP 工具 · 覆盖 97.7% OKX REST API · P0 P1 全部清零**
116
+ ---
117
+
118
+ ## 本地开发
119
+
120
+ ```bash
121
+ git clone https://github.com/okx-wallet-H/hvip-mcp.git
122
+ cd hvip-mcp
123
+ npm install
124
+ npm run build
125
+ npm start
126
+ ```
69
127
 
70
128
  ---
71
129
 
72
130
  ## 架构
73
131
 
74
132
  ```
75
- 原子层 (300+ 工具) AI Agent 直接调用
76
-
77
- Skill 组合层 (4 个) → 串联多工具,一次完成复杂任务
78
-
79
- 反馈通道GitHub Issues Skill 需求 AI Agent 自行实现并提 PR
133
+ 原子层 (350 工具) [L:READ] 权限标记 → AI Agent 按需调用
134
+
135
+ Skill 组合层 (13 个) → 串联多工具,一次完成复杂任务
136
+
137
+ agent_catalog15 域地图按意图路由直达目标工具
80
138
  ```
81
139
 
82
140
  ---
83
141
 
84
142
  ## 贡献
85
143
 
86
- AI Agent 或开发者都可以贡献 Skill:
87
-
88
144
  1. 阅读 [`CLAUDE.md`](./CLAUDE.md) 了解项目规范
89
145
  2. 阅读 [`CONTRIBUTING.md`](./CONTRIBUTING.md) 了解提交流程
90
- 3. Fork → 创建 Skill PRReview → 合并
91
-
92
- 每个 Skill 串联多个原子工具,解决一个具体的使用场景。
146
+ 3. Fork → 创建分支 开发 `npm run build` PR
93
147
 
94
148
  ---
95
149
 
96
150
  ## 文档
97
151
 
98
152
  - [`CLAUDE.md`](./CLAUDE.md) — AI Agent 项目指南
99
- - [`CONTRIBUTING.md`](./CONTRIBUTING.md) — Skill 贡献流程
100
- - [`docs/OKX-MCP-API对接标准-v0.1.8.md`](./docs/OKX-MCP-API对接标准-v0.1.8.md) — API 对接规范
153
+ - [`CONTRIBUTING.md`](./CONTRIBUTING.md) — 贡献流程
154
+ - [`docs/OKX-MCP-API对接标准-v0.2.49.md`](./docs/OKX-MCP-API对接标准-v0.2.49.md) — API 对接规范
101
155
  - [`docs/OKX-MCP-防幻觉对接SOP-v1.0.md`](./docs/OKX-MCP-防幻觉对接SOP-v1.0.md) — 防幻觉 SOP
package/dist/index.js CHANGED
@@ -37023,11 +37023,73 @@ var AgentHub = class {
37023
37023
  rooms = /* @__PURE__ */ new Map();
37024
37024
  heartbeatTimer = null;
37025
37025
  version = "0.0.0";
37026
+ port = 0;
37027
+ db = null;
37028
+ // ── 持久化绑定 ──
37029
+ setDB(db) {
37030
+ this.db = db;
37031
+ const rows = db.loadTasks();
37032
+ for (const r of rows) {
37033
+ this.tasks.set(r.taskId, {
37034
+ status: r.status,
37035
+ assignedTo: r.assignedTo || void 0,
37036
+ claimedAt: r.claimedAt || void 0,
37037
+ result: r.result || void 0,
37038
+ branch: r.branch || void 0
37039
+ });
37040
+ }
37041
+ if (rows.length > 0) {
37042
+ console.log(`[AgentHub] \u4ECE DB \u6062\u590D ${rows.length} \u4E2A\u4EFB\u52A1`);
37043
+ }
37044
+ }
37026
37045
  // ── 启动 ──
37027
37046
  start(port, host = "0.0.0.0", version2 = "0.0.0") {
37028
37047
  this.version = version2;
37029
- this.wss = new import_websocket_server.default({ port, host });
37030
- console.log(`[AgentHub] WS Server v${version2} started on ws://${host}:${port}`);
37048
+ const startWss = (p) => {
37049
+ return new Promise((resolve2) => {
37050
+ const wss = new import_websocket_server.default({ port: p, host });
37051
+ let resolved = false;
37052
+ const done = (ok) => {
37053
+ if (!resolved) {
37054
+ resolved = true;
37055
+ resolve2(ok);
37056
+ }
37057
+ };
37058
+ wss.on("listening", () => {
37059
+ this.wss = wss;
37060
+ this.port = p;
37061
+ done(true);
37062
+ });
37063
+ wss.on("error", () => {
37064
+ try {
37065
+ wss.close();
37066
+ } catch {
37067
+ }
37068
+ done(false);
37069
+ });
37070
+ setTimeout(() => done(false), 1e3);
37071
+ });
37072
+ };
37073
+ const ports = [port, port + 1, port + 2];
37074
+ startWss(ports[0]).then((ok) => {
37075
+ if (!ok) return startWss(ports[1]);
37076
+ return true;
37077
+ }).then((ok) => {
37078
+ if (!ok) return startWss(ports[2]);
37079
+ return ok === true ? true : false;
37080
+ }).then((ok) => {
37081
+ if (!ok) {
37082
+ process.stderr.write(`[AgentHub] WS Hub \u8DF3\u8FC7\uFF08\u7AEF\u53E3 ${ports.join("/")} \u4E0D\u53EF\u7528\uFF09
37083
+ `);
37084
+ return;
37085
+ }
37086
+ process.stderr.write(`[AgentHub] WS Hub v${version2} ws://${host}:${this.port}
37087
+ `);
37088
+ this.setupHub();
37089
+ });
37090
+ }
37091
+ setupHub() {
37092
+ if (!this.wss) return;
37031
37093
  this.ensureRoom("#lobby");
37032
37094
  this.ensureRoom("#review");
37033
37095
  this.wss.on("connection", (ws) => {
@@ -37035,7 +37097,8 @@ var AgentHub = class {
37035
37097
  ws.on("message", (raw) => {
37036
37098
  try {
37037
37099
  const msg = JSON.parse(raw.toString());
37038
- this.handleMessage(ws, agentId, msg);
37100
+ const newId = this.handleMessage(ws, agentId, msg);
37101
+ if (newId) agentId = newId;
37039
37102
  } catch {
37040
37103
  this.send(ws, { type: "error", message: "\u6D88\u606F\u683C\u5F0F\u9519\u8BEF\uFF1A\u975E JSON" });
37041
37104
  }
@@ -37052,7 +37115,7 @@ var AgentHub = class {
37052
37115
  if (now - a.lastSeen > 12e4) {
37053
37116
  a.ws.close();
37054
37117
  this.agents.delete(id);
37055
- console.log(`[AgentHub] Agent \u5FC3\u8DF3\u8D85\u65F6: ${id}`);
37118
+ console.log("[AgentHub] Agent \u5FC3\u8DF3\u8D85\u65F6: " + id);
37056
37119
  }
37057
37120
  }
37058
37121
  }, 3e4);
@@ -37061,8 +37124,7 @@ var AgentHub = class {
37061
37124
  handleMessage(ws, authAgentId, msg) {
37062
37125
  switch (msg.type) {
37063
37126
  case "agent:hello":
37064
- this.handleHello(ws, msg);
37065
- break;
37127
+ return this.handleHello(ws, msg);
37066
37128
  case "agent:status":
37067
37129
  if (authAgentId) this.handleAgentStatus(authAgentId);
37068
37130
  break;
@@ -37088,6 +37150,7 @@ var AgentHub = class {
37088
37150
  default:
37089
37151
  this.send(ws, { type: "error", message: `\u672A\u77E5\u6D88\u606F\u7C7B\u578B: ${msg.type}` });
37090
37152
  }
37153
+ return null;
37091
37154
  }
37092
37155
  // ── Agent 注册 ──
37093
37156
  handleHello(ws, msg) {
@@ -37096,7 +37159,7 @@ var AgentHub = class {
37096
37159
  const capabilities = Array.isArray(msg.capabilities) ? msg.capabilities : [];
37097
37160
  if (!agentId) {
37098
37161
  this.send(ws, { type: "error", message: "\u7F3A\u5C11 agentId" });
37099
- return;
37162
+ return "";
37100
37163
  }
37101
37164
  const existing = this.agents.get(agentId);
37102
37165
  if (existing) existing.ws.close();
@@ -37134,17 +37197,17 @@ var AgentHub = class {
37134
37197
  }
37135
37198
  }
37136
37199
  }
37200
+ return agentId;
37137
37201
  }
37138
37202
  handleDisconnect(agentId) {
37139
37203
  const info = this.agents.get(agentId);
37140
37204
  console.log(`[AgentHub] Agent \u79BB\u7EBF: ${agentId} (${info?.name || "?"})`);
37141
- for (const [, room] of this.rooms) {
37205
+ for (const [roomId, room] of this.rooms) {
37142
37206
  if (room.members.has(agentId)) {
37143
37207
  room.members.delete(agentId);
37144
37208
  this.sendToRoomMembers(room, {
37145
37209
  type: "room:member_left",
37146
- roomId: agentId,
37147
- // fixed below
37210
+ roomId,
37148
37211
  agentId
37149
37212
  });
37150
37213
  }
@@ -37155,6 +37218,7 @@ var AgentHub = class {
37155
37218
  t.status = "unassigned";
37156
37219
  t.assignedTo = void 0;
37157
37220
  t.claimedAt = void 0;
37221
+ this.db?.saveTask({ taskId: tid, status: "unassigned" });
37158
37222
  this.broadcast({ type: "task:released", taskId: tid, reason: "Agent \u79BB\u7EBF" });
37159
37223
  }
37160
37224
  }
@@ -37187,6 +37251,7 @@ var AgentHub = class {
37187
37251
  if (a) a.status = "working";
37188
37252
  this.joinRoom(agentId, `#task-${taskId}`);
37189
37253
  console.log(`[AgentHub] ${agentId} \u8BA4\u9886 ${taskId}`);
37254
+ this.db?.saveTask({ taskId, status: "assigned", title: this.getTaskTitle(taskId), assignedTo: agentId, claimedAt: task.claimedAt });
37190
37255
  this.sendTo(agentId, {
37191
37256
  type: "task:assigned",
37192
37257
  taskId,
@@ -37212,6 +37277,7 @@ var AgentHub = class {
37212
37277
  const a = this.agents.get(agentId);
37213
37278
  if (a) a.status = "idle";
37214
37279
  console.log(`[AgentHub] ${agentId} \u5B8C\u6210 ${taskId}: ${result}`);
37280
+ this.db?.saveTask({ taskId, status: "done", title: this.getTaskTitle(taskId), assignedTo: agentId, result, branch });
37215
37281
  this.sendToRoom(`#task-${taskId}`, agentId, `\u5DF2\u5B8C\u6210 ${taskId}: ${result} (branch: ${branch})\uFF0C\u7B49\u5F85\u5BA1\u6838\u3002`);
37216
37282
  this.sendToRoom("#review", agentId, `${taskId} \u63D0\u4EA4\u5B8C\u6210\uFF0Cbranch: ${branch}`);
37217
37283
  this.broadcast({
@@ -37243,10 +37309,12 @@ var AgentHub = class {
37243
37309
  if (!task) return;
37244
37310
  if (verdict === "approved") {
37245
37311
  task.status = "reviewed";
37312
+ this.db?.saveTask({ taskId, status: "reviewed", reviewedAt: (/* @__PURE__ */ new Date()).toISOString() });
37246
37313
  } else {
37247
37314
  task.status = "unassigned";
37248
37315
  task.assignedTo = void 0;
37249
37316
  task.claimedAt = void 0;
37317
+ this.db?.saveTask({ taskId, status: "unassigned" });
37250
37318
  }
37251
37319
  const roomId = `#task-${taskId}`;
37252
37320
  const msg = verdict === "approved" ? `\u2705 ${taskId} \u5BA1\u6838\u901A\u8FC7\u3002\u5DF2\u5408\u5E76\u5230 master \u5E76\u5220\u9664\u8FDC\u7A0B\u5206\u652F\u3002` : `\u274C ${taskId} \u5BA1\u6838\u4E0D\u901A\u8FC7\u3002${feedback || "\u8BF7\u4FEE\u6539\u540E\u91CD\u65B0 push\u3002"}`;
@@ -37297,6 +37365,7 @@ var AgentHub = class {
37297
37365
  const msg = { roomId, from, text, ts: (/* @__PURE__ */ new Date()).toISOString() };
37298
37366
  room.messages.push(msg);
37299
37367
  if (room.messages.length > MAX_ROOM_MESSAGES) room.messages.shift();
37368
+ this.db?.saveMessage(roomId, from, text, msg.ts);
37300
37369
  const raw = JSON.stringify({ type: "room:message", ...msg });
37301
37370
  for (const agentId of room.members) {
37302
37371
  const a = this.agents.get(agentId);
@@ -38212,7 +38281,7 @@ async function startStdio(server, version2, auth, readOnly, skipped, skipLog) {
38212
38281
  await server.connect(transport);
38213
38282
  }
38214
38283
  async function main() {
38215
- const VERSION = "0.2.55";
38284
+ const VERSION = "0.2.57";
38216
38285
  const argv = process.argv.slice(2);
38217
38286
  if (argv.includes("--help") || argv.includes("-h")) printHelpAndExit(VERSION);
38218
38287
  if (argv.includes("--version") || argv.includes("-v")) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "hvip-mcp-server",
3
- "version": "0.2.55",
3
+ "version": "0.2.57",
4
4
  "description": "hvip MCP Server — 365 工具覆盖 97.7% OKX REST API,含交易/行情/资金/策略/预测市场/技术指标/Smart Money(非 OKX 官方产品)",
5
5
  "homepage": "https://github.com/okx-wallet-H/hvip-mcp",
6
6
  "repository": {