xbbg-mcp
For an existing MCP client that should call Bloomberg directly: Claude Code, OpenCode, Claude Desktop, or any host that launches local stdio servers. You write no code; settings come from environment variables.
MCP server
xbbg-mcp is a local stdio MCP server built on the xbbg Rust engine. An MCP client launches it as a subprocess and calls twelve read-only Bloomberg tools that return bounded JSON with Arrow schema metadata.
Bring your own Bloomberg access
No xbbg-mcp release asset contains Bloomberg SDK files, runtime libraries, credentials, or market data. You supply the Bloomberg runtime and a connection (Desktop API through a Terminal, or a SAPI/B-PIPE host) under your own Bloomberg agreements and entitlements. Bloomberg checks entitlements per security and field on every request, so a working session can still return empty or partial results.
New in 1.8.0
XBBG_MCP_KEY_COLUMN names the column that holds each row's security: ticker (default, deprecated) or security. With the default, the server logs a warning at startup.bflds results end with Bloomberg's field id column, and refused field ids are kept in xbbg.field_errors metadata even when no field was answered.xbbg.field_exceptions metadata is stored as a compact dictionary; the server validates it and returns bounded, expanded records.xbbg-mcpFor an existing MCP client that should call Bloomberg directly: Claude Code, OpenCode, Claude Desktop, or any host that launches local stdio servers. You write no code; settings come from environment variables.
For agents you build in Python. xbbg_langgraph creates 35 LangChain tools that run on your xbbg engine and return a separate artifact for your application.
@xbbg/langgraphThe same 35 tools for LangChain.js and LangGraph.js on Node.js 24+, backed by @xbbg/core.
xbbg-mcp | LangGraph adapters | |
|---|---|---|
| Runs as | A separate process that the MCP client starts and talks to over stdin/stdout | Tools inside your Python or Node.js process |
| Tools | 12: reference, historical, bulk, and intraday bar requests, BQL, search, field metadata, auction venues and snapshots, entitlement and delay checks, and a generic request tool | 35: request tools including ticks, BQR, and BEQS; YAS, preferreds, corporate bonds, index members, ISIN and ETF recipes; auction tools; finite live snapshots; 11 helpers including Vega-Lite chart specs |
| Configuration | Environment variables read once at startup | Factory options in code |
| Results | One bounded JSON payload per call | Model-facing content plus an independently bounded artifact |
| Install | GitHub Release archive, installer script, .mcpb bundle, or source build | Python: source checkout (not on PyPI). Node.js: npm install @xbbg/langgraph |
See Python LangChain and LangGraph and @xbbg/langgraph for the adapters.
xbbg-mcp is distributed through GitHub Releases only; the crate is not published to crates.io. Each tagged release, such as v1.8.0, attaches these assets:
| Asset | Contents | Platform |
|---|---|---|
xbbg-mcp-v<VERSION>-darwin-arm64.tar.gz | xbbg-mcp launcher and xbbg-mcp-real binary | macOS on Apple silicon |
xbbg-mcp-v<VERSION>-linux-amd64.tar.gz | xbbg-mcp launcher and xbbg-mcp-real binary | Linux x86-64 with glibc 2.28 or newer |
xbbg-mcp-v<VERSION>-windows-amd64.zip | xbbg-mcp.exe only | Windows x64 |
xbbg-mcp-v<VERSION>.mcpb | Launchers and binaries for all three platforms, plus the MCPB manifest.json | macOS arm64, Linux amd64, Windows amd64 |
server.json | MCP Registry metadata that points at the release's .mcpb and its SHA-256 | — |
The official MCP Registry lists the server as io.github.underloam/xbbg-mcp; each registry entry installs the .mcpb asset of its release over stdio. There are no prebuilt binaries for macOS x86-64 or Linux arm64; build from source there.
The installer supports macOS arm64 and Linux amd64:
curl -fsSL https://raw.githubusercontent.com/underloam/xbbg/main/scripts/install-xbbg-mcp.sh | shPass a version to install a specific release instead of the latest:
curl -fsSL https://raw.githubusercontent.com/underloam/xbbg/main/scripts/install-xbbg-mcp.sh | sh -s -- 1.8.0The script needs curl and tar. It downloads xbbg-mcp-v<VERSION>-<platform>.tar.gz from the GitHub Release and installs xbbg-mcp (the launcher) and xbbg-mcp-real (the compiled binary) into ~/.local/bin. Set XBBG_MCP_INSTALL_DIR to install elsewhere, or XBBG_MCP_VERSION instead of the version argument. It then prints the Claude Code and OpenCode setup lines and warns when the install directory is not on PATH. On any other operating system or architecture it stops with an error.
xbbg-mcp and xbbg-mcp-real in the same directory. The launcher runs the binary beside it, or the one named by XBBG_MCP_REAL_BIN.xbbg-mcp.exe, without a launcher, and the installer script does not run on Windows. Make sure Windows can load the 64-bit blpapi3_64.dll, for example from a directory on PATH, or use the MCPB bundle, whose PowerShell launcher finds and checks the runtime for you.Claude Desktop and other MCPB-aware clients install xbbg-mcp-v<VERSION>.mcpb directly. Its install form maps optional settings to environment variables:
| Bundle setting | Variable | Default |
|---|---|---|
| Bloomberg runtime library directory | XBBG_MCP_LIB_DIR | empty (use the discovery order below) |
| Bloomberg host | XBBG_MCP_HOST | localhost |
| Bloomberg port | XBBG_MCP_PORT | 8194 |
| Authentication method | XBBG_MCP_AUTH_METHOD | none |
| Maximum returned rows, cells, metadata properties, metadata bytes, string characters, UTF-8 string bytes, and JSON result bytes | XBBG_MCP_MAX_ROWS … XBBG_MCP_MAX_RESULT_BYTES | See Result budgets |
The other variables on this page are not bundle settings; to use them, run the server from an archive or a source build and set them in your client's server configuration. On Windows the bundle starts its launcher with powershell.exe -NoProfile -ExecutionPolicy Bypass -File and the bundled server/xbbg-mcp.ps1.
From a repository checkout:
bash ./scripts/sdktool.sh
cargo build --release -p xbbg-mcp --locked
./scripts/xbbg-mcpscripts/sdktool.sh stages an authorized Bloomberg SDK under vendor/blpapi-sdk/, and scripts/xbbg-mcp is the same launcher, which also finds target/release/xbbg-mcp (or target/debug/xbbg-mcp). With a live Bloomberg connection, uv run python -X utf8 scripts/xbbg_mcp_smoke.py checks the stdio handshake and a few requests against the local build.
The macOS and Linux launcher uses the first directory that contains a Bloomberg runtime library (libblpapi3.dylib, libblpapi3.so, or libblpapi3_64.so), prepends it to DYLD_LIBRARY_PATH (macOS) or LD_LIBRARY_PATH (Linux), and then replaces itself with the binary:
XBBG_MCP_LIB_DIRBLPAPI_LIB_DIRBLPAPI_ROOT: the SDK root itself, its lib, lib64, or platform-named subdirectory, or its newest version-numbered subdirectoryvendor/blpapi-sdk/<version>/ in the launcher's parent directory (in a checkout, the repository root)blpapi package, located with python3 or pythonIf you install Bloomberg's Python package, the launcher usually needs no other configuration:
pip install blpapi --index-url https://blpapi.bloomberg.com/repository/releases/python/simple/The Windows launcher in the MCPB follows the same order, then scans PATH (a Bloomberg Terminal install puts its DAPI directory there), and only then tries the Python package with py, python, and python3. It also checks what it found:
blpapi3_64.dll.XBBG_MCP_LIB_DIR or BLPAPI_LIB_DIR is reported on stderr straight away; other rejected runtimes are listed if no usable runtime is found.blpapi3_64.dll beside the executable or in a Windows system directory would shadow the validated one in the DLL search order.xbbg-mcp.exe with the validated directory as both its working directory and its first PATH entry, and passes its own standard input, output, and error straight to the child, so PowerShell never touches the MCP stream.The server answers MCP initialization without a Bloomberg session. The engine starts on the first tool call, so connection and authentication problems appear as that call's error.
claude mcp add --transport stdio xbbg -- ~/.local/bin/xbbg-mcpUse the absolute path of the launcher (the installer prints it):
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"xbbg": {
"type": "local",
"command": ["/path/to/xbbg-mcp"],
"enabled": true
}
}
}Install the .mcpb bundle from the GitHub Release and fill in the settings form.
Register a local stdio server whose command is the launcher (xbbg-mcp on macOS and Linux) or xbbg-mcp.exe on Windows, with no arguments, and set the environment variables below in that server's environment.
Every tool is annotated read-only, non-destructive, and open-world. Required arguments are listed first.
| Tool | Purpose | Arguments |
|---|---|---|
bdp | Reference data | tickers, fields; optional overrides, options, field_types, format (long, long_typed, long_metadata), include_security_errors, validate_fields, return_eids, on_delayed |
bdh | Historical data | tickers, fields, start_date, end_date (YYYYMMDD or YYYY-MM-DD); optional overrides, options, field_types, format (adds semi_long), validate_fields, return_eids, on_delayed |
bds | Bulk data for exactly one bulk field | tickers, field; optional overrides, options, validate_fields, return_eids |
bdib | Intraday bars | ticker, start_datetime, end_datetime (ISO-8601), interval (positive minutes); optional event_type, request_tz, output_tz, options, return_eids, on_delayed |
bql | Bloomberg Query Language | expression; optional app_name |
bsrch | Saved Bloomberg search | domain; optional parameters, passed through as named request elements |
bflds | Field metadata lookup. Results end with Bloomberg's field id column; refused ids stay in xbbg.field_errors even when no field was answered | Either fields or search_spec, not both |
resolve_venues | Route composite equities and ISINs to their primary listing, and preferreds to venue pricing sources | securities; optional pcs_overrides |
auction_snapshot | Auction and imbalance reference data read on the resolved primary venue | securities; optional groups, fields, pcs_overrides |
check_entitlements | Check entitlement IDs against a Bloomberg service | eids (1 to 10,000 positive IDs, duplicates removed); optional service (default //blp/refdata) |
delay_status | Per-ticker delayed or real-time status for this session | tickers; optional check_identity (default false) |
request | Generic request for raw or custom services and operations, including RawRequest through request_operation | service; optional operation, request_operation, extractor, securities or security, fields, overrides, elements, kwargs, start_date/end_date or start_datetime/end_datetime, event_type or event_types, interval, return_eids, on_delayed, and more |
The server also returns MCP instructions that summarize when to use each tool.
The server reads its environment once at startup. In each row the first variable that is set to a non-empty value wins, so XBBG_MCP_* names take precedence over the shared XBBG_* names in parentheses. An invalid value, or a budget below its minimum, stops the server before the MCP handshake with an Error: "..." line on stderr and exit status 1.
The MCP environment covers one host and port and the auth modes below. TLS, ZFP, failover server lists, SOCKS5, and a request timeout are not configurable here; requests use the engine default of no timeout.
| Variable (fallbacks) | Default | Notes |
|---|---|---|
XBBG_MCP_HOST (XBBG_MCP_SERVER_HOST, XBBG_HOST, XBBG_SERVER_HOST, XBBG_SERVER) | localhost | Bloomberg API host |
XBBG_MCP_PORT (XBBG_MCP_SERVER_PORT, XBBG_PORT, XBBG_SERVER_PORT) | 8194 | Bloomberg API port |
XBBG_MCP_AUTH_METHOD (XBBG_AUTH_METHOD) | unset (no authentication) | none, user, app, userapp, dir or directory, manual, token; case-insensitive |
XBBG_MCP_APP_NAME (XBBG_APP_NAME) | unset | Required by app, userapp, and manual. An authentication setting, not a BQL setting |
XBBG_MCP_DIR_PROPERTY (XBBG_DIR_PROPERTY) | unset | Required by dir and directory |
XBBG_MCP_USER_ID (XBBG_USER_ID) | unset | Required by manual |
XBBG_MCP_IP_ADDRESS (XBBG_IP_ADDRESS) | unset | Required by manual |
XBBG_MCP_TOKEN (XBBG_TOKEN) | unset | Required by token |
Setting an app name, directory property, user ID, IP address, or token without an auth method is a startup error.
| Variable (fallbacks) | Default | Notes |
|---|---|---|
XBBG_MCP_BQL_APP_NAME | unset | Default BQL clientContext.appName; see BQL client context |
XBBG_MCP_REQUEST_POOL_SIZE (XBBG_REQUEST_POOL_SIZE) | 2 | Request workers |
XBBG_MCP_VALIDATION_MODE (XBBG_VALIDATION_MODE) | disabled | disabled, lenient, strict |
XBBG_MCP_FIELD_CACHE_PATH (XBBG_FIELD_CACHE_PATH) | ~/.xbbg/field_cache.json | Field-type cache file |
XBBG_MCP_WARMUP_SERVICES (XBBG_WARMUP_SERVICES) | //blp/refdata,//blp/apiflds | Comma-separated services opened when the engine starts |
XBBG_MCP_SDK_LOG_LEVEL (XBBG_SDK_LOG_LEVEL) | off | Bloomberg SDK logging: off, fatal, error, warn, info, debug, trace |
XBBG_MCP_NUM_START_ATTEMPTS (XBBG_NUM_START_ATTEMPTS, XBBG_MAX_ATTEMPT) | 3 | Session connection attempts |
XBBG_MCP_AUTO_RESTART_ON_DISCONNECTION (XBBG_AUTO_RESTART_ON_DISCONNECTION, XBBG_AUTO_RESTART) | true | true/false, 1/0, yes/no, or on/off |
XBBG_MCP_RETRY_MAX_RETRIES (XBBG_RETRY_MAX_RETRIES) | 0 | Retries for transient request failures |
XBBG_MCP_RETRY_INITIAL_DELAY_MS (XBBG_RETRY_INITIAL_DELAY_MS) | 1000 | First retry delay |
XBBG_MCP_RETRY_BACKOFF_FACTOR (XBBG_RETRY_BACKOFF_FACTOR) | 2.0 | Delay multiplier per retry |
XBBG_MCP_RETRY_MAX_DELAY_MS (XBBG_RETRY_MAX_DELAY_MS) | 30000 | Retry delay ceiling |
XBBG_MCP_OVERFLOW_POLICY (XBBG_OVERFLOW_POLICY) | drop_newest | drop_newest or block |
XBBG_MCP_KEY_COLUMN (XBBG_KEY_COLUMN) | ticker | Column that holds each row's security: ticker or security. ticker is deprecated because it collides with Bloomberg's TICKER field; security becomes the default in the next major release |
These MCP-only settings take integers. A value below the minimum is rejected rather than silently disabling a limit.
| Variable | Default | Minimum | Bounds |
|---|---|---|---|
XBBG_MCP_MAX_ROWS | 500 | 1 | Returned rows |
XBBG_MCP_MAX_CELLS | 50,000 | 1 | Returned cells and inspected schema columns; also entitlement-list items and validation-error records |
XBBG_MCP_MAX_METADATA_PROPERTIES | 50,000 | 1 | Retained metadata properties and array items, and metadata entries inspected |
XBBG_MCP_MAX_METADATA_BYTES | 65,536 | 1 | Raw metadata bytes inspected before parsing, and retained metadata with its count summaries |
XBBG_MCP_MAX_STRING_CHARS | 2,048 | 1 | Unicode characters per string |
XBBG_MCP_MAX_STRING_BYTES | 8,192 | 3 | UTF-8 bytes per string, including a truncation marker |
XBBG_MCP_MAX_RESULT_BYTES | 1,048,576 | 2,048 | The final serialized JSON payload, including schema, metadata, and diagnostics; also bounds error results |
| Variable | Used by | Effect |
|---|---|---|
XBBG_MCP_LIB_DIR, BLPAPI_LIB_DIR, BLPAPI_ROOT | Launchers | Bloomberg runtime location; see discovery |
XBBG_MCP_REAL_BIN | macOS/Linux launcher | Path of the compiled binary to run |
XBBG_MCP_INSTALL_DIR | Installer | Install directory (default $HOME/.local/bin) |
XBBG_MCP_VERSION | Installer | Release to install when no version argument is given (default: latest) |
XBBG_MCP_REPO, XBBG_MCP_DOWNLOAD_URL | Installer | Source repository (default underloam/xbbg) or a full archive URL |
RUST_LOG | Server | Log level for the engine and MCP library: trace, debug, info, warn (default), or error |
Every successful call returns one structured JSON object. A one-row bdp result looks like this excerpt (additional counters omitted):
{
"schema": [{ "name": "PX_LAST", "data_type": "Float64", "nullable": true }],
"row_count": 1,
"column_count": 1,
"returned_rows": 1,
"returned_columns": 1,
"returned_cells": 1,
"result_budget_bytes": 1048576,
"truncated": {
"rows": false,
"columns": false,
"cells": false,
"values": false,
"metadata": false,
"output": false
},
"rows": [{ "PX_LAST": 190.1 }]
}row_count and column_count describe the source batch; the returned_* fields describe what was emitted. truncated is an object of flags, not a single boolean.truncation_counts reports omissions, including omitted_rows, omitted_columns, omitted_cells, known_omitted_value_bytes, omitted_complex_values, and known_omitted_metadata_properties. Treat known_* counts as lower bounds; schema_column_count_complete, metadata_input_count_complete, and metadata_property_count_complete say whether a count is complete. Optional metadata_counts adds per-key diagnostics.Date32 values are YYYY-MM-DD; Time64 values are HH:MM:SS[.fraction] with no invented date or timezone; timestamps end in Z for UTC or carry their declared offset. Integers outside JavaScript's safe range are returned as strings.xbbg.security_errors, xbbg.field_errors, xbbg.field_exceptions, xbbg.delayed, and xbbg.eid_data metadata are kept before generic metadata and rows. Even these can be omitted when they cannot fit; truncation_counts.omitted_priority_metadata names any that were dropped.xbbg.field_exceptions dictionaries are validated before projection and returned as bounded expanded records, never as partially clipped dictionary references.Failures stay errors, never empty success-shaped results. Error messages respect the string and result-byte limits (message_truncated: true marks shortening), and validation errors carry bounded errors records with path, message, and a per-record truncated flag, plus total_errors, returned_errors, and omitted_errors.
return_eids: true is accepted only where Bloomberg supports returnEids:
| Tool | Bloomberg operation |
|---|---|
bdp, bds | ReferenceDataRequest (including bulk) |
bdh | HistoricalDataRequest |
bdib | IntradayBarRequest |
request | IntradayTickRequest (and the operations above) |
Intraday ticks go through the generic tool:
{
"service": "//blp/refdata",
"operation": "IntradayTickRequest",
"extractor": "intraday_tick",
"security": "AAPL US Equity",
"start_datetime": "2024-01-15T09:30:00",
"end_datetime": "2024-01-15T10:00:00",
"event_types": ["TRADE"],
"return_eids": true
}When the map fits the budgets, it is returned as structured JSON at metadata["xbbg.eid_data"]; metadata_counts["xbbg.eid_data"] reports total and returned EID and security counts, valid, and counts_complete (an unknown total is null, not zero). Pass the IDs to check_entitlements:
{ "eids": [101, 202], "service": "//blp/refdata" }The result includes service, eids, entitled, and failed_eids, with total, returned, and omitted counts and truncated flags for both lists. A shortened list is not the full entitlement result. See Entitlements for the underlying Bloomberg concepts.
Bloomberg serves delayed data without marking the rows. delay_status reads IS_DELAYED_STREAM, EXCHANGE_DELAY, EXCH_CODE, and the feed EIDs in one reference-data request and returns one row per unique ticker, in input order:
{ "tickers": ["VOD LN Equity", "AAPL US Equity"], "check_identity": false }Rows contain ticker, delayed, delay_minutes, exchange_delay, exch_code, realtime_eid1 to realtime_eid4, delayed_eid, realtime_entitled, delayed_entitled, and error. check_identity: true also checks the feed EIDs against //blp/mktdata and fills the two *_entitled columns; it needs SAPI/B-PIPE authorization through XBBG_MCP_AUTH_METHOD or a Desktop API user enrolled in EMRS, otherwise the call fails.
on_delayed runs the same check alongside bdp, bdh, bdib, and request (for ReferenceDataRequest, HistoricalDataRequest, IntradayBarRequest, and IntradayTickRequest; not bulk data). bdp reads the flags in the same request. The others send one small extra reference-data request, and only when the window reaches the last 24 hours.
on_delayed | Result |
|---|---|
| omitted | No check |
warn or ignore | Data plus metadata["xbbg.delayed"], keyed by ticker, for example { "VOD LN Equity": { "delayed": true, "delay_minutes": 15 } } |
raise | The call fails with an error naming the delayed tickers |
MCP has no warnings channel, so warn and ignore behave the same. Tickers without a Bloomberg delay flag are absent from the map.
resolve_venues keeps one row per input, including duplicates and input order, with status (resolved, unresolved, unsupported, or mismatch), error, and the venue details. auction_snapshot resolves venues first and then reads the requested fields on each venue; failed inputs keep their status row with null data fields.
{
"securities": ["IBM US Equity", "AAPL US Equity"],
"groups": ["imbalance", "quotes"],
"fields": ["IN_AUCTION_RT"]
}groups accepts imbalance, indicative, state, halts, results, composite, quotes, and default. Groups expand first, then explicit fields, with duplicates removed. With neither, the default group (imbalance, indicative, state, halts, results) is used; include default in groups to extend it.pcs_overrides maps preferred exchange names to pricing-source codes, for example { "NEW YORK": "SNY2" }; a blank value disables the built-in mapping for that exchange.delay_status to check.See Exchange Auctions for how venue routing works.
XBBG_MCP_BQL_APP_NAME sets the engine's default clientContext.appName for every BQL request the server sends, including those through request. A per-call app_name on bql, or a clientContext.appName key in the generic tool's string-valued elements map, overrides it:
{
"expression": "get(name()) for('IBM US Equity')",
"app_name": "example-authorized-bql-app"
}Without either, the app name is omitted and Bloomberg's default applies. A blank per-call app_name is rejected. Use a name authorized for your environment: this setting grants no BQL entitlement and does not change session authentication, and XBBG_MCP_APP_NAME never doubles as a BQL app name.
RUST_LOG=info or RUST_LOG=debug to add engine and MCP-library logs, and XBBG_MCP_SDK_LOG_LEVEL for Bloomberg SDK logging.xbbg-mcp: stdin closed; shutting down and exits with status 0. A failed stdin read, reader-thread failure, or abnormal service stop exits nonzero.Error: "...". A configuration problem, for example max_result_bytes must be at least 2048, got 100, auth_method is required when auth-specific environment variables are set, or app_name is required for auth_method=app.ticker. With the default key column the server logs that results name the security column ticker, which collides with Bloomberg's TICKER field and becomes security in the next major release. Set XBBG_MCP_KEY_COLUMN=security to switch now.xbbg-mcp: could not locate the Bloomberg runtime library. Set XBBG_MCP_LIB_DIR, BLPAPI_LIB_DIR, or BLPAPI_ROOT, or install Bloomberg's blpapi package for the python3 or python the launcher finds.xbbg-mcp: could not locate the real xbbg-mcp binary. Keep xbbg-mcp-real next to the launcher, reinstall, or set XBBG_MCP_REAL_BIN.blpapi3_64.dll and why: no readable version, older than the minimum, or a shadowing copy beside the executable or in a system directory. If xbbg-mcp.exe still exits with STATUS_DLL_NOT_FOUND, STATUS_ENTRYPOINT_NOT_FOUND, or STATUS_INVALID_IMAGE_FORMAT, the launcher reports the selected runtime and its version; a direct or transitive dependency failed to load.xbbg.security_errors, xbbg.field_errors, and xbbg.field_exceptions metadata, and use delay_status when values look stale.xbbg-mcp runs locally and sends no telemetry. Tool calls go only to the Bloomberg endpoint you configure (XBBG_MCP_HOST and XBBG_MCP_PORT, default localhost:8194), and results go only to the MCP client that launched the server.
Build agents in Python with the xbbg_langgraph tools.
The same tools for LangChain.js and LangGraph.js.
Entitlement IDs, identity checks, and delayed data in xbbg.
Venue routing and auction snapshots behind the auction tools.