dse-stock-mcp
# dse-stock-mcp
Ask your AI assistant about the Dhaka Stock Exchange and get live numbers back — every listed
share, today's gainers and losers, market breadth, turnover.
An [MCP](https://modelcontextprotocol.io/) server built with [FastMCP](https://github.com/PrefectHQ/fastmcp).
> ⚠️ **Not investment advice.** This tool reports publicly published prices. It does not analyse,
> recommend, or predict. Figures are last-traded values and may lag the live market. Verify
> anything you intend to act on against [dsebd.org](https://www.dsebd.org) directly.
> **Unofficial.** Not affiliated with or endorsed by the Dhaka Stock Exchange.
## Tools
| Tool | What it does |
|---|---|
| `market_summary()` | How many shares rose, fell, held flat or never traded, plus total turnover. |
| `top_movers(direction, limit)` | Biggest movers — `gainers`, `losers`, `volume` or `value`. |
| `get_stock(codes)` | Prices for specific trading codes, e.g. `["GP", "BRACBANK"]`. |
| `search_stock(query)` | Find trading codes by substring, e.g. `"BANK"` → 25 matches. |
Covers all ~395 listed instruments. One request to the exchange serves each call.
## Install
Requires [uv](https://docs.astral.sh/uv/) and Python 3.12+.
```bash
git clone https://github.com/Claudefarid/dse-stock-mcp.git
cd dse-stock-mcp
uv sync
uv run fastmcp install claude-code server.py:mcp
```
Restart your client, then ask *"Which DSE shares gained the most today?"* No API key, no login,
no paid data feed.
Verify with `uv run python test_server.py`.
## Two things that will bite you if you build this yourself
Both are handled here, and both produce *wrong answers* rather than errors if you miss them.
**1. Untraded shares look like a -100% crash.**
A share that did not trade is listed with `LTP = 0` and `TRADE = 0` — the exchange prints `--`
for its change. Compute percent change naively and you get −100%, so your "biggest losers" list
fills up with shares that simply never traded. On the day this was written, 11 of 395 shares were
untraded, and they crowded out every genuine decline. This server marks them `traded: false`,
excludes them from movers, and counts them separately in `market_summary`.
**2. `dsebd.org` serves an incomplete TLS certificate chain.**
The leaf certificate is signed by a Sectigo intermediate that the server never sends. Browsers
and curl recover by fetching it via AIA; Python's `certifi` bundle cannot, so `httpx` fails with
`CERTIFICATE_VERIFY_FAILED`.
**The fix is not `verify=False`.** That disables verification entirely — a bad trade anywhere,
and a worse one for financial data. This server verifies against the operating system's trust
store via [`truststore`](https://pypi.org/project/truststore/), which resolves the missing
intermediate and keeps verification fully intact.
```python
import ssl, truststore
ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
httpx.AsyncClient(verify=ctx)
```
## Please be considerate
Prices are published by the Dhaka Stock Exchange. Requests identify themselves by User-Agent.
Each call is a single page fetch — don't poll it in a tight loop.
## License
MIT — see [LICENSE](LICENSE). Covers this code only, not the exchange's data.
TDQS
Scored across 4 tools
Each tool has a clearly distinct purpose: exact price lookup, ranked movers, market breadth, and code search. Even get_stock and search_stock are disambiguated by the explicit guidance to use search_stock for partial names.
Names are all lowercase snake_case and readable, but the pattern is mixed: get_stock and search_stock follow verb_noun, while top_movers and market_summary are noun phrases. This is not a consistent convention.
Four tools is well-scoped for a focused stock market data server. Each tool provides a distinct, valuable capability without redundancy or bloat.
The toolset covers the core read-only workflows: looking up prices, finding movers, understanding market breadth, and discovering trading codes. Historical data or detailed company information would be nice but are not essential to the apparent purpose.