npm.io
0.2.0 • Published yesterdayCLI

yahoo-stock-mcp

Licence
MIT
Version
0.2.0
Deps
5
Size
8.5 MB
Vulns
0
Weekly
0

yahoo-stock-mcp

npm version

English | 中文

An MCP server (TypeScript / Node.js) that pulls comprehensive market data for stocks via Yahoo Finance and Investing.com (GraphQL + TVC), persists it to an external MySQL (configured via a YAHOO_STOCK_MCP_DATABASE_URL connection string, not bundled with the server), and queries it by ticker.

Architecturally the MCP server stays lightweight: it is only a thin query layer plus a sync trigger, while the database is a fully external dependency.

Install

npm install -g yahoo-stock-mcp

Requires Node.js >= 20 and an external MySQL (see the .env config below).

Quick start (npm global install)

The package already ships the compiled dist/ and the Go sidecar bin/gqlproxy, so no build step is needed — just use the yahoo-stock-mcp command:


# 0. Configure the external MySQL connection (.env)
#    YAHOO_STOCK_MCP_DATABASE_URL=mysql://user:pass@host:3306/yahoo_stock_mcp
#    For a local dev database you can spin one up with deploy/docker-compose.mysql.yml:
#    docker compose -f deploy/docker-compose.mysql.yml up -d

# 1. Initialise the schema in the configured database
yahoo-stock-mcp db:init

# 2. Full sync of one stock (pull history from 2000-01-01 + all fundamentals)
yahoo-stock-mcp sync --symbol NVDA --full

# Incremental sync afterwards (only new data)
yahoo-stock-mcp sync --symbol NVDA

# Incremental sync and also pull 15m bars (1m/5m/15m/30m/60m)
yahoo-stock-mcp sync --symbol NVDA --intraday 15m

# Sync every stored symbol
yahoo-stock-mcp sync --all --full

# Sync all GICS sector ETFs + constituents (sector rotation data)
yahoo-stock-mcp sync --sectors

# 3. Start the MCP server (stdio)
yahoo-stock-mcp server

Run from source (development / contribution)

npm install
npm run build:all   # TypeScript + Go sidecar
npm run server      # stdio; use npm run sync -- ... or npm run dev for other commands

Tests

# Requires a local MySQL (default 127.0.0.1:3306, see deploy/docker-compose.mysql.yml) with the schema initialised
npm run test:db    # query layer: covers all query functions, LIMIT binding regression, edge params
npm run test:mcp   # protocol layer: initialize/tools/list/tools/call end-to-end + stdin close exit
npm test           # both

Tests use a dedicated ZZTEST symbol and clean up automatically, so they never touch real data.

MCP tools

Tool Description
sync_stock Full/incremental sync of one stock to MySQL
search_symbol Search stored instruments by symbol/name
get_quote Latest quote + key metrics
get_bars Historical candles (1d/1wk/1mo)
get_profile Company profile
get_financials The three financial statements
get_ratios Valuation / financial ratios
get_dividends Dividend history & summary
get_analyst_forecast Analyst consensus & price target
get_earnings Earnings history & estimates
get_holders Institutional holders
get_news News
get_options Option chain snapshot (queried after being synced to DB)
get_option_quote Live option quotes straight from Yahoo (on demand, no local DB needed): underlying quote + optional expiry/strike/direction filters
get_company_events Forward-looking event calendar: next earnings / call / ex-dividend / dividend dates (Yahoo calendarEvents + Investing next_release_date)
get_insider_transactions Insider trading: executive/director buys & sells, shares, amounts (Yahoo insiderTransactions)
get_analyst_actions Analyst upgrades/downgrades & target-price changes (Yahoo upgradeDowngradeHistory)
get_earnings_trend Quarterly earnings estimate trend: EPS/revenue estimates, growth, 7/30/60/90-day revisions (Yahoo earningsTrend)
get_recommendation_trend Analyst rating trend (monthly strong buy/buy/hold/sell/strong sell)
get_fund_holders Mutual fund ownership (Yahoo fundOwnership)
get_short_interest Short-interest snapshot: shares short, short ratio, % of float (Yahoo defaultKeyStatistics)
get_holder_breakdown Ownership breakdown: insider/institutional %, institutional float, institutional count (Yahoo majorHoldersBreakdown)
get_intraday_bars Minute-level bars (1m/5m/15m/30m/60m, queried after being synced to DB)
list_sectors Sector catalog: the 11 GICS sectors + SPY benchmark, mapped to SPDR sector ETFs
get_sector_performance Sector rotation view: each sector's latest price + 1d/5d/20d change ranking vs SPY benchmark
get_sector_members Sector constituents (sector ETF topHoldings, incl. weights)
sync_sectors Sync all sector ETF quotes (~30 days of bars) and constituents

Data sources

  • Yahoo Finance: bars (v8 chart), quoteSummary (needs cookie+crumb), options (v7), news (v1 search), fundamentals (fundamentals-timeseries, no auth)
  • Investing.com: GraphQL gql.api.investing.com/graphql (quotes/statements/ratios/dividends/estimates/earnings/profile/executives/holders, no auth), TVC bars (carrier token)

Data checklist

For the "watch the market, position early" use case, the following dimensions are added on top of the per-stock fundamentals, all fetched from existing Yahoo quoteSummary / Investing GraphQL endpoints:

