# Gma2 Mcp

> grandMA2 MCP is a Python tool to remotely control grandMA2 onPC via persistent Telnet, enabling automated lighting-console workflows and command pipelines.

- **Type:** MCP server
- **Install:** `agentstack add mcp-chienchuanw-gma2-mcp`
- **Verified:** Yes — security-reviewed for prompt injection and unsafe behavior
- **Seller:** [chienchuanw](https://agentstack.voostack.com/s/chienchuanw)
- **Installs:** 0
- **Category:** [Integrations](https://agentstack.voostack.com/c/integrations)
- **Latest version:** 0.1.0
- **License:** Apache-2.0
- **Upstream author:** [chienchuanw](https://github.com/chienchuanw)
- **Source:** https://github.com/chienchuanw/gma2-mcp

## Install

```sh
agentstack add mcp-chienchuanw-gma2-mcp
```

Requires the [AgentStack CLI](https://agentstack.voostack.com/docs/cli). Works with Claude Code, Cursor, and any MCP-compatible agent.

## About

# GMA2 MCP

An MCP server that lets AI assistants control grandMA2 lighting consoles via Telnet. It exposes 101 high-level tools for cue management, fixture control, preset management, executor control, macro editing, appearance assignment, bulk operations, console state queries, show file management, read-back verification, music show workflows, and more through the Model Context Protocol.

## Table of Contents

- [Overview](#overview)
- [Features](#features)
- [Getting Started](#getting-started)
  - [Prerequisites](#prerequisites)
  - [Installation](#installation)
  - [Configuration](#configuration)
  - [MCP Registration](#mcp-registration)
- [Usage](#usage)
  - [MCP Tools](#mcp-tools)
  - [Command Builder](#command-builder)
  - [Direct Telnet Access](#direct-telnet-access)
- [Command Reference](#command-reference)
  - [Helping Keywords](#1-helping-keywords-prepositionsconjunctions)
  - [Object Keywords](#2-object-keywords-nouns)
  - [Function Keywords](#3-function-keywords-verbs)
  - [At Keyword](#4-at-keyword-special)
  - [Copy and Move](#5-copy-and-move-keywords)
  - [Assign](#6-assign-keyword)
  - [Label](#7-label-keyword)
  - [Appearance](#8-appearance-keyword)
  - [Macro Placeholder](#9-macro-placeholder--character)
- [Project Structure](#project-structure)
- [Development](#development)
- [Troubleshooting](#troubleshooting)
- [License](#license)
- [Contributing](#contributing)

## Overview

grandMA2 consoles accept commands over Telnet, but building correct command strings requires knowledge of the MA2 syntax rules -- keyword ordering, preset type mappings, option flags, and object hierarchies. This project handles that complexity in layered components:

1. **Command Builder** (`src/commands/`) -- Python functions that construct valid grandMA2 command strings following the official syntax rules. Each function is a thin wrapper that returns a string; it never touches the network.
2. **MCP Server** (`src/server.py`) -- A FastMCP server that exposes 101 tools covering cue management, fixture control, presets, executors, global state, labeling, appearance assignment, macro editing, bulk cue operations, sequence playback, console state queries, show file management, read-back verification, music show workflows, and raw commands over stdio transport. It manages a persistent Telnet connection to the console and delegates command construction to the builder layer.
3. **Response Parser** (`src/response_parser.py`) -- Pure functions for parsing grandMA2 Telnet output: tabular `List` data into structured dicts, and inline `Error #NN: REASON` failures (with ANSI stripping) for the verified execution path.
4. **Execution Core** (`src/execution.py`) -- `ExecutionResult` plus the pure `build_result()` that turns a raw Telnet reply into a structured `{ok, echo, error_code, error_text, raw}`. Mutating tools route through `GMA2TelnetClient.execute()` so they report the console's real outcome instead of fabricating success.
5. **GMA2Client** (`src/gma2_client.py`) -- A high-level orchestration class that composes multiple command builder calls into workflow-level methods (e.g., build an entire cue list, set up a fixture group with a preset, create song objects for music shows).
6. **CommandSequence** (`src/command_sequence.py`) -- A builder-pattern class for composing multiple commands into an ordered batch that can be previewed and executed as a unit.

The command builder covers all grandMA2 command-line keywords organized by category: object keywords (fixtures, channels, groups, presets, cues, sequences, executors), function keywords (store, delete, copy, move, goto, label, assign, and many more), and helping keywords (thru, at, +).

## Features

- **100 MCP tools** -- Cue management (store/update/delete/goto, CMD assignment, timing, bulk operations), fixture control (set values/attributes, clear programmer, advanced selection: next/previous/invert/locate/align/fix), preset management (store/apply), executor control (on/off/go/kill/toggle/release/top, fader, rate/speed, flash/swop/stomp/temp busking), global state (blackout, highlight), blind/preview modes, object labeling, appearance assignment, copy/move and extended delete (group/preset/fixture/show), park/unpark, macro editing, effect control (apply, speed, form, range, phase, width, envelope, seconds, speed group, sync), MAtricks fan effects, show/user variables, timecode (SMPTE), MIDI output (note/control/program), clone fixtures, console state queries, show file management, read-back verification, music show workflows, and raw command execution.
- **Verified command execution** -- grandMA2 reports failures inline in the Telnet reply (`Error #NN: REASON`). Mutating tools route through a verified execution core (`src/execution.py`) that parses the reply and returns the console's real outcome, so the assistant is not given false success on a rejected command. Multi-command tools abort on the first error.
- **Range/batch selectors** -- Object tools accept grandMA2 selection expressions (`1 thru 10`, `1 + 3 + 5`, `1 thru 10 - 4`) validated by `src/commands/selector.py`, so a whole range copies/moves in one call instead of looping per ID.
- **Show-aware name resolution** -- `src/introspection.py` queries `List Attribute` (cached) and resolves friendly, show-specific attribute names (e.g. `White` -> `COLORRGB5`) before sending, rejecting unknown names with suggestions.
- **Fixture-profile resolver** -- `src/profile_resolver.py` parses MA2 fixture-type / GDTF XML and resolves named functions (`open`/`closed`/`strobe`/`random`/`iris`/`frost`/`prism`) to the correct per-fixture-type value, so the same logical preset (e.g. "Strobe Fast") gets the right DMX value on every profile.
- **Palette builders** -- `build_color_palette` and the generalized `build_preset_palette` program whole preset palettes in one call, with per-fixture-type values, Global/Selective scope, and per-type merge (extend a palette to a new fixture group non-destructively).
- **Destructive command safety warnings** -- Delete tools include informational warnings about downstream effects (orphaned executor handles, lost cue programming) to help AI assistants understand impact before confirming.
- **Complete command builder** -- Over 350 Python functions covering all grandMA2 command-line keywords across 30+ modules, each returning a correctly formatted command string.
- **High-level client** -- `GMA2Client` provides workflow-level methods: build cue lists, set up fixture groups with presets, quick look programming, batch executor assignments. Uses grandMA2's inline naming syntax to minimize Telnet round-trips.
- **Command chaining** -- `CommandSequence` lets you compose multiple commands, preview them, and execute them as a batch.
- **Resilient Telnet client** -- Built on `telnetlib3` with automatic login, persistent connections, connection health checking, auto-reconnection with bounded exponential backoff, command serialization via `asyncio.Lock`, and graceful shutdown. If the console restarts or the network drops, the client detects the failure and reconnects transparently before the next command.
- **Connection error surfacing** -- MCP tools catch connection failures and return human-readable error messages instead of unhandled exceptions, so the AI assistant knows when commands are not reaching the console.
- **Configurable transport** -- Supports `stdio` (default, single client) and `streamable-http` (multi-client, web-based access) transports. HTTP host and port are configurable via environment variables.
- **Configurable via environment** -- Host, port, user, password, and transport settings set through `.env` or environment variables.

## Getting Started

### Prerequisites

- Python >= 3.12
- A grandMA2 console (or onPC) with Telnet access enabled
- [uv](https://docs.astral.sh/uv/) (recommended) or pip

On macOS, if you need a Telnet client for manual testing:

```bash
brew install telnet
```

### Installation

```bash
git clone 
cd gma2-mcp
```

Using uv:

```bash
uv sync
```

Using pip:

```bash
python -m venv .venv
source .venv/bin/activate
pip install -e .
```

### Configuration

Copy the template and fill in your console details:

```bash
cp .env.template .env
```

| Variable       | Description                          | Default         |
|----------------|--------------------------------------|-----------------|
| `GMA_HOST`      | IP address of the grandMA2 onPC                | `127.0.0.1`     |
| `GMA_PORT`      | Telnet port                                    | `30000`         |
| `GMA_USER`      | Login username                                 | `administrator` |
| `GMA_PASSWORD`  | Login password                                 | `admin`         |
| `MCP_TRANSPORT` | MCP transport protocol (`stdio`, `streamable-http`) | `stdio`     |
| `MCP_HOST`      | HTTP bind address (streamable-http only)       | `127.0.0.1`     |
| `MCP_PORT`      | HTTP port (streamable-http only)               | `8000`          |

`GMA_HOST` should be set to the IP address of the machine running grandMA2 onPC. You can find this in the onPC network settings or by checking the machine's network configuration.

Port 30000 is the standard command port. Port 30001 is read-only (log output).

To enable HTTP transport for web-based or multi-client access:

```bash
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)
```

When using `streamable-http`, concurrent commands from multiple clients are automatically serialized via an internal lock to prevent interleaved Telnet commands, since the grandMA2 console processes commands sequentially.

### MCP Registration

Add the server to your MCP client configuration.

**Claude Desktop** (`~/Library/Application Support/Claude/claude_desktop_config.json` on macOS):

```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"
      }
    }
  }
}
```

**Without uv** -- point directly to the virtualenv Python:

```json
{
  "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"
      }
    }
  }
}
```

**Claude Code (CLI / IDE extensions)**

Claude Code manages MCP servers through its own configuration, separate from Claude Desktop. You can set it up using either the CLI command or by editing the settings file directly.

**Option 1: Using the `claude mcp add` command (recommended)**

Run the following command in your terminal:

```bash
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
```

This registers the MCP server with Claude Code. The `-e` flags set environment variables that the server reads at startup. Replace `/path/to/gma2-mcp` with the actual path to your cloned repository, and adjust the `GMA_HOST`, `GMA_USER`, and `GMA_PASSWORD` values to match your console.

To register the server for a specific project only (instead of globally), add the `-s project` flag:

```bash
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
```

**Option 2: Editing the settings file manually**

Add the server entry to your Claude Code settings file. The file location depends on the scope:

- **User-level** (available in all projects): `~/.claude/settings.json`
- **Project-level** (available only in the current project): `.claude/settings.json` in the project root

```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"
      }
    }
  }
}
```

**Verifying the setup**

After registering the server, verify it is working:

```bash
# List all registered MCP servers
claude mcp list

# Check the server details
claude mcp get gma2
```

When you start a new Claude Code session, the server starts automatically. You can confirm the tools are available by asking Claude to list its MCP tools or by directly requesting a grandMA2 operation (e.g., "toggle blackout on the console").

**Managing the server**

```bash
# 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
```

## Usage

### MCP Tools

The server exposes 101 tools:

| Tool                              | Description                                                          |
|-----------------------------------|----------------------------------------------------------------------|
| `capabilities`                    | Report version, registered tools, and profile schema version (contract surface; no console connection) |
| `create_fixture_group`            | Select fixtures and store as a named group (2 commands)              |
| `store_cue`                       | Store current programmer state as a cue                              |
| `delete_cue`                      | Delete a cue (includes downstream safety warnings)                   |
| `goto_cue_tool`                   | Jump to a specific cue (executor or sequence)                        |
| `set_fixture_value`               | Set fixture(s) to a dimmer value (0-100)                             |
| `set_fixture_attribute`           | Set a specific attribute (Pan, Tilt, etc.) on fixture(s)             |
| `clear_programmer`                | Clear the programmer (all, selection, active, default)               |
| `store_preset`                    | Store current values as a preset                                     |
| `apply_preset`                    | Apply an existing preset to the current selection                    |
| `control_executor`                | On/off/go/kill/toggle an executor                                    |
| `set_executor_fader`              | Set executor fader level (0-100)                                     |
| `assign_to_executor`              | Assign a sequence to an executor (supports named page paths)         |
| `toggle_blackout`                 | Toggle grand blackout                                                |
| `toggle_highlight`                | Toggle highlight mode                                                |
| `label_object`                    | Assign a name label to any MA2 object                                |
| `label_sequence_cue`              | Label a cue within a specific sequence                               |
| `assign_appearance`               | Set frame/background colors on pool objects and cues (RGB/HSB/hex)   |
| `set_macro_line`                  | Set the command for a specific macro line                            |
| `run_macro`                       | Execute a macro by ID (Go+ Macro)                                    |
| `create_macro`                    | Create a macro with command lines (store + assign lines + label)     |
| `label_macro_tool`                | Label a macro in the macro pool                                      |
| `list_macros`                     | List macros in the macro pool                                        |
| `delete_macro_tool`               | Delete a macro (with destructive operation warnings)                 |
| `apply_effect`                    | Apply effect

…

## Source & license

This open-source MCP server is cataloged on AgentStack and links to its original source — we do not rehost the code.

- **Author:** [chienchuanw](https://github.com/chienchuanw)
- **Source:** [chienchuanw/gma2-mcp](https://github.com/chienchuanw/gma2-mcp)
- **License:** Apache-2.0

Install and usage instructions live in the source repository linked above.

## Pricing

- **Free** — Free

## Security capabilities

Automated source analysis of v0.1.0 — what this tool can access:

- **Network access:** no
- **Filesystem access:** no
- **Shell / process execution:** no
- **Environment & secrets:** yes
- **Dynamic code execution:** no

*"Yes" means the capability is present in the source — more access means more to trust, not that it is unsafe.*


## Versions

- **0.1.0** — security scan: passed — Imported from the upstream source.

## Links

- Listing page: https://agentstack.voostack.com/l/mcp-chienchuanw-gma2-mcp
- Seller: https://agentstack.voostack.com/s/chienchuanw
- Browse the marketplace: https://agentstack.voostack.com/browse

---
Listed on AgentStack — the marketplace for AI agent skills and MCP servers. Every listing is security-reviewed. Creators keep 70%.
