这是一个基于Model Context Protocol (MCP)的服务器,通过基于WebSocket的插件系统对MuseScore进行编程控制。这使得像Claude这样的AI助手能够作曲、添加歌词、浏览乐谱并直接控制MuseScore。

首先,将QML插件代码保存到您的MuseScore插件目录中:
macOS: ~/Documents/MuseScore4/Plugins/musescore-mcp-websocket.qml
Windows: %USERPROFILE%\Documents\MuseScore4\Plugins\musescore-mcp-websocket.qml
Linux: ~/Documents/MuseScore4/Plugins/musescore-mcp-websocket.qml
git clone <your-repo>
cd mcp-agents-demo
python -m venv .venv
source .venv/bin/activate # 在Windows上:.venv\Scripts\activate
pip install fastmcp websockets
在您的Claude Desktop配置文件中添加以下内容:
macOS: ~/Library/Application Support/Claude/claude_desktop_config.json
Windows: %APPDATA%\Claude\claude_desktop_config.json
{
"mcpServers": {
"musescore": {
"command": "/path/to/your/project/.venv/bin/python",
"args": [
"/path/to/your/project/server.py"
]
}
}
}
注意:更新路径以匹配您项目的实际位置。
[插入不同功能的截图,如和声、旋律写作等,作为放大版GIF]
对于开发,使用MCP开发工具:
# 安装MCP开发工具
pip install mcp
# 测试您的服务器
mcp dev server.py
# 检查连接状态
mcp dev server.py --inspect
要查看MuseScore插件的控制台输出,请从终端运行MuseScore:
macOS:
/Applications/MuseScore\ 4.app/Contents/MacOS/mscore
Windows:
cd "C:\Program Files\MuseScore 4\bin"
MuseScore.exe
Linux:
musescore4
此MCP服务器提供了全面的MuseScore控制:
get_cursor_info() - 获取当前光标位置和选择信息go_to_measure(measure) - 导航到特定小节go_to_beginning_of_score() / go_to_final_measure() - 导航到开始/结束next_element() / prev_element() - 元素间移动光标next_staff() / prev_staff() - 在五线谱之间移动select_current_measure() - 选择当前小节add_note(pitch, duration, advance_cursor_after_action) - 添加具有MIDI音高的音符add_rest(duration, advance_cursor_after_action) - 添加休止符add_tuplet(duration, ratio, advance_cursor_after_action) - 添加连音(三连音等)insert_measure() - 在当前位置插入小节append_measure(count) - 在乐谱末尾添加小节delete_selection(measure) - 删除当前选择或特定小节add_lyrics_to_current_note(text) - 向当前音符添加歌词add_lyrics(lyrics_list) - 批量向多个音符添加歌词set_title(title) - 设置乐谱标题get_score() - 获取完整的乐谱分析和结构ping_musescore() - 测试与MuseScore的连接connect_to_musescore() - 建立WebSocket连接undo() - 撤销最后一个操作set_time_signature(numerator, denominator) - 更改拍号processSequence(sequence) - 执行批量命令检查/examples文件夹中的示例MuseScore文件,展示各种音乐风格:
每个示例包括:
.mscz - MuseScore文件(可编辑).pdf - 乐谱.mp3 - 音频预览# 设置乐谱
await set_title("我的第一首歌")
await go_to_beginning_of_score()
# 添加音符(MIDI音高:60=C, 62=D, 64=E等)
await add_note(60, {"numerator": 1, "denominator": 4}, True) # 四分音符C
await add_note(64, {"numerator": 1, "denominator": 4}, True) # 四分音符E
await add_note(67, {"numerator": 1, "denominator": 4}, True) # 四分音符G
await add_note(72, {"numerator": 1, "denominator": 2}, True) # 二分音符C
# 添加歌词
await go_to_beginning_of_score()
await add_lyrics_to_current_note("Do")
await next_element()
await add_lyrics_to_current_note("Mi")
await next_element()
await add_lyrics_to_current_note("Sol")
await next_element()
await add_lyrics_to_current_note("Do")
# 一次添加多条歌词
await add_lyrics(["双-", "胞", "双-", "胞", "小-", "星星"])
# 使用序列处理进行复杂操作
sequence = [
{"action": "goToBeginningOfScore", "params": {}},
{"action": "addNote", "params": {"pitch": 60, "duration": {"numerator": 1, "denominator": 4}, "advanceCursorAfterAction": True}},
{"action": "addNote", "params": {"pitch": 64, "duration": {"numerator": 1, "denominator": 4}, "advanceCursorAfterAction": True}},
{"action": "addRest", "params": {"duration": {"numerator": 1, "denominator": 4}, "advanceCursorAfterAction": True}}
]
await processSequence(sequence)
.qml文件是否位于正确的插件目录中mcp、server或appmcp-agents-demo/
├── .venv/
├── server.py # Python MCP服务器入口点
├── musescore-mcp-websocket.qml # MuseScore插件
├── requirements.txt
├── README.md
└── src/ # 源代码模块
├── __init__.py
├── client/ # WebSocket客户端功能
│ ├── __init__.py
│ └── websocket_client.py
├── tools/ # MCP工具实现
│ ├── __init__.py
│ ├── connection.py # 连接管理工具
│ ├── navigation.py # 乐谱导航工具
│ ├── notes_measures.py # 音符和小节操作
│ ├── sequences.py # 批量操作工具
│ ├── staff_instruments.py # 五线谱和乐器工具
│ └── time_tempo.py # 时间和节奏工具
└── types/ # 类型定义
├── __init__.py
└── action_types.py # WebSocket动作类型定义
创建一个requirements.txt文件,包含:
fastmcp
websockets
常用MIDI音高值供参考:
持续时间格式:{"numerator": int, "denominator": int}
{"numerator": 1, "denominator": 1}{"numerator": 1, "denominator": 2}{"numerator": 1, "denominator": 4}{"numerator": 1, "denominator": 8}{"numerator": 3, "denominator": 8}