Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Developer Guide

This guide is the shortest path for developers who want to use or extend ibkr-agent-gateway.

Install and Run

From this checkout:

cargo run --bin ibkr-agent -- health --json
cargo run --bin ibkr-agent -- accounts list --json

Install the CLI locally:

cargo install --path .
ibkr-agent health --json

Embed the library from another local Rust project:

cargo add ibkr-agent-gateway --path /path/to/ibkr-agent-gateway
use ibkr_agent_gateway::prelude::*;

#[tokio::main]
async fn main() -> Result<(), GatewayError> {
    let gateway = Gateway::new(GatewayConfig::fake_local())?;
    let accounts = gateway.list_accounts().await?;
    println!("visible_accounts={}", accounts.len());
    Ok(())
}

Backend Modes

Use GatewayConfig::fake_local() while developing. It reads deterministic fixtures from tests/fixtures/cpapi/ and needs no broker session.

Use GatewayConfig::client_portal(url) only when the Interactive Brokers Client Portal Gateway is already running and manually authenticated outside this project. TLS verification can be disabled only for localhost URLs.

For production-like deployments, read production-readiness.md. The CLI runner defaults to fake fixtures only when --config is omitted. A real broker CLI run should pass an explicit YAML config, such as config/local.example.yaml, and supply the configured audit HMAC secret through the environment.

CLI Surface

Read and session inspection:

ibkr-agent backend status --json
ibkr-agent session requirements --json
ibkr-agent account summary --account DU1234567 --json
ibkr-agent portfolio snapshot --account DU1234567 --json
ibkr-agent positions list --account DU1234567 --json
ibkr-agent market snapshot --contract-id 265598 --json
ibkr-agent executions list --account DU1234567 --json

Order preview is non-executable and must be explicitly enabled:

ibkr-agent orders preview \
  --account DU1234567 \
  --symbol AAPL \
  --side buy \
  --quantity 1 \
  --limit-price 100 \
  --currency USD \
  --enable-preview \
  --json

Paper submit/cancel commands require explicit paper enablement and an idempotency key. Submit also requires the approval id returned by approvals create:

ibkr-agent approvals create --account DU1234567 --preview-id <preview_id> --ttl-seconds 300 --json
ibkr-agent orders submit --account DU1234567 --approval-id <approval_id> --idempotency-key paper-submit-001 --enable-paper --json
ibkr-agent orders cancel --account DU1234567 --broker-order-id paper-order-local --idempotency-key paper-cancel-001 --enable-paper --json

CLI live submit and cancel run the full gate stack and then call a LiveOrderWriter. The CLI defaults to LocalCandidateLiveWriter, so the broker order id is a deterministic local-candidate-* value. Use --live-broker client-portal with a Client Portal Gateway config to call ClientPortalLiveWriter from the CLI; --live-broker refusing is available for fail-closed checks. Production deployments can also inject their own writer through the SDK boundary (see docs/production-readiness.md):

ibkr-agent orders live-submit \
  --account DU1234567 \
  --approval-id <approval_id> \
  --idempotency-key live-submit-001 \
  --enable-live \
  --live-scope \
  --open-kill-switch \
  --acknowledge-paper-to-live \
  --live-broker local-candidate \
  --json

Audit review:

ibkr-agent audit tail --limit 20 --json
ibkr-agent audit export --limit 500 --json
ibkr-agent audit verify --json

MCP

Local stdio MCP:

ibkr-agent mcp serve --transport stdio --describe --json
ibkr-agent mcp serve --transport stdio --json

--describe exits after a smoke-check description. Without it, the command runs the stdio JSON-RPC loop, advertises only tools enabled by local scopes, and audits every tool call.

Remote HTTP MCP is disabled by default. Enabling it requires complete remote MCP runtime config, an OAuth/OIDC issuer, RS256/RSA JWKS validation, a token-id HMAC secret, accepted audiences, allowed scopes, and the independent safety flag. In CLI YAML, that safety flag is safety.remote_mcp_enabled; the SDK-facing GatewayConfiguration field is safety.remote_public_mcp_enabled.

ibkr-agent --config config/remote.example.yaml mcp serve --transport http --enable-remote-mcp --bind 127.0.0.1:8080

The HTTP listener serves protected-resource metadata and routes authorized JSON-RPC requests on POST /mcp. See remote-mcp-oauth.md.

Example client configs live under examples/mcp-clients/.

Validation

Run these before changing package behavior:

cargo fmt --check
cargo clippy --workspace --all-targets --features unstable-internal-test-support -- -D warnings
cargo test --workspace --features unstable-internal-test-support
cargo test --workspace --features unstable-internal-test-support secret

Run packaging checks before release work:

cargo package --allow-dirty --no-verify --list
cargo publish --dry-run --locked

Safety Rules for Contributors

  • Do not return broker cookies, bearer tokens, credentials, raw headers, local paths, or raw session material from any CLI, MCP, log, fixture, or audit path.
  • Keep broker logic provider-neutral; provider-specific behavior belongs in compatibility examples and tests.
  • Keep write-capable flows fail-closed unless explicit config, scope, approval, idempotency, audit, and risk gates are satisfied.
  • Preserve the public facade boundary in src/public/* and src/lib.rs; keep implementation details under src/internal/*.