Wie funktioniert der WAGO PLC MCP Server?

Antwort

Der Server macht aus der WDA-REST-API jeder WAGO-SPS 29 MCP-Tools. So kann ein KI-Agent Systemeinstellungen lesen und ändern. Der Server prüft jeden Schreibzugriff im Code, bevor der Zugriff eine SPS erreicht.

  1. Der Agent sieht benannte Tools. Der Server erledigt die HTTP-Aufrufe, das Paging und die Anmeldung an jeder SPS.1
  2. Beim Start speichert der Server die Parameter- und Methoden-IDs jeder SPS. Eine Suche kontaktiert die SPS deshalb nicht.2
  3. Der Agent kann keine Sicherheitsprüfung entfernen und keine SPS hinzufügen. Eine Person ändert diese Einstellungen und startet den Container neu.3

Gilt fürServer 2.4.4, Commit 015769b. Die Beispielausgabe stammt von einem Lesezugriff auf einen PFC300 mit Firmware 04.09.01. Für neue Leser dieses Servers.

1

Welche Begriffe brauchen Sie zuerst?

BegriffBedeutungBeispiel
MCPEin Protokoll, mit dem ein KI-Assistent feste Tools aufruftget_parameter
WDADie WAGO-REST-API für System- und DiagnoseverwaltungGET /wda/parameters/{id}
ParameterEin benannter Systemwert0-0-ntpclient-enabled
MethodeEine Aktion, die auf der SPS läuftNTP-Synchronisation, Neustart
WatchlistEine Liste von Parametern, die die SPS für wiederholtes Lesen bereithältDienststatus alle 30 s

Eine Parameter-ID hat eine feste Form: <device>-<instance>-<feature>-<name>. 0-0-ntpclient-enabled bedeutet also Gerät 0, Instanz 0, Feature ntpclient, Name enabled.3

2

Aus welchen Teilen besteht der Server?

Vom KI-Agenten zur SPS
Diagram structure
  • MCP-Client client
  • 29 MCP-Tools tools
  • PLC-Manager-Cache cache
  • Sicherheitsprüfungen gates
  • WDA-Client wda
  • Audit-Log audit
  • Konfigurations-Repository repo
  • WAGO-SPS-Flotte plc
  • client → tools · Bearer-Key
  • tools → cache · sucht
  • tools → gates · schreibt
  • tools → wda · liest
  • gates → wda · bestanden
  • gates → audit · protokolliert
  • gates → repo · GitOps-YAML
  • wda → plc · HTTPS
DateiAufgabe
src/main.pyDefiniert die Tools und startet den Server
src/auth.pyPrüft den Bearer-Key und das Rate-Limit
src/safety.pyErkennt gefährliche Methoden und schreibgeschützte SPSen
src/plc_manager.pyRegistriert SPSen und speichert ihre IDs
src/wda_client.pySendet die WDA-Anfragen für eine SPS
src/enricher.pyErgänzt Rohwerte um Labels und Statustext
src/audit.pySchreibt das Audit-Log mit Hash-Kette
src/gitops.pyErstellt YAML-Vorschläge für das Konfigurations-Repository
src/config.pyLiest die Flottenliste, die Secrets und die TLS-Einstellungen
3

Was passiert beim Serverstart?

Serverstart
Diagram structure
  • Sicherheitsprofil prüfen profile
  • Audit-Kette laden seed
  • Flottenliste lesen fleet
  • Jede SPS registrieren register
  • API-Key ermitteln key
  • Tools bereitstellen serve
  • fleet → register
  • key → serve
  • profile → seed
  • register → key
  • seed → fleet
  1. Sicherheitsprofil prüfen

    Mit SECURITY_PROFILE=hardened stoppt der Server, wenn TLS nicht vollständig ist.

  2. Audit-Kette laden

    Der Server liest die letzte Log-Zeile. So setzt sich die Hash-Kette nach einem Neustart fort.

  3. Flottenliste lesen

    Die Liste kommt aus WAGO_PLC_HOSTS und WAGO_PLC_HOSTS_FILE. Die Passwörter kommen aus Docker Secrets oder Einstellungen.

  4. Jede SPS registrieren

    Der Server testet die Anmeldung und speichert dann die IDs. Standardmäßig registriert er 5 SPSen gleichzeitig.

  5. API-Key ermitteln

    Die Reihenfolge ist Docker Secret, MCP_API_KEY, gespeicherte Datei, neuer Key. Der stdio-Transport nutzt keinen Key.

  6. Tools bereitstellen

    Standard ist Port 6042 unter /mcp. Die Route /health braucht keinen Key.

Wenn eine SPS den Anmeldetest nicht besteht oder ihre Parameter oder Methoden nicht laden, überspringt der Server diese SPS und läuft weiter.42

