Skip to main content
Glama
diofthecr3ed

Broker-mcp

by diofthecr3ed

Broker-mcp — Broker MCP Server (Phase 1 · read-only · stdio)

A first-party Model Context Protocol server that connects a customer's Broker (Broker by Parent Company) trading account to any MCP-compatible AI client — Claude Desktop, Cursor, VS Code and others. Built to PRD v1.3 ("Broker MCP — Product Requirements Document"), this is the Phase 1 deliverable: read-only, local (stdio) only.

This server cannot trade. Order placement/modification/cancellation tools are not merely disabled — they do not exist in this codebase (FR-G1, the Zerodha excluded-tools pattern). Nothing here can change account state at Broker, move funds, or sell holdings. Phase 2 (trade tools behind guardrails) is a separate, compliance-gated build.


1. What is implemented (PRD traceability)

Tools (21, all annotated readOnlyHint for account data)

Tool

What it does

PRD

get_login_url / complete_login / session_status / logout

Daily login handoff: browser link → Broker's own login page → one-time request token → encrypted local session

FR-A1–A5

get_profile

Account profile

FR-R1

get_margins

Equity + commodity funds/margins (optionally per segment)

FR-R1

get_holdings

Demat holdings with avg cost, LTP, day & overall P&L

FR-R2

get_positions

Net + day positions with P&L

FR-R2

get_ltp / get_ohlc / get_quote

Prices for many instruments; batch limits 1,000 / 1,000 / 500 enforced with transparent chunking

FR-R3, V3

resolve_symbol

"BANKNIFTY next expiry 52000 CE" → exactly one instrument, or candidates to disambiguate (never guesses)

FR-R4, V2

get_expiries / get_option_chain

Option expiries and chain (strikes × LTP/OI/volume/bid/ask around ATM). Greeks/IV honestly reported as unavailable

FR-R5

get_historical

Daily/intraday candles (8 documented intervals) with range guards

FR-R6

get_orders / get_order / get_trades

Order book, order history, trade book — read only

FR-R7

calculate_margin

Pre-trade margin for hypothetical orders; uses Broker's margin API when live, else a clearly-labelled rough estimate

FR-R8

server_status / refresh_instruments

Diagnostics, per-tool metrics, instrument-master refresh

FR-O4, V2

Guardrails & controls in this build

  • Read-only by construction — no write tool registered anywhere (FR-G1; guardrail stage 3).

  • Audit trail — every tool call written to append-only JSONL with UTC timestamp, unique correlation ID (mcp-…), user id, redacted arguments, outcome and latency (FR-G7; stage 10). Location: <data dir>/audit/audit-YYYYMMDD.jsonl.

  • Assistant framing — server instructions and tool descriptions state: knowledgeable assistant, not an autonomous trader; no Broker-authored advice; never fabricate Greeks/IV; credentials only on Broker's own pages (FR-G8, R7 mitigation).

  • Readable errors — raw 4xx/5xx bodies never reach the model; failures follow the PRD §4.7 message patterns ("Your Broker session has expired — reconnect to continue", "Insufficient margin…", "I couldn't find that contract — did you mean…") (FR-O1).

  • Rate limiting — client-side token bucket (default 3 req/s, far below anything order-loop shaped) plus exponential backoff and a readable message on upstream 429 (FR-O2). Broker publishes no rate limits; the cap is deliberately conservative.

  • Timestamps + source labels — every response is wrapped in an envelope with as_of_utc, as_of_ist, a data_source label ("point-in-time snapshot, not a live stream" / "MOCK SANDBOX DATA") and a market-session hint (FR-O3).

  • Token security — the daily access token is stored only on the user's machine, encrypted at rest (Fernet), never transmitted to any Broker-hosted MCP infrastructure (none exists in Phase 1). Corrupt stores are discarded, forcing a clean reconnect (FR-A5). Daily expiry is handled gracefully with a reconnect prompt (FR-A4).

  • Input validation — typed schemas on every tool (pydantic), field-level rejection messages (V1); instrument references must resolve to exactly one contract or the tool asks (V2); batch limits chunked transparently (V3); session freshness checked at call time (V14).

Verification status (FR-O6)

  • 57 unit tests, all passing (pytest): schemas, chunking, symbol-resolution grammar, option chain composition, error translation, token-store encryption round-trip, audit redaction, plus end-to-end tool calls through the real FastMCP layer.

  • stdio protocol smoke test passing: the server was spawned by a real MCP client (mcp.client.stdio), initialized (protocol 2025-11-25), tools listed with annotations, tools called, error paths exercised — the equivalent of the MCP Inspector check the PRD requires before client wiring.

  • A multi-agent adversarial code review (PRD-compliance / correctness / security / SDK-usage) was run on this codebase; confirmed findings were fixed.


