Skip to main content
Glama
DasClown

strompreis-mcp

by DasClown
README.md
# ⚡ Strompreis MCP — Electricity Price Forecast for AI Agents

[![Python ≥3.11](https://img.shields.io/badge/python-%3E%3D3.11-blue.svg)](https://www.python.org/downloads/)
[![License: MIT](https://img.shields.io/badge/license-MIT-green.svg)](LICENSE)
[![Smithery](https://img.shields.io/badge/Smithery-Install-7C3AED)](https://smithery.ai/servers/DasClown/strompreis-mcp)

**MCP server that gives AI agents German electricity prices — real day-ahead auction prices where available, statistical estimates beyond.**
Tells your smart home agent when to run the dishwasher, charge the car, or schedule power-hungry tasks.

Built for the [Model Context Protocol](https://modelcontextprotocol.io) — works with Claude Desktop, Cline, and any MCP-compatible client.

---

## Architecture

```
                    ┌────────────────────────────┐
                    │    SMARD (Bundesnetzagentur) │
                    │    Live-Strompreise 15min    │
                    └──────────┬─────────────────┘
                               │ API
                    ┌──────────▼─────────────────┐
                    │   strompreis-collector       │
                    │   (Cron: every 15 min)       │
                    └──────────┬─────────────────┘
                               │ writes
                    ┌──────────▼─────────────────┐
                    │   SQLite Database             │
                    │   ~/.strompreis/strompreis.db │
                    │   ├── price_data (historical) │
                    │   ├── api_keys (auth)         │
                    │   └── usage_log (rate limit)  │
                    └──────────┬─────────────────┘
                               │ reads
              ┌────────────────┼────────────────┐
              │                │                 │
    ┌─────────▼──────┐  ┌─────▼──────┐  ┌──────▼─────────┐
    │  MCP Server     │  │  B2C Site   │  │  CLI Tools     │
    │  (stdio/SSE)    │  │  (FastAPI)  │  │  status/vacuum │
    │  price_forecast │  │  savings    │  │                 │
    │  best_hours     │  │  checker    │  │                 │
    │  db_status      │  │  affiliate  │  │                 │
    └─────────────────┘  └────────────┘  └─────────────────┘
```

## Quick Start

### 1. Install

```bash
pip install strompreis-mcp
```

Or from source:
```bash
git clone https://github.com/DasClown/strompreis-mcp.git
cd strompreis-mcp
pip install -e .
```

### 2. Initialize database + first data collection

```bash
# Automatic setup
bash scripts/setup.sh

# Or manual:
strompreis-collector collect
strompreis-collector status
```

### 3. Add to Claude Desktop

Edit `~/.config/Claude/claude_desktop_config.json`:

```json
{
  "mcpServers": {
    "strompreis": {
      "command": "strompreis-mcp"
    }
  }
}
```

Or with Cline / any MCP client:
```json
{
  "mcpServers": {
    "strompreis": {
      "command": "strompreis-mcp",
      "args": []
    }
  }
}
```

## Tools & Resources

Built on the **official MCP Python SDK** (`mcp.server.fastmcp.FastMCP`).

### Tools

| Tool | Parameters | Returns |
|:-----|:-----------|:--------|
| `price_forecast` | `hours` (1-72, default 24) | JSON array: `[{timestamp, price_ct, confidence, is_peak, source}]` |
| `best_hours` | `count` (default 3) | Human-readable cheapest hours recommendation |
| `db_status` | _none_ | Database health: rows, latest timestamp, usage stats (incl. keyless quota) |

### Resources (read-only URIs)

| URI | Description |
|:----|:------------|
| `strompreis://prices/live` | Most recent SMARD day-ahead series (raw + ct/kWh) |
| `strompreis://prices/history` | Local DB history (last 30 days) |
| `strompreis://db/status` | Database health snapshot as JSON |

Resources sind nützlich für Clients, die URIs bevorzugen statt Tool-Calls (z. B. zum Einbetten in Kontextfenster).

Each `price_forecast` entry carries a `source` field:

- **`auction`** — verbindlicher Day-Ahead-Auktionspreis (EPEX, via SMARD), `confidence = 1.0`. Gilt typ. für die nächsten 24–36 h, sobald die Auktion veröffentlicht wurde.
- **`statistical`** — Schätzung aus historischem Stunden-/Wochentagsprofil + kurzfristigem Trend, für Stunden jenseits des Auktionshorizonts. `confidence` sinkt mit der Distanz.

So weiß der Agent (und der User), ob eine Empfehlung auf echten Preisen beruht oder geschätzt ist.

### Example Prompts

> *"When is the cheapest time to run my laundry today?"*  
> → Agent calls `best_hours(count=3)` → Empfehlung aus Auktionspreisen (✓) oder Schätzung (~), inkl. Herkunft.

> *"What's the electricity price forecast for tomorrow?"*  
> → Agent calls `price_forecast(hours=48)` → Stundenpreise in ct/kWh, gemischt auction/statistical.

> *"Should I charge my EV now or wait?"*  
> → Agent calls `price_forecast(hours=24)`, findet das günstigste Fenster.

## Database Persistence

The database lives at `~/.strompreis/strompreis.db`. It persists:

| Table | Purpose | Retention |
|:------|:--------|:----------|
| `price_data` | Historical SMARD prices + generation data; `timestamp_utc` ist `UNIQUE` (Dedup) | Unlimited (for ML training) |
| `api_keys` | Monetization: tier-based API access | Manual expiration |
| `usage_log` | Rate limiting + analytics (auch keyless, mit `api_key IS NULL`) | Accumulates |
| `price_meta` | Schema-Versionierung für automatische Migrationen | Persistent |

Beim Start migriert das Paket ältere Schemata automatisch (siehe `CHANGELOG.md`).

### Cron Setup (recommended)

```bash
# Fetch data every 15 minutes
*/15 * * * * cd /path/to/strompreis-mcp && strompreis-collector collect

# Weekly database maintenance (Sunday 03:00)
0 3 * * 0 cd /path/to/strompreis-mcp && strompreis-collector vacuum
```

Or use the provided crontab:
```bash
crontab deploy/crontab
```

### CLI Commands

```bash
# Fetch + store latest SMARD data
strompreis-collector collect

# Show database health
strompreis-collector status
# → 📊 Strompreis DB Status
#     Total rows:     1,248
#     Latest data:    2026-06-30T21:00:00+00:00
#     DB file size:   180 KB

# Weekly maintenance
strompreis-collector vacuum
```

## Deployment

### Transports

Der Server unterstützt alle MCP-Transporte (über `STROMPREIS_TRANSPORT`):

| Transport | Use Case | Aufruf |
|:----------|:---------|:-------|
| `stdio` (default) | Lokale Clients (Claude Desktop, Cline) | `strompreis-mcp` |
| `sse` | Remote, B2C-Site, getunnelt | `STROMPREIS_TRANSPORT=sse strompreis-mcp` |
| `streamable-http` | Modernes Remote (empfohlen für Produktion) | `STROMPREIS_TRANSPORT=streamable-http strompreis-mcp` |

Konfiguriere Host/Port via `--host` / `--port` oder `MCP_HOST` / `MCP_PORT`.

### systemd (production)

```bash
# Edit deploy/strompreis-mcp.service paths for your system, then:
sudo cp deploy/strompreis-mcp.service /etc/systemd/system/
sudo systemctl enable --now strompreis-mcp

# Monitor
journalctl -u strompreis-mcp -f
```

### B2C Website (side-stream)

```bash
# Install dependencies
pip install strompreis-mcp[b2c]

# Run
python3 -m uvicorn b2c.server:app --host 0.0.0.0 --port 8080
```

Then open `http://localhost:8080` — users enter their annual kWh consumption and get:
- ✅ Savings calculation (fixed vs dynamic tariff)
- ✅ Tibber/Awattar affiliate comparison
- ✅ 24h price forecast snippet

#### B2C Configuration (env vars)

Keine Secrets im Source. Alle IDs/URLs kommen aus der Umgebung:

| Variable | Zweck |
|:---------|:------|
| `STROMPREIS_AWIN_ID` | Awin Publisher-ID für Tibber-Affiliate |
| `STROMPREIS_TIBBER_URL` | Override: vollständiger Tibber-Link |
| `STROMPREIS_AWATTAR_URL` | Override: Awattar-Partner-Link |
| `STROMPREIS_IMPRINT_URL` | Impressum-URL (DSGVO, Footer) |
| `STROMPREIS_PRIVACY_URL` | Datenschutz-URL (DSGVO, Footer) |
| `STROMPREIS_FESTPREIS_AVG` | Avg. Festpreis ct/kWh (Default 28.0) |
| `STROMPREIS_BÖRSEN_AUFSCHLAG` | Dynamisch-Aufschlag ct/kWh (Default 5.5) |

**Wichtig (kommerzieller Betrieb, DSGVO):** Für eine öffentliche B2C-Seite brauchst du Impressum und Datenschutzerklärung. Setze `STROMPREIS_IMPRINT_URL` und `STROMPREIS_PRIVACY_URL` — sie erscheinen im Footer.

### Smithery

[![Smithery](https://img.shields.io/badge/Smithery-Install-7C3AED)](https://smithery.ai/servers/DasClown/strompreis-mcp)

One-click install for Claude Desktop via Smithery.

## API Key Mode (keyed mode, for production/Multi-Tenant)

By default the server runs in **keyless mode** (100 req/day global limit, persisted in DB).  
For production use, switch to **keyed mode** with the `strompreis-keys` CLI:

```bash
# Create a key
strompreis-keys create "my-app" --tier pro --limit 10000
# → sp_xxx... (shown once)

# List keys (masked)
strompreis-keys list
strompreis-keys list --tier pro --inactive

# Verify / revoke
strompreis-keys verify sp_xxx...
strompreis-keys revoke sp_xxx...
```

Then start the server with the key:

```bash
export STROMPREIS_API_KEY=sp_your_key_here
strompreis-mcp
```

In keyed mode:
- All requests validated against `api_keys` table
- Per-key daily rate limiting
- Usage logged to `usage_log` table
- `db_status` zeigt aktive Keys und heutige Abrufe

### Tiers (Vorschlag für kommerzielle Preisgestaltung)

| Tier | Limit/Tag | Use Case |
|:-----|:----------|:---------|
| `free` | 100 | Persönliche Smart-Home-Integration |
| `pro` | 10.000 | Kleinere SaaS-Produkte, Hobby-Projekte |
| `enterprise` | 100.000+ | Kommerzielle Apps, vertraglich |

Limits sind pro Key konfigurierbar (`--limit N`); die Tier-Bezeichnung ist lediglich ein Label.

## Data Sources

| Source | Provider | API | Data |
|:-------|:---------|:---:|:-----|
| Day-ahead auction prices | [SMARD (BNetzA)](https://www.smard.de) | [Open REST](https://www.smard.de/app/chart_data/122/DE-LU/) | Live, hourly (verbindlich für ca. 24–36 h) |
| Solar generation | SMARD | Chart API | Live, hourly |
| Wind generation | SMARD | Chart API | Live, hourly |
| Grid load | SMARD | Chart API | Live, hourly |

**Wie die Vorhersage zustande kommt (v0.3):**
- Innerhalb des Day-Ahead-Auktionshorizonts: echte, verbindliche Börsenpreise (`source: "auction"`).
- Darüber hinaus: statistische Schätzung aus DB-Historie (Stundenprofil, Wochentag, kurzfristiger Trend) (`source: "statistical"`).

**Geplant für v0.4+:**
- ENTSO-E Transparency (grenzüberschreitender Stromhandel, Netzengpässe)
- DWD BrightSky (Wetter: Solarstrahlung, Windgeschwindigkeit, Temperatur)
- ML-Modell (z. B. Random Forest / Gradient Boosting) für die Schätzung jenseits des Auktionshorizonts — solange es gemessene Qualitätsvorteile bringt.

## License

MIT

---

Built by [@DasClown](https://github.com/DasClown) — German electricity prices for AI agents.