bd-finance-mcp
bd-finance-mcp
Bangladesh's financial markets, available to your AI assistant. Both stock exchanges, every listed share, and what the taka is worth today.
An MCP server built with FastMCP.
⚠️ Not investment advice. This reports publicly published prices. It does not analyse, recommend, or predict. Figures are last-traded values and may lag the live market.
Unofficial. Not affiliated with DSE, CSE, or Bangladesh Bank.
Tools
Tool | What it does |
| The same share priced on both exchanges, with the spread between them. |
| Breadth — how many shares rose, fell, held flat or never traded. |
|
|
| Prices for specific trading codes. |
| Find codes by substring, e.g. |
| How a whole sector traded — did banks rise while textiles fell? |
| The 22 DSE sectors you can ask about. |
| Sector, market cap, P/E ratio, paid-up capital, shares outstanding. |
| Taka per USD, EUR, GBP, SAR, AED, MYR and 160 more. |
| Latest business and financial headlines. |
| Which papers are covered, and which could not be. |
company_profile turns a bare price into something you can reason about — GP trades at a P/E of
11.44 in Telecommunication with a 326,907mn taka market cap, BRAC Bank at 6.14 in Banking. Prices
alone don't tell you that.
compare_exchanges is the one you can't easily do yourself — most Bangladeshi companies list on
both markets, and the prices genuinely differ. GP was trading at 240.60 on Dhaka and 241.50 on
Chittagong while this was being written.
sector_performance answers the question a price list can't: how did banks do today? It
aggregates every share in a sector — advancers, decliners, average move, best and worst — from
one query. Partial names work, so "pharma" finds "Pharmaceuticals & Chemicals".
Prices tell you a share moved; finance_news tells you why.
Every market response carries a market block saying whether DSE is currently trading
(Sunday–Thursday, 10:00–14:30 Asia/Dhaka) and whether the figures are live or the last completed
session. Outside session hours, "today's gainers" means the previous close — the response says so
rather than leaving you to assume.
Sources
Source | Provides |
Dhaka Stock Exchange — ~395 instruments, company fundamentals | |
Chittagong Stock Exchange — ~387 instruments | |
Currency reference rates, 166 currencies | |
dsebd.org sector pages | 22 sectors and their constituents |
The Daily Star — Business | Bangladeshi business news |
The Business Standard — Economy | Bangladeshi business news |
Dhaka Tribune | General newsroom (see note below) |
Financial Times — Companies | International business news |
Dhaka Tribune publishes no business-only feed, so its articles are general newsroom output.
finance_news leaves it out by default (business_only=True) rather than passing student
politics off as market coverage — name it in sources, or set business_only=False, to include it.
Bonik Barta is not available. It is a single-page app: every path, including /api/v1/,
returns the same HTML shell with HTTP 200. There is no feed or API behind it. A status code alone
is not proof a source works.
New Age is not available. No working RSS feed exists at any conventional path.
Financial Times links are paywalled. Headlines and summaries come through the public feed; the articles themselves require a subscription.
No API key, login, or paid data feed.
Not included: Bangladesh Bank. Its econdata pages sit behind a CAPTCHA challenge. That is an
explicit request not to automate, and this project respects it rather than working around it. Use
exchange_rate for reference rates instead — but note those are mid-market, not BB's official
rate, and not what a bank will actually pay you.
Not included: gold prices. BAJUS renders them client-side; nothing is in the HTML to parse.
Not included: the DSEX index. It appears only in DSE's navigation menus — the live value is
injected by JavaScript, so there is nothing to read from the served HTML. market_summary gives
you breadth and turnover instead, which describes the session without pretending to quote an
index it cannot see.
Install
Requires uv and Python 3.12+.
git clone https://github.com/Claudefarid/bd-finance-mcp.git
cd bd-finance-mcp
uv sync
uv run fastmcp install claude-code server.py:mcpRestart your client, then ask "Compare GP's price on both Bangladeshi exchanges" or "What's the taka doing against the riyal?"
Verify with uv run python test_server.py.
Six things that will bite you if you build this yourself
Each of these produces wrong answers rather than errors — the dangerous kind of bug.
1. The two exchanges disagree about untraded shares.
DSE reports a share that did not trade with price 0. CSE carries yesterday's price forward.
Compute percent change naively and DSE hands you a list of −100% "crashes" that are really just
shares nobody bought. Trade count is the only signal that works on both, so it decides whether a
percentage is meaningful here.
This matters more on CSE than you would guess: 187 of its 387 listed shares did not trade on the day this was written. Nearly half the market. Get this wrong and CSE data is worthless.
2. dsebd.org serves an incomplete TLS certificate chain.
Its leaf certificate is signed by a Sectigo intermediate 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 altogether, which is a bad trade
anywhere and a worse one for financial data. Verify against the OS trust store instead:
import ssl, truststore
ctx = truststore.SSLContext(ssl.PROTOCOL_TLS_CLIENT)
httpx.AsyncClient(verify=ctx)3. DSE's P/E table is one column per trading day, and the newest is last.
The ratio table sits under a Particulars header whose columns are dates. Read the first column —
the obvious choice — and you report a P/E from a week ago as today's. company_profile takes the
last populated column and returns the date alongside it, so the figure is always checkable.
There is a second trap in the same table: the page carries several Particulars headers, and the
first one reads "Unaudited / Audited" rather than dates. Matching on width picks the right one.
A missing P/E is not a parsing failure, either. DSE prints - across the row for companies
without meaningful earnings — BEXIMCO, for one — so None there is the honest answer.
4. The Daily Star's feed puts HTML inside its <title> tags.
Its headlines arrive wrapped in an unescaped anchor:
<title><a href="/business/news/...">7,896 customers withdraw Tk 327 crore</a></title>ElementTree parses that anchor as a child element, so findtext("title") returns an empty
string — not an error, just nothing. Every Daily Star headline came back blank, and because an
empty headline matches no keyword, the paper looked like it was ignoring every topic when it was
simply never being read. "".join(element.itertext()) collects descendant text and fixes it.
5. Substring matching puts the IT sector inside "Financial Institutions".
The obvious way to resolve a sector name is query in name.lower(). Ask for "IT" and you match
both IT Sector and Financial Inst**it**utions — so the most natural query for the sector fails as
ambiguous. Matching runs in tiers instead: exact, then prefix, then word-boundary, then substring,
taking the first tier that resolves to one sector.
6. Mid-market rates are not remittance rates.
exchange_rate returns reference rates. Banks and exchange houses apply their own spread, so
what actually lands in a recipient's account is lower. The tool says so in its own description,
so a model relying on it does not quietly present these as the rate you'd receive.
Please be considerate
Each call is a single page fetch, and requests identify themselves by User-Agent. Don't poll in a tight loop.
License
MIT — see LICENSE. Covers this code only, not the exchanges' data.
Latest Blog Posts
- Who's Calling? MCP Hosts Are an Identity Blind Spot (And the Spec Knows It)By Om-Shree-0709 on .mcpAgent IdentityOAuth 2.1
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/Claudefarid/bd-finance-mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server