# Bloomberg MCP Server ## Introduction This project provides a **Model Context Protocol (MCP) server** that integrates with Bloomberg’s Hypermedia API. It allows clients (e.g., Windsurf, Postman MCP, internal assistants that supports MCP integration) to fetch **historical** and **current** rates in a structured, normalized format. The server is built in Python with: - `FastMCP`for MCP tooling - `httpx` for async HTTP requests - Server-Sent Events (SSE) to handle Bloomberg’s asynchronous data distribution --- ## Features - πŸ”‘ **JWT-based authentication** with Bloomberg Hypermedia API - πŸ“ˆ **Historical rates tool** – get normalized time series data over a date range - πŸ“Š **Current rates tool** – get latest/snapshot quotes for securities - πŸ™‹ **Greeting/help tool** – friendly entry point with usage examples - βœ… **Access control via NocoDB API** – restrict tool usage by user status - 🧩 **Schema validation** with `msgspec` - πŸ“‘ **SSE dispatcher** – handles async Bloomberg responses - πŸ“ **Structured error responses** for consistent handling - πŸ“¦ **Dockerized** with `pyproject.toml` + `uv` dependency management - πŸ–₯️ **Console-only logging** with configurable log levels --- ## Installation Clone the repository and install dependencies with **uv**: ```bash git clone https://github.com/AlterDomus/bloomberg-mcp-server.git cd bloomberg-mcp-server # install dependencies (pyproject.toml) uv venv # Optional, if you want to create a virtual enviornment (recommended) uv sync ``` --- ## Configuration All configuration is via environment variables. ### Bloomberg credentials: ```bash BLOOMBERG_HOST_URL=https://api.bloomberg.com BLOOMBERG_CLIENT_ID= BLOOMBERG_CLIENT_SECRET= ``` ### Bloomberg configurations: ```bash BLOOMBERG_CATALOG_ID= BLOOMBERG_API_VERSION= BLOOMBERG_REQUEST_TIMEOUT= BLOOMBERG_TERMINAL_USER_NUMBER= BLOOMBERG_SECURITY_LIMIT= ``` ### Access control (NocoDB): ```bash NOCODB_API_URL=https://nocodb.example.com/api/v1/db/data/v1/mydb/user_access NOCODB_TOKEN= ``` ### Logging: ```bash LOG_LEVEL=INFO # DEBUG, INFO, WARNING, ERROR ``` --- ## Running the Server ### Local (stdio): ```bash python -m main ``` **Path (stdio):** ```bash C:\Projects\bloomberg-mcp\.venv\Scripts\python.exe C:\Projects\bloomberg-mcp\main.py # Path consist of env and the main file location ``` ### Local (streamable HTTP): ```bash python -m main ``` **URL (streamable HTTP):** ```bash http://127.0.0.1:8000/mcp ``` **Headers (streamable HTTP):** ```json { "Content-Type": "application/json", "x-librechat-user-email": "" } ``` --- ## Available Tools ### `greeting` **Purpose**: Return a friendly introduction and examples. **Input**: Optional payload. **Output**: ```json { "message": "πŸ‘‹ Hi! I’m your Bloomberg AI Assistant..." } ``` --- ### `historical_rates` **Purpose**: Retrieve normalized historical time series for securities. **Input**: ```json { "symbols": [{"id_type":"TICKER","id_value":"EURUSD Curncy"}], "fields": [{"name":"PX_LAST"},{"name":"PX_MID"}], "currency": "USD", "start_date": "2024-01-01", "end_date": "2024-01-05" } ``` **Output**: ```json { "data": { "TICKER:EURUSD Curncy": [ {"date":"2024-01-01","values":{"PX_LAST":1.23,"PX_MID":1.22}} ] } } ``` --- ### `current_rates` **Purpose**: Retrieve latest/snapshot quotes. **Input**: ```json { "symbols": [{"id_type":"SEDOL","id_value":"2046251"}], "fields": [{"name":"BID"},{"name":"ASK"},{"name":"PX_LAST"}], "currency": "EUR" } ``` **Output**: ```json { "data": { "SEDOL:2046251": { "fields": {"BID":189.7,"ASK":190.3,"PX_LAST":190.1} } } } ``` --- ## Authentication and Access Management Bloomberg API requires a **JWT token**, generated with client ID and secret. Access control is enforced per tool: The server queries a **NocoDB endpoint** with the logged-in user email (passed via HTTP header). - User must exist and have status `active` - Otherwise, the tool returns a structured `ACCESS_DENIED` error. --- ## Development Notes ### Project Layout: ``` scripts/ sample_current.json sample_historical.json test_historical.py src/ config.py server.py schemas/ base.py current.py error.py historical.py services/ sse.py access.py tools/ greeting.py historical.py current.py _guards.py utils/ auth.py errors.py http.py logging_config.py parsing.py main.py .env .env.example ``` - **Logging**: Unified console logging via `src/utils/logging_config.py` - **Schemas**: Request/response types defined with `msgspec` - **Error Handling**: All errors use a shared `make_error_response` helper - **Tests**: Include examples like `test_historical.py` - **Docker**: Lightweight `python:3.12-slim` with `uv` package manager ---