fmp-ai-tools 0.2.3 → 0.2.4-beta.1

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/README.md CHANGED
@@ -92,7 +92,7 @@ export async function POST(req: Request) {
92
92
  FMP_API_KEY=your_api_key_here
93
93
  ```
94
94
 
95
- Get your API key from [Financial Modeling Prep](https://site.financialmodelingprep.com/pricing-plans?couponCode=eroy) and get your API key. This link will get you 10% off.
95
+ Get an API key from [Financial Modeling Prep](https://site.financialmodelingprep.com/pricing-plans).
96
96
 
97
97
  The tools internally use the `fmp-node-api` library, which reads this environment variable to authenticate with the Financial Modeling Prep API.
98
98
 
@@ -339,6 +339,7 @@ Each tool accepts specific parameters. Here are some common ones:
339
339
  - `from` - Start date in YYYY-MM-DD format
340
340
  - `to` - End date in YYYY-MM-DD format
341
341
  - `name` - For economic indicators: specific indicator name
342
+ - `limit` - Max rows returned by tools that wrap large list endpoints (earnings/economic calendars, institutional and ETF holdings, market performance, executive compensation, congressional trades by name; defaults 20–50). Institutional and ETF holdings are sorted largest-first.
342
343
 
343
344
  ## Error Handling
344
345
 
@@ -192,6 +192,11 @@ function toToolResponse(res) {
192
192
  }
193
193
  return JSON.stringify(res.data, null, 2);
194
194
  }
195
+ function limitRows(res, limit2, compare) {
196
+ if (res.success === false || !Array.isArray(res.data)) return res;
197
+ const rows = compare ? [...res.data].sort(compare) : res.data;
198
+ return { ...res, data: rows.slice(0, limit2) };
199
+ }
195
200
  function toToolError(error) {
196
201
  const message = error instanceof Error ? error.message : String(error);
197
202
  let type = "unknown";
@@ -331,9 +336,11 @@ var companyDefinitions = [
331
336
  }),
332
337
  defineTool({
333
338
  name: "getCompanyExecutiveCompensation",
334
- description: "Get the company executive compensation",
335
- inputSchema: symbolSchema,
336
- execute: async ({ symbol: symbol2 }) => toToolResponse(await getFMPClient().company.getExecutiveCompensation(symbol2))
339
+ description: "Get the company executive compensation (at most `limit` records)",
340
+ inputSchema: symbolSchema.extend({
341
+ limit: zod.z.number().int().positive().default(20).describe("Max number of compensation records to return (default 20)")
342
+ }),
343
+ execute: async ({ symbol: symbol2, limit: limit2 = 20 }) => toToolResponse(limitRows(await getFMPClient().company.getExecutiveCompensation(symbol2), limit2))
337
344
  }),
338
345
  defineTool({
339
346
  name: "getStockPeers",
@@ -378,7 +385,7 @@ var financialDefinitions = [
378
385
  ),
379
386
  statementTool(
380
387
  "getFinancialRatios",
381
- "Get financial ratios for a company including profitability, liquidity, and efficiency metrics",
388
+ "Get financial ratios for a company by period: valuation (P/E incl. diluted P/E, PEG, P/B, P/S, P/FCF, EV multiple), profitability margins, liquidity, leverage, efficiency, and per-share metrics",
382
389
  "financial ratios",
383
390
  (args) => getFMPClient().financial.getFinancialRatios(args)
384
391
  ),
@@ -435,7 +442,7 @@ var financialDefinitions = [
435
442
  }),
436
443
  defineTool({
437
444
  name: "getFinancialRatiosTTM",
438
- description: "Get current trailing-twelve-month (TTM) financial ratios for a company (margins, returns, liquidity)",
445
+ description: "Get current trailing-twelve-month (TTM) financial ratios for a company (one snapshot row): valuation (P/E incl. diluted P/E, PEG, P/B, P/S, P/FCF, EV multiple), margins, liquidity, leverage, and per-share metrics",
439
446
  inputSchema: zod.z.object({ symbol: symbol("TTM financial ratios") }),
440
447
  execute: async ({ symbol: symbol2 }) => toToolResponse(await getFMPClient().financial.getFinancialRatiosTTM({ symbol: symbol2 }))
441
448
  }),
@@ -458,29 +465,36 @@ var financialDefinitions = [
458
465
  ];
459
466
  var dateRangeSchema = zod.z.object({
460
467
  from: zod.z.string().optional().nullable().describe("Start date in YYYY-MM-DD format (optional)"),
461
- to: zod.z.string().optional().nullable().describe("End date in YYYY-MM-DD format (optional)")
468
+ to: zod.z.string().optional().nullable().describe("End date in YYYY-MM-DD format (optional)"),
469
+ limit: zod.z.number().int().positive().default(50).describe("Max number of entries to return (default 50)")
462
470
  });
463
471
  var calendarDefinitions = [
464
472
  defineTool({
465
473
  name: "getEarningsCalendar",
466
- description: "Get earnings calendar showing upcoming and recent earnings announcements",
474
+ description: "Get earnings calendar showing upcoming and recent earnings announcements (at most `limit` entries; narrow the date range for full coverage)",
467
475
  inputSchema: dateRangeSchema,
468
- execute: async ({ from, to }) => toToolResponse(
469
- await getFMPClient().calendar.getEarningsCalendar({
470
- from: from ?? void 0,
471
- to: to ?? void 0
472
- })
476
+ execute: async ({ from, to, limit: limit2 = 50 }) => toToolResponse(
477
+ limitRows(
478
+ await getFMPClient().calendar.getEarningsCalendar({
479
+ from: from ?? void 0,
480
+ to: to ?? void 0
481
+ }),
482
+ limit2
483
+ )
473
484
  )
474
485
  }),
475
486
  defineTool({
476
487
  name: "getEconomicCalendar",
477
- description: "Get economic calendar showing upcoming and recent economic events and indicators",
488
+ description: "Get economic calendar showing upcoming and recent economic events and indicators (at most `limit` entries; narrow the date range for full coverage)",
478
489
  inputSchema: dateRangeSchema,
479
- execute: async ({ from, to }) => toToolResponse(
480
- await getFMPClient().calendar.getEconomicsCalendar({
481
- from: from ?? void 0,
482
- to: to ?? void 0
483
- })
490
+ execute: async ({ from, to, limit: limit2 = 50 }) => toToolResponse(
491
+ limitRows(
492
+ await getFMPClient().calendar.getEconomicsCalendar({
493
+ from: from ?? void 0,
494
+ to: to ?? void 0
495
+ }),
496
+ limit2
497
+ )
484
498
  )
485
499
  })
486
500
  ];
@@ -544,17 +558,20 @@ var economicDefinitions = [
544
558
  var etfDefinitions = [
545
559
  defineTool({
546
560
  name: "getETFHoldings",
547
- description: "Get ETF holdings for a specific ETF symbol, showing the underlying assets and their weights",
561
+ description: "Get the largest holdings of an ETF (by portfolio weight), showing the underlying assets and their weights",
548
562
  inputSchema: zod.z.object({
549
563
  symbol: zod.z.string().min(1, "ETF symbol is required").describe("ETF symbol (e.g., SPY, QQQ, VTI)"),
550
- date: zod.z.string().optional().nullable().describe("Date for holdings in YYYY-MM-DD format (optional)")
564
+ date: zod.z.string().optional().nullable().describe("Date for holdings in YYYY-MM-DD format (optional)"),
565
+ limit: zod.z.number().int().positive().default(50).describe("Max number of holdings to return, largest weight first (default 50)")
551
566
  }),
552
- execute: async ({ symbol: symbol2, date }) => {
567
+ execute: async ({ symbol: symbol2, date, limit: limit2 = 50 }) => {
553
568
  const params = { symbol: symbol2 };
554
569
  if (date) {
555
570
  params.date = date;
556
571
  }
557
- return toToolResponse(await getFMPClient().etf.getHoldings(params));
572
+ return toToolResponse(
573
+ limitRows(await getFMPClient().etf.getHoldings(params), limit2, (a, b) => b.pctVal - a.pctVal)
574
+ );
558
575
  }
559
576
  }),
560
577
  defineTool({
@@ -580,11 +597,20 @@ var insiderDefinitions = [
580
597
  var institutionalDefinitions = [
581
598
  defineTool({
582
599
  name: "getInstitutionalHolders",
583
- description: "Get institutional holders for a specific stock symbol showing which institutions own shares and their holdings",
600
+ description: "Get the largest institutional holders of a stock (by shares held), showing which institutions own shares and their holdings",
584
601
  inputSchema: zod.z.object({
585
- symbol: zod.z.string().min(1, "Stock symbol is required").describe("Stock symbol (e.g., AAPL, MSFT, GOOGL)")
602
+ symbol: zod.z.string().min(1, "Stock symbol is required").describe("Stock symbol (e.g., AAPL, MSFT, GOOGL)"),
603
+ limit: zod.z.number().int().positive().default(20).describe("Max number of holders to return, largest first (default 20)")
586
604
  }),
587
- execute: async ({ symbol: symbol2 }) => toToolResponse(await getFMPClient().institutional.getInstitutionalHolders({ symbol: symbol2 }))
605
+ // FMP returns thousands of holders in no particular order (~1 MB for AAPL),
606
+ // so sort by shares held and keep the top `limit`.
607
+ execute: async ({ symbol: symbol2, limit: limit2 = 20 }) => toToolResponse(
608
+ limitRows(
609
+ await getFMPClient().institutional.getInstitutionalHolders({ symbol: symbol2 }),
610
+ limit2,
611
+ (a, b) => b.shares - a.shares
612
+ )
613
+ )
588
614
  })
589
615
  ];
590
616
  var empty = zod.z.object({});
@@ -595,9 +621,11 @@ var snapshotDateSchema = zod.z.object({
595
621
  var marketDefinitions = [
596
622
  defineTool({
597
623
  name: "getMarketPerformance",
598
- description: "Get overall market performance data including major indices performance",
599
- inputSchema: empty,
600
- execute: async () => toToolResponse(await getFMPClient().market.getMarketPerformance())
624
+ description: "Get overall market performance data including major indices performance (at most `limit` indices)",
625
+ inputSchema: zod.z.object({
626
+ limit: zod.z.number().int().positive().default(50).describe("Max number of indices to return (default 50)")
627
+ }),
628
+ execute: async ({ limit: limit2 = 50 }) => toToolResponse(limitRows(await getFMPClient().market.getMarketPerformance(), limit2))
601
629
  }),
602
630
  defineTool({
603
631
  name: "getSectorPerformance",
@@ -801,6 +829,7 @@ var technicalDefinitions = [
801
829
  }
802
830
  })
803
831
  ];
832
+ var byNameLimit = zod.z.number().int().positive().default(50).describe("Max number of trades to return (default 50)");
804
833
  var symbolSchema3 = zod.z.object({
805
834
  symbol: zod.z.string().min(1, "Stock symbol is required").describe("Stock symbol (e.g., AAPL, MSFT, GOOGL)")
806
835
  });
@@ -822,19 +851,25 @@ var senateHouseDefinitions = [
822
851
  }),
823
852
  defineTool({
824
853
  name: "getSenateTradingByName",
825
- description: "Get senate trading data for a specific senator by name showing their trading activity",
854
+ description: "Get senate trading data for a specific senator by name showing their trading activity (at most `limit` trades)",
826
855
  inputSchema: zod.z.object({
827
- name: zod.z.string().min(1, "Name is required").describe("The name of the senator to get trading data for")
856
+ name: zod.z.string().min(1, "Name is required").describe("The name of the senator to get trading data for"),
857
+ limit: byNameLimit
828
858
  }),
829
- execute: async ({ name }) => toToolResponse(await getFMPClient().senateHouse.getSenateTradingByName({ name }))
859
+ execute: async ({ name, limit: limit2 = 50 }) => toToolResponse(
860
+ limitRows(await getFMPClient().senateHouse.getSenateTradingByName({ name }), limit2)
861
+ )
830
862
  }),
831
863
  defineTool({
832
864
  name: "getHouseTradingByName",
833
- description: "Get house trading data for a specific representative by name showing their trading activity",
865
+ description: "Get house trading data for a specific representative by name showing their trading activity (at most `limit` trades)",
834
866
  inputSchema: zod.z.object({
835
- name: zod.z.string().min(1, "Name is required").describe("The name of the representative to get trading data for")
867
+ name: zod.z.string().min(1, "Name is required").describe("The name of the representative to get trading data for"),
868
+ limit: byNameLimit
836
869
  }),
837
- execute: async ({ name }) => toToolResponse(await getFMPClient().senateHouse.getHouseTradingByName({ name }))
870
+ execute: async ({ name, limit: limit2 = 50 }) => toToolResponse(
871
+ limitRows(await getFMPClient().senateHouse.getHouseTradingByName({ name }), limit2)
872
+ )
838
873
  }),
839
874
  defineTool({
840
875
  name: "getSenateTradingRSSFeed",