CHUK音乐MCP服务器
MCP音乐设计系统-- 用于音乐创作的shadcn/ui.
你将模式复制到你的项目中,你拥有它们,你修改它们。该库提供了正确的图元和设计良好的起点,而不是一个黑匣子。
视觉
音乐是一个设计系统,而不是DAW。 这是一个用于构图的控制平面。
LLM在意图层面运作——结构、能量、安排。该系统处理音乐理论。作曲家拥有自己的模式。
特性
- 模式系统:可复制、可拥有的模式模板(鼓、贝斯、和声、旋律、fx)
- 风格系统:约束捆绑 限制, 建议,以及 验证
- 排列模型:具有能量曲线和和谐的层×截面结构
- 得分IR:版本化的中间表示——黄金文件可测试、可区分、可往返
- MIDI导出:从YAML到可播放MIDI文件的确定性编译
- MCP集成:完整的MCP服务器,配备37多种AI辅助构图工具
快速开始
# Install
git clone https://github.com/chuk-ai/chuk-mcp-music
cd chuk-mcp-music
pip install -e ".[dev]"
# Compile an arrangement
python examples/compile_arrangement.py
# Verify determinism
shasum output/demo.mid
# e3b0c442... (always the same for the same input)堆栈
Intent (LLM)
↓
Tokens (semantic constraints)
↓
Structure (sections, energy curves)
↓
Layers (drums, bass, harmony, melody, fx)
↓
Patterns (owned, modifiable recipes)
↓
Score IR (symbolic, inspectable, versioned)
↓
MIDI (deterministic compilation)
↓
Audio (optional, downstream)你拥有什么与图书馆拥有什么
| 你拥有 | 图书馆拥有 |
|---|---|
| 复制到项目中的模式 | 模式定义(pattern/v1, score_ir/v1) |
| 排列YAML文件 | 编译器管道 |
| 样式替代和自定义 | 验证规则 |
| 项目特定的图案库 | 默认图案/样式库 |
| 输出MIDI文件 | IR规范和规范化 |
边界是明确的: 你拥有内容,图书馆拥有机器.
关键概念
图案(阴影层)
模式是可复制、可拥有、可修改的模板:
# patterns/bass/root-pulse.yaml
schema: pattern/v1
name: root-pulse
role: bass
pitched: true
parameters:
density:
type: enum
values: [half, quarter, eighth]
default: quarter
variants:
driving:
density: eighth
template:
events:
- degree: chord.root
beat: 0
velocity: $velocity_base安排(你的作文)
# arrangements/demo.arrangement.yaml
schema: arrangement/v1
key: D_minor
tempo: 124
harmony:
default_progression: [i, VI, III, VII]
sections:
- name: intro
bars: 8
- name: verse
bars: 16
layers:
bass:
role: bass
patterns:
pulse:
ref: bass/root-pulse
variant: driving
arrangement:
intro: null
verse: pulse样式(约束束)
风格有三个作用:
- 限制 --节奏范围、禁止模式、关键偏好
- 建议 --每层模式候选名单,注册提示
- 验证 --lint错误及其可操作的修复
# styles/library/melodic-techno.yaml
schema: style/v1
name: melodic-techno
description: Driving, melodic electronic music
tokens:
tempo:
range: [120, 128]
default: 124
key_preference: minor
structure_hints:
breakdown_required: true
section_multiples: 8
layer_hints:
bass:
suggested: [bass/rolling-sixteenths, bass/root-pulse]
register: low
forbidden:
patterns: [drums/trap-*]验证输出:
{
"valid": false,
"errors": [
{"message": "Tempo 140 outside style range [120, 128]", "severity": "error"},
{"message": "Pattern drums/trap-hat forbidden by style", "severity": "error"}
],
"suggestions": [
{"message": "Consider drums/four-on-floor for drums layer", "severity": "info"}
]
}分数IR(中间表示)
分数IR是 稳定、可检查的合同 在编曲和MIDI之间:
Arrangement YAML → Score IR (diffable, versioned) → MIDI同样的安排→ 相同分数IR→ 相同的MIDI。总是。
架构摘录(score_ir/v1)
{
"schema": "score_ir/v1",
"name": "my-track",
"key": "D_minor",
"tempo": 124,
"time_signature": {"numerator": 4, "denominator": 4},
"ticks_per_beat": 480,
"total_bars": 24,
"notes": [
{
"start_ticks": 0,
"pitch": 50,
"duration_ticks": 480,
"velocity": 90,
"channel": 1,
"source_layer": "bass",
"source_pattern": "bass/root-pulse",
"source_section": "verse",
"bar": 0,
"beat": 0.0
}
],
"sections": [
{"name": "intro", "start_ticks": 0, "end_ticks": 15360, "bars": 8}
]
}规范化规则
- 笔记排序方式
(start_ticks, channel, pitch) - 按以下方式排序的部分
start_ticks - 所有时间单位为滴答(每拍480滴答)
- 每张钞票上的来源可追溯性
用法
# Compile and inspect
result = compiler.compile(arrangement)
print(result.score_ir.summary())
# {'name': 'my-track', 'total_bars': 32, 'total_notes': 256,
# 'layers': {'drums': 128, 'bass': 64, 'harmony': 64},
# 'pitch_range': (36, 72), 'velocity_range': (60, 110)}
# Compare two versions
diff = old_ir.diff_summary(new_ir)
# {'notes_added': 12, 'notes_removed': 8, 'notes_unchanged': 244,
# 'tempo_changed': False, 'key_changed': False}
# Debug: "Why is this note here?"
for note in result.score_ir.notes:
if note.pitch == 50 and note.bar == 3:
print(f"From {note.source_layer}/{note.source_pattern} in {note.source_section}")常见工作流
1.从样式创建轨迹
# Apply style → suggest patterns → add sections → arrange → compile
music_apply_style(arrangement="my-track", style="melodic-techno")
music_suggest_patterns(arrangement="my-track", role="bass")
# Returns: ["bass/rolling-sixteenths", "bass/root-pulse"]
music_add_section(arrangement="my-track", name="intro", bars=8)
music_add_section(arrangement="my-track", name="verse", bars=16)
music_arrange_layer(arrangement="my-track", layer="bass",
section_patterns={"intro": None, "verse": "main"})
music_compile_midi(arrangement="my-track")2.在Bassline上迭代
# Preview → tweak → diff → compile
music_preview_section(arrangement="my-track", section="verse")
music_update_pattern_params(arrangement="my-track", layer="bass",
params={"density": "eighth"})
music_diff_ir(arrangement="my-track-v1", other_arrangement="my-track-v2")
# {'notes_added': 32, 'notes_removed': 16, ...}
music_compile_midi(arrangement="my-track")3.调试错误结果
# Compile to IR → inspect provenance → validate → fix
result = music_compile_to_ir(arrangement="my-track")
# Inspect which pattern produced the wrong notes
# Each note has: source_layer, source_pattern, source_section, bar, beat
music_validate(arrangement="my-track")
# {"valid": false, "errors": [{"message": "Channel conflict on channel 1"}]}
# Fix the issue
music_set_layer_level(arrangement="my-track", name="bass", level=0.8)4.提取茎(红外往返)
# Compile → modify IR → emit separate MIDI files
ir = music_compile_to_ir(arrangement="my-track")
# Extract just the bass layer
bass_ir = music_modify_ir(ir_json=ir["score_ir"], filter_layers=["bass"])
music_emit_midi_from_ir(ir_json=bass_ir["score_ir"], output_name="bass-stem")
# Extract drums, reduce velocity
drums_ir = music_modify_ir(ir_json=ir["score_ir"],
filter_layers=["drums"],
velocity_scale=0.8)
music_emit_midi_from_ir(ir_json=drums_ir["score_ir"], output_name="drums-stem")
# Transpose harmony up an octave
harmony_ir = music_modify_ir(ir_json=ir["score_ir"],
filter_layers=["harmony"],
transpose=12)
music_emit_midi_from_ir(ir_json=harmony_ir["score_ir"], output_name="harmony-high")MCP工具
服务器提供37多种按域组织的工具:
排列工具 (6):
music_create_arrangement-创建新安排music_get_arrangement-获取安排详细信息music_list_arrangements-列出所有安排music_save_arrangement-保存到YAMLmusic_delete_arrangement-删除安排music_duplicate_arrangement-克隆一个安排
结构工具 (11):
music_add_section,music_remove_section,music_reorder_sectionsmusic_set_section_energy,music_add_layer,music_remove_layermusic_arrange_layer,music_mute_layer,music_solo_layermusic_set_layer_level,music_set_harmony
图案工具 (6):
music_list_patterns,music_describe_patternmusic_add_pattern,music_remove_patternmusic_update_pattern_params,music_copy_pattern_to_project
样式工具 (6):
music_list_styles,music_describe_stylemusic_suggest_patterns,music_validate_stylemusic_apply_style,music_copy_style_to_project
编译工具 (8):
music_compile_midi,music_preview_sectionmusic_compile_to_ir,music_diff_irmusic_modify_ir,music_emit_midi_from_irmusic_export_yaml,music_validate
人性化(计划中)
决定论并不意味着机器人。人性化是 种子和明确:
# In arrangement
humanize:
timing_ms: 8 # ±8ms timing drift
velocity: 6 # ±6 velocity variation
seed: 42 # Reproducible randomness相同的种子→ 同样的人性化→ 仍然是确定性的。改变种子以探索变化。
发展
# Clone and install
git clone https://github.com/chuk-ai/chuk-mcp-music
cd chuk-mcp-music
pip install -e ".[dev]"
# Run full check suite
make check # Linting, types, security, tests (532 tests)
# Run tests with coverage
make test-cov # Currently at 89% coverage
# Format code
ruff format .
ruff check --fix .项目结构
src/chuk_mcp_music/
├── core/ # Music primitives (pitch, rhythm, chord, scale)
├── models/ # Pydantic models (arrangement, pattern, style)
├── arrangement/ # Arrangement management
├── patterns/ # Pattern system and library
│ └── library/ # Built-in patterns (copy these!)
├── styles/ # Style system and library
│ └── library/ # Built-in styles
├── compiler/ # Compilation pipeline
│ ├── arranger.py # Arrangement → Score IR → MIDI
│ ├── score_ir.py # Intermediate representation (versioned, diffable)
│ └── midi.py # MIDI file generation
├── tools/ # MCP tool implementations
└── async_server.py # MCP server entry point路线图
看 路线图.md 查看完整的设计文档。
接下来:
- 导出配置文件(GM、Ableton、Logic鼓图)
- CC自动化通道(过滤器清扫、侧链躲避)
- 通过网络MIDI实时预览
- 从MIDI导入中学习模式
许可证
麻省理工学院
