TIA Openness RPC
Keep a TIA Portal Openness session open and script it over JSON-RPC with plccheck tia rpc.
plccheck tia rpc exposes one persistent TIA Portal Openness host over newline-delimited JSON-RPC 2.0. It is intended for agentic exploration and automation that needs to keep a TIA Portal connection, project session, and discovered object handles alive across many calls.
This is an internal JSON-RPC interface, not an MCP server. plccheck hmi and
plccheck mcp use this host for WinCC Unified engineering; see
WinCC Unified agent commands.
Start the host
plccheck tia rpc
plccheck tia rpc --filesystem-root C:\automation\exports
plccheck tia rpc --allow-project-writes --allow-private-api
The command reads UTF-8 JSON-RPC frames from stdin and writes one compact JSON frame per line to stdout. Diagnostics use stderr. A UTF-8 BOM on the first input frame is accepted. Closing stdin requests graceful host shutdown.
The Go proxy starts tia-openness-bridge.exe, sends the protocol initialize request, validates the complete protocol/capability contract, and then forwards user frames. A client of plccheck tia rpc must not send another initialize request.
Managed host installation
Packaged Windows x64 builds carry a candidate bundle containing:
tia-openness-bridge.exetia-openness-bridge.exe.configtia-openness-bridge.manifest.json
Each packaged bridge bundle is installed at %ProgramFiles%\plccheck\tia-openness-bridge\bundles\<sha256>. The identity covers the executable, config, and manifest. The installed executable is named tia-openness-bridge-<sha256>.exe, with a matching .exe.config and its own Siemens Openness AllowList entry. Identical npm and extension bundles share one installation; different versions and builds coexist.
A foreground TIA command automatically installs and trusts its bundle when needed. This initial setup can request Windows administrator approval. Later commands reuse the installed bundle without changing other versions. Background extension checks set PLCCHECK_TIA_HOST_SETUP=0, which makes managed launch inspect setup and report an actionable error when setup is needed, without changing files, repairing trust, or opening UAC. Explicit tia host install remains available.
plccheck tia host status --json
plccheck tia host install
plccheck tia host upgrade
plccheck tia host uninstall
Install and repair transactions use staging, backup, and recovery-marker paths scoped to the selected bundle. An interrupted update is rolled back or cleaned up on the next install, upgrade, uninstall, or foreground managed launch. The manifest is published with the executable and config as one bundle, and the previous installation is retained until trust verification succeeds.
Once an update is committed, a backup executable still held open by an older RPC session does not block commands or trigger another administrator prompt. A later repair moves that backup to a separate <sha256>.retired-* directory if needed. Retired files are cleaned up when Windows permits deletion; existing RPC sessions can finish normally.
tia host status|install|upgrade|uninstall selects the bundle shipped with the invoking CLI. Uninstall removes only that bundle and its trust entry. Earlier installations remain available to their matching clients; there is no automatic removal of older versions. The old shared v1 installation and its trust entry remain available to clients released before 2.17.2.
plccheck tia trust --json inspects trust without installing or recovering the host. plccheck tia trust --install installs or repairs the managed host and its trust; repeating it reuses a current AllowList entry and group membership. Use --no-elevate to return an error if administrator rights are needed instead of opening UAC. --bridge <path> targets a specific executable directly.
PLCCHECK_TIA_BRIDGE is an explicit development/test escape hatch. It bypasses managed installation, platform checks, manifests, and automatic trust convergence.
Startup policy
Policy is fixed when the proxy initializes the host and cannot be escalated by later requests.
| CLI flag | Allows |
|---|---|
| none | Session discovery and bounded public reads |
--allow-project-writes |
Saving, reflected project mutations, and HMI edits and compilation |
--allow-device-actions |
Online/offline/download/snapshot and arbitrary reflected method invocation |
--allow-private-api |
Private reflection and non-public members |
--filesystem-root <path> |
$file and $directory arguments below the selected root; repeatable |
Filesystem roots apply to tagged $file and $directory values. Plain string arguments are strings and are not interpreted as filesystem grants; callers should expose paths only through tagged values when invoking APIs that consume files or directories.
Methods
The host advertises the exact supported set through host.capabilities.
Host and session
host.statushost.capabilitieshost.shutdowntia.listProcessessession.opensession.currentsession.rootssession.savesession.closeoperation.run
session.open accepts an optional selector, which can be an open project name or project/archive path. The host owns at most one session. Reopening the same selector reuses it; a different selector conflicts until the current session is closed.
session.roots returns handles for the TiaPortal and project objects. Saving or mutating a project advances the session generation and invalidates handles that may no longer describe current TIA state.
For operation.run, action export writes PLC software and system constants, while action export-hardware writes the canonical CAx AML through the active session. The derived hardware YAML views and five-minute CAx watchdog belong to plccheck tia export hardware, not the raw RPC action.
WinCC Unified HMI
hmi.listhmi.inspecthmi.sethmi.createhmi.deletehmi.compilehmi.scriptReadhmi.scriptWrite
These methods back plccheck hmi and plccheck mcp. hmi.list, hmi.inspect and hmi.scriptRead are reads. hmi.set, hmi.create, hmi.delete, hmi.compile and hmi.scriptWrite require --allow-project-writes. plccheck hmi save uses session.save. Request formats are in WinCC Unified agent commands.
Handles and bounded reads
handle.releasehandle.releaseAllobject.describeobject.getobject.getAttributeobject.getCompositionobject.getServiceobject.enumerateobject.resolve
Handles are opaque, process-local, session-bound identifiers. They include a session generation and become stale after generation-changing operations. Callers should release handles they no longer need and treat invalid/stale-handle errors as a signal to reacquire roots and traverse again.
Reads return bounded projections. Collections require offset/limit pagination, and nested values are projected only to advertised depth/item/string/response limits. Objects that cannot be safely projected are returned as handles.
Reflection discovery and invocation
type.searchtype.describetype.invoketype.constructobject.setobject.setAttributeobject.invoke
type.search and type.describe expose approved Siemens types and stable member IDs. Invocation uses those IDs rather than accepting arbitrary CLR member text. Public reads are available under the default policy; writes, private APIs, and device actions require the corresponding startup flags.
Arguments may use tagged objects:
{"$ref":"obj_..."}
{"$enum":{"name":"Member"}}
{"$type":"Siemens.Namespace.TypeName"}
{"$file":"C:\\automation\\exports\\block.xml"}
{"$directory":"C:\\automation\\exports"}
{"$secretEnv":"TIA_PASSWORD"}
$secretEnv reads the named environment variable inside the bridge. Secret values are not included in projections or audit arguments.
Enum references use the reflected parameter/property type; name is the enum
member name. A plain string member name is also accepted. The wrapper does not
suppress TIA dialogs: for example, creating an HMI connection while simulation is
running can prompt that delta loading will be lost. A timed-out mutation must be
inspected before retrying because it may still be waiting on such a dialog.
Events and audit
event.subscribeevent.unsubscribeaudit.recent
The host emits tia/progress for request-scoped progress and tia/event for subscribed TIA events. Event subscriptions are released on explicit unsubscribe, session close/loss, and host shutdown. audit.recent returns the bounded in-memory reflection audit trail.
Request example
After starting plccheck tia rpc, send application requests directly:
{"jsonrpc":"2.0","id":1,"method":"session.open","params":{"selector":"Demo Project"}}
{"jsonrpc":"2.0","id":2,"method":"session.roots"}
{"jsonrpc":"2.0","id":3,"method":"object.describe","params":{"handle":"obj_..."}}
{"jsonrpc":"2.0","id":4,"method":"session.close"}
{"jsonrpc":"2.0","id":5,"method":"host.shutdown"}
Responses can be interleaved with notifications. Match responses by id; do not assume the next stdout line is the response to the last request.
Cancellation and failure behavior
Send $/cancelRequest with {"id": <request-id>} to request cancellation. Cancellation is cooperative. The host has a bounded work queue and returns stable server-busy, cancellation, policy, session, handle, TIA-installation, and Openness-availability errors.
The proxy never replays an in-flight request after a host crash or protocol EOF. Such requests have ambiguous effects and fail. Start a new proxy for subsequent work, reopen the project explicitly, and reacquire all handles.
Validation
Fake-backend validation:
dotnet build tia_openness_bridge/TiaOpennessBridge.csproj -c Release
./scripts/test-tia-bridge-helpers.ps1
./scripts/test-tia-bridge-protocol.ps1
./scripts/test-tia-bridge-reflection.ps1
./scripts/test-tia-rpc-packaged.ps1 -PlccheckPath out/go/windows-amd64/siemens-lsp.exe -BridgePath out/go/windows-amd64/tia-openness-bridge.exe
Safe live read-only validation:
./scripts/validate-tia-rpc-live.ps1 -Project "Demo Project"
The live script lists TIA processes, opens one project session, obtains roots, describes the project root, releases the handle, closes the session, and shuts down. It does not enable project writes, private APIs, or device actions.