Metadata-Version: 2.4
Name: screener-mcp
Version: 0.2.0
Summary: Indian Stock Research MCP server powered by Screener.in
Author: LogeshR15
License: MIT
Project-URL: Homepage, https://github.com/LogeshR15/screener-mcp
Project-URL: Repository, https://github.com/LogeshR15/screener-mcp
Project-URL: Issues, https://github.com/LogeshR15/screener-mcp/issues
Keywords: mcp,screener,indian-stocks,nse,bse,stock-research,claude,llm
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Office/Business :: Financial :: Investment
Requires-Python: >=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: mcp<2.0.0,>=1.0.0
Requires-Dist: httpx>=0.27.0
Requires-Dist: beautifulsoup4>=4.12.0
Requires-Dist: lxml>=5.0.0
Provides-Extra: dev
Requires-Dist: pytest; extra == "dev"
Requires-Dist: pytest-asyncio; extra == "dev"
Provides-Extra: ai
Requires-Dist: pdfplumber>=0.11.0; extra == "ai"
Requires-Dist: chromadb>=0.5.0; extra == "ai"
Requires-Dist: sentence-transformers>=3.0.0; extra == "ai"
Dynamic: license-file

# screener-mcp — Indian Stock Research for Claude

> Turn Claude into a personal Indian equity analyst powered by live [Screener.in](https://www.screener.in) data — now with AI document analysis, NSE announcements, and research notebooks.

[![PyPI](https://img.shields.io/pypi/v/screener-mcp)](https://pypi.org/project/screener-mcp/)
[![Python](https://img.shields.io/pypi/pyversions/screener-mcp)](https://pypi.org/project/screener-mcp/)
[![CI](https://github.com/LogeshR15/screener-mcp/actions/workflows/ci.yml/badge.svg)](https://github.com/LogeshR15/screener-mcp/actions/workflows/ci.yml)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)

**300+ active users** · [Report an issue](https://github.com/LogeshR15/screener-mcp/issues) · [LinkedIn](https://linkedin.com/in/logesh-ramasamy/) · logeshl2003@gmail.com

---

## What you can ask

```
"Compare ITC and HUL on all key ratios"
"Find chemical stocks with low debt and strong growth"
"Explain Jyothy Labs like I'm a beginner"
"What are the red flags in Asian Paints?"
"Find hidden gems below ₹5000 crore market cap"
"What did TCS management say about margins in Q3FY25?"
"Summarize the key risks from Reliance's 2024 annual report"
"How has ITC's capex strategy evolved over the last 3 years?"
"Which of TATASTEEL, JSWSTEEL, and SAIL mentioned raw material cost pressure recently?"
"Show me recent dividend announcements for HDFCBANK"
"How does copper price affect Havells and Polycab?"
"Save a research note on TITAN — strong Q3, watch margins"
```

---

## Quick install

```bash
claude mcp add screener -s user -- uvx --from 'screener-mcp[ai]' screener-mcp
```

> Requires [uv](https://github.com/astral-sh/uv): `pip install uv` or `brew install uv`
>
> The `[ai]` extra pulls in `pdfplumber`, `chromadb`, and `sentence-transformers` (~1-2GB, via torch) and is
> required for `analyze_annual_report`, `analyze_earnings_call`, `ask_company_research`, and
> `search_market_commentary`. Plain `uvx screener-mcp` installs only the lightweight core — those four tools
> will fail with a "not installed" error until you add the extra.

**Manual install:**

```bash
git clone https://github.com/LogeshR15/screener-mcp
cd screener-mcp
python3.11 -m venv .venv
source .venv/bin/activate
pip install --upgrade pip
pip install -e .

claude mcp add screener -s user -- \
  $(pwd)/.venv/bin/python3.11 \
  $(pwd)/run_server.py
```

> No `python3.11` on your machine? Any Python **3.11+** works (e.g. `python3.12 -m venv .venv`) — just point `claude mcp add` at that same interpreter.
> `pip install -e .` fails with "editable mode currently requires a setuptools-based build"? Your venv's `pip` is too old — run `pip install --upgrade pip` first (as above), then retry.

---

## Claude Desktop setup

Claude Desktop doesn't read `claude mcp add` — you edit its config file directly.

**1.** Install [uv](https://github.com/astral-sh/uv) if you don't have it:

```bash
brew install uv   # or: pip install uv
```

**2.** Open the config file:

- **macOS:** `~/Library/Application Support/Claude/claude_desktop_config.json`
- **Windows:** `%APPDATA%\Claude\claude_desktop_config.json`
- **Linux:** `~/.config/Claude/claude_desktop_config.json`

In the app you can also get there via **Settings → Developer → Edit Config**.

**3.** Add the `screener` server (create the file with just this content if it doesn't exist):

```json
{
  "mcpServers": {
    "screener": {
      "command": "uvx",
      "args": ["--from", "screener-mcp[ai]", "screener-mcp"],
      "env": {
        "SCREENER_USERNAME": "your@email.com",
        "SCREENER_PASSWORD": "yourpassword"
      }
    }
  }
}
```

The `env` block is how Claude Desktop passes credentials — it does **not** inherit
your shell's `~/.zshrc` exports. Leave `env` out entirely if you only want the
no-login company-research tools.

> `spawn uvx ENOENT` on launch? Claude Desktop starts with a minimal `PATH` and
> can't find `uvx`. Use the absolute path instead — run `which uvx` (e.g.
> `/opt/homebrew/bin/uvx`) and put that in `"command"`.

**Already cloned the repo?** Point it at your venv interpreter instead:

```json
{
  "mcpServers": {
    "screener": {
      "command": "/absolute/path/to/screener-mcp/.venv/bin/python3.11",
      "args": ["/absolute/path/to/screener-mcp/run_server.py"]
    }
  }
}
```

**4.** Quit Claude Desktop completely (**Cmd+Q** on macOS — closing the window
isn't enough) and reopen it.

**5.** Check the tools icon in the message composer — `screener` should be listed
with its 25 tools. Then ask: `"Search for Asian Paints"`.

> Server not showing up? Open **Settings → Developer** to see its status, and
> check the logs at `~/Library/Application Support/Claude/logs/mcp-server-screener.log`
> (macOS) or `%APPDATA%\Claude\logs\` (Windows). Invalid JSON in the config —
> a stray trailing comma is the usual culprit — makes Claude Desktop skip every
> server silently.

---

## Credentials setup

Company financials work **without login**. Stock screening requires a free account.

**1.** Register free at [screener.in/register](https://www.screener.in/register/)

**2.** Add to `~/.zshrc` or `~/.bashrc`:

```bash
export SCREENER_USERNAME="your@email.com"
export SCREENER_PASSWORD="yourpassword"
```

**3.** Reload shell (`source ~/.zshrc`) and restart Claude Code.

> Claude Desktop does not read your shell profile — put the same two values in the
> `"env"` block of `claude_desktop_config.json` instead (see [Claude Desktop setup](#claude-desktop-setup)).

**For document analysis** (annual reports, earnings calls), install extra deps:

```bash
pip install pdfplumber sentence-transformers chromadb
# or: pip install -e ".[ai]"
```

---

## Verify connection

```bash
claude mcp list
# screener  stdio  Connected
```

Then ask Claude: `"Search for Asian Paints"` — you should get results.

---

## Running as a remote server (HTTP)

By default this runs over stdio — a local process, used by `claude mcp add`, Claude
Desktop, and similar clients. Some integrations — any client that asks for an
HTTPS **Server URL** — instead need a network server.

Run it with HTTP transport:

```bash
MCP_TRANSPORT=streamable-http PORT=8000 python run_server.py
# Serves MCP over HTTP at http://<host>:8000/mcp
```

Env vars:

| Variable | Purpose | Default |
|----------|---------|---------|
| `SCREENER_USERNAME` | Screener.in login email (needed for screening tools) | — |
| `SCREENER_PASSWORD` | Screener.in password | — |
| `MCP_TRANSPORT` | `stdio` or `streamable-http` | `stdio` |
| `PORT` / `MCP_PORT` | Port to listen on (HTTP transport only) | `8000` |
| `MCP_HOST` | Bind address (HTTP transport only) | `0.0.0.0` |
| `CHROMA_PERSIST_DIR` | Where the document-analysis vector store is cached | `~/.screener-mcp/chroma_db` |

To get a public HTTPS URL, deploy this to any host that can run a long-lived
Python process and terminate TLS for you (Render, Railway, Fly.io, a VM behind
a reverse proxy, etc.), then point the client at `https://your-host/mcp`.

> Note: a bare `streamable-http` server has no authentication. If you deploy
> it publicly, put it behind your platform's access controls (API gateway,
> IP allowlist, auth proxy) rather than exposing it to the open internet
> unauthenticated — especially if you set `SCREENER_USERNAME`/`PASSWORD`,
> since anyone who can reach the URL would act as your Screener.in account.

### Deploying with Docker

A `Dockerfile` is included. It installs the full `[ai]` extras (document
analysis included) — expect a slow first build (~1-2GB with torch).

```bash
# Build and tag the image
docker build -t screener-mcp:latest .

# Run it, exposing the HTTP port and setting credentials
docker run -p 8000:9000 \
  -e PORT=9000 \
  -e SCREENER_USERNAME=you@example.com \
  -e SCREENER_PASSWORD=yourpassword \
  screener-mcp:latest
```

Then point the client at `http://<host>:8000/mcp`.

---

## Tools — 30 total

### Company Research

| Tool | What it does | Login needed |
|------|-------------|:---:|
| `search_company` | Find company by name or symbol | No |
| `get_company_overview` | Key ratios, price, 52W range, about | No |
| `get_financials` | P&L / Balance Sheet / Cash Flow / Ratios | No |
| `get_quarterly_results` | Last 8 quarters of results | No |
| `get_shareholding_pattern` | Promoter / FII / DII holding trend | No |
| `get_peer_comparison` | Sector peer comparison table | No |
| `compare_companies` | Side-by-side comparison (2–5 stocks) | No |
| `compare_stocks_ui` | Interactive dashboard (Claude Desktop) | No |
| `get_full_analysis` | All data combined for deep analysis | No |
| `analyze_red_flags` | Structured red flag detection | No |
| `explain_for_beginners` | Plain-language company explainer | No |

### Stock Screening

| Tool | What it does | Login needed |
|------|-------------|:---:|
| `screen_stocks` | Custom Screener.in query | Yes |
| `screen_by_theme` | Pre-built thematic screens | Yes |
| `list_investment_themes` | Show all available themes | No |

### Document Analysis *(new)*

| Tool | What it does | Extra deps needed |
|------|-------------|:---:|
| `get_document_list` | List annual reports & earnings call transcripts | No |
| `analyze_annual_report` | Ask any question over one annual report PDF | Yes |
| `analyze_earnings_call` | Ask any question over one earnings call transcript | Yes |
| `ask_company_research` | Ask a question across ALL of a company's cached documents at once (multiple years/quarters) | Yes |
| `search_market_commentary` | Search a question across multiple companies' already-indexed documents at once | Yes |

> Uses a local RAG pipeline: PDF → pdfplumber → ChromaDB → sentence-transformers. Results are cached on disk — the same report is never re-downloaded or re-indexed.
> `ask_company_research` and `search_market_commentary` build on the same cache — the former indexes a company's recent documents and searches across them together (good for "how has X changed over time?"); the latter searches only what's *already* indexed across several symbols (good for "which of these companies mentioned Y?").

### Corporate Events *(new)*

| Tool | What it does | Login needed |
|------|-------------|:---:|
| `get_company_announcements` | NSE corporate announcements with category filter | No |
| `search_shareholder` | Find investor activity via NSE bulk deals | No |
| `get_bulk_deals` | All NSE bulk deals for one company — no investor name needed | No |
| `get_promoter_pledge_history` | Dedicated promoter pledge % trend with severity flag | No |
| `get_credit_ratings` | CRISIL/ICRA/CARE/India Ratings rating actions — a debt-quality check | No |

### Market & Research *(new)*

| Tool | What it does | Login needed |
|------|-------------|:---:|
| `get_commodity_prices` | Commodity price context + impacted companies | No |
| `notebook_ai` | Save, read, and AI-summarize research notes locally | No |

### Portfolio *(new)*

| Tool | What it does | Login needed |
|------|-------------|:---:|
| `add_portfolio_stock` | Add/merge a holding into your local portfolio (quantity-weighted avg cost) | No |
| `update_portfolio_stock` | Overwrite quantity/avg price on an existing holding (partial sell, cost correction) | No |
| `remove_portfolio_stock` | Remove a holding entirely | No |
| `get_portfolio` | View holdings with live price, P&L (₹ and %), and weight | No |

> Stored locally at `~/.screener-mcp/portfolio.json` — no account, no external service, nothing leaves your machine.

---

## Pre-built screening themes

```
undervalued_small_cap       Small caps, ROCE > 15%, low debt, PE < 20
high_roce_low_debt          ROCE > 20%, debt to equity < 0.3
compounders                 15%+ growth: revenue, profit, ROE, ROCE
turnaround                  Strong recent profit recovery
rising_profit_falling_price Improving profits, compressed valuation
improving_roce              ROCE > 15% with profit momentum
hidden_gems                 Small cap, high ROCE, strong growth
dividend_aristocrats        Consistent dividends with quality financials
qarp                        Quality at reasonable price
micro_cap_growth            High-growth micro caps < ₹1000 Cr
ev_theme                    EV & auto ancillary growth companies
chemicals                   Specialty chemicals, strong fundamentals
defense                     Defense sector with revenue momentum
railways                    Railway infra/equipment companies
renewable_energy            Renewable energy sector
```

---

## Custom screen syntax

```
Market Capitalization < 5000 AND Return on capital employed > 15 AND Debt to equity < 0.5
Profit growth 5Years > 20 AND Sales growth 5Years > 15 AND Debt to equity < 0.3
Dividend yield > 3 AND Return on equity > 15 AND Pledged percentage < 5
```

Supported operators: `>` `<` `=` `AND`

Full field list in [CONTRIBUTING.md](CONTRIBUTING.md#screenerinscreenerinquery-field-names).

---

## How document analysis works

```
analyze_annual_report("TCS", 2024, "What are the key risks?")

  1. Fetch PDF link from Screener.in / NSE
  2. Download and parse with pdfplumber
  3. Chunk into 500-word overlapping segments
  4. Embed with sentence-transformers (runs locally, no API key needed)
  5. Store in ChromaDB (~/.screener-mcp/chroma_db/)
  6. Semantic search returns top-5 relevant excerpts
  7. Claude reasons over the excerpts to answer your question

Results are cached — the same report is never re-processed twice.
```

---

## Architecture

```
screener-mcp/
├── run_server.py
├── tests/                          # Offline registry + docs-consistency tests
└── src/screener_mcp/
    ├── server.py                   # FastMCP — all 23 tool definitions
    ├── client.py                   # Screener.in HTTP client + auth
    ├── core/
    │   ├── nse_client.py           # NSE India API (announcements, filings)
    │   ├── rag.py                  # PDF → chunk → embed → query pipeline
    │   └── vector_store.py         # ChromaDB wrapper
    ├── parsers/
    │   ├── company.py              # Screener.in company page parser
    │   └── screener.py             # Screen results parser
    └── tools/
        ├── company_tools.py        # Company data tools
        ├── screening_tools.py      # Stock screening + themes
        ├── analysis_tools.py       # Deep analysis, red flags, beginner
        ├── documents.py            # Annual reports + earnings calls (RAG)
        ├── announcements.py        # NSE corporate announcements
        ├── shareholders.py         # Bulk deal / shareholder search
        ├── commodities.py          # Commodity price analysis
        └── notebook.py             # Research notes
```

---

## Data sources & limitations

| Source | Data provided |
|--------|--------------|
| [Screener.in](https://www.screener.in) | 10+ years of financials, ratios, shareholding, peers |
| [NSE India](https://www.nseindia.com) | Announcements, annual reports, bulk deals |
| [MCX India](https://www.mcxindia.com) | Commodity prices (best-effort) |

- Financial data lags by ~1 quarter
- Document analysis requires machine-readable PDFs (scanned/image-only PDFs may fail)
- NSE bulk deals only capture single trades > 0.5% of equity
- `get_company_announcements` and `search_shareholder` depend on NSE's public API, which
  frequently rate-limits or blocks server IPs (403/404 responses) — if a query returns
  "no data found", it may be NSE blocking the request rather than an empty result
- This is a research tool — not financial advice

---

## Contributing

See [CONTRIBUTING.md](CONTRIBUTING.md) — adding a new tool takes ~10 minutes.

```bash
git clone https://github.com/LogeshR15/screener-mcp
cd screener-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
```

The test suite is offline — no network, no Screener.in credentials — and
checks that the tool registry and the docs still agree with each other. If you
add or rename a tool, tests fail until you update `EXPECTED_TOOLS` in
[`tests/test_tools.py`](tests/test_tools.py), the `server.py` docstring, and
the README tool table.

**Dependency files:**
- `pyproject.toml` — the source of truth; `[ai]` extra adds document analysis
- `requirements.txt` — full install (core + document analysis, pulls in torch)
- `requirements-core.txt` — lightweight install, no document-analysis tools

---

## License

[MIT](LICENSE) © Logesh Ramasamy

---

## Contact

**Logesh Ramasamy** · logeshl2003@gmail.com · [LinkedIn](https://linkedin.com/in/logesh-ramasamy/)
