Skip to main content

Busy Bar MCP Server

A Python MCP server written with FastMCP that wraps the busybar_python_sdk to communicate with a physical Busy Bar device over HTTP. The Busy Bar is a digital time-management display — this MCP server provides 32 tools for account retrieval, system information, time operations, BLE control, and input events, exposing its functionality through the standard Model Context Protocol so other tools and AI assistants can interact with it programmatically.

Status: 32 MCP tools are fully implemented across account retrieval, system information, time operations, device state queries, BLE control, and input events, with a complete test suite. The project is ready to use — see the What's Next section below for planned work.

Prerequisites

  • Python ≥ 3.12 — the project pins Python 3.12+ (see .python-version)
  • uv — dependency manager and virtual environment resolver

Installation

Clone the repository and install dependencies:

uv sync

This creates a virtual environment and installs all packages declared in pyproject.toml, including busybar-python-sdk ≥ 27.5.1 — currently resolved from test.pypi.org (the testpypi index declared in pyproject.toml plus the committed [tool.uv.sources] mapping, so no manual --index flags are needed) until it is promoted to production PyPI.

Configuration

The server supports configuration through either a .env file or environment variables. The same two variables are required in both cases:

Variable Description Example
BUSYBAR_API_TOKEN API auth token for authenticating with the Busy Bar device; transmitted to the device as the X-API-Token header (per the busybar-python-sdk 27.5.1 generated ApiKeyAuth scheme — see Authentication below) my-super-secret-token
BUSYBAR_BASE_URL IP address or hostname of the Busy Bar device (a scheme-prefixed http://… / https://… value is also accepted) 10.0.4.20

Using .env

Create a .env file in the project root:

BUSYBAR_API_TOKEN=my-super-secret-token
BUSYBAR_BASE_URL=10.0.4.20

The server loads .env when it starts.

Using environment variables

You can also configure the server through variables already present in the process environment:

export BUSYBAR_API_TOKEN=my-super-secret-token
export BUSYBAR_BASE_URL=10.0.4.20

Then start the server normally.

Configuration precedence

Environment variables take precedence over values in .env. The server loads .env with override=False, so an environment variable that has already been exported is never replaced by the value in .env.

For example, if .env contains:

BUSYBAR_BASE_URL=10.0.4.20

but the shell contains:

export BUSYBAR_BASE_URL=10.0.4.30

then 10.0.4.30 is used.

Usage

Set BUSYBAR_API_TOKEN and BUSYBAR_BASE_URL through either .env or the environment, then start the MCP server:

# One-shot run via uvx (no local install required)
BUSYBAR_API_TOKEN=… BUSYBAR_BASE_URL=10.0.4.20 uvx busybar-mcp

# Or install locally and run the console script
uv sync
BUSYBAR_API_TOKEN=… BUSYBAR_BASE_URL=10.0.4.20 busybar-mcp

Local development and device testing with MCP Inspector

For local development, the Inspector needs to launch the installed busybar-mcp console script from the project environment. This ensures it uses the project's installed dependencies and loads .env from the project root.

  1. Install the project dependencies:

    uv sync
    
  2. Create a .env file in the project root using the variables documented above. Do not commit this file; it contains your device token.

  3. Start the Inspector in one terminal:

    npm exec --yes --package=@modelcontextprotocol/inspector -- mcp-inspector
    

    Leave that terminal running and open the local URL it prints.

  4. In the Inspector, select STDIO and configure:

    • Command: the absolute path to this checkout's .venv/bin/busybar-mcp
    • Arguments: leave empty
    • Working directory: the absolute path to this repository's root directory

    Use the project's own virtual environment and working directory. The server loads .env automatically; you do not need to enter BUSYBAR_API_TOKEN or BUSYBAR_BASE_URL in the Inspector when .env is configured.

  5. Click Connect, open Tools, and call a read-only device tool such as get_transport or get_timezone to verify connectivity. Tools that change device settings or send input events should only be used when you intend to make that change.

Troubleshooting: if mcp dev fails with inspector: command not found, use the manual Inspector workflow above. If the Inspector cannot connect, verify the command points to .venv/bin/busybar-mcp, the working directory is the project root, .env contains both required values, and the device is reachable from this machine.

mcp_entry.py is a dev-only entry helper for mcp dev / the MCP Inspector: it loads .env and registers tools on the server object, but is not a standalone server launcher. The regular mcp dev path may start a separate environment; for validating the locally installed SDK and dependencies, use the Inspector configuration above.

Once started, clients can connect to the server using their MCP transport.

MCP Tools

Account tools

Tool Description
get_account_info Retrieve linked account information (email, account ID) from the Busy Bar device
get_account_status Check MQTT connection state for the linked account
get_account_backend Inspect MQTT backend configuration (server URL, certificate settings)

System tools

Tool Description
get_api_version Query the API version supported by the device
get_transport Get the current network transport type (USB or Wi-Fi)
get_device_status Comprehensive health check: device, firmware, system, and power state
get_device_info Retrieve hardware identifiers and manufacturing details
get_firmware_info Get firmware version and build metadata
get_system_status Runtime system metrics (uptime, API SemVer, auto-update settings)
get_power_status Battery charge level, voltage, current, and charging state

Time tools

Tool Description
get_time Retrieve the device's real-time clock timestamp in ISO 8601 format
get_timezone Get the currently configured timezone (name, offset, abbreviation)
get_tzlist List all supported timezones available for configuration

Device Status & Configuration

Tool Description
get_ble_status Retrieve BLE module status (powered state, MAC address)
enable_ble Enable the BLE module and start advertising
disable_ble Disable the BLE module and stop advertising
remove_ble_pairing Remove the current BLE pairing so the device becomes discoverable again
get_busy_snapshot Get the current BUSY timer state including profile and timing details
get_http_access Inspect HTTP API key management mode and validity
get_device_name Get the human-readable device name
get_display_brightness Retrieve the current display brightness level
get_audio_volume Retrieve the current audio volume level
get_smart_home_pairing_status Query Matter fabric count and latest commissioning outcome
get_smart_home_switch_state Read smart home relay/output state and startup behavior
list_storage_files List files and directories on device storage (accepts optional path argument)
get_storage_status Get storage capacity details (used, free, total bytes)
get_firmware_update_status Check currently installed firmware and pending update state
get_update_changelog Retrieve release notes for a specific firmware version (accepts required version argument)
get_autoupdate_settings Get automatic update configuration (enabled, window start/end)
get_wifi_status Get Wi-Fi connection details (SSID, signal strength, channel, security)
get_wifi_networks Retrieve scanned available Wi-Fi networks in range (generated WiFiApi.get_wifi_networks() SDK call, GET /api/wifi/networks)

Input tools

Tool Description
send_input_key Send a single key-press event to the device (up, down, ok, back, start, busy, custom, off, apps, settings)

Architecture

The project follows a thin-client layering with a clear separation between MCP presentation, configuration, and device access:

┌───────────────────────────────┐      MCP/stdio       ┌──────────────────┐
│           MCP Client          │ ◄──────────────────► │   busybar_mcp    │
│         (AI tool)             │                      │                  │
└───────────────────────────────┘                      └────────┬─────────┘
                                                                │
                                      ┌─────────────────────────┼─────────────────────┐
                                      │                         │                     │
                                      ▼                         ▼                     ▼
                                  config.py                tools/              client.py
                                      │                         │                     │
                                      └─────────────────────────┼─────────────────────┘
                                                                │ SDK calls
                                                                ▼
                                                        busybar_python_sdk
                                                                │ HTTP
                                                                ▼
                                                          Busy Bar Device

Package structure

mcp_entry.py           # Repo-root dev-only entry file for mcp dev / MCP Inspector
busybar_mcp/
├── __init__.py       # Package API and entry point
├── __main__.py       # python -m busybar_mcp entry point
├── server.py         # MCP server and tool registration
├── client.py         # Busy Bar SDK client boundary
├── config.py         # Runtime configuration from environment
├── _server.py        # Backwards-compatible server import
├── utils.py          # Shared serialization/error utilities
└── tools/             # MCP tool modules and registration

The key responsibilities are:

  • server.py — creates the MCP server, registers the tool package, and starts the stdio transport.
  • config.py — reads BUSYBAR_BASE_URL and BUSYBAR_API_TOKEN from the process environment and validates that they are present.
  • client.py — provides the boundary between the MCP application and busybar_python_sdk.
  • tools/ — contains the MCP tool implementations and their registration.
  • utils.py — contains shared serialization and tool-error helpers.
  • __init__.py / __main__.py — provide the package and command-line entry points.
  • mcp_entry.py — repo-root dev-only entry file (loads .env, registers tools on server) for use with mcp dev; not part of the package or distribution.

At startup, server.py loads .env using load_dotenv(override=False). This means exported environment variables are preserved and take precedence over .env values.

The SDK communicates with the device over HTTP using the OpenAPI schema defined by openapi.yaml.

Testing

A working test suite is included with the project. The convenience runner at run_tests.py invokes pytest against the tests/ directory with sensible defaults and no-header output.

Run basic tests

python run_tests.py

Run with coverage output

COVERAGE=1 python run_tests.py

Coverage is reported via pytest-cov (--cov=busybar_mcp --cov-report=term-missing).

Test Coverage Summary

  • 32 MCP tools tested — one parametrized happy-path test per tool across account, system info, time, BLE, busy timer, settings, smart home, storage, update, wifi, and input categories.
  • Configuration tests verify required environment variables and configuration parsing.
  • Error-path tests verify behaviour when the Busy Bar device is missing or unreachable (mocked HTTP failures).
  • Missing environment variable tests confirm that absent BUSYBAR_BASE_URL / BUSYBAR_API_TOKEN are handled gracefully.
  • Serialization tests verify _serialize() handles SDK models, dicts, lists, scalars, and edge cases correctly.

Publishing

Releases are automated by the GitHub Actions pipeline (.github/workflows/publish.yml), triggered on every push to main:

  1. pyproject.toml metadata is synchronized (repository URL, testpypi index) via scripts/sync_metadata.py.
  2. The project version is aligned with the busybar-python-sdk version (the first X.Y.Z token in its dependency specifier).
  3. The updated commit is tagged v<version> (e.g., v27.5.1).
  4. The package is built with uv build (sdist + wheel).
  5. On success the artifacts are published to test.pypi.org via uv publish --index testpypi (never pypi.org).

Publishing requires a repository secret PyPI_API_TOKEN holding a test.pypi.org API token — obtain one at https://test.pypi.org/legacy/token/ and add it under Settings → Secrets and variables → Actions on https://github.com/nuxnik/busybar-mcp. Runs where the version was already published perform no commit, tag, or upload (idempotent).

What's Next

  • Extend with additional write/mutation tools (display messages, notifications)
  • Implement MCP resources for live device data streams
  • Configure linting and formatting toolchain

Metadata

Release files for busybar-mcp 27.5.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for busybar-mcp 27.5.1
File Size Uploaded Provenance
busybar_mcp-27.5.1.tar.gz 121.2 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for busybar-mcp 27.5.1
File Interpreter ABI Platform
busybar_mcp-27.5.1-py3-none-any.whl Python 3 none any Details

Total release size: 169.9 kB

Release files / busybar_mcp-27.5.1.tar.gz

Download URL busybar_mcp-27.5.1.tar.gz
Size 121.2 kB
Tags Source
SHA-256 checksum
How to use checksums
696a13924479b38123fde2c658a7646d4f36fad1171ba3691c182817174f8cee
BLAKE2b-256 checksum
How to use checksums
c08ffcb8a2fd72cc0a0f90af6a3ddb1b73a70ccaa8abb75ecd8e5bd9ad7be153
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.11

Release files / busybar_mcp-27.5.1-py3-none-any.whl

Download URL busybar_mcp-27.5.1-py3-none-any.whl
Size 48.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
05d2cdb675f7959c81312c02b69c14c2f9dea60168345eb044504f11b81fa006
BLAKE2b-256 checksum
How to use checksums
c2f0caf8c172665cf0381ba670951b09f0d0b4d2223047a8003fc0683cb42860
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.7.11

Security for busybar-mcp 27.5.1

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page