thndr-mcp
# thndr-mcp
[](https://github.com/armaaar/thndr-mcp/actions/workflows/ci.yml)
[](https://github.com/armaaar/thndr-mcp/releases)
[](LICENSE)
> **Unofficial and not affiliated with Thndr. Not financial advice. Provided "AS IS", at your own risk — to the maximum
> extent permitted by law, the maintainers accept no responsibility for financial decisions, losses or any other
> liability arising from its use.**
> Read the [Disclaimer](#disclaimer) before using it.
An **unofficial, community** toolkit for [Thndr](https://thndr.app), the broker for the Egyptian Exchange (EGX), US
stocks (NYSE, Nasdaq and ETFs, through Alpaca) and the Abu Dhabi Securities Exchange (ADX), with two
interfaces that offer **exactly the same use cases**:
- **`thndr-mcp`**: a [Model Context Protocol](https://modelcontextprotocol.io) server. Ask Claude about your
portfolio, orders, the market, price history, order books and your trading journal, and manage watchlists and
price alerts.
- **`thndr`**: a command-line interface for the same use cases, for humans and scripts (`--json` for machine
output).
Both are generated from the same list of use-case classes and run them through one shared path
([ADR 0012](docs/adr/0012-use-case-classes-shared-by-mcp-and-cli.md)). They share one login session
([ADR 0013](docs/adr/0013-persisted-login-flow-and-shared-session.md)).
> Thndr publishes no API. This project uses the private API of Thndr's own web platform
> [ThndrX](https://x.thndr.app), reverse-engineered from its public JavaScript (see [`docs/api`](docs/api)). It is
> not affiliated with or endorsed by Thndr. It may break when Thndr changes things. See the [Disclaimer](#disclaimer).
**Currently read-only for money ([ADR 0006](docs/adr/0006-trading-safety.md)):** neither interface places, modifies or cancels
orders and never moves funds. Trade in the Thndr app.
## Requirements
- Node.js ≥ 20 (`.nvmrc` pins 22 for development: `nvm use`)
- A Thndr account with the **Thndr mobile app logged in on your phone** (needed to approve logins)
- Access to ThndrX (it currently requires a *Thndr Trader* subscription)
## Install
thndr-mcp installs straight from GitHub (an npm package will follow); you need Node.js ≥ 20. `npx` downloads and
builds it on first use, so there is nothing to clone.
### Claude Code
```bash
claude mcp add thndr -- npx -y github:armaaar/thndr-mcp
```
### Claude Desktop
Add to `claude_desktop_config.json` (Settings → Developer → Edit Config) and restart Claude Desktop:
```json
{
"mcpServers": {
"thndr": { "command": "npx", "args": ["-y", "github:armaaar/thndr-mcp"] }
}
}
```
Any other MCP client that runs local stdio servers works the same way: command `npx`, arguments
`-y github:armaaar/thndr-mcp`.
### Pin a version
`github:armaaar/thndr-mcp` follows the `main` branch. To pin a [release](https://github.com/armaaar/thndr-mcp/releases),
use its tag — e.g. `github:armaaar/thndr-mcp#v0.1.0` — or the prebuilt package attached to every release, which starts
faster because nothing is built:
```bash
claude mcp add thndr -- npx -y https://github.com/armaaar/thndr-mcp/releases/download/v0.1.0/thndr-mcp-0.1.0.tgz
```
The [CHANGELOG](CHANGELOG.md) lists what changed in each version.
### First use
Ask your assistant something like "how is my Thndr portfolio doing?". The first tool call opens a login page in your
browser: enter your email and the code Thndr emails you, then approve the login with the QR code in the Thndr mobile
app. The session is stored on your computer (see [Logging in](#logging-in)).
### From source
```bash
git clone https://github.com/armaaar/thndr-mcp && cd thndr-mcp
npm install && npm run build
npm link # optional: puts `thndr` and `thndr-mcp` on your PATH
claude mcp add thndr -- node "$PWD/dist/thndr-mcp.js"
```
Inside this repository the bundled [`.mcp.json`](.mcp.json) already registers the server in dev mode.
### CLI
Run it without installing (`npx -y -p github:armaaar/thndr-mcp thndr help`), or install it once with
`npm install -g github:armaaar/thndr-mcp`:
```bash
thndr help # every command, grouped by bounded context
thndr login # guided login (email code + approve on your phone)
thndr get-account-summary
thndr get-price-snapshot COMI HRHO ETEL
thndr get-price-history COMI --resolution 1d --bars 30
thndr screen-market --sector Banks --sort-by value --limit 10
thndr get-account-orders --status open --json # same JSON the MCP tool returns
thndr create-alert COMI 95.5
thndr get-price-history --help # arguments of any command
```
Every MCP tool `x_y_z` is the CLI command `thndr x-y-z`. Tool arguments are camelCase (e.g. `sortBy`,
`timeoutSeconds`) and become `--kebab-case` flags on the CLI (`--sort-by`, `--timeout-seconds`); arrays may be
repeated or comma-separated, and a few commands also take positional arguments (`thndr get-price-snapshot COMI HRHO`).
Exit codes: `0` ok, `1` use-case error, `2` invalid usage or input.
## Logging in
Thndr logins need two factors, just like ThndrX:
1. A 6-digit code sent to your Thndr email.
2. Approval of the login request **in the Thndr mobile app**.
You can do it from the terminal:
```bash
thndr login # or step by step: thndr login-start you@example.com → thndr login-verify-code 123456 → thndr login-complete
```
…or just ask Claude for what you want ("how is my portfolio doing?"). If you are not logged in, the MCP server opens
a login page in your browser: enter your email and the emailed code, then scan the QR code with your phone and approve
the login in the Thndr app (Thndr sends no notification for it). The request then completes on its own
([ADR 0016](docs/adr/0016-login-on-demand-via-mcp-elicitation.md), [ADR 0017](docs/adr/0017-browser-login-page.md)).
The page runs on `127.0.0.1` and talks only to the local server, so your code never passes through Claude. This works
in any MCP client that runs local servers (Claude Code, Claude Desktop, …). If the client stops waiting, finish the
page and ask again. The session is renewed automatically; when it finally expires you are only asked to approve once
more on your phone (no new email code).
Without a browser on the machine (SSH, containers), use `thndr login` in a terminal, or let Claude call `login_start`
→ `login_verify_code` → (you approve on your phone) → `login_complete`.
Accounts that only use Google/Apple sign-in can use `login_import_session` with the `Cookie` header of a logged-in
`x.thndr.app` browser session.
The session is stored in `~/.config/thndr-mcp/session.json` (mode `0600`). Delete it or call `logout` to end it.
## Use cases (MCP tools = CLI commands)
Every tool takes a `market`: `egypt` (EGX, default), `us`, `uae` or `simulator` (Thndr's paper-trading account).
Thndr offers different features per market — for example the order book, financials and whole-market screens exist only
for Egypt, and US/UAE price history is closing prices only — so a tool asked for something a market lacks answers
`FEATURE_DISABLED` and says where it is available. `get_markets` lists your markets and what works in each
([ADR 0021](docs/adr/0021-all-thndr-markets.md)).
| Area | MCP tool names (CLI uses kebab-case) |
| --- | --- |
| Session | `auth_status`, `login_start`, `login_verify_code`, `login_request_approval`, `login_complete`, `login_import_session`, `logout` |
| Market data | `search_instruments`, `get_instrument_details`, `get_price_snapshot`, `get_price_history`, `get_market_depth`, `get_recent_trades`, `get_market_status`, `screen_market`, `get_screeners`, `get_index_constituents`, `get_peers`, `get_price_performance`, `get_financials`, `get_news`, `get_economic_indicators`, `get_markets`, `get_market_movers`, `get_trending`, `get_tags`, `get_tag_instruments`, `get_dividends` |
| Portfolio | `get_account_summary`, `get_account_positions`, `get_position`, `get_account_orders`, `get_realized_returns`, `get_closed_trades`, `get_sell_journal`, `get_trading_metrics`, `get_account_activity`, `get_portfolio_allocation`, `get_portfolio_performance`, `get_savings` |
| Engagement | `get_watchlists`, `get_watchlist`, `create_watchlist`, `edit_watchlist`, `delete_watchlist`, `get_alerts`, `get_alert`, `create_alert`, `update_alert`, `delete_alert`, `get_notifications`, `mark_notifications_read` |
Tool names follow the [IBKR MCP](docs/adr/0008-ibkr-mcp-as-reference.md) where Thndr has an equivalent. Commands
(create, edit, delete, mark read, login steps) return a short receipt — ids, flags and a message — rather than the
full object; call the matching query to see the new state (e.g. `create_watchlist` → `get_watchlist`,
`update_alert` → `get_alert`). Details are in [`docs/use-cases`](docs/use-cases).
## Configuration
| Variable | Default | Purpose |
| --- | --- | --- |
| `THNDR_SESSION_FILE` | `~/.config/thndr-mcp/session.json` | Where credentials are stored |
| `THNDR_LANGUAGE` | `en` | `en` or `ar` for localized fields |
| `THNDR_LOG_LEVEL` | `info` | `debug`, `info`, `warn`, `error`, `silent` (logs go to stderr) |
| `THNDR_RUNTIME_VERSION` | bundled | Override the `x-thndrx-runtime-version` header |
| `THNDR_API_BASE_URL` / `THNDR_WEB_BASE_URL` | `https://prod.thndr.app` / `https://x.thndr.app/api` | API endpoints |
| `THNDR_USER_AGENT` | Chrome-like | User agent of HTTP requests to Thndr |
| `THNDR_DEVICE_NAME` | `thndr-mcp` | Device name in the login approval link (shown as a QR code; keep it short) |
## Development
```bash
npm run dev # MCP server over stdio with tsx
npm run cli -- help # CLI with tsx
npm run check # typecheck + lint + tests with coverage gate (> 95%)
npm run sync:api # re-download ThndrX and regenerate docs/api/endpoints.generated.md
npm run capture:fixtures # (logged in) capture real response shapes to .cache/fixtures
```
Architecture: Domain-Driven Design in five Clean Architecture layers with Command–Query Separation and an enforced
context map ([ADR 0015](docs/adr/0015-five-layer-clean-architecture-cqs-and-context-map.md)): `src/domain` (entities,
value objects, repository interfaces, shared kernel) ← `src/application` (use-case classes extending `Query` /
`Command`, [ADR 0012](docs/adr/0012-use-case-classes-shared-by-mcp-and-cli.md); application services; ports) ←
`src/repositories` (repository implementations, translators) → `src/data-sources` (Thndr HTTP client and DTOs,
Firebase, session file, logging), and `src/presentation` (presenters, MCP and CLI apps). The rules are checked by
`src/__tests__/architecture.test.ts`. `npm run build` bundles the two binaries with tsup
(`dist/thndr-mcp.js`, `dist/thndr.js`; [ADR 0014](docs/adr/0014-extensionless-imports-and-bundled-build.md)).
See [`docs/`](docs/README.md) for ADRs, domain models, use cases and the API specs, and [`CLAUDE.md`](CLAUDE.md) for
contributor rules.
## Disclaimer
**Unofficial project.** thndr-mcp is an independent, community, open-source project. It is not affiliated with,
endorsed, sponsored or supported by Thndr (Thndr Technology Holding, Thndr Securities Brokerage), Axis Markets, Alpaca
Securities LLC, the Egyptian Exchange (EGX), Egypt's Financial Regulatory Authority (FRA), the Abu Dhabi Securities
Exchange (ADX) or Anthropic. All names and trademarks belong to their owners and are used only to identify the
services this software works with.
**Not financial advice.** Nothing this software produces — data, calculations, or anything an AI assistant generates
from them — is financial, investment, tax or legal advice, or a recommendation to buy, sell or hold any security. The
maintainers and contributors are not licensed brokers or investment advisers. Investing carries risk, including the
loss of capital. Do your own research and consult a licensed professional.
**AI output can be wrong.** AI assistants can misread data, invent figures or draw wrong conclusions. Check everything
in the official Thndr app before you act.
**No warranty; use at your own risk.** The software is provided "AS IS", without warranty of any kind (see
[LICENSE](LICENSE)). It relies on a private, undocumented API that Thndr may change, limit or block at any time. Data
may be incomplete, delayed, wrong or unavailable. To the maximum extent permitted by applicable law, the maintainers
and contributors are not liable for any loss or damage arising from the software or its use, including trading or
investment losses, lost profits, decisions based on its output, data errors, delays, outages, and any restriction,
suspension or closure of your account or other action by Thndr or any third party.
**Your responsibility.** You alone are responsible for how you use this software. You must comply with Thndr's terms
and client agreements and with the securities laws and regulations that apply to you. Using an unofficial client may
breach your broker's terms.
**Interoperability.** The API was learned by observing Thndr's own web and mobile apps, used with the maintainers' own
accounts, solely so that independently written software can work with Thndr. thndr-mcp accesses only your own
account, with your own credentials. This repository contains no copy of Thndr's apps; `docs/api` quotes only short
excerpts of client code where they are needed to describe the interface.
**Privacy.** thndr-mcp runs on your computer and sends nothing to the maintainers. It talks to Thndr and its service
providers. Data you ask an AI assistant to analyse goes to that assistant's provider under the provider's terms. Your
session token is stored locally: protect it like a password.
The same text is in [DISCLAIMER.md](DISCLAIMER.md).
## License
[Apache License 2.0](LICENSE). See also [NOTICE](NOTICE). Contributions are accepted under the same license
([CONTRIBUTING.md](CONTRIBUTING.md)); report vulnerabilities as described in [SECURITY.md](SECURITY.md).
TDQS
Scored across 52 tools
Most tools target distinct resources, but several clusters overlap: get_watchlist vs get_watchlists, get_alert vs get_alerts, get_index_constituents vs screen_market's index filter, and get_market_movers vs screen_market's top-gainer mode. The detailed descriptions help an agent recover, but the set still requires careful reading to avoid misselection.
The set is predominantly snake_case with a predictable verb_noun or get_/create_/update_/delete_ prefix pattern. A few outliers like auth_status (noun-only) and logout (verb-only) are minor deviations rather than a broken convention.
With 52 tools this server is far beyond the typical well-scoped 3-15 range and exceeds even the '25+ too many' threshold. Although many tools serve real subdomains, the sheer surface size creates an extreme mismatch for an agent to navigate.
Read-side coverage is broad and CRUD is complete for watchlists and alerts, with full auth and account analysis. However, the surface has notable gaps for a trading integration: no order placement/change/cancel and no savings transfers, both explicitly excluded as read-only.