v2.0.0
The data flows out. Orders don't go in.
ibkr is a read-only interface to your Interactive Brokers account, reachable from a Go library, a shell CLI, a stdio MCP server (Claude Desktop, Cursor, Continue, Zed), and a Claude Code plugin. Hand it to an assistant, a cron job, a notebook, or your own service.
What's new in v2.0.0
- v2.0.0 is a Go-library major, not a product rewrite. The
ibkrCLI, daemon, MCP tools, and paired app behave the same as v1.15 plus the improvements below; the major bump exists because the publishedpkg/ibkrGo API modernized in one breaking pass (context-first methods, noGetprefixes — details under Changed) and Go-module semver therefore requires the module path to move togithub.com/osauer/ibkr/v2. Action required only for Go developers importing the library: update imports togithub.com/osauer/ibkr/v2/pkg/ibkrand installs togo install github.com/osauer/ibkr/v2/cmd/ibkr@latest. Binary, MCPB, and plugin users are unaffected. - Trading rulebook v2, from the 2026-07-08 dual senior review against a live confirmed-stress tape. The checklist grows from 12 to 14 rules: rule 13
exit_disciplinefences long-option losses at −40% of premium paid (watch) / −60% (act), with classified hedge legs exempt — the hedge is allowed to decay — and an advisory preview warning when a draft would average down into a flagged line (averaging down resets the basis; the fence does not follow it down). Rule 14fx_exposuremakes non-base-currency NLV explicit (watch-only above 60% — a structural breach must inform, not become a permanently lit act). Rules 3/4/12 thresholds are now regime-conditional: the daemon latches the regime lifecycle stage (persisted across restarts, so a bounce mid-stress cannot reset thresholds to calm), buckets it calm / early_warning / confirmed (cash floor −25/0/+10% of NLV; ex-hedge extrinsic budget 10-15/7.5-12/5-10%; hedge band 25-35/30-50/40-70%), and a carried or never-seen stage evaluates BOTH the carried and calm sets and reports the worse verdict — stale regime data can hold or tighten a verdict, never relax it, in either band direction. Partial data may now indict but never acquit: rule 1 reports provable lower-bound breaches ("at least X% of NLV",observed_is_lower_bound) from signed interval arithmetic when deltas are missing, instead of hiding a certain breach behindunknown.
Claude Desktop MCPB
Download ibkr.mcpb from the Assets section below or from:
https://github.com/osauer/ibkr/releases/latest/download/ibkr.mcpb
Open the .mcpb file with Claude Desktop, drag it into Claude Desktop, or use Settings -> Extensions -> Advanced settings -> Install Extension. The bundle carries the local ibkr binary for macOS and Linux. Windows is not supported outside WSL because the daemon uses Unix-only primitives.
Shell and generic MCP install
curl -fsSL https://raw.githubusercontent.com/osauer/ibkr/main/install.sh | sh
ibkr setup claude-desktopThe first command picks the right binary for your platform, verifies its SHA-256, installs it to ~/.local/bin/ibkr, and adds that directory to your PATH if needed. On macOS it also clears the Gatekeeper quarantine flag. The second command writes the legacy MCP server entry into Claude Desktop's config; fully quit Claude Desktop and reopen.
If you only want the shell tool, stop after the first command and try:
ibkr account
ibkr quote AAPL
ibkr positions --by underlyingPrerequisite: a running IB Gateway 10.37+ or TWS (paper or live) on the same machine. The daemon auto-discovers it across the four standard ports.
See the README for the full feature menu and the troubleshooting matrix. Read-only by construction; the Safety section walks through the four guards.
⚠️ Broker-write capable build (ibkr-trading-* tarballs)
Everything above — the installer, the MCPB bundle, and the plain ibkr-v2.0.0-* tarballs — is read-only by construction: order transmission is not compiled in.
The ibkr-trading-v2.0.0-* tarballs are different: that binary can place, modify, and cancel orders with your broker once you configure the trading gates ([trading] mode plus a pinned gateway endpoint and account, cross-checked against the connected session; every write still needs a submit-eligible preview token). Only download it if you intend to trade through ibkr. Before enabling anything, read SECURITY.md and the trading preview guide, start against a paper account, and verify with ibkr trading status. Each release's order pipeline is exercised by an automated paper-trading round-trip before tagging.
Paranoid? Inspect the installer before running it
curl -fsSL https://raw.githubusercontent.com/osauer/ibkr/main/install.sh -o install.sh
less install.sh
sh install.shDoing something custom?
go install:go install github.com/osauer/ibkr/v2/cmd/ibkr@v2.0.0(or@latest).- Different install dir:
IBKR_INSTALL_DIR=/usr/local/bin sh install.sh. The installer won't touch your shell rc when you override; manage PATH yourself. - Manual download: pick a tarball or
.mcpbfrom the Assets section below. Verify againstSHA256SUMS. - Cursor / Continue / Zed / other local MCP clients: see Pick your path in the README for the JSON snippet (config file path differs per client).
- Claude Code:
/plugin marketplace add osauer/ibkrthen/plugin install ibkr@ibkrinside any session.
Windows isn't supported. The daemon uses Unix-only primitives (setsid, flock, AF_UNIX sockets). WSL works.
Added
- Rule 2 hedge-premium tier: option lines classified as rule-12 hedges measure against 15%/25% of NLV instead of the 5%/10% speculative tier, disclosed per offender — the designated hedge no longer tops the premium list every single day (alarm-fatigue fix), while rule 12 gains an act tier at more than twice the band top ("a directional short wearing a hedge's clothing"). The two changes ship atomically: a hedge past twice the band top always keeps an act somewhere.
- Rule 7 now covers short puts spanning an earnings print: watch by default, act when the line's assignment notional reaches 10% of NLV (or a name's spanning short puts together reach 20%) — a gap through the strike is a forced size-up on earnings day.
- Option legs whose greeks tick carried no underlying spot now borrow the same-name stock leg's account mark (disclosed as
stock_leg_mark, quality-gated, never classifying hedge legs), so rules 4 and 6 evaluate pre-market for stock-backed names instead of reporting unknown until the option surface opens. - The rules result's
input_healthgains aregime_stagerow; row notes disclose which regime threshold set applied and why.
Fixed
- Rule 6 (
catalyst_coverage) could assert pass with every option leg's OTM-ness unassessable: legs with no underlying spot were silently skipped, so pre-market the rule passed a book holding an OTM call that expires five days before its name's earnings — a live violation of the never-false-pass invariant, observed 2026-07-08. Such legs are now named unknowns, and the property test covers per-leg nil underlying with healthy positions. - Rule 8 (
earnings_size_freeze) had the same silent-skip shape: names with material greeks gaps were dropped from the sweep entirely, letting the rule pass while rule 1 reported the same name unknown. Gapped names now stay unknown offenders unless earnings are provably beyond the freeze window. - The rules-decisions journal now creates its state directory before appending (matches the order/regime journals); previously a missing
~/.local/state/ibkr/made journaling silently no-op. - Gateway-down reconnect attempts are now paced by an exponential backoff (1s→2s→4s→8s, capped at 15s), and the per-attempt "connection failed" line dropped from Error to Debug. Reconnection is demand-driven — every read handler that finds the connector down triggers one — and a refused dial returns instantly, so a multi-hour outage retried ~2.6×/s and wrote 66,900 identical
connection refusedlines toibkr-daemon.logover a single 7h gateway outage (observed 2026-07-08). The streak resets on a completed handshake and stays exempt on the first attempt, so a fresh drop still reconnects immediately; the 15s cap stays below the CLI's 25sibkr statushandshake wait, so a Gateway→TWS switch still recovers in one invocation.
Changed
- Breaking —
pkg/ibkrGo API, and the module path is nowgithub.com/osauer/ibkr/v2. The published client library dropped its pre-context idioms in one pass; theibkrCLI, daemon, MCP, and app surfaces are unaffected. Accessors lose theGetprefix (CachedPositions,OptionIV,OptionGreeks,OptionUnderlyingPrice,OptionQuoteBidAsk,OptionPrevClose,MarketDataTypeForSymbol,Connection.MarketDataType), andGetMarketDatais nowMarketDataSnapshot— the bare name would collide with theMarketDatatype. The fiveX/XCtxmethod pairs collapsed to one ctx-first method each:FetchHistoricalDailyBars(ctx, symbol, lookbackDays, timeout),FetchHistoricalDailyBarsWhatToShow(ctx, symbol, lookbackDays, whatToShow, timeout),FetchHistoricalDailyBarsWithContract(ctx, contract, lookbackDays, timeout)— timeout ≤ 0 keeps the 45 s default, and a ctx deadline always caps the effective budget — plusConnection.RequestHistoricalData(ctx, …)andConnection.CancelHistoricalData(ctx, reqID). Nil contexts are no longer tolerated (the 21 per-methodctx == nilguards are gone; passcontext.Background()explicitly). The unusedOrderstruct left the public surface (internaltrackedOrdernow);IBKROrderstays the wire type and theOrderSide/OrderType/TimeInForce/OrderStatusenums are unchanged. - Rulebook policy
rulebook-v1→rulebook-v2(version 2): every new threshold is part of the policy fingerprint, and the flat rule-3/4/12 threshold fields moved into the three regime sets (the calm set carries the v1 numbers unchanged). - Design doc corrected where it had drifted from the implementation: the rules-decisions journal lives under
~/.local/state/ibkr/, rules 9/10 read a dedicated best-effort SPY snapshot quote (not the regime snapshot), and the operator TOML policy override is documented as planned, not shipped.
Engineering notes
- Repo-wide taste-review pass (2026-07-11), no behavior or rendered-output changes: the ±2% dealer-gamma band and its gap→regime classifier now live once in
internal/rpc/regime_policy.go(GammaRegimeFromGap,GammaBucketRegime,HeuristicThresholds) instead of six hand-coded copies across daemon and CLI — the same single-copy treatment the 2026-06-12 incident forced on regime headlines; fixed-fractional sizing moved from the CLI adapter intointernal/risk(risk.ComputeSize), so MCP no longer imports a sibling adapter for policy math;computeGammaZeroFordecomposed from 604 to 399 lines (contract prewarm and leg fan-out extracted with their abort machinery); dead SPA CSS and an inertIBKR_HANDSHAKE_PERMISSIVEtest knob deleted.