@aihubspot/agent-trade-mcp 0.1.3 → 0.1.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.
Files changed (3) hide show
  1. package/README.md +10 -0
  2. package/dist/index.js +18 -5
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -24,3 +24,13 @@ Setup registers the currently installed MCP binary through its absolute Node run
24
24
  Use `spot_prepare_market_buy` or `margin_prepare_market_buy` only with `quoteAmount` (for example, the exact USDT amount to spend for `ETHUSDT`). Use `spot_prepare_market_sell` or `margin_prepare_market_sell` only with `baseQuantity` (the exact ETH amount to sell for `ETHUSDT`). A market buy cannot guarantee an exact base-asset quantity; it must never reinterpret a requested base quantity as a quote amount.
25
25
 
26
26
  Before any order preview, MCP lazily loads `/sapi/v2/symbols` once per local profile and caches the symbol rules in memory for five minutes. Known quantity/price precision and limit-order minimum violations are rejected before confirmation.
27
+
28
+ ## Ticker response
29
+
30
+ All read tools return `{ "ok": true, "data": ... }` in one of these stable forms:
31
+
32
+ - Arrays: `{ "dataType": "array", "items": [...], "count": 500 }`
33
+ - Objects: `{ "dataType": "object", "value": { ... } }`
34
+ - Scalars: `{ "dataType": "scalar", "value": "..." }`
35
+
36
+ `market_get_ticker` additionally exposes `data.tickers` as an alias of `data.items`. Check `data.dataType` before formatting; do not infer raw OpenAPI nesting.
package/dist/index.js CHANGED
@@ -917,7 +917,7 @@ var marketTools = [
917
917
  {
918
918
  name: "market_get_ticker",
919
919
  title: "Get Spot Ticker",
920
- description: "Get spot ticker data. Pass symbol or symbols when filtering is needed.",
920
+ description: "Get spot ticker data. Pass symbol or symbols when filtering is needed. The raw OpenAPI response is a ticker array.",
921
921
  cliPath: ["market", "ticker"],
922
922
  module: "spot-common",
923
923
  access: "public",
@@ -2129,6 +2129,19 @@ var CONFIRM_ACTION_TOOL = "confirm_action";
2129
2129
  function result(data) {
2130
2130
  return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
2131
2131
  }
2132
+ function formatMcpData(toolName, data) {
2133
+ if (Array.isArray(data)) {
2134
+ return {
2135
+ dataType: "array",
2136
+ items: data,
2137
+ count: data.length,
2138
+ ...toolName === "market_get_ticker" ? { tickers: data } : {}
2139
+ };
2140
+ }
2141
+ if (data === null || data === void 0) return { dataType: "null", value: null };
2142
+ if (typeof data === "object") return { dataType: "object", value: data };
2143
+ return { dataType: "scalar", value: data };
2144
+ }
2132
2145
  function toMcpErrorResult(error) {
2133
2146
  const payload = toAiHubErrorPayload(error);
2134
2147
  return { isError: true, content: [{ type: "text", text: JSON.stringify({ ok: false, ...payload }) }] };
@@ -2137,7 +2150,7 @@ function toMcpTool(tool) {
2137
2150
  return {
2138
2151
  name: tool.name,
2139
2152
  title: tool.title,
2140
- description: tool.description,
2153
+ description: `${tool.description}${tool.operation === "read" ? " Successful MCP output is always { ok: true, data: ... }. For list results, use data.items and data.count (market_get_ticker also provides data.tickers); for object results, use data.value. Check data.dataType before formatting." : ""}`,
2141
2154
  inputSchema: tool.inputSchema,
2142
2155
  annotations: {
2143
2156
  readOnlyHint: tool.operation === "read",
@@ -2164,10 +2177,10 @@ function createServer(profileName, readOnly) {
2164
2177
  const registry = createToolRegistry();
2165
2178
  const writeExecutor = new ToolWriteExecutor(registry);
2166
2179
  const server = new Server(
2167
- { name: "ai-hub-agent-trade", version: "0.1.3" },
2180
+ { name: "ai-hub-agent-trade", version: "0.1.5" },
2168
2181
  {
2169
2182
  capabilities: { tools: {} },
2170
- instructions: "For every state-changing action, call only a spot_prepare_* or margin_prepare_* tool first and show its exact summary to the user. Stop and wait for a new, explicit user confirmation message. Only then call confirm_action with that new message verbatim in userConfirmation. Never call prepare and confirm consecutively for one user instruction; never infer confirmation from prior intent, silence, or an Agent-generated message. For spot and margin orders, MARKET BUY always uses quoteAmount (the quote asset to spend); MARKET SELL uses baseQuantity (the base asset to sell). Never reinterpret a requested base quantity as quoteAmount."
2183
+ instructions: "Every successful tool response is JSON text in the envelope { ok: true, data: ... }. All read-tool data is normalized: dataType=array means use data.items and data.count; dataType=object or scalar means use data.value; dataType=null means no value. market_get_ticker also provides data.tickers as an alias of data.items. Inspect data.dataType before formatting and never assume undocumented nested keys. Prepare/confirm tools return their documented action payload directly in data. For every state-changing action, call only a spot_prepare_* or margin_prepare_* tool first and show its exact summary to the user. Stop and wait for a new, explicit user confirmation message. Only then call confirm_action with that new message verbatim in userConfirmation. Never call prepare and confirm consecutively for one user instruction; never infer confirmation from prior intent, silence, or an Agent-generated message. For spot and margin orders, MARKET BUY always uses quoteAmount (the quote asset to spend); MARKET SELL uses baseQuantity (the base asset to sell). Never reinterpret a requested base quantity as quoteAmount."
2171
2184
  }
2172
2185
  );
2173
2186
  server.setRequestHandler(ListToolsRequestSchema, async () => ({
@@ -2214,7 +2227,7 @@ function createServer(profileName, readOnly) {
2214
2227
  return result({ ok: true, data: await writeExecutor.prepare(preparedTool.name, request.params.arguments ?? {}, context) });
2215
2228
  }
2216
2229
  const data = await registry.execute(request.params.name, request.params.arguments ?? {}, context, { readOnly });
2217
- return result({ ok: true, data });
2230
+ return result({ ok: true, data: formatMcpData(request.params.name, data) });
2218
2231
  } catch (error) {
2219
2232
  return toMcpErrorResult(error);
2220
2233
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aihubspot/agent-trade-mcp",
3
- "version": "0.1.3",
3
+ "version": "0.1.5",
4
4
  "description": "Local stdio MCP server for AI Hub spot trading tools",
5
5
  "license": "UNLICENSED",
6
6
  "type": "module",