Skip to content
Conduit

mcp server

solar-manager-mcp

MCP server for Solar Manager (solar-manager.ch) — cloud API and local gateway API for AI assistants

aurelgreiner/solar-manager-mcpcommunitylistedunreviewed

Set up

Runs on your computer. Pick your agent and operating system.

This project does not publish an install method we can turn into a config. Follow the README instead.

README

synced Oct 23, 2026

solar-manager-mcp

An MCP server for Solar Manager, the Swiss PV energy management system. It lets an AI assistant read your plant's live and historical data — and, if you explicitly allow it, control your devices.

Both of Solar Manager's APIs are covered:

  • Cloud API (cloud.solar-manager.ch) — history, forecast, tariffs, statistics, device control. Needs an internet connection and a Cloud API key.
  • Local API (the gateway on your own network) — live values every few seconds, no internet, no cloud round-trip. Needs a local API key from the gateway UI.

One file, no build step, no framework. uv pulls the single dependency on first run. Works with Claude over stdio and with ChatGPT over HTTP.

Not affiliated with or endorsed by Solar Manager AG. Built against the public External API.

Tools

ToolWhat it does
list_endpoints(search)Lists the ~50 cloud endpoints, filtered by substring ("battery", "forecast", "tariff"). Deprecated ones are marked.
describe_endpoint(path, method)Parameters and response schema for one endpoint, $refs inlined.
request(method, path, query, body)Calls a cloud endpoint. Writes are blocked by default.
local_live()Live values from the gateway on your LAN, with device names resolved.

Why four tools instead of fifty

Generating one tool per endpoint would put ~50 tool definitions into the model's context and would need regenerating whenever Solar Manager ships a new API version. Instead the OpenAPI spec is fetched at runtime and searched on demand, so the server stays current on its own and costs almost no context. The assistant looks up what it needs, then calls it.

Setup

1. Get your keys

Cloud API key — in the Solar Manager portal: Profil bearbeiten → Cloud-API-Schlüssel → API Schlüssel hinzufügen. Pick the scopes you want:

ScopeNeeded for
readAll GET endpoints — data, forecast, devices, tariffs
externalOverride:readReading the external-override (control) state
writeConfiguration, e.g. PUT /v1/configure/sensor-priority
externalOverride:writeThe PUT /v1/control/* endpoints that actually switch hardware

Read-only (read + externalOverride:read) is the sane default. If the menu entry is missing, Solar Manager support has to enable the feature for your account.

Local API key — in the gateway UI: Einstellungen → Lokale API → API Schlüssel hinzufügen. Make sure the HTTP or HTTPS toggle is on. This is a different key from the cloud one and only works against the gateway itself.

Copy either key immediately — neither is shown again after creation.

2. Find your gateway's IP

The gateway answers on /v2/point. From a machine on the same network:

for i in $(seq 1 254); do (curl -sk -m 2 -o /dev/null -w "%{http_code} 192.168.1.$i\n" "https://192.168.1.$i/v2/point" &); done | grep 401

The host replying 401 (unauthorized, because no key was sent) is your gateway. Adjust the subnet to yours. Giving it a DHCP reservation saves you doing this again.

3. Register with your client

  • Claude — Claude Desktop and Claude Code, local, no tunnel needed
  • ChatGPT — needs developer mode and an HTTPS endpoint, so the server runs in HTTP mode behind a tunnel

The short version for Claude Desktop, keys inline in the config:

{
  "mcpServers": {
    "solar-manager": {
      "command": "uv",
      "args": ["run", "--script", "/absolute/path/to/solar-manager-mcp/server.py"],
      "env": {
        "SOLAR_MANAGER_API_KEY": "sm_...",
        "SOLAR_MANAGER_LOCAL_URL": "https://192.168.1.42",
        "SOLAR_MANAGER_LOCAL_API_KEY": "..."
      }
    }
  }
}

Every key is optional: cloud key only → cloud tools work; local key only → local_live() works; both → everything.

If you'd rather not have credentials in the config file — because it's synced, shared, or you juggle several clients — copy secrets.example.json to secrets.json next to server.py, chmod 600 it, and leave the env block out. Environment variables win over secrets.json when both are present.

4. Verify

uv run --script server.py --check

Offline self-check of the parts that can break silently. For an end-to-end test, ask your assistant "what is my solar plant doing right now?".

Usage notes

Most cloud endpoints are keyed by smId, the plant identifier. Get it from GET /v1/users (field sm_id). Typical calls:

GET /v1/overview                                    today / week / month / year totals
GET /v1/users                                       account info, sm_id
GET /v3/users/{smId}/data/range?from&to&interval    history (interval 300, 900 or 3600 s)
GET /v3/users/{smId}/data/stream                    latest values via the cloud
GET /v3/users/{smId}/data/forecast                  PV forecast, 15-minute steps
GET /v3/users/{smId}/devices                        devices incl. IP, MAC, priority
GET /v3/users/{smId}/tariffs                        tariff configuration

Reading the data

Field names are terse and shared across both APIs:

FieldMeaning
pW / pWhPV production, power in W / energy in Wh per interval
cW / cWhConsumption, power / energy
bcW / bcWhBattery charging, power / energy
bdW / bdWhBattery discharging, power / energy
socBattery state of charge in %
eWh / iWhPer device: energy exported / imported over the interval
scWh / cPvWhSelf-consumption including / excluding battery charging
cOtherWResidual consumption of unmetered devices
powerPer device power in W (negative = feeding in, e.g. a discharging battery)
activeDevice1 on/charging, 0 off, −1 discharging
t / ivTimestamp / interval in seconds the Wh values accumulate over

Device control

The PUT /v1/control/* endpoints physically switch batteries, car chargers, heat pumps and water heaters. They are blocked unless you set SOLAR_MANAGER_ALLOW_CONTROL=1. The safer route is not to grant the write scopes to your API key in the first place — then control is impossible rather than merely disabled.

The local API is read-only by nature: it exposes only /v2/point and /v2/devices. No history, no forecast, no control.

Gotchas

  • Never send your API key to POST /v3/auth/refresh. That endpoint treats it as a refresh token and rotates it, invalidating the key in your config. This server only ever sends x-api-key, which does not rotate.
  • /v2/customers times out server-side. Use /v1/users instead.
  • The local gateway uses a self-signed certificate, so TLS verification is disabled for that host only. Don't point SOLAR_MANAGER_LOCAL_URL at anything internet-facing.
  • Email/password auth (SOLAR_MANAGER_EMAIL + SOLAR_MANAGER_PASSWORD) still works as a fallback via the deprecated /v1/oauth/login, which Solar Manager removes in June 2027. Use an API key.

Requirements

uv and Python 3.10+. The only dependency is the MCP SDK, which uv installs on first run from the inline script metadata — nothing else to set up.

server.py --http serves the same tools over Streamable HTTP on 127.0.0.1:8000/mcp for clients that can't spawn a local process; see the ChatGPT guide.

License

MIT

↑↓ navigate openesc close