Related MCP server: Forgeline

2. What works right now vs. what is gated

Works today, no dependencies: mock sandbox mode

Broker_MCP_MODE=mock (or Broker-mcp --mock) runs the full server against a deterministic built-in sandbox — no credentials, no network. Every tool works: a realistic instrument master (NIFTY/BANKNIFTY option chains, equities, futures), holdings, positions, an order book with COMPLETE/OPEN/REJECTED orders, historical candles. All responses are loudly labelled "MOCK SANDBOX DATA — synthetic values… NOT real market data." This is the evaluation, demo and client-integration surface, and it satisfies the PRD's sandbox-before-live posture.

Live mode — gated on the Broker open-API programme reaching GA

The live client is fully implemented against the verified Broker API surface (checked 19 Jul 2026 against developer.Broker.in and the official PyBrokerAPI SDK source): host api.Broker.in, Authorization: token api_key:access_token, checksum-based token exchange, gzipped daily instruments CSV, quote batch limits, historical intervals. To go live you need, from the Broker Developer Portal: an app (API key + secret) with its redirect URL and static IPs registered — i.e. Phase 0 of the PRD ("open APIs at GA") must be true for the account. Until then, live calls fail with readable configuration/session errors.

Known open items (flagged in code, degrade gracefully)

Item

Status

Behaviour today

POST /optionchain, /optionchain/expirylist

In the official SDK, not on the docs site — PRD says confirm GA with API team

Tried first; on failure the chain is composed from instrument master + batched quotes (OI/volume live, Greeks/IV honestly absent)

POST /margins/orders, /margins/basket

Same "confirm GA" flag

Tried first; falls back to a clearly-labelled rough estimate (authoritative: false)

Access-token expiry time

Broker's own docs contradict themselves (12 AM vs 6 AM IST)

Session marked suspect after midnight, expired at 6 AM; the API's own 401 always wins and produces a reconnect prompt

API version header

Docs majority X-Version: 3, SDK sends X-Broker-Version: 3

Both sent; smoke-test at GA

Rate limits

Not documented by Broker anywhere

Conservative client-side cap (3 req/s)

Refresh-token / connect-once UX (PRD Q5)

Open decision for API/Security

Not built; daily reconnect flow implemented


3. Quickstart

Windows (PowerShell):

cd Broker-mcp
python -m venv .venv
.venv\Scripts\python -m pip install -e ".[dev]"
.venv\Scripts\python .venv\Scripts\pywin32_postinstall.py -install   # required: places pywin32 DLLs
.venv\Scripts\python -m pytest                                       # 57 tests
.venv\Scripts\Broker-mcp --mock                                      # run the server (stdio) in sandbox mode

The pywin32_postinstall step is required on Windows: the official mcp SDK imports pywintypes for its stdio transport, and pip alone does not always place the loader DLL. Skip it and both pytest and the server fail with ImportError: DLL load failed while importing _win32sysloader. The COM-registration warnings it prints (needs admin) are harmless.

macOS / Linux:

cd Broker-mcp
python -m venv .venv
.venv/bin/python -m pip install -e ".[dev]"
.venv/bin/python -m pytest            # 57 tests
.venv/bin/Broker-mcp --mock           # run the server (stdio) in sandbox mode

Note: the running server prints nothing and waits silently — that is correct. An MCP stdio server is not a REPL; it waits for a client (Claude Desktop, Inspector) to speak JSON-RPC on stdin. Press Ctrl+C to stop it. Clients launch their own copy of the server; you do not run it by hand for them.

Troubleshooting the environment

Symptom

Cause

Fix

ModuleNotFoundError: No module named 'pydantic_core._pydantic_core' (or a stale *.cp3XX-win_amd64.pyd for the wrong version)

The .venv mixes wheels built for a different Python (e.g. a 3.12 wheel under a 3.13 interpreter — often from a venv reused after a Python upgrade)

Recreate the venv with the current Python: delete .venv, then repeat the steps above. Quick check: .venv\Scripts\python --version must match the cp3XX tag on the .pyd files in .venv\Lib\site-packages\pydantic_core\.

ImportError: DLL load failed while importing _win32sysloader

The pywin32 post-install step was skipped

