The full upstream README, mirrored here for reference. Install config, tool schemas, adoption signals, and an original overview live on the Xbbg MCP listing page.
Latest release: xbbg==1.4.11 (release: notes)
This
mainbranch is the Rust-powered v1 release. For the legacy pure-Python line, userelease/0.x.
Important: xbbg is an independent open-source project. It is not affiliated with, endorsed by, sponsored by, or approved by Bloomberg Finance L.P. or its affiliates. Bloomberg, Bloomberg Terminal, B-PIPE, BQL, and related names are trademarks or service marks of their respective owners. xbbg does not grant access to Bloomberg services, data, software, licenses, credentials, or entitlements; users must obtain and use those separately under their own Bloomberg agreements and applicable policies.
xbbg is a Bloomberg client with Python as the primary surface and companion JavaScript/Node bindings, all backed by a shared Rust engine for request execution, response parsing, Arrow-shaped data movement, async workers, typed errors, and diagnostics.
Use xbbg when you already have Bloomberg access and want higher-level helpers for common request patterns, plus an escape hatch for lower-level Bloomberg service requests.
Core scope:
js-xbbgxbbg's project goal is direct: be the most complete, technically advanced, and performance-focused open-source Bloomberg client for Python workflows, while staying independent of Bloomberg and requiring users to bring their own authorized Bloomberg access.
The short version: if all you need is a tiny one-off bdp() wrapper, several packages can work. xbbg is built for the path where that notebook later grows into intraday data, BQL, streaming, B-PIPE/SAPI, ZFP, async services, typed errors, diagnostics, and non-pandas data pipelines.
| Capability | xbbg | raw blpapi | pdblp / blp | bbg-fetch | polars-bloomberg |
|---|---|---|---|---|---|
| BDP/BDS/BDH helpers | yes | manual SDK code | yes | yes | partial |
| Intraday bars and ticks | yes | manual SDK code | limited / no | no | partial |
| Streaming subscriptions | yes | manual SDK code | no | no | no |
| BQL, BEQS, BSRCH, BQR, YAS, BTA | broad helper coverage | manual SDK code | limited | limited | partial |
| DAPI, SAPI/B-PIPE, ZFP, TLS, failover, SOCKS5 | configurable engine support | manual SDK code | limited | limited | limited |
| Async worker pools and isolated subscription sessions | yes | application-owned | no | no | no |
| Rust request/parsing engine with Arrow-shaped output | yes | no | no | no | no |
| Output backends beyond pandas | Narwhals, native, PyArrow, pandas, Polars, DuckDB | application-owned | pandas-first | pandas-first | Polars-first |
| Typed errors, diagnostics, field cache, testing helpers | yes | application-owned | limited | limited | limited |
| Usable install footprint (Windows x64, Python 3.14) | xbbg 1.3.0 + narwhals 2.22.1, no blpapi = 16.933 MiB | blpapi 3.26.5.1 = 14.401 MiB | pdblp 0.1.8 + pandas 3.0.3 + numpy 2.4.6 + blpapi 3.26.5.1 = 129.344 MiB / blp 0.0.4 + pandas 3.0.3 + numpy 2.4.6 + blpapi 3.26.5.1 = 129.530 MiB | bbg-fetch 2.0.2 + pandas 3.0.3 + numpy 2.4.6 + blpapi 3.26.5.1 = 129.360 MiB | polars-bloomberg 0.6.0 + polars 1.41.2 + blpapi 3.26.5.1 = 197.296 MiB |
Conda users can install the conda-forge build:
blpapi is not required as a Python dependency. xbbg only needs Bloomberg's shared runtime library
(blpapi3_64.dll on Windows, libblpapi3_64.so on macOS/Linux), which can come from Bloomberg
Terminal/DAPI, a managed Bloomberg C++ SDK install, or Bloomberg's official blpapi wheel. Installing
the wheel is just the easiest discovery path for many users:
Supported Python versions: 3.10 through 3.14.
Requirements and notes:
bash ./scripts/sdktool.sh on macOS/Linux or .\\scripts\\sdktool.ps1 on Windows PowerShell.BLPAPI_ROOT or use xbbg.set_sdk_path(...).C:\blp\DAPI and C:\Program Files (x86)\Bloomberg\Blp\DAPI before requiring manual configuration.manylinux_2_28 (x86_64): any distro with glibc ≥ 2.28 works — RHEL/Alma/Rocky 8+, Debian 10+, Ubuntu 20.04+, Amazon Linux 2023.xbbg[pyarrow], xbbg[pandas], xbbg[polars], or xbbg[duckdb].Verify the install:
Common request patterns:
ETF NAV / iNAV workflows live in xbbg.ext and resolve Bloomberg's authoritative
ETF_NAV_TICKER / ETF_INAV_TICKER relationships instead of guessing ticker suffixes:
For longer walkthroughs and example output shapes, use the examples notebook or xbbg.org.
xbbg also ships supported Node bindings in @xbbg/core. The JS layer uses the same Rust engine through a native N-API addon, so Node can use the same Bloomberg connection modes and request surfaces as Python.
The packages target Node.js 24+ server runtimes. Packaged native addons are provided for macOS arm64, Linux x64 (glibc 2.28+), and Windows x64. You still need Bloomberg access plus Bloomberg SDK runtime libraries on the target system.
See js-xbbg/README.md for platform packaging, runtime prerequisites, and the supported JavaScript API surface.
For LangChain and LangGraph agents, use the supported @xbbg/langgraph adapter. It exposes reusable server-side Bloomberg tools backed by @xbbg/core without making MCP, a chat app, or a browser integration the core path:
Use the existing apps/xbbg-mcp package only when you specifically need MCP.
By default, xbbg starts a Rust-backed engine and connects to local Bloomberg Desktop API / DAPI on localhost:8194. Configure the engine before the first request when you need a different transport, authentication mode, worker count, timeout policy, field cache, or logging behavior.
Common environments:
| Environment | Use when | Configuration shape |
|---|---|---|
| Desktop API / DAPI | Local Bloomberg Terminal session | no config, or configure(host="localhost", port=8194) |
| Direct server / SAPI | Firm-managed Bloomberg server | configure(host="bpipe-host", port=8194, auth_method="app", app_name="...") |
| B-PIPE | Enterprise Bloomberg feed infrastructure | direct host/failover config plus the auth/TLS settings your Bloomberg setup requires |
| ZFP leased line | Bloomberg zero-footprint leased-line path | configure(zfp_remote="8194", tls_client_credentials="...", tls_trust_material="...") |
Example B-PIPE/SAPI-style configuration:
Example ZFP leased-line configuration:
The engine uses separate worker pools for request/response calls and subscriptions:
runtime_worker_threads defaults to 2 (minimum 1) and controls the engine's shared Tokio runtime, not the total process thread count. subscription_pool_size is the pre-warm count (default 1, minimum 0); max_subscription_sessions caps concurrent subscription sessions (default 32, minimum 1, and at least subscription_pool_size). Native subscription admission waits for capacity instead of allocating unbounded sessions. Node uses the corresponding runtimeWorkerThreads, subscriptionPoolSize, and maxSubscriptionSessions fields.
Use Engine(...) when an application needs a scoped engine with its own connection settings instead of mutating global configuration.
Engine shutdown closes subscription admission and signals both idle and checked-out sessions, waking pending operations so termination and errors can reach callers. Close subscriptions explicitly before releasing their engine; do not rely on interpreter teardown for application cleanup.
Field-cache snapshots are published atomically. On Windows this uses FileRenameInfoEx with POSIX rename semantics, requiring Windows 10 1607+ and a supporting filesystem. Existing readers can finish with the old snapshot while new opens see the complete replacement. Unsupported filesystems report persistence errors and retain the prior snapshot; there is no unsafe replacement fallback.
| Area | Functions |
|---|---|
| Reference and bulk data | bdp, bds, bflds, fieldInfo, fieldSearch, blkp, bport |
| Historical data | bdh, dividend, earnings, turnover, dividend_yield |
| Intraday data | bdib, bdtick |
| Query and screening | bql, beqs, bsrch, bqr, bcurves, bgovts, etf_holdings, index_members |
| Analytics and utilities | yas, bta, ta_studies, ta_study_params, convert_ccy, fut_ticker, active_futures, futures_curve, vol_surface, resolve_isins, issuer_isins, cdx_ticker, active_cdx |
| Real-time data | subscribe, stream, vwap, mktbar, depth, chains |
| Generic requests | request, Service, Operation, RequestParams, OutputMode |
| Schema and diagnostics | bops, bschema, get_sdk_info, enable_sdk_logging, print_backend_status |
| Testing helpers | xbbg.testing.create_mock_response, xbbg.testing.mock_engine |
Most sync helpers have async counterparts with an a prefix: bdp → abdp, bdh → abdh, bdib → abdib, request → arequest.
Bloomberg can return entitlement IDs only for these four request operations. Opt in with return_eids=True:
| Bloomberg operation | Python routes |
|---|---|
ReferenceDataRequest | blp.bdp, blp.bds (BDS uses the reference-data operation) |
HistoricalDataRequest | blp.bdh |
IntradayBarRequest | blp.bdib |
IntradayTickRequest | blp.bdtick |
For example, request EIDs with intraday ticks and check them against the default //blp/refdata service:
EID metadata remains available through the native ArrowTable.eid_data property, pandas attrs["xbbg_eid_data"], or PyArrow schema metadata under xbbg.eid_data. Polars and DuckDB do not provide a stable entitlement-metadata side channel; use the native, PyArrow, or pandas backend when EIDs are required.
This opt-in request metadata is separate from a subscription message's top-level EID field.
xbbg defaults to a Narwhals DataFrame. When PyArrow is installed, the Narwhals frame is backed by a real pyarrow.Table; otherwise xbbg falls back through available dataframe libraries and finally to its native Arrow carrier.
Output shape is controlled with format=, including long, long_typed, long_metadata, and semi_long.
ArrowTable, ArrowRecordBatch, and ArrowColumn slices can retain their source allocations. Use .compact() when retaining a small result should release that backing storage: it returns an independent copy of the logical values with right-sized buffers, preserving schema, nulls, and physical batch/chunk boundaries. Native zero-column tables retain their row count.xbbg[polars] to include the timezone data required on Windows.backend="polars_lazy" returns a Polars LazyFrame; backend="narwhals_lazy" returns a genuine Narwhals lazy frame backed by Polars and requires Polars. Bloomberg retrieval and Arrow-to-Polars conversion have already happened: only subsequent local dataframe operations are deferred, with no Bloomberg query pushdown.spawn or fork before initializing the DuckDB backend.Use async helpers directly in async applications:
In Jupyter, VS Code Interactive, and marimo, one-shot sync calls such as blp.bdp(...) and blp.bdh(...) use a notebook-only bridge when the notebook event loop is already running. Generic async applications such as FastAPI or ASGI services should still use the async APIs directly.
Use asubscribe() when you need dynamic add/remove, explicit unsubscribe, raw Arrow batches, or subscription health diagnostics. Use astream() for the simple async iterator, or stream() for synchronous iteration.
Key behaviors:
output accepts exactly record_batch, backend, dict, or tick (case-insensitive); omitting it keeps whatever raw and tick_mode selectraw=True or output="record_batch" yields raw xbbg ArrowRecordBatch values for max-performance consumerstick_mode=True, output="dict", or output="tick" returns native dict ticks and implies raw subscription modeoutput="backend" returns the configured backend output, the same as default iteration without raw=Trueall_fields=True exposes all top-level scalar Bloomberg subscription fieldsMKTDATA_EVENT_TYPE and MKTDATA_EVENT_SUBTYPEconflate=True requests Bloomberg-conflated quote updates on //blp/mktdata; trades are still delivered as receivedsub.add(...), sub.remove(...), sub.status, sub.events, sub.failed_tickers, and sub.stats expose runtime control and diagnosticsasync with on an acquired subscription or try/finally with await sub.unsubscribe() for deterministic cleanup; unsubscribe(drain=True) closes the subscription and returns remaining buffered native Arrow batches rather than discarding themPython stream() producers share one managed background event-loop thread, not a thread per stream. Each sync bridge has a bounded queue (stream_capacity, default 256, minimum 1) and asynchronously waits for consumer space; native overflow policy remains separate. Active sync producers are admitted per global/scoped engine up to max_subscription_sessions; excess producers raise RuntimeError rather than creating more tasks. Callbacks run on the consuming thread. Close the generator explicitly when stopping early: close cancels and waits for producer cleanup, and a cleanup timeout is reported while the producer remains tracked against its admission limit. In async applications use astream() directly and close it explicitly when retaining the generator after an early exit.
In Node, pass { allFields: true } to stream() / subscribe() helpers for the same top-level field expansion. Default iteration yields scalar Tick objects; sub.arrow() constructs Arrow JS tables without IPC for supported schemas. Exposed mutable buffers are JS-owned snapshots: exclusive bounded allocations can be transferred, while shared/sliced/oversized storage is copied or canonicalized first. This is not a universal zero-copy Rust/JS boundary. Choose scalar or Arrow reads once per subscription; see the Node lifecycle and benchmark contracts.
The repository also includes a local MCP server for coding-agent workflows. It wraps selected xbbg request/response operations and returns bounded JSON results with schema metadata.
See apps/xbbg-mcp/README.md for installation, supported environment variables, raw GitHub Release tar/zip assets, and the xbbg-mcp-v<VERSION>.mcpb local connector artifact. Official MCP Registry publication uses the generated server.json metadata after the matching GitHub Release contains the .mcpb; no MCP release asset includes Bloomberg SDK files or runtime components.
Empty results usually mean one of the inputs or entitlements is wrong rather than that the Python call failed:
Connection failures:
print(xbbg.get_sdk_info()) to see how the SDK/runtime was detectedTimeouts and large responses:
bdp/bdh requests with shard_requests=Truerequest_pool_size, subscription_pool_size, queue sizes, and keep-alive settings for managed infrastructureWhen reporting issues, include:
import xbbg; print(xbbg.__version__)Set up the development environment with pixi:
Common checks:
For non-live tests, use xbbg.testing:
Publishing is handled through GitHub Actions and PyPI Trusted Publishing.
If you use xbbg in research or published work, please cite: