@okx_ai/okx-trade-mcp 1.2.8 → 1.2.9-beta.2
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 +107 -14
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/scripts/postinstall-download.js +152 -0
package/dist/index.js
CHANGED
|
@@ -2049,6 +2049,59 @@ function registerAccountTools() {
|
|
|
2049
2049
|
}
|
|
2050
2050
|
];
|
|
2051
2051
|
}
|
|
2052
|
+
async function resolveQuoteCcySz(instId, sz, tgtCcy, instType, client) {
|
|
2053
|
+
if (tgtCcy !== "quote_ccy") {
|
|
2054
|
+
return { sz, tgtCcy, conversionNote: void 0 };
|
|
2055
|
+
}
|
|
2056
|
+
const [instrumentsRes, tickerRes] = await Promise.all([
|
|
2057
|
+
client.publicGet("/api/v5/public/instruments", {
|
|
2058
|
+
instType,
|
|
2059
|
+
instId
|
|
2060
|
+
}),
|
|
2061
|
+
client.publicGet("/api/v5/market/ticker", { instId })
|
|
2062
|
+
]);
|
|
2063
|
+
const instruments = Array.isArray(instrumentsRes.data) ? instrumentsRes.data : [];
|
|
2064
|
+
if (instruments.length === 0) {
|
|
2065
|
+
throw new Error(
|
|
2066
|
+
`Failed to fetch instrument info for ${instId}: empty instrument list. Cannot determine ctVal for quote_ccy conversion.`
|
|
2067
|
+
);
|
|
2068
|
+
}
|
|
2069
|
+
const ctValStr = String(instruments[0].ctVal ?? "");
|
|
2070
|
+
const ctVal = parseFloat(ctValStr);
|
|
2071
|
+
if (!isFinite(ctVal) || ctVal <= 0) {
|
|
2072
|
+
throw new Error(
|
|
2073
|
+
`Invalid ctVal "${ctValStr}" for ${instId}. ctVal must be a positive number for quote_ccy conversion.`
|
|
2074
|
+
);
|
|
2075
|
+
}
|
|
2076
|
+
const tickers = Array.isArray(tickerRes.data) ? tickerRes.data : [];
|
|
2077
|
+
if (tickers.length === 0) {
|
|
2078
|
+
throw new Error(
|
|
2079
|
+
`Failed to fetch ticker price for ${instId}: empty ticker response. Cannot determine last price for quote_ccy conversion.`
|
|
2080
|
+
);
|
|
2081
|
+
}
|
|
2082
|
+
const lastStr = String(tickers[0].last ?? "");
|
|
2083
|
+
const lastPx = parseFloat(lastStr);
|
|
2084
|
+
if (!isFinite(lastPx) || lastPx <= 0) {
|
|
2085
|
+
throw new Error(
|
|
2086
|
+
`Invalid last price "${lastStr}" for ${instId}. Last price must be a positive number for quote_ccy conversion.`
|
|
2087
|
+
);
|
|
2088
|
+
}
|
|
2089
|
+
const usdtAmount = parseFloat(sz);
|
|
2090
|
+
const contractValue = ctVal * lastPx;
|
|
2091
|
+
const contracts = Math.floor(usdtAmount / contractValue);
|
|
2092
|
+
if (contracts <= 0) {
|
|
2093
|
+
const minUsdt = contractValue.toFixed(2);
|
|
2094
|
+
throw new Error(
|
|
2095
|
+
`sz=${sz} USDT is too small to buy even 1 contract of ${instId}. Minimum amount required is at least ${minUsdt} USDT (ctVal=${ctValStr}, lastPx=${lastStr}, 1 contract = ${minUsdt} USDT).`
|
|
2096
|
+
);
|
|
2097
|
+
}
|
|
2098
|
+
const conversionNote = `Converting ${sz} USDT \u2192 ${contracts} contracts (ctVal=${ctValStr}, lastPx=${lastStr}, formula: floor(${sz} / (${ctValStr} \xD7 ${lastStr})) = ${contracts})`;
|
|
2099
|
+
return {
|
|
2100
|
+
sz: String(contracts),
|
|
2101
|
+
tgtCcy: void 0,
|
|
2102
|
+
conversionNote
|
|
2103
|
+
};
|
|
2104
|
+
}
|
|
2052
2105
|
function registerAlgoTradeTools() {
|
|
2053
2106
|
return [
|
|
2054
2107
|
{
|
|
@@ -2144,6 +2197,13 @@ function registerAlgoTradeTools() {
|
|
|
2144
2197
|
handler: async (rawArgs, context) => {
|
|
2145
2198
|
const args = asRecord(rawArgs);
|
|
2146
2199
|
const reduceOnly = args.reduceOnly;
|
|
2200
|
+
const resolved = await resolveQuoteCcySz(
|
|
2201
|
+
requireString(args, "instId"),
|
|
2202
|
+
requireString(args, "sz"),
|
|
2203
|
+
readString(args, "tgtCcy"),
|
|
2204
|
+
"SWAP",
|
|
2205
|
+
context.client
|
|
2206
|
+
);
|
|
2147
2207
|
const response = await context.client.privatePost(
|
|
2148
2208
|
"/api/v5/trade/order-algo",
|
|
2149
2209
|
compactObject({
|
|
@@ -2152,8 +2212,8 @@ function registerAlgoTradeTools() {
|
|
|
2152
2212
|
side: requireString(args, "side"),
|
|
2153
2213
|
posSide: readString(args, "posSide"),
|
|
2154
2214
|
ordType: requireString(args, "ordType"),
|
|
2155
|
-
sz:
|
|
2156
|
-
tgtCcy:
|
|
2215
|
+
sz: resolved.sz,
|
|
2216
|
+
tgtCcy: resolved.tgtCcy,
|
|
2157
2217
|
tpTriggerPx: readString(args, "tpTriggerPx"),
|
|
2158
2218
|
tpOrdPx: readString(args, "tpOrdPx"),
|
|
2159
2219
|
tpTriggerPxType: readString(args, "tpTriggerPxType"),
|
|
@@ -2169,7 +2229,11 @@ function registerAlgoTradeTools() {
|
|
|
2169
2229
|
}),
|
|
2170
2230
|
privateRateLimit("swap_place_algo_order", 20)
|
|
2171
2231
|
);
|
|
2172
|
-
|
|
2232
|
+
const result = normalizeResponse(response);
|
|
2233
|
+
if (resolved.conversionNote) {
|
|
2234
|
+
result._conversion = resolved.conversionNote;
|
|
2235
|
+
}
|
|
2236
|
+
return result;
|
|
2173
2237
|
}
|
|
2174
2238
|
},
|
|
2175
2239
|
{
|
|
@@ -2477,6 +2541,13 @@ function registerFuturesAlgoTools() {
|
|
|
2477
2541
|
handler: async (rawArgs, context) => {
|
|
2478
2542
|
const args = asRecord(rawArgs);
|
|
2479
2543
|
const reduceOnly = args.reduceOnly;
|
|
2544
|
+
const resolved = await resolveQuoteCcySz(
|
|
2545
|
+
requireString(args, "instId"),
|
|
2546
|
+
requireString(args, "sz"),
|
|
2547
|
+
readString(args, "tgtCcy"),
|
|
2548
|
+
"FUTURES",
|
|
2549
|
+
context.client
|
|
2550
|
+
);
|
|
2480
2551
|
const response = await context.client.privatePost(
|
|
2481
2552
|
"/api/v5/trade/order-algo",
|
|
2482
2553
|
compactObject({
|
|
@@ -2485,8 +2556,8 @@ function registerFuturesAlgoTools() {
|
|
|
2485
2556
|
side: requireString(args, "side"),
|
|
2486
2557
|
posSide: readString(args, "posSide"),
|
|
2487
2558
|
ordType: requireString(args, "ordType"),
|
|
2488
|
-
sz:
|
|
2489
|
-
tgtCcy:
|
|
2559
|
+
sz: resolved.sz,
|
|
2560
|
+
tgtCcy: resolved.tgtCcy,
|
|
2490
2561
|
tpTriggerPx: readString(args, "tpTriggerPx"),
|
|
2491
2562
|
tpOrdPx: readString(args, "tpOrdPx"),
|
|
2492
2563
|
tpTriggerPxType: readString(args, "tpTriggerPxType"),
|
|
@@ -2502,7 +2573,11 @@ function registerFuturesAlgoTools() {
|
|
|
2502
2573
|
}),
|
|
2503
2574
|
privateRateLimit("futures_place_algo_order", 20)
|
|
2504
2575
|
);
|
|
2505
|
-
|
|
2576
|
+
const result = normalizeResponse(response);
|
|
2577
|
+
if (resolved.conversionNote) {
|
|
2578
|
+
result._conversion = resolved.conversionNote;
|
|
2579
|
+
}
|
|
2580
|
+
return result;
|
|
2506
2581
|
}
|
|
2507
2582
|
},
|
|
2508
2583
|
{
|
|
@@ -2911,7 +2986,7 @@ function registerSkillsTools() {
|
|
|
2911
2986
|
{
|
|
2912
2987
|
name: "skills_download",
|
|
2913
2988
|
module: "skills",
|
|
2914
|
-
description: "Download a skill zip file from OKX Skills Marketplace to a local directory. Always call skills_search first to confirm the skill name exists. Downloads the latest approved version. NOTE:
|
|
2989
|
+
description: "Download a skill zip file from OKX Skills Marketplace to a local directory. Always call skills_search first to confirm the skill name exists. Downloads the latest approved version. NOTE: Downloads third-party developer content as a zip \u2014 does NOT install to agents. For full installation use CLI: okx skill add <name>. Use when the user wants to inspect or manually install a skill package.",
|
|
2915
2990
|
inputSchema: {
|
|
2916
2991
|
type: "object",
|
|
2917
2992
|
properties: {
|
|
@@ -4432,6 +4507,13 @@ function buildContractTradeTools(cfg) {
|
|
|
4432
4507
|
const args = asRecord(rawArgs);
|
|
4433
4508
|
const reduceOnly = args.reduceOnly;
|
|
4434
4509
|
const attachAlgoOrds = buildAttachAlgoOrds(args);
|
|
4510
|
+
const resolved = await resolveQuoteCcySz(
|
|
4511
|
+
requireString(args, "instId"),
|
|
4512
|
+
requireString(args, "sz"),
|
|
4513
|
+
readString(args, "tgtCcy"),
|
|
4514
|
+
defaultType,
|
|
4515
|
+
context.client
|
|
4516
|
+
);
|
|
4435
4517
|
const response = await context.client.privatePost(
|
|
4436
4518
|
"/api/v5/trade/order",
|
|
4437
4519
|
compactObject({
|
|
@@ -4440,8 +4522,8 @@ function buildContractTradeTools(cfg) {
|
|
|
4440
4522
|
side: requireString(args, "side"),
|
|
4441
4523
|
posSide: readString(args, "posSide"),
|
|
4442
4524
|
ordType: requireString(args, "ordType"),
|
|
4443
|
-
sz:
|
|
4444
|
-
tgtCcy:
|
|
4525
|
+
sz: resolved.sz,
|
|
4526
|
+
tgtCcy: resolved.tgtCcy,
|
|
4445
4527
|
px: readString(args, "px"),
|
|
4446
4528
|
reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
|
|
4447
4529
|
clOrdId: readString(args, "clOrdId"),
|
|
@@ -4450,7 +4532,11 @@ function buildContractTradeTools(cfg) {
|
|
|
4450
4532
|
}),
|
|
4451
4533
|
privateRateLimit(n("place_order"), 60)
|
|
4452
4534
|
);
|
|
4453
|
-
|
|
4535
|
+
const result = normalizeResponse(response);
|
|
4536
|
+
if (resolved.conversionNote) {
|
|
4537
|
+
result._conversion = resolved.conversionNote;
|
|
4538
|
+
}
|
|
4539
|
+
return result;
|
|
4454
4540
|
}
|
|
4455
4541
|
},
|
|
4456
4542
|
// ── cancel_order ─────────────────────────────────────────────────────────
|
|
@@ -5525,7 +5611,7 @@ function registerOptionAlgoTools() {
|
|
|
5525
5611
|
tgtCcy: {
|
|
5526
5612
|
type: "string",
|
|
5527
5613
|
enum: ["base_ccy", "quote_ccy"],
|
|
5528
|
-
description: "Size unit. base_ccy(default): sz in contracts, quote_ccy: sz in USDT (
|
|
5614
|
+
description: "Size unit. base_ccy(default): sz in contracts, quote_ccy: sz in USDT (auto-converted to contracts)"
|
|
5529
5615
|
},
|
|
5530
5616
|
reduceOnly: {
|
|
5531
5617
|
type: "boolean",
|
|
@@ -5541,6 +5627,13 @@ function registerOptionAlgoTools() {
|
|
|
5541
5627
|
handler: async (rawArgs, context) => {
|
|
5542
5628
|
const args = asRecord(rawArgs);
|
|
5543
5629
|
const reduceOnly = readBoolean(args, "reduceOnly");
|
|
5630
|
+
const resolved = await resolveQuoteCcySz(
|
|
5631
|
+
requireString(args, "instId"),
|
|
5632
|
+
requireString(args, "sz"),
|
|
5633
|
+
readString(args, "tgtCcy"),
|
|
5634
|
+
"OPTION",
|
|
5635
|
+
context.client
|
|
5636
|
+
);
|
|
5544
5637
|
const response = await context.client.privatePost(
|
|
5545
5638
|
"/api/v5/trade/order-algo",
|
|
5546
5639
|
compactObject({
|
|
@@ -5548,8 +5641,8 @@ function registerOptionAlgoTools() {
|
|
|
5548
5641
|
tdMode: requireString(args, "tdMode"),
|
|
5549
5642
|
side: requireString(args, "side"),
|
|
5550
5643
|
ordType: requireString(args, "ordType"),
|
|
5551
|
-
sz:
|
|
5552
|
-
tgtCcy:
|
|
5644
|
+
sz: resolved.sz,
|
|
5645
|
+
tgtCcy: resolved.tgtCcy,
|
|
5553
5646
|
tpTriggerPx: readString(args, "tpTriggerPx"),
|
|
5554
5647
|
tpOrdPx: readString(args, "tpOrdPx"),
|
|
5555
5648
|
tpTriggerPxType: readString(args, "tpTriggerPxType"),
|
|
@@ -7384,7 +7477,7 @@ var _require = createRequire(import.meta.url);
|
|
|
7384
7477
|
var pkg = _require("../package.json");
|
|
7385
7478
|
var SERVER_NAME = "okx-trade-mcp";
|
|
7386
7479
|
var SERVER_VERSION = pkg.version;
|
|
7387
|
-
var GIT_HASH = true ? "
|
|
7480
|
+
var GIT_HASH = true ? "5f833a2" : "dev";
|
|
7388
7481
|
|
|
7389
7482
|
// src/server.ts
|
|
7390
7483
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|