Skip to main content

screener-ai-tool

An async Python toolkit for fetching and analyzing Indian (NSE/BSE) stock data from screener.in — fundamentals, price history, technical indicators, peer comparisons, shareholding patterns, and corporate documents/announcements. Ships as a CLI (screener), a library (screener_ai), and an MCP server for use with Claude and other LLM clients.

Disclaimer: This is a personal-use tool for analyzing publicly visible data on screener.in. It is not affiliated with or endorsed by screener.in. Be polite: respect screener.in's Terms of Service, keep request rates low (defaults are conservative), prefer an authenticated session for heavier usage, and do not use this tool to circumvent rate limits or scrape at scale. You are responsible for how you use this tool.

Architecture

                         ┌───────────────────────────┐
                         │        screener.in         │
                         │  (HTML pages + JSON APIs)   │
                         └──────────────┬─────────────┘
                                         │ httpx (rate-limited, retried)
                                         ▼
                         ┌───────────────────────────┐
                         │       client.py            │
                         │  ScreenerClient             │
                         │  - RateLimiter (token bkt)  │
                         │  - retries + backoff        │
                         │  - cookie jar / session      │
                         └──────────────┬─────────────┘
                                         │
                ┌────────────────────────┼─────────────────────────┐
                ▼                        ▼                          ▼
        ┌──────────────┐        ┌───────────────┐          ┌──────────────┐
        │  parsers.py   │        │  auth.py       │          │ indicators.py │
        │  HTML/JSON →  │        │  login/session │          │ SMA/EMA/RSI/  │
        │  pydantic     │        │  persistence   │          │ MACD/Bollinger│
        │  models       │        │                │          │ /Stochastic   │
        └──────┬────────┘        └───────┬────────┘          └──────┬────────┘
                │                          │                          │
                └────────────┬─────────────┴────────────┬────────────┘
                              ▼                          ▼
                      ┌───────────────────────────────────────┐
                      │             service.py                  │
                      │           ScreenerService                │
                      │  high-level facade (search, overview,   │
                      │  price_history, financials, peers,      │
                      │  shareholding, documents, technical,     │
                      │  snapshot) — page-cache(8) per instance  │
                      └───────┬───────────────────┬─────────────┘
                               │                   │
                ┌──────────────▼───┐     ┌─────────▼──────────┐
                │     bulk.py        │     │     export.py       │
                │  bulk_fetch over   │     │  JSON/CSV/Parquet    │
                │  many symbols      │     │  export              │
                │  (semaphore-bound) │     │                      │
                └──────────────┬─────┘     └─────────┬───────────┘
                               │                       │
                ┌──────────────▼───────────────────────▼───────────┐
                │                  Interfaces                        │
                │  ┌────────────────────┐   ┌──────────────────────┐│
                │  │     cli.py          │   │   mcp_server.py       ││
                │  │  `screener ...`     │   │  FastMCP server        ││
                │  │  typer + rich       │   │  `screener_*` tools     ││
                │  └────────────────────┘   └──────────────────────┘│
                └─────────────────────────────────────────────────────┘

Installation

This repo ships an llms.txt written for AI coding agents. Paste this into your agent (Claude Code, Cursor, Codex, etc.):

Fetch and follow the instructions at
https://raw.githubusercontent.com/singhvedant/screener-ai-tool/main/llms.txt
to install screener-ai-tool, register its MCP server, and install its skill.

The agent will: install the package (pip/uv), register the screener MCP server, copy skills/screener-ai-tool/SKILL.md into its own skills directory (so the skill can be toggled on/off independently later), and verify everything works end-to-end.

Manual installation

Requires Python 3.11+.

pip install screener-ai-tool
# or
uv pip install screener-ai-tool

Or from source, with uv:

git clone https://github.com/singhvedant/screener-ai-tool.git
cd screener-ai-tool

# create a virtual environment and install in editable mode with dev deps
uv venv
source .venv/bin/activate
uv pip install -e ".[dev]"

After installation the screener CLI entry point is available (or run via uv run screener ... / python -m screener_ai ...).

Authentication & session persistence

