Skip to main content
Glama
sepa79

RPG Ledger MCP Server

by sepa79
README.md
# RPG Ledger MCP Server

Serwer legera do sesji RPG sterowanych przez AI. Udostępnia stan kampanii (postacie, ekwipunek, questy, logi) przez MCP i proste API HTTP, tak żeby np. ChatGPT mógł być Mistrzem Gry / NPC.

## Architektura

- `app.py` – FastAPI + FastMCP
  - MCP tools (używane przez klienta AI):
    - `list_campaigns()` – lista kampanii
    - `get_campaign(campaign_id)` – pełne dane kampanii
    - `get_character(campaign_id, char_id)` – jedna postać
    - `list_locations(campaign_id)` – lista lokacji kampanii
    - `list_factions(campaign_id)` – lista frakcji kampanii
    - `create_campaign(campaign_id, name, from_campaign_id, overwrite)` – tworzenie kampanii
    - `create_character(campaign_id, character)` – dodanie nowej postaci
    - `update_character(campaign_id, char_id, patch)` – modyfikacja istniejącej postaci
    - `upsert_location(campaign_id, location)` – dodawanie/aktualizacja lokacji
    - `delete_location(campaign_id, location_id_or_name)` – usunięcie lokacji po id lub nazwie
    - `faction_rep_add(campaign_id, faction_id, delta, name)` – zmiana reputacji frakcji
    - `upsert_faction(campaign_id, faction)` – dodanie/aktualizacja frakcji (id, name, rep, description)
    - `mutate(...)` – modyfikacje legera (gold/hp/xp/notki/deń/questy/ekwipunek itd.)
    - `spawn_npc_group(campaign_id, template_id, ...)` – generowanie grupy NPC z szablonu
    - `dev_todo(...)` – narzędzie dla MG/AI do zapisywania TODO w logu
    - `save_campaign_snapshot(campaign_id, slot)` / `restore_campaign_snapshot(campaign_id, slot)` – snapshoty kampanii
- `data/` – pliki kampanii JSON (np. `kampania-1.json`)
- `logs/` – zdarzenia z gry (`logs.jsonl`)
- `static/index.html` – prosta przeglądarka kampanii w przeglądarce

Serwer HTTP nasłuchuje na porcie `8000`, MCP jest wystawione jako SSE pod `/mcp` (FastMCP over HTTPS/HTTP).

## Uruchomienie przez Docker Compose (zalecane)

Wymagane:
- Docker + Docker Compose

```bash
docker compose up --build
```

To uruchomi dwa kontenery:

- `rpg-ledger-mcp` – serwer FastAPI + MCP na `http://localhost:8000`
- `rpg-ledger-ngrok` – tunel HTTP do `rpg-ledger-mcp:8000` (publiczny URL z ngrok)

W pliku `docker-compose.yml` można wstawić własny `NGROK_AUTHTOKEN`.

Przydatne adresy lokalnie:

- UI kampanii: `http://localhost:8000/`
- API kampanii: `http://localhost:8000/api/campaigns` itd.
- Logi: `http://localhost:8000/api/logs`

## Konfiguracja MCP (klient np. ChatGPT Desktop / inne)

Serwer MCP jest dostępny jako endpoint HTTP SSE:

- URL: `http://localhost:8000/mcp`

W konfiguracji klienta MCP ustaw:

- typ: „HTTP / SSE” (FastMCP)
- endpoint: `http://localhost:8000/mcp` (lub publiczny URL z ngrok)

Po podłączeniu klient powinien widzieć narzędzia MCP (`list_campaigns`, `get_campaign`, `get_character`, `mutate`, `dev_todo`).

## Lokalny development (bez Dockera)

Wymagany Python 3.11+.

```bash
pip install -r requirements.txt
uvicorn app:app --reload --host 0.0.0.0 --port 8000
```

Potem korzystasz z tych samych URL co wyżej (`http://localhost:8000/...`).

## Dev TODO z poziomu MG / AI

Narzędzie `dev_todo(...)` pozwala MG/AI zapisywać pomysły na rozwój systemu:

- wywołanie MCP `dev_todo(summary=..., details=..., tags=[...])`
- wpis trafia do osobnego pliku `logs/dev-todos.jsonl` z `type: "todo"`,
  odczytywanego przez endpoint `/api/dev-todos` i zakładkę TODO w UI

Dzięki temu możesz:

- grać sesję,
- pozwalać MG/AI zgłaszać brakujące funkcje jako TODO,
- później przejrzeć `/api/logs` i zaimplementować kolejne kawałki logiki legera.

## Kampania testowa / test pack

Żeby nie zaśmiecać logów głównej kampanii, w katalogu `data/` jest osobna kampania testowa:

- plik: `data/kampania-test.json`
- `id`: `kampania-test`
- zawiera prostą mapę (`karczma` ↔ `las-testowy`) i dwie postacie (`test-warrior`, `test-mage`).

Rekomendacja:

- do ręcznych testów MCP/UI wybieraj w topbarze kampanię „Kampania Testowa”,
- w narzędziach MCP (`mutate`, `roll_dice`, itp.) używaj `campaign_id="kampania-test"`.

Dzięki temu wpisy testowe w `logs/logs.jsonl` będą odseparowane od właściwej kampanii po `campaign_id`.

### E2E test pack (lokalnie)

Jest też prosty E2E test dla kampanii testowej (bezpośrednio po HTTP):

```bash
docker compose up -d
python scripts/e2e_test_pack.py
```

Test:

- sprawdza dostępność serwera na `http://localhost:8000`,
- upewnia się, że `kampania-test` istnieje w `/api/campaigns`,
- przed testem przywraca plik `data/kampania-test.json` z szablonu `data/kampania-test.template.json`,
- wykonuje kilka mutacji na kampanii testowej (`hp_add`, `gold_add`, `location_set`),
- weryfikuje, że zmiany w stanie oraz wpisy w `logs/logs.jsonl` są zgodne z oczekiwaniami,
- po udanym teście ponownie przywraca `data/kampania-test.json` z szablonu (logi pozostają append-only).