hvip-mcp-server 0.2.56 → 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.
- package/README.md +98 -44
- package/dist/index.js +33 -8
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,101 +1,155 @@
|
|
|
1
1
|
# hvip MCP Server
|
|
2
2
|
|
|
3
|
-
> OKX
|
|
3
|
+
> OKX 全部能力接入 AI —— 365 个 MCP 工具,覆盖 97.7% OKX REST API
|
|
4
4
|
|
|
5
5
|
[](https://www.npmjs.com/package/hvip-mcp-server)
|
|
6
6
|
[](https://github.com/okx-wallet-H/hvip-mcp/blob/master/LICENSE)
|
|
7
|
-
[](https://github.com/okx-wallet-H/hvip-mcp)
|
|
8
7
|
|
|
9
|
-
📦
|
|
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
|
-
|
|
14
|
+
**这不是命令行工具**——hvip-mcp 是 MCP (Model Context Protocol) 服务器,由 AI 客户端在后台自动运行。你只需要在配置文件中加一行 JSON,AI 自己会启动它。
|
|
18
15
|
|
|
19
|
-
|
|
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
|
|
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
|
-
|
|
72
|
+
> API Key 在 [OKX 官网](https://www.okx.com) → 个人中心 → API 中创建,开通「读取」权限即可查账户,「交易」权限可下单。
|
|
38
73
|
|
|
39
|
-
|
|
40
|
-
npx hvip-mcp-server
|
|
41
|
-
```
|
|
74
|
+
---
|
|
42
75
|
|
|
43
|
-
|
|
76
|
+
## 工作流
|
|
44
77
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
| 🔹
|
|
60
|
-
| 🔹
|
|
61
|
-
| 🔹
|
|
62
|
-
| 🔹
|
|
63
|
-
| 🔹
|
|
64
|
-
| 🔹
|
|
65
|
-
| 🔹
|
|
66
|
-
| 🔹
|
|
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
|
-
|
|
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
|
-
原子层 (
|
|
76
|
-
|
|
77
|
-
Skill 组合层 (
|
|
78
|
-
|
|
79
|
-
|
|
133
|
+
原子层 (350 工具) → [L:READ] 权限标记 → AI Agent 按需调用
|
|
134
|
+
↓
|
|
135
|
+
Skill 组合层 (13 个) → 串联多工具,一次完成复杂任务
|
|
136
|
+
↓
|
|
137
|
+
agent_catalog → 15 域地图 → 按意图路由 → 直达目标工具
|
|
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 →
|
|
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) —
|
|
100
|
-
- [`docs/OKX-MCP-API对接标准-v0.
|
|
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
|
@@ -37024,6 +37024,24 @@ var AgentHub = class {
|
|
|
37024
37024
|
heartbeatTimer = null;
|
|
37025
37025
|
version = "0.0.0";
|
|
37026
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
|
+
}
|
|
37027
37045
|
// ── 启动 ──
|
|
37028
37046
|
start(port, host = "0.0.0.0", version2 = "0.0.0") {
|
|
37029
37047
|
this.version = version2;
|
|
@@ -37079,7 +37097,8 @@ var AgentHub = class {
|
|
|
37079
37097
|
ws.on("message", (raw) => {
|
|
37080
37098
|
try {
|
|
37081
37099
|
const msg = JSON.parse(raw.toString());
|
|
37082
|
-
this.handleMessage(ws, agentId, msg);
|
|
37100
|
+
const newId = this.handleMessage(ws, agentId, msg);
|
|
37101
|
+
if (newId) agentId = newId;
|
|
37083
37102
|
} catch {
|
|
37084
37103
|
this.send(ws, { type: "error", message: "\u6D88\u606F\u683C\u5F0F\u9519\u8BEF\uFF1A\u975E JSON" });
|
|
37085
37104
|
}
|
|
@@ -37105,8 +37124,7 @@ var AgentHub = class {
|
|
|
37105
37124
|
handleMessage(ws, authAgentId, msg) {
|
|
37106
37125
|
switch (msg.type) {
|
|
37107
37126
|
case "agent:hello":
|
|
37108
|
-
this.handleHello(ws, msg);
|
|
37109
|
-
break;
|
|
37127
|
+
return this.handleHello(ws, msg);
|
|
37110
37128
|
case "agent:status":
|
|
37111
37129
|
if (authAgentId) this.handleAgentStatus(authAgentId);
|
|
37112
37130
|
break;
|
|
@@ -37132,6 +37150,7 @@ var AgentHub = class {
|
|
|
37132
37150
|
default:
|
|
37133
37151
|
this.send(ws, { type: "error", message: `\u672A\u77E5\u6D88\u606F\u7C7B\u578B: ${msg.type}` });
|
|
37134
37152
|
}
|
|
37153
|
+
return null;
|
|
37135
37154
|
}
|
|
37136
37155
|
// ── Agent 注册 ──
|
|
37137
37156
|
handleHello(ws, msg) {
|
|
@@ -37140,7 +37159,7 @@ var AgentHub = class {
|
|
|
37140
37159
|
const capabilities = Array.isArray(msg.capabilities) ? msg.capabilities : [];
|
|
37141
37160
|
if (!agentId) {
|
|
37142
37161
|
this.send(ws, { type: "error", message: "\u7F3A\u5C11 agentId" });
|
|
37143
|
-
return;
|
|
37162
|
+
return "";
|
|
37144
37163
|
}
|
|
37145
37164
|
const existing = this.agents.get(agentId);
|
|
37146
37165
|
if (existing) existing.ws.close();
|
|
@@ -37178,17 +37197,17 @@ var AgentHub = class {
|
|
|
37178
37197
|
}
|
|
37179
37198
|
}
|
|
37180
37199
|
}
|
|
37200
|
+
return agentId;
|
|
37181
37201
|
}
|
|
37182
37202
|
handleDisconnect(agentId) {
|
|
37183
37203
|
const info = this.agents.get(agentId);
|
|
37184
37204
|
console.log(`[AgentHub] Agent \u79BB\u7EBF: ${agentId} (${info?.name || "?"})`);
|
|
37185
|
-
for (const [, room] of this.rooms) {
|
|
37205
|
+
for (const [roomId, room] of this.rooms) {
|
|
37186
37206
|
if (room.members.has(agentId)) {
|
|
37187
37207
|
room.members.delete(agentId);
|
|
37188
37208
|
this.sendToRoomMembers(room, {
|
|
37189
37209
|
type: "room:member_left",
|
|
37190
|
-
roomId
|
|
37191
|
-
// fixed below
|
|
37210
|
+
roomId,
|
|
37192
37211
|
agentId
|
|
37193
37212
|
});
|
|
37194
37213
|
}
|
|
@@ -37199,6 +37218,7 @@ var AgentHub = class {
|
|
|
37199
37218
|
t.status = "unassigned";
|
|
37200
37219
|
t.assignedTo = void 0;
|
|
37201
37220
|
t.claimedAt = void 0;
|
|
37221
|
+
this.db?.saveTask({ taskId: tid, status: "unassigned" });
|
|
37202
37222
|
this.broadcast({ type: "task:released", taskId: tid, reason: "Agent \u79BB\u7EBF" });
|
|
37203
37223
|
}
|
|
37204
37224
|
}
|
|
@@ -37231,6 +37251,7 @@ var AgentHub = class {
|
|
|
37231
37251
|
if (a) a.status = "working";
|
|
37232
37252
|
this.joinRoom(agentId, `#task-${taskId}`);
|
|
37233
37253
|
console.log(`[AgentHub] ${agentId} \u8BA4\u9886 ${taskId}`);
|
|
37254
|
+
this.db?.saveTask({ taskId, status: "assigned", title: this.getTaskTitle(taskId), assignedTo: agentId, claimedAt: task.claimedAt });
|
|
37234
37255
|
this.sendTo(agentId, {
|
|
37235
37256
|
type: "task:assigned",
|
|
37236
37257
|
taskId,
|
|
@@ -37256,6 +37277,7 @@ var AgentHub = class {
|
|
|
37256
37277
|
const a = this.agents.get(agentId);
|
|
37257
37278
|
if (a) a.status = "idle";
|
|
37258
37279
|
console.log(`[AgentHub] ${agentId} \u5B8C\u6210 ${taskId}: ${result}`);
|
|
37280
|
+
this.db?.saveTask({ taskId, status: "done", title: this.getTaskTitle(taskId), assignedTo: agentId, result, branch });
|
|
37259
37281
|
this.sendToRoom(`#task-${taskId}`, agentId, `\u5DF2\u5B8C\u6210 ${taskId}: ${result} (branch: ${branch})\uFF0C\u7B49\u5F85\u5BA1\u6838\u3002`);
|
|
37260
37282
|
this.sendToRoom("#review", agentId, `${taskId} \u63D0\u4EA4\u5B8C\u6210\uFF0Cbranch: ${branch}`);
|
|
37261
37283
|
this.broadcast({
|
|
@@ -37287,10 +37309,12 @@ var AgentHub = class {
|
|
|
37287
37309
|
if (!task) return;
|
|
37288
37310
|
if (verdict === "approved") {
|
|
37289
37311
|
task.status = "reviewed";
|
|
37312
|
+
this.db?.saveTask({ taskId, status: "reviewed", reviewedAt: (/* @__PURE__ */ new Date()).toISOString() });
|
|
37290
37313
|
} else {
|
|
37291
37314
|
task.status = "unassigned";
|
|
37292
37315
|
task.assignedTo = void 0;
|
|
37293
37316
|
task.claimedAt = void 0;
|
|
37317
|
+
this.db?.saveTask({ taskId, status: "unassigned" });
|
|
37294
37318
|
}
|
|
37295
37319
|
const roomId = `#task-${taskId}`;
|
|
37296
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"}`;
|
|
@@ -37341,6 +37365,7 @@ var AgentHub = class {
|
|
|
37341
37365
|
const msg = { roomId, from, text, ts: (/* @__PURE__ */ new Date()).toISOString() };
|
|
37342
37366
|
room.messages.push(msg);
|
|
37343
37367
|
if (room.messages.length > MAX_ROOM_MESSAGES) room.messages.shift();
|
|
37368
|
+
this.db?.saveMessage(roomId, from, text, msg.ts);
|
|
37344
37369
|
const raw = JSON.stringify({ type: "room:message", ...msg });
|
|
37345
37370
|
for (const agentId of room.members) {
|
|
37346
37371
|
const a = this.agents.get(agentId);
|
|
@@ -38256,7 +38281,7 @@ async function startStdio(server, version2, auth, readOnly, skipped, skipLog) {
|
|
|
38256
38281
|
await server.connect(transport);
|
|
38257
38282
|
}
|
|
38258
38283
|
async function main() {
|
|
38259
|
-
const VERSION = "0.2.
|
|
38284
|
+
const VERSION = "0.2.57";
|
|
38260
38285
|
const argv = process.argv.slice(2);
|
|
38261
38286
|
if (argv.includes("--help") || argv.includes("-h")) printHelpAndExit(VERSION);
|
|
38262
38287
|
if (argv.includes("--version") || argv.includes("-v")) {
|
package/package.json
CHANGED