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.yamltest for serial numberUNIT-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:
- The laptop can reach each station's API port (default
5000) — firewall rules may need to allow this. - The
Maestro__BaseUrlin each.mcp.jsonentry uses the station's IP or hostname, notlocalhost. - 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 |