Skip to main content
Glama

Weather & Stock MCP Server

by Jeetinida
quote.js12.6 kB
import { Type } from "@sinclair/typebox"; import { YahooDateInMs, YahooFinanceDate, YahooNumber, YahooTwoNumberRange, } from "../lib/yahooFinanceTypes.js"; export const QuoteBase = Type.Object({ language: Type.String(), // "en-US", region: Type.String(), // "US", quoteType: Type.String(), // "EQUITY" | "ETF" | "MUTUALFUND"; typeDisp: Type.Optional(Type.String()), // "Equity", not always present. quoteSourceName: Type.Optional(Type.String()), // "Delayed Quote", triggerable: Type.Boolean(), // true, currency: Type.Optional(Type.String()), // "USD", // Seems to appear / disappear based not on symbol but network load (#445) customPriceAlertConfidence: Type.Optional(Type.String()), // "HIGH" | "LOW"; TODO: anything else? marketState: Type.Union([ Type.Literal("REGULAR"), Type.Literal("CLOSED"), Type.Literal("PRE"), Type.Literal("PREPRE"), Type.Literal("POST"), Type.Literal("POSTPOST"), ]), tradeable: Type.Boolean(), // false, cryptoTradeable: Type.Optional(Type.Boolean()), // false exchange: Type.String(), // "NMS", shortName: Type.Optional(Type.String()), // "NVIDIA Corporation", longName: Type.Optional(Type.String()), // "NVIDIA Corporation", messageBoardId: Type.Optional(Type.String()), // "finmb_32307", exchangeTimezoneName: Type.String(), // "America/New_York", exchangeTimezoneShortName: Type.String(), // "EST", gmtOffSetMilliseconds: YahooNumber, // -18000000, market: Type.String(), // "us_market", esgPopulated: Type.Boolean(), // false, fiftyTwoWeekLowChange: Type.Optional(YahooNumber), // 362.96002, fiftyTwoWeekLowChangePercent: Type.Optional(YahooNumber), // 2.0088556, fiftyTwoWeekRange: Type.Optional(YahooTwoNumberRange), // "180.68 - 589.07" -> { low, high } fiftyTwoWeekHighChange: Type.Optional(YahooNumber), // -45.429993, fiftyTwoWeekHighChangePercent: Type.Optional(YahooNumber), // -0.07712155, fiftyTwoWeekLow: Type.Optional(YahooNumber), // 180.68, fiftyTwoWeekHigh: Type.Optional(YahooNumber), // 589.07, fiftyTwoWeekChangePercent: Type.Optional(YahooNumber), // 22.604025 dividendDate: Type.Optional(YahooFinanceDate), // 1609200000, // maybe always present on EQUITY? earningsTimestamp: Type.Optional(YahooFinanceDate), // 1614200400, earningsTimestampStart: Type.Optional(YahooFinanceDate), // 1614200400, earningsTimestampEnd: Type.Optional(YahooFinanceDate), // 1614200400, trailingAnnualDividendRate: Type.Optional(YahooNumber), // 0.64, trailingPE: Type.Optional(YahooNumber), // 88.873634, trailingAnnualDividendYield: Type.Optional(YahooNumber), // 0.0011709387, epsTrailingTwelveMonths: Type.Optional(YahooNumber), // 6.117, epsForward: Type.Optional(YahooNumber), // 11.68, epsCurrentYear: Type.Optional(YahooNumber), // 9.72, priceEpsCurrentYear: Type.Optional(YahooNumber), // 55.930042, sharesOutstanding: Type.Optional(YahooNumber), // 619000000, bookValue: Type.Optional(YahooNumber), // 24.772, fiftyDayAverage: Type.Optional(YahooNumber), // 530.8828, fiftyDayAverageChange: Type.Optional(YahooNumber), // 12.757202, fiftyDayAverageChangePercent: Type.Optional(YahooNumber), // 0.024030166, twoHundredDayAverage: Type.Optional(YahooNumber), // 515.8518, twoHundredDayAverageChange: Type.Optional(YahooNumber), // 27.788208, twoHundredDayAverageChangePercent: Type.Optional(YahooNumber), // 0.053868588, marketCap: Type.Optional(YahooNumber), // 336513171456, forwardPE: Type.Optional(YahooNumber), // 46.54452, priceToBook: Type.Optional(YahooNumber), // 21.945745, sourceInterval: YahooNumber, // 15, exchangeDataDelayedBy: YahooNumber, // 0, firstTradeDateMilliseconds: Type.Optional(YahooDateInMs), // 917015400000 -> Date priceHint: YahooNumber, // 2, postMarketChangePercent: Type.Optional(YahooNumber), // 0.093813874, postMarketTime: Type.Optional(YahooFinanceDate), // 1612573179 -> new Date() postMarketPrice: Type.Optional(YahooNumber), // 544.15, postMarketChange: Type.Optional(YahooNumber), // 0.51000977, regularMarketChange: Type.Optional(YahooNumber), // -2.9299927, regularMarketChangePercent: Type.Optional(YahooNumber), // -0.53606904, regularMarketTime: Type.Optional(YahooFinanceDate), // 1612558802 -> new Date() regularMarketPrice: Type.Optional(YahooNumber), // 543.64, regularMarketDayHigh: Type.Optional(YahooNumber), // 549.19, regularMarketDayRange: Type.Optional(YahooTwoNumberRange), // "541.867 - 549.19" -> { low, high } regularMarketDayLow: Type.Optional(YahooNumber), // 541.867, regularMarketVolume: Type.Optional(YahooNumber), // 4228841, regularMarketPreviousClose: Type.Optional(YahooNumber), // 546.57, preMarketChange: Type.Optional(YahooNumber), // -2.9299927, preMarketChangePercent: Type.Optional(YahooNumber), // -0.53606904, preMarketTime: Type.Optional(YahooFinanceDate), // 1612558802 -> new Date() preMarketPrice: Type.Optional(YahooNumber), // 543.64, bid: Type.Optional(YahooNumber), // 543.84, ask: Type.Optional(YahooNumber), // 544.15, bidSize: Type.Optional(YahooNumber), // 18, askSize: Type.Optional(YahooNumber), // 8, fullExchangeName: Type.String(), // "NasdaqGS", financialCurrency: Type.Optional(Type.String()), // "USD", regularMarketOpen: Type.Optional(YahooNumber), // 549.0, averageDailyVolume3Month: Type.Optional(YahooNumber), // 7475022, averageDailyVolume10Day: Type.Optional(YahooNumber), // 5546385, displayName: Type.Optional(Type.String()), // "NVIDIA", symbol: Type.String(), // "NVDA" underlyingSymbol: Type.Optional(Type.String()), // "LD.MI" (for LDO.MI, #363) // only on ETF? not on EQUITY? ytdReturn: Type.Optional(YahooNumber), // 0.31 trailingThreeMonthReturns: Type.Optional(YahooNumber), // 16.98 trailingThreeMonthNavReturns: Type.Optional(YahooNumber), // 17.08 ipoExpectedDate: Type.Optional(YahooFinanceDate), // "2020-08-13", newListingDate: Type.Optional(YahooFinanceDate), // "2021-02-16", nameChangeDate: Type.Optional(YahooFinanceDate), prevName: Type.Optional(Type.String()), averageAnalystRating: Type.Optional(Type.String()), pageViewGrowthWeekly: Type.Optional(YahooNumber), // Since 2021-11-11 (#326) openInterest: Type.Optional(YahooNumber), // SOHO (#248) beta: Type.Optional(YahooNumber), }, { additionalProperties: Type.Any(), }); /* * [TODO] Fields seen in a query but not in this module yet: * * - extendedMarketChange * - extendedMarketChangePercent * - extendedMarketPrice * - extendedMarketTime * - dayHigh (separate to regularMarketDayHigh, etc) * - dayLow (separate to regularMarketDayLow, etc) * - volume (separaet to regularMarketVolume, etc) * * i.e. on yahoo site, with ?fields=dayHigh,dayLow,etc. */ /* * Guaranteed fields, even we don't ask for them */ const QuoteCryptoCurrency = Type.Composite([ QuoteBase, Type.Object({ quoteType: Type.Literal("CRYPTOCURRENCY"), circulatingSupply: YahooNumber, fromCurrency: Type.String(), // 'BTC' toCurrency: Type.String(), // 'USD=X' lastMarket: Type.String(), // 'CoinMarketCap' coinImageUrl: Type.Optional(Type.String()), // 'https://s.yimg.com/uc/fin/img/reports-thumbnails/1.png' volume24Hr: Type.Optional(YahooNumber), // 62631043072 volumeAllCurrencies: Type.Optional(YahooNumber), // 62631043072 startDate: Type.Optional(YahooFinanceDate), // new Date(1367103600 * 1000) }), ]); const QuoteCurrency = Type.Composite([ QuoteBase, Type.Object({ quoteType: Type.Literal("CURRENCY"), }), ]); const QuoteEtf = Type.Composite([ QuoteBase, Type.Object({ quoteType: Type.Literal("ETF"), }), ]); const QuoteEquity = Type.Composite([ QuoteBase, Type.Object({ quoteType: Type.Literal("EQUITY"), dividendRate: Type.Optional(Type.Number()), dividendYield: Type.Optional(Type.Number()), }), ]); const QuoteFuture = Type.Composite([ QuoteBase, Type.Object({ quoteType: Type.Literal("FUTURE"), headSymbolAsString: Type.String(), contractSymbol: Type.Boolean(), underlyingExchangeSymbol: Type.String(), expireDate: YahooFinanceDate, expireIsoDate: YahooFinanceDate, }), ]); const QuoteIndex = Type.Composite([ QuoteBase, Type.Object({ quoteType: Type.Literal("INDEX"), }), ]); const QuoteOption = Type.Composite([ QuoteBase, Type.Object({ quoteType: Type.Literal("OPTION"), strike: YahooNumber, openInterest: YahooNumber, expireDate: YahooNumber, expireIsoDate: YahooNumber, underlyingSymbol: Type.String(), }), ]); const QuoteMutualfund = Type.Composite([ QuoteBase, Type.Object({ quoteType: Type.Literal("MUTUALFUND"), }), ]); const QuoteSchema = Type.Union([ QuoteCryptoCurrency, QuoteCurrency, QuoteEtf, QuoteEquity, QuoteFuture, QuoteIndex, QuoteMutualfund, QuoteOption, ]); const QuoteFieldSchema = Type.KeyOf(QuoteSchema); const ResultType = Type.Union([ Type.Literal("array"), Type.Literal("object"), Type.Literal("map"), ]); const QuoteResponseArraySchema = Type.Array(QuoteSchema); export const QuoteOptionsSchema = Type.Object({ fields: Type.Optional(Type.Array(QuoteFieldSchema)), return: Type.Optional(ResultType), }); const QuoteOptionsWithReturnArraySchema = Type.Composite([ QuoteOptionsSchema, Type.Object({ return: Type.Optional(Type.Literal("array")), }), ]); const QuoteOptionsWithReturnMapSchema = Type.Composite([ QuoteOptionsSchema, Type.Object({ return: Type.Literal("map"), }), ]); const QuoteOptionsWithReturnObjectSchema = Type.Composite([ QuoteOptionsSchema, Type.Object({ return: Type.Literal("object"), }), ]); const queryOptionsDefaults = {}; export default async function quote(query, queryOptionsOverrides, moduleOptions) { const symbols = typeof query === "string" ? query : query.join(","); const returnAs = queryOptionsOverrides && queryOptionsOverrides.return; const results = await this._moduleExec({ moduleName: "quote", query: { url: "https://${YF_QUERY_HOST}/v7/finance/quote", needsCrumb: true, schema: QuoteOptionsSchema, defaults: queryOptionsDefaults, runtime: { symbols }, overrides: queryOptionsOverrides, transformWith(queryOptions) { // Options validation ensures this is a string[] if (queryOptions.fields) queryOptions.fields.join(","); // Don't pass this on to Yahoo delete queryOptions.return; return queryOptions; }, }, result: { schema: QuoteResponseArraySchema, transformWith(rawResult) { var _a; // console.log({ rawResult: JSON.stringify(rawResult, null, 2) }); let results = (_a = rawResult === null || rawResult === void 0 ? void 0 : rawResult.quoteResponse) === null || _a === void 0 ? void 0 : _a.result; if (!results || !Array.isArray(results)) throw new Error("Unexpected result: " + JSON.stringify(rawResult)); // Filter out quoteType==='NONE' // So that delisted stocks will be undefined just like symbol-not-found results = results.filter((quote) => (quote === null || quote === void 0 ? void 0 : quote.quoteType) !== "NONE"); return results; }, }, moduleOptions, }); if (returnAs) { switch (returnAs) { case "array": return results; case "object": { const object = {}; for (const result of results) object[result.symbol] = result; return object; // TODO: type } case "map": { const map = new Map(); for (const result of results) map.set(result.symbol, result); return map; // TODO: type } } } else { // By default, match the query input shape (string or string[]). return typeof query === "string" ? results[0] : results; } }

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