Skip to main content
Glama

Weather & Stock MCP Server

by Jeetinida
fundamentalsTimeSeries.js7.24 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.processResponse = exports.processQuery = void 0; exports.default = fundamentalsTimeSeries; const typebox_1 = require("@sinclair/typebox"); // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore: we have to ignore this for csm output. const timeseries_json_1 = __importDefault(require("../lib/timeseries.json")); const yahooFinanceTypes_js_1 = require("../lib/yahooFinanceTypes.js"); const FundamentalsTimeSeries_Types = ["quarterly", "annual", "trailing"]; const FundamentalsTimeSeries_Modules = [ "financials", "balance-sheet", "cash-flow", "all", ]; const FundamentalsTimeSeriesResultSchema = typebox_1.Type.Object({ date: yahooFinanceTypes_js_1.YahooFinanceDate, }, { additionalProperties: typebox_1.Type.Unknown(), title: "FundamentalsTimeSeriesResult", }); const FundamentalsTimeSeriesOptionsSchema = typebox_1.Type.Object({ period1: typebox_1.Type.Union([yahooFinanceTypes_js_1.YahooFinanceDate, yahooFinanceTypes_js_1.YahooNumber, typebox_1.Type.String()]), period2: typebox_1.Type.Optional(typebox_1.Type.Union([yahooFinanceTypes_js_1.YahooFinanceDate, yahooFinanceTypes_js_1.YahooNumber, typebox_1.Type.String()])), type: typebox_1.Type.Optional(typebox_1.Type.String()), merge: typebox_1.Type.Optional(typebox_1.Type.Boolean()), // This returns a completely different format that will break the transformer padTimeSeries: typebox_1.Type.Optional(typebox_1.Type.Boolean()), // Not exactly sure what this does, assume it pads p1 and p2??? lang: typebox_1.Type.Optional(typebox_1.Type.String()), region: typebox_1.Type.Optional(typebox_1.Type.String()), module: typebox_1.Type.String(), }, { title: "FundamentalsTimeSeriesOptions", }); const FundamentalsTimeSeriesResultsSchema = typebox_1.Type.Array(FundamentalsTimeSeriesResultSchema); const queryOptionsDefaults = { merge: false, padTimeSeries: true, lang: "en-US", region: "US", type: "quarterly", }; function fundamentalsTimeSeries(symbol, queryOptionsOverrides, moduleOptions) { return this._moduleExec({ moduleName: "options", query: { assertSymbol: symbol, url: `https://query1.finance.yahoo.com/ws/fundamentals-timeseries/v1/finance/timeseries/${symbol}`, needsCrumb: false, schema: FundamentalsTimeSeriesOptionsSchema, defaults: queryOptionsDefaults, overrides: queryOptionsOverrides, transformWith: exports.processQuery, }, result: { schema: FundamentalsTimeSeriesResultsSchema, transformWith(response) { if (!response || !response.timeseries) throw new Error(`Unexpected result: ${JSON.stringify(response)}`); return (0, exports.processResponse)(response); }, }, moduleOptions, }); } /** * Transform the input options into query parameters. * The options module defines which keys that are used in the query. * The keys are joined together into the query parameter type and * pre-fixed with the options type (e.g. annualTotalRevenue). * @param queryOptions Input query options. * @returns Query parameters. */ const processQuery = function (queryOptions) { // Convert dates if (!queryOptions.period2) queryOptions.period2 = new Date(); const dates = ["period1", "period2"]; for (const fieldName of dates) { const value = queryOptions[fieldName]; if (value instanceof Date) queryOptions[fieldName] = Math.floor(value.getTime() / 1000); else if (typeof value === "string") { const timestamp = new Date(value).getTime(); if (isNaN(timestamp)) throw new Error("yahooFinance.fundamentalsTimeSeries() option '" + fieldName + "' invalid date provided: '" + value + "'"); queryOptions[fieldName] = Math.floor(timestamp / 1000); } } // Validate query parameters. if (queryOptions.period1 === queryOptions.period2) { throw new Error("yahooFinance.fundamentalsTimeSeries() options `period1` and `period2` " + "cannot share the same value."); } else if (!FundamentalsTimeSeries_Types.includes(queryOptions.type || "")) { throw new Error("yahooFinance.fundamentalsTimeSeries() option type invalid."); } else if (!FundamentalsTimeSeries_Modules.includes(queryOptions.module || "")) { throw new Error("yahooFinance.fundamentalsTimeSeries() option module invalid."); } // Join the keys for the module into query types. const keys = Object.entries(timeseries_json_1.default).reduce((previous, [module, keys]) => { if (queryOptions.module == "all") { return previous.concat(keys); } else if (module == queryOptions.module) { return previous.concat(keys); } else return previous; }, []); const queryType = queryOptions.type + keys.join(`,${queryOptions.type}`); return { period1: queryOptions.period1, period2: queryOptions.period2, type: queryType, }; }; exports.processQuery = processQuery; /** * Transforms the time-series into an array with reported values per period. * Each object represents a period and its properties are the data points. * Financial statement content variates and keys are skipped when empty. * The query keys include the option type (e.g. annualTotalRevenue). * In the response the type is removed (e.g. totalRevenue) for * easier mapping by the client. * @param response Query response. * @returns Formatted response. */ const processResponse = function (response) { const keyedByTimestamp = {}; const replace = new RegExp(FundamentalsTimeSeries_Types.join("|")); for (let ct = 0; ct < response.timeseries.result.length; ct++) { const result = response.timeseries.result[ct]; if (!result.timestamp || !result.timestamp.length) { continue; } for (let ct = 0; ct < result.timestamp.length; ct++) { const timestamp = result.timestamp[ct]; const dataKey = Object.keys(result)[2]; if (!keyedByTimestamp[timestamp]) { keyedByTimestamp[timestamp] = { date: timestamp }; } if (!result[dataKey][ct] || !result[dataKey][ct].reportedValue || !result[dataKey][ct].reportedValue.raw) { continue; } const short = dataKey.replace(replace, ""); const key = short == short.toUpperCase() ? short : short[0].toLowerCase() + short.slice(1); keyedByTimestamp[timestamp][key] = result[dataKey][ct].reportedValue.raw; } } return Object.keys(keyedByTimestamp).map((k) => keyedByTimestamp[k]); }; exports.processResponse = processResponse;

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/Jeetinida/stocknews-mcp'

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