flash-trade-mcp 0.3.1 → 0.3.3
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 +219 -18
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -49207,6 +49207,18 @@ class FlashApiClient {
|
|
|
49207
49207
|
async reversePosition(req) {
|
|
49208
49208
|
return this.post("/transaction-builder/reverse-position", req);
|
|
49209
49209
|
}
|
|
49210
|
+
async placeTriggerOrder(req) {
|
|
49211
|
+
return this.post("/transaction-builder/place-trigger-order", req);
|
|
49212
|
+
}
|
|
49213
|
+
async editTriggerOrder(req) {
|
|
49214
|
+
return this.post("/transaction-builder/edit-trigger-order", req);
|
|
49215
|
+
}
|
|
49216
|
+
async cancelTriggerOrder(req) {
|
|
49217
|
+
return this.post("/transaction-builder/cancel-trigger-order", req);
|
|
49218
|
+
}
|
|
49219
|
+
async cancelAllTriggerOrders(req) {
|
|
49220
|
+
return this.post("/transaction-builder/cancel-all-trigger-orders", req);
|
|
49221
|
+
}
|
|
49210
49222
|
async previewLimitOrderFees(req) {
|
|
49211
49223
|
return this.post("/preview/limit-order-fees", req);
|
|
49212
49224
|
}
|
|
@@ -49229,8 +49241,9 @@ function registerHealthTools(server, client) {
|
|
|
49229
49241
|
const health = await client.getHealth();
|
|
49230
49242
|
const lines = [`Status: ${health.status}`];
|
|
49231
49243
|
for (const [key, val] of Object.entries(health)) {
|
|
49232
|
-
if (key !== "status")
|
|
49233
|
-
lines.push(`${key}: ${val}`);
|
|
49244
|
+
if (key !== "status") {
|
|
49245
|
+
lines.push(`${key}: ${typeof val === "object" ? JSON.stringify(val) : val}`);
|
|
49246
|
+
}
|
|
49234
49247
|
}
|
|
49235
49248
|
return { content: [{ type: "text", text: lines.join(`
|
|
49236
49249
|
`) }] };
|
|
@@ -49329,7 +49342,21 @@ function registerPoolTools(server, client) {
|
|
|
49329
49342
|
description: "List all liquidity pools on Flash Trade. Pools hold the collateral that backs perpetual positions. Returns pool addresses and configuration."
|
|
49330
49343
|
}, async () => {
|
|
49331
49344
|
const pools = await client.getPools();
|
|
49332
|
-
|
|
49345
|
+
const lines = [
|
|
49346
|
+
`${pools.length} pools available:
|
|
49347
|
+
`,
|
|
49348
|
+
"Pool Name | Custodies | Pubkey",
|
|
49349
|
+
"---------------|-----------|----------------------------------------------"
|
|
49350
|
+
];
|
|
49351
|
+
for (const p of pools) {
|
|
49352
|
+
const name = (p.account?.name ?? "Unknown").padEnd(15);
|
|
49353
|
+
const custodyCount = String(p.account?.custodies?.length ?? 0).padEnd(10);
|
|
49354
|
+
lines.push(`${name}| ${custodyCount}| ${p.pubkey}`);
|
|
49355
|
+
}
|
|
49356
|
+
lines.push(`
|
|
49357
|
+
Use get_pool with a pubkey for full details. Use get_pool_data for AUM and utilization metrics.`);
|
|
49358
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
49359
|
+
`) }] };
|
|
49333
49360
|
});
|
|
49334
49361
|
server.registerTool("get_pool", {
|
|
49335
49362
|
description: "Get detailed information about a specific pool by its on-chain account pubkey.",
|
|
@@ -49379,14 +49406,14 @@ function registerPriceTools(server, client) {
|
|
|
49379
49406
|
}, async ({ symbol: symbol2 }) => {
|
|
49380
49407
|
const data = await client.getPrice(symbol2);
|
|
49381
49408
|
const usd = formatPrice(data.price, data.exponent);
|
|
49382
|
-
|
|
49383
|
-
|
|
49384
|
-
|
|
49385
|
-
|
|
49386
|
-
|
|
49387
|
-
Timestamp: ${data.timestamp}`
|
|
49388
|
-
|
|
49389
|
-
|
|
49409
|
+
const lines = [
|
|
49410
|
+
`${symbol2.toUpperCase()}: $${usd}`,
|
|
49411
|
+
`Raw: ${data.price} (exp: ${data.exponent})`
|
|
49412
|
+
];
|
|
49413
|
+
if (data.timestamp)
|
|
49414
|
+
lines.push(`Timestamp: ${data.timestamp}`);
|
|
49415
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
49416
|
+
`) }] };
|
|
49390
49417
|
});
|
|
49391
49418
|
}
|
|
49392
49419
|
|
|
@@ -49494,8 +49521,26 @@ function registerPoolDataTools(server, client) {
|
|
|
49494
49521
|
const snapshot = await client.getPoolSnapshot(pool_pubkey);
|
|
49495
49522
|
return { content: [{ type: "text", text: JSON.stringify(snapshot, null, 2) }] };
|
|
49496
49523
|
}
|
|
49497
|
-
const
|
|
49498
|
-
|
|
49524
|
+
const raw = await client.getPoolData();
|
|
49525
|
+
const pools = raw.pools ?? raw;
|
|
49526
|
+
const lines = [
|
|
49527
|
+
`${pools.length} pools:
|
|
49528
|
+
`,
|
|
49529
|
+
"Pool | AUM | LP Price | Stable% | Custodies",
|
|
49530
|
+
"---------------|--------------|----------|---------|----------"
|
|
49531
|
+
];
|
|
49532
|
+
for (const p of pools) {
|
|
49533
|
+
const name = (p.poolName ?? "Unknown").padEnd(15);
|
|
49534
|
+
const aum = `$${p.lpStats?.totalPoolValueUsd ?? "?"}`.padEnd(14);
|
|
49535
|
+
const lp = `$${p.lpStats?.lpPrice ?? "?"}`.padEnd(9);
|
|
49536
|
+
const stable = `${p.lpStats?.stableCoinPercentage ?? "?"}%`.padEnd(8);
|
|
49537
|
+
const custodies = (p.custodyStats ?? []).map((c) => c.symbol).join(", ");
|
|
49538
|
+
lines.push(`${name}| ${aum}| ${lp}| ${stable}| ${custodies}`);
|
|
49539
|
+
}
|
|
49540
|
+
lines.push(`
|
|
49541
|
+
Use get_pool_data with pool_pubkey for full custody stats.`);
|
|
49542
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
49543
|
+
`) }] };
|
|
49499
49544
|
});
|
|
49500
49545
|
}
|
|
49501
49546
|
|
|
@@ -49556,7 +49601,7 @@ function registerOpenPositionTool(server, client) {
|
|
|
49556
49601
|
slippage_percentage: exports_external.string().max(8).optional().describe('Default: "0.5" (0.5%)'),
|
|
49557
49602
|
take_profit: exports_external.string().max(32).optional().describe("TP trigger price in UI format"),
|
|
49558
49603
|
stop_loss: exports_external.string().max(32).optional().describe("SL trigger price in UI format"),
|
|
49559
|
-
degen_mode: exports_external.boolean().optional().describe("Enable degen mode (higher leverage limits)")
|
|
49604
|
+
degen_mode: exports_external.coerce.boolean().optional().describe("Enable degen mode (higher leverage limits)")
|
|
49560
49605
|
}
|
|
49561
49606
|
}, async (params) => {
|
|
49562
49607
|
const res = await client.openPosition({
|
|
@@ -49573,12 +49618,21 @@ function registerOpenPositionTool(server, client) {
|
|
|
49573
49618
|
stopLoss: params.stop_loss,
|
|
49574
49619
|
degenMode: params.degen_mode
|
|
49575
49620
|
});
|
|
49576
|
-
|
|
49621
|
+
let text = formatOpenPreview({
|
|
49577
49622
|
outputTokenSymbol: params.output_token_symbol,
|
|
49578
49623
|
tradeType: params.trade_type,
|
|
49579
49624
|
inputTokenSymbol: params.input_token_symbol,
|
|
49580
49625
|
inputAmountUi: params.input_amount
|
|
49581
49626
|
}, res);
|
|
49627
|
+
if (params.take_profit || params.stop_loss) {
|
|
49628
|
+
const collateral = parseFloat(res.youPayUsdUi || "0");
|
|
49629
|
+
const fee = parseFloat(res.entryFee || "0");
|
|
49630
|
+
if (collateral - fee < 10) {
|
|
49631
|
+
text += `
|
|
49632
|
+
|
|
49633
|
+
WARNING: Collateral after fees is below $10. Take-profit and stop-loss orders require >$10 collateral and will FAIL on-chain. Use at least $11-12 input_amount.`;
|
|
49634
|
+
}
|
|
49635
|
+
}
|
|
49582
49636
|
return { content: [{ type: "text", text }] };
|
|
49583
49637
|
});
|
|
49584
49638
|
}
|
|
@@ -49621,7 +49675,7 @@ function registerClosePositionTool(server, client) {
|
|
|
49621
49675
|
position_key: exports_external.string().regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/).describe("Position account pubkey to close"),
|
|
49622
49676
|
input_usd: exports_external.string().max(32).describe('USD amount to close, e.g. "500.00" for full or "250.00" for partial'),
|
|
49623
49677
|
withdraw_token_symbol: exports_external.string().max(16).describe('Token to receive: "USDC", "SOL", etc.'),
|
|
49624
|
-
keep_leverage_same: exports_external.boolean().optional().describe("Keep leverage constant during partial close"),
|
|
49678
|
+
keep_leverage_same: exports_external.coerce.boolean().optional().describe("Keep leverage constant during partial close"),
|
|
49625
49679
|
slippage_percentage: exports_external.string().max(8).optional().describe('Default: "0.5" (0.5%)')
|
|
49626
49680
|
}
|
|
49627
49681
|
}, async (params) => {
|
|
@@ -49755,7 +49809,7 @@ function registerReversePositionTool(server, client) {
|
|
|
49755
49809
|
position_key: exports_external.string().regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/).describe("Position account pubkey to reverse"),
|
|
49756
49810
|
owner: exports_external.string().regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/).describe("Wallet pubkey"),
|
|
49757
49811
|
slippage_percentage: exports_external.string().max(8).optional().describe('Default: "0.5" (0.5%)'),
|
|
49758
|
-
degen_mode: exports_external.boolean().optional().describe("Enable degen mode for the new position")
|
|
49812
|
+
degen_mode: exports_external.coerce.boolean().optional().describe("Enable degen mode for the new position")
|
|
49759
49813
|
}
|
|
49760
49814
|
}, async (params) => {
|
|
49761
49815
|
const res = await client.reversePosition({
|
|
@@ -56893,6 +56947,152 @@ Signature: ${signature2}` }],
|
|
|
56893
56947
|
});
|
|
56894
56948
|
}
|
|
56895
56949
|
|
|
56950
|
+
// src/tools/trigger-orders.ts
|
|
56951
|
+
function registerTriggerOrderTools(server, client) {
|
|
56952
|
+
server.registerTool("place_trigger_order", {
|
|
56953
|
+
description: "Place a take-profit (TP) or stop-loss (SL) trigger order on an existing position. The trigger order will automatically close part or all of the position when the price hits the trigger level. Requires an open position for the given market/side. Returns an unsigned transaction. Up to 5 trigger orders per position.",
|
|
56954
|
+
inputSchema: {
|
|
56955
|
+
market_symbol: exports_external.string().max(16).describe('Market symbol, e.g. "SOL", "BTC", "ETH"'),
|
|
56956
|
+
collateral_symbol: exports_external.string().max(16).describe('Collateral token, e.g. "USDC", "JITOSOL"'),
|
|
56957
|
+
side: exports_external.enum(["LONG", "SHORT"]).describe("Position side"),
|
|
56958
|
+
trigger_price: exports_external.string().max(32).describe('Trigger price in UI format, e.g. "160.00"'),
|
|
56959
|
+
size_amount: exports_external.string().max(32).describe('Size in target token to close when triggered, e.g. "0.5"'),
|
|
56960
|
+
is_stop_loss: exports_external.coerce.boolean().describe("true = stop-loss, false = take-profit"),
|
|
56961
|
+
owner: exports_external.string().regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/).describe("Wallet pubkey (must own the position)")
|
|
56962
|
+
}
|
|
56963
|
+
}, async (params) => {
|
|
56964
|
+
const res = await client.placeTriggerOrder({
|
|
56965
|
+
marketSymbol: params.market_symbol,
|
|
56966
|
+
collateralSymbol: params.collateral_symbol,
|
|
56967
|
+
side: params.side,
|
|
56968
|
+
triggerPriceUi: params.trigger_price,
|
|
56969
|
+
sizeAmountUi: params.size_amount,
|
|
56970
|
+
isStopLoss: params.is_stop_loss,
|
|
56971
|
+
owner: params.owner
|
|
56972
|
+
});
|
|
56973
|
+
const lines = [
|
|
56974
|
+
`=== Place ${params.is_stop_loss ? "Stop-Loss" : "Take-Profit"} Order ===`,
|
|
56975
|
+
`Market: ${params.market_symbol} ${params.side}`,
|
|
56976
|
+
`Trigger: $${params.trigger_price}`,
|
|
56977
|
+
`Size: ${params.size_amount} ${params.market_symbol}`
|
|
56978
|
+
];
|
|
56979
|
+
if (res.err)
|
|
56980
|
+
lines.push(`
|
|
56981
|
+
WARNING: ${res.err}`);
|
|
56982
|
+
if (res.transactionBase64) {
|
|
56983
|
+
lines.push(`
|
|
56984
|
+
Transaction (base64, unsigned — sign with wallet):`);
|
|
56985
|
+
lines.push(res.transactionBase64);
|
|
56986
|
+
}
|
|
56987
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
56988
|
+
`) }] };
|
|
56989
|
+
});
|
|
56990
|
+
server.registerTool("edit_trigger_order", {
|
|
56991
|
+
description: "Edit an existing take-profit or stop-loss trigger order. Change the trigger price, size, or order type without canceling and re-placing. Requires the order_id (0-7) from get_orders. Returns an unsigned transaction.",
|
|
56992
|
+
inputSchema: {
|
|
56993
|
+
market_symbol: exports_external.string().max(16).describe('Market symbol, e.g. "SOL", "BTC", "ETH"'),
|
|
56994
|
+
collateral_symbol: exports_external.string().max(16).describe('Collateral token, e.g. "USDC", "JITOSOL"'),
|
|
56995
|
+
side: exports_external.enum(["LONG", "SHORT"]).describe("Position side"),
|
|
56996
|
+
order_id: exports_external.coerce.number().describe("Index of the trigger order to edit (0-7)"),
|
|
56997
|
+
trigger_price: exports_external.string().max(32).describe("New trigger price in UI format"),
|
|
56998
|
+
size_amount: exports_external.string().max(32).describe("New size in target token"),
|
|
56999
|
+
is_stop_loss: exports_external.coerce.boolean().describe("true = stop-loss, false = take-profit"),
|
|
57000
|
+
owner: exports_external.string().regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/).describe("Wallet pubkey (must be original order owner)")
|
|
57001
|
+
}
|
|
57002
|
+
}, async (params) => {
|
|
57003
|
+
const res = await client.editTriggerOrder({
|
|
57004
|
+
marketSymbol: params.market_symbol,
|
|
57005
|
+
collateralSymbol: params.collateral_symbol,
|
|
57006
|
+
side: params.side,
|
|
57007
|
+
orderId: params.order_id,
|
|
57008
|
+
triggerPriceUi: params.trigger_price,
|
|
57009
|
+
sizeAmountUi: params.size_amount,
|
|
57010
|
+
isStopLoss: params.is_stop_loss,
|
|
57011
|
+
owner: params.owner
|
|
57012
|
+
});
|
|
57013
|
+
const lines = [
|
|
57014
|
+
`=== Edit ${params.is_stop_loss ? "Stop-Loss" : "Take-Profit"} Order #${params.order_id} ===`,
|
|
57015
|
+
`Market: ${params.market_symbol} ${params.side}`,
|
|
57016
|
+
`New Trigger: $${params.trigger_price}`,
|
|
57017
|
+
`New Size: ${params.size_amount} ${params.market_symbol}`
|
|
57018
|
+
];
|
|
57019
|
+
if (res.err)
|
|
57020
|
+
lines.push(`
|
|
57021
|
+
WARNING: ${res.err}`);
|
|
57022
|
+
if (res.transactionBase64) {
|
|
57023
|
+
lines.push(`
|
|
57024
|
+
Transaction (base64, unsigned — sign with wallet):`);
|
|
57025
|
+
lines.push(res.transactionBase64);
|
|
57026
|
+
}
|
|
57027
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
57028
|
+
`) }] };
|
|
57029
|
+
});
|
|
57030
|
+
server.registerTool("cancel_trigger_order", {
|
|
57031
|
+
description: "Cancel a single take-profit or stop-loss trigger order. Requires the order_id (0-7) from get_orders. Returns an unsigned transaction.",
|
|
57032
|
+
inputSchema: {
|
|
57033
|
+
market_symbol: exports_external.string().max(16).describe('Market symbol, e.g. "SOL", "BTC", "ETH"'),
|
|
57034
|
+
collateral_symbol: exports_external.string().max(16).describe('Collateral token, e.g. "USDC", "JITOSOL"'),
|
|
57035
|
+
side: exports_external.enum(["LONG", "SHORT"]).describe("Position side"),
|
|
57036
|
+
order_id: exports_external.coerce.number().describe("Index of the trigger order to cancel (0-7)"),
|
|
57037
|
+
is_stop_loss: exports_external.coerce.boolean().describe("true = stop-loss, false = take-profit"),
|
|
57038
|
+
owner: exports_external.string().regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/).describe("Wallet pubkey (must own the order)")
|
|
57039
|
+
}
|
|
57040
|
+
}, async (params) => {
|
|
57041
|
+
const res = await client.cancelTriggerOrder({
|
|
57042
|
+
marketSymbol: params.market_symbol,
|
|
57043
|
+
collateralSymbol: params.collateral_symbol,
|
|
57044
|
+
side: params.side,
|
|
57045
|
+
orderId: params.order_id,
|
|
57046
|
+
isStopLoss: params.is_stop_loss,
|
|
57047
|
+
owner: params.owner
|
|
57048
|
+
});
|
|
57049
|
+
const lines = [
|
|
57050
|
+
`=== Cancel ${params.is_stop_loss ? "Stop-Loss" : "Take-Profit"} Order #${params.order_id} ===`,
|
|
57051
|
+
`Market: ${params.market_symbol} ${params.side}`
|
|
57052
|
+
];
|
|
57053
|
+
if (res.err)
|
|
57054
|
+
lines.push(`
|
|
57055
|
+
WARNING: ${res.err}`);
|
|
57056
|
+
if (res.transactionBase64) {
|
|
57057
|
+
lines.push(`
|
|
57058
|
+
Transaction (base64, unsigned — sign with wallet):`);
|
|
57059
|
+
lines.push(res.transactionBase64);
|
|
57060
|
+
}
|
|
57061
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
57062
|
+
`) }] };
|
|
57063
|
+
});
|
|
57064
|
+
server.registerTool("cancel_all_trigger_orders", {
|
|
57065
|
+
description: "Cancel ALL take-profit and stop-loss trigger orders for a market+side. Removes all TP and SL orders in one transaction. Returns an unsigned transaction.",
|
|
57066
|
+
inputSchema: {
|
|
57067
|
+
market_symbol: exports_external.string().max(16).describe('Market symbol, e.g. "SOL", "BTC", "ETH"'),
|
|
57068
|
+
collateral_symbol: exports_external.string().max(16).describe('Collateral token, e.g. "USDC", "JITOSOL"'),
|
|
57069
|
+
side: exports_external.enum(["LONG", "SHORT"]).describe("Position side"),
|
|
57070
|
+
owner: exports_external.string().regex(/^[1-9A-HJ-NP-Za-km-z]{32,44}$/).describe("Wallet pubkey (must own the orders)")
|
|
57071
|
+
}
|
|
57072
|
+
}, async (params) => {
|
|
57073
|
+
const res = await client.cancelAllTriggerOrders({
|
|
57074
|
+
marketSymbol: params.market_symbol,
|
|
57075
|
+
collateralSymbol: params.collateral_symbol,
|
|
57076
|
+
side: params.side,
|
|
57077
|
+
owner: params.owner
|
|
57078
|
+
});
|
|
57079
|
+
const lines = [
|
|
57080
|
+
`=== Cancel All Trigger Orders ===`,
|
|
57081
|
+
`Market: ${params.market_symbol} ${params.side}`
|
|
57082
|
+
];
|
|
57083
|
+
if (res.err)
|
|
57084
|
+
lines.push(`
|
|
57085
|
+
WARNING: ${res.err}`);
|
|
57086
|
+
if (res.transactionBase64) {
|
|
57087
|
+
lines.push(`
|
|
57088
|
+
Transaction (base64, unsigned — sign with wallet):`);
|
|
57089
|
+
lines.push(res.transactionBase64);
|
|
57090
|
+
}
|
|
57091
|
+
return { content: [{ type: "text", text: lines.join(`
|
|
57092
|
+
`) }] };
|
|
57093
|
+
});
|
|
57094
|
+
}
|
|
57095
|
+
|
|
56896
57096
|
// src/tools/index.ts
|
|
56897
57097
|
function registerReadTools(server, client) {
|
|
56898
57098
|
registerHealthTools(server, client);
|
|
@@ -56909,6 +57109,7 @@ function registerTransactionTools(server, client) {
|
|
|
56909
57109
|
registerClosePositionTool(server, client);
|
|
56910
57110
|
registerCollateralTools(server, client);
|
|
56911
57111
|
registerReversePositionTool(server, client);
|
|
57112
|
+
registerTriggerOrderTools(server, client);
|
|
56912
57113
|
registerSignAndSendTool(server);
|
|
56913
57114
|
}
|
|
56914
57115
|
|
|
@@ -56985,7 +57186,7 @@ try {
|
|
|
56985
57186
|
const client = new FlashApiClient(config2);
|
|
56986
57187
|
const server = new McpServer({
|
|
56987
57188
|
name: "flash-trade",
|
|
56988
|
-
version: "0.3.
|
|
57189
|
+
version: "0.3.3"
|
|
56989
57190
|
}, {
|
|
56990
57191
|
capabilities: {
|
|
56991
57192
|
tools: {},
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "flash-trade-mcp",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "MCP server for Flash Trade — perpetual futures DEX on Solana. Provides AI agents with typed tools for trading, position management, and market data.",
|
|
5
5
|
"module": "src/index.ts",
|
|
6
6
|
"main": "dist/index.js",
|