screener.in allows limited anonymous browsing (~50 page views/day) before showing rate-limit prompts. Logging in with your screener.in account raises those limits significantly.

# interactive (prompts for password, hidden input)
screener login --email you@example.com

# or via environment variables (useful for CI / scripts)
export SCREENER_EMAIL=you@example.com
export SCREENER_PASSWORD=your-password
screener login

# check status
screener auth-status

# log out (clears saved session)
screener logout

On success, the session cookie (sessionid) is written to ~/.screener-ai/session.json (mode 0600, JSON of cookie name → value). All subsequent CLI/MCP/library calls reuse this session automatically until it expires or screener logout is run. Credentials and cookies are never logged.

CLI usage

All commands support --json for raw JSON output (useful for piping into jq or other tools), and most accept --days / --consolidated/--standalone where relevant. Async commands wrap asyncio.run; errors print a message to stderr and exit with code 1 (authentication errors suggest screener login).

screener search QUERY

Search for companies by name or symbol.

screener search reliance
screener search tata --json

screener price SYMBOL [--days 365] [--limit 30]

Show recent price history (rich table of the latest --limit rows).

screener price RELIANCE
screener price RELIANCE --days 90 --limit 10
screener price TCS --json > tcs_prices.json

screener overview SYMBOL

Company overview: name, sector/industry, key ratios, pros/cons.

screener overview RELIANCE
screener overview INFY --json

screener fundamentals SYMBOL [--statement profit-loss|quarters|balance-sheet|cash-flow|ratios]

Fetch a financial statement table.

screener fundamentals RELIANCE --statement quarters
screener fundamentals RELIANCE --statement balance-sheet --json

screener technical SYMBOL [--days 365] [--series]

Technical analysis snapshot (SMA/EMA/RSI/MACD/Bollinger + signals). Pass --series to include full indicator time series.

screener technical RELIANCE
screener technical RELIANCE --days 180 --series --json

screener events SYMBOL / screener news SYMBOL

events shows announcements + corporate documents; news is an alias view focused on announcements, credit ratings, and concall material.

screener events RELIANCE
screener news RELIANCE --json

screener peers SYMBOL

Peer comparison table (with median row).

screener peers RELIANCE

screener shareholding SYMBOL

Quarterly and yearly shareholding pattern tables.

screener shareholding RELIANCE

screener snapshot SYMBOL

Aggregated "everything we know" snapshot — overview, financial tables, shareholding, peers, documents, and technical analysis, fetched concurrently.

screener snapshot RELIANCE --json

screener bulk SYMBOLS... [--dataset price] [--concurrency 8] [--out FILE]

Fetch a dataset for many symbols concurrently. Per-symbol failures are captured (never raised) as {"error": "..."} entries.

screener bulk RELIANCE TCS INFY HDFCBANK --dataset overview
screener bulk RELIANCE TCS INFY --dataset price --days 90 --concurrency 16 --out prices.json

screener export SYMBOL [--what price|fundamentals|snapshot] [--fmt json|csv|parquet] [--out FILE]

Export data to JSON, CSV, or Parquet (CSV/Parquet for tabular data such as price history and financial tables via pandas).

screener export RELIANCE --what price --fmt csv --out reliance_price.csv
screener export RELIANCE --what snapshot --fmt json --out reliance_snapshot.json

screener serve [--transport stdio|http] [--host 127.0.0.1] [--port 8631]

Run the MCP server (see below).

MCP setup

# if installed via pip/uv (entry point on PATH)
claude mcp add screener -- screener serve

# if running from a cloned repo
claude mcp add screener -- uv run --directory ~/Development/screener-ai-tool screener serve

This registers a screener MCP server that Claude launches on demand via stdio.

HTTP transport

To run the server over streamable HTTP (e.g. for remote access or shared deployments):

uv run --directory ~/Development/screener-ai-tool screener serve --transport http --host 127.0.0.1 --port 8631

Then point an MCP-compatible client at http://127.0.0.1:8631.

MCP tool list

All tools return JSON-serializable dicts (model_dump).

