Live demo — data resets daily at 03:00 UTC. Nothing you enter is saved. Server UI →

product: maestro audience: test-developer, operator, ai-assistant authority: normative

MCP Server — Multi-Station Setup


One MCP Server Per Station

Every WorkflowEngine.McpServer instance connects to exactly one WorkflowEngine.Api instance. There is no routing layer. If you have three test stations (ST-01, ST-02, ST-03), you need three separate MCP server entries — one per station.

This is intentional: it prevents an AI assistant from accidentally starting a test on the wrong station. The MCP server knows only one API address and can only act on that station.


Registering Multiple Stations

Add one entry per station to your MCP client configuration. The key names under mcpServers are arbitrary labels used by the client — choose names that match your station IDs.

Example: three stations in .mcp.json

{
  "mcpServers": {
    "maestro-ST-01": {
      "type": "stdio",
      "command": "dotnet",
      "args": [
        "run",
        "--project",
        "WorkflowEngine.McpServer/WorkflowEngine.McpServer.csproj",
        "--no-launch-profile"
      ],
      "env": {
        "Maestro__BaseUrl": "http://10.0.1.11:5000",
        "Maestro__StationLabel": "ST-01"
      }
    },
    "maestro-ST-02": {
      "type": "stdio",
      "command": "dotnet",
      "args": [
        "run",
        "--project",
        "WorkflowEngine.McpServer/WorkflowEngine.McpServer.csproj",
        "--no-launch-profile"
      ],
      "env": {
        "Maestro__BaseUrl": "http://10.0.1.12:5000",
        "Maestro__StationLabel": "ST-02"
      }
    },
    "maestro-ST-03": {
      "type": "stdio",
      "command": "dotnet",
      "args": [
        "run",
        "--project",
        "WorkflowEngine.McpServer/WorkflowEngine.McpServer.csproj",
        "--no-launch-profile"
      ],
      "env": {
        "Maestro__BaseUrl": "http://10.0.1.13:5000",
        "Maestro__StationLabel": "ST-03"
      }
    }
  }
}

Each entry starts an independent dotnet run process when the AI client connects to it. The processes do not share state.


The Station Label and Response Envelope

Every tool response from the MCP server includes a top-level station field:

{
  "station": "ST-02",
  "result": {
    "testName": "voltage-test",
    "verdict": "PASS",
    ...
  }
}

station always equals the Maestro__StationLabel configured for that server instance. When an AI assistant is working with multiple stations simultaneously, this field prevents confusion — the assistant always knows which station produced the response even if several tool calls were made in parallel.

Rule: set Maestro__StationLabel to match the station_id stored in that station's Station Config (the value returned by get_station_id). Keeping these in sync avoids confusing discrepancies in the AI's reasoning.


Targeting a Specific Station

In a multi-station session, address the AI assistant explicitly:

"On ST-02, start the TestFiles/board-test.yaml test for serial number UNIT-007."

The AI client routes the tool call to the maestro-ST-02 server (by matching the server label in the conversation context). The start_test response will include "station": "ST-02" confirming the correct station was used.


Parallel Execution Across Stations

An AI assistant can start tests on multiple stations in parallel by calling start_test on each server, then calling wait_for_test_completion on each execution ID:

# pseudocode — the AI drives this through conversation
ST-01: exec_id_a = start_test(yamlFilePath=..., serialNumber="UNIT-001", unattendedMode=true)
ST-02: exec_id_b = start_test(yamlFilePath=..., serialNumber="UNIT-002", unattendedMode=true)
ST-03: exec_id_c = start_test(yamlFilePath=..., serialNumber="UNIT-003", unattendedMode=true)

ST-01: result_a = wait_for_test_completion(executionId=exec_id_a)
ST-02: result_b = wait_for_test_completion(executionId=exec_id_b)
ST-03: result_c = wait_for_test_completion(executionId=exec_id_c)

Each wait_for_test_completion call runs against its own server and does not block the others (the AI client can interleave them).


Network Requirements

If the AI assistant is running on an engineer's laptop and the stations are on a factory network, ensure:

  1. The laptop can reach each station's API port (default 5000) — firewall rules may need to allow this.
  2. The Maestro__BaseUrl in each .mcp.json entry uses the station's IP or hostname, not localhost.
  3. Each station runs its own WorkflowEngine.Api — there is no central API to route through.

Pre-Built Executables for Air-Gapped Stations

On production stations without the .NET 10 SDK, publish a self-contained executable once and copy it to each station. See setup.md § 5 for the publish command.

With pre-built executables, update each .mcp.json entry to use the executable path instead of dotnet run.


Troubleshooting

Symptom Likely cause Fix
"station": "Maestro Station" in every response Maestro__StationLabel was not set in the env block Add "Maestro__StationLabel": "ST-01" to the env section
Tool calls all go to the same station All entries share the same Maestro__BaseUrl Verify each entry has a distinct IP/hostname
Second server fails to start Port conflict or missing SDK Check the second station's API is running and .NET 10 is on the PATH
AI calls the wrong station Station labels are ambiguous Use distinct, unambiguous labels (maestro-ST-01, maestro-ST-02) — not generic names like maestro-a
An unhandled error has occurred. Reload 🗙

Rejoining the server...

Rejoin failed... trying again in seconds.

Failed to rejoin.
Please retry or reload the page.

The session has been paused by the server.

Failed to resume the session.
Please retry or reload the page.