midiMCP
README.md
# midiMCP — MIDI 编辑 MCP 服务
面向 AI 生成音乐的本地 **Model Context Protocol (MCP)** 服务。让 LLM 通过标准工具创建、解析、编辑 MIDI 文件,并把生成的文件以绝对路径回传,配合试听形成"生成 → 回传 → 试听 → 修改"的闭环迭代。已接入 TRAE 可直接调用测试。
## 项目介绍
AI 无法直接"听"音乐,但可以通过符号化 MIDI 数据理解并修改音乐。本项目把 MIDI 的生成、解析、编辑、音频渲染封装成一组 **MCP 工具**,使 AI 能:
* 基于音符描述、**紧凑旋律字符串** 或 **多轨多音色** **生成** `.mid` 文件并拿到文件路径
* 将**特定格式的 Markdown/TXT 乐谱**直接转换为 `.mid`
* 使用**音乐语义**(琴键/音阶/罗马数字和弦进行)**自动编曲**(旋律+伴奏+低音三轨)
- 将 `.mid` **解析**为可推理的 JSON 摘要(音符/速度/拍号/通道)
- 对已有文件做**编辑**(转调、倒置、力度、量化、增减音符、换音色、**可控轨道追加**)并写出新文件
* 将 MIDI **渲染**为 `.wav` 供人工试听(谐波+包络加性合成,音色更接近真实乐器),再据反馈继续修改
* 将 `.mid` **转换为文本乐谱**(`midi_to_md`),与 `midi_from_text` 互逆,便于纯文本编辑/搬运
* 通过**风格参考知识库**调取 15 种人类常用"循环小节"(`midi_styles` 查询 / `midi_loop` 生成),让编曲更符合人类听感
## 项目结构
```
midiMCP/
├── midi_mcp/
│ ├── __init__.py # 包定义
│ ├── midi_engine.py # MIDI 核心引擎(生成/编曲/解析/编辑/渲染/转文本/列举)
│ ├── knowledge.py # 风格参考知识库加载与循环小节生成(调取 styles.json)
│ ├── knowledge/
│ │ └── styles.json # 风格参考知识库:15 种风格的和弦进行/速度/音色/鼓点循环模板
│ └── server.py # MCP 服务层(FastMCP + 工具集)
├── soundfonts/ # 音色库与 FluidSynth 运行库(内置 libfluidsynth-3.dll 及依赖;FluidR3_GM.sf2 通用 GM 音色 + SalamanderGrandPiano.sf2 真钢琴音色,渲染自动启用采样音色)
├── output/ # 生成/编辑/渲染的文件输出目录
├── docs/
│ └── 用户测试文档.md # 交付给用户的测试指引
├── requirements.txt # 依赖清单
├── .venv/ # 虚拟环境
├── README.md
└── .trae/specs/ # 本项目的 Spec / Task / Checklist
```
## 项目使用技术
| 技术 | 用途 |
| ------------------------------------------------------------------- | ----------------- |
| Python 3.14(本机) | 运行环境,配合虚拟环境 |
| [mido](https://github.com/mido/mido) | 底层 MIDI 消息/事件读写 |
| [pretty\_midi](https://github.com/craffel/pretty_midi) | 高层音符级操作 |
| [mcp](https://github.com/modelcontextprotocol/python-sdk) (FastMCP) | MCP 服务框架,stdio 传输 |
| pydantic v2 | 工具入参校验与结构输出 |
| numpy | 音频波形加性合成(谐波+包络) |
## 项目完整功能(MCP 工具)
| 工具 | 说明 |
| ------------------- | --------------------------------------------------------------------------------------------------------------- |
| `midi_create` | 按音符列表 / 紧凑旋律字符串 / 多轨多音色 生成新 `.mid`,支持拍速/拍号/GM 音色 |
| `midi_compose` | **乐理驱动编曲**:给定旋律、琴键、音阶与和弦进行,自动生成旋律+伴奏+低音三轨;支持 `style` 风格参数 |
| `midi_from_text` | 将**特定格式的 Markdown/TXT 乐谱**转换为 `.mid`(全局配置 + 多轨) |
| `midi_to_md` | 将 `.mid` 转换为**文本乐谱**(与 `midi_from_text` 互逆) |
| `midi_styles` | 查询**风格参考知识库**(不含 id 返回全部风格摘要,含 id 返回单个完整字段+循环模板) |
| `midi_loop` | 按风格知识库"循环小节"模板生成**和弦+低音+鼓点** MIDI |
| `midi_read` | 解析 `.mid` 为结构化 JSON 摘要(只读) |
| `midi_edit` | 转调/倒置/力度/速度/量化/增减音符/换音色等;`add_notes` 可指定目标轨道或新建轨道 |
| `midi_render_audio` | 渲染 `.mid` 为 `.wav` 试听音频。默认内置加性合成(已柔化高频/混响/削顶,不再刺耳);传 `soundfont`(.sf2) 且装有 pyfluidsynth+FluidSynth 库时,自动切换真采样音色 |
| `midi_list` | 列出输出目录中的生成文件 |
所有写操作均**不修改源文件**,且返回**绝对路径**供 AI 引用回传。
### 生成效率优化:紧凑旋律字符串
`midi_create` 新增 `melody` 参数,用一行紧凑字符串代替逐条构造音符,显著减少 token:
```text
C4 C4 G4 G4 A4 A4 G4:2 | F4 F4 E4 E4 D4 D4 C4:2
```
* 空格分隔音符,`|` 为小节分隔(不产生休止)
* 音符格式 `音名[:拍数[:力度]]`,如 `C4`、`C4:2`、`C4:1.5:90`
* `R` / `r` / `_` / `-` 表示休止(占 1 拍)
### 乐理驱动编曲:midi\_compose
用**音乐语义**而非逐条音符描述乐曲:
```text
midi_compose(
melody="C4 C4 G4 G4 A4 A4 G4:2",
key="C", scale="major", chord_progression="I-IV-V-I",
arpeggio=True,
)
```
* `chord_progression` 支持罗马数字(`I-IV-V-I`、`vi-IV-I-V`)与显式和弦名(`C-G-Am-F`)
* 支持十余种音阶:major / minor / harmonic\_minor / melodic\_minor / dorian / phrygian / lydian / mixolydian / locrian / pentatonic / blues / whole\_tone / chromatic
* 小调键书写为 `Am`、`Em`(自动采用 minor 音阶),对应 `i-...` 进行
### 多轨多音色编排
`midi_create` 新增 `tracks` 参数,可实现"旋律 + 和弦伴奏 + 低音"等多轨编曲,每轨独立 GM 音色。
### 编辑追加目标可控
`midi_edit` 的 `add_notes` 新增目标控制:
* `target_track`:指定追加到第几轨(默认追加到最后一条)
* `new_track` + `add_program`:追加为一个新轨道
### 文本乐谱转 MIDI:midi\_from\_text
用特定格式的 Markdown/TXT 直接生成多轨 MIDI。参考 `output/示例乐谱.md`:
```markdown
# 小星星
tempo: 120 # 全局配置(轨道声明之前)
time_signature: 4/4
name: 小星星
## 旋律 # `## 轨道名` 开始一条新轨道
program: 0 # 该轨 GM 音色(可省略,默认 0)
velocity: 90 # 该轨默认力度(可省略)
melody: C4 C4 G4 G4 A4 A4 G4:2 # 紧凑旋律串
## 和弦伴奏
program: 4
- pitch: C3, time: 0, duration: 4, velocity: 60 # 键值对音符
- C2 0 4 70 # 四元组音符(音名 时间 时长 力度)
```
* 全局配置:`tempo` / `time_signature` / `name` / `key` / `scale`(置于第一个 `##` 之前)
* 轨道控制:`program` 音色、`velocity` 默认力度、`melody` 紧凑旋律
* 逐条音符:键值对 `pitch:..., time:..., duration:..., velocity:...` 或四元组 `音名 时间 时长 力度`
* `#` 开头为注释;`##` 为轨道分隔头
### MIDI → 文本乐谱:midi\_to\_md(互逆)
把任意 `.mid` 反解为可用 `midi_from_text` 还原的 Markdown 乐谱,便于纯文本编辑、搬运与回显:
```text
midi_to_md(file_path="output/e2e_from_text.mid") # 返回 text=Markdown 乐谱
```
* 自动提取首段速度 `tempo`、首拍号 `time_signature` 与曲名
* 每轨转为 `## 轨道名` + `program` + 逐条 `- pitch:..., time:..., duration:..., velocity:...`
* 打击乐轨用 `program: 128` 标记(可由 `midi_from_text` 还原为鼓轨)
### 风格参考知识库:midi\_styles / midi\_loop / midi\_compose(style)
`knowledge/styles.json` 收录 **16 种**广为流传的经典和弦进行/循环小节(流行、爵士、蓝调、古典卡农、Bossa、摇滚、EDM、Lo-fi、雷鬼、宁静治愈氛围等,均为乐理范式非受版权保护旋律)。其中 **`calm_peace`「宁静治愈氛围」** 源自采样分析纯音乐「宁静」风格歌单:慢速大调进行 I–iii–vi–IV(如 C-Em-Am-F)、钢琴琶音配弦乐衬底、低音稀疏留白,营造治愈梦境氛围。每个风格含:调式、和弦进行(罗马数字)、速度、拍号、音色、低音/鼓点 **16 步网格**循环模板。
```text
midi_styles() # 列出全部风格(id/名称/流派/情绪/速度/标签)
midi_styles(style_id="edm_anthem") # 取单风格完整字段(含 loop 循环模板)
midi_loop(style_id="pop_four_chord", bars=4) # 生成 和弦+低音+鼓点 循环小节 MIDI
midi_compose(melody="...", key="Am", style="ballad_minor") # 编曲一键套用风格
```
AI 编曲/合成前先调 `midi_styles` 选风格,再以风格 id 交给 `midi_loop` 或 `midi_compose`,即可参考人类常用律动产出更符合听感的高质量音乐。
## 项目安装使用方法
> 按项目约定:使用**本机 Python** 并创建**虚拟环境**。
```powershell
# 1. 创建虚拟环境
python -m venv .venv
# 2. 激活并安装依赖(Windows PowerShell)
.\.venv\Scripts\Activate.ps1
pip install -r requirements.txt
# 3. 校验语法与导入
.\.venv\Scripts\python.exe -m py_compile midi_mcp\server.py
.\.venv\Scripts\python.exe -c "import midi_mcp.server"
# 4. 本地直接运行(stdio 服务)
.\.venv\Scripts\python.exe -m midi_mcp.server
```
### 接入 TRAE
在 TRAE 的 MCP 配置中,以 **stdio** 方式注册本服务,命令:
```
.\.venv\Scripts\python.exe -m midi_mcp.server
```
(若以 `mcp` 命令启动:`uv run` 或直接指向 `server.py`,确保工作目录为项目根目录以正确解析 `midi_mcp` 包。)
注册后即可在 TRAE 对话中调用 `midi_*` 工具进行端到端测试。
## 项目更新日志
* **2026-09-02 · v0.4.6(真钢琴音色库:告别"廉价电子琴")**
* **根因排查**:wav 钢琴"像廉价电子琴"的根因**不是响度归一化**,而是专用钢琴库 `soundfonts\SalamanderGrandPiano.sf2` 从未下载完整(原压缩包仅 11.5MB / 实际 310MB,解压报 EOFError),钢琴轨一直回落到 FluidR3 的 GM 合成钢琴音色
* **修复**:重下完整 Salamander Grand Piano(Yamaha C5 三角钢琴)压缩包(310MB,Range 8 并发分段)并解压出 **约 1.2GB** 的 `SalamanderGrandPiano.sf2`;FluidSynth 分层渲染现真正启用钢琴专用库
* **分层渲染**:钢琴轨(program 0/1)用 Salamander 真采样,其它乐器(弦乐/低音/鼓)仍用 FluidR3 GM 库,避免整库替换导致音色整体漂移
* **可验证性**:`midi_render_audio` 新增返回字段 `piano_soundfont_used: true/false`,一眼确认真钢琴库是否生效
* **重渲染产物**:`output\锚点_雨与浪_Salamander真钢琴.wav`、`output\锚点_圆舞_Salamander真钢琴.wav`(峰值 0.95,旧 GM 版仅 0.32)
* **2026-09-02 · v0.4.5(锚点曲《雨与浪·圆舞》· 圆舞曲版)**
* 依据用户对《雨中舞》旋律的偏好重构锚点曲:3/4 圆舞曲旋转律动、婉转上扬旋律、八音盒清亮音色(program 10 + 弦乐衬底 48 + 圆舞曲低音)
* 直接以 pretty\_midi 精细编排,实现真正的圆舞曲"蓬-嚓-嚓"节奏与留白收束
* 产物:`output\锚点_海边悬崖小屋_雨与浪圆舞.mid` + `.wav`(约 133s,采样音色渲染);4/4 原版保留可对比
* **2026-09-02 · v0.4.4(新增「宁静治愈」风格,源自歌单学习)**
* **抓取并分析纯音乐「宁静」歌单**:定位为酷狗歌单集合,取到曲目元数据;归纳其音乐共性——慢速、温暖大调、纯乐器、多留白
* **新增风格** **`calm_peace`「宁静治愈氛围」**:慢速 72、大调进行 I–iii–vi–IV(如 C-Em-Am-F)、钢琴琶音(program 0)+ 弦乐衬底(program 48)+ 稀疏低音(program 33,仅 1、3 拍轻触),无鼓
* **生成示例**:`output\示例_宁静治愈.mid`(3 轨)+ `output\示例_宁静治愈.wav`(采样音色渲染,约 23s),供试听验证
* 全量 e2e 协议测试 25 项通过
* **2026-09-02 · v0.4.4(节奏呼吸度:告别"摇篮曲"拖沓感)**
* **旋律/伴奏/低音加入默认"呼吸度"(articulation=0.88)**:音符仍按完整节拍步进,但每音实际奏响留出约 12% 换气间隙,相邻音符切得更干净,解决"节奏过慢、像摇篮曲拖着走"的连奏糊感;宏观拍速完全不变
* **连奏可调**:`midi_create`(`melody_articulation`)与 `midi_compose`(`articulation`)新增参数,0.1\~1.0,越小越干脆,`1` 即完全连奏
* 复刻乐曲时可显式传 `tempo`(原曲 BPM)进一步对齐速度(该参数本就支持)
* **2026-09-02 · v0.4.3(FluidR3\_GM 已随库就位 + 校验修复)**
* **FluidR3 GM 音色库已下载**:完整 `FluidR3_GM.sf2`(148,398,306 字节,GPL 授权、供个人使用)已放入 `soundfonts/`,渲染自动启用采样音色
* **SF2 文件头魔数修复**:`_looks_like_sf2` 中 `sfbk` 与 `LIST` 两个字段位置交换错导致合法库被误判降级,已按 SoundFont 规范修正(字节 8-11 为 `sfbk`、12-15 为 `LIST`)
* 实测 `render_audio` 自动返回 `renderer: fluidsynth` 并产出有效音频;全量 e2e 协议测试通过
* **2026-09-02 · v0.4.2(FluidR3 音色库 + FluidSynth 运行库随项目分发)**
* **FluidSynth 运行库内置**:`soundfonts/fluidsynth/bin/` 随项目分发官方预编译 `libfluidsynth-3.dll`(v2.3.4,含 glib/sndfile 等依赖)。引擎在导入 pyfluidsynth 前自动将该目录加入 DLL/PATH 搜索,Windows 下开箱即用,无需再单独安装 FluidSynth
* **默认音色库自动启用**:将完整 `FluidR3_GM.sf2`(148,398,306 字节)放入 `soundfonts/`,`midi_render_audio` 便自动用 FluidSynth 采样渲染(`renderer: fluidsynth`),无需再传 `soundfont` 参数;未放入或未下载完整时自动降级内置合成并说明
* **加载稳健性**:新增 `.sf2` 文件头校验(RIFF/LIST/sfbk),并对默认音色库做"下载是否完整"的大小门槛,避免半成品文件触发加载导致 fluidsynth 错误输出污染;全量 23 项协议测试通过
* **2026-09-01 · v0.4.1(渲染音质修复)**
* **内置加性合成去刺耳化**:力度"加亮"改为温和线性曲线(高频泛音不再反超基音)、增加 \~5.5kHz 泛音低通滚降柔化、1ms 淡入防咔哒、混响脉冲响应先低通(去掉"s沙沙")且混入比例从 0.32 降至 0.16、末尾改用 tanh 软限幅防削顶失真
* **新增 FluidSynth 高级音色引擎**:`midi_render_audio` 新增 `soundfont` 参数(.sf2 路径),环境具备 pyfluidsynth+FluidSynth 原生库时切换为真采样音色;环境不满足时自动降级到内置合成并返回 `renderer` 字段与说明(返回 `renderer: fluidsynth | additive`)
* 依赖增加可选 `pyfluidsynth`;渲染路径全部经自动化验证
* **2026-08-30 · v0.4.0**
* 新增 `midi_to_md`:将 `.mid` 反解为与 `midi_from_text` 互逆的 Markdown/TXT 乐谱;打击乐轨以 `program: 128` 标记并支持还原为鼓轨
* 新增**风格参考知识库**(`knowledge/styles.json`):收录 15 种广为流传的经典和弦进行/循环小节,每风格含调式、速度、拍号、音色与低音/鼓 16 步网格模板
* 新增 `midi_styles` 工具:查询风格知识库(列出全部风格 / 取单风格完整字段含循环模板)
* 新增 `midi_loop` 工具:按风格循环模板生成**和弦+低音+鼓点** MIDI(支持多风格混搭、琴键与循环节数)
* `midi_compose` 新增 `style` 参数:一键套用知识库风格的调式/进行/速度/音色(显式参数优先)
* 文本格式解析新增 `program: 128` 打击乐通道;e2e 测试扩至 21 项全部 PASS
* **2026-08-29 · v0.3.0**
* 新增 `midi_from_text` 工具:将特定格式的 Markdown/TXT 乐谱(全局配置 + `##` 多轨)转换为 MIDI
* 音符支持两种写法:键值对 `pitch/time/duration/velocity` 与四元组 `音名 时间 时长 力度`
* 提供乐谱示例 `output/示例乐谱.md`;e2e 测试扩至 14 项全部 PASS
* **2026-08-29 · v0.2.0**
* 生成效率:`midi_create` 新增紧凑 `melody` 字符串(如 `"C4 C4 G4 G4 A4 A4 G4:2"`)自动解析,替代逐条构造音符,显著降低 token 消耗
* 多轨能力:`midi_create` 新增 `tracks` 参数,支持多轨多音色编排(旋律+伴奏+低音)
* 乐理抽象:新增 `midi_compose` 工具,支持琴键/音阶/罗马数字或显式和弦进行自动编曲,输出三轨
* 渲染音质:渲染改用"谐波+包络"加性合成,并按 GM 音色族区分钢琴/簧管/弦乐/铜管/拨弦等音色质感;`_synth_audio` 现已按各轨音色选择谐波
* 编辑可控:`midi_edit` 的 `add_notes` 新增 `target_track`(指定轨道)与 `new_track`+`add_program`(新建轨道)控制
* 修复:`compose_midi` 琴键解析越界、`-` 分隔的和弦进行无法解析
* 同步更新服务器工具定义、e2e 测试(12 项全部 PASS)与用户测试文档
- **2026-08-29 · v0.1.0**
* 搭建项目骨架、虚拟环境与依赖
* 实现 MIDI 核心引擎(生成/解析/编辑/渲染/列举)
* 实现 FastMCP 服务层,暴露 5 个 `midi_*` 工具
* 一次性 local 冒烟与本机验证
* 提供用户测试文档
This server cannot be deployed
Maintenance
ActivityMaintained
ResponsivenessNo issues