Run .venv\Scripts\python .venv\Scripts\pywin32_postinstall.py -install

Claude Desktop (mock sandbox — works immediately)

%APPDATA%\Claude\claude_desktop_config.json:

{
  "mcpServers": {
    "Broker": {
      "command": "C:\\path\\to\\Broker-mcp\\.venv\\Scripts\\Broker-mcp.exe",
      "args": ["--mock"]
    }
  }
}

Claude Desktop (live)

{
  "mcpServers": {
    "Broker": {
      "command": "C:\\path\\to\\Broker-mcp\\.venv\\Scripts\\Broker-mcp.exe",
      "env": {
        "Broker_API_KEY": "your_app_api_key",
        "Broker_API_SECRET": "your_app_api_secret"
      }
    }
  }
}

Then in chat: "Connect my Broker account" → the assistant calls get_login_url, you log in on Broker's own page (mobile + OTP + MPIN — never in the chat), copy the request_token from the redirect URL, and say "complete login with token …". The session lasts until the daily regulatory expiry; the server prompts to reconnect after that.

Cursor and VS Code configs, plus sample prompts: docs/client-setup.md and docs/sample-prompts.md.

Test it end-to-end (mock mode — no credentials)

Two ways, quickest first.

MCP Inspector — a browser UI to click each tool and inspect raw responses. Best for methodical tool-by-tool testing; needs Node.js.

npx @modelcontextprotocol/inspector .venv\Scripts\Broker-mcp.exe --mock

It prints a http://localhost:… URL. Open it → ConnectTools tab → pick a tool (e.g. get_holdings) → Run Tool. The Inspector launches and talks to the server for you.