Um die Flotte zu ändern, bearbeiten Sie die Liste und erstellen den Container neu. Dann registrieren sich alle SPSen erneut.5

4

Welche Tools bekommt der Agent?

GruppeToolsAnzahl
Flotte und Gerätlist_plcs, describe_plc, get_device, get_feature4
Parameter lesenfind_parameters, get_parameter, get_parameters_bulk, get_parameter_definition, get_enum_definition, get_parameter_referenced_instances, list_parameter_instances, get_parameter_instance8
Parameter schreibenset_parameters, set_parameterGeprüft2
Methodenfind_methods, get_method, invoke_method, get_method_run, list_method_runs, delete_method_runGeprüft6
Watchlistscreate_watchlist, read_watchlist, list_watchlists, delete_watchlist4
Dateiencreate_file, upload_file, download_file, get_file_metadataGeprüft4
Auditget_plc_audit_log1
SummeAlle Gruppen29

In den Gruppen Methoden und Dateien gelten die Sicherheitsprüfungen nur für invoke_method, create_file und upload_file. Der Server gibt dem Agenten auch die Resource wago://catalog und den Prompt wago_assistant.6

Die übliche Reihenfolge ist list_plcs, describe_plc, find_parameters oder find_methods, get_parameter oder get_method, dann set_parameters oder invoke_method.

5

Was passiert beim Lesen und Schreiben?

Einen Parameter suchen, lesen und schreiben
Diagram structure
  • KI-Agent agent
  • MCP-Tools tools
  • PLC-Manager-Cache cache
  • Sicherheitsprüfungen gates
  • WAGO-SPS plc
  • agent → tools · find_parameters
  • tools → cache · IDs suchen
  • tools → agent · passende IDs
  • agent → tools · get_parameter
  • tools → plc · GET /wda/parameters/{id}
  • plc → tools · Rohwert
  • tools → agent · Wert und Labels
  • agent → tools · set_parameters
  • tools → gates · SPS schreibgeschützt?
  • gates → plc · PATCH /wda/parameters
  • plc → agent · 204, dann Status ok
Echtes Ergebnis von get_parameterjson
{
  "dataRank": "scalar",
  "dataType": "boolean",
  "path": "NTPClient/Enabled",
  "value": true,
  "status": "Activated",
  "writeable": true
}

WDA gibt den Rohwert zurück. Der Server ergänzt status, path und writeable. Bei einem Enum ergänzt er auch das Text-Label.7

Vor einem Schreibzugriff prüft der Server den Cache. Er lehnt eine unbekannte ID und einen nicht beschreibbaren Parameter ab. Ein falscher Schreibzugriff erreicht die SPS also nicht.8

6

Wann erlaubt der Server einen Schreibzugriff?

Sicherheitsprüfungen von invoke_method
Diagram structure
  • invoke_method call
  • Schreibgeschützt? readonly
  • GitOps-Modus? gitops
  • Gefährliche Methode? dangerous
  • Läuft auf der SPS run
  • Abgelehnt refused-readonly
  • YAML-Vorschlag proposal
  • Abgelehnt refused-dangerous
  • call → readonly
  • dangerous → refused-dangerous · ja
  • dangerous → run · nein
  • gitops → dangerous · nein
  • gitops → proposal · ja
  • readonly → gitops · nein
  • readonly → refused-readonly · ja
BedingungLesenset_parametersSichere MethodeGefährliche MethodeDatei-Upload
Schreibgeschützte SPS, alle ModiErlaubtAbgelehntAbgelehntAbgelehntAbgelehnt
Live-Modus (Standard)ErlaubtErlaubt, wenn beschreibbarErlaubtAbgelehnt, außer in WAGO_ALLOW_METHODSErlaubt
GitOps-ModusErlaubtYAML-VorschlagYAML-VorschlagPerson gibt freiYAML-Vorschlag mit requires_human: CRITICALAbgelehnt

Eine gefährliche Methode hat ein Segment, das mit reboot, restart, factory, firmware oder format beginnt. Alle 0-0-update-*-Methoden sind auch gefährlich.3

Eine schreibgeschützte SPS kommt aus WAGO_ALLOW_WRITES, WAGO_READONLY_HOSTS oder # readonly in der Flottendatei. Jeder WAGO_ALLOW_WRITES-Wert außer true sperrt Schreibzugriffe.9

Im GitOps-Modus gibt das Tool YAML zurück. Der Agent committet das YAML in das Konfigurations-Repository und öffnet einen Pull Request. CI wendet die Änderung nach dem Merge an.10

7

Welche WDA-Details machen Probleme?

Der WDA-Client behandelt diese Details, sodass der Agent sie nie sieht. Sie brauchen die Details nur für eine Änderung an src/wda_client.py oder für einen Test mit curl.

