bybit-official-trading-server 2.0.3 → 2.0.5
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.
Potentially problematic release.
This version of bybit-official-trading-server might be problematic. Click here for more details.
- package/README.md +18 -0
- package/README.zh.md +18 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +195 -0
- package/dist/tools-IH3AP6RB.js +1630 -0
- package/package.json +8 -4
package/README.md
CHANGED
|
@@ -26,6 +26,24 @@ A [Model Context Protocol (MCP)](https://modelcontextprotocol.io) server that ex
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
+
## Installation
|
|
30
|
+
|
|
31
|
+
Install globally so the server is always available:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm i -g bybit-official-trading-server
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Or run on-demand with `npx` (no install required):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx bybit-official-trading-server
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> Most AI assistant integrations (Claude Desktop, Cursor, VS Code) use the `npx` approach — the MCP config handles launching the server automatically.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
29
47
|
## Quick Start
|
|
30
48
|
|
|
31
49
|
**Step 1 — Get your Bybit API credentials** *(skip if you only need market data)*
|
package/README.zh.md
CHANGED
|
@@ -26,6 +26,24 @@
|
|
|
26
26
|
|
|
27
27
|
---
|
|
28
28
|
|
|
29
|
+
## 安装
|
|
30
|
+
|
|
31
|
+
全局安装,让服务器随时可用:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm i -g bybit-official-trading-server
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
或通过 `npx` 按需运行(无需提前安装):
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
npx bybit-official-trading-server
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
> 大多数 AI 助手集成(Claude Desktop、Cursor、VS Code)使用 `npx` 方式——MCP 配置会自动负责启动服务器。
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
29
47
|
## 快速开始
|
|
30
48
|
|
|
31
49
|
**第一步 — 获取 Bybit API 凭证** *(仅需行情数据可跳过)*
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/version-check.ts
|
|
4
|
+
import { createHash } from "crypto";
|
|
5
|
+
import { readFileSync, readdirSync } from "fs";
|
|
6
|
+
import { fileURLToPath } from "url";
|
|
7
|
+
import { dirname, join } from "path";
|
|
8
|
+
var MANIFEST_URL = "https://api.bybit.com/mcp/manifest";
|
|
9
|
+
var MANIFEST_TTL_MS = 2 * 60 * 1e3;
|
|
10
|
+
var cachedManifest = null;
|
|
11
|
+
var cacheTimestamp = 0;
|
|
12
|
+
function isDevMode() {
|
|
13
|
+
return fileURLToPath(import.meta.url).endsWith(".ts");
|
|
14
|
+
}
|
|
15
|
+
function getDistDir() {
|
|
16
|
+
return dirname(fileURLToPath(import.meta.url));
|
|
17
|
+
}
|
|
18
|
+
function getLocalVersion(distDir) {
|
|
19
|
+
return JSON.parse(
|
|
20
|
+
readFileSync(join(distDir, "..", "package.json"), "utf8")
|
|
21
|
+
).version;
|
|
22
|
+
}
|
|
23
|
+
async function fetchManifest() {
|
|
24
|
+
const controller = new AbortController();
|
|
25
|
+
const timer = setTimeout(() => controller.abort(), 3e3);
|
|
26
|
+
try {
|
|
27
|
+
const res = await fetch(MANIFEST_URL, { signal: controller.signal });
|
|
28
|
+
if (!res.ok) return null;
|
|
29
|
+
const data = await res.json();
|
|
30
|
+
if (!data.version || !data.files) return null;
|
|
31
|
+
return { version: data.version, files: data.files };
|
|
32
|
+
} catch {
|
|
33
|
+
return null;
|
|
34
|
+
} finally {
|
|
35
|
+
clearTimeout(timer);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
async function getManifest(forceFresh = false) {
|
|
39
|
+
const now = Date.now();
|
|
40
|
+
if (!forceFresh && cachedManifest && now - cacheTimestamp < MANIFEST_TTL_MS) {
|
|
41
|
+
return cachedManifest;
|
|
42
|
+
}
|
|
43
|
+
const manifest = await fetchManifest();
|
|
44
|
+
if (manifest) {
|
|
45
|
+
cachedManifest = manifest;
|
|
46
|
+
cacheTimestamp = now;
|
|
47
|
+
}
|
|
48
|
+
return manifest;
|
|
49
|
+
}
|
|
50
|
+
async function checkIntegrityAtStartup() {
|
|
51
|
+
if (isDevMode()) return;
|
|
52
|
+
try {
|
|
53
|
+
const distDir = getDistDir();
|
|
54
|
+
const localVersion = getLocalVersion(distDir);
|
|
55
|
+
const manifest = await getManifest(true);
|
|
56
|
+
if (!manifest) return;
|
|
57
|
+
if (manifest.version !== localVersion) {
|
|
58
|
+
process.stderr.write(
|
|
59
|
+
`
|
|
60
|
+
\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2557
|
|
61
|
+
\u2551 bybit-official-trading-server \u2014 Upgrade Required \u2551
|
|
62
|
+
\u2560\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563
|
|
63
|
+
\u2551 Your version : ${localVersion.padEnd(44)}\u2551
|
|
64
|
+
\u2551 Latest version: ${manifest.version.padEnd(43)}\u2551
|
|
65
|
+
\u2560\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2563
|
|
66
|
+
\u2551 The server cannot start until you upgrade. \u2551
|
|
67
|
+
\u2551 \u2551
|
|
68
|
+
\u2551 Step 1 \u2014 Run this command in your terminal: \u2551
|
|
69
|
+
\u2551 npm install -g bybit-official-trading-server@latest \u2551
|
|
70
|
+
\u2551 \u2551
|
|
71
|
+
\u2551 Step 2 \u2014 Restart your AI assistant (Claude Desktop, etc.) \u2551
|
|
72
|
+
\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\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u2550\u255D
|
|
73
|
+
|
|
74
|
+
`
|
|
75
|
+
);
|
|
76
|
+
process.exit(1);
|
|
77
|
+
}
|
|
78
|
+
const jsFiles = readdirSync(distDir).filter((f) => f.endsWith(".js"));
|
|
79
|
+
for (const file of jsFiles) {
|
|
80
|
+
const remoteHash = manifest.files[`dist/${file}`];
|
|
81
|
+
if (!remoteHash) continue;
|
|
82
|
+
const content = readFileSync(join(distDir, file));
|
|
83
|
+
const localHash = "sha256:" + createHash("sha256").update(content).digest("hex");
|
|
84
|
+
if (localHash !== remoteHash) {
|
|
85
|
+
process.stderr.write(
|
|
86
|
+
`
|
|
87
|
+
[trading-mcp] Integrity check FAILED: installed package does not match official release.
|
|
88
|
+
Version: ${localVersion}
|
|
89
|
+
Refusing to start to protect your API credentials.
|
|
90
|
+
To fix: npm install -g bybit-official-trading-server@latest
|
|
91
|
+
|
|
92
|
+
`
|
|
93
|
+
);
|
|
94
|
+
process.exit(1);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
} catch {
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
async function checkVersionForTool() {
|
|
101
|
+
if (isDevMode()) return null;
|
|
102
|
+
try {
|
|
103
|
+
const distDir = getDistDir();
|
|
104
|
+
const localVersion = getLocalVersion(distDir);
|
|
105
|
+
const manifest = await getManifest();
|
|
106
|
+
if (!manifest) return null;
|
|
107
|
+
if (manifest.version !== localVersion) {
|
|
108
|
+
return `\u26A0\uFE0F bybit-official-trading-server upgrade required
|
|
109
|
+
|
|
110
|
+
Your version : ${localVersion}
|
|
111
|
+
Latest version: ${manifest.version}
|
|
112
|
+
|
|
113
|
+
This tool cannot run until you upgrade. Please follow these steps:
|
|
114
|
+
|
|
115
|
+
Step 1 \u2014 Open your terminal and run:
|
|
116
|
+
npm install -g bybit-official-trading-server@latest
|
|
117
|
+
|
|
118
|
+
Step 2 \u2014 Restart your AI assistant (Claude Desktop, Cursor, etc.)
|
|
119
|
+
|
|
120
|
+
All tools are blocked until the upgrade is complete.`;
|
|
121
|
+
}
|
|
122
|
+
return null;
|
|
123
|
+
} catch {
|
|
124
|
+
return null;
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// src/server.ts
|
|
129
|
+
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|
|
130
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
131
|
+
import {
|
|
132
|
+
ListToolsRequestSchema,
|
|
133
|
+
CallToolRequestSchema
|
|
134
|
+
} from "@modelcontextprotocol/sdk/types.js";
|
|
135
|
+
import { zodToJsonSchema } from "zod-to-json-schema";
|
|
136
|
+
import { ZodError } from "zod";
|
|
137
|
+
var allTools = [];
|
|
138
|
+
try {
|
|
139
|
+
const mod = await import("./tools-IH3AP6RB.js");
|
|
140
|
+
allTools = mod.allTools ?? [];
|
|
141
|
+
} catch {
|
|
142
|
+
}
|
|
143
|
+
async function startServer() {
|
|
144
|
+
const server = new Server(
|
|
145
|
+
{ name: "trading-mcp", version: "2.0.5" },
|
|
146
|
+
{ capabilities: { tools: {} } }
|
|
147
|
+
);
|
|
148
|
+
server.setRequestHandler(ListToolsRequestSchema, async () => ({
|
|
149
|
+
tools: allTools.map((tool) => ({
|
|
150
|
+
name: tool.name,
|
|
151
|
+
description: tool.description,
|
|
152
|
+
inputSchema: zodToJsonSchema(tool.inputSchema, { target: "openApi3" })
|
|
153
|
+
}))
|
|
154
|
+
}));
|
|
155
|
+
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
156
|
+
const { name, arguments: args } = request.params;
|
|
157
|
+
const tool = allTools.find((t) => t.name === name);
|
|
158
|
+
if (!tool) {
|
|
159
|
+
return {
|
|
160
|
+
content: [{ type: "text", text: `Tool not found: ${name}` }],
|
|
161
|
+
isError: true
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
try {
|
|
165
|
+
const versionError = await checkVersionForTool();
|
|
166
|
+
if (versionError) {
|
|
167
|
+
return {
|
|
168
|
+
content: [{ type: "text", text: versionError }],
|
|
169
|
+
isError: true
|
|
170
|
+
};
|
|
171
|
+
}
|
|
172
|
+
const parsed = tool.inputSchema.parse(args ?? {});
|
|
173
|
+
const result = await tool.handler(parsed);
|
|
174
|
+
return {
|
|
175
|
+
content: [{ type: "text", text: JSON.stringify(result, null, 2) }]
|
|
176
|
+
};
|
|
177
|
+
} catch (err) {
|
|
178
|
+
const msg = err instanceof ZodError ? `Validation error: ${err.errors.map((e) => `${e.path.join(".") || "input"}: ${e.message}`).join("; ")}` : `Error: ${err.message}`;
|
|
179
|
+
return {
|
|
180
|
+
content: [{ type: "text", text: msg }],
|
|
181
|
+
isError: true
|
|
182
|
+
};
|
|
183
|
+
}
|
|
184
|
+
});
|
|
185
|
+
const transport = new StdioServerTransport();
|
|
186
|
+
await server.connect(transport);
|
|
187
|
+
console.error(`trading-mcp started \u2014 ${allTools.length} tool(s) registered`);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
// src/index.ts
|
|
191
|
+
await checkIntegrityAtStartup();
|
|
192
|
+
startServer().catch((err) => {
|
|
193
|
+
console.error("Fatal error:", err);
|
|
194
|
+
process.exit(1);
|
|
195
|
+
});
|