Tool Description
screener_login(email, password) Authenticate and persist a session (use when rate-limited as anonymous)
screener_auth_status() Current authentication status
screener_search(query, limit=10) Search for companies
screener_price(symbol, days=365, limit=0) Price history (optionally truncated to last limit points)
screener_overview(symbol) Company overview + key ratios
screener_fundamentals(symbol, statement="profit-loss") Financial statement table
screener_technical(symbol, days=365, include_series=False) Technical indicators + signals
screener_peers(symbol) Peer comparison table
screener_shareholding(symbol) Shareholding pattern (quarterly/yearly)
screener_events(symbol) Announcements + corporate documents
screener_news(symbol) Announcements + credit ratings + concalls
screener_snapshot(symbol, days=365) Full aggregated snapshot
screener_bulk(symbols, dataset="price", days=365, concurrency=8) Bulk fetch over many symbols
screener_export(symbol, what="snapshot", fmt="json", out_path="") Export data to a file

Data models

Defined with pydantic v2 in screener_ai.models:

  • SearchResult — id, name, url, symbol (parsed from url)
  • CompanyRef — symbol, name, company_id, warehouse_id, consolidated
  • PricePoint / PriceHistory — date, close, dma50, dma200, volume, delivery_pct
  • KeyRatios — market_cap, current_price, high_52w, low_52w, pe, book_value, dividend_yield, roce, roe, face_value, extras
  • CompanyOverview — ref, about, website, bse_code, nse_code, sector, industry, ratios, pros, cons
  • FinancialTable — kind, columns, rows (raw strings) + .numeric() helper
  • ShareholdingPattern — quarterly / yearly FinancialTable
  • PeerRow / PeerComparison — peer metrics + median row
  • DocumentLink / CorporateDocs — announcements, annual reports, credit ratings, concalls
  • IndicatorSeries, MACDResult, BollingerResult — technical indicator series
  • TechnicalSnapshot / TechnicalAnalysis — latest indicator values + signals
  • FullSnapshot — everything aggregated for one symbol

Rate limiting & politeness

  • Default: 2 requests/second, burst of 5 (token-bucket RateLimiter).
  • On HTTP 429, the client backs off exponentially (with jitter) and honors Retry-After; if retries are exhausted, RateLimitError is raised.
  • Connection pooling is bounded (max_connections=20, keepalive=10).
  • Anonymous browsing is heavily throttled by screener.in (~50 page views/day). Log in (screener login) for a much higher effective limit, and consider lowering --concurrency for bulk/snapshot operations.
  • bulk_fetch / screener bulk isolate per-symbol errors — one bad symbol never aborts the whole batch.

Testing

# unit tests only (no network) — the default safe subset
pytest -m "not integration and not load"

# live integration tests (hits screener.in; skips gracefully on network errors)
pytest -m integration

# heavy load test (500+ symbols; requires network and takes a while)
pytest -m load

Unit tests use captured fixtures in tests/fixtures/ (real screener.in HTML and JSON responses) plus respx to mock httpx for client-level tests — no network access is required for pytest -m "not integration and not load".

License

MIT — see LICENSE.

Release files for screener-ai-tool 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for screener-ai-tool 0.1.0
File Size Uploaded
screener_ai_tool-0.1.0.tar.gz 158.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for screener-ai-tool 0.1.0
File Interpreter ABI Platform
screener_ai_tool-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 199.7 kB

Release files / screener_ai_tool-0.1.0.tar.gz

Download URL screener_ai_tool-0.1.0.tar.gz
Size 158.6 kB
Tags Source
SHA-256 checksum
How to use checksums
ee739cd3153608792a7c462c8cd107d1380864fba3c89dbab0403905078a86b7
BLAKE2b-256 checksum
How to use checksums
ed4439efd54f05eb8d5f44ea73d74a94b5bbe3d364ece227c3d54d849927cace
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release files / screener_ai_tool-0.1.0-py3-none-any.whl

Download URL screener_ai_tool-0.1.0-py3-none-any.whl
Size 41.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
c3e53d59517cb1b3850bb3da0ea043a05a69c25bf6468023496255d07825e805
BLAKE2b-256 checksum
How to use checksums
89409a779d2af3fe158206f29bc65a15c50535f034c269110585cdfd6ba6d562
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Jun 15, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page