bloomberg-mcp-server

VrushilG/bloomberg-mcp-server

3.1

If you are the rightful owner of bloomberg-mcp-server and would like to certify it and/or have it hosted online, please leave a comment on the right or send an email to dayong@mcphub.com.

The Bloomberg MCP Server is a Python-based server that integrates with Bloomberg’s Hypermedia API to provide historical and current financial data in a structured format.

Tools
3
Resources
0
Prompts
0

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:

  • FastMCPfor 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:

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:

BLOOMBERG_HOST_URL=https://api.bloomberg.com
BLOOMBERG_CLIENT_ID=<your client id>
BLOOMBERG_CLIENT_SECRET=<your client secret>

Bloomberg configurations:

BLOOMBERG_CATALOG_ID=<catalog id>
BLOOMBERG_API_VERSION=<version number>
BLOOMBERG_REQUEST_TIMEOUT=<request timeout>
BLOOMBERG_TERMINAL_USER_NUMBER=<users terminal number>
BLOOMBERG_SECURITY_LIMIT=<default security limit>

Access control (NocoDB):

NOCODB_API_URL=https://nocodb.example.com/api/v1/db/data/v1/mydb/user_access
NOCODB_TOKEN=<nocodb-api-token>

Logging:

LOG_LEVEL=INFO  # DEBUG, INFO, WARNING, ERROR

Running the Server

Local (stdio):

python -m main

Path (stdio):

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):

python -m main

URL (streamable HTTP):

http://127.0.0.1:8000/mcp

Headers (streamable HTTP):

{
  "Content-Type": "application/json",
  "x-librechat-user-email": "<logged-in user from MCP client>"
}

Available Tools

greeting

Purpose: Return a friendly introduction and examples.
Input: Optional payload.
Output:

{
  "message": "👋 Hi! I’m your Bloomberg AI Assistant..."
}

historical_rates

Purpose: Retrieve normalized historical time series for securities.
Input:

{
  "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:

{
  "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:

{
  "symbols": [{"id_type":"SEDOL","id_value":"2046251"}],
  "fields": [{"name":"BID"},{"name":"ASK"},{"name":"PX_LAST"}],
  "currency": "EUR"
}

Output:

{
  "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
<configuration files>
  • 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