Skip to main content
Glama
README.md
# ams-mcp

Reads a home electricity meter by voice. It is a small MCP server that asks the
meter's HAN-port reader, an [AmsToMqttBridge](https://github.com/UtilitechAS/amsreader-firmware)
device on the home network, what it has seen, and answers in a sentence to read
aloud. It is made as a plugin for claude-voice, and works with any MCP client
over stdio.

It only reads. It sends nothing but GET, to seven JSON pages the reader shows
without a login, and never a page that saves a setting, reboots or upgrades
([ADR-AM-001](decisions/ADR-AM-001-read-the-readers-own-pages-over-http.md)).

## The five tools

| Tool | Says |
|---|---|
| `ams_now` | the power drawn or sent now, each phase's volts and amps, and the power factor |
| `ams_energy` | kWh in and out, and what it cost, this hour, today and this month |
| `ams_price` | the price now, the next hours, and the cheapest hours left today |
| `ams_capacity` | the capacity step, the month's top three hours, and how far this hour is from the next step |
| `ams_history` | today by hour, or this month by day, in short |

Every answer has `say`, in kW, kWh and kr, `success`, and `read_at`, the time
of the reading. A reading older than about 30 seconds, or one the reader has
not had from the meter lately, starts "Not confirmed".

## Try it without the meter

`--simulate` answers from pages recorded off a real reader, and says so:

```console
$ ams-mcp ask now --simulate
Simulated: Drawing 1.05 kW from the grid now. The phases carry 2.9, 0.9 and 1.5 A. This meter sends no power factor.
$ ams-mcp ask energy --simulate
Simulated: Today 33.2 kWh, 30.85 kr. This hour 0.32 kWh. This month 605 kWh, 548 kr.
```

## Point it at the reader

The address goes in a file of your own, never in this repository:

<!-- not run: it writes into the reader's own settings folder -->
```toml
# ~/.config/ams-mcp/config.toml
[reader]
address = "192.0.2.10"     # the reader's address on your network
timezone = "Europe/Oslo"   # optional; the computer's own by default
```

Without it, the server says where the file should be and stops:

```console
$ ams-mcp serve --settings-file /nowhere/config.toml
ams-mcp: No settings file at /nowhere/config.toml; write [reader] address = "..." there, or use --simulate.
```

`ams-mcp serve` then serves the tools over stdio. For claude-voice:

<!-- not run: it is a block for claude-voice's own settings file -->
```toml
[plugins.ams]
command = "uv"
args = ["run", "ams-mcp", "serve"]
cwd = "~/ams-mcp"
tools = ["ams_now", "ams_energy", "ams_price", "ams_capacity", "ams_history"]
timeout = 30
```

What each of the reader's short keys means, read from the firmware's source,
is in [docs/pages.md](docs/pages.md).

## The gates

Every one of these runs in continuous integration, and all of them run here:

```console
$ uv run ruff check .
All checks passed!
```

<!-- not run: the workflow runs each of these; nesting them here would run the suite inside itself -->
```bash
uv run ruff format --check .   # layout
uv run mypy src                # types
uv run pytest -q               # behaviour
python scripts/mutate.py       # that each rule's own test can fail
```

`CONTRIBUTING.md` says what each one is for, and
[`decisions/`](decisions/README.md) records the choices that shaped them,
including how a change is made here.

## Licence

GPL-3.0-or-later. See [LICENSE](LICENSE).

TDQS

A3.7/5.0

Scored across 5 tools

Disambiguation4/5

Each tool targets a distinct facet of metering data: instantaneous power (ams_now), accumulated energy/cost (ams_energy), spot price (ams_price), capacity step (ams_capacity), and period summaries (ams_history). The only real overlap is between ams_energy and ams_history, which both cover today's/month's totals, but the descriptions differentiate them (kWh+cost figures vs. peak-hour/busiest-day summaries).

Naming Consistency5/5

All five tools follow one clean pattern: the `ams_` server prefix plus a single domain noun (now, energy, price, capacity, history). There is no mixing of verbs, casing, or styles.

Tool Count5/5

Five focused read-only tools is a well-scoped surface for a smart-meter data server; each tool maps to a distinct question a user would ask (current draw, consumption, price, capacity, history). Nothing feels padded or missing at the count level.

Completeness4/5

The surface covers the core read-only lifecycle: live power, energy/cost over hour/day/month, hourly prices with forward look, capacity, and day/month rollups. Minor gaps remain—no arbitrary date-range or deeper historical queries (only 'day'/'month' with last month), and no way to act on capacity or price data.

Maintenance

ActivityMaintained
ResponsivenessNo recent community issues