Claude Desktop — the real client experience:

  1. Add the mock config above to %APPDATA%\Claude\claude_desktop_config.json (merge into any existing mcpServers block — don't overwrite the file).

  2. Fully quit Claude Desktop from the system-tray icon (right-click → Quit) — closing the window is not enough; it keeps running in the tray and won't reload the config.

  3. Reopen Claude Desktop, start a new chat, click the tools icon in the input box — Broker should appear with 21 tools.

  4. Ask a sample prompt; approve the tool-use prompt the first time it fires:

    • "How is my portfolio doing today?" → holdings, labelled MOCK SANDBOX DATA

    • "Show the NIFTY option chain for the nearest expiry" → chain with OI/volume; Greeks/IV honestly absent

    • "Buy 2 lots of NIFTY futures" → refused (no order tools exist in Phase 1 — proves read-only)

You do not start the server yourself for a client — each client (Claude Desktop, Inspector) launches its own copy from the command path. If Broker does not appear, check %APPDATA%\Claude\logs\mcp-server-Broker.log. More prompts: docs/sample-prompts.md.


4. Regulatory position — read before any real-world use

This section is a product-level summary of PRD §8. It is not legal advice. Phase 1 must not be offered to customers until Broker Compliance & Legal have signed off.

Why Phase 1 (this build) is the low-risk posture

Read-only tools never touch order routing, so under SEBI's algo-trading framework (circular of 4 Feb 2025, fully mandatory since 1 Apr 2026) no Algo-ID tagging, no algo registration and no Research-Analyst question arises — there are no orders. Phase 1 rides on the controls the Broker open-API programme itself must already satisfy (client-specific API keys, OAuth + 2FA, static-IP whitelisting, 5-year audit, VAPT). Six brokers (Zerodha, 5paisa, Groww, Dhan, FYERS, Upstox) already operate official MCPs; the read-only posture matches Zerodha/Upstox/FYERS.

Approvals required BEFORE customer launch of this read-only build

#

Approval / action

Who grants it

Status

1

Broker open APIs at GA, SEBI-compliant (static IP, OAuth 2.1, 2FA, audit, VAPT) — the gating dependency the MCP inherits

Exchanges (NSE/BSE/MCX) via the existing API-programme approval; owned by API/infra teams

Gating — outside this repo

2

Standard API review for the MCP as an API client of that programme

Broker internal (API team + Compliance)

Required

3

Consent & disclosure language shown at connection (read scopes, risk/non-advice statement, fee disclosure)

Broker Compliance, against SEBI + exchange norms

Required — copy in this repo is engineering draft only

4

Confirmation of the "confirm with API team" endpoints and the token-expiry time

Broker API team

Required before customer docs

5

5-year retention pipeline for the audit logs this server writes

Broker ops/compliance

Required (server writes the records; retention is operational)

Additionally required before Phase 2 (trade tools — NOT in this build)

  • Written confirmation that a human-confirmed, sub-10-orders/sec, user-instructed MCP order is ordinary API trading, not a registrable algo (PRD Q2) — Compliance/Legal, with NSE/BSE if needed.

  • Written comfort that an LLM in the order path does not trigger black-box-algo / RA-licence duties (PRD Q3).

  • Exchange Algo-ID tagging, static-IP enforcement on the write path, mock/simulation session sign-off, sandbox order-path testing, kill switch, idempotency chaos-tests, 100% confirmation coverage.

  • Any material change to an approved order flow requires fresh review.

And before any hosted (Phase 3) endpoint

Security review + external VAPT by a CERT-In-empanelled auditor, plus resolution of how a hosted endpoint satisfies static-IP requirements for writes (may end up read-only-hosted). This build deliberately ships no network listener — stdio only.

Standing non-goals baked into this build

No autonomous trading, no order loops, no Broker-authored advice or strategy, no bespoke LLM. The model analyses the user's own data at the user's explicit request.


5. Architecture

AI client (Claude/Cursor/VS Code)
        │ stdio (JSON-RPC, MCP)
        ▼
Broker-mcp  ──  server.py     FastMCP tools · audit shell · readable errors
                session.py    login handoff · encrypted token store · daily expiry
                backend.py    LiveBackend (api.Broker.in) ⇄ MockBackend (sandbox)
                instruments.py daily master cache · symbol resolution · chain composition
                ratelimit.py  token bucket + backoff      audit.py  JSONL + metrics
                routes.py     every endpoint path, with confirm-GA flags
        │ HTTPS (Authorization: token api_key:access_token)
        ▼
api.Broker.in  (the SEBI-compliant Broker open-API gateway — static IP, 2FA,
                Algo-ID machinery all live there; the MCP never bypasses it)

Data locations (per-user, overridable via Broker_MCP_DATA_DIR):

  • Encrypted session: <data dir>/session.enc + local key token.key

  • Instrument cache: <cache dir>/instruments-YYYYMMDD.csv

  • Audit log: <data dir>/audit/audit-YYYYMMDD.jsonl (ship to WORM storage for the 5-year SEBI retention)

6. Configuration reference

Env var

Meaning

Default

Broker_API_KEY / Broker_API_SECRET

App credentials from the Broker Developer Portal

— (required for live)

Broker_ACCESS_TOKEN

Directly inject a daily access token (skips login flow)

Broker_MCP_MODE

live or mock

live

Broker_BASE_URL

Override API host (e.g. UAT)

https://api.Broker.in

Broker_MCP_DATA_DIR

Session/audit/cache location

OS per-user data dir

Broker_MCP_LOG_LEVEL

Server log level

INFO

7. Development

.venv\Scripts\python -m pytest -v          # test suite
npx @modelcontextprotocol/inspector .venv\Scripts\Broker-mcp.exe --mock   # MCP Inspector

Layout: src/Broker_mcp/ (see §5), tests/ (57 tests), docs/ (client setup, sample prompts). Python ≥3.10. Dependencies: mcp (official SDK), httpx, pydantic, cryptography, platformdirs.

8. FAQ

What does it mean for the server to "run"?

An MCP server is not a web app you open in a browser, and not a program with a menu you type commands into. It is a small process that speaks JSON-RPC over stdio (standard input/output). "Running" means: the process has started and is blocked, waiting for an AI client to send it a message on stdin. It prints nothing and does nothing on its own — a silent, blinking cursor is the correct running state, not a hang.

You will almost never start it yourself. Each AI client (Claude Desktop, Cursor, VS Code, the MCP Inspector) launches its own copy from the command path in its config, exchanges JSON-RPC messages with it (initializetools/listtools/call), and shuts it down when you close the client. When you ran Broker-mcp --mock in a terminal by hand, you started an orphan copy with nothing connected to it — harmless, but it just sits there until you press Ctrl+C. The only time you launch it directly is under the MCP Inspector, which then plays the role of the client for you.

So "is the server running?" is rarely the right question — the right question is "has my client launched it and listed its tools?" (check the tools icon in Claude Desktop, or the Tools tab in the Inspector).

Will the live (real) server behave very differently from the mock sandbox?

No — not in shape or behaviour. The server is built around a single Backend interface with two implementations (LiveBackendapi.Broker.in, MockBackend → synthetic data). Every one of the 21 tools, plus input validation, symbol resolution, option-chain composition, the margin estimate, the response envelope (timestamps + source labels), the audit log, error translation and batch chunking, is backend-agnostic — the same code runs in both modes. Switching to live changes where the numbers come from, not how the server acts on them.

The mock even makes the three "confirm-GA" endpoints (option_chain, option_expiries, order_margins) fail on purpose, so the sandbox exercises the fallback paths production uses when those endpoints aren't live: the chain is composed from the instrument master + batched quotes, and margin falls back to a labelled rough estimate.

Then how close is the sandbox to the real thing — and what is untested?

Structurally it's a high-fidelity stand-in: you are testing the real server, just with synthetic numbers. What the sandbox does not exercise (these paths exist and are written to the verified Broker spec, but have never touched a real server, because none exists pre-GA):

Area

Mock today

Live reality

Data values

Toy option pricing, hash-derived OI/volume, sine-wave candles, no Greeks/IV

Real market prices; the confirm-GA endpoints may return richer data (real OI, possibly Greeks/IV, authoritative margins)

Auth

Bypassed

Real token-exchange checksum flow + Authorization: token key:token

HTTP / rate limiting

Not used

Token bucket + 429 backoff — only instantiated in LiveBackend, never hit in mock

Instruments CSV

Generated with Kite-convention columns

Real gzipped CSV — actual column names could differ

Error translation

Synthetic errors

Real error envelopes / error_type values map to the readable messages

Wire unknowns

N/A

Version header (X-Version vs X-Broker-Version — code sends both), token-expiry time, whether option-chain/margins are GA

The PRD notes the two source-of-truth documents (Broker docs vs the PyBrokerAPI SDK) do not fully agree; the live code makes defensible choices (sends both version headers, tries endpoint-then- composes) precisely so a smoke-test at GA can confirm the details. Expect a short integration pass then — it is anticipated, not a defect.

What is needed for the live (real) server to work?

  1. The gating dependency (outside this repo): Broker's open-API programme reaches GA and is SEBI-compliant for the account — PRD Phase 0. No code substitutes for this.

  2. A registered app in the Broker Developer Portal: API key + secret, a registered redirect URL, and static IPs whitelisted.

  3. Config: set Broker_API_KEY and Broker_API_SECRET in the client's env block and drop --mock (mode defaults to live). See §3 "Claude Desktop (live)".

  4. Daily login handoff: connect → get_login_url → log in on Broker's own page → copy the request_token from the redirect → complete_login. The encrypted access token lands on your machine and expires daily per SEBI rules.

  5. A live smoke-test to confirm the wire unknowns above (CSV columns, error shapes, which endpoints are GA, token-expiry time).

Why does the server print nothing / look frozen when I run it?

That is expected — see "What does it mean for the server to run?" above. It is waiting for stdin. Press Ctrl+C to stop it. To actually see it do something, use the MCP Inspector or a client.

Why can't it place trades?

By design (PRD FR-G1, Phase 1). Order-placement tools do not exist in this codebase — not disabled, absent. Nothing here can change account state. Trade tools are a separate, compliance- gated Phase 2 build. See §1 and §4.

F
license - not found
-
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    D
    maintenance
    A read-only MCP server that provides access to Charles Schwab account data and market information, including portfolio positions, real-time quotes, options chains, price history, and account balances through AI assistants.
    Last updated
    9
    MIT
  • A
    license
    A
    quality
    B
    maintenance
    Read-only Modbus TCP monitoring server that exposes safe MCP tools for AI agents to read holding/input registers, coils, and device identity from industrial devices without write access.
    Last updated
    4
    Apache 2.0
  • A
    license
    A
    quality
    C
    maintenance
    Read-only MCP server for Interactive Brokers that exposes market data, positions, and account info as MCP tools.
    Last updated
    8
    MIT
  • A
    license
    -
    quality
    D
    maintenance
    A read-only MCP server that connects to Interactive Brokers Gateway or TWS to expose account, contract, execution, and historical-data queries over stdio.
    Last updated
    7
    MIT

View all related MCP servers

Related MCP Connectors

  • MCP server exposing the Backtest360 engine API as tools for AI agents.

  • Hosted MCP for stocks, options, Greeks, brokers, order previews, alerts, and workflows.

  • Real SEC, 13F, insider, congress & macro data your AI agent can cite. Hosted MCP, 24 tools.

View all MCP Connectors

Latest Blog Posts

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/diofthecr3ed/Broker-MCP'

If you have feedback or need assistance with the MCP directory API, please join our Discord server