ibkr-risk-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| IBKR_HOST | No | Where TWS listens. A remote host must also be in the API's Trusted IPs | 127.0.0.1 |
| IBKR_PORT | No | 7496/7497 TWS live/paper, 4001/4002 Gateway live/paper | 7496 |
| IBKR_ACCOUNT | No | **Required** on a multi-account login. Without it every position/account tool refuses rather than combining accounts | |
| IBKR_CLIENT_ID | No | Must differ from every other script on this TWS. **Never 0** — TWS reserves that for orders placed by hand | 17 |
| IBKR_ENABLE_WHATIF | No | The gate on `whatif_order`. Also decides whether the connection itself is opened read-only | false |
| IBKR_GREEKS_TIMEOUT | No | Seconds to wait for greeks on one contract. Short by design — IB answers fast or never, and explicit refusals cut the wait short anyway | 4 |
| IBKR_RISK_FREE_RATE | No | Used to discount and to carry spot to the forward in the local repricing | 0.04 |
| IBKR_WHATIF_TIMEOUT | No | Seconds to wait for a what-if reply. IB sometimes never sends one | 5 |
| IBKR_CONNECT_TIMEOUT | No | Seconds for the API handshake | 6 |
| IBKR_MARKET_DATA_TYPE | No | 1 live, 2 frozen, 3 delayed, 4 delayed-frozen. 3 works and does carry greeks | 1 |
| IBKR_MAX_MKT_DATA_LINES | No | Concurrent market data subscriptions. IB allows about 50 | 40 |
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
This server publishes no instructions, or was last inspected before Glama recorded them.
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| check_connectionA | Check whether TWS or IB Gateway is reachable and an account is logged in. Call this first whenever another tool fails. It separates the four situations that all present as "cannot connect" and need different fixes:
|
| get_margin_summaryA | Margin and liquidity, split by segment. Returns NetLiquidation, EquityWithLoanValue, FullInitMarginReq,
FullMaintMarginReq, AvailableFunds, ExcessLiquidity, TotalCashValue,
BuyingPower and Leverage — each as the account total and, where IB reports
it, separately for the securities ( The segments are the point. Futures margin must be met in the commodities segment; IB covers a shortfall there by sweeping cash out of the securities segment. An account whose total excess liquidity looks healthy can still be one bad day away from a forced liquidation if the shortfall lands in commodities while securities is also falling. Report the segment figures, not only the totals, whenever futures are involved. |
| get_position_greeksA | IB's model greeks for every option position — its numbers, not ones implied locally. Returns per position: conid, symbol, secType, right, strike, lastTradeDate, settlementDate, daysToExpiry, position, multiplier, undPrice, impliedVol, delta, gamma, vega, theta, optPrice and pvDividend. Things to know about the values:
|
| get_vol_surfaceA | IB's implied volatility surface for an underlying: a grid of (expiry, strike) with impliedVol, delta, optPrice, undPrice and daysToExpiry. This is the input that makes local repricing deterministic. With IB's own volatilities in hand, a constant-volatility scenario needs no proprietary model — only Black-76 arithmetic on top of numbers IB published. Do not collapse the surface to one number. Volatility has a term structure: ES at 139 days can sit near 15% at the money while the front month prints 12%. Using the front month for a longer tenor understates a long-dated position badly. Read the tenor you need, and interpolate between tenors in total variance if you must.
Strikes with no published volatility come back under Check which instrument you got. A bare root is ambiguous: |
| stress_portfolioA | Reprice the whole portfolio — options, equities, futures — across underlying shocks and return the P&L curve and its trough. The trough is the primary output: the worst point of the curve and the
shock at which it sits. The model, returned with every result in
Check Risk Navigator's own volatility shock model is not published. |
| stress_curveA | The portfolio P&L curve under several volatility regimes at once — the data behind a risk graph, for plotting rather than for reading point by point. Risk Navigator draws two curves: a constant-volatility line and one from its
own implied-volatility model, which is not documented and cannot be
reproduced. This returns as many as you ask for, and the volatility
assumption behind each is a number in the output rather than a black box:
Read the slope-0 curve first. It is the constant-volatility case and the only one with an external check — it should sit close to Risk Navigator's blue line. If it does not, the volatility lookup is wrong and no other scenario in the result means anything. Check How each curve is built, and where it is weakest:
|
| stress_whatifA | The same stress run, with hypothetical legs added — three curves and three troughs: the portfolio as it stands, the portfolio plus the legs, and the difference. This is what replaces reading Risk Navigator's What-If by hand: "if I add N puts at strike K expiring E, where does the trough move to?" Read all three troughs. The trough of the difference is not the difference of the troughs — adding protection moves where the worst point sits as well as how deep it is, and comparing only the depths hides the move. A structure that lifts the bottom by very little may still have pushed it from −8% out to −15%, which is the part that matters. Hypothetical options are priced off IB's current model greeks for those
exact contracts, so both curves start from the same volatilities and the
difference is the structure alone. A leg that cannot be resolved or priced
is reported in With Nothing is sent to IB's order path here — this is pure local repricing. For what the structure costs in margin, use whatif_order. |
| calibrate_vol_coordA | Fit
What to do:
The fit comes back with the residual at every point and, more usefully, with what to distrust about it: the tenor range your positions actually constrain, and the most extreme volatility the fitted decay produces. A decay that reproduces the curve by pricing a wing at 150% has fitted the chart rather than the market, and it says so rather than leaving you to find out three layers down in a P&L. Unless A fit taken against a portfolio that does not reconcile is returned but
not stored. The reason is asymmetry of failure: a curve that is missing
a position announces itself through Nothing here trades or quotes. It reads positions and reprices locally. |
| whatif_orderA | IB's own margin impact for a hypothetical structure. Nothing reaches the market. Each order carries Returns initMargin, maintMargin and equityWithLoan before/after/change, plus commission and any warningText, in two views:
Read the combined figure, not the sum of the legs. SPAN offsets the legs
against each other and against what the account already holds, so the two
differ — the difference is reported as If every call fails with no margin figures, check whether TWS has "Read-Only API" enabled — that setting blocks what-if orders too. |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 9 tools
The three stress_* tools and two what-if tools live in the same conceptual neighborhood, so an agent must read carefully to pick between stress_portfolio, stress_curve, stress_whatif, and whatif_order. That said, each has a clearly distinct purpose—underlying-shock P&L, multi-volatility curves, hypothetical-leg P&L, and IB margin impact—and the descriptions draw those boundaries well.
snake_case verb_noun names are the dominant pattern (check_connection, get_margin_summary, stress_portfolio, calibrate_vol_coord), but whatif_order breaks the verb convention and the stress_/get_/whatif_ prefixes are not uniformly aligned. Still, the names are predictable enough to group and search.
Nine tools cover the server's stated risk-analysis scope without redundancy: connection health, margin, greeks, vol surface, stress curves, what-if, and calibration. Each tool occupies a distinct function and none feel like filler.
The risk workflow is well covered: users can check connectivity, inspect margin and greeks, fetch vol surfaces, stress the book, add hypothetical legs, and estimate margin impact. Minor gaps remain—there is no direct non-option position listing and no way to stress an individual underlying without running the whole portfolio—but these are workarounds rather than dead ends.