HoneyMCP
# ๐ฏ HoneyMCP โ ์ผ๋ถ์ถค(ADOFAI) ๊ณ ํ๋ฆฌํฐ ๋งต ์๋์์ฑ MCP
> **"๋งต ๋ง๋ค์ด์ค" ํ๋ง๋๋ฉด ์ ํ๋ธ๊ธ ์ปค์คํ
๋งต์ด ๋์ต๋๋ค.**
> A Model Context Protocol server that generates human-quality
> *A Dance of Fire and Ice* custom levels from any song.
> ๋
ธ๋๋ฅผ ์ฃผ๋ฉด ์ค์ ์ํ์ ๋ง์ถ ํ์ผ๊ธธ + ๋งค์ง์ํด + ์นด๋ฉ๋ผ/์กฐ๋ช
์ดํํธ๊น์ง ์๋์ผ๋ก ๋ฝ์์ค๋๋ค.
  
## โจ ํต์ฌ ๊ธฐ์ (์ ๋
ธ์ผ์ด ์๋๊ฐ)
| ๊ธฐ์ | ์ค๋ช
|
|---|---|
| ๐น **์ค์ ์ํ ์ฑํฌ** | ffmpeg + spectral flux๋ก ๋
ธ๋์ ์จ์
(์ํ) ์๋ฐฑ ๊ฐ๋ฅผ 2์ด ๋ง์ ์ถ์ถ. ํ์ผ์ ์ง์ง ์ํ ์์ ๋ฐฐ์น (์ฑํฌ์จ ~90%) |
| ๐งฒ **SetSpeed ๋ฐ์ ๊ณ ์ ** | ๊ณต์ ์๋ํฐ ๊ฐ์ด๋์ ๋งค์ง์์ดํ ์ ์. ๋ํ์ ์์ ๋กญ๊ฒ, ๋ฐ์๋ ํ์ผ๋ง๋ค BPM ๋ณด์ ์ผ๋ก ๊ณ ์ |
| ๐บ๏ธ **๊ฒน์นจ ์ ๋ก ๋ฐฐ์น** | ์ ํ์ผ ์ขํ ์๋ฎฌ๋ ์ด์
+ DFS ๋ฐฑํธ๋ํน. ๋ญ๊ฐ์ง ๋ฉ์ด๋ฆฌ ์์ฒ ์ฐจ๋จ |
| ๐๐ข **์๋๋น์จ ์ ํ** | ํ์ผ ์๋๋น๋ฅผ ๊ธฐ์ค์ 0.45~2.6๋ฐฐ๋ก ๊ฐ์ . ๋น ๋ฆ/๋๋ฆผ ํ์(ํ ๋ผ/๊ฑฐ๋ถ์ด) ๋๋ฐฐ + ๋ถ๊ฐ๋ฅ ๊ตฌ๊ฐ ์์ฒ ์ฐจ๋จ. ๋น ๋ฅธ ์ํ=์ง์ ์คํธ๋ฆผ, ๋๋ฆฐ ์ํ=ํฐ ๋ํ (๊ณ ์ ์์น) |
| ๐ **ํ๋ ์ด์ฆ ๋ชจํฐํ** | 8ํ์ผ๋ง๋ค ๋ฌผ๊ฒฐโ์ง๊ทธ์ฌ๊ทธโ์ํฌโ๋์ ์ํ + ๊ตฌ๊ฐ๋ง๋ค ๋ฐฉํฅ ์ ํ. ํํ ๊ณ ์๋๋ก ๋ฐฉ์ง |
| ๐ก๏ธ **ํ์ง ๊ฒ์ดํธ** | ์ ์์ ๊ฒ์ฆ(errors/warnings). ๋ถํฉ๊ฒฉ์ด๋ฉด ์๋ ๋ฐ๊ฟ ์ต๋ 6ํ ์๋ ์ฌ์์ฑ ํ ์ต๊ณ ๋ณธ๋ง ์ ์ฅ |
| ๐ **2/3/4ํค ๋์์น๊ธฐ** | ๊ณต์ ๊ฐ์ด๋ multi-press ์ ์(0.01ยฐ ํ๋ ๋ฏธ๋์คํ). โ
5๋ถํฐ ์ฝ๋ฌ์ค์ 2ํค ์๋, ์๋ ์ถ๊ฐ๋ ๊ฐ๋ฅ |
## ๐ ์๊ตฌ์ฌํญ
- Python 3.10+
- **ffmpeg** (์ํ ์ถ์ถ์ฉ. ์์ผ๋ฉด ๊ธฐ๊ณ ๊ทธ๋ฆฌ๋ ํด๋ฐฑ์ผ๋ก ๋์)
- Windows: `winget install ffmpeg` (๋๋ [ffmpeg.org](https://ffmpeg.org/download.html))
- ์ผ๋ถ์ถค ๋ณธํธ (๊ฒฐ๊ณผ๋ฌผ ํ์ธ์ฉ. ์์ฑ ์์ฒด๋ ๊ฒ์ ์์ด ๋จ)
## ๐ ์ค์น
```powershell
git clone https://github.com/dohunkr/HoneyMCP.git
cd HoneyMCP
pip install -e ".[dev]"
```
## ๐ MCP ์ฐ๊ฒฐ๋ฒ (ํด๋ผ์ด์ธํธ๋ณ)
์๋ฒ ์คํ ๋ช
๋ น(๊ณตํต): `python -m honey_mcp.server` (stdio ๋ฐฉ์)
> โ ๏ธ ์ค์ ํ **ํด๋ผ์ด์ธํธ๋ฅผ ์์ ํ ์ข
๋ฃโ์ฌ์์**ํด์ผ ๋ฐ์๋ฉ๋๋ค.
### opencode (`opencode.json` โ ํ๋ก์ ํธ ๋ฃจํธ)
```json
{
"$schema": "https://opencode.ai/config.json",
"mcp": {
"honey-adofai": {
"type": "local",
"command": ["C:/Python310/python.exe", "-m", "honey_mcp.server"],
"enabled": true
}
}
}
```
`command`์ python ๊ฒฝ๋ก๋ ๋ณธ์ธ ํ๊ฒฝ์ ๋ง๊ฒ ์์ . `.venv` ์ฌ์ฉ ์ `.venv/Scripts/python.exe` ์ ๋๊ฒฝ๋ก ๊ถ์ฅ.
`opencode.json.example` ์ฐธ๊ณ . ์ฐ๊ฒฐ ํ์ธ: ํด ๋ชฉ๋ก์ `honey-adofai`๊ฐ ๋ณด์ด๋ฉด OK.
### Claude Code (`.mcp.json` โ ํ๋ก์ ํธ ๋ฃจํธ)
```json
{
"mcpServers": {
"honey-adofai": {
"command": "python",
"args": ["-m", "honey_mcp.server"],
"cwd": "D:/Github/ADOFAI/HoneyMCP"
}
}
}
```
### Cursor (`~/.cursor/mcp.json`)
```json
{
"mcpServers": {
"honey-adofai": {
"command": "python",
"args": ["-m", "honey_mcp.server"],
"cwd": "D:/Github/ADOFAI/HoneyMCP"
}
}
}
```
### Antigravity / Codex
MCP ์ค์ ์ stdio ์๋ฒ๋ก ๋ฑ๋ก (์์ ๋์ผ):
command `python`, args `["-m", "honey_mcp.server"]`, cwd = ์ด ํด๋.
## ๐ฎ ์ฌ์ฉ๋ฒ
์ฑํ
์ ๋
ธ๋ ํ์ผ ๊ฒฝ๋ก๋ง ์ฃผ๋ฉด ๋ฉ๋๋ค:
```
D:\Music\track.ogg ๋ก ๋งต ๋ง๋ค์ด์ค (โ
5, ํ๋ คํ๊ฒ)
```
AI๋ ์๋์ผ๋ก `analyze_song โ generate_full_map โ ํ์ง๊ฒ์ดํธ`๋ฅผ ์ํํฉ๋๋ค.
์ถ๋ ฅ: `D:/Github/ADOFAI/HoneyMap_<๊ณก๋ช
>/` ์์ `.adofai` + ๋
ธ๋ ๋ณต์ฌ๋ณธ โ
**์ผ๋ถ์ถค ๋ ๋ฒจ ์๋ํฐ๋ก ํด๋๋ฅผ ์ด์ด์ F5 ํ
์คํธํ๋ ์ด.**
MCP ์์ด ์ง์ ์์ฑ๋ ๊ฐ๋ฅ:
```powershell
python tools/make_map.py --audio "C:/Music/song.ogg" --outdir "D:/Github/ADOFAI/HoneyMap_song" `
--title "Song" --artist "Artist" --difficulty 5 --style showcase --seed 7
```
- `difficulty`: 1~10 (โ
5-6 ๊ถ์ฅ. โ
5๋ถํฐ 2ํค ๋์์น๊ธฐ, โ
7๋ถํฐ 6๊ฐ, โ
9๋ถํฐ 3ํค)
- `style`: `showcase`(ํ๋ ค) / `clean`(๊น๋) / `party`
## ๐งฐ MCP ๋๊ตฌ
| ๋๊ตฌ | ์ค๋ช
|
|---|---|
| `analyze_song(audio_path)` | BPM/์คํ์
/์ํ/๊ตฌ๊ฐ ๋ถ์ (~2์ด) |
| `generate_full_map(audio_path, output_dir, title, artist, difficulty, style, seed)` | ์์ท ํ๋งต ์์ฑ + ํ์ง๊ฒ์ดํธ + ์๋์ฌ์๋ |
| `validate_level_tool(level_path)` | ์ ์/์๋ฌ/๊ฒฝ๊ณ ๋ฆฌํฌํธ |
| `adjust_effects(level_path, style, zoom, enable_flash)` | ํ์ผ ์ ์ง + ์ดํํธ๋ง ๊ต์ฒด |
| `add_multipress(level_path, floor, keys)` | 2/3/4ํค ๋์์น๊ธฐ ์๋ ์ถ๊ฐ |
| `list_patterns()` | ํจํด ์ฌ์ |
| ํ๋กฌํํธ `make_map` / ๋ฆฌ์์ค `adofai://spec` | AI ์์
ๆ้ + ์คํ ์์ฝ |
## ๐ก๏ธ ํ์ง ๊ฒ์ดํธ (์ฌ๋ฐ๋ฐฉ์ง)
`errors` (ํ๋๋ผ๋ ์์ผ๋ฉด ์๋ ์ฌ์์ฑ):
- ๊ฒ์ enum ์๋ฐ (`Forward` ๋ฑ โ ๊ณผ๊ฑฐ ๋ก๋ฉ ํฌ๋์ ์์ธ)
- SetSpeed๊ฐ ๊ธฐ์ค์ 0.35~3๋ฐฐ ์ด๊ณผ (๋ถ๊ฐ๋ฅ ๊ตฌ๊ฐ)
- floor ๋ฒ์ ์ด๊ณผ / ํ์ผ ๋ถ์กฑ / BPM ๋ฒ์ ์ดํ
`warnings` (์ ์ ๊ฐ์ ):
- ์ง์ 7์ฐ์ ๊ณ ์๋๋ก / ์ข์ฐํ์ ํธ์ค / ํ์ผ ๊ฒน์นจ / ์ํ ์ฑํฌ์จ 60% ๋ฏธ๋ง
## ๐บ๏ธ ๋งต ์ถ๋ ฅ ๊ท์น
- ๋ชจ๋ ๋งต์ `D:/Github/ADOFAI/HoneyMap_<๊ณก๋ช
>/` ์ ์์ฑ (ํ๋ก์ ํธ ํด๋์ ๋ถ๋ฆฌ)
- ์์: ๋๋ผ์๋ชฝ ํผ์๋
ธ ์ปค๋ฒ โ ํ์ผ 210๊ฐ, score 100, ์ฑํฌ์จ 90%, 2ํคร3
## ๐งช ๊ฐ๋ฐ
```powershell
pytest -q
```
๊ตฌ์กฐ: `src/honey_mcp/` โ `server.py`(MCP) / `audio.py` / `onsets.py`(์ํ์ถ์ถ) /
`chart.py`(์ฑ๋ณด+๋ฐฐ์น) / `effects.py`(์ดํํธ) / `adofai.py`(ํ์ผIO+๊ฒ์ฆ+๋ฉํฐํ๋ ์ค)
## โ ํธ๋ฌ๋ธ์ํ
| ์ฆ์ | ์์ธ/ํด๊ฒฐ |
|---|---|
| `Requested value 'Forward' was not found` | ๊ตฌ๋ฒ์ ์ฐ์ถ๋ฌผ. ์ต์ ๋ฒ์ ์ผ๋ก ์ฌ์์ฑ (๊ฒ์ดํธ์์ ์์ฒ ์ฐจ๋จ๋จ) |
| ํ์ผ์ ํ ๋ผ/๊ฑฐ๋ถ์ด ๋๋ฐฐ | ๊ตฌ๋ฒ์ ์๋ ํญ์ฃผ. v6+ ์๋๋น์จ ์ ํ์ผ๋ก ํด๊ฒฐ |
| MCP๊ฐ ๋
ธ๋ ๋ถ์์์ ๋ฉ์ถค | ๊ตฌ librosa ๊ฒฝ๋ก ๋ฌธ์ . ํ์ฌ ffmpeg ๊ธฐ๋ฐ์ผ๋ก 2์ด ๋ด์ธ (ffmpeg ์ค์น ํ์ธ) |
| ํ๊ธ ์ถ๋ ฅ ๊นจ์ง (cp949) | `$env:PYTHONUTF8="1"` ์ค์ |
| MCP๊ฐ ์ ๋ณด์ | ํด๋ผ์ด์ธํธ ์ฌ์์ ํ์ธ + python ์ ๋๊ฒฝ๋ก ํ์ธ |
## ๐ ๋ผ์ด์ ์ค
MIT โ ์์ ๋กญ๊ฒ ์ฐ๊ณ ๊ณ ์น๊ณ ๊ณต์ ํ์ธ์. ๋งต์ ๋ง๋ค ๋ ์ฌ์ฉํ ๋
ธ๋์ ์ ์๊ถ์ ๊ฐ ๊ถ๋ฆฌ์์๊ฒ ์์ต๋๋ค.
TDQS
Scored across 6 tools
Tools target distinct stages: audio analysis, pattern listing, full generation, validation, multipress editing, and effects adjustment. The only mild overlap is that generate_full_map is a one-shot pipeline that may implicitly subsume analysis and pattern selection, but the dedicated tools still have clear separate purposes.
Most names follow a consistent snake_case verb_noun pattern: analyze_song, list_patterns, add_multipress, generate_full_map, adjust_effects. The only deviation is validate_level_tool, where the redundant _tool suffix breaks the otherwise clean convention.
Six tools is well-scoped for a specialized ADOFAI map-generation server. Each tool covers a distinct operation in the create-validate-adjust workflow without obvious redundancy or bloat.
The surface covers the core lifecycle: analyze a song, generate a full map, validate it, adjust effects, and add multipress patterns. Minor gaps remain, such as removing multipress, editing individual tiles or rhythms directly, or previewing maps without full regeneration.