v2.1.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.1.0
- A personal risk constitution now governs capital discipline (advisory/shadow — nothing blocks orders). The operator writes every number into
~/.config/ibkr/policies/risk-policy.toml(no defaults in code): protected equity floor, declared risk capital, a two-tier drawdown ladder measured from a cash-flow-adjusted peak with a latching shadow block, one-shot expiring overrides, and reconciliation tolerances.ibkr policy show --explainrenders the whole contract in plain language. - Broker statements are ingested and reconciled daily. A
[flex]config section fetches IBKR Flex statements on a daily schedule (immutable raw retention), a recon engine matches statement flows against the declared ledger with never-false-match semantics, andibkr reconrenders the report. At policy v3, broker-confirmed flows become the authoritative capital-flow input and a fully clean, fresh report extends the reconcile clock automatically — recurring sign-off chores are retired; exceptions, and only exceptions, require the human.ibkr recon backtestreplays the full statement window (complete flow review plus capital-ladder equity replay) for validation before trust. - Agent sessions now implement through a hook-enforced Codex-only lane (
scripts/codex-implement.sh): planning, review, and integration stay in the orchestrating session, implementation runs headless in an isolated sibling worktree with fail-closed approvals, and inline code edits by agent sessions are deterministically blocked (human-approved break-glass:scripts/waive-inline.sh). Action required: none for CLI/MCP/app users; repo contributors using agent sessions get the new flow automatically.
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.1.0-* tarballs — is read-only by construction: order transmission is not compiled in.
The ibkr-trading-v2.1.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.1.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
- Risk constitution phase 1:
ibkr policy(show/--explain, capital-event, override, reset-drawdown, artefact) over an operator-authoredrisk-policy.toml; capital-event journal with replay; drawdown warn/block ladder where the block latches until a journaled human reset; policy fingerprinting and sibling-policy drift display. All five policy write verbs are human-origin-only at the daemon. - Post-trade truth (phase 3a):
[flex]daily statement ingestion with single-purpose token-file rules;internal/flexstmttyped parser — unknown line types become louduncategorizedexceptions, never actions; recon engine +ibkr recon [--json]; the reconcile verb is report-gated (bare attestation retired) with a one-shot override as the statement-outage valve. - Recon backtest:
ibkr recon backtestreviews every flow in the retained statement window and replays the daily equity series against the recorded peak and drawdown-ladder crossings; the equity comparison is same-day (statement close vs that day's runtime observation) instead of latest-vs-latest. - Risk-policy v3: clean-report auto-extend of the reconcile clock behind a strict same-day equity-divergence gate (new operator-authored key
recon.max_equity_divergence_pct); statement-authoritative cumulative flows with declarations demoted to provisional same-day bridge entries; new non-exceptionconfirmedcategory for broker-confirmed undeclared flows; statement value-date peak correction, exactly once per statement line; declared-vs-statement figures displayed side by side during the transition. Pre-genesis statement flows classify as disclosed, report-id-pinnedbaselinerows — never exceptions, never signature-gated. - Codex delegation runner with a transactional lifecycle (fresh-task/resume/cleanup guards), pinned model/effort/service tier per run, offline-only gates for delegates, and a project execpolicy that prompts on live targets.
- The paired app's monitor tab opens with a daemon-composed daily brief: five sections (market, calendar, portfolio, risk, process) built from existing typed results with per-row disclosed degradation. Viewing stamps the brief once per foreground look with a server-assigned human origin — agent renders never stamp — and a one-tap sign-off submits the reconcile attestation for exactly the report the operator saw. A governance write, not a broker write; the CLI renders the same snapshot.
ibkr app deviceslists paired-device grants, andibkr app devices prune [--keep-days N](default 7) retires stale grants and their push subscriptions while keeping freshly-paired-but-unused devices (activity is the later of created and last-seen). The endpoints answer only local-Mac callers and the relay refuses to forward the device paths, so relayed requests cannot reach them.
Changed
pkg/ibkrconstructors now clone caller-supplied configs — later mutations of the caller's config struct no longer leak into a live client — and stale nil-context doc promises are dropped.- Rulebook policy fingerprint moved to a JSON projection (
rulebook-fp-v3); the rules-decisions journal now records the policy fingerprint with every transition, so journaled verdicts name the policy identity that produced them. - Runtime settings surfaces are single-sourced from the settings registry behind the generated reference — daemon flatten/apply, CLI grammar/help, and generated docs consume one table, parity-gated.
ibkr policy showrenders capital state as plain-language sentences (risk brake, money at risk, ledger check) instead of raw field dumps.- The Canary SPA is split into ES-module feature files behind a drift gate, and the canary engine moved from
internal/cliintointernal/canary; no rendered-output change. - CLI gamma open-interest warnings trust the daemon's session classification instead of reclassifying locally.
- Proposal-outcome deduplication keys are cached; dead outcome fields and unused MCP modes were removed from the proposal surface.
make releasenow preflights credentials before any gate work: gh CLI auth plus the stored MCP Registry JWT's expiry (30-minute minimum,REGISTRY_TOKEN_MIN_VALID_MINUTESoverrides), running the interactive device-code refresh up front instead of stranding at the final registry-publish leg.
Fixed
- Option days-to-expiry calculations were off by one across DST boundaries (both copies of the date math agree again).
- Flex statement lines with a missing amount attribute parse as unavailable and surface as loud
uncategorizedexceptions, instead of fabricating an amount of 0.00; an explicit zero stays present. - The documented reconcile-clock outage valve — a one-shot override on
capital.max_unreconciled_days— was recorded, journaled, and displayed but never consumed by evaluation; it now extends the clock, for exactly that one control. - Paired PWA sessions survive daemon restarts, binary rebuilds, and iOS home-screen isolation; pairing state no longer resets.
- Opportunity refresh backoff is capped at 15 minutes and shared across engines, so a transient failure no longer parks a feed for hours.
- Integration tests against a live gateway no longer race the async handshake (they poll up to 25 s), and closed-market skips key on typed calendar/session authorities, never on error text.
- The paired app's market-session clock renders in the browser's locale instead of hard-coded en-US string surgery.
Engineering notes
- Remote-relay unit tests and the embedded PWA asset-syntax check are bound into
make check; delegated Go briefs requiremake checkin-worktree. - v2 policy files cannot drift spuriously under the new binary: the pre-v3 constitution-fingerprint projection and the v2 recon report-id projection are preserved byte-for-byte, regression-tested.
- The browser smoke now covers settings-tab navigation and visibility — previously the only panel without id-contract coverage.