fix MCP
This commit is contained in:
13
.cursor/rules/mcp-postgres-ems.mdc
Normal file
13
.cursor/rules/mcp-postgres-ems.mdc
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
description: MCP PostgreSQL EMS — když uživatel napíše „použij MCP“ nebo chce živá data z DB
|
||||
globs:
|
||||
alwaysApply: true
|
||||
---
|
||||
|
||||
# MCP → EMS Postgres (read-only)
|
||||
|
||||
- **Server ID** pro volání MCP nástroje: **`user-postgres-ems`** (v Cursor UI může být zobrazen jako **postgres-ems** — to je stejný server).
|
||||
- **Nástroj:** **`query`**. **Argument:** `{"sql": "<SELECT …>"}` — pouze read-only.
|
||||
- Při žádosti o živá data / „použij MCP“: **nejprve zavolej `query`**. Neargumentuj, že připojení „nejde“ nebo že MCP „neexistuje“, dokud volání reálně neskončí chybou.
|
||||
- Po chybě: uveď text chyby a praktické kroky (VPN, MCP zapnutý v Cursoru, dostupnost DB z prostředí kde MCP běží).
|
||||
- Detailní postup, příklady SQL a bezpečnost: **`docs/07-mcp-postgres-ems.md`**.
|
||||
16
CLAUDE.md
16
CLAUDE.md
@@ -21,6 +21,17 @@ Multi-site Energy Management System: optimalizuje FVE, baterii a flexibilní zá
|
||||
| Pole / zařízení | Modbus TCP (`pymodbus`), HTTP (Loxone, případně API vozidel) |
|
||||
| Solver | PuLP + HiGHS (`HiGHS_CMD`) |
|
||||
| Runtime | Docker Compose |
|
||||
| **Živá DB přes MCP (Cursor)** | Server ID **`user-postgres-ems`**, nástroj **`query`**, `{ "sql": "…" }` — viz **`docs/07-mcp-postgres-ems.md`** a pravidlo **`.cursor/rules/mcp-postgres-ems.mdc`** |
|
||||
|
||||
---
|
||||
|
||||
## 2b. MCP — živá EMS databáze (read-only)
|
||||
|
||||
Když uživatel napíše **„použij MCP“** nebo potřebuje **aktuální řádky z Postgresu** (plán, telemetrie, journal):
|
||||
|
||||
1. Zavolej MCP nástroj **`query`** na serveru **`user-postgres-ems`** s argumentem `{"sql": "<SELECT …>"}`.
|
||||
2. **Neodmlouvej** bez pokusu (typ „nepřipojím se“, „MCP neexistuje“). Po chybě popiš **skutečnou** chybu a co zkontrolovat.
|
||||
3. Kanonický popis, příklady a bezpečnost: **`docs/07-mcp-postgres-ems.md`**.
|
||||
|
||||
---
|
||||
|
||||
@@ -33,6 +44,7 @@ Multi-site Energy Management System: optimalizuje FVE, baterii a flexibilní zá
|
||||
| `docs/04-modules/` | Modulové specifikace (ceny, forecast, spotřeba, TČ, telemetrie, řízení, plánování, režimy, EV) |
|
||||
| `docs/loxone-integration.md` | Loxone watchdog, heartbeat, role exekutora |
|
||||
| `docs/06-open-questions.md` | Nedokončené rozhodnutí – doplňovat místo hádání |
|
||||
| `docs/07-mcp-postgres-ems.md` | MCP read-only SQL na EMS DB (server `user-postgres-ems`, nástroj `query`) |
|
||||
| `db/migration/` | Flyway versioned migrace `V00x__*.sql` (schéma, seed, alter) |
|
||||
| `db/routines/` | Repeatable SQL: funkce `ems.fn_*` |
|
||||
| `db/views/` | Repeatable SQL: view `ems.vw_*` |
|
||||
@@ -94,7 +106,7 @@ Projekt je **SQL-first**: doménová logika, agregace, joiny mezi tabulkami a st
|
||||
|
||||
17. **Modbus zápis = journal.** Každý zápis do zařízení přes control exporter se loguje do `ems.modbus_command`. **Verifikační job** běží každé **2 minuty** a ověřuje nedávno zápis (`written` → čtení registru). Při **mismatch** po max. **3** pokusech o zápis → u běžných registrů přepnutí na **SELF_SUSTAIN** (`run_fn_set_mode_with_discord` → `fn_set_mode`, `activated_by` = `system:mismatch`) + **Discord** při skutečné změně režimu. **Výjimka:** souvislý blok Deye **62–64** (čas) → po 3 neúspěšných ověřeních **bez** změny režimu, kritický **Discord** (`notify_modbus_clock_verify_exhausted`). **Obecně:** při jakékoli změně `mode_code` z Pythonu (`POST /api/v1/sites/{id}/mode`, mismatch → SELF_SUSTAIN, `fn_expire_modes`) lze Discord zapnout přes `DISCORD_WEBHOOK_URL`. Detail: `docs/04-modules/modbus-command-journal.md`.
|
||||
|
||||
18. **Deye zápis registrů 60–499:** pouze **FC 0x10** (`write_registers`), **nikdy** FC 0x06 pro tento rozsah; **`execute_modbus_commands`** slučuje souvislé adresy do jednoho FC 0x10. **Režimy:** `get_deye_mode` → **SELL** jen při **\|battery_w\| ≥ \|grid_setpoint_w\|** a obou záporných (záměr výdeje baterie do sítě); **CHARGE** při `battery_w` > 500 a `grid_setpoint_w` > 200; jinak **PASSIVE**. **PASSIVE:** reg. **108/109** škálované podle `battery_w` z plánu (ne vždy max); **SELL:** 108=0, 109=max, **143** omezeno podle `|grid_setpoint_w|`; **142/178/145/TOU** jako v `write_inverter_setpoints`. **PRESERVE:** `lock_battery` → 108/109=0. **Čas 62–64**, bloky TOU **1–2** vs **3–6**, verify, Discord: beze změny oproti dřívějšímu chování — plný popis **`docs/04-modules/modbus-registers.md`** a princip *Keep it simple* u režimů **`docs/04-modules/operating-modes.md`**.
|
||||
18. **Deye zápis registrů 60–499:** pouze **FC 0x10** (`write_registers`), **nikdy** FC 0x06 pro tento rozsah; **`execute_modbus_commands`** slučuje souvislé adresy do jednoho FC 0x10. **Režimy:** `get_deye_mode` → **SELL** jen při **\|battery_w\| ≥ \|grid_setpoint_w\|** a obou záporných (záměr výdeje baterie do sítě); **CHARGE** při `battery_w` > 500 a `grid_setpoint_w` > 200; jinak **PASSIVE**. **PASSIVE (AUTO):** reg. **108** i **109** na **max. proud z DB** (plný rozsah baterie); jemnější výkon drží **TOU** z plánu. **SELL:** 108=0, 109=max, **143** omezeno podle `|grid_setpoint_w|`; **142/178/145/TOU** jako v `write_inverter_setpoints`. **PRESERVE:** `lock_battery` → 108/109=0. **Čas 62–64**, bloky TOU **1–2** vs **3–6**, verify, Discord: beze změny oproti dřívějšímu chování — plný popis **`docs/04-modules/modbus-registers.md`** a **`docs/04-modules/operating-modes.md`**.
|
||||
|
||||
19. **Baterie – export v LP:** V `solve_dispatch` binárka `z_export[t]`: pokud `grid_export` v daném slotu **≥ 1** W, platí koncové `soc[t] ≥ arb_base_wh` (ekonomická rezerva z DB, ne časová řada `arb_floor_series`). Bez exportu může plán jít k `min_soc_percent` (provozní podlaha; u paralelních packů často 11–12 %, migrace V029 + komentář sloupce).
|
||||
|
||||
@@ -192,7 +204,7 @@ Specifikace z `docs/02-architecture.md`, modulových docs a komentářů v `plan
|
||||
| Self-hosted deploy (Gitea, Caddy, `/opt/ems-deploy`) | `docs/deployment-self-hosted.md`, `deploy/deploy.sh` |
|
||||
| Reset DB / restore z dumpu (Docker volume, Timescale) | `docs/database-reset-and-restore.md`, `scripts/import_ems_db.sh` |
|
||||
| Nespecifikované chování | `docs/06-open-questions.md` (přidat otázku, neimpl. naslepo) |
|
||||
| **MCP read-only SQL na EMS DB** | Cursor MCP server **`postgres-ems`**, nástroj **`query`**. |
|
||||
| **MCP read-only SQL na EMS DB** | **`docs/07-mcp-postgres-ems.md`** — server ID **`user-postgres-ems`**, nástroj **`query`**, `{"sql":"…"}`. Pravidlo **`.cursor/rules/mcp-postgres-ems.mdc`**. |
|
||||
|
||||
---
|
||||
|
||||
|
||||
76
docs/07-mcp-postgres-ems.md
Normal file
76
docs/07-mcp-postgres-ems.md
Normal file
@@ -0,0 +1,76 @@
|
||||
# MCP: read-only dotazy na EMS PostgreSQL
|
||||
|
||||
Tento dokument je **jednotný návod pro AI agenty i lidi**. Když v projektu napíšeš **„použij MCP“** (nebo chceš živá data z EMS DB), postupuj přesně tady — **bez hádání názvů serverů** a **bez odmítání bez vyzkoušení**.
|
||||
|
||||
---
|
||||
|
||||
## 1. Který MCP server
|
||||
|
||||
| Co | Hodnota |
|
||||
|----|-----------|
|
||||
| **Identifikátor pro volání nástroje** (např. Cursor `call_mcp_tool`) | `user-postgres-ems` |
|
||||
| **Zobrazovaný název** v Cursor Settings | často `postgres-ems` |
|
||||
| **Konfigurace** | uživatelský `~/.cursor/mcp.json` (ne je v gitu) — spojení na konkrétní host/DB |
|
||||
|
||||
**Důležité:** v UI se může jmenovat `postgres-ems`, ale **programové volání** používá **`user-postgres-ems`**. Oba označují **stejný** server.
|
||||
|
||||
---
|
||||
|
||||
## 2. Který nástroj a parametry
|
||||
|
||||
| Položka | Hodnota |
|
||||
|---------|---------|
|
||||
| **Nástroj** | `query` |
|
||||
| **Argument** | JSON: `{ "sql": "<jeden read-only SELECT>" }` |
|
||||
| **Omezení** | jen **SELECT** (read-only server); žádné `INSERT`/`UPDATE`/`DELETE` |
|
||||
|
||||
Schéma argumentů (pro ověření): v Cursor profilu cesta typu
|
||||
`.cursor/projects/<název-projektu>/mcps/user-postgres-ems/tools/query.json`
|
||||
(soubor se objeví po povolení MCP serveru v Cursoru).
|
||||
|
||||
---
|
||||
|
||||
## 3. Povinné chování agenta
|
||||
|
||||
1. **Nejdřív zavolej** MCP `query` — **nepiš**, že „se tam stejně nepřipojíš“ nebo že MCP „neexistuje“**, dokud** volání **nepadne** s reálnou chybou.
|
||||
2. Používej server **`user-postgres-ems`** a nástroj **`query`** — **nevymýšlej** varianty jako `postgres-ems` jako *server parameter*, pokud tvoje rozhraní výslovně nevyžaduje jiný identifikátor (v Cursor agent API je to typicky **`user-postgres-ems`**).
|
||||
3. **Při úspěchu** — stručně shrň výsledek (tabulka / fakta), případně navazuj dalšími SELECTy.
|
||||
4. **Při selhání** (timeout, connection refused, auth) — uveď přesnou chybu a **konkrétní** kroky: VPN / dostupnost hosta z prostředí kde MCP běží, že je v Cursoru zapnutý server `postgres-ems`, že uživatel má běžící Postgres.
|
||||
|
||||
---
|
||||
|
||||
## 4. Příklady dotazů (kopírovatelné)
|
||||
|
||||
```sql
|
||||
select current_database() as db, current_timestamp as ts;
|
||||
```
|
||||
|
||||
```sql
|
||||
select id, code, name, active from ems.site order by id;
|
||||
```
|
||||
|
||||
```sql
|
||||
select pr.id, pr.site_id, pr.run_type, pr.status, pr.horizon_start, pr.horizon_end, pr.created_at
|
||||
from ems.planning_run pr
|
||||
where pr.status = 'active'
|
||||
order by pr.created_at desc
|
||||
limit 10;
|
||||
```
|
||||
|
||||
```sql
|
||||
select ems.fn_plan_explain_bundle(2, 6);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 5. Odkud to vychází v repozitáři
|
||||
|
||||
- Stručná návěstí také v **[`../CLAUDE.md`](../CLAUDE.md)** (sekce MCP + tabulka „Kde hledat co“).
|
||||
- Trvalé pravidlo pro agenta: **[`../.cursor/rules/mcp-postgres-ems.mdc`](../.cursor/rules/mcp-postgres-ems.mdc)** (`alwaysApply: true`).
|
||||
|
||||
---
|
||||
|
||||
## 6. Bezpečnost
|
||||
|
||||
- V dotazech **nevypisuj** connection stringy ani hesla z `mcp.json`.
|
||||
- MCP je určený k **diagnostice a reportingu**; měnící operace přes aplikaci (API, migrace), ne přes read-only MCP.
|
||||
Reference in New Issue
Block a user