GMA2 MCP
MCP服务器,让AI助手通过Telnet控制grandMA2照明控制台。它通过模型上下文协议提供了41个高级工具,用于线索管理、夹具控制、预设管理、执行器控制、宏编辑、外观分配、批量操作、控制台状态查询、节目文件管理、读回验证、音乐节目工作流等。
目录
- 帮助关键字 - 对象关键字 - 功能关键字 - 在关键字 - 复制和移动 - 分配 - 标签 - 外观 - 宏占位符
概述
grandMA2控制台通过Telnet接受命令,但构建正确的命令字符串需要了解MA2语法规则——关键字排序、预设类型映射、选项标志和对象层次结构。该项目分两层处理这种复杂性:
- 指令产生器 (
src/commands/)--按照官方语法规则构造有效grandMA2命令字符串的Python函数。每个函数都是一个返回字符串的瘦包装器;它从不接触网络。 - MCP服务器 (
src/server.py)--一个FastMCP服务器,它公开了41个工具,涵盖了线索管理、夹具控制、预设、执行器、全局状态、标签、外观分配、宏编辑、批量线索操作、序列播放、控制台状态查询、节目文件管理、回读验证、音乐节目工作流和stdio传输上的原始命令。它管理到控制台的持久Telnet连接,并将命令构造委托给构建器层。 - 响应解析器 (
src/response_parser.py)--用于解析grandMA2 Telnet输出的纯函数(来自List命令)转换为结构化数据。读回工具使用它来返回解析后的字典,而不是原始文本。 - GMA2客户端 (
src/gma2_client.py)--一个高级编排类,它将多个命令生成器调用组合到工作流级方法中(例如,构建一个完整的提示列表,设置一个预设的夹具组,为音乐节目创建歌曲对象)。 - 命令序列 (
src/command_sequence.py)--一个构建器模式类,用于将多个命令组合成一个有序的批处理,该批处理可以作为一个单元进行预览和执行。
命令生成器涵盖了按类别组织的所有grandMA2命令行关键字:对象关键字(夹具、通道、组、预设、提示、序列、执行器)、功能关键字(存储、删除、复制、移动、跳转、标签、分配等)和帮助关键字(through、at、+)。
特性
- 41个MCP工具 --线索管理(存储/删除/转到、CMD分配)、夹具控制(设置值、设置属性、清除编程器)、预设管理(存储或应用)、执行器控制(开/关/去/杀死/切换、推子级别、序列分配)、全局状态(黑屏、高亮显示)、对象标签(通用+序列范围的线索标签)、外观分配(RGB、HSB、十六进制、源副本)、宏行编辑、跨序列范围的批量线索操作(存储、标签、外观)、序列回放、控制台状态查询(列表组/线索/预设/变量、读取对象注释、通用对象查询)、显示文件管理(保存/加载/新建/列表显示)、读回验证(读取宏行、提示信息、具有结构化解析的对象标签)、音乐表演工作流(创建歌曲对象、设置歌曲宏、构建集列表)和原始命令执行。
- 破坏性指挥安全警告 --删除工具包括有关下游效应(孤立的执行器句柄、丢失的线索编程)的信息警告,以帮助人工智能助手在确认之前了解影响。
- 完整的命令生成器 --200多个Python函数,涵盖了30多个模块中的所有grandMA2命令行关键字,每个函数都返回一个格式正确的命令字符串。
- 高级客户 --
GMA2Client提供工作流级别的方法:构建提示列表、使用预设设置夹具组、快速查看编程、批处理执行器分配。使用grandMA2的内联命名语法来最大限度地减少Telnet往返。 - 命令链 --
CommandSequence允许您组合多个命令,预览它们,并批量执行它们。 - 弹性Telnet客户端 --基于
telnetlib3具有自动登录、持久连接、连接健康检查、带有界指数回退的自动重新连接、通过以下方式进行命令序列化asyncio.Lock,以及优雅的关机。如果控制台重新启动或网络中断,客户端会检测到故障,并在下一个命令之前透明地重新连接。 - 连接错误浮出水面 --MCP工具捕获连接失败并返回人类可读的错误消息,而不是未处理的异常,因此AI助手知道命令何时未到达控制台。
- 可配置运输 --支持
stdio(默认,单客户端)和streamable-http(多客户端、基于网络的访问)传输。HTTP主机和端口可以通过环境变量进行配置。 - 可通过环境配置 --通过设置主机、端口、用户、密码和传输设置
.env或环境变量。
入门指南
先决条件
- Python>=3.12
- 启用Telnet访问的grandMA2控制台(或onPC)
- 紫外线 (推荐)或pip
在macOS上,如果您需要Telnet客户端进行手动测试:
brew install telnet安装
git clone
cd gma2-mcp使用紫外线:
uv sync使用pip:
python -m venv .venv
source .venv/bin/activate
pip install -e .配置
复制模板并填写您的控制台详细信息:
cp .env.template .env| 变量 | 描述 | 默认值 |
|---|---|---|
GMA_HOST | grandMA2 onPC的IP地址 | 127.0.0.1 |
GMA_PORT | Telnet端口 | 30000 |
GMA_USER | 登录用户名 | administrator |
GMA_PASSWORD | 登录密码 | admin |
MCP_TRANSPORT | MCP传输协议(stdio, streamable-http) | stdio |
MCP_HOST | HTTP绑定地址(仅限可流式传输的HTTP) | 127.0.0.1 |
MCP_PORT | HTTP端口(仅限可流式传输的HTTP) | 8000 |
GMA_HOST 应设置为运行grandMA2 onPC的计算机的IP地址。您可以在onPC网络设置或检查机器的网络配置中找到此信息。
端口30000是标准命令端口。端口30001是只读的(日志输出)。
要启用基于web或多客户端访问的HTTP传输:
MCP_TRANSPORT=streamable-http
MCP_HOST=0.0.0.0 # bind to all interfaces (default: 127.0.0.1)
MCP_PORT=3000 # custom port (default: 8000)当使用 streamable-http,来自多个客户端的并发命令通过内部锁自动序列化,以防止交错的Telnet命令,因为grandMA2控制台按顺序处理命令。
MCP注册
将服务器添加到MCP客户端配置中。
克劳德桌面版 (~/Library/Application Support/Claude/claude_desktop_config.json 在macOS上):
{
"mcpServers": {
"gma2": {
"command": "uv",
"args": [
"--directory",
"/path/to/gma2-mcp",
"run",
"python",
"-m",
"src.server"
],
"env": {
"GMA_HOST": "2.0.0.1",
"GMA_USER": "administrator",
"GMA_PASSWORD": "admin"
}
}
}
}无紫外线 --直接指向virtualenv Python:
{
"mcpServers": {
"gma2": {
"command": "/path/to/gma2-mcp/.venv/bin/python",
"args": ["-m", "src.server"],
"cwd": "/path/to/gma2-mcp",
"env": {
"GMA_HOST": "2.0.0.1",
"GMA_USER": "administrator",
"GMA_PASSWORD": "admin"
}
}
}
}克劳德代码(CLI/IDE扩展)
Claude Code通过自己的配置管理MCP服务器,与Claude Desktop分开。您可以使用CLI命令或直接编辑设置文件进行设置。
选项1:使用 claude mcp add 命令(推荐)
在终端中运行以下命令:
claude mcp add gma2 \
-e GMA_HOST=2.0.0.1 \
-e GMA_USER=administrator \
-e GMA_PASSWORD=admin \
-- uv --directory /path/to/gma2-mcp run python -m src.server这将使用Claude Code注册MCP服务器。这 -e 标志设置服务器在启动时读取的环境变量。替换 /path/to/gma2-mcp 使用克隆存储库的实际路径,并调整 GMA_HOST, GMA_USER,以及 GMA_PASSWORD 值以匹配您的主机。
要仅为特定项目注册服务器(而不是全局注册),请添加 -s project 标志:
claude mcp add gma2 -s project \
-e GMA_HOST=2.0.0.1 \
-e GMA_USER=administrator \
-e GMA_PASSWORD=admin \
-- uv --directory /path/to/gma2-mcp run python -m src.server选项2:手动编辑设置文件
将服务器条目添加到Claude Code设置文件中。文件位置取决于范围:
- 用户级别 (适用于所有项目):
~/.claude/settings.json - 项目级别 (仅在当前项目中可用):
.claude/settings.json在项目根中
{
"mcpServers": {
"gma2": {
"command": "uv",
"args": [
"--directory",
"/path/to/gma2-mcp",
"run",
"python",
"-m",
"src.server"
],
"env": {
"GMA_HOST": "2.0.0.1",
"GMA_USER": "administrator",
"GMA_PASSWORD": "admin"
}
}
}
}验证设置
注册服务器后,验证其是否正常工作:
# List all registered MCP servers
claude mcp list
# Check the server details
claude mcp get gma2当您启动新的Claude Code会话时,服务器会自动启动。您可以通过要求Claude列出其MCP工具或直接请求grandMA2操作(例如,“在控制台上切换停电”)来确认工具可用。
管理服务器
# Remove the server
claude mcp remove gma2
# Re-add with different settings
claude mcp add gma2 \
-e GMA_HOST=192.168.1.100 \
-- uv --directory /path/to/gma2-mcp run python -m src.server用法
MCP工具
服务器公开了41个工具:
| 工具 | 说明 |
|---|---|
create_fixture_group | 选择装置并存储为命名组(2个命令) |
store_cue | 将当前程序员状态存储为提示 |
delete_cue | 删除提示(包括下游安全警告) |
goto_cue_tool | 跳转到特定提示(执行器或序列) |
set_fixture_value | 将灯具设置为调光值(0-100) |
set_fixture_attribute | 在夹具上设置特定属性(平移、倾斜等) |
clear_programmer | 清除编程器(全部、选择、活动、默认) |
store_preset | 将当前值存储为预设值 |
apply_preset | 将现有预设应用于当前选择 |
control_executor | 开/关/去/杀死/切换执行器 |
set_executor_fader | 设置执行器推子级别(0-100) |
assign_to_executor | 为执行器分配序列(支持命名页面路径) |
toggle_blackout | 切换大停电 |
toggle_highlight | 切换高亮显示模式 |
label_object | 为任何MA2对象指定名称标签 |
label_sequence_cue | 在特定序列中标记线索 |
assign_appearance | 在池对象和线索上设置框架/背景颜色(RGB/HSB/hex) |
set_macro_line | 为特定宏行设置命令 |
run_macro | 按ID执行宏(Go+macro) |
create_macro | 使用命令行创建宏(存储+分配行+标签) |
label_macro_tool | 在宏池中标记宏 |
list_macros | 列出宏池中的宏 |
delete_macro_tool | 删除宏(带有破坏性操作警告) |
apply_effect | 将池中的效果应用于当前设备选择 |
set_effect_speed | 以BPM或Hz为单位设置效果速度 |
set_effect_form | 设置效果波形(正弦、斜坡、方形等) |
set_effect_range | 设置效果高值和/或低值 |
set_effect_phase | 以度为单位设置效果相位偏移 |
set_effect_width | 设置效果宽度(循环百分比) |
stop_effects | 停止运行当前选择的效果(关闭效果) |
sync_effects_tool | 同步所有跑步效果 |
set_cue_cmd | 为线索的CMD字段指定命令 |
store_cue_across_sequences | 在一次呼叫中跨一系列序列存储提示 |
label_cue_across_sequences | 在一次通话中,在一系列序列中标记一个线索 |
appearance_cue_across_sequences | 在一次通话中设置一系列序列的提示外观 |
execute_sequence | 按顺序前进、暂停或转到提示 |
list_groups | 列出所有已定义的组(返回原始控制台响应) |
list_cues | 按顺序列出提示(返回原始控制台响应) |
list_presets | 按类型列出预设值并进行验证(返回原始控制台响应) |
get_cue_annotation | 根据提示阅读用户添加的注释文本 |
get_group_annotation | 读取组上用户添加的注释文本 |
list_variables | 使用可选筛选器列出显示或用户变量 |
query_object | 任何MA2对象类型的通用查询(列表或注释模式) |
save_show_tool | 保存当前节目文件(可选名称) |
load_show_tool | 加载显示文件(破坏性--警告未保存的更改) |
new_show_tool | 创建新的空显示(破坏性-警告未保存的更改) |
list_shows_tool | 列出控制台上可用的显示文件 |
read_macro_lines | 读取宏行内容(解析为结构化数据) |
read_cue_info | 读取线索属性:标签、CMD、淡入淡出(解析) |
read_object_label | 读取任何池对象的标签(序列、页面、宏等) |
create_song_objects | 为歌曲创建并标记序列+页面对 |
setup_song_macro | 使用SetVar命令创建宏以分配歌曲变量 |
build_set_list | 构建一个带有宏链接提示的集合列表序列 |
send_raw_command | 发送任何grandMA2命令行指令 |
查询/反思工具
查询工具使用 send_command_with_response() 捕获grandMA2 Telnet输出并返回原始文本。grandMA2手册没有记录以下设备的确切Telnet有线格式 List 和 Info 响应,因此这些工具返回未处理的控制台输出,人工智能可以直接解释。
list_groups,list_cues,list_presets--使用grandMA2List关键字检索显示数据。接受可选的ID范围(例如。,list_groups(group_id=1, end_group_id=10)).list_presets在发送之前,根据9种已知类型验证预设类型。get_cue_annotation,get_group_annotation--使用grandMA2Info关键字,读取用户在对象上添加的描述性文本注释(通过设置Info Group 3 "some note"在控制台上)。这些不会返回对象属性,如淡入淡出时间或夹具组合——使用list_cues或list_groups为了这个。list_variables--路线至ListVar(显示变量)或ListUserVar(用户变量)基于variable_type参数。支持可选的过滤模式。query_object--专用工具未涵盖的任何grandMA2对象类型的通用查询。支持mode="list"(默认)和mode="annotation".
当控制台不返回数据时,所有查询工具都会返回描述性消息,而不是空字符串。
显示文件管理工具
save_show_tool--保存当前节目文件。接受可选show_name以另存为特定名称。用途/noconfirm以抑制将阻止Telnet的覆盖确认弹出窗口。load_show_tool--按名称加载显示文件。这是一个破坏性的操作:对当前节目的未保存更改将丢失。接受save_first=True加载前保存当前节目。用途/noconfirm以抑制GUI弹出。new_show_tool--创建新的空节目。同样的破坏行为和save_first选项为load_show_tool.list_shows_tool--列出控制台所选驱动器上的可用显示文件。接受可选的过滤器模式。
读回工具
回读工具使用 send_command_with_response() 捕获grandMA2 List 命令输出并将其解析为结构化字典 src/response_parser.py每个工具返回一个包含解析字段和 raw_response 调试字段。如果无法识别响应格式,工具将返回 parsed: False 原始输出。
read_macro_lines--发送List Macro {pool}.{id}并解析每行的编号和CMD内容。退货{"macro_id": N, "parsed": True, "lines": [{"line_number": 1, "cmd": "..."}], "raw_response": "..."}.read_cue_info--发送List Cue {id} Sequence {seq}并提取标签、CMD和淡入淡出时间。退货{"sequence_id": N, "cue_id": N, "label": "...", "cmd": "...", "fade": "...", "raw_response": "..."}.read_object_label--发送List {type} {id}并提取对象的名称/标签。适用于任何池对象类型(序列、页面、组等)。对于宏object_id必须具有池资格(例如。,"1.5"对于池1中的宏5)。
音乐表演工作流程工具
高级工具,自动化音乐节目编程的常见多步模式。这些代表 GMA2Client 工作流方法。
create_song_objects--创建并标记具有相同ID和名称的序列+页面对。这是每首歌曲节目的标准模式(例如。,create_song_objects(song_id=101, song_name="Opening+Childhood")发送2个命令)。setup_song_macro--创建带有标签的宏SetVar第1行上的命令,用于跟踪当前歌曲。接受可选var_name(默认值:$song).发送3个命令:存储宏、标签、分配CMD。build_set_list--创建带有链接到歌曲宏的提示的集合列表序列。对于每首歌曲,存储一个以歌曲名称为标签的提示,并分配Macro {id}作为提示CMD。接受以下列表{cue_id, macro_id, name}字典。
delete_show 故意不将其作为MCP工具公开——它是不可逆的,对于人工智能发起的操作来说太危险了。这 Backup 命令也被排除在外,因为它在控制台上打开了一个GUI菜单(根据grandMA2手册第368页),该菜单在Telnet上无法运行。使用 save_show_tool 使用特定名称作为实际的备份机制。
指令产生器
这 src/commands/ 模块可以独立用于构建命令字符串:
from src.commands import fixture, at_full, store_group, label_group
fixture(1, end=10) # "fixture 1 thru 10"
at_full() # "at full"
store_group(5) # "store group 5"
store_group(5, name="Front Wash") # 'store group 5 "Front Wash"' (inline naming)
label_group(5, "Front Wash") # 'label group 5 "Front Wash"' (separate label command)GMA2Client(工作流编排)
这 GMA2Client 类提供了组合多个命令的高级工作流方法。这些方法使用grandMA2的内联命名语法来最小化Telnet往返次数:
from src.gma2_client import GMA2Client
async with GMA2Client.create("192.168.1.100") as client:
# Build a cue list with names and fade times
# Uses inline naming: 1 command per named cue (store cue N "Name"),
# plus 1 command per fade time
await client.build_cue_list(1, [
{"id": 1, "name": "Preset", "fade": 0},
{"id": 2, "name": "Look 1", "fade": 3.0},
{"id": 3, "name": "Blackout", "fade": 2.0},
])
# Select fixtures, store as named group, apply a preset (3 commands)
# Uses inline naming: store group N "Name" in a single command
await client.setup_group_with_preset(
fixtures=(1, 10), group_id=1,
group_name="Front Wash", preset_type="color", preset_id=3,
)
# Quick look: set fixtures to a value, optionally store as cue
await client.quick_look(fixtures=(1, 20), value=75, store_as_cue=5)
# Batch assign sequences to executors
await client.assign_sequences_to_executors([(1, 1), (2, 2), (3, 3)])
# Clone fixture programming (with /noconfirm for telnet)
await client.clone_fixtures(source_fixture=1, target_fixture=11,
source_end=5, target_end=15, mode="overwrite")
# Apply effect to a group with parameters
await client.setup_effect_on_group(group_id=1, effect_id=5,
bpm=120, form="sin", high=100, low=0)
# Set up a full executor page
await client.setup_executor_page(page=1, assignments=[
{"executor_id": 1, "sequence_id": 1, "label": "Wash", "fader_level": 80},
{"executor_id": 2, "sequence_id": 2, "label": "Spots"},
])
# Label multiple objects at once
await client.batch_label("group", {1: "Wash", 2: "Spots", 3: "Beams"})
# Create and optionally run a macro
await client.create_and_run_macro(
macro_id=10, commands=["Go Sequence 1", "Go Sequence 2"],
name="Start Show", run=True,
)
# Music show workflows: create song objects (sequence + page pair)
await client.create_song_objects(song_id=101, song_name="Opening+Childhood")
# Set up a song macro with SetVar on line 1
await client.setup_song_macro(macro_id=101, song_name="Opening+Childhood")
# Build a full set list with cue-to-macro links
await client.build_set_list(
sequence_id=100, sequence_name="Set List",
songs=[
{"cue_id": 1, "macro_id": 101, "name": "Opening+Childhood"},
{"cue_id": 2, "macro_id": 102, "name": "Nostalgia"},
{"cue_id": 3, "macro_id": 103, "name": "Finale"},
],
)命令序列(命令链)
这 CommandSequence 类允许您组合多个命令并将其作为批处理执行:
from src.command_sequence import CommandSequence
from src.commands import fixture_at, store_group, at_full
seq = CommandSequence()
seq.add(fixture_at(1, 50)).add(at_full()).add(store_group(1))
# Preview before sending
print(seq.preview()) # ['fixture 1 at 50', 'at full', 'store group 1']
# Execute all commands
result = await seq.execute(client)
# {'commands_sent': [...], 'count': 3, 'success': True}直接电话网络接入
对于通过Makefile进行的手动测试:
make server # Connect to grandMA2 command port (30000)
make log # Connect to log output port (30001)要退出Telnet会话:按 Ctrl + ],然后键入 quit.
手动运行MCP服务器
uv run python -m src.server命令参考
命令生成器遵循官方的grandMA2命令行语法。基本模式是 [Function] [Object]。所有对象都有默认函数,大多数函数都有默认对象类型。对象排列在层次树中。
1.助词(介词/连词)
用于创建函数和对象之间的关系。
| 关键字 | 描述 | 示例 |
|---|---|---|
Thru | 范围选择 | Fixture 1 Thru 10 |
+ | 添加到选择 | Fixture 1 + 3 + 5 |
At | 设置值 | At 50 |
2.对象关键字(名词)
在显示文件中分配对象。通常与数字、ID、名称或标签结合使用。
| 对象 | 函数 | 示例 |
|---|---|---|
fixture() | 按夹具ID选择夹具 | fixture(34) -> fixture 34 |
channel() | 按通道ID选择灯具 | channel(11, sub_id=5) -> channel 11.5 |
group() | 选择组中的设备 | group(3) -> group 3 |
preset() | 应用预设 | preset("color", 5) -> preset 4.5 |
cue() | 参考提示 | cue(5) -> cue 5 |
sequence() | 引用序列 | sequence(3) -> sequence 3 |
3.功能关键字(动词)
执行一项任务或功能,后面通常是它们所应用的对象。
| 功能 | 说明 | 示例 |
|---|---|---|
store() | 将对象存储在显示文件中 | store("macro", 5) -> store macro 5 |
store_cue() | 使用可选内联名称存储提示 | store_cue(1, name="Look") -> store cue 1 "Look" |
store_preset() | 使用选项存储预设 | store_preset("dimmer", 3) -> store preset 1.3 |
store_group() | 存储组(带可选内联名称) | store_group(1, name="Front") -> store group 1 "Front" |
label_group() | 为组添加标签 | label_group(1, "Front") -> label group 1 "Front" |
delete_group() | 删除组 | delete_group(1) -> delete group 1 |
select_fixture() | SelFix功能 | select_fixture(1, 10) -> selfix fixture 1 thru 10 |
clear() | 清晰的程序员 | clear() -> clear |
clear_selection() | 仅清除选择 | clear_selection() -> clearselection |
clear_active() | 清除活动值 | clear_active() -> clearactive |
clear_all() | 全部清除 | clear_all() -> clearall |
go_sequence() | 开始序列回放 | go_sequence(1) -> go+ sequence 1 |
pause_sequence() | 暂停顺序 | pause_sequence(1) -> pause sequence 1 |
goto_cue() | 跳转到提示 | goto_cue(1, 5) -> goto cue 5 sequence 1 |
4.在关键字(特殊)
At 同时作为功能关键字和帮助关键字。
| 功能 | 说明 | 示例 |
|---|---|---|
at(75) | 将调光器设置为值 | at(75) -> at 75 |
at(cue=3) | 应用提示值 | at(cue=3) -> at cue 3 |
at(fade=2) | 设置淡入淡出时间 | at(fade=2) -> at fade 2 |
at_full() | 设置为100% | at_full() -> at full |
at_zero() | 设置为0% | at_zero() -> at 0 |
attribute_at() | 设置属性值 | attribute_at("Pan", 20) -> attribute "Pan" at 20 |
fixture_at() | 将夹具设置为值 | fixture_at(2, 50) -> fixture 2 at 50 |
fixture_at() | 从夹具复制 | fixture_at(2, source_fixture=3) -> fixture 2 at fixture 3 |
channel_at() | 将通道设置为值 | channel_at(1, 75) -> channel 1 at 75 |
group_at() | 将组设置为值 | group_at(3, 50) -> group 3 at 50 |
executor_at() | 设置执行器推子 | executor_at(3, 50) -> executor 3 at 50 |
preset_type_at() | 设置预设类型值 | preset_type_at(2, 50, end_type=9) -> presettype 2 thru 9 at 50 |
5.复制和移动关键字
复制会创建重复项。Move会重新定位对象(如果目标被占用,则进行交换)。
| 功能 | 说明 | 示例 |
|---|---|---|
copy("group", 1, 5) | 复制到目标 | copy group 1 at 5 |
copy("group", 1, end=3, target=11) | 复制范围 | copy group 1 thru 3 at 11 |
copy("group", 2, 6, target_end=8) | 复制到目标范围 | copy group 2 at 6 thru 8 |
copy("cue", 5) | 复制到剪贴板 | copy cue 5 |
copy_cue(2, 6) | 复制提示 | copy cue 2 at 6 |
move("group", 5, 9) | 移动对象 | move group 5 at 9 |
move("group", 1, 10, end=3) | 移动范围 | move group 1 thru 3 at 10 |
复制选项: overwrite, merge, status, cueonly, noconfirm
6.指定关键字
定义对象、修补和特性指定之间的关系。
| 功能 | 说明 | 示例 |
|---|---|---|
assign("sequence", 1, "executor", 6) | 将seq分配给执行人 | assign sequence 1 at executor 6 |
assign("dmx", "2.101", "channel", 5) | 将DMX修补到通道 | assign dmx 2.101 at channel 5 |
assign("group", 1, "layout", 1, x=5, y=2) | 分配到布局 | assign group 1 at layout 1 /x=5 /y=2 |
assign_function("Toggle", "executor", 101) | 为按钮分配功能 | assign toggle at executor 101 |
assign_fade(3, 5) | 为提示指定淡入淡出时间 | assign fade 3 cue 5 |
assign_to_layout("group", 1, 1, x=5, y=2) | 指定布局位置 | assign group 1 at layout 1 /x=5 /y=2 |
assign_macro_cmd(101, 1, "Go Seq 5") | 设置宏行命令 | assign macro 1.101.1 /cmd="Go Seq 5" |
assign_cue_cmd(1, 100, "Macro 101") | 设置提示CMD字段 | assign cue 1 sequence 100 /cmd="Macro 101" |
分配选项: break_, multipatch, reset, x, y, noconfirm, special, cue_mode, password
7.标签关键字
为对象命名。名称中的数字会自动枚举范围。
| 功能 | 说明 | 示例 |
|---|---|---|
label("group", 3, "All Studiocolors") | 标签组 | label group 3 "All Studiocolors" |
label("fixture", 1, "Mac700 1", end=10) | 标签范围 | label fixture 1 thru 10 "Mac700 1" |
label("preset", '"color"."Red"', "Dark") | 标签预设 | label preset "color"."Red" "Dark" |
label_sequence_cue("Set List", 1, "Opening") | 按顺序标记线索 | label sequence "Set List" cue 1 "Opening" |
label_sequence_cue(100, 1, "Act 1", end_cue=5) | 标签提示范围 | label sequence 100 cue 1 thru 5 "Act 1" |
8.外观关键字
更改池对象的框架颜色和线索的背景颜色。
| 功能 | 说明 | 示例 |
|---|---|---|
appearance("preset", "0.1", red=100, green=0, blue=0) | 设置RGB颜色 | appearance preset 0.1 /r=100 /g=0 /b=0 |
appearance("preset", "0.1", hue=0, saturation=100) | 设置HSB颜色 | appearance preset 0.1 /h=0 /s=100 |
appearance("group", 1, end=5, color="FF0000") | 设置十六进制颜色 | appearance group 1 thru 5 /color=FF0000 |
appearance("macro", 2, source_type="macro", source_id=13) | 从源复制 | appearance macro 2 at macro 13 |
appearance("preset", 1, reset=True) | 重置外观 | appearance preset 1 /reset |
9.宏占位符(@Character)
这 @ 性格(不同于 At 关键字)用作宏中用户输入的占位符。
| 功能 | 说明 | 示例 |
|---|---|---|
macro_with_input_after() | @在宏行末尾 | macro_with_input_after("Load") -> Load @ |
macro_with_input_before() | @在宏行的开头 | macro_with_input_before("Fade 20") -> @ Fade 20 |
项目结构
gma2-mcp/
├── src/
│ ├── commands/ # Command builder module
│ │ ├── __init__.py # Public API exports
│ │ ├── constants.py # PRESET_TYPES, store option sets
│ │ ├── helpers.py # Internal helper functions
│ │ └── functions/ # Function keywords by category
│ │ ├── advanced_edit.py # Flip, CircularCopy, Import, Export
│ │ ├── assignment.py # Assign keyword functions
│ │ ├── blackout.py # Blackout, Freeze, Highlight, Solo
│ │ ├── blind.py # Blind, Preview modes
│ │ ├── call.py # Call keyword
│ │ ├── conditionals.py # EndIf, IfActive, IfOutput, Or, With
│ │ ├── crossfade.py # Crossfade, ManualXFade
│ │ ├── cue_timing.py # Delay, Fade timing
│ │ ├── edit.py # Copy, Move, Delete, Remove
│ │ ├── effect.py # Effect, EffectBPM, EffectForm
│ │ ├── executor_control.py # Off, On, Kill, Flash, Swop
│ │ ├── fixture_control.py # Align, Fix, Locate, Next, Prev
│ │ ├── flash_swop_ext.py # FlashGo, SwopGo, StoreLook
│ │ ├── helping.py # Helping keywords (Thru, +)
│ │ ├── info.py # List and Info queries
│ │ ├── intensity.py # Full, Zero, Load, Learn
│ │ ├── labeling.py # Label and Appearance
│ │ ├── list_ext.py # ListShows, ListOops, ListVar
│ │ ├── macro.py # Macro placeholder functions
│ │ ├── matricks.py # MAtricks keywords
│ │ ├── midi.py # MIDI control functions
│ │ ├── navigation.py # Down, Up, NextRow, Search
│ │ ├── network.py # Remote, Telnet, JoinSession
│ │ ├── park.py # Park/Unpark functions
│ │ ├── playback.py # Go, GoBack, Goto, DefGo
│ │ ├── programmer.py # Block, Clone, Default, Update
│ │ ├── rate_speed.py # Rate, Speed control
│ │ ├── rdm.py # RDM functions
│ │ ├── selection.py # SelFix and Clear functions
│ │ ├── show_data.py # CrashLog, Lua, PSR, Thru
│ │ ├── step_timing.py # SnapPercent, StepFade, FadePath
│ │ ├── store.py # Store functions
│ │ ├── system.py # Backup, Setup, Shutdown, Login
│ │ ├── values.py # At and value setting
│ │ └── variables.py # Variable functions
│ ├── command_sequence.py # CommandSequence for multi-command batching
│ ├── gma2_client.py # High-level workflow orchestration client (15 methods)
│ ├── response_parser.py # Parse grandMA2 Telnet output into structured data
│ ├── server.py # MCP server (FastMCP, 41 tools, configurable stdio/streamable-http transport)
│ └── telnet_client.py # Async Telnet client with health check, auto-reconnect, command lock, state tracking
├── tests/ # Pytest test suite (one file per module)
├── doc/ # grandMA2 user manual (PDF)
├── connect.sh # Telnet connection script with auto-login
├── Makefile # Utility commands (server, log, test)
├── pyproject.toml # Project metadata and dependencies
└── .env.template # Environment variable template发展
运行测试
make test或者直接:
uv run pytest -v运行特定的测试文件:
uv run pytest tests/test_playback.py -v依赖项
| 包装 | 用途 |
|---|---|
mcp>=1.21.0 | 模型上下文协议库 |
python-dotenv | 环境变量加载 |
telnetlib3 | 异步Telnet客户端 |
pytest | 测试框架(开发) |
pytest-asyncio | 异步测试支持(开发) |
建筑
该项目有五层:
- Telnet 客户端 (
src/telnet_client.py)--与控制台的低级异步Telnet通信。包含ConnectionState跟踪(断开/连接/连接/重新连接)、健康检查探测、具有有界指数回退的自动重新连接(可配置的重试和延迟)、在快速命令序列中跳过冗余探测的健康检查TTL,asyncio.Lock-基于命令序列化实现并发访问安全,并通过服务器生命周期挂钩实现优雅关闭。 - 指令产生器 (
src/commands/)--构造命令字符串的纯函数。无法访问网络。 - 响应解析器 (
src/response_parser.py)--解析grandMA2 Telnet的纯函数List命令输出为结构化字典。退货parsed: False无法识别的格式。 - 编排 (
src/gma2_client.py,src/command_sequence.py)--高级工作流方法(包括音乐表演工作流在内的15种方法)和命令批处理,组成构建器+telnet。 - MCP服务器 (
src/server.py)--通过可配置传输公开41个工具的FastMCP服务器(stdio或streamable-http),将构建器连接到Telnet客户端。
所有控制台通信都通过Telnet客户端层。
故障排除
连接失败 --验证控制台IP和端口。确保控制台上启用了Telnet。手动测试 make server.
会话中途连接中断 --Telnet客户端最多可重试3次自动重新连接(指数回退:1s、2s、4s)。如果所有重试都失败,工具将返回一条明确的错误消息。检查控制台是否正在运行且可访问。
身份验证错误 --在中检查用户名/密码 .env。确认控制台上存在用户帐户。登录区分大小写。
夹具设置被过时的连接锁定 --如果前一个会话在没有调用的情况下崩溃 disconnect(),控制台可能仍持有Telnet锁。重新启动控制台或等待其会话超时。MCP服务器现在调用 disconnect() 关闭以防止这种情况。
命令不起作用 --根据grandMA2手册验证语法。确保当前显示文件中存在引用的对象(装置、组、预设)。
许可证
此项目根据Apache许可证2.0获得许可。看 许可证 了解详情。
贡献
- 分叉存储库
- 创建要素分支(
git checkout -b feature/name) - 提交您的更改
- 推送到分支并打开Pull Request
提交前运行测试: make test
