Skip to main content
Glama
holger1411

unofficialMCP4Vaillant

by holger1411
README.md
# unofficialMCP4Vaillant

An **unofficial** MCP (Model Context Protocol) server that exposes a Vaillant
heat pump's data to AI assistants like Claude. Query outdoor and room
temperatures, hot water status, energy consumption, COP estimates, schedules,
and diagnostics through natural conversation.

**This project is not affiliated with, endorsed by, or sponsored by Vaillant
Group.** "Vaillant" is a registered trademark of Vaillant Group; it is used
here only to describe what the server connects to.

> **Disclaimer:** This project uses an unofficial, reverse-engineered API via
> [`myPyllant`](https://github.com/signalkraft/mypyllant) and is **not affiliated
> with Vaillant Group**. The API may change or break at any time. Use at your
> own risk.

## Features (v1, read-only)

- **Status snapshot** — outdoor / room / DHW temperatures, water pressure,
  per-zone setpoints, per-circuit flow temperature, special functions.
- **Hardware inventory** — controller, firmware, all heat generators and
  auxiliary devices, serial numbers.
- **Energy report** — consumption, environment energy, heat generated per
  device per operation mode, with a derived **COP estimate** and quality flag.
- **Diagnostics** — trouble codes, heating curve, bivalence points, holiday
  mode.

Write/control operations are explicitly out of scope for v1.

## Prerequisites

- A MyVaillant account with at least one claimed system.
- Python **3.10–3.13** (myPyllant does not yet support 3.14).
- Claude Desktop or any MCP-compatible client.

## Installation

```bash
git clone https://github.com/holger1411/unofficialMCP4Vaillant.git
cd unofficialMCP4Vaillant
python3.12 -m venv .venv
source .venv/bin/activate
pip install -e .
```

## Configuration

```bash
cp .env.example .env
# edit .env and set VAILLANT_USERNAME, VAILLANT_PASSWORD,
# and (if not in Germany or not the Vaillant brand) VAILLANT_BRAND / VAILLANT_COUNTRY.
```

| Variable | Default | Description |
|---|---|---|
| `VAILLANT_USERNAME` | _required_ | MyVaillant account email |
| `VAILLANT_PASSWORD` | _required_ | MyVaillant account password |
| `VAILLANT_BRAND` | `vaillant` | One of `vaillant`, `sdbg`, `bulex`, `glow-worm` |
| `VAILLANT_COUNTRY` | `germany` | Country slug (see `myPyllant.const.COUNTRIES`) |
| `VAILLANT_DEFAULT_SYSTEM_ID` | _empty_ | Override picked system when more than one exists |
| `VAILLANT_CACHE_ENABLED` | `true` | Disable for debugging |
| `VAILLANT_LOG_LEVEL` | `INFO` | DEBUG / INFO / WARNING / ERROR |

### Claude Desktop

Add to your `claude_desktop_config.json` (see
`claude_desktop_config_snippet.json` for a template):

```json
{
  "mcpServers": {
    "unofficial-mcp4vaillant": {
      "command": "/absolute/path/to/unofficialMCP4Vaillant/.venv/bin/python",
      "args": ["-m", "vaillant_mcp_server"],
      "env": {
        "VAILLANT_USERNAME": "your-email@example.com",
        "VAILLANT_PASSWORD": "your-password"
      }
    }
  }
}
```

## Available Tools

| Tool | Description |
|---|---|
| `vaillant_get_status` | Current temperatures, water pressure, modes, per-zone/DHW state |
| `vaillant_get_devices` | Static hardware inventory |
| `vaillant_get_energy_report` | Energy consumption + COP estimate over a time range |
| `vaillant_get_diagnostics` | Trouble codes, heating curve, holiday mode |

Time ranges accepted: `today`, `yesterday`, `week` (ISO Mon–today), `month`,
`year`, `custom`. All ranges are resolved in the **home's local timezone**, not
the host's.

## Architecture

- Single long-lived `MyPyllantAPI` instance, owned by a `VaillantClient`.
  Concurrent reads are lock-free; the lock is held only during initial login
  and re-login.
- On `401`/`403`, the client transparently re-authenticates and retries the
  call once. The old API instance stays usable for in-flight callers and is
  closed after they drain.
- Transient errors (5xx, timeouts, connection resets) retry up to 3× with
  jittered exponential backoff. Rate limits (`429`) raise a dedicated error
  honoring `Retry-After`.
- Per-tool TTL cache (`status` 60 s, `devices` 24 h, `energy_report` 5 min,
  `diagnostics` not cached). **Failures are never cached.**
- All logs go to stderr through a `SecretRedactor` filter that scrubs
  credentials, tokens, serial numbers, and UUIDs.

## Security

See [`SECURITY.md`](SECURITY.md). Report security issues via GitHub Private
Vulnerability Reporting, **not** as public issues.

## Development

```bash
pip install -e '.[dev]' || pip install -r requirements-dev.txt
pytest
ruff check .
mypy
```

See [`CONTRIBUTING.md`](CONTRIBUTING.md) for fixture-capture and live-test
workflows.

## Credits

This project would not exist without:

- **[signalkraft/mypyllant](https://github.com/signalkraft/mypyllant)** — the
  reverse-engineered Python library that does all the actual API work.
  ([PyPI](https://pypi.org/project/myPyllant/))
- **[Model Context Protocol](https://modelcontextprotocol.io)** — the open
  protocol that makes this server interoperable across AI assistants.
- **[holger1411/polestar-mcp](https://github.com/holger1411/polestar-mcp)** —
  pattern reference for the long-lived async client + TTL cache layout.

## License

[MIT](LICENSE).

TDQS

A3.8/5.0

Scored across 4 tools

Disambiguation5/5

Each tool targets a distinct aspect: devices for hardware inventory, diagnostics for configuration and faults, energy report for consumption data, and status for live system state. No overlap in purpose.

Naming Consistency5/5

All tools follow a consistent pattern: 'vaillant_get_<resource>', using snake_case and a uniform verb-noun structure.

Tool Count5/5

Four tools is well-scoped for a read-only monitoring server covering essential areas: inventory, diagnostics, energy, and live status.

Completeness4/5

Covers all key read-only needs for a heat pump system. Minor gap: no historical trending beyond energy report, and no tool for firmware updates or config changes, but those are likely write operations outside scope.

Maintenance

ActivityInactive
ResponsivenessNo issues