Dimension Table Source
Forward-looking event calendar company_events Yahoo calendarEvents + Investing next_release_date (next earnings/dividend)
Insider transactions insider_transactions Yahoo insiderTransactions
Analyst actions analyst_actions Yahoo upgradeDowngradeHistory (upgrades/downgrades/target changes)
Earnings estimate trend earnings_trend Yahoo earningsTrend (quarterly EPS/revenue estimate + 7/30/60/90-day revisions)
Recommendation trend recommendation_trend Yahoo recommendationTrend (monthly rating distribution)
Fund holders fund_holders Yahoo fundOwnership
Short interest short_interest Yahoo defaultKeyStatistics (sharesShort/shortRatio/% of float)
Holder breakdown holder_breakdown Yahoo majorHoldersBreakdown (insider/institutional %)
Minute bars intraday_bars Yahoo chart v8 (1m/5m/15m/30m/60m)
Sector catalog & rotation sectors / sector_members GICS 11 sectors + SPY benchmark, sector ETF (XLC..XLU/SPY) quotes + topHoldings constituent weights

Indices / ETFs / cross-assets (e.g. ^GSPC, ^VIX, SPY, TLT) can be synced directly as symbols: Yahoo natively serves index quotes, and any Investing side failures are skipped automatically, so Yahoo data still lands in the DB.

Client integration (Claude Desktop / Cursor / Codex)

{
  "mcpServers": {
    "yahoo-stock-mcp": {
      "command": "yahoo-stock-mcp",
      "args": ["server"],
      "env": {
        "YAHOO_STOCK_MCP_DATABASE_URL": "mysql://user:pass@host:3306/yahoo_stock_mcp",
        "YAHOO_STOCK_MCP_PROXY_URL": "http://127.0.0.1:17890"
      }
    }
  }
}

command relies on yahoo-stock-mcp being on PATH (satisfied after a global npm install); if not globally installed, use the source path instead: node /path/to/yahoo-stock-mcp/dist/cli.js server. All config vars use the YAHOO_STOCK_MCP_ prefix so they never collide with other apps' DATABASE_URL / PROXY_URL / USER_AGENT.

Notes

  • Full sync: pulls all daily bars from YAHOO_STOCK_MCP_BARS_START_DATE (default 2000-01-01) + all fundamentals + an options snapshot + news + the data checklist (events/insiders/analysts/earnings trend/short interest/funds, etc.).
  • Incremental sync: only pulls new bars since sync_state.last_bar_date, and refreshes quotes, ratios, estimates, news, the options snapshot and the data checklist.
  • Minute bars: --intraday <1m|5m|15m|30m|60m> pulls the last 7 days of minute bars into intraday_bars (idempotent upsert).
  • Sectors: sync --sectors syncs the 11 GICS sector ETFs (XLC..XLU) + SPY benchmark quotes and topHoldings constituents in one go; get_sector_performance returns the rotation ranking.
  • Options: get_options reads the snapshot synced to the DB; get_option_quote fetches the latest quotes directly from Yahoo on demand (incl. underlying price, optional expiry, strike, and direction filters) — no prior sync required.
  • All writes are idempotent upserts (INSERT ... ON DUPLICATE KEY UPDATE) and can be re-run safely.
  • Rate limiting is built in (default 300ms/request); Yahoo crumb cache 25 min, TVC token cache 25 min.

About investing.com's TLS interception

investing.com blocks Node.js requests via Cloudflare TLS fingerprinting (HTTP 403), while a Go client can access it normally. That's why the project bundles a tiny Go transport proxy cmd/gqlproxy (~200 lines, stdlib only):

npm run build:sidecar   # produces bin/gqlproxy

The TS data-source layer tries Node fetch first, and automatically switches to that proxy on a 403 (with a persistent cookie session that handles the Cloudflare challenge). From networks that aren't fingerprint-blocked the proxy is unnecessary; set YAHOO_STOCK_MCP_INVESTING_TRANSPORT=node to force pure Node.

# Full build (TypeScript + Go sidecar)
npm run build:all

Environment variables

Var Default Description
YAHOO_STOCK_MCP_DATABASE_URL derived from DB_* Full MySQL connection string, e.g. mysql://user:pass@host:3306/yahoo_stock_mcp; takes precedence over DB_*
YAHOO_STOCK_MCP_DB_HOST/DB_PORT/DB_USER/DB_PASSWORD/DB_NAME 127.0.0.1/3306/stock/stock123/yahoo_stock_mcp MySQL connection (used when DATABASE_URL is not set)
YAHOO_STOCK_MCP_USER_AGENT Chrome 148 UA Request fingerprint
YAHOO_STOCK_MCP_REQUEST_DELAY_MS 300 Per-request rate limit
YAHOO_STOCK_MCP_PROXY_URL none HTTP(S) proxy for all Node fetch requests, e.g. http://127.0.0.1:17890; Yahoo needs it from mainland China
YAHOO_STOCK_MCP_BARS_START_DATE 2000-01-01 Full-sync start date
YAHOO_STOCK_MCP_BARS_PROVIDER yahoo Bar source (yahoo/investing)
YAHOO_STOCK_MCP_NEWS_COUNT 20 News count per fetch
YAHOO_STOCK_MCP_INVESTING_TRANSPORT auto node / go / auto
YAHOO_STOCK_MCP_GQLPROXY_COOKIE_FILE .cache/gqlproxy_cookies.txt sidecar cookie session file

Keywords