omnitrade-mcp 0.4.4 → 0.5.0

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 (2) hide show
  1. package/dist/index.js +54 -9
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -292,9 +292,12 @@ function registerBalanceTools(server, exchangeManager) {
292
292
  );
293
293
  server.tool(
294
294
  "get_portfolio",
295
- "Get a unified portfolio summary across all exchanges with total values.",
296
- {},
297
- async () => {
295
+ "Get a unified portfolio summary with USD values. Shows total portfolio worth and individual holdings.",
296
+ {
297
+ minValue: z2.number().default(1).describe("Minimum USD value to display (default: $1). Set to 0 to show all."),
298
+ showAll: z2.boolean().default(false).describe("Show all assets including dust (overrides minValue)")
299
+ },
300
+ async ({ minValue, showAll }) => {
298
301
  const assetTotals = {};
299
302
  const errors = [];
300
303
  for (const [name, ex] of exchangeManager.getAll()) {
@@ -313,17 +316,59 @@ function registerBalanceTools(server, exchangeManager) {
313
316
  errors.push(`${name}: ${error.message}`);
314
317
  }
315
318
  }
316
- const assets = Object.entries(assetTotals).map(([asset, data]) => ({
317
- asset,
318
- total: data.total,
319
- distribution: data.byExchange
320
- })).sort((a, b) => b.total - a.total);
319
+ const priceCache = {};
320
+ const stablecoins = ["USDT", "USDC", "BUSD", "DAI", "USD", "TUSD", "USDP"];
321
+ const priceExchange = exchangeManager.getAll().values().next().value;
322
+ if (priceExchange) {
323
+ for (const symbol of Object.keys(assetTotals)) {
324
+ if (stablecoins.includes(symbol.toUpperCase())) {
325
+ priceCache[symbol] = 1;
326
+ continue;
327
+ }
328
+ try {
329
+ const ticker = await priceExchange.fetchTicker(`${symbol}/USDT`);
330
+ if (ticker.last) {
331
+ priceCache[symbol] = ticker.last;
332
+ }
333
+ } catch {
334
+ try {
335
+ const ticker = await priceExchange.fetchTicker(`${symbol}/USD`);
336
+ if (ticker.last) {
337
+ priceCache[symbol] = ticker.last;
338
+ }
339
+ } catch {
340
+ priceCache[symbol] = 0;
341
+ }
342
+ }
343
+ }
344
+ }
345
+ const assets = Object.entries(assetTotals).map(([asset, data]) => {
346
+ const price = priceCache[asset] ?? 0;
347
+ const usdValue = data.total * price;
348
+ return {
349
+ asset,
350
+ quantity: data.total,
351
+ price,
352
+ usdValue: parseFloat(usdValue.toFixed(2)),
353
+ distribution: data.byExchange
354
+ };
355
+ }).filter((a) => showAll || a.usdValue >= minValue).sort((a, b) => b.usdValue - a.usdValue);
356
+ const totalUsdValue = assets.reduce((sum, a) => sum + a.usdValue, 0);
357
+ const hiddenCount = Object.keys(assetTotals).length - assets.length;
321
358
  const portfolio = {
322
359
  summary: {
360
+ totalValue: `$${totalUsdValue.toLocaleString("en-US", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`,
323
361
  totalAssets: assets.length,
362
+ hiddenAssets: hiddenCount > 0 ? `${hiddenCount} assets below $${minValue}` : void 0,
324
363
  exchanges: exchangeManager.getNames()
325
364
  },
326
- assets,
365
+ holdings: assets.map((a) => ({
366
+ asset: a.asset,
367
+ quantity: a.quantity,
368
+ price: a.price > 0 ? `$${a.price.toLocaleString("en-US")}` : "N/A",
369
+ value: `$${a.usdValue.toLocaleString("en-US", { minimumFractionDigits: 2 })}`,
370
+ percent: totalUsdValue > 0 ? `${(a.usdValue / totalUsdValue * 100).toFixed(1)}%` : "0%"
371
+ })),
327
372
  errors: errors.length > 0 ? errors : void 0
328
373
  };
329
374
  return {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "omnitrade-mcp",
3
- "version": "0.4.4",
3
+ "version": "0.5.0",
4
4
  "description": "Multi-exchange AI trading via MCP. 107 exchanges. One AI.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",