Finviz MCP
This server does not currently have a deployable release on Glama. Follow the repository's setup instructions to install and configure it for your MCP client, including any required credentials and local dependencies.
Finviz MCP — Market Data, Screeners & Fundamentals for AI Assistants
Finviz MCP server gives Claude, ChatGPT, Cursor, Copilot and any MCP client a single, structured way to read everything finviz.com publishes, without a browser, an API key, or a Finviz account.
Every tool is read-only, every failure is a typed error envelope, and every payload carries its own source URL so an answer can be traced back to the page it came from.
Independent open-source project —not affiliated with, endorsed by, or associated with Finviz. "Finviz" is a trademark of its respective owner. This server reads publicly reachable, server-rendered pages and the site's own unauthenticated JSON routes; it does not log in, does not use a Finviz account, and does not bypass the Elite paywall (Elite-gated responses are reported as ELITE_ONLY, never faked).
Not financial advice. Nothing produced by this software is investment, financial, legal, tax, or accounting advice. Market data may be delayed, inaccurate, or incomplete and is provided without warranty. Do your own research.
Why this server
Most "Finviz scrapers" stop at the quote header. This one covers the whole page — and, crucially, documents which upstream route each field comes from, because finviz has no official API:
Question | Tool | Upstream source |
What is VCIG trading at, and what do its 84 fundamentals say? |
|
|
Just the fundamentals, small payload |
| same page, |
Who are its peers? |
| same page, Peers row |
Screen the market |
|
|
Which filters exist? |
|
|
What moved it today? |
|
|
What did it file? |
|
|
Who bought or sold? |
|
|
How crowded is the short? |
|
|
Earnings history and revisions |
|
|
Can it fund itself? |
|
|
Options chain with greeks |
|
|
A chart image |
|
|
What is the market doing? |
|
|
Related MCP server: xoomar-mcp
Architecture
src/finviz_mcp/
├── server.py # MCP routing layer — validation, delegation, error envelope
└── core/
├── errors.py # ErrorCode enum, make_error(), FinvizServiceError
├── utils/validators.py # ticker / filter / order / view / period / scale allow-lists
└── services/
├── finviz_client.py # httpx transport, TTL cache + stale fallback, retry, CF/Elite detection
├── proxy_manager.py # optional rotating residential proxy (env only)
├── html_utils.py # every HTML → dict parser (pure, synchronous)
├── quote_service.py # quote / snapshot / peers / short interest / earnings / dilution
├── screener_service.py# SSR island parsing + filter catalogue
├── news_service.py # /api/news/quote rows + reactions
├── filings_service.py # /api/quote/filings paging + form filter
├── insider_service.py # insider table + institutional ownership islands
├── market_service.py # indices, why-moving, options chain
└── chart_service.py # charts2-node URL builder + PNG downloadNo business logic lives in server.py. Everything is testable without an MCP client, and the parsers are tested against real captured markup, not hand-written HTML.
Quick start
Run from source with uv (recommended)
git clone https://github.com/giraygokirmak/finviz-mcp.git
cd finviz-mcp
uv sync --dev
uv run finviz-mcp # stdio (what MCP clients launch)Install as a package
pip install finviz-mcp-server
finviz-mcp # stdioClaude Desktop
claude_desktop_config.json:
{
"mcpServers": {
"finviz": {
"command": "uv",
"args": ["--directory", "/absolute/path/to/finviz-mcp", "run", "finviz-mcp"]
}
}
}Or, if you installed the package, just:
{
"mcpServers": {
"finviz": { "command": "finviz-mcp" }
}
}Docker / Docker Compose
docker compose up -d --buildThe container listens on port 8000 internally, published as 6007 (change the left-hand side of the port mapping if that collides on your host):
ports:
- "6007:8000"Point any streamable-http MCP client at http://localhost:6007/mcp. A liveness probe is served at http://localhost:6007/health (used by the image's HEALTHCHECK).
Chart PNGs are written to FINVIZ_CHART_DIR (/home/mcpuser/.finviz-mcp/charts in the image) and persisted by the finviz-charts named volume, so finviz_chart keeps returning real file paths across restarts.
Run it directly without Compose:
docker build -t finviz-mcp:latest .
docker run --rm -p 6007:8000 -v finviz-charts:/home/mcpuser/.finviz-mcp/charts finviz-mcp:latestStreamable HTTP from source
uv run finviz-mcp streamable-http --host 0.0.0.0 --port 6007
# MCP: http://localhost:6007/mcp
# health: http://localhost:6007/healthThe 17 tools
Quote & fundamentals
Tool | What it returns |
| Last close and after-hours price with change, sector/industry/country/cap class/exchange, the full 84-metric snapshot ( |
| The 84 metrics only — raw strings + coerced numbers + finviz's own metric descriptions |
| The page's real peer row: ticker, company, industry, country, market cap |
Screening
Tool | What it returns |
| One page of results (20 rows upstream), |
| Every filter key with its tab, UI type, title and option values (cached 1h) |
News & events
Tool | What it returns |
| Up to 100 newest-first headlines with source, URL, day-of-headline move and next-session move |
| SEC filings with accession numbers, report/filing dates and direct SEC links |
| Next earnings date, last 12 quarters (actual vs estimate), annual history, estimate revisions, price reactions, fundamental series |
| Finviz's own explainer: headline, markdown bullet summary, sentiment, catalyst flag |
Ownership & risk
Tool | What it returns |
| Form-4 rows (insider, relationship, date, buy/sale, cost, shares, value, resulting holdings, SEC link) + 12-month aggregated buy/sell series |
| Managers and funds with |
| Bi-weekly FINRA settlement series + latest reading + computed short-float % |
| Dilution model (share count, float, 60-day high, baby-shelf threshold, cash runway, months of cash) — with an income-statement fallback for names finviz does not flag |
| Chain for one expiry: strike, bid/ask, IV, greeks, open interest, volume |
Charts, market & ops
Tool | What it returns |
| Downloads a PNG to |
| DJI / COMP / SPX / IWM: last, change, OHLC and the intraday series |
| Version, cache occupancy, upstream reachability |
Try these first
Give me the full Finviz picture on VCIG
Screen technology stocks above $2B, cheapest P/E first
What are the last 10 SEC filings for AAPL, 8-Ks only?
Which insiders bought SNDL this year?
Chart NVDA weekly, 1200x600, with SMAsUpstream data sources (what the server actually calls)
Finviz publishes no documented API. Everything below was reverse-engineered from the rendered pages and the site's own React islands, and is what this server consumes:
JSON routes (undocumented, unversioned, unauthenticated)
GET /api/quote/filings?t={t}&page={n}&pageSize={n}&o={sort}&f={forms}
GET /api/news/quote/{t} → {"html": "<news rows>", "timestamp": "..."}
GET /api/stocks-why-moving/{t} → headline, summary, sentiment, catalyst
GET /api/indices_data → DJI, COMP, SPX, IWM intraday OHLCV
GET /api/screener-filters?type=stocks → 83 filters with optionsDocument routes (server-rendered HTML; the interesting data lives in <script id="…-init-data"> islands)
GET /stock?t={t}&ta=1&p=d → header, 84-field snapshot, profile, peers,
insider table, insider-init-data-0,
institutional-ownership-init-data-0
GET /stock?t={t}&ty=si&ta=1&p=d → route-init-data: short-interest series
GET /stock?t={t}&ty=ea&ta=1&p=d → route-init-data: earnings + revisions
fa-init-data-0: EPS/sales series
GET /stock?t={t}&ty=oc&ta=1&p=d[&e=YYYY-MM-DD] → route-init-data: options chain
GET /stock?t={t}&ty=lf&ta=1&p=d → route-init-data: same shape as /api/quote/filings
GET /stock?t={t}&ty=di&ta=1&p=d → route-init-data: dilution model (schema_version 1)
GET /screener/stocks?v={view}&f={filters}&o={order}&r={offset}&c={columns}
→ <script data-ssr-props="ssr-island-1"> JSONBinary
GET https://charts2-node.finviz.com/chart?w=&h=&bw=2&bm=1&bb=1&t={t}&tf=d|w|m
&s=linear|logarithmic&pm=0&am=0&ct=candle_stick|line_chart|heikin_ashi
&o[0][ot]=sma&o[0][op]=20&o[0][oc]=DC32B363 …Notes that shaped the implementation:
/api/quotedoes not work. Every parameter spelling returns HTTP 400{"error":"invalid quote query"}, so the quote is necessarily HTML-scraped./api/related-tickersis a trap. It ignores its ticker argument and always returns the same mega-cap list, so peers come from the page's Peers row instead./api/suggestionsignores its query and returns a fixed list — not used.The screener island is the whole result page:
data.rows[].text|numbers,totalCount,firstRow,pageSize. Pagination is the 0-basedr=offset; upstream caps at 20 rows per page regardless ofpageSize.c=is a count-like column selector:c=0,1,…,Nprogressively adds numeric fields up to 67 in finviz's fixed order.Chart params:
s=logand unknownct=values return HTTP 400Invalid request— validated client-side instead of forwarded blindly.A real Chrome User-Agent is required; a bare
python-httpx/xUA gets a Cloudflare interstitial. No browser is needed (verified with plainurllib).
The full field-level reference — page anatomy, the 84 snapshot labels in page order, every island's shape, the screener row schema, decoded chart parameters and the dead routes — is in docs/FINVIZ_API_MAP.md.
Elite-gated (reported as ELITE_ONLY, never faked): /api/compare-perf/*, /api/ticker-flags*, /api/watchlists*, /export/quote, and full 13F ownership history.
Error envelope
Every tool returns its normal payload on success and this shape on failure — never a raw exception string:
{
"error": {
"code": "NO_DATA",
"message": "finviz.com lists no option contracts for VCIG",
"ticker": "VCIG",
"retryable": false
}
}Codes: SYMBOL_NOT_FOUND, INVALID_TICKER, INVALID_PARAMETER, UPSTREAM_RATE_LIMIT, UPSTREAM_TIMEOUT, UPSTREAM_BLOCKED, UPSTREAM_ERROR, ELITE_ONLY, NO_DATA, PARTIAL_DATA, PARSE_ERROR, DEPENDENCY_MISSING, INTERNAL_ERROR.
retryable tells the client whether repeating the identical call could plausibly work (rate limit, timeout, Cloudflare challenge) or not (bad ticker, unsupported parameter, no such tab). Branch on code; show message to the user.
Configuration
All settings are optional environment variables (see .env.example):
Variable | Default | Purpose |
|
| Streamable-http bind (CLI flags win) |
|
| Upstream request timeout, seconds |
|
| Page/JSON cache lifetime, seconds |
|
| Headline cache lifetime, seconds |
|
| Retries for 429 / 5xx / timeouts (4xx never retried) |
|
| Where |
| bundled Chrome UA | Override only if finviz starts challenging it |
| off | Optional rotating residential proxy for rate-limited egress |
The 30-second cache is a correctness feature, not just an optimisation: one finviz_quote fans out over a ~240 KB page, and quote + snapshot + peers would otherwise re-download it three times. Stale entries are served when upstream fails, so a rate-limited client still gets numbers.
Development
uv sync --dev
uv run pytest tests/unit -q # 87 tests, hermetic (no network)CI never depends on finviz.com being reachable. To exercise the real site end to end (every service, both a small cap and a large cap):
uv run python tools/smoke_live.py VCIG
uv run python tools/smoke_live.py AAPLFixtures under tests/fixtures/ are excerpts of real finviz markup captured during development, regenerated with tools/make_fixtures.py; the parsers are therefore exercised against actual tag soup rather than an idealised version of it.
CI: test.yml runs the hermetic suite on Python 3.10–3.13; publish-image.yml re-runs it and then publishes a multi-arch (amd64 + arm64) image to GHCR on main and on v* tags.
Limitations
Scraping is inherently fragile. A finviz redesign breaks the parsers in
html_utils.py— one file, by design.PARSE_ERRORmeans "markup changed", not "retry".Rate limiting is real. The cache and the retry/backoff layer are polite by default; do not point a loop at thousands of tickers without pacing.
Elite features are not available. Ownership history beyond the two islands, exports and watchlists need a Finviz subscription; this server says so instead of guessing.
Foreign private issuers (6-K filers) often have no quarterly earnings rows, no insider table and no short-interest series. That returns
NO_DATAwith an explanation rather than an empty success.No candle-level JSON. Finviz renders charts as PNGs only, so
finviz_chartreturns an image path, not a series.
License
MIT — see LICENSE.
This server cannot be deployed
Maintenance
Related MCP Connectors
Real SEC, 13F, insider, congress & macro data your AI agent can cite. Hosted MCP, 24 tools.
Stock research for AI assistants: scan US stocks, ETFs and futures, cite SEC filings, save queries.
US stock market data for AI agents: SEC filings, financials, insider trades, 13F, options, macro.
SEC-filed company financials with filing citations, plus market data, for AI agents
Related MCP Servers
AlicenseAqualityCmaintenanceEnables AI assistants to access stock prices, financial statements, earnings call transcripts, and fundamental data for 60,000+ public companies via 25 read-only tools.2521 npm4MIT- AlicenseAqualityCmaintenanceEnables AI agents to query free public market data through 21 tools spanning 29 datasets sourced from SEC EDGAR/XBRL, FINRA, CFTC, the Federal Reserve, USAspending and exchange APIs. Covers short interest, insider and fund holdings, company financials, macro and policy rates, funding rates, crypto market metrics, IPOs and federal contracts, with no API key required to start.22104 npmApache 2.0
- AlicenseAqualityAmaintenanceEnables AI agents to access 37 read-only market-research tools for querying quotes, news, SEC filings, financial statements, ownership and insider activity, earnings, corporate calendars, options, and crypto data.4922 PyPI20AGPL 3.0
- AlicenseNot gradedqualityAmaintenanceEnables AI assistants to access and analyze financial data, stock information, company fundamentals, and market insights through 250+ tools spanning stocks, ETFs, crypto, forex, commodities, economics, and more.332 npmApache 2.0