Skip to main content
Glama

MCP Avantage

by MissionSquad
index.ts45.1 kB
#!/usr/bin/env node import { FastMCP, UserError, Context } from "@missionsquad/fastmcp"; // Import Context import { AVantage } from "@missionsquad/avantage"; import { z } from "zod"; import { resourceManager } from "./resource-manager.js"; import { config, apiKeyErrorMessage } from "./config.js"; import { logger } from "./logger.js"; import * as schemas from "./schemas.js"; // Import all schemas // ============================================================================= // MCP Server Initialization // ============================================================================= const server = new FastMCP({ name: "mcp-avantage-server", version: "1.0.0", // description: // "MCP Server providing tools to interact with the Alpha Vantage API via the @j4ys0n/avantage library.", }); // ============================================================================= // Generic Tool Execution Logic // ============================================================================= /** * A generic function to execute an Avantage library method within an MCP tool. * Handles API key resolution, AVantage instance management via ResourceManager, * calling the library method, and handling the response/errors. * * @param toolName The name of the MCP tool (for logging). * @param args Validated tool arguments. * @param context MCP execution context containing extraArgs and requestId. * @param avantageMethod A function that takes the AVantage instance and args, and calls the appropriate library method. * @returns The stringified data from the Avantage library call. * @throws {UserError} If authentication fails or the library call returns an error. */ async function executeAvantageTool<TArgs, TResult>( toolName: string, args: TArgs, context: Context<Record<string, unknown> | undefined>, // Use the imported Context type directly avantageMethod: ( av: AVantage, args: TArgs ) => Promise<{ error?: boolean; reason?: string; data?: TResult }> ): Promise<string> { logger.info(`Executing '${toolName}' tool for request ID: ${context}`); logger.debug(`Args for ${toolName}: ${JSON.stringify(args)}`); // --- Authentication & Resource Management --- // Access extraArgs safely - it might be null or undefined const extraArgsApiKey = context.extraArgs?.apiKey as string | undefined; const apiKey = extraArgsApiKey || config.apiKey; if (!apiKey) { logger.error(`'${toolName}' failed: Alpha Vantage API key missing.`); throw new UserError(apiKeyErrorMessage); } logger.debug( `Using AV API key (source: ${extraArgsApiKey ? "extraArgs" : "environment"}) for ${toolName}` ); try { // Get or create AVantage instance managed by ResourceManager const av = await resourceManager.getResource<AVantage>( apiKey, // Cache key is the resolved API key "avantage_client", // Type identifier for logging async (key) => { // Factory Function logger.info( `Creating new AVantage instance for key ending ...${key.slice(-4)}` ); // AVantage library reads AV_PREMIUM from process.env internally return new AVantage(key); }, async (avInstance) => { // Cleanup Function (no-op needed for AVantage) logger.debug(`Destroying AVantage instance (no-op)`); } ); // --- Library Call --- const result = await avantageMethod(av, args); // --- Response Handling --- if (result.error) { logger.warn( `'${toolName}' failed. Reason from avantage: ${result.reason}` ); throw new UserError(result.reason || `Tool '${toolName}' failed.`); } if (result.data === undefined || result.data === null) { logger.warn(`'${toolName}' completed successfully but returned no data.`); return "null"; // Return string "null" for empty data } logger.info(`'${toolName}' completed successfully.`); // Stringify the data part of the response return JSON.stringify(result.data); } catch (error: any) { logger.error( `Error during execution of '${toolName}': ${error.message}`, error ); // If it's already a UserError, rethrow it if (error instanceof UserError) { throw error; } // Otherwise, wrap it in a UserError throw new UserError( `An unexpected error occurred while executing tool '${toolName}': ${error.message}` ); } } // ============================================================================= // Tool Definitions // ============================================================================= // --- Alpha Intelligence Tools --- server.addTool({ name: "alphaIntelligence_newsSentiments", description: "Fetches market news and sentiment data from Alpha Vantage.", parameters: schemas.NewsSentimentsParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "alphaIntelligence_newsSentiments", args, context, (av, params) => av.alphaIntelligence.newsSentiments(params) ), }); server.addTool({ name: "alphaIntelligence_topGainersLosers", description: "Retrieves the top N gainers, losers, and most actively traded US tickers.", parameters: z.object({}), // No parameters needed execute: ( args, context // Let type be inferred ) => executeAvantageTool( "alphaIntelligence_topGainersLosers", args, context, (av) => av.alphaIntelligence.topGainersLosers() ), }); server.addTool({ name: "alphaIntelligence_insiderTransactions", description: "Fetches aggregated insider trading information for a given symbol.", parameters: schemas.InsiderTransactionsParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "alphaIntelligence_insiderTransactions", args, context, (av, params) => av.alphaIntelligence.insiderTransactions(params.symbol) ), }); // Note: Analytics endpoints are complex and might require more specific handling or schema adjustments // server.addTool({ // name: 'alphaIntelligence_fixedWindowAnalytics', // description: 'Performs analytics calculations over a fixed time window.', // parameters: schemas.FixedWindowAnalyticsParamsSchema, // execute: (args, context) => // Let type be inferred // executeAvantageTool('alphaIntelligence_fixedWindowAnalytics', args, context, (av, params) => av.alphaIntelligence.fixedWindowAnalytics(params)), // }) // server.addTool({ // name: 'alphaIntelligence_slidingWindowAnalytics', // description: 'Performs analytics calculations over a sliding time window.', // parameters: schemas.SlidingWindowAnalyticsParamsSchema, // execute: (args, context) => // Let type be inferred // executeAvantageTool('alphaIntelligence_slidingWindowAnalytics', args, context, (av, params) => av.alphaIntelligence.slidingWindowAnalytics(params)), // }) // --- Commodities Tools --- server.addTool({ name: "commodities_wtiCrudeOil", description: "Retrieves West Texas Intermediate (WTI) crude oil prices.", parameters: schemas.CommoditiesDailyWeeklyMonthlyParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "commodities_wtiCrudeOil", args, context, (av, params) => av.commodities.wtiCrudeOil(params) ), }); server.addTool({ name: "commodities_brentCrudeOil", description: "Retrieves Brent crude oil prices.", parameters: schemas.CommoditiesDailyWeeklyMonthlyParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "commodities_brentCrudeOil", args, context, (av, params) => av.commodities.brentCrudeOil(params) ), }); server.addTool({ name: "commodities_naturalGas", description: "Retrieves natural gas prices.", parameters: schemas.CommoditiesDailyWeeklyMonthlyParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("commodities_naturalGas", args, context, (av, params) => av.commodities.naturalGas(params) ), }); server.addTool({ name: "commodities_copper", description: "Retrieves copper prices.", parameters: schemas.CommoditiesMonthlyQuarterlyAnnualParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("commodities_copper", args, context, (av, params) => av.commodities.copper(params) ), }); server.addTool({ name: "commodities_aluminum", description: "Retrieves aluminum prices.", parameters: schemas.CommoditiesMonthlyQuarterlyAnnualParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("commodities_aluminum", args, context, (av, params) => av.commodities.aluminum(params) ), }); server.addTool({ name: "commodities_wheat", description: "Retrieves wheat prices.", parameters: schemas.CommoditiesMonthlyQuarterlyAnnualParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("commodities_wheat", args, context, (av, params) => av.commodities.wheat(params) ), }); server.addTool({ name: "commodities_corn", description: "Retrieves corn prices.", parameters: schemas.CommoditiesMonthlyQuarterlyAnnualParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("commodities_corn", args, context, (av, params) => av.commodities.corn(params) ), }); server.addTool({ name: "commodities_cotton", description: "Retrieves cotton prices.", parameters: schemas.CommoditiesMonthlyQuarterlyAnnualParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("commodities_cotton", args, context, (av, params) => av.commodities.cotton(params) ), }); server.addTool({ name: "commodities_sugar", description: "Retrieves sugar prices.", parameters: schemas.CommoditiesMonthlyQuarterlyAnnualParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("commodities_sugar", args, context, (av, params) => av.commodities.sugar(params) ), }); server.addTool({ name: "commodities_coffee", description: "Retrieves coffee prices.", parameters: schemas.CommoditiesMonthlyQuarterlyAnnualParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("commodities_coffee", args, context, (av, params) => av.commodities.coffee(params) ), }); server.addTool({ name: "commodities_globalIndex", description: "Retrieves the global commodity index.", parameters: schemas.CommoditiesMonthlyQuarterlyAnnualParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "commodities_globalIndex", args, context, (av, params) => av.commodities.globalIndex(params) ), }); // --- Core Stock Tools --- server.addTool({ name: "coreStock_intraday", description: "Fetches intraday time series data for a stock symbol.", parameters: schemas.CoreStockIntradayParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("coreStock_intraday", args, context, (av, params) => av.coreStock.intraday(params) ), }); server.addTool({ name: "coreStock_daily", description: "Fetches daily time series data for a stock symbol.", parameters: schemas.CoreStockDailyParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("coreStock_daily", args, context, (av, params) => av.coreStock.daily(params) ), }); server.addTool({ name: "coreStock_dailyAdjusted", description: "Fetches daily adjusted time series data for a stock symbol.", parameters: schemas.CoreStockDailyAdjustedParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "coreStock_dailyAdjusted", args, context, (av, params) => av.coreStock.dailyAdjusted(params) ), }); server.addTool({ name: "coreStock_weekly", description: "Fetches weekly time series data for a stock symbol.", parameters: schemas.CoreStockWeeklyParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("coreStock_weekly", args, context, (av, params) => av.coreStock.weekly(params) ), }); server.addTool({ name: "coreStock_weeklyAdjusted", description: "Fetches weekly adjusted time series data for a stock symbol.", parameters: schemas.CoreStockWeeklyAdjustedParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "coreStock_weeklyAdjusted", args, context, (av, params) => av.coreStock.weeklyAdjusted(params) ), }); server.addTool({ name: "coreStock_monthly", description: "Fetches monthly time series data for a stock symbol.", parameters: schemas.CoreStockMonthlyParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("coreStock_monthly", args, context, (av, params) => av.coreStock.monthly(params) ), }); server.addTool({ name: "coreStock_monthlyAdjusted", description: "Fetches monthly adjusted time series data for a stock symbol.", parameters: schemas.CoreStockMonthlyAdjustedParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "coreStock_monthlyAdjusted", args, context, (av, params) => av.coreStock.monthlyAdjusted(params) ), }); server.addTool({ name: "coreStock_quote", description: "Fetches a global quote for a single stock symbol.", parameters: schemas.CoreStockQuoteParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("coreStock_quote", args, context, (av, params) => av.coreStock.quote(params) ), }); server.addTool({ name: "coreStock_bulkQuotes", description: "Fetches realtime quotes for multiple stock symbols (up to 100). Premium endpoint.", parameters: schemas.CoreStockBulkQuotesParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("coreStock_bulkQuotes", args, context, (av, params) => av.coreStock.bulkQuotes(params) ), }); server.addTool({ name: "coreStock_search", description: "Searches for stock symbols matching keywords.", parameters: schemas.CoreStockSearchParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("coreStock_search", args, context, (av, params) => av.coreStock.search(params) ), }); // --- Crypto Tools --- server.addTool({ name: "crypto_exchangeRates", description: "Fetches the realtime exchange rate for a cryptocurrency pair (e.g., BTC to USD).", parameters: schemas.CryptoExchangeRateParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("crypto_exchangeRates", args, context, (av, params) => av.crypto.exchangeRates(params.from_currency, params.to_currency) ), }); server.addTool({ name: "crypto_intraday", description: "Fetches intraday time series data for a cryptocurrency.", parameters: schemas.CryptoIntradayParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("crypto_intraday", args, context, (av, params) => av.crypto.intraday(params) ), }); server.addTool({ name: "crypto_daily", description: "Fetches daily time series data for a cryptocurrency.", parameters: schemas.CryptoTimeSeriesParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("crypto_daily", args, context, (av, params) => av.crypto.daily(params) ), }); server.addTool({ name: "crypto_weekly", description: "Fetches weekly time series data for a cryptocurrency.", parameters: schemas.CryptoTimeSeriesParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("crypto_weekly", args, context, (av, params) => av.crypto.weekly(params) ), }); server.addTool({ name: "crypto_monthly", description: "Fetches monthly time series data for a cryptocurrency.", parameters: schemas.CryptoTimeSeriesParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("crypto_monthly", args, context, (av, params) => av.crypto.monthly(params) ), }); // --- Economic Indicators Tools --- server.addTool({ name: "economicIndicators_realGDP", description: "Retrieves US Real Gross Domestic Product (GDP) data.", parameters: schemas.EconomicIndicatorsRealGDPParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "economicIndicators_realGDP", args, context, (av, params) => av.economicIndicators.realGDP(params) ), }); server.addTool({ name: "economicIndicators_realGDPPerCapita", description: "Retrieves US Real GDP per Capita data.", parameters: schemas.EconomicIndicatorsDataTypeParamSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "economicIndicators_realGDPPerCapita", args, context, (av, params) => av.economicIndicators.realGDPPerCapita(params) ), }); server.addTool({ name: "economicIndicators_treasuryYield", description: "Retrieves US Treasury yield curve data for various maturities.", parameters: schemas.EconomicIndicatorsTreasuryYieldParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "economicIndicators_treasuryYield", args, context, (av, params) => av.economicIndicators.treasuryYield(params) ), }); server.addTool({ name: "economicIndicators_federalFundsRate", description: "Retrieves the effective federal funds rate.", parameters: schemas.EconomicIndicatorsFederalFundsRateParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "economicIndicators_federalFundsRate", args, context, (av, params) => av.economicIndicators.federalFundsRate(params) ), }); server.addTool({ name: "economicIndicators_cpi", description: "Retrieves US Consumer Price Index (CPI) data.", parameters: schemas.EconomicIndicatorsCPIParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("economicIndicators_cpi", args, context, (av, params) => av.economicIndicators.cpi(params) ), }); server.addTool({ name: "economicIndicators_inflation", description: "Retrieves US inflation rate data.", parameters: schemas.EconomicIndicatorsDataTypeParamSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "economicIndicators_inflation", args, context, (av, params) => av.economicIndicators.inflation(params) ), }); server.addTool({ name: "economicIndicators_retailSales", description: "Retrieves US retail sales data.", parameters: schemas.EconomicIndicatorsDataTypeParamSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "economicIndicators_retailSales", args, context, (av, params) => av.economicIndicators.retailSales(params) ), }); server.addTool({ name: "economicIndicators_durableGoodsOrders", description: "Retrieves US durable goods orders data.", parameters: schemas.EconomicIndicatorsDataTypeParamSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "economicIndicators_durableGoodsOrders", args, context, (av, params) => av.economicIndicators.durableGoodsOrders(params) ), }); server.addTool({ name: "economicIndicators_unemploymentRate", description: "Retrieves US unemployment rate data.", parameters: schemas.EconomicIndicatorsDataTypeParamSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "economicIndicators_unemploymentRate", args, context, (av, params) => av.economicIndicators.unemploymentRate(params) ), }); server.addTool({ name: "economicIndicators_nonfarmPayroll", description: "Retrieves US nonfarm payroll data.", parameters: schemas.EconomicIndicatorsDataTypeParamSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "economicIndicators_nonfarmPayroll", args, context, (av, params) => av.economicIndicators.nonfarmPayroll(params) ), }); // --- Forex Tools --- server.addTool({ name: "forex_exchangeRates", description: "Fetches the realtime exchange rate for a currency pair (e.g., EUR to USD).", parameters: schemas.ForexExchangeRateParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("forex_exchangeRates", args, context, (av, params) => av.forex.exchangeRates(params.from_currency, params.to_currency) ), }); server.addTool({ name: "forex_intraday", description: "Fetches intraday time series data for a Forex pair.", parameters: schemas.ForexIntradayParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("forex_intraday", args, context, (av, params) => av.forex.intraday(params) ), }); server.addTool({ name: "forex_daily", description: "Fetches daily time series data for a Forex pair.", parameters: schemas.ForexDailyParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("forex_daily", args, context, (av, params) => av.forex.daily(params) ), }); server.addTool({ name: "forex_weekly", description: "Fetches weekly time series data for a Forex pair.", parameters: schemas.ForexWeeklyMonthlyParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("forex_weekly", args, context, (av, params) => av.forex.weekly(params) ), }); server.addTool({ name: "forex_monthly", description: "Fetches monthly time series data for a Forex pair.", parameters: schemas.ForexWeeklyMonthlyParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("forex_monthly", args, context, (av, params) => av.forex.monthly(params) ), }); // --- Fundamental Data Tools --- server.addTool({ name: "fundamentalData_companyOverview", description: "Fetches company overview details. Premium endpoint.", parameters: schemas.FundamentalDataSymbolParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "fundamentalData_companyOverview", args, context, (av, params) => av.fundamentalData.companyOverview(params.symbol) ), }); server.addTool({ name: "fundamentalData_etfProfile", description: "Fetches ETF profile details.", parameters: schemas.FundamentalDataSymbolParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "fundamentalData_etfProfile", args, context, (av, params) => av.fundamentalData.etfProfile(params.symbol) ), }); server.addTool({ name: "fundamentalData_dividends", description: "Fetches historical dividend data for a symbol.", parameters: schemas.FundamentalDataSymbolParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "fundamentalData_dividends", args, context, (av, params) => av.fundamentalData.dividends(params.symbol) ), }); server.addTool({ name: "fundamentalData_splits", description: "Fetches historical stock split data for a symbol.", parameters: schemas.FundamentalDataSymbolParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("fundamentalData_splits", args, context, (av, params) => av.fundamentalData.splits(params.symbol) ), }); server.addTool({ name: "fundamentalData_incomeStatement", description: "Fetches income statement data (annual/quarterly). Premium endpoint.", parameters: schemas.FundamentalDataSymbolParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "fundamentalData_incomeStatement", args, context, (av, params) => av.fundamentalData.incomeStatement(params.symbol) ), }); server.addTool({ name: "fundamentalData_balanceSheet", description: "Fetches balance sheet data (annual/quarterly). Premium endpoint.", parameters: schemas.FundamentalDataSymbolParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "fundamentalData_balanceSheet", args, context, (av, params) => av.fundamentalData.balanceSheet(params.symbol) ), }); server.addTool({ name: "fundamentalData_cashFlow", description: "Fetches cash flow data (annual/quarterly). Premium endpoint.", parameters: schemas.FundamentalDataSymbolParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "fundamentalData_cashFlow", args, context, (av, params) => av.fundamentalData.cashFlow(params.symbol) ), }); server.addTool({ name: "fundamentalData_earnings", description: "Fetches earnings data (annual/quarterly). Premium endpoint.", parameters: schemas.FundamentalDataSymbolParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "fundamentalData_earnings", args, context, (av, params) => av.fundamentalData.earnings(params.symbol) ), }); server.addTool({ name: "fundamentalData_listingStatus", description: "Fetches active or delisted symbols (CSV endpoint).", parameters: schemas.FundamentalDataListingStatusParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "fundamentalData_listingStatus", args, context, (av, params) => av.fundamentalData.listingStatus(params) ), }); server.addTool({ name: "fundamentalData_earningsCalendar", description: "Fetches upcoming earnings calendar (CSV endpoint).", parameters: schemas.FundamentalDataEarningsCalendarParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "fundamentalData_earningsCalendar", args, context, (av, params) => av.fundamentalData.earningsCalendar(params) ), }); server.addTool({ name: "fundamentalData_ipoCalendar", description: "Fetches upcoming IPO calendar (CSV endpoint).", parameters: z.object({}), // No parameters execute: ( args, context // Let type be inferred ) => executeAvantageTool("fundamentalData_ipoCalendar", args, context, (av) => av.fundamentalData.ipoCalendar() ), }); // --- Options Data Tools (Premium) --- server.addTool({ name: "optionsData_realtimeOptions", description: "Fetches realtime options chain data. Premium endpoint.", parameters: schemas.OptionsDataRealtimeOptionsParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "optionsData_realtimeOptions", args, context, (av, params) => av.optionsData.realtimeOptions(params) ), }); server.addTool({ name: "optionsData_historicalOptions", description: "Fetches historical options chain data. Premium endpoint.", parameters: schemas.OptionsDataHistoricalOptionsParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "optionsData_historicalOptions", args, context, (av, params) => av.optionsData.historicalOptions(params) ), }); // --- Technical Indicators Tools --- // Group 1: Basic Moving Averages server.addTool({ name: "technicalIndicators_sma", description: "Simple Moving Average (SMA)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_sma", args, context, (av, params) => av.technicalIndicators.sma(params) ), }); server.addTool({ name: "technicalIndicators_ema", description: "Exponential Moving Average (EMA)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_ema", args, context, (av, params) => av.technicalIndicators.ema(params) ), }); server.addTool({ name: "technicalIndicators_wma", description: "Weighted Moving Average (WMA)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_wma", args, context, (av, params) => av.technicalIndicators.wma(params) ), }); server.addTool({ name: "technicalIndicators_dema", description: "Double Exponential Moving Average (DEMA)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_dema", args, context, (av, params) => av.technicalIndicators.dema(params) ), }); server.addTool({ name: "technicalIndicators_tema", description: "Triple Exponential Moving Average (TEMA)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_tema", args, context, (av, params) => av.technicalIndicators.tema(params) ), }); server.addTool({ name: "technicalIndicators_trima", description: "Triangular Moving Average (TRIMA)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_trima", args, context, (av, params) => av.technicalIndicators.trima(params) ), }); server.addTool({ name: "technicalIndicators_kama", description: "Kaufman Adaptive Moving Average (KAMA)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_kama", args, context, (av, params) => av.technicalIndicators.kama(params) ), }); // Group 2: Volume Indicators server.addTool({ name: "technicalIndicators_ad", description: "Chaikin A/D Line", parameters: schemas.TechnicalIndicatorsCommonIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("technicalIndicators_ad", args, context, (av, params) => av.technicalIndicators.ad(params) ), }); server.addTool({ name: "technicalIndicators_adosc", description: "Chaikin A/D Oscillator", parameters: schemas.TechnicalIndicatorsFastSlowIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_adosc", args, context, (av, params) => av.technicalIndicators.adosc(params) ), }); server.addTool({ name: "technicalIndicators_obv", description: "On Balance Volume (OBV)", parameters: schemas.TechnicalIndicatorsCommonIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_obv", args, context, (av, params) => av.technicalIndicators.obv(params) ), }); // Group 3: Hilbert Transform Indicators server.addTool({ name: "technicalIndicators_htTrendline", description: "Hilbert Transform - Instantaneous Trendline", parameters: schemas.TechnicalIndicatorsHtTrendlineParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_htTrendline", args, context, (av, params) => av.technicalIndicators.htTrendline(params) ), }); server.addTool({ name: "technicalIndicators_htSine", description: "Hilbert Transform - Sine Wave", parameters: schemas.TechnicalIndicatorsHtSineParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_htSine", args, context, (av, params) => av.technicalIndicators.htSine(params) ), }); server.addTool({ name: "technicalIndicators_htTrendmode", description: "Hilbert Transform - Trend vs Cycle Mode", parameters: schemas.TechnicalIndicatorsHtTrendmodeParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_htTrendmode", args, context, (av, params) => av.technicalIndicators.htTrendmode(params) ), }); server.addTool({ name: "technicalIndicators_htDcperiod", description: "Hilbert Transform - Dominant Cycle Period", parameters: schemas.TechnicalIndicatorsHtDcperiodParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_htDcperiod", args, context, (av, params) => av.technicalIndicators.htDcperiod(params) ), }); server.addTool({ name: "technicalIndicators_htDcphase", description: "Hilbert Transform - Dominant Cycle Phase", parameters: schemas.TechnicalIndicatorsHtDcphaseParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_htDcphase", args, context, (av, params) => av.technicalIndicators.htDcphase(params) ), }); server.addTool({ name: "technicalIndicators_htPhasor", description: "Hilbert Transform - Phasor Components", parameters: schemas.TechnicalIndicatorsHtPhasorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_htPhasor", args, context, (av, params) => av.technicalIndicators.htPhasor(params) ), }); // Group 4: MAMA Indicator server.addTool({ name: "technicalIndicators_mama", description: "MESA Adaptive Moving Average (MAMA)", parameters: schemas.TechnicalIndicatorsMamaIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_mama", args, context, (av, params) => av.technicalIndicators.mama(params) ), }); // Group 5: T3 and NATR server.addTool({ name: "technicalIndicators_t3", description: "Triple Exponential Moving Average (T3)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("technicalIndicators_t3", args, context, (av, params) => av.technicalIndicators.t3(params) ), }); server.addTool({ name: "technicalIndicators_natr", description: "Normalized Average True Range (NATR)", parameters: schemas.TechnicalIndicatorsNatrParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_natr", args, context, (av, params) => av.technicalIndicators.natr(params) ), }); // Group 6: VWAP (Premium) server.addTool({ name: "technicalIndicators_vwap", description: "Volume Weighted Average Price (VWAP). Premium endpoint, requires intraday interval.", parameters: schemas.TechnicalIndicatorsCommonIndicatorParamsSchema, // Requires interval check execute: (args, context) => { // Let type be inferred // Add specific check for VWAP interval requirement if (!args.interval.includes("min")) { throw new UserError( "VWAP only supports intraday intervals (e.g., 1min, 5min, 15min, 30min, 60min)." ); } return executeAvantageTool( "technicalIndicators_vwap", args, context, (av, params) => av.technicalIndicators.vwap(params) ); }, }); // Other Indicators server.addTool({ name: "technicalIndicators_rocr", description: "Rate of change ratio (ROCR)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_rocr", args, context, (av, params) => av.technicalIndicators.rocr(params) ), }); server.addTool({ name: "technicalIndicators_aroon", description: "Aroon", parameters: schemas.TechnicalIndicatorsAroonParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_aroon", args, context, (av, params) => av.technicalIndicators.aroon(params) ), }); server.addTool({ name: "technicalIndicators_aroonosc", description: "Aroon Oscillator", parameters: schemas.TechnicalIndicatorsAroonOscParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_aroonosc", args, context, (av, params) => av.technicalIndicators.aroonosc(params) ), }); server.addTool({ name: "technicalIndicators_mfi", description: "Money Flow Index (MFI)", parameters: schemas.TechnicalIndicatorsMfiParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_mfi", args, context, (av, params) => av.technicalIndicators.mfi(params) ), }); server.addTool({ name: "technicalIndicators_trix", description: "1-day Rate Of Change (ROC) of a Triple Smooth EMA (TRIX)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_trix", args, context, (av, params) => av.technicalIndicators.trix(params) ), }); server.addTool({ name: "technicalIndicators_ultosc", description: "Ultimate Oscillator", parameters: schemas.TechnicalIndicatorsCommonIndicatorParamsSchema, // Needs specific params? Check AV docs execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_ultosc", args, context, (av, params) => av.technicalIndicators.ultosc(params) ), }); server.addTool({ name: "technicalIndicators_dx", description: "Directional Movement Index (DX)", parameters: schemas.TechnicalIndicatorsDxParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool("technicalIndicators_dx", args, context, (av, params) => av.technicalIndicators.dx(params) ), }); server.addTool({ name: "technicalIndicators_minusDI", description: "Minus Directional Indicator (-DI)", parameters: schemas.TechnicalIndicatorsMinusDiParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_minusDI", args, context, (av, params) => av.technicalIndicators.minusDI(params) ), }); server.addTool({ name: "technicalIndicators_plusDI", description: "Plus Directional Indicator (+DI)", parameters: schemas.TechnicalIndicatorsPlusDiParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_plusDI", args, context, (av, params) => av.technicalIndicators.plusDI(params) ), }); server.addTool({ name: "technicalIndicators_minusDM", description: "Minus Directional Movement (-DM)", parameters: schemas.TechnicalIndicatorsMinusDmParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_minusDM", args, context, (av, params) => av.technicalIndicators.minusDM(params) ), }); server.addTool({ name: "technicalIndicators_plusDM", description: "Plus Directional Movement (+DM)", parameters: schemas.TechnicalIndicatorsPlusDmParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_plusDM", args, context, (av, params) => av.technicalIndicators.plusDM(params) ), }); server.addTool({ name: "technicalIndicators_bbands", description: "Bollinger Bands (BBANDS)", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, // Needs more params? Check AV docs execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_bbands", args, context, (av, params) => av.technicalIndicators.bbands(params) ), }); server.addTool({ name: "technicalIndicators_midpoint", description: "Midpoint over period", parameters: schemas.TechnicalIndicatorsTimeSeriesIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_midpoint", args, context, (av, params) => av.technicalIndicators.midpoint(params) ), }); server.addTool({ name: "technicalIndicators_midprice", description: "Midpoint price over period", parameters: schemas.TechnicalIndicatorsMidpriceParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_midprice", args, context, (av, params) => av.technicalIndicators.midprice(params) ), }); server.addTool({ name: "technicalIndicators_sar", description: "Parabolic SAR", parameters: schemas.TechnicalIndicatorsCommonIndicatorParamsSchema, // Needs more params? Check AV docs execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_sar", args, context, (av, params) => av.technicalIndicators.sar(params) ), }); server.addTool({ name: "technicalIndicators_trange", description: "True Range", parameters: schemas.TechnicalIndicatorsCommonIndicatorParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_trange", args, context, (av, params) => av.technicalIndicators.trange(params) ), }); server.addTool({ name: "technicalIndicators_atr", description: "Average True Range (ATR)", parameters: schemas.TechnicalIndicatorsAtrParamsSchema, execute: ( args, context // Let type be inferred ) => executeAvantageTool( "technicalIndicators_atr", args, context, (av, params) => av.technicalIndicators.atr(params) ), }); // ============================================================================= // Server Lifecycle and Event Handling // ============================================================================= server.on("connect", (event) => { // Access client ID via session logger.info(`Client connected: ${event.session}`); }); server.on("disconnect", (event) => { // Access client ID via session logger.info(`Client disconnected: ${event.session}`); }); // Removed server.on('error', ...) as it's not a standard FastMCP event // and errors are handled via promises and process events. // Graceful shutdown handling const cleanup = () => { logger.info("Shutting down server and cleaning up resources..."); resourceManager.destroyAllNow(); logger.info("Resource cleanup complete."); }; process.on("SIGINT", () => { logger.info("Received SIGINT signal."); cleanup(); process.exit(0); }); process.on("SIGTERM", () => { logger.info("Received SIGTERM signal."); cleanup(); process.exit(0); }); process.on("uncaughtException", (error) => { logger.error("UNCAUGHT EXCEPTION:", error); cleanup(); process.exit(1); }); process.on("unhandledRejection", (reason, promise) => { logger.error("UNHANDLED REJECTION:", reason); cleanup(); process.exit(1); }); // ============================================================================= // Start the Server // ============================================================================= server .start({ transportType: "stdio", }) .then(() => { logger.info( `🚀 ${server.options.name} v${server.options.version} started successfully on stdio.` ); logger.info("Waiting for MCP client connections..."); }) .catch((error) => { logger.error("❌ Failed to start MCP server:", error); process.exit(1); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MissionSquad/mcp-avantage'

If you have feedback or need assistance with the MCP directory API, please join our Discord server