What do you need to update WAGO PLC firmware?

Answer

The WAGO PLC MCP server cannot flash a PLC. A person or CI runs the separate fwupdate tool, and that tool needs a committed Git approval for the device and the firmware revision.

  1. invoke_method refuses all firmware* and 0-0-update-* methods, so an agent cannot start an update.1
  2. upload_file sends the full file with one PUT, and the WDA docs record 413 for that call. Firmware uploads need chunks of about 4 MB.23
  3. In GitOps mode, the agent only proposes the change. A person reviews and merges the proposal.4

Applies toServer 2.4.4, firmware 4.9.1 and 02.00.13. Checked in code and docs. No device touched. The upload limit was not tested through the MCP server.

1

Who can write firmware to a PLC?

Two separate paths to the PLC
Diagram structure
  • AI agent agent
  • Engineer or CI engineer
  • Firmware files files
  • MCP server mcp
  • Approval repository policy
  • fwupdate tool tool
  • WAGO PLC plc
  • Audit log audit
  • agent → mcp · reads, proposes
  • engineer → policy · commits
  • policy → tool · checked
  • files → tool · selected
  • mcp → plc · no firmware
  • tool → plc · flashes
  • mcp → audit · records
  • tool → audit · records

Both paths write to the same hash-chained audit log. The log also records each refusal.5

2

What must be ready before you start?

ItemRequirement
HostDocker with Compose, and Git. Windows 10 or 11 and Linux both work.
NetworkHTTPS (port 443) from the host to each PLC. The container uses network_mode: host.
ToolThe image wagoalex/wago-plc-mcp-server-fwupdate and the fwupdate/ folder of the repository.
FirmwareThe files from WAGO: .wup, or a signed .zip for the CC100-IEC62443.
ApprovalA committed firmware-policy.yaml that names the device IP and the exact revision.
CredentialsThe WBM user name and password. Use one Docker secret for each device if the passwords differ.
Device folder/tmp/fwupdate on the PLC, with group admin and mode 0770.
Minimum buildPFC300: 30. CC100, PFC200 G2, TP600, and Edge Controller: 28. The CC100-IEC62443 has no check.
Maintenance windowA stopped machine or process, because the PLC restarts during the update.
3

Which firmware file does each device take?

DeviceFirmware fileRevision to approve
CC100CC100-Linux4.9.1
PFC200 G2, except 0750-8217PFC-G2-Linux4.9.1
PFC200 G2 0750-8217 (modem)PFC-G2-Linux-red-autoupdateModem only4.9.50
PFC300PFC-300-Linux4.9.1
TP600 and Edge ControllerTP-Linux4.9.1
WP400WP400-Linux4.9.1
CC100-IEC62443wago-image-wago-cc100-02.00.13-fw-bundle.zipKeep zeros02.00.13

Both PFC-G2 files list the same article numbers, so the file data cannot identify 0750-8217. The approved revision selects the file.6

4

How do you run an update?

From firmware file to updated PLC
Diagram structure
  • Get firmware files get-files
  • Set connection values set-env
  • Commit approval commit
  • Do a dry run dry-run
  • Flash the PLC flash
  • Verify audit log verify
  • commit → dry-run
  • dry-run → flash · passed
  • flash → verify · done
  • get-files → set-env
  • set-env → commit
  1. Get firmware files

    Copy the .wup or .zip files into the firmware folder.

  2. Set connection values

    Copy _env to .env. Set PLC_IP and PLC_PASSWORD.

  3. Commit approval

    Add the IP and the revision to firmware-policy.yaml. Commit the file.

  4. Do a dry run

    Run the tool with DRY_RUN=true. The tool uploads and checks the file, then cancels.

  5. Flash the PLC

    Stop the machine. Run the tool. Wait for ==> Done.

  6. Verify audit log

    Run audit_verify.py. The result must show an intact chain.

firmware-policy.yamlyaml
approvals:
  192.168.1.10: "4.9.1"
Commands, in the fwupdate folderbash
cp _env .env
docker compose pull
docker compose run --rm -e DRY_RUN=true fwupdate
docker compose run --rm fwupdate

To update all approved PLCs, replace fwupdate with fleet in the last two commands. The tool then updates one PLC after the other.7

5

Which route should you use?

RouteApprovalWho runs itUse it when
Tool by handEntry in firmware-policy.yamlYou, on a host in the plant networkNo runner is available
ops/fw-*.yaml fileThe merged pull requestCI, at the mergeBest recordFor routine work
Run workflowEntry in firmware-policy.yamlCI, when you click itThe approval exists and you want to use it now

The CI routes need a self-hosted runner and the apply.yml and firmware.yml workflows. They also need the FIRMWARE_SOURCE and AUDIT_SYSLOG variables. Without AUDIT_SYSLOG, a CI run leaves no audit record.6

6

What should you expect during the flash?

Duration
5 to 15 minutes for each PLC. About 20 minutes on the CC100-IEC62443.
CC100 restart
Up to 10 minutes.
Progress
It stops at about 93%. The status Unconfirmed (4) is the real signal.
Last line
==> Done. with the status and the new firmware version.
7

What stops an update?

MessageAction
has uncommitted changesCommit the file. On Windows, also add .gitattributes with *.yaml text eol=lf.
not listed in the firmware policyAdd the device in a pull request.
is approved for firmware X, but the resolved bundle is YCorrect the policy, or the firmware folder.
bundles match order numberSet TARGET_VERSION to the exact revision.
Device is already atNo action is necessary. Set FW_ALLOW_REFLASH=true only for an intentional reflash.
below the minimumFirst update to the intermediate build in the message.
activate failedMake /tmp/fwupdate on the PLC. Use the command below.
Run on the PLC with SSHbash
mkdir -p /tmp/fwupdate && chgrp admin /tmp/fwupdate && chmod 770 /tmp/fwupdate
8

What do the docs not answer yet?

9

Are you ready to update?

Opening diagram…