BYD Vehicle Bridge Server
FreeNot checkedA secure, read-only MCP server that connects to BYD electric vehicles via the BYD cloud API, enabling AI agents to query real-time vehicle data such as battery
About
A secure, read-only MCP server that connects to BYD electric vehicles via the BYD cloud API, enabling AI agents to query real-time vehicle data such as battery SOC, range, tire pressures, door states, and GPS.
README
Python MCP Docker Tests Docker License
A secure, read-only MCP (Model Context Protocol) server that connects to your BYD electric vehicle via the BYD cloud API. Designed for AI agents (like OpenClaw, Claude Code, or any MCP client) to query real-time vehicle data — battery SOC, range, tire pressures, door states, GPS, and more — while keeping your credentials safe on your own infrastructure.
Built with Python, pyBYD, and the MCP SDK.
Architecture
┌─────────────────────── Host Machine ──────────────────────────┐
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ Docker Network: byd-internal (172.28.0.0/16) │ │
│ │ │ │
│ │ ┌──────────────────────┐ MCP (SSE) ┌──────────┐ │ │
│ │ │ AI Agent │◄──────────────►│ BYD │ │ │
│ │ │ (OpenClaw / Claude) │ │ Bridge │ │ │
│ │ │ │ │ │ │ │
│ │ │ Tools: │ │ Tools: │ │ │
│ │ │ · get_battery() │ │ · poll │ │ │
│ │ │ · get_vehicle() │ │ · cache │ │ │
│ │ │ · get_all_data() │ │ · serve │ │ │
│ │ │ · get_health() │ │ │ │ │
│ │ └──────────────────────┘ └─────┬────┘ │ │
│ │ │ │ │
│ │ BYD Cloud API │ │
│ │ │ │ │
│ │ ┌────▼────┐ │ │
│ │ │ BYD │ │ │
│ │ │ Cloud │ │ │
│ │ └─────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ Credentials stored in .env — never leave this machine │
└───────────────────────────────────────────────────────────────┘
Key Design Decisions
| Decision | Rationale |
|---|---|
| MCP over REST | AI agents discover tools natively via the Model Context Protocol. No manual URL memorization, no raw HTTP parsing. |
| SSE transport | Server-Sent Events over HTTP — standard MCP transport, compatible with all MCP clients. |
| Background polling | The server polls the BYD API every 60s and caches results. Tools return instant cached data, never block on the network. |
| Internal Docker network | The bridge container exposes zero ports to the host. Only containers on the same Docker network can reach it. |
| Read-only by design | Remote commands (lock/unlock, AC control, windows) are intentionally excluded. This bridge reads, never writes. |
| Dual mode | minimal mode for privacy-sensitive users (no GPS, no door states). full mode for complete telemetry. |
| ghcr.io registry | Docker image published to GitHub Container Registry. Pull on any server — no rebuild needed. |
| PR workflow | All changes go through pull requests. Tests run automatically on every PR. |
Features
- 🔋 Battery Monitoring — State of charge (SOC %), estimated range, charging status
- 🚗 Driving Data — Speed, power (kW), odometer, outside/cabin temperature
- 🔌 Charging Details — Voltage, current, charge rate, time to full (full mode)
- 🛞 Tire Pressures — All four wheels with units (full mode)
- 🚪 Door & Window States — Open/closed status, lock state (full mode)
- 📍 GPS Location — Latitude, longitude, heading (full mode)
- 🌡️ HVAC Status — AC on/off, target temperature, fan speed (full mode)
- 🔒 Read-Only — No remote commands. No write access. Ever.
- 🐳 Dockerized — Single container, minimal footprint, non-root user
- 🔐 Credentials Safe — BYD username/password never leave your VPS
- 🧪 28 Unit Tests — Full test suite runs on every PR via GitHub Actions
- ⚙️ CI/CD — Automated tests + Docker image build + push to ghcr.io
MCP Tools
| Tool | Mode | Description |
|---|---|---|
get_battery() |
both | Battery SOC %, charging status, range, mileage, temps, speed, power |
get_vehicle() |
both | VIN, model, brand, plate, energy type |
get_all_data() |
both | Everything available (mode-dependent) |
get_health() |
both | Connection status, mode, poll interval, last poll time, errors |
Tool Output Example
// get_battery() response
{
"soc_percent": 73,
"charging_status": "disconnected",
"estimated_range_km": 280,
"mileage_km": 12450,
"outside_temp_c": 31.5,
"cabin_temp_c": 28.0,
"speed_kmh": 0,
"engine_power_kw": 0.0,
"fuel_percent": null,
"last_updated": "2026-07-31T08:30:00+00:00"
}
Quick Start
Prerequisites
- A BYD electric vehicle with an active BYD account
- A server with Docker and Docker Compose installed
- An MCP client (OpenClaw, Claude Code, etc.)
1. Pull the Image
docker pull ghcr.io/pavelpervi/byd-vehicle-bridge:latest
2. Configure
Create a directory and .env file:
mkdir -p /opt/byd-bridge && cd /opt/byd-bridge
cat > .env << 'EOF'
[email protected]
BYD_PASSWORD=your-password
BYD_COUNTRY=IL
BYD_MODE=minimal # or "full"
EOF
3. Deploy with Docker Compose
# docker-compose.yml
cat > docker-compose.yml << 'EOF'
services:
byd-bridge:
image: ghcr.io/pavelpervi/byd-vehicle-bridge:latest
container_name: byd-bridge
restart: unless-stopped
env_file: .env
networks:
- byd-internal
healthcheck:
test: ["CMD", "python3", "-c", "import socket; s=socket.create_connection(('localhost', 8000), timeout=5); s.close()"]
interval: 30s
timeout: 10s
retries: 3
start_period: 15s
networks:
byd-internal:
driver: bridge
ipam:
config:
- subnet: 172.28.0.0/16
EOF
docker compose up -d
4. Connect Your MCP Client
For OpenClaw (running on the same host):
# Connect the OpenClaw container to the bridge network
docker network connect byd-internal <openclaw-container-name>
# Register the MCP server
openclaw mcp add byd-bridge --url http://byd-bridge:8000 --transport sse --timeout 30
For Claude Code or any stdio MCP client:
{
"mcpServers": {
"byd-bridge": {
"command": "docker",
"args": ["exec", "-i", "byd-bridge", "python3", "-m", "byd_bridge"]
}
}
}
5. Verify
# Check the container is running
docker ps | grep byd-bridge
# View logs
docker logs byd-bridge
# Test the MCP tools
openclaw mcp call byd-bridge get_health
openclaw mcp call byd-bridge get_battery
Expected output from get_health:
{
"status": "ok",
"mode": "minimal",
"vehicle_connected": true,
"last_successful_poll": "2026-07-31T08:30:00+00:00",
"poll_interval_s": 60,
"error": null
}
Security
What's Protected
| Concern | How It's Addressed |
|---|---|
| Credentials | BYD username/password stored in .env on your VPS only. Never sent to the AI agent. |
| Network Exposure | Zero ports published to the host. Only accessible on the internal Docker network. |
| Write Access | No remote commands implemented. The bridge reads data only. |
| Privilege Escalation | Container runs as non-root user, read-only filesystem, all Linux capabilities dropped. |
| GPS Privacy | GPS data only available in full mode. Default minimal mode excludes it. |
Minimal vs Full Mode
| Data Point | minimal |
full |
|---|---|---|
| Battery SOC, range, charging | ✅ | ✅ |
| Speed, power, mileage | ✅ | ✅ |
| Outside/cabin temperature | ✅ | ✅ |
| Vehicle info (VIN, model) | ✅ | ✅ |
| Tire pressures | ❌ | ✅ |
| Door/window states | ❌ | ✅ |
| GPS location | ❌ | ✅ |
| Charging voltage/current | ❌ | ✅ |
| HVAC status | ❌ | ✅ |
Configuration Reference
| Variable | Default | Description |
|---|---|---|
BYD_USERNAME |
— | BYD account email or phone (required) |
BYD_PASSWORD |
— | BYD account password (required) |
BYD_COUNTRY |
IL |
ISO country code for API region |
BYD_MODE |
minimal |
minimal or full data scope |
POLL_INTERVAL |
60 |
Seconds between BYD API polls |
BYD_PORT |
8000 |
MCP server port (internal) |
Project Structure
byd-vehicle-bridge/
├── src/
│ └── byd_bridge/ ← Python package
│ ├── __init__.py
│ ├── __main__.py ← Entry: python -m byd_bridge
│ ├── config.py ← Settings from env vars (lazy singleton)
│ ├── state.py ← BridgeState + background poller
│ └── server.py ← MCP server with 4 tools
├── tests/
│ ├── __init__.py
│ ├── conftest.py ← Shared fixtures
│ ├── test_config.py ← 12 tests: validation, defaults, errors
│ ├── test_state.py ← 5 tests: init, data shapes, copy safety
│ └── test_server.py ← 11 tests: before/after poll, registration
├── .github/
│ └── workflows/
│ ├── tests.yml ← CI: runs tests on every PR
│ └── docker-build.yml ← CD: builds & pushes image to ghcr.io
├── Dockerfile
├── docker-compose.yml
├── pyproject.toml ← Modern Python project config
├── requirements.txt
├── .env.example
├── .gitignore
├── README.md
└── LICENSE
Running Tests
Tests are run automatically on every pull request via GitHub Actions, but you can also run them locally:
# Install dependencies
pip install -r requirements.txt
pip install -e .
# Run all 28 tests
python -m pytest tests/ -v
Test Coverage
| Test File | Tests | What It Covers |
|---|---|---|
test_config.py |
12 | Mode validation, env parsing, defaults, missing credentials |
test_state.py |
5 | BridgeState init, data shapes, copy safety |
test_server.py |
11 | Tool registration, before/after poll states, async MCP calls |
CI/CD Pipeline
| Event | Workflow | What Happens |
|---|---|---|
| Push to PR branch | tests.yml |
Runs all 28 tests, lints with Ruff |
PR merged to main |
tests.yml + docker-build.yml |
Tests pass, then Docker image is built and pushed to ghcr.io/pavelpervi/byd-vehicle-bridge |
Tag pushed (v*.*.*) |
docker-build.yml |
Image tagged with semver (v1.0.0) |
Retention: Only the latest 5 versions are kept in ghcr.io. Old sha-* images are automatically cleaned up.
How It Works
Background Polling
When the server starts, a daemon thread launches an async event loop that:
- Authenticates to the BYD cloud API using pyBYD
- Fetches the vehicle list and real-time data
- In
fullmode, also fetches GPS, charging details, and HVAC status - Caches everything in memory
- Sleeps for
POLL_INTERVALseconds, then repeats
MCP Tool Calls
When an AI agent calls a tool (e.g., get_battery()):
- The MCP server receives the request
- Looks up the cached data from the latest poll
- Returns the data immediately — no network call to BYD
- The agent receives structured, typed data
This means tool calls are instant (single-digit milliseconds) — the latency lives in the background poller, not in the agent's request.
Why SSE Transport?
MCP supports three transports:
| Transport | Use Case |
|---|---|
| stdio | Local subprocess — server runs as a child of the MCP client |
| SSE | Remote server — HTTP with Server-Sent Events (what we use) |
| Streamable HTTP | Newer HTTP transport — simpler than SSE |
SSE is the standard choice for a Docker-deployed MCP server. It requires no special client configuration beyond the URL.
Tech Stack
- Python 3.12 — Core language
- pyBYD — Async Python client for the BYD vehicle API
- MCP SDK — Model Context Protocol SDK (v2.0.0+,
MCPServerclass) - Docker — Containerization
- GitHub Actions — CI/CD: tests + image build
- GitHub Container Registry — Docker image hosting
- python-dotenv — Environment variable management
- pytest — Test framework
- Ruff — Python linter
Development
Prerequisites
git clone https://github.com/pavelpervi/byd-vehicle-bridge.git
cd byd-vehicle-bridge
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt
pip install -e .
Run the Server Locally
# Set BYD credentials
export [email protected]
export BYD_PASSWORD=your-password
export BYD_COUNTRY=IL
export BYD_MODE=minimal
# Start the MCP server
python -m byd_bridge
The server starts on port 8000 (or BYD_PORT if set).
Run Tests
# Set test env vars (required by config module)
export [email protected]
export BYD_PASSWORD=test-password
# Run all tests
python -m pytest tests/ -v
Build the Docker Image Locally
docker build -t byd-bridge .
docker run --rm -p 8000:8000 --env-file .env byd-bridge
Acknowledgements
- pyBYD — The excellent Python library that makes BYD API access possible
- hass-byd-vehicle — Home Assistant integration that inspired this project
- Model Context Protocol — The protocol standardizing AI-tool communication
License
MIT
Installing BYD Vehicle Bridge Server
This server has no published package — it is built from source. Open the repository and follow its README.
▸ github.com/pavelpervi/byd-vehicle-bridgeFAQ
Is BYD Vehicle Bridge Server MCP free?
Yes, BYD Vehicle Bridge Server MCP is free — one-click install via Unyly at no cost.
Does BYD Vehicle Bridge Server need an API key?
No, BYD Vehicle Bridge Server runs without API keys or environment variables.
Is BYD Vehicle Bridge Server hosted or self-hosted?
A hosted option is available: Unyly runs the server in the cloud, no local setup required.
How do I install BYD Vehicle Bridge Server in Claude Desktop, Claude Code or Cursor?
Open BYD Vehicle Bridge Server on unyly.org, pick your client tab (Claude Desktop, Claude Code, Cursor) and press Install — the config is generated automatically, no JSON editing.
Related MCPs
Fetch
Web content fetching and conversion for efficient LLM usage.
AWS KB Retrieval
Retrieval from AWS Knowledge Base using Bedrock Agent Runtime.
by modelcontextprotocolSpring AI MCP Server
Provides auto-configuration for setting up an MCP server in Spring Boot applications.
llm-analysis-assistant
A very streamlined mcp client that supports calling and monitoring stdio/sse/streamableHttp, and can also view request responses through the /logs page. It also
by xuzexin-hzCompare BYD Vehicle Bridge Server with
Not sure what to pick?
Find your stack in 60 seconds
Author?
Embed badge for your README
Browse similar
All ai MCPs