AufgabeKorrekter AufrufFalle
Verbindenhttps://<PLC_IP>/wdaHTTP gibt 426 zurück
AnmeldenBasic Auth, dann das WAGO-WDX-Auth-Token als Bearer-TokenNach einem 401 holt der Client einmal ein neues Token
SchreibenPATCH /wda/parametersErfolg ist 204 mit leerem Body. POST gibt 405 zurück.
Methode aufrufenPOST /wda/methods/{id}/runs?result-behavior=syncJedes Argument braucht die Form {"value": ...}
Viele Einträge lesenFolgen Sie links.nextWDA sendet höchstens 255 Einträge je Seite
Parameter lesenErgänzen Sie parameter-errors-as-data-attributes=trueOhne diese Option kann ein nicht lesbarer Parameter die ganze Seite stoppen
8

Wie schützt sich der Server, und wie zeichnet er Änderungen auf?

Verbindung oder SchutzStandardStärkere Einstellung
Client zu ServerBearer-Key, 60 Anfragen pro Minute je IP-Adresse, kein TLSSetzen Sie MCP_TLS_CERT und MCP_TLS_KEY
Server zu SPSNicht verifiziertHTTPS ohne ZertifikatsprüfungSetzen Sie WAGO_TLS_CA oder ein Docker Secret plc_cert_<ip>
StartNur WarnungenSECURITY_PROFILE=hardened verweigert den Start ohne TLS
Lokales stdioKeine Netzwerkverbindung, also kein KeyNicht nötig
Audit-LogLokale Hash-Kette in /app/data/audit.logSetzen Sie AUDIT_SYSLOG für eine zweite Kopie auf einem anderen Host

Jede Audit-Zeile speichert den SHA-256-Hash der vorherigen Zeile. Wenn jemand eine alte Zeile ändert, schlägt die Prüfung bei der nächsten Zeile fehl. Der Server entfernt Passwörter, bevor er den Hash berechnet.17

So verbindet sich die Kettetext
Zeile 1: {"action": "set_parameters", "result": "ok", "prev": "<Startwert>"}
Zeile 2: {"action": "invoke_method", "result": "denied: dangerous method", "prev": "<SHA-256 von Zeile 1>"}
Zeile 3: {"action": "set_parameters", "result": "ok", "prev": "<SHA-256 von Zeile 2>"}
Audit-Log prüfenbash
docker exec wmcp python /app/src/audit_verify.py --log /app/data/audit.log
9

Warum braucht dieselbe Anfrage verschiedene Parameter?

WAGO-Geräte nutzen zwei Firmware-Generationen. Eine Parameter-ID aus einer Generation kann in der anderen fehlen.18

PunktPTXdistYocto
BeispielgerätCC100 751-9401CC100-IEC62443 751-9412
Firmware-Format04.09.01 (Build 31)02.00.13
Parameterzahl auf derselben Hardware-LinieCa. 360Ca. 1056
DNS-ServerEin flacher Parameter: 0-0-networking-dns-customdnsserversEiner je Bridge: 0-0-networking-bridges-<N>-nameservers-dns
Rolle der I/O-KanäleFestKonfigurierbar: 0-0-io-channelcompositions-<N>-channels

Lesen Sie vor einem Schreibzugriff auf eine unbekannte SPS den Parameter 0-0-version-firmwareversion. Suchen Sie dann das Feature mit find_parameters. Nutzen Sie eine Parameter-ID aus einer anderen Generation nicht ohne diese Prüfung.

10

Was macht der Server nicht?

  • Er liest und schreibt keine I/O-Tags des Steuerungsprogramms, keine Prozesswerte und keinen SPS-Speicher.
  • Er unterstützt nur WAGO-Geräte. Er ist kein HMI und kein SCADA-System.
  • Er erlaubt einem Agenten nicht, eine SPS hinzuzufügen oder zu entfernen.
  • Er flasht keine Firmware. Eine Person oder CI startet das separate fwupdate-Tool. Siehe docs/firmware-update-overview.de.html.19
11

Wie können Sie den Server sicher ausprobieren?

Nutzen Sie eine Test-SPS. Diese Anfragen lesen nur Daten.

Fragen Sie den AgentenToolErwartetes Ergebnis
Zeige meine SPSen.list_plcsDie IP-Adressen der registrierten SPSen
Beschreibe 192.168.1.10.describe_plcGeräteklasse, Parameterzahl, Feature-Namen
Welche Firmware läuft auf 192.168.1.10?find_parameters, get_parameterEin Wert wie 04.09.01
Ist NTP auf 192.168.1.10 aktiv?get_parameterstatus: Activated oder Deactivated
Zeige die letzten Audit-Einträge.get_plc_audit_logLetzte Schreibzugriffe, Methodenaufrufe und Ablehnungen
12

Können Sie diese Punkte jetzt erklären?

Opening diagram…