Skip to main content
Glama
chanyou0311

aiseg2-mcp

by chanyou0311
README.md
<!-- mcp-name: io.github.chanyou0311/aiseg2-mcp -->

# aiseg2-mcp

日本語版は [README.ja.md](./README.ja.md) をご覧ください。

An **unofficial, read-only** [Model Context Protocol](https://modelcontextprotocol.io) server for
the **Panasonic AiSEG2** home energy management (HEMS) controller. It lets an MCP client (e.g.
Claude) read your home's live power flow, per-circuit consumption, circuit names, and daily energy
totals from the AiSEG2's local web interface.

This project is not affiliated with or endorsed by Panasonic. "AiSEG" is a Panasonic trademark.

## Verified environment

Developed and tested against:

- AiSEG2 model **MKN713** series
- Firmware **Ver.2.97I-01**

The AiSEG2 web interface is undocumented and changes between firmware revisions. **On a different
model or firmware the pages this server scrapes may differ and some tools may not work.** If you hit
a parse error, please open an issue with your model / firmware version.

## Tools

All tools are **read-only** (annotated `readOnlyHint`, non-destructive). The server only issues
GETs and the display-only refresh POSTs the web UI itself uses; it never touches settings or any
`/action/` endpoint.

| Tool | Returns |
|---|---|
| `get_power_flow` | Instantaneous generation/consumption (kW), buy/sell state, battery status, generation sources, top consuming circuits |
| `get_circuit_breakdown` | Every measured circuit's instantaneous draw (W), ranked highest first, with the total |
| `list_circuits` | Registered circuit ids and names (the authoritative naming source) |
| `get_daily_totals` | Today's cumulative generation / consumption / grid-buy / grid-sell (kWh) |
| `get_history` | Long-term energy history from the SD-card export (Wh), long-form points. Args: `granularity` (`30min`/`hour`/`day`/`month`/`year`), `start`/`end` (per granularity: `YYYY-MM-DD`, `YYYY-MM`, or `YYYY`), optional `metrics`/`circuits` filters, `limit`/`offset` paging |
| `get_cost_history` | Long-term energy-cost history from the SD-card export (JPY). Args: `granularity` (`day`/`month`/`year`), `start`/`end`, `limit`/`offset` |

> **The two history tools require an SD card inserted in the AiSEG2** — they read the device's SD-card CSV export. The export is downloaded once and cached (see `AISEG_CACHE_DIR` / `AISEG_CACHE_TTL`), so the first call is slow and later calls are fast.

## Install & run

Three ways to run it, depending on your setup.

### 1. uvx (PyPI — once published)

The simplest option for a local (stdio) MCP client. Requires [uv](https://docs.astral.sh/uv/).

```bash
AISEG_URL=http://192.168.0.216 AISEG_PASSWORD=... uvx aiseg2-mcp
```

Add it to Claude Code:

```bash
claude mcp add aiseg2 \
  --env AISEG_URL=http://192.168.0.216 \
  --env AISEG_PASSWORD=your-digest-password \
  -- uvx aiseg2-mcp
```

### 2. docker run (GHCR)

The container defaults to the `streamable-http` transport (long-lived network service). Only expose
it behind an authenticating proxy — see [Security](#security).

```bash
docker run --rm -p 8000:8000 \
  -e AISEG_URL=http://192.168.0.216 \
  -e AISEG_PASSWORD=your-digest-password \
  ghcr.io/chanyou0311/aiseg2-mcp:latest
```

### 3. From source

Requires Python 3.12+ and uv.

```bash
uv sync
AISEG_URL=http://192.168.0.216 AISEG_PASSWORD=... uv run aiseg2-mcp
```

### Remote (authenticated claude.ai Custom Connector)

To reach the server from claude.ai while your AiSEG2 stays on your LAN, see
[`examples/remote/`](./examples/remote/) — a Docker Compose stack (MCP + GitHub-OAuth proxy +
Cloudflare Tunnel).

## Running the image

This repo's job ends at pushing the image to GHCR. Where and how it actually runs (Kubernetes
manifests, etc.) is defined elsewhere — for the maintainer's own deployment, in
[fumo-infra](https://github.com/chanyou0311/fumo-infra). The table below is the contract another
system builds against to run this image.

| | |
|---|---|
| Image & tags | `ghcr.io/chanyou0311/aiseg2-mcp:sha-<7hex>` on every push to `main` (created timestamp = the source commit's time, not the build time); a `vX.Y.Z` release tag additionally publishes `X.Y.Z`, `X.Y`, and `latest` |
| Listens on | `8000/tcp` — streamable-http MCP endpoint at `/mcp` |
| Health checks | liveness: `GET /health`; readiness: TCP connect on port `8000` |
| Required env | `AISEG_URL`, `AISEG_PASSWORD` (secret) |
| Optional env (default) | `AISEG_USER` (`aiseg`), `AISEG_TRANSPORT` (`streamable-http` — set as an image-level `ENV`; the package's own default, e.g. when run via `uvx`, is `stdio`), `AISEG_HOST` (`0.0.0.0`), `AISEG_PORT` (`8000`), `AISEG_DISABLE_DNS_REBINDING_PROTECTION` (`false`), `AISEG_CACHE_DIR` (`<tempdir>/aiseg2-mcp-cache`), `AISEG_CACHE_TTL` (`3600`), `LOG_LEVEL` (`info`) — see [Configuration](#configuration-environment-variables) below for details |

There is no deployment definition (Kubernetes manifests) in this repo.

## Configuration (environment variables)

| Variable | Required | Default | Description |
|---|---|---|---|
| `AISEG_URL` | yes | — | AiSEG2 base URL, e.g. `http://192.168.0.216` (http only) |
| `AISEG_PASSWORD` | yes | — | HTTP Digest password for the AiSEG2 web UI |
| `AISEG_USER` | no | `aiseg` | HTTP Digest user |
| `AISEG_TRANSPORT` | no | `stdio` | `stdio` or `streamable-http` |
| `AISEG_HOST` | no | `0.0.0.0` | Bind host (streamable-http only) |
| `AISEG_PORT` | no | `8000` | Bind port (streamable-http only) |
| `AISEG_DISABLE_DNS_REBINDING_PROTECTION` | no | `false` | Disable the SDK Host allowlist — **only** behind a trusted auth proxy |
| `AISEG_CACHE_DIR` | no | `<tempdir>/aiseg2-mcp-cache` | Where the SD-card history export is cached |
| `AISEG_CACHE_TTL` | no | `3600` | Seconds to reuse a cached history export before re-downloading |
| `LOG_LEVEL` | no | `info` | Log level |

## Security

- **LAN-only by design.** The AiSEG2 speaks plain HTTP with Digest auth; keep it and this server on
  a trusted local network. The password is read from the environment and is never logged.
- **Read-only.** There is no tool that changes a device setting. The tool surface is enforced by
  tests (registered-tool allowlist, tool-name guard, a source scan for `/action/`, and read-only
  annotation checks).
- **Do not expose the `streamable-http` transport to untrusted networks without authentication.**
  This server carries no auth of its own; if you run it as a network service, put an authenticating
  reverse proxy in front of it. `AISEG_DISABLE_DNS_REBINDING_PROTECTION=true` is only appropriate in
  that proxied setup.

## Acknowledgements

The AiSEG2 web interface is undocumented; this project builds on the reverse-engineering knowledge
shared by prior work:

- [shimosyan/aiseg2-influxdb-forwarder](https://github.com/shimosyan/aiseg2-influxdb-forwarder) — the circuit-paging "repeat the last page" terminator and the electric-flow fields.
- [hiroaki0923/aiseg2-bridge](https://github.com/hiroaki0923/aiseg2-bridge) — endpoint and page structure.
- [Bugfire/aiseg_download](https://github.com/Bugfire/aiseg_download) — Digest auth and data-endpoint conventions.

## License

[MIT](./LICENSE)

TDQS

A4.7/5.0

Scored across 6 tools

Disambiguation5/5

Each tool targets a distinct aspect: instantaneous overview, per-circuit draw, canonical names, daily totals, historical energy, and historical cost. The only slight overlap is get_power_flow's top circuits vs get_circuit_breakdown, but descriptions clearly differentiate summary versus full detail.

Naming Consistency5/5

All tools use snake_case verb_noun patterns: get_ for data retrieval and list_ for enumerating resources. The naming is consistent and predictable, following a clear convention.

Tool Count5/5

6 tools is well-scoped for a read-only energy monitoring API. Each tool provides a distinct piece of data without being redundant or overwhelming.

Completeness5/5

The tool set covers current status, per-circuit breakdown, canonical circuit list, daily cumulative totals, long-term history, and cost history. For a monitoring-focused server, this is complete and leaves no obvious dead ends.

Maintenance

ActivityMaintained
ResponsivenessNo issues