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 + FastMCPMCP tools (używane przez klienta AI):
list_campaigns()– lista kampaniiget_campaign(campaign_id)– pełne dane kampaniiget_character(campaign_id, char_id)– jedna postaćlist_locations(campaign_id)– lista lokacji kampaniilist_factions(campaign_id)– lista frakcji kampaniicreate_campaign(campaign_id, name, from_campaign_id, overwrite)– tworzenie kampaniicreate_character(campaign_id, character)– dodanie nowej postaciupdate_character(campaign_id, char_id, patch)– modyfikacja istniejącej postaciupsert_location(campaign_id, location)– dodawanie/aktualizacja lokacjidelete_location(campaign_id, location_id_or_name)– usunięcie lokacji po id lub nazwiefaction_rep_add(campaign_id, faction_id, delta, name)– zmiana reputacji frakcjiupsert_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 szablonudev_todo(...)– narzędzie dla MG/AI do zapisywania TODO w logusave_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
To uruchomi dwa kontenery:
rpg-ledger-mcp– serwer FastAPI + MCP nahttp://localhost:8000rpg-ledger-ngrok– tunel HTTP dorpg-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/campaignsitd.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+.
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.jsonlztype: "todo", odczytywanego przez endpoint/api/dev-todosi 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/logsi 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.jsonid:kampania-testzawiera 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żywajcampaign_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):
Test:
sprawdza dostępność serwera na
http://localhost:8000,upewnia się, że
kampania-testistnieje w/api/campaigns,przed testem przywraca plik
data/kampania-test.jsonz szablonudata/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.jsonlsą zgodne z oczekiwaniami,po udanym teście ponownie przywraca
data/kampania-test.jsonz szablonu (logi pozostają append-only).