@pgnio/helios-mcp 0.2.7 → 0.2.9
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/{chunk-V453JYRN.mjs → chunk-7TMDGB6C.mjs} +64 -31
- package/dist/{chunk-WLCFIWFP.mjs → chunk-LMZEWQVW.mjs} +68 -32
- package/dist/cli.js +41 -15
- package/dist/cli.mjs +1 -1
- package/dist/index.d.mts +15 -9
- package/dist/index.d.ts +15 -9
- package/dist/index.js +41 -15
- package/dist/index.mjs +1 -1
- package/docs/ai-agent-indicators/00_columns.txt +76 -0
- package/docs/ai-agent-indicators/00_index.txt +4 -19
- package/package.json +1 -1
- package/dist/chunk-52XY4KRG.mjs +0 -3038
- package/dist/chunk-7EDI4KLD.mjs +0 -3042
- package/dist/chunk-EIAUO3XE.mjs +0 -2955
- package/dist/chunk-NCF7ASJB.mjs +0 -2986
- package/dist/chunk-NWGWXYTS.mjs +0 -2964
- package/dist/chunk-UYCUR7QV.mjs +0 -2994
- package/dist/chunk-XE6HRID3.mjs +0 -2992
- package/docs/ai-agent-indicators/squeeze_duration.txt +0 -115
- package/docs/ai-agent-indicators/squeeze_energy.txt +0 -128
- package/docs/ai-agent-indicators/tf_alignment.txt +0 -165
- package/docs/ai-agent-indicators/volatility_squeeze.txt +0 -169
package/dist/cli.js
CHANGED
|
@@ -139,19 +139,21 @@ var protectiveOrderKindSchema = import_zod.z.enum(["STOP_LOSS", "TAKE_PROFIT"]);
|
|
|
139
139
|
var protectiveOrderSideSchema = import_zod.z.enum(["BUY", "SELL"]);
|
|
140
140
|
var protectiveOrderPositionSideSchema = import_zod.z.enum(["BOTH", "LONG", "SHORT"]);
|
|
141
141
|
var protectiveOrderSchema = import_zod.z.object({
|
|
142
|
+
/** Helios's record id: what helios_positions_delete_tp_sl takes (the Hyperliquid order id works there too). */
|
|
142
143
|
id: import_zod.z.string(),
|
|
143
|
-
|
|
144
|
-
|
|
144
|
+
/** The Hyperliquid order id (named after the retired Binance field). */
|
|
145
|
+
binanceOrderId: import_zod.z.number().int().nonnegative().nullish(),
|
|
146
|
+
clientOrderId: import_zod.z.string().nullish(),
|
|
145
147
|
symbol: import_zod.z.string(),
|
|
146
148
|
side: protectiveOrderSideSchema,
|
|
147
|
-
positionSide: protectiveOrderPositionSideSchema,
|
|
149
|
+
positionSide: protectiveOrderPositionSideSchema.nullish().transform((value) => value ?? "BOTH"),
|
|
148
150
|
status: import_zod.z.string(),
|
|
149
151
|
kind: protectiveOrderKindSchema,
|
|
150
|
-
groupId: import_zod.z.string(),
|
|
151
|
-
stopPrice: import_zod.z.string().
|
|
152
|
-
parentClientOrderId: import_zod.z.string().
|
|
153
|
-
assetId: import_zod.z.number().int().nonnegative().
|
|
154
|
-
createdAt: import_zod.z.string().
|
|
152
|
+
groupId: import_zod.z.string().nullish(),
|
|
153
|
+
stopPrice: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]).nullish().transform((value) => value == null ? value : String(value)),
|
|
154
|
+
parentClientOrderId: import_zod.z.string().nullish(),
|
|
155
|
+
assetId: import_zod.z.number().int().nonnegative().nullish(),
|
|
156
|
+
createdAt: import_zod.z.string().nullish()
|
|
155
157
|
});
|
|
156
158
|
var hyperliquidPortfolioSnapshotSchema = import_zod.z.object({
|
|
157
159
|
provider: import_zod.z.literal("hyperliquid"),
|
|
@@ -160,6 +162,7 @@ var hyperliquidPortfolioSnapshotSchema = import_zod.z.object({
|
|
|
160
162
|
totalMargin: import_zod.z.number(),
|
|
161
163
|
unrealizedPnl: import_zod.z.number(),
|
|
162
164
|
positions: import_zod.z.array(openPositionSchema),
|
|
165
|
+
/** Unreadable entries are dropped (see readProtectiveOrders) rather than failing the read. */
|
|
163
166
|
protectiveOrders: import_zod.z.array(protectiveOrderSchema)
|
|
164
167
|
});
|
|
165
168
|
var portfolioInputSchema = import_zod.z.object({
|
|
@@ -354,6 +357,8 @@ var closePositionInputSchema = import_zod.z.object({
|
|
|
354
357
|
});
|
|
355
358
|
var closePositionResultSchema = import_zod.z.object({
|
|
356
359
|
status: import_zod.z.literal("submitted"),
|
|
360
|
+
/** `no_position`: nothing was open on this coin, so no order was sent. Absent from older data-bridges. */
|
|
361
|
+
outcome: import_zod.z.enum(["closed", "no_position"]).optional(),
|
|
357
362
|
provider: providerSchema.optional(),
|
|
358
363
|
symbol: import_zod.z.string(),
|
|
359
364
|
mode: import_zod.z.literal("FULL"),
|
|
@@ -544,7 +549,8 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
544
549
|
}
|
|
545
550
|
return portfolioSnapshotSchema.parse({
|
|
546
551
|
...result,
|
|
547
|
-
provider: parsedInput.provider
|
|
552
|
+
provider: parsedInput.provider,
|
|
553
|
+
protectiveOrders: readProtectiveOrders(result.protectiveOrders)
|
|
548
554
|
});
|
|
549
555
|
}
|
|
550
556
|
async getLedgerFills(accessToken, input = {}) {
|
|
@@ -597,7 +603,7 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
597
603
|
}
|
|
598
604
|
async closePosition(accessToken, input) {
|
|
599
605
|
const parsedInput = closePositionInputSchema.parse(input);
|
|
600
|
-
await this.request(
|
|
606
|
+
const payload = await this.request(
|
|
601
607
|
accessToken,
|
|
602
608
|
"positions.close",
|
|
603
609
|
{
|
|
@@ -608,8 +614,10 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
608
614
|
},
|
|
609
615
|
"POST"
|
|
610
616
|
);
|
|
617
|
+
const outcome = this.tryUnwrapResult(payload)?.outcome;
|
|
611
618
|
return closePositionResultSchema.parse({
|
|
612
619
|
status: "submitted",
|
|
620
|
+
...outcome === "closed" || outcome === "no_position" ? { outcome } : {},
|
|
613
621
|
provider: parsedInput.provider,
|
|
614
622
|
symbol: parsedInput.symbol,
|
|
615
623
|
mode: "FULL",
|
|
@@ -707,6 +715,14 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
707
715
|
});
|
|
708
716
|
}
|
|
709
717
|
}
|
|
718
|
+
/** The result of a mutation older data-bridges answer with nothing; null when there is none. */
|
|
719
|
+
tryUnwrapResult(payload) {
|
|
720
|
+
try {
|
|
721
|
+
return this.unwrapResult(payload) ?? null;
|
|
722
|
+
} catch {
|
|
723
|
+
return null;
|
|
724
|
+
}
|
|
725
|
+
}
|
|
710
726
|
unwrapResult(payload) {
|
|
711
727
|
if (!payload || typeof payload !== "object") {
|
|
712
728
|
throw new HeliosAgentApiError({
|
|
@@ -767,6 +783,13 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
767
783
|
return envelope;
|
|
768
784
|
}
|
|
769
785
|
};
|
|
786
|
+
function readProtectiveOrders(value) {
|
|
787
|
+
if (!Array.isArray(value)) return [];
|
|
788
|
+
return value.flatMap((entry) => {
|
|
789
|
+
const parsed = protectiveOrderSchema.safeParse(entry);
|
|
790
|
+
return parsed.success ? [parsed.data] : [];
|
|
791
|
+
});
|
|
792
|
+
}
|
|
770
793
|
var DEFAULT_AGENT_REFRESH_WINDOW_MS = 60 * 1e3;
|
|
771
794
|
var agentConnectionStatusSchema = import_zod3.z.enum([
|
|
772
795
|
"disconnected",
|
|
@@ -1220,6 +1243,9 @@ var HeliosAgentMcpDocsService = class {
|
|
|
1220
1243
|
}
|
|
1221
1244
|
async getDocument(input) {
|
|
1222
1245
|
const documentPath = resolveDocumentPath(this.docsRoot, input.path);
|
|
1246
|
+
if (!(0, import_node_fs.existsSync)(documentPath) || !(0, import_node_fs.statSync)(documentPath).isFile()) {
|
|
1247
|
+
throw new Error(`No document "${input.path}". helios_docs_get_index lists the documents.`);
|
|
1248
|
+
}
|
|
1223
1249
|
const body = (0, import_node_fs.readFileSync)(documentPath, "utf8");
|
|
1224
1250
|
const stats = (0, import_node_fs.statSync)(documentPath);
|
|
1225
1251
|
const relativePath = toPosixPath(import_node_path.default.relative(this.docsRoot, documentPath));
|
|
@@ -2522,7 +2548,7 @@ function createHeliosAccountToolDefinitions(service) {
|
|
|
2522
2548
|
{
|
|
2523
2549
|
name: "helios_portfolio_get",
|
|
2524
2550
|
title: "Get Helios Portfolio",
|
|
2525
|
-
description: "Returns
|
|
2551
|
+
description: "Returns balances, open positions and their TP/SL (protectiveOrders, each with the id helios_positions_delete_tp_sl takes). Provider may be omitted if one is already pinned with helios_provider_set_active.",
|
|
2526
2552
|
inputSchema: providerSelectionInputSchema,
|
|
2527
2553
|
async execute(input) {
|
|
2528
2554
|
const result = portfolioToolOutputSchema.parse(await service.getPortfolio(input));
|
|
@@ -2618,7 +2644,7 @@ function createHeliosMarketToolDefinitions(service) {
|
|
|
2618
2644
|
{
|
|
2619
2645
|
name: "helios_market_get_snapshot",
|
|
2620
2646
|
title: "Get Helios Market Snapshot",
|
|
2621
|
-
description: "Returns a compact market snapshot for the selected, all, or explicitly requested symbols. By default: the top 50 coins by market cap with the main columns; name symbols to get other coins, pass fields for other columns.",
|
|
2647
|
+
description: "Returns a compact market snapshot for the selected, all, or explicitly requested symbols. By default: the top 50 coins by market cap with the main columns; name symbols to get other coins, pass fields for other columns. What each column means: helios_docs_get_document with path ai-agent-indicators/00_columns.txt (read it once).",
|
|
2622
2648
|
inputSchema: marketSnapshotInputSchema,
|
|
2623
2649
|
async execute(input) {
|
|
2624
2650
|
const result = marketSnapshotToolOutputSchema.parse(await service.getSnapshot(input));
|
|
@@ -2759,7 +2785,7 @@ function createHeliosTradingToolDefinitions(service) {
|
|
|
2759
2785
|
content: [
|
|
2760
2786
|
{
|
|
2761
2787
|
type: "text",
|
|
2762
|
-
text: result.status
|
|
2788
|
+
text: result.status !== "connected" ? result.message : result.closure.outcome === "no_position" ? `No open ${result.closure.symbol} position: nothing was closed and no order was sent.` : `Sent a market order closing the full ${result.closure.provider ?? input.provider ?? "hyperliquid"} ${result.closure.symbol} position. Check helios_positions_get_open to confirm.`
|
|
2763
2789
|
}
|
|
2764
2790
|
],
|
|
2765
2791
|
structuredContent: result.status === "connected" ? result : {
|
|
@@ -2793,7 +2819,7 @@ function createHeliosTradingToolDefinitions(service) {
|
|
|
2793
2819
|
{
|
|
2794
2820
|
name: "helios_positions_delete_tp_sl",
|
|
2795
2821
|
title: "Delete Helios TP/SL",
|
|
2796
|
-
description: "Deletes
|
|
2822
|
+
description: "Deletes a take-profit or stop-loss. orderId is the id from helios_portfolio_get protectiveOrders, or the Hyperliquid order id of the TP/SL. Provider may be omitted if one is already pinned with helios_provider_set_active.",
|
|
2797
2823
|
inputSchema: deleteTpSlInputSchema,
|
|
2798
2824
|
async execute(input) {
|
|
2799
2825
|
const result = deleteTpSlToolOutputSchema.parse(await service.deleteTpSl(input));
|
|
@@ -2886,7 +2912,7 @@ async function createHeliosAgentMcpServer(options) {
|
|
|
2886
2912
|
const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
|
|
2887
2913
|
const server = new McpServer({
|
|
2888
2914
|
name: "helios",
|
|
2889
|
-
version: "0.2.
|
|
2915
|
+
version: "0.2.9"
|
|
2890
2916
|
});
|
|
2891
2917
|
const sessionStore = options.sessionStore ?? new FileAgentSessionStore(options.sessionPath ?? getDefaultHeliosAgentMcpSessionPath());
|
|
2892
2918
|
const client = new HeliosAgentAuthClient({
|
package/dist/cli.mjs
CHANGED
package/dist/index.d.mts
CHANGED
|
@@ -94,28 +94,28 @@ declare const portfolioSnapshotSchema: z.ZodObject<{
|
|
|
94
94
|
}, z.core.$strip>>;
|
|
95
95
|
protectiveOrders: z.ZodArray<z.ZodObject<{
|
|
96
96
|
id: z.ZodString;
|
|
97
|
-
binanceOrderId: z.ZodOptional<z.ZodNumber
|
|
98
|
-
clientOrderId: z.ZodOptional<z.ZodString
|
|
97
|
+
binanceOrderId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
98
|
+
clientOrderId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
99
99
|
symbol: z.ZodString;
|
|
100
100
|
side: z.ZodEnum<{
|
|
101
101
|
BUY: "BUY";
|
|
102
102
|
SELL: "SELL";
|
|
103
103
|
}>;
|
|
104
|
-
positionSide: z.ZodEnum<{
|
|
104
|
+
positionSide: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
105
105
|
LONG: "LONG";
|
|
106
106
|
SHORT: "SHORT";
|
|
107
107
|
BOTH: "BOTH";
|
|
108
|
-
}
|
|
108
|
+
}>>>, z.ZodTransform<"LONG" | "SHORT" | "BOTH", "LONG" | "SHORT" | "BOTH" | null | undefined>>;
|
|
109
109
|
status: z.ZodString;
|
|
110
110
|
kind: z.ZodEnum<{
|
|
111
111
|
STOP_LOSS: "STOP_LOSS";
|
|
112
112
|
TAKE_PROFIT: "TAKE_PROFIT";
|
|
113
113
|
}>;
|
|
114
|
-
groupId: z.ZodString
|
|
115
|
-
stopPrice: z.ZodOptional<z.ZodString
|
|
116
|
-
parentClientOrderId: z.ZodOptional<z.ZodString
|
|
117
|
-
assetId: z.ZodOptional<z.ZodNumber
|
|
118
|
-
createdAt: z.ZodString
|
|
114
|
+
groupId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
115
|
+
stopPrice: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodTransform<string | null | undefined, string | number | null | undefined>>;
|
|
116
|
+
parentClientOrderId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
117
|
+
assetId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
118
|
+
createdAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
119
119
|
}, z.core.$strip>>;
|
|
120
120
|
}, z.core.$strip>;
|
|
121
121
|
declare const ledgerFillsInputSchema: z.ZodObject<{
|
|
@@ -440,6 +440,10 @@ declare const closePositionInputSchema: z.ZodObject<{
|
|
|
440
440
|
}, z.core.$strip>;
|
|
441
441
|
declare const closePositionResultSchema: z.ZodObject<{
|
|
442
442
|
status: z.ZodLiteral<"submitted">;
|
|
443
|
+
outcome: z.ZodOptional<z.ZodEnum<{
|
|
444
|
+
closed: "closed";
|
|
445
|
+
no_position: "no_position";
|
|
446
|
+
}>>;
|
|
443
447
|
provider: z.ZodOptional<z.ZodEnum<{
|
|
444
448
|
hyperliquid: "hyperliquid";
|
|
445
449
|
}>>;
|
|
@@ -606,6 +610,8 @@ declare class HeliosAgentDataBridgeClient {
|
|
|
606
610
|
private request;
|
|
607
611
|
private buildProcedureUrl;
|
|
608
612
|
private parseJson;
|
|
613
|
+
/** The result of a mutation older data-bridges answer with nothing; null when there is none. */
|
|
614
|
+
private tryUnwrapResult;
|
|
609
615
|
private unwrapResult;
|
|
610
616
|
private extractErrorCode;
|
|
611
617
|
private extractErrorMessage;
|
package/dist/index.d.ts
CHANGED
|
@@ -94,28 +94,28 @@ declare const portfolioSnapshotSchema: z.ZodObject<{
|
|
|
94
94
|
}, z.core.$strip>>;
|
|
95
95
|
protectiveOrders: z.ZodArray<z.ZodObject<{
|
|
96
96
|
id: z.ZodString;
|
|
97
|
-
binanceOrderId: z.ZodOptional<z.ZodNumber
|
|
98
|
-
clientOrderId: z.ZodOptional<z.ZodString
|
|
97
|
+
binanceOrderId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
98
|
+
clientOrderId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
99
99
|
symbol: z.ZodString;
|
|
100
100
|
side: z.ZodEnum<{
|
|
101
101
|
BUY: "BUY";
|
|
102
102
|
SELL: "SELL";
|
|
103
103
|
}>;
|
|
104
|
-
positionSide: z.ZodEnum<{
|
|
104
|
+
positionSide: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodEnum<{
|
|
105
105
|
LONG: "LONG";
|
|
106
106
|
SHORT: "SHORT";
|
|
107
107
|
BOTH: "BOTH";
|
|
108
|
-
}
|
|
108
|
+
}>>>, z.ZodTransform<"LONG" | "SHORT" | "BOTH", "LONG" | "SHORT" | "BOTH" | null | undefined>>;
|
|
109
109
|
status: z.ZodString;
|
|
110
110
|
kind: z.ZodEnum<{
|
|
111
111
|
STOP_LOSS: "STOP_LOSS";
|
|
112
112
|
TAKE_PROFIT: "TAKE_PROFIT";
|
|
113
113
|
}>;
|
|
114
|
-
groupId: z.ZodString
|
|
115
|
-
stopPrice: z.ZodOptional<z.ZodString
|
|
116
|
-
parentClientOrderId: z.ZodOptional<z.ZodString
|
|
117
|
-
assetId: z.ZodOptional<z.ZodNumber
|
|
118
|
-
createdAt: z.ZodString
|
|
114
|
+
groupId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
115
|
+
stopPrice: z.ZodPipe<z.ZodOptional<z.ZodNullable<z.ZodUnion<readonly [z.ZodString, z.ZodNumber]>>>, z.ZodTransform<string | null | undefined, string | number | null | undefined>>;
|
|
116
|
+
parentClientOrderId: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
117
|
+
assetId: z.ZodOptional<z.ZodNullable<z.ZodNumber>>;
|
|
118
|
+
createdAt: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
119
119
|
}, z.core.$strip>>;
|
|
120
120
|
}, z.core.$strip>;
|
|
121
121
|
declare const ledgerFillsInputSchema: z.ZodObject<{
|
|
@@ -440,6 +440,10 @@ declare const closePositionInputSchema: z.ZodObject<{
|
|
|
440
440
|
}, z.core.$strip>;
|
|
441
441
|
declare const closePositionResultSchema: z.ZodObject<{
|
|
442
442
|
status: z.ZodLiteral<"submitted">;
|
|
443
|
+
outcome: z.ZodOptional<z.ZodEnum<{
|
|
444
|
+
closed: "closed";
|
|
445
|
+
no_position: "no_position";
|
|
446
|
+
}>>;
|
|
443
447
|
provider: z.ZodOptional<z.ZodEnum<{
|
|
444
448
|
hyperliquid: "hyperliquid";
|
|
445
449
|
}>>;
|
|
@@ -606,6 +610,8 @@ declare class HeliosAgentDataBridgeClient {
|
|
|
606
610
|
private request;
|
|
607
611
|
private buildProcedureUrl;
|
|
608
612
|
private parseJson;
|
|
613
|
+
/** The result of a mutation older data-bridges answer with nothing; null when there is none. */
|
|
614
|
+
private tryUnwrapResult;
|
|
609
615
|
private unwrapResult;
|
|
610
616
|
private extractErrorCode;
|
|
611
617
|
private extractErrorMessage;
|
package/dist/index.js
CHANGED
|
@@ -179,19 +179,21 @@ var protectiveOrderKindSchema = import_zod.z.enum(["STOP_LOSS", "TAKE_PROFIT"]);
|
|
|
179
179
|
var protectiveOrderSideSchema = import_zod.z.enum(["BUY", "SELL"]);
|
|
180
180
|
var protectiveOrderPositionSideSchema = import_zod.z.enum(["BOTH", "LONG", "SHORT"]);
|
|
181
181
|
var protectiveOrderSchema = import_zod.z.object({
|
|
182
|
+
/** Helios's record id: what helios_positions_delete_tp_sl takes (the Hyperliquid order id works there too). */
|
|
182
183
|
id: import_zod.z.string(),
|
|
183
|
-
|
|
184
|
-
|
|
184
|
+
/** The Hyperliquid order id (named after the retired Binance field). */
|
|
185
|
+
binanceOrderId: import_zod.z.number().int().nonnegative().nullish(),
|
|
186
|
+
clientOrderId: import_zod.z.string().nullish(),
|
|
185
187
|
symbol: import_zod.z.string(),
|
|
186
188
|
side: protectiveOrderSideSchema,
|
|
187
|
-
positionSide: protectiveOrderPositionSideSchema,
|
|
189
|
+
positionSide: protectiveOrderPositionSideSchema.nullish().transform((value) => value ?? "BOTH"),
|
|
188
190
|
status: import_zod.z.string(),
|
|
189
191
|
kind: protectiveOrderKindSchema,
|
|
190
|
-
groupId: import_zod.z.string(),
|
|
191
|
-
stopPrice: import_zod.z.string().
|
|
192
|
-
parentClientOrderId: import_zod.z.string().
|
|
193
|
-
assetId: import_zod.z.number().int().nonnegative().
|
|
194
|
-
createdAt: import_zod.z.string().
|
|
192
|
+
groupId: import_zod.z.string().nullish(),
|
|
193
|
+
stopPrice: import_zod.z.union([import_zod.z.string(), import_zod.z.number()]).nullish().transform((value) => value == null ? value : String(value)),
|
|
194
|
+
parentClientOrderId: import_zod.z.string().nullish(),
|
|
195
|
+
assetId: import_zod.z.number().int().nonnegative().nullish(),
|
|
196
|
+
createdAt: import_zod.z.string().nullish()
|
|
195
197
|
});
|
|
196
198
|
var hyperliquidPortfolioSnapshotSchema = import_zod.z.object({
|
|
197
199
|
provider: import_zod.z.literal("hyperliquid"),
|
|
@@ -200,6 +202,7 @@ var hyperliquidPortfolioSnapshotSchema = import_zod.z.object({
|
|
|
200
202
|
totalMargin: import_zod.z.number(),
|
|
201
203
|
unrealizedPnl: import_zod.z.number(),
|
|
202
204
|
positions: import_zod.z.array(openPositionSchema),
|
|
205
|
+
/** Unreadable entries are dropped (see readProtectiveOrders) rather than failing the read. */
|
|
203
206
|
protectiveOrders: import_zod.z.array(protectiveOrderSchema)
|
|
204
207
|
});
|
|
205
208
|
var portfolioInputSchema = import_zod.z.object({
|
|
@@ -394,6 +397,8 @@ var closePositionInputSchema = import_zod.z.object({
|
|
|
394
397
|
});
|
|
395
398
|
var closePositionResultSchema = import_zod.z.object({
|
|
396
399
|
status: import_zod.z.literal("submitted"),
|
|
400
|
+
/** `no_position`: nothing was open on this coin, so no order was sent. Absent from older data-bridges. */
|
|
401
|
+
outcome: import_zod.z.enum(["closed", "no_position"]).optional(),
|
|
397
402
|
provider: providerSchema.optional(),
|
|
398
403
|
symbol: import_zod.z.string(),
|
|
399
404
|
mode: import_zod.z.literal("FULL"),
|
|
@@ -584,7 +589,8 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
584
589
|
}
|
|
585
590
|
return portfolioSnapshotSchema.parse({
|
|
586
591
|
...result,
|
|
587
|
-
provider: parsedInput.provider
|
|
592
|
+
provider: parsedInput.provider,
|
|
593
|
+
protectiveOrders: readProtectiveOrders(result.protectiveOrders)
|
|
588
594
|
});
|
|
589
595
|
}
|
|
590
596
|
async getLedgerFills(accessToken, input = {}) {
|
|
@@ -637,7 +643,7 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
637
643
|
}
|
|
638
644
|
async closePosition(accessToken, input) {
|
|
639
645
|
const parsedInput = closePositionInputSchema.parse(input);
|
|
640
|
-
await this.request(
|
|
646
|
+
const payload = await this.request(
|
|
641
647
|
accessToken,
|
|
642
648
|
"positions.close",
|
|
643
649
|
{
|
|
@@ -648,8 +654,10 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
648
654
|
},
|
|
649
655
|
"POST"
|
|
650
656
|
);
|
|
657
|
+
const outcome = this.tryUnwrapResult(payload)?.outcome;
|
|
651
658
|
return closePositionResultSchema.parse({
|
|
652
659
|
status: "submitted",
|
|
660
|
+
...outcome === "closed" || outcome === "no_position" ? { outcome } : {},
|
|
653
661
|
provider: parsedInput.provider,
|
|
654
662
|
symbol: parsedInput.symbol,
|
|
655
663
|
mode: "FULL",
|
|
@@ -747,6 +755,14 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
747
755
|
});
|
|
748
756
|
}
|
|
749
757
|
}
|
|
758
|
+
/** The result of a mutation older data-bridges answer with nothing; null when there is none. */
|
|
759
|
+
tryUnwrapResult(payload) {
|
|
760
|
+
try {
|
|
761
|
+
return this.unwrapResult(payload) ?? null;
|
|
762
|
+
} catch {
|
|
763
|
+
return null;
|
|
764
|
+
}
|
|
765
|
+
}
|
|
750
766
|
unwrapResult(payload) {
|
|
751
767
|
if (!payload || typeof payload !== "object") {
|
|
752
768
|
throw new HeliosAgentApiError({
|
|
@@ -807,6 +823,13 @@ var HeliosAgentDataBridgeClient = class {
|
|
|
807
823
|
return envelope;
|
|
808
824
|
}
|
|
809
825
|
};
|
|
826
|
+
function readProtectiveOrders(value) {
|
|
827
|
+
if (!Array.isArray(value)) return [];
|
|
828
|
+
return value.flatMap((entry) => {
|
|
829
|
+
const parsed = protectiveOrderSchema.safeParse(entry);
|
|
830
|
+
return parsed.success ? [parsed.data] : [];
|
|
831
|
+
});
|
|
832
|
+
}
|
|
810
833
|
var DEFAULT_AGENT_REFRESH_WINDOW_MS = 60 * 1e3;
|
|
811
834
|
var agentConnectionStatusSchema = import_zod3.z.enum([
|
|
812
835
|
"disconnected",
|
|
@@ -1260,6 +1283,9 @@ var HeliosAgentMcpDocsService = class {
|
|
|
1260
1283
|
}
|
|
1261
1284
|
async getDocument(input) {
|
|
1262
1285
|
const documentPath = resolveDocumentPath(this.docsRoot, input.path);
|
|
1286
|
+
if (!(0, import_node_fs.existsSync)(documentPath) || !(0, import_node_fs.statSync)(documentPath).isFile()) {
|
|
1287
|
+
throw new Error(`No document "${input.path}". helios_docs_get_index lists the documents.`);
|
|
1288
|
+
}
|
|
1263
1289
|
const body = (0, import_node_fs.readFileSync)(documentPath, "utf8");
|
|
1264
1290
|
const stats = (0, import_node_fs.statSync)(documentPath);
|
|
1265
1291
|
const relativePath = toPosixPath(import_node_path.default.relative(this.docsRoot, documentPath));
|
|
@@ -2596,7 +2622,7 @@ function createHeliosAccountToolDefinitions(service) {
|
|
|
2596
2622
|
{
|
|
2597
2623
|
name: "helios_portfolio_get",
|
|
2598
2624
|
title: "Get Helios Portfolio",
|
|
2599
|
-
description: "Returns
|
|
2625
|
+
description: "Returns balances, open positions and their TP/SL (protectiveOrders, each with the id helios_positions_delete_tp_sl takes). Provider may be omitted if one is already pinned with helios_provider_set_active.",
|
|
2600
2626
|
inputSchema: providerSelectionInputSchema,
|
|
2601
2627
|
async execute(input) {
|
|
2602
2628
|
const result = portfolioToolOutputSchema.parse(await service.getPortfolio(input));
|
|
@@ -2692,7 +2718,7 @@ function createHeliosMarketToolDefinitions(service) {
|
|
|
2692
2718
|
{
|
|
2693
2719
|
name: "helios_market_get_snapshot",
|
|
2694
2720
|
title: "Get Helios Market Snapshot",
|
|
2695
|
-
description: "Returns a compact market snapshot for the selected, all, or explicitly requested symbols. By default: the top 50 coins by market cap with the main columns; name symbols to get other coins, pass fields for other columns.",
|
|
2721
|
+
description: "Returns a compact market snapshot for the selected, all, or explicitly requested symbols. By default: the top 50 coins by market cap with the main columns; name symbols to get other coins, pass fields for other columns. What each column means: helios_docs_get_document with path ai-agent-indicators/00_columns.txt (read it once).",
|
|
2696
2722
|
inputSchema: marketSnapshotInputSchema,
|
|
2697
2723
|
async execute(input) {
|
|
2698
2724
|
const result = marketSnapshotToolOutputSchema.parse(await service.getSnapshot(input));
|
|
@@ -2833,7 +2859,7 @@ function createHeliosTradingToolDefinitions(service) {
|
|
|
2833
2859
|
content: [
|
|
2834
2860
|
{
|
|
2835
2861
|
type: "text",
|
|
2836
|
-
text: result.status
|
|
2862
|
+
text: result.status !== "connected" ? result.message : result.closure.outcome === "no_position" ? `No open ${result.closure.symbol} position: nothing was closed and no order was sent.` : `Sent a market order closing the full ${result.closure.provider ?? input.provider ?? "hyperliquid"} ${result.closure.symbol} position. Check helios_positions_get_open to confirm.`
|
|
2837
2863
|
}
|
|
2838
2864
|
],
|
|
2839
2865
|
structuredContent: result.status === "connected" ? result : {
|
|
@@ -2867,7 +2893,7 @@ function createHeliosTradingToolDefinitions(service) {
|
|
|
2867
2893
|
{
|
|
2868
2894
|
name: "helios_positions_delete_tp_sl",
|
|
2869
2895
|
title: "Delete Helios TP/SL",
|
|
2870
|
-
description: "Deletes
|
|
2896
|
+
description: "Deletes a take-profit or stop-loss. orderId is the id from helios_portfolio_get protectiveOrders, or the Hyperliquid order id of the TP/SL. Provider may be omitted if one is already pinned with helios_provider_set_active.",
|
|
2871
2897
|
inputSchema: deleteTpSlInputSchema,
|
|
2872
2898
|
async execute(input) {
|
|
2873
2899
|
const result = deleteTpSlToolOutputSchema.parse(await service.deleteTpSl(input));
|
|
@@ -2960,7 +2986,7 @@ async function createHeliosAgentMcpServer(options) {
|
|
|
2960
2986
|
const { McpServer } = await import("@modelcontextprotocol/sdk/server/mcp.js");
|
|
2961
2987
|
const server = new McpServer({
|
|
2962
2988
|
name: "helios",
|
|
2963
|
-
version: "0.2.
|
|
2989
|
+
version: "0.2.9"
|
|
2964
2990
|
});
|
|
2965
2991
|
const sessionStore = options.sessionStore ?? new FileAgentSessionStore(options.sessionPath ?? getDefaultHeliosAgentMcpSessionPath());
|
|
2966
2992
|
const client = new HeliosAgentAuthClient({
|
package/dist/index.mjs
CHANGED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
HELIOS SNAPSHOT COLUMNS: HOW TO READ THEM
|
|
2
|
+
Short guide to the column ids in helios_market_get_snapshot, _chunk and symbol detail `row`.
|
|
3
|
+
All % values are already percent (2.5 = 2.5%). null = unavailable, never zero.
|
|
4
|
+
Longer guides for single indicators are in this folder (see 00_index.txt).
|
|
5
|
+
|
|
6
|
+
PRICE AND SIZE
|
|
7
|
+
rank market cap rank (1 = largest). null = unranked.
|
|
8
|
+
lp last price.
|
|
9
|
+
qv 24h quote volume in USD. Low qv = thin market, wider fills.
|
|
10
|
+
bv 24h base volume (coins).
|
|
11
|
+
|
|
12
|
+
RETURNS (% change over the window)
|
|
13
|
+
r1m r3m r5m r15m r30m r1h r2h r4h r6h r8h r12h r24h r3d r7d
|
|
14
|
+
|
|
15
|
+
DISTANCE FROM RECENT RANGE
|
|
16
|
+
fh24 fh7 % from the 24h / 7d high. Always <= 0. -10 = 10% below the high.
|
|
17
|
+
fl24 fl7 % from the 24h / 7d low. Always >= 0. 2 = 2% above the low.
|
|
18
|
+
Near 0 on fl = sitting on the low; near 0 on fh = at the high.
|
|
19
|
+
|
|
20
|
+
REGIME AND MOMENTUM
|
|
21
|
+
reg regime label from 12 timeframe changes:
|
|
22
|
+
up: CASCADE UP, PARABOLIC, BREAKOUT, TREND UP, GRIND UP, SPIKE UP
|
|
23
|
+
down: CASCADE DOWN, CRASH, BREAKDOWN, TREND DN, BLEED, SPIKE DN
|
|
24
|
+
turning: REVERSAL (down->up), ROLLOVER (up->down), EXHAUST UP, EXHAUST DN
|
|
25
|
+
no trend: CHOP, CONSOL, RANGING (momentum signals are weak here)
|
|
26
|
+
Known quirk: a steady fall can read CRASH even when not accelerating.
|
|
27
|
+
hmi Helios momentum index, -100..100. Cross-timeframe momentum, 1h-4h weigh most.
|
|
28
|
+
> 40 strong up, 15..40 up, -15..15 no direction, < -40 strong down.
|
|
29
|
+
hmiv hmi velocity (rate of change of hmi). > 0 momentum improving, < 0 fading.
|
|
30
|
+
Meaningless when hmi is between -15 and 15.
|
|
31
|
+
tri trend strength label: STRONG TREND, MODERATE TREND, WEAK TREND, RANGING/CHOPPY.
|
|
32
|
+
No direction: use hmi or reg for which way.
|
|
33
|
+
trv trend strength 0..100 (> 60 STRONG, > 40 MODERATE, > 20 WEAK).
|
|
34
|
+
de directional efficiency -1..1. +1 every timeframe moving up cleanly,
|
|
35
|
+
-1 every timeframe moving down cleanly, near 0 choppy.
|
|
36
|
+
|
|
37
|
+
STRETCH
|
|
38
|
+
ob overbought, 0..100 (weighted RSI across timeframes). >= 70 stretched up,
|
|
39
|
+
<= 30 stretched down.
|
|
40
|
+
obosp probability ob is high versus its own last 60 readings, 0..1.
|
|
41
|
+
> 0.9 extreme for this coin right now, < 0.1 extreme low.
|
|
42
|
+
In a strong trend ob can be 95 while obosp is low; read both.
|
|
43
|
+
vwz VWAP z-score vs the 7d VWAP. > +2 far above, -0.5..0.5 at VWAP, < -2 far below.
|
|
44
|
+
|
|
45
|
+
STRUCTURE
|
|
46
|
+
ms market structure: RANGING, CONSOL (compressed), BREAKING↑ / BREAKING↓,
|
|
47
|
+
CONFIRMED-BREAK↑ / ↓, TEST-S (testing support), TEST-R (testing resistance),
|
|
48
|
+
FAILED-BREAK (breakout that reversed).
|
|
49
|
+
srs nearest support price. srr nearest resistance price (null = none found).
|
|
50
|
+
|
|
51
|
+
SCORE
|
|
52
|
+
hs Helios score, a mean-reversion setup score. Positive = long setup
|
|
53
|
+
(needs ob <= 30 and de <= -0.4), negative = short setup (ob >= 60, de >= 0.4),
|
|
54
|
+
0 = no setup. Size: 5+ notable, 7+ strong, 9+ rare. Short scores have not
|
|
55
|
+
held up in backtests; long scores in a falling market have.
|
|
56
|
+
|
|
57
|
+
OTHER COLUMNS (only with fields)
|
|
58
|
+
hfi Helios flow index (funding, OI, CVD), -100..100. Its OI part saturates; treat as rough.
|
|
59
|
+
ar az activity ratio and z-score (volume now vs baseline; ar < 0.5 = dead).
|
|
60
|
+
vwap poc pocd vap VWAP price, volume point of control, % from it, value-area position.
|
|
61
|
+
macdh macds macdd MACD histogram, signal label, divergence.
|
|
62
|
+
vcc vcp volatility clustering and change-point probability.
|
|
63
|
+
obosd overbought/oversold divergence. trh trend Hurst (> 0.5 trending).
|
|
64
|
+
|
|
65
|
+
MARKET BLOCK (every response)
|
|
66
|
+
os how many of 23 large coins are down more than 7% in 24h (0..23). High = broad selloff.
|
|
67
|
+
mti micro trend: 5m + 1h moves of BTC, ETH, BNB, SOL, scaled. > 0 majors rising now.
|
|
68
|
+
Mti macro trend: weighted 5m/1h/6h/24h momentum of six majors, in %. > 0 market up.
|
|
69
|
+
|
|
70
|
+
WHAT HAS HELD UP IN BACKTESTS (out of sample, last 2 years)
|
|
71
|
+
- Buying a sharp turn up (hmiv > 0, r15m and r1h turning positive) in a coin whose
|
|
72
|
+
reg is BREAKDOWN or CRASH, especially when the whole market is down (os high, Mti < 0).
|
|
73
|
+
- Fading stretched moves beat chasing them.
|
|
74
|
+
- Shorts did not hold up. Edges are small: about +0.1% a trade after a 0.38% round-trip cost,
|
|
75
|
+
on holds of 1-3 days. Frequent in-and-out trading pays fees without that edge.
|
|
76
|
+
Size small, always use a stop.
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
================================================================================
|
|
2
2
|
HELIOS INDICATOR INDEX — AI AGENT REFERENCE
|
|
3
3
|
================================================================================
|
|
4
|
-
#
|
|
5
|
-
#
|
|
4
|
+
# START WITH 00_columns.txt: a short guide to every snapshot column id (hmi, reg, ob, hs...).
|
|
5
|
+
# The entries below are longer guides, one per indicator. Format: file | data_field | type | range | purpose
|
|
6
|
+
# data_field names here are the long names; snapshot columns use the short ids in 00_columns.txt.
|
|
6
7
|
|
|
7
8
|
--------------------------------------------------------------------------------
|
|
8
9
|
MOMENTUM / DIRECTION
|
|
@@ -22,10 +23,6 @@ regime.txt
|
|
|
22
23
|
19-state market regime classifier (e.g. CASCADE_UP, CHOP, REVERSAL).
|
|
23
24
|
PRIMARY GATE: invalidates all momentum indicators when CHOP/CONSOL/RANGING.
|
|
24
25
|
|
|
25
|
-
tf_alignment.txt
|
|
26
|
-
indicators.tf_alignment | NUMERIC | 0..100
|
|
27
|
-
% of short-TF (1m-2h) movement aligned with macro (4h-24h) direction.
|
|
28
|
-
Breadth complement to HMI magnitude.
|
|
29
26
|
|
|
30
27
|
directional_efficiency.txt
|
|
31
28
|
indicators.directional_efficiency | NUMERIC | -1..1
|
|
@@ -135,21 +132,10 @@ hfi_weights.txt
|
|
|
135
132
|
Any weight < 0.10 = that data source is degraded.
|
|
136
133
|
|
|
137
134
|
--------------------------------------------------------------------------------
|
|
138
|
-
VOLATILITY
|
|
135
|
+
VOLATILITY
|
|
139
136
|
--------------------------------------------------------------------------------
|
|
140
|
-
volatility_squeeze.txt
|
|
141
|
-
indicators.volatility_squeeze | NUMERIC | [0, ∞); typical [0.1, 1.5]
|
|
142
|
-
Short/long GARCH(1,1) ratio. LOWER = MORE compressed (< 0.8 = in squeeze).
|
|
143
|
-
Counterintuitive scale: value 0.2 = maximum squeeze, NOT minimum.
|
|
144
137
|
|
|
145
|
-
squeeze_duration.txt
|
|
146
|
-
indicators.squeeze_duration | INTEGER | [0, ∞)
|
|
147
|
-
Count of consecutive ticks with volatility_squeeze < 0.8. Resets to 0 on break.
|
|
148
138
|
|
|
149
|
-
squeeze_energy.txt
|
|
150
|
-
indicators.squeeze_energy | NUMERIC | [0, ∞)
|
|
151
|
-
Integrated compression: squeeze_duration × (0.8 - volatility_squeeze).
|
|
152
|
-
Summary measure of pent-up energy. Zero = no active squeeze.
|
|
153
139
|
|
|
154
140
|
volatility_clustering.txt
|
|
155
141
|
indicators.volatility_clustering | NUMERIC | [0.7, 1.5] ← NOT [0, 1]
|
|
@@ -200,7 +186,6 @@ DEPENDENCY MAP — KEY RELATIONSHIPS
|
|
|
200
186
|
macd_signal → macd_histogram (state without magnitude is incomplete)
|
|
201
187
|
macd_divergence → macd_signal (divergence leads; cross confirms)
|
|
202
188
|
hfi → hfi_weights (composite without component split is opaque)
|
|
203
|
-
squeeze_energy → volatility_squeeze + squeeze_duration (derived from both)
|
|
204
189
|
vwap_zscore → vwap + volatility_clustering (both required for interpretation)
|
|
205
190
|
poc_distance → poc (normalized deviation requires knowing the level)
|
|
206
191
|
value_area_position → regime (same state is opposite signal in different regimes)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pgnio/helios-mcp",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.9",
|
|
4
4
|
"description": "Helios MCP server: connect an AI agent to your Helios account to read markets and your portfolio and to trade on Hyperliquid. Most apps can use the hosted URL https://helios.pgn.io/mcp instead.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"homepage": "https://helios.pgn.io/?connect=ai",
|