@okx_ai/okx-trade-mcp 1.2.7 → 1.2.8-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 CHANGED
@@ -1534,7 +1534,7 @@ function registerAccountTools() {
1534
1534
  {
1535
1535
  name: "account_get_asset_balance",
1536
1536
  module: "account",
1537
- description: "Get funding account balance (asset account). Different from account_get_balance which queries the trading account.",
1537
+ description: "Get funding account balance (asset account). Different from account_get_balance which queries the trading account. Optionally includes total asset valuation across all account types (trading, funding, earn, etc.).",
1538
1538
  isWrite: false,
1539
1539
  inputSchema: {
1540
1540
  type: "object",
@@ -1542,17 +1542,41 @@ function registerAccountTools() {
1542
1542
  ccy: {
1543
1543
  type: "string",
1544
1544
  description: "e.g. BTC or BTC,ETH. Omit for all."
1545
+ },
1546
+ showValuation: {
1547
+ type: "boolean",
1548
+ description: "Include total asset valuation breakdown by account type (trading/funding/earn). Default false."
1545
1549
  }
1546
1550
  }
1547
1551
  },
1548
1552
  handler: async (rawArgs, context) => {
1549
1553
  const args = asRecord(rawArgs);
1550
- const response = await context.client.privateGet(
1554
+ const ccy = readString(args, "ccy");
1555
+ const showValuation = readBoolean(args, "showValuation");
1556
+ if (showValuation) {
1557
+ const balanceResp2 = await context.client.privateGet(
1558
+ "/api/v5/asset/balances",
1559
+ compactObject({ ccy }),
1560
+ privateRateLimit("account_get_asset_balance", 6)
1561
+ );
1562
+ let valuationData = null;
1563
+ try {
1564
+ const valuationResp = await context.client.privateGet(
1565
+ "/api/v5/asset/asset-valuation",
1566
+ {},
1567
+ privateRateLimit("account_get_asset_valuation", 1)
1568
+ );
1569
+ valuationData = valuationResp.data;
1570
+ } catch {
1571
+ }
1572
+ return { ...normalizeResponse(balanceResp2), valuation: valuationData };
1573
+ }
1574
+ const balanceResp = await context.client.privateGet(
1551
1575
  "/api/v5/asset/balances",
1552
- compactObject({ ccy: readString(args, "ccy") }),
1576
+ compactObject({ ccy }),
1553
1577
  privateRateLimit("account_get_asset_balance", 6)
1554
1578
  );
1555
- return normalizeResponse(response);
1579
+ return normalizeResponse(balanceResp);
1556
1580
  }
1557
1581
  },
1558
1582
  {
@@ -2967,6 +2991,39 @@ function registerGridTools() {
2967
2991
  ];
2968
2992
  }
2969
2993
  var BASE = "/api/v5/tradingBot/dca";
2994
+ function buildTriggerParam(args, algoOrdType) {
2995
+ const triggerStrategy = readString(args, "triggerStrategy") ?? "instant";
2996
+ if (triggerStrategy === "price" && algoOrdType === "spot_dca") {
2997
+ throw new OkxApiError(
2998
+ "triggerStrategy 'price' is only supported for contract_dca. spot_dca supports: instant, rsi",
2999
+ { code: "VALIDATION", endpoint: `${BASE}/create` }
3000
+ );
3001
+ }
3002
+ const param = { triggerAction: "start", triggerStrategy };
3003
+ if (triggerStrategy === "price") {
3004
+ param["triggerPx"] = requireString(args, "triggerPx");
3005
+ const triggerCond = readString(args, "triggerCond");
3006
+ if (triggerCond) param["triggerCond"] = triggerCond;
3007
+ } else if (triggerStrategy === "rsi") {
3008
+ param["triggerCond"] = requireString(args, "triggerCond");
3009
+ param["thold"] = requireString(args, "thold");
3010
+ param["timeframe"] = requireString(args, "timeframe");
3011
+ param["timePeriod"] = readString(args, "timePeriod") ?? "14";
3012
+ }
3013
+ return param;
3014
+ }
3015
+ function validateSafetyOrderParams(args, maxSafetyOrds) {
3016
+ if (Number(maxSafetyOrds) <= 0) return;
3017
+ const required = ["safetyOrdAmt", "pxSteps", "pxStepsMult", "volMult"];
3018
+ for (const field of required) {
3019
+ if (!readString(args, field)) {
3020
+ throw new OkxApiError(`${field} is required when maxSafetyOrds > 0`, {
3021
+ code: "VALIDATION",
3022
+ endpoint: `${BASE}/create`
3023
+ });
3024
+ }
3025
+ }
3026
+ }
2970
3027
  function normalizeWrite2(response) {
2971
3028
  const data = response.data;
2972
3029
  if (Array.isArray(data) && data.length > 0) {
@@ -3036,57 +3093,11 @@ function registerDcaTools() {
3036
3093
  endpoint: `${BASE}/create`
3037
3094
  });
3038
3095
  }
3039
- const triggerStrategy = readString(args, "triggerStrategy") ?? "instant";
3040
- if (triggerStrategy === "price" && algoOrdType === "spot_dca") {
3041
- throw new OkxApiError("triggerStrategy 'price' is only supported for contract_dca. spot_dca supports: instant, rsi", {
3042
- code: "VALIDATION",
3043
- endpoint: `${BASE}/create`
3044
- });
3045
- }
3046
- const triggerParam = {
3047
- triggerAction: "start",
3048
- triggerStrategy
3049
- };
3050
- if (triggerStrategy === "price") {
3051
- triggerParam["triggerPx"] = requireString(args, "triggerPx");
3052
- const triggerCond = readString(args, "triggerCond");
3053
- if (triggerCond) {
3054
- triggerParam["triggerCond"] = triggerCond;
3055
- }
3056
- } else if (triggerStrategy === "rsi") {
3057
- triggerParam["triggerCond"] = requireString(args, "triggerCond");
3058
- triggerParam["thold"] = requireString(args, "thold");
3059
- triggerParam["timeframe"] = requireString(args, "timeframe");
3060
- const timePeriod = readString(args, "timePeriod");
3061
- triggerParam["timePeriod"] = timePeriod ?? "14";
3062
- }
3096
+ const triggerParam = buildTriggerParam(args, algoOrdType);
3063
3097
  const maxSafetyOrds = requireString(args, "maxSafetyOrds");
3064
- if (Number(maxSafetyOrds) > 0) {
3065
- if (!readString(args, "safetyOrdAmt")) {
3066
- throw new OkxApiError("safetyOrdAmt is required when maxSafetyOrds > 0", {
3067
- code: "VALIDATION",
3068
- endpoint: `${BASE}/create`
3069
- });
3070
- }
3071
- if (!readString(args, "pxSteps")) {
3072
- throw new OkxApiError("pxSteps is required when maxSafetyOrds > 0", {
3073
- code: "VALIDATION",
3074
- endpoint: `${BASE}/create`
3075
- });
3076
- }
3077
- if (!readString(args, "pxStepsMult")) {
3078
- throw new OkxApiError("pxStepsMult is required when maxSafetyOrds > 0", {
3079
- code: "VALIDATION",
3080
- endpoint: `${BASE}/create`
3081
- });
3082
- }
3083
- if (!readString(args, "volMult")) {
3084
- throw new OkxApiError("volMult is required when maxSafetyOrds > 0", {
3085
- code: "VALIDATION",
3086
- endpoint: `${BASE}/create`
3087
- });
3088
- }
3089
- }
3098
+ validateSafetyOrderParams(args, maxSafetyOrds);
3099
+ const allowReinvestRaw = args["allowReinvest"];
3100
+ const allowReinvest = allowReinvestRaw !== void 0 ? allowReinvestRaw === true || allowReinvestRaw === "true" : void 0;
3090
3101
  const response = await context.client.privatePost(
3091
3102
  `${BASE}/create`,
3092
3103
  compactObject({
@@ -3103,7 +3114,7 @@ function registerDcaTools() {
3103
3114
  tpPct: requireString(args, "tpPct"),
3104
3115
  slPct: readString(args, "slPct"),
3105
3116
  slMode: readString(args, "slMode"),
3106
- allowReinvest: args["allowReinvest"] !== void 0 ? args["allowReinvest"] === true || args["allowReinvest"] === "true" : void 0,
3117
+ allowReinvest,
3107
3118
  triggerParams: [triggerParam],
3108
3119
  tag: context.config.sourceTag,
3109
3120
  algoClOrdId: readString(args, "algoClOrdId"),
@@ -4663,6 +4674,7 @@ function registerFuturesTools() {
4663
4674
  }
4664
4675
  ];
4665
4676
  }
4677
+ var TWO_DAYS_MS = 2 * 24 * 60 * 60 * 1e3;
4666
4678
  function registerMarketTools() {
4667
4679
  return [
4668
4680
  {
@@ -4762,7 +4774,7 @@ function registerMarketTools() {
4762
4774
  {
4763
4775
  name: "market_get_candles",
4764
4776
  module: "market",
4765
- description: "Get candlestick (OHLCV) data for an instrument. history=false (default): recent candles up to 1440 bars; history=true: older historical data.",
4777
+ description: "Get candlestick (OHLCV) data for an instrument. Automatically retrieves historical data (back to 2021) when requesting older time ranges. Use the `after` parameter to paginate back in time (the old `history` parameter has been removed). IMPORTANT: Before fetching with `after`/`before`, estimate the number of candles: time_range_ms / bar_interval_ms. If the estimate exceeds ~500 candles, inform the user of the estimated count and ask for confirmation before proceeding.",
4766
4778
  isWrite: false,
4767
4779
  inputSchema: {
4768
4780
  type: "object",
@@ -4787,29 +4799,29 @@ function registerMarketTools() {
4787
4799
  limit: {
4788
4800
  type: "number",
4789
4801
  description: "Max results (default 100)"
4790
- },
4791
- history: {
4792
- type: "boolean",
4793
- description: "true=older historical data beyond recent window"
4794
4802
  }
4795
4803
  },
4796
4804
  required: ["instId"]
4797
4805
  },
4798
4806
  handler: async (rawArgs, context) => {
4799
4807
  const args = asRecord(rawArgs);
4800
- const isHistory = readBoolean(args, "history") ?? false;
4801
- const path4 = isHistory ? "/api/v5/market/history-candles" : "/api/v5/market/candles";
4802
- const response = await context.client.publicGet(
4803
- path4,
4804
- compactObject({
4805
- instId: requireString(args, "instId"),
4806
- bar: readString(args, "bar"),
4807
- after: readString(args, "after"),
4808
- before: readString(args, "before"),
4809
- limit: readNumber(args, "limit")
4810
- }),
4811
- publicRateLimit("market_get_candles", 40)
4812
- );
4808
+ const afterTs = readString(args, "after");
4809
+ const beforeTs = readString(args, "before");
4810
+ const query = compactObject({
4811
+ instId: requireString(args, "instId"),
4812
+ bar: readString(args, "bar"),
4813
+ after: afterTs,
4814
+ before: beforeTs,
4815
+ limit: readNumber(args, "limit")
4816
+ });
4817
+ const rateLimit = publicRateLimit("market_get_candles", 40);
4818
+ const hasTimestamp = afterTs !== void 0 || beforeTs !== void 0;
4819
+ const useHistory = afterTs !== void 0 && Number(afterTs) < Date.now() - TWO_DAYS_MS;
4820
+ const path4 = useHistory ? "/api/v5/market/history-candles" : "/api/v5/market/candles";
4821
+ const response = await context.client.publicGet(path4, query, rateLimit);
4822
+ if (!useHistory && hasTimestamp && Array.isArray(response.data) && response.data.length === 0) {
4823
+ return normalizeResponse(await context.client.publicGet("/api/v5/market/history-candles", query, rateLimit));
4824
+ }
4813
4825
  return normalizeResponse(response);
4814
4826
  }
4815
4827
  },
@@ -5662,7 +5674,14 @@ function registerOptionTools() {
5662
5674
  handler: async (rawArgs, context) => {
5663
5675
  const args = asRecord(rawArgs);
5664
5676
  const status = readString(args, "status") ?? "live";
5665
- const path4 = status === "archive" ? "/api/v5/trade/orders-history-archive" : status === "history" ? "/api/v5/trade/orders-history" : "/api/v5/trade/orders-pending";
5677
+ let path4;
5678
+ if (status === "archive") {
5679
+ path4 = "/api/v5/trade/orders-history-archive";
5680
+ } else if (status === "history") {
5681
+ path4 = "/api/v5/trade/orders-history";
5682
+ } else {
5683
+ path4 = "/api/v5/trade/orders-pending";
5684
+ }
5666
5685
  const response = await context.client.privateGet(
5667
5686
  path4,
5668
5687
  compactObject({
@@ -7070,7 +7089,7 @@ var _require = createRequire(import.meta.url);
7070
7089
  var pkg = _require("../package.json");
7071
7090
  var SERVER_NAME = "okx-trade-mcp";
7072
7091
  var SERVER_VERSION = pkg.version;
7073
- var GIT_HASH = true ? "475621d" : "dev";
7092
+ var GIT_HASH = true ? "f9ea608" : "dev";
7074
7093
 
7075
7094
  // src/server.ts
7076
7095
  import { Server } from "@modelcontextprotocol/sdk/server/index.js";