loenn-mcp-delta
by Magedeline
README.md
# loenn-mcp (Pro)
[](https://pypi.org/project/loenn-mcp/)
[](LICENSE)
[](https://www.python.org/)
**The full/Pro Celeste map editor for AI agents** — a [Model Context Protocol](https://modelcontextprotocol.io/) (MCP) server that brings full Celeste `.bin` map editing to Claude, GitHub Copilot, and other MCP clients, plus a standalone `pcgscene` CLI for scripting and CI. Read, edit, analyze, generate, and preview maps without opening Lönn.
This build additionally includes the AI-powered analysis tools (Claude API)
and the full MdMC/WFC procedural generation pipeline ported from
[PCGHelper](https://github.com/Magedeline/PCGHelper) — see
[AI-Powered Analysis](#ai-powered-analysis) and
[Advanced PCG (MdMC/WFC)](#advanced-pcg-mdmcwfc). The free tier is
[loenn-mcp](https://github.com/Magedeline/loenn-mcp), which ships everything
here except those two sections.
Works with [Everest](https://github.com/EverestAPI/Everest) mods and maps from [Lönn](https://github.com/CelestialCartographers/Loenn) or [Ahorn](https://github.com/CelestialCartographers/Ahorn).
## Contents
- [Features](#features)
- [Installation & setup](#installation--setup)
- [`pcgscene` CLI](#pcgscene-cli)
- [Procedural generation](#procedural-generation)
- [Image-to-map conversion](#image-to-map-conversion)
- [Seeded terrain generation](#seeded-terrain-generation)
- [Analysis & insights](#analysis--insights)
- [AI-Powered Analysis](#ai-powered-analysis)
- [Advanced PCG (MdMC/WFC)](#advanced-pcg-mdmcwfc)
- [Configuration](#configuration)
- [Architecture](#architecture)
- [Requirements](#requirements)
- [License](#license)
## Features
**83 MCP tools** for complete map manipulation and AI-assisted design, plus the `pcgscene` command-line tool for scripting and CI.
### Core Tools
**Reading & Querying**
- `list_maps` — List all `.bin` files
- `read_map_overview` — Summary of rooms, entities, triggers, stylegrounds
- `read_room` — Full room details (tiles, entities, triggers, decals)
- `get_room_tiles` — Raw tile grid (FG or BG)
- `read_map_metadata` — Quick metadata without full read
- `search_entities` — Find entities by type, position, room
- `search_triggers` — Find triggers by type
- `compare_rooms` — Side-by-side room comparison
**Editing**
- `add_entity` / `remove_entity` — Place or delete entities
- `update_entity` / `move_entity` — Modify entity properties or position
- `add_trigger` / `remove_trigger` — Place or delete triggers
- `set_room_tiles` — Replace tile grid
- `add_room` / `remove_room` — Create or delete rooms
- `create_map` — Create new `.bin` file
- `update_room` — Modify room properties (music, dark, wind, etc.)
- `clone_room` — Duplicate a room
- `batch_add_entities` — Add multiple entities at once
- `resize_room` — Change room dimensions
**Decals & Effects**
- `list_decals` / `add_decal` / `remove_decal` — Manage foreground/background decals
- `list_stylegrounds` / `add_styleground` / `update_styleground` / `remove_styleground` — Manage map effects
**Definitions & Catalog**
- `list_entity_definitions` / `get_entity_definition` — Browse entity types
- `list_trigger_definitions` / `get_trigger_definition` — Browse trigger types
- `list_effect_definitions` / `get_effect_definition` — Browse effect types
### Analysis & Insights
**Basic Analysis**
- `analyze_map` — Entity counts, type breakdown, world bounds
- `visualize_map_layout` — ASCII mini-map
- `preview_map_section` — Detailed ASCII preview
**Advanced Analysis**
- `analyze_entity_usage` — Entity stats across entire map
- `analyze_difficulty` — Room/map difficulty estimation
- `find_entity_references` — Locate all instances of an entity type
- `detect_map_patterns` — Identify design archetypes (linear, hub, etc.)
- `analyze_room_connectivity` — Adjacency graph analysis
**Suggestions & Improvements**
- `suggest_improvements` — Actionable room suggestions
- `compare_maps` — Structural diff between maps
**Wiki & Caching**
- `wiki_save` / `wiki_search` / `wiki_list` / `wiki_get` — Persist and retrieve analysis results
**Project Management**
- `get_mod_info` — Project metadata and structure
- `validate_map` / `batch_validate_and_fix` — Playability validation with auto-fix
- `export_room_json` / `import_room_json` — JSON room exchange
**Diffing**
- `summarize_map_diff` — Track map evolution with snapshots
### Rendering
- `render_map_html` — Interactive HTML preview (zoom, pan, search, minimap)
### Procedural Generation
**Pattern-Based Generation**
- `build_pattern_library` — Extract patterns from existing maps
- `generate_room_from_pattern` — Generate rooms with strategy + seed
- `ingest_external_map` — Download and extract patterns from GameBanana
**Image & Terrain Generation**
- `generate_map_from_image` — Convert color-mapped images to playable maps
- `generate_terrain_map` — Procedural maps with Perlin noise + Voronoi biomes
- `preview_terrain_biomes` — Preview biome layout before generation
### Procedural Generation (Advanced)
**PCGHelper Tools** — MdMC/WFC tile generation
- `pcg_mdmc_presets` — List configuration presets
- `pcg_skeleton_generate` — Layout non-overlapping room skeleton
- `pcg_markov_fill` — Fill rooms with MdMC/WFC/hybrid
- `pcg_score_room` — Evaluate interestingness & difficulty
- `pcg_pipeline` — One-shot end-to-end generation
---
## Installation & Setup
### Install from PyPI
```bash
pip install loenn-mcp
```
Or from source:
```bash
git clone https://github.com/Magedeline/loenn-mcp-delta
cd loenn-mcp-delta
pip install -e .
```
### Connect to Claude Desktop
Add to `claude_desktop_config.json`:
```json
{
"mcpServers": {
"loenn-mcp": {
"command": "python",
"args": ["-m", "loenn_mcp.server"],
"env": {
"LOENN_MCP_WORKSPACE": "/absolute/path/to/your/mod"
}
}
}
}
```
### Connect to GitHub Copilot (VS Code)
Add to `.vscode/mcp.json`:
```json
{
"servers": {
"loenn-mcp": {
"type": "stdio",
"command": "python",
"args": ["-m", "loenn_mcp.server"],
"env": {
"LOENN_MCP_WORKSPACE": "${workspaceFolder}"
}
}
}
}
```
### Preview Maps Locally
```bash
python -m loenn_mcp.preview_map Maps/01_City_A.bin
python -m loenn_mcp.preview_map Maps/01_City_A.bin g- # filter by prefix
```
The interactive HTML preview supports zoom, pan, room details, search, and minimap with keyboard shortcuts.
---
## `pcgscene` CLI
A batch-first command-line tool for scanning and repairing maps outside an
MCP client — install once, use from scripts, pre-commit hooks, or CI. Every
command that touches a `.bin` file writes through the same atomic,
backed-up, round-trip-validated path as the MCP server, so a bad run can
never destroy a map.
```bash
pip install loenn-mcp
pcgscene scan MyMap.bin # score every room + map connectivity
pcgscene validate MyMap.bin # in-game readiness checklist (exit 0/1)
pcgscene fix MyMap.bin --dry-run # preview safe auto-repairs
pcgscene fix MyMap.bin # apply them (backed up first)
pcgscene generate MyMap.bin --preset simple_fair --seed 42
pcgscene diff before.bin after.bin # what changed between two maps
```
| Command | What it does |
|---|---|
| `scan` | Scores every room (interestingness, difficulty, exit connectivity, spawn presence, fairness gate) plus map-wide reachability from the start room. |
| `score` | Deep report for a single room (`--room NAME`). |
| `validate` | In-game readiness checklist — bad names, missing spawns, sealed exits, unreachable rooms — with a CI-friendly exit code. |
| `fix` | Safe auto-repairs: adds missing spawns, sanitizes bad room names, converts `strawberry{golden}` to real `goldenBerry` entities. Supports `--dry-run` and `--only spawns,names,berries`. |
| `generate` | Preset-driven generation (`quick` / `simple_fair` / `explore` / `challenge`) with a reproducible `--seed`, using this build's `pcg_helper` MdMC/WFC pipeline. |
| `diff` | Room/entity/tile changes between two maps. |
Every command accepts `--json` (and `--out FILE`) for machine-readable
output, so an editor plugin or CI step can consume the report directly.
---
## Procedural Generation
### Generation Strategies
| Strategy | Description |
|---|---|
| `balanced` | Mix of exploration and challenge (default) |
| `exploration` | Open spaces, gentle platforming, few hazards |
| `challenge` | Dense tiles, many hazards, tight jumps |
| `speedrun` | Linear path, minimal platforms, fast flow |
### Model Profiles
| Profile | Behavior | Use Case |
|---|---|---|
| `creative` | Random seed each call | Maximum variety |
| `deterministic` | Stable seed from strategy | Reproducible layouts |
| `architect` | Random seed | Emphasis on shape/connectivity |
### Quick Start Example
```python
# 1. Build pattern library from existing maps
build_pattern_library()
# 2. Create a new map
create_map("Maps/PCG/Generated.bin", "PCG/Generated")
# 3. Generate rooms
generate_room_from_pattern(
map_path="Maps/PCG/Generated.bin",
room_name="a-01",
strategy="exploration",
seed=42,
model_profile="deterministic"
)
# 4. Validate and preview
validate_room("Maps/PCG/Generated.bin", "a-01")
render_map_html("Maps/PCG/Generated.bin")
```
### Seeded Generation
Use `seed=<int>` + `model_profile="deterministic"` for reproducible output:
```python
# Both calls produce identical rooms
generate_room_from_pattern(..., strategy="challenge", seed=1234, model_profile="deterministic")
generate_room_from_pattern(..., strategy="challenge", seed=1234, model_profile="deterministic")
```
### GameBanana Integration
Download and extract patterns from community mods:
```python
# Dry-run (preview only)
ingest_external_map(
source_url="https://gamebanana.com/mods/53774",
attribution="Spring Collab 2020",
confirm_download=False
)
# Download and extract
ingest_external_map(
source_url="https://gamebanana.com/mods/53774",
attribution="Spring Collab 2020 (various authors)",
confirm_download=True,
tags="community,expert"
)
```
Patterns are saved to `PCG/Datasets/` with attribution. Always verify mod licenses permit derivative use.
---
## Image-to-Map Conversion
Convert color-mapped images directly into playable Celeste maps. Each pixel becomes one 8×8 tile.
### Default Color Mapping
| Color | Hex | Maps to |
|---|---|---|
| Black | `#000000` | Solid tile |
| White | `#FFFFFF` | Air (empty) |
| Red | `#FF0000` | Spike hazard |
| Green | `#00FF00` | Player spawn |
| Blue | `#0000FF` | Jump-through platform |
| Yellow | `#FFFF00` | Strawberry |
| Magenta | `#FF00FF` | Spring |
| Cyan | `#00FFFF` | Refill crystal |
| Orange | `#FF8000` | Crumble block |
| Grey | `#808080` | Background solid |
### Usage
```python
# Basic conversion
generate_map_from_image(image_path="Assets/my_level.png")
# Custom colors and scale
generate_map_from_image(
image_path="Assets/large_map.png",
output_path="Maps/Custom/level.bin",
scale=4, # 4×4 pixel blocks → 1 tile
color_map_json='{"#FF0000":"solid","#00FF00":"spawn"}'
)
```
Requires `Pillow`: `pip install loenn-mcp[image]`
---
## Seeded Terrain Generation
Generate complete maps with Perlin noise and Voronoi biomes. Inspired by [AliShazly/map-generator](https://github.com/AliShazly/map-generator).
### Biomes
| Biome | Terrain |
|---|---|
| `mountain` | Dense tiles, tight platforms, spikes |
| `forest` | Moderate density, many platforms, springs |
| `plains` | Open spaces, gentle platforms, collectibles |
| `lake` | Sparse tiles, jump-throughs, refills |
| `cave` | Enclosed, crumble blocks, dark rooms |
| `summit` | Sparse platforms, wind effects |
### Quick Example
```python
# Generate a 4×3 map with seed 42
generate_terrain_map(seed=42, difficulty=3, width_rooms=4, height_rooms=3)
# Preview biome layout before generating
preview_terrain_biomes(seed=42, width_rooms=4, height_rooms=3)
# Output:
# [P] [^] [^] [F]
# [~] [P] [^] [M]
# [C] [~] [P] [F]
```
### Parameters
| Parameter | Default | Description |
|---|---|---|
| `seed` | -1 (random) | Integer seed for reproducible output |
| `width_rooms` | 4 | Rooms horizontally |
| `height_rooms` | 3 | Rooms vertically |
| `frequency` | 8.0 | Perlin noise frequency (lower = smoother) |
| `voronoi_points` | 12 | Number of biome region centres |
| `biome_set` | all | Comma-separated biome names |
| `difficulty` | 3 | 1-5 scale for hazard density |
---
## Analysis & Insights
Advanced analysis tools for map design, difficulty, and patterns.
### Quick Examples
```python
# Analyze difficulty
analyze_difficulty(map_path="Maps/MyMod/1-City.bin")
# Detect gameplay patterns
detect_map_patterns(map_path="Maps/MyMod/1-City.bin")
# → "standard-level (7-15 rooms)", "linear-horizontal", "checkpointed"
# Get room suggestions
suggest_improvements(map_path="Maps/MyMod/1-City.bin", room_name="lvl_a-01")
# Track map evolution
summarize_map_diff(map_path="Maps/MyMod/1-City.bin") # save snapshot
# ... edit map ...
summarize_map_diff(map_path="Maps/MyMod/1-City.bin") # show diff
# Cache results for instant re-use
wiki_save(key="city_difficulty", content="Avg 4.2/10, 3 hard rooms", tags="analysis")
wiki_search(query="difficulty")
# Batch validation
batch_validate_and_fix(map_path="Maps/MyMod/1-City.bin", auto_fix=True)
# Search and clone
search_entities(map_path="Maps/MyMod/1-City.bin", entity_type="strawberry")
clone_room(map_path="Maps/MyMod/1-City.bin", source_room="lvl_a-01", new_name="lvl_a-01-copy")
# Export/import rooms
export_room_json(map_path="Maps/MyMod/1-City.bin", room_name="lvl_a-01")
import_room_json(map_path="Maps/MyMod/2-Resort.bin", json_path="Export/lvl_a-01.json")
```
### Wiki Cache
Analysis results persist in `.loenn_mcp_wiki/` as JSON files for instant re-use across sessions.
---
## AI-Powered Analysis
Leverage Claude AI for intelligent map feedback, room descriptions, and entity suggestions.
### Setup
```bash
pip install loenn-mcp
export ANTHROPIC_API_KEY="sk-ant-..." # Get from https://console.anthropic.com/
```
### Available Tools
| Tool | Description |
|---|---|
| `ai_analyze_map` | Design feedback (general/difficulty/visual/flow) |
| `ai_describe_room` | Generate room descriptions in various styles |
| `ai_suggest_entities` | Entity placement recommendations with coordinates |
### Examples
```python
# Get design feedback
ai_analyze_map(map_path="Maps/MyMod/1-City.bin", analysis_type="general")
# → "Strengths: Good checkpoints. Add more strawberries in rooms 3-5..."
# Generate descriptions
ai_describe_room(map_path="Maps/MyMod/1-City.bin", room_name="lvl_a-03", style="atmospheric")
# → "A windswept precipice where ancient stone meets howling gales..."
# Get entity suggestions
ai_suggest_entities(map_path="Maps/MyMod/1-City.bin", room_name="lvl_a-03", goal="add_challenge")
# → "1. Add spikes at (120, 80) for timing challenge..."
```
### Analysis Types
- `general` — Overall design with suggestions
- `difficulty` — Difficulty curve analysis
- `visual` — Visual variety and theme feedback
- `flow` — Player movement and navigation
### Description Styles
- `atmospheric` — Evocative, mood-focused
- `technical` — Gameplay-focused
- `story` — Narrative snippets
- `brief` — 1-2 sentence summaries
### Suggestion Goals
- `improve_flow` — Better player guidance
- `add_challenge` — Skill-testing elements
- `reduce_difficulty` — Accessibility
- `add_secrets` — Exploration rewards
Gracefully degrades if `ANTHROPIC_API_KEY` is not set.
---
## Advanced PCG (MdMC/WFC)
Full Python port of the [PCGHelper Lönn mod](https://github.com/Magedeline/PCGHelper) — MdMC/WFC tile generation, skeleton layout, and end-to-end pipeline. Also reachable from the shell via `pcgscene generate` (see [`pcgscene` CLI](#pcgscene-cli)).
### Tools
| Tool | Description |
|---|---|
| `pcg_mdmc_presets` | List 7 MdMC configuration presets |
| `pcg_skeleton_generate` | Layout non-overlapping room skeleton |
| `pcg_markov_fill` | Fill rooms with MdMC/WFC/hybrid |
| `pcg_score_room` | Evaluate interestingness & difficulty |
| `pcg_pipeline` | One-shot end-to-end generation |
### Generation Modes
- `mdmc` — Multi-dimensional Markov Chain
- `wfc` — Wave Function Collapse
- `hybrid` — Combination of both
### Scoring Metrics
**Interestingness I** = w1·global_NLE + w2·local_NLE + w3·Shannon_entropy
**Difficulty D** = z1·hole_frequency + z2·local_LE + z3·NLE_scarcity
### MdMC Presets
| Key | Description |
|---|---|
| `000011012` | L-shape (default) |
| `000011112` | 3-neighbour causal |
| `001001112` | 4-neighbour |
| `011011012` | 5-neighbour |
| `010111010` | Cross (WFC recommended) |
| `101000101` | Diagonals only |
| `111101111` | All 8 neighbours |
### Example
```python
# One-shot end-to-end generation
pcg_pipeline(
map_path="Maps/MyMod/1-City.bin",
room_count=8,
generation_mode="mdmc",
seed=42,
ensure_playable=True,
place_entities=True,
)
# → "PCG pipeline complete: 8 rooms added"
# Score a room
pcg_score_room(map_path="Maps/MyMod/1-City.bin", room_name="lvl_a-03")
# → "Interestingness I = 0.4231 | Difficulty D = 0.5812"
# Fill existing empty rooms
pcg_markov_fill(
map_path="Maps/MyMod/1-City.bin",
room_names="skel_0,skel_1,skel_2",
generation_mode="wfc",
configuration="010111010",
start_room="skel_0", # gets the player spawn
end_room="skel_2", # gets the golden berry
seed=99,
)
```
---
## Configuration
| Variable | Default | Description |
|---|---|---|
| `LOENN_MCP_WORKSPACE` | Current directory | Root of your Celeste mod project. All map paths are relative to this. Path traversal is blocked. |
---
## Architecture
### Core Modules
**`celeste_bin.py`** — Standalone `.bin` parser
- Pure Python (no Everest/Lönn required)
- Full read/write round-trip with no data loss
- Handles all 7 value types: bool, uint8, int16, int32, float32, lookup string, raw string, RLE-encoded string
- Recursive element tree matching Lönn/Maple format
**`pcg.py`** — Procedural generation
- Pattern extraction from rooms (size, entity density, tile motifs, gameplay tags)
- JSON pattern library with deduplication
- Strategy-based generation (balanced, exploration, challenge, speedrun)
- Seeded randomness for reproducible output
- Model profiles (deterministic, creative, architect)
**`image_map.py`** — Image-to-map conversion
- Color-to-role mapping (configurable palette)
- Automatic room splitting
- Entity placement from pixel colors
- Scale support (downscaling)
- Fuzzy color matching
**`terrain_gen.py`** — Seeded terrain generation
- Perlin noise with fractal octaves
- Voronoi biome partitioning
- Fully seeded (same seed = identical output)
- Difficulty scaling (1-5)
- Biome-aware entities
**`gdep_tools.py`** — Game analysis
- Wiki caching (`.loenn_mcp_wiki/`)
- Pattern detection (linear, hub, collectible-rich, etc.)
- Difficulty analysis (1-10 scale)
- Room connectivity graphs
- Map diffing with snapshots
- Batch validation and auto-fix
- Actionable suggestions
**`ai_analyzer.py`** — AI-powered analysis
- Claude API integration
- Design feedback (general, difficulty, visual, flow)
- Room descriptions (atmospheric, technical, story, brief)
- Entity placement suggestions
- Graceful degradation
**`server.py`** — MCP server
- Built with [FastMCP](https://github.com/jlowin/fastmcp)
- Path-traversal protection
- Atomic map writes
- Explicit download confirmation
**`cli.py`** — `pcgscene` command-line tool
- scan / score / validate / fix / diff / generate, all `--json`-capable
- Shares `celeste_bin`'s atomic-write path — no separate write logic to drift
- `generate` calls into `pcg_helper.run_pipeline` directly
---
## Requirements
- Python 3.9+
- `fastmcp >= 3.0.0`
- `anthropic >= 0.40.0` (optional, for AI-powered tools)
- `Pillow >= 9.0` (optional, for image-to-map conversion)
Install with all optional features:
```bash
pip install loenn-mcp[image]
```
No Celeste installation required.
---
## License
MIT — see [LICENSE](LICENSE).
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues