@okx_ai/okx-trade-mcp 1.2.5 → 1.2.6
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 +185 -46
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -882,9 +882,9 @@ var OKX_CODE_BEHAVIORS = {
|
|
|
882
882
|
"50100": { retry: false, suggestion: "API key lacks required permissions. Update API key permissions." },
|
|
883
883
|
"50110": { retry: false, suggestion: "API key expired. Generate a new API key." },
|
|
884
884
|
// Insufficient funds / margin → do not retry
|
|
885
|
-
"51008": { retry: false, suggestion: "Insufficient balance.
|
|
886
|
-
"51119": { retry: false, suggestion: "Insufficient margin. Add margin
|
|
887
|
-
"51127": { retry: false, suggestion: "Insufficient available margin. Reduce position or
|
|
885
|
+
"51008": { retry: false, suggestion: "Insufficient balance in trading account. Check funding account via account_get_asset_balance \u2014 funds may be there. Use account_transfer (from=18, to=6) to move funds to trading account, then retry." },
|
|
886
|
+
"51119": { retry: false, suggestion: "Insufficient margin. Add margin or check funding account (account_get_asset_balance). Transfer via account_transfer (from=18, to=6) if needed." },
|
|
887
|
+
"51127": { retry: false, suggestion: "Insufficient available margin. Reduce position, add margin, or transfer from funding account (account_transfer from=18 to=6)." },
|
|
888
888
|
// Instrument unavailable → do not retry
|
|
889
889
|
"51021": { retry: false, suggestion: "Instrument does not exist. Check instId." },
|
|
890
890
|
"51022": { retry: false, suggestion: "Instrument not available for trading." },
|
|
@@ -967,6 +967,15 @@ var OkxRestClient = class {
|
|
|
967
967
|
rateLimit
|
|
968
968
|
});
|
|
969
969
|
}
|
|
970
|
+
async publicPost(path4, body, rateLimit) {
|
|
971
|
+
return this.request({
|
|
972
|
+
method: "POST",
|
|
973
|
+
path: path4,
|
|
974
|
+
auth: "public",
|
|
975
|
+
body,
|
|
976
|
+
rateLimit
|
|
977
|
+
});
|
|
978
|
+
}
|
|
970
979
|
async privatePost(path4, body, rateLimit) {
|
|
971
980
|
return this.request({
|
|
972
981
|
method: "POST",
|
|
@@ -1121,46 +1130,6 @@ var OkxRestClient = class {
|
|
|
1121
1130
|
return this.processResponse(rawText, response, elapsed, traceId, reqConfig, requestPath);
|
|
1122
1131
|
}
|
|
1123
1132
|
};
|
|
1124
|
-
var DEFAULT_SOURCE_TAG = "MCP";
|
|
1125
|
-
var OKX_SITES = {
|
|
1126
|
-
global: {
|
|
1127
|
-
label: "Global",
|
|
1128
|
-
apiBaseUrl: "https://www.okx.com",
|
|
1129
|
-
webUrl: "https://www.okx.com"
|
|
1130
|
-
},
|
|
1131
|
-
eea: {
|
|
1132
|
-
label: "EEA",
|
|
1133
|
-
apiBaseUrl: "https://eea.okx.com",
|
|
1134
|
-
webUrl: "https://my.okx.com"
|
|
1135
|
-
},
|
|
1136
|
-
us: {
|
|
1137
|
-
label: "US",
|
|
1138
|
-
apiBaseUrl: "https://app.okx.com",
|
|
1139
|
-
webUrl: "https://app.okx.com"
|
|
1140
|
-
}
|
|
1141
|
-
};
|
|
1142
|
-
var SITE_IDS = Object.keys(OKX_SITES);
|
|
1143
|
-
var BOT_SUB_MODULE_IDS = [
|
|
1144
|
-
"bot.grid",
|
|
1145
|
-
"bot.dca"
|
|
1146
|
-
];
|
|
1147
|
-
var BOT_DEFAULT_SUB_MODULES = ["bot.grid"];
|
|
1148
|
-
var EARN_SUB_MODULE_IDS = [
|
|
1149
|
-
"earn.savings",
|
|
1150
|
-
"earn.onchain",
|
|
1151
|
-
"earn.dcd"
|
|
1152
|
-
];
|
|
1153
|
-
var MODULES = [
|
|
1154
|
-
"market",
|
|
1155
|
-
"spot",
|
|
1156
|
-
"swap",
|
|
1157
|
-
"futures",
|
|
1158
|
-
"option",
|
|
1159
|
-
"account",
|
|
1160
|
-
...EARN_SUB_MODULE_IDS,
|
|
1161
|
-
...BOT_SUB_MODULE_IDS
|
|
1162
|
-
];
|
|
1163
|
-
var DEFAULT_MODULES = ["spot", "swap", "option", "account", ...BOT_DEFAULT_SUB_MODULES];
|
|
1164
1133
|
function asRecord(value) {
|
|
1165
1134
|
if (!value || typeof value !== "object" || Array.isArray(value)) {
|
|
1166
1135
|
return {};
|
|
@@ -1285,6 +1254,152 @@ function assertNotDemo(config, endpoint) {
|
|
|
1285
1254
|
);
|
|
1286
1255
|
}
|
|
1287
1256
|
}
|
|
1257
|
+
var INDICATOR_BARS = [
|
|
1258
|
+
"3m",
|
|
1259
|
+
"5m",
|
|
1260
|
+
"15m",
|
|
1261
|
+
"1H",
|
|
1262
|
+
"4H",
|
|
1263
|
+
"12Hutc",
|
|
1264
|
+
"1Dutc",
|
|
1265
|
+
"3Dutc",
|
|
1266
|
+
"1Wutc"
|
|
1267
|
+
];
|
|
1268
|
+
var INDICATOR_CODE_OVERRIDES = {
|
|
1269
|
+
"rainbow": "BTCRAINBOW",
|
|
1270
|
+
"range-filter": "RANGEFILTER",
|
|
1271
|
+
"stoch-rsi": "STOCHRSI",
|
|
1272
|
+
"pi-cycle-top": "PI_CYCLE_TOP",
|
|
1273
|
+
"pi-cycle-bottom": "PI_CYCLE_BOTTOM",
|
|
1274
|
+
// boll is an alias for bb; server supports BB not BOLL
|
|
1275
|
+
"boll": "BB"
|
|
1276
|
+
};
|
|
1277
|
+
function resolveIndicatorCode(name) {
|
|
1278
|
+
const lower = name.toLowerCase();
|
|
1279
|
+
return INDICATOR_CODE_OVERRIDES[lower] ?? name.toUpperCase().replace(/-/g, "_");
|
|
1280
|
+
}
|
|
1281
|
+
function readNumberArray(args, key) {
|
|
1282
|
+
const value = args[key];
|
|
1283
|
+
if (value === void 0 || value === null) return void 0;
|
|
1284
|
+
if (!Array.isArray(value)) return void 0;
|
|
1285
|
+
return value.map((item) => Number(item));
|
|
1286
|
+
}
|
|
1287
|
+
function registerIndicatorTools() {
|
|
1288
|
+
return [
|
|
1289
|
+
{
|
|
1290
|
+
name: "market_get_indicator",
|
|
1291
|
+
module: "market",
|
|
1292
|
+
description: "Get technical indicator values for an instrument (MA, EMA, RSI, MACD, BB, KDJ, SUPERTREND, AHR999, BTCRAINBOW, and more). No credentials required.",
|
|
1293
|
+
isWrite: false,
|
|
1294
|
+
inputSchema: {
|
|
1295
|
+
type: "object",
|
|
1296
|
+
properties: {
|
|
1297
|
+
instId: {
|
|
1298
|
+
type: "string",
|
|
1299
|
+
description: "Instrument ID, e.g. BTC-USDT"
|
|
1300
|
+
},
|
|
1301
|
+
indicator: {
|
|
1302
|
+
type: "string",
|
|
1303
|
+
description: "Indicator name (case-insensitive). Examples: ma, ema, rsi, macd, bb, kdj, supertrend, ahr999, rainbow, pi-cycle-top, pi-cycle-bottom, mayer, envelope, halftrend, alphatrend, pmax, waddah, tdi, qqe, range-filter"
|
|
1304
|
+
},
|
|
1305
|
+
bar: {
|
|
1306
|
+
type: "string",
|
|
1307
|
+
enum: [...INDICATOR_BARS],
|
|
1308
|
+
description: "Timeframe. Default: 1H"
|
|
1309
|
+
},
|
|
1310
|
+
params: {
|
|
1311
|
+
type: "array",
|
|
1312
|
+
items: { type: "number" },
|
|
1313
|
+
description: "Indicator parameters, e.g. [5, 20] for MA with periods 5 and 20"
|
|
1314
|
+
},
|
|
1315
|
+
returnList: {
|
|
1316
|
+
type: "boolean",
|
|
1317
|
+
description: "Return a historical list instead of the latest value only. Default: false"
|
|
1318
|
+
},
|
|
1319
|
+
limit: {
|
|
1320
|
+
type: "integer",
|
|
1321
|
+
minimum: 1,
|
|
1322
|
+
maximum: 100,
|
|
1323
|
+
description: "Number of historical records to return (only used when returnList=true). Default: 10"
|
|
1324
|
+
},
|
|
1325
|
+
backtestTime: {
|
|
1326
|
+
type: "integer",
|
|
1327
|
+
description: "Backtest timestamp in milliseconds. Omit for live (real-time) mode"
|
|
1328
|
+
}
|
|
1329
|
+
},
|
|
1330
|
+
required: ["instId", "indicator"]
|
|
1331
|
+
},
|
|
1332
|
+
handler: async (rawArgs, context) => {
|
|
1333
|
+
const args = asRecord(rawArgs);
|
|
1334
|
+
const instId = requireString(args, "instId");
|
|
1335
|
+
const indicator = requireString(args, "indicator");
|
|
1336
|
+
const bar = readString(args, "bar") ?? "1H";
|
|
1337
|
+
const params = readNumberArray(args, "params");
|
|
1338
|
+
const returnList = readBoolean(args, "returnList") ?? false;
|
|
1339
|
+
const limit = readNumber(args, "limit") ?? 10;
|
|
1340
|
+
const backtestTime = readNumber(args, "backtestTime");
|
|
1341
|
+
const apiCode = resolveIndicatorCode(indicator);
|
|
1342
|
+
const indicatorConfig = compactObject({
|
|
1343
|
+
paramList: params && params.length > 0 ? params : void 0,
|
|
1344
|
+
returnList,
|
|
1345
|
+
limit: returnList ? limit : void 0
|
|
1346
|
+
});
|
|
1347
|
+
const body = compactObject({
|
|
1348
|
+
instId,
|
|
1349
|
+
timeframes: [bar],
|
|
1350
|
+
indicators: { [apiCode]: indicatorConfig },
|
|
1351
|
+
backtestTime
|
|
1352
|
+
});
|
|
1353
|
+
const response = await context.client.publicPost(
|
|
1354
|
+
"/api/v5/aigc/mcp/indicators",
|
|
1355
|
+
body,
|
|
1356
|
+
publicRateLimit("market_get_indicator", 5)
|
|
1357
|
+
);
|
|
1358
|
+
return normalizeResponse(response);
|
|
1359
|
+
}
|
|
1360
|
+
}
|
|
1361
|
+
];
|
|
1362
|
+
}
|
|
1363
|
+
var DEFAULT_SOURCE_TAG = "MCP";
|
|
1364
|
+
var OKX_SITES = {
|
|
1365
|
+
global: {
|
|
1366
|
+
label: "Global",
|
|
1367
|
+
apiBaseUrl: "https://www.okx.com",
|
|
1368
|
+
webUrl: "https://www.okx.com"
|
|
1369
|
+
},
|
|
1370
|
+
eea: {
|
|
1371
|
+
label: "EEA",
|
|
1372
|
+
apiBaseUrl: "https://eea.okx.com",
|
|
1373
|
+
webUrl: "https://my.okx.com"
|
|
1374
|
+
},
|
|
1375
|
+
us: {
|
|
1376
|
+
label: "US",
|
|
1377
|
+
apiBaseUrl: "https://app.okx.com",
|
|
1378
|
+
webUrl: "https://app.okx.com"
|
|
1379
|
+
}
|
|
1380
|
+
};
|
|
1381
|
+
var SITE_IDS = Object.keys(OKX_SITES);
|
|
1382
|
+
var BOT_SUB_MODULE_IDS = [
|
|
1383
|
+
"bot.grid",
|
|
1384
|
+
"bot.dca"
|
|
1385
|
+
];
|
|
1386
|
+
var BOT_DEFAULT_SUB_MODULES = ["bot.grid"];
|
|
1387
|
+
var EARN_SUB_MODULE_IDS = [
|
|
1388
|
+
"earn.savings",
|
|
1389
|
+
"earn.onchain",
|
|
1390
|
+
"earn.dcd"
|
|
1391
|
+
];
|
|
1392
|
+
var MODULES = [
|
|
1393
|
+
"market",
|
|
1394
|
+
"spot",
|
|
1395
|
+
"swap",
|
|
1396
|
+
"futures",
|
|
1397
|
+
"option",
|
|
1398
|
+
"account",
|
|
1399
|
+
...EARN_SUB_MODULE_IDS,
|
|
1400
|
+
...BOT_SUB_MODULE_IDS
|
|
1401
|
+
];
|
|
1402
|
+
var DEFAULT_MODULES = ["spot", "swap", "option", "account", ...BOT_DEFAULT_SUB_MODULES];
|
|
1288
1403
|
function registerAccountTools() {
|
|
1289
1404
|
return [
|
|
1290
1405
|
{
|
|
@@ -3922,7 +4037,12 @@ function buildContractTradeTools(cfg) {
|
|
|
3922
4037
|
},
|
|
3923
4038
|
sz: {
|
|
3924
4039
|
type: "string",
|
|
3925
|
-
description: "Contracts count
|
|
4040
|
+
description: "Contracts count by default. Set tgtCcy=quote_ccy to use USDT amount instead."
|
|
4041
|
+
},
|
|
4042
|
+
tgtCcy: {
|
|
4043
|
+
type: "string",
|
|
4044
|
+
enum: ["base_ccy", "quote_ccy"],
|
|
4045
|
+
description: "Size unit. base_ccy(default): sz in contracts, quote_ccy: sz in USDT"
|
|
3926
4046
|
},
|
|
3927
4047
|
px: { type: "string", description: "Required for limit/post_only/fok/ioc" },
|
|
3928
4048
|
reduceOnly: {
|
|
@@ -3950,6 +4070,7 @@ function buildContractTradeTools(cfg) {
|
|
|
3950
4070
|
posSide: readString(args, "posSide"),
|
|
3951
4071
|
ordType: requireString(args, "ordType"),
|
|
3952
4072
|
sz: requireString(args, "sz"),
|
|
4073
|
+
tgtCcy: readString(args, "tgtCcy"),
|
|
3953
4074
|
px: readString(args, "px"),
|
|
3954
4075
|
reduceOnly: typeof reduceOnly === "boolean" ? String(reduceOnly) : void 0,
|
|
3955
4076
|
clOrdId: readString(args, "clOrdId"),
|
|
@@ -5605,6 +5726,11 @@ function registerSpotTradeTools() {
|
|
|
5605
5726
|
type: "string",
|
|
5606
5727
|
description: "Buy market: quote amount, all others: base amount"
|
|
5607
5728
|
},
|
|
5729
|
+
tgtCcy: {
|
|
5730
|
+
type: "string",
|
|
5731
|
+
enum: ["base_ccy", "quote_ccy"],
|
|
5732
|
+
description: "Size unit. base_ccy(default): sz in base (e.g. BTC), quote_ccy: sz in quote (e.g. USDT)"
|
|
5733
|
+
},
|
|
5608
5734
|
px: {
|
|
5609
5735
|
type: "string",
|
|
5610
5736
|
description: "Required for limit/post_only/fok/ioc"
|
|
@@ -5643,6 +5769,7 @@ function registerSpotTradeTools() {
|
|
|
5643
5769
|
side: requireString(args, "side"),
|
|
5644
5770
|
ordType: requireString(args, "ordType"),
|
|
5645
5771
|
sz: requireString(args, "sz"),
|
|
5772
|
+
tgtCcy: readString(args, "tgtCcy"),
|
|
5646
5773
|
px: readString(args, "px"),
|
|
5647
5774
|
clOrdId: readString(args, "clOrdId"),
|
|
5648
5775
|
tag: context.config.sourceTag,
|
|
@@ -6371,6 +6498,7 @@ function registerSwapTradeTools() {
|
|
|
6371
6498
|
function allToolSpecs() {
|
|
6372
6499
|
return [
|
|
6373
6500
|
...registerMarketTools(),
|
|
6501
|
+
...registerIndicatorTools(),
|
|
6374
6502
|
...registerSpotTradeTools(),
|
|
6375
6503
|
...registerSwapTradeTools(),
|
|
6376
6504
|
...registerFuturesTools(),
|
|
@@ -6412,7 +6540,18 @@ function readFullConfig() {
|
|
|
6412
6540
|
const path4 = configFilePath();
|
|
6413
6541
|
if (!existsSync(path4)) return { profiles: {} };
|
|
6414
6542
|
const raw = readFileSync(path4, "utf-8");
|
|
6415
|
-
|
|
6543
|
+
try {
|
|
6544
|
+
return parse(raw);
|
|
6545
|
+
} catch (err) {
|
|
6546
|
+
throw new ConfigError(
|
|
6547
|
+
`Failed to parse ${path4}: ${err instanceof Error ? err.message : String(err)}`,
|
|
6548
|
+
`If your passphrase or keys contain special characters:
|
|
6549
|
+
- Contains # \\ " \u2192 use single quotes: passphrase = 'your#pass'
|
|
6550
|
+
- Contains ' \u2192 use double quotes: passphrase = "your'pass"
|
|
6551
|
+
- Contains both \u2192 use triple quotes: passphrase = '''your'#pass'''
|
|
6552
|
+
Or re-run: okx config init`
|
|
6553
|
+
);
|
|
6554
|
+
}
|
|
6416
6555
|
}
|
|
6417
6556
|
function readTomlProfile(profileName) {
|
|
6418
6557
|
const config = readFullConfig();
|
|
@@ -6802,7 +6941,7 @@ var _require = createRequire(import.meta.url);
|
|
|
6802
6941
|
var pkg = _require("../package.json");
|
|
6803
6942
|
var SERVER_NAME = "okx-trade-mcp";
|
|
6804
6943
|
var SERVER_VERSION = pkg.version;
|
|
6805
|
-
var GIT_HASH = true ? "
|
|
6944
|
+
var GIT_HASH = true ? "9f66f84" : "dev";
|
|
6806
6945
|
|
|
6807
6946
|
// src/server.ts
|
|
6808
6947
|
import { Server } from "@modelcontextprotocol/sdk/server/index.js";
|