tiax command reference
Generated from the live --help output of every verb. The C# Usage strings are the single source of truth; this file is a projection of them. tiax-v21.exe shares the same sources, so this reference covers both flavours.
| Verb | Summary |
|---|---|
scan |
Turn an exports folder into AI-readable JSON (no TIA Portal needed) |
scl |
Print a block's logic as SCL (no TIA Portal needed) |
query |
Ask questions about a scanned project (no TIA Portal needed) |
report |
Generate a visual explorer and Markdown docs (no TIA Portal needed) |
mcp |
Serve a project to Claude over MCP (stdio): cache queries + live TIA tools |
devices |
List a project's devices, modules and I/O addresses (needs TIA Portal) |
export |
Export a TIA project's PLC data to SIMATIC ML XML (needs TIA Portal) |
build |
Generate hardware, tags and SCL blocks into a project (WRITES; needs TIA Portal) |
compile |
Compile every PLC and HMI target and save (WRITES; needs TIA Portal) |
import-block |
Import one edited block XML back into a project (WRITES; needs TIA Portal) |
hmi |
Add project languages and import HMI screens (WRITES; needs TIA Portal) |
clean-sources |
Delete leftover external sources + stale XRef cache (WRITES; needs TIA Portal) |
engine |
Persistent TIA session server for tiax-agent (named pipe; internal) |
doctor |
Check TIA Portal, Openness, user group, versions and license |
setup |
Write the MCP server config for Claude Desktop, Cursor and VS Code |
pro |
CAx import, library types, alarm texts, online/download, WinCC Unified (needs TIA Portal) |
plcsim |
PLCSIM Advanced: list/start/stop instances, read/write tags, run test specs |
selftest |
Live selftest on a copy of a scratch project; promotes capabilities on this PC |
restore |
Restore a project from a backup (new folder, or in place with --in-place --confirmed) |
openness |
Browse, read, write and invoke anything in the Openness object model by path (needs TIA Portal) |
script |
Run a compiled TIATool script against a project in an Openness transaction (needs TIA Portal) |
project |
Create, archive (.zapNN) or retrieve a TIA project (needs TIA Portal) |
scl-apply |
Lint, generate and compile one SCL source into a PLC (WRITES; needs TIA Portal) |
journal |
Verify a workspace journal's hash chain, or export it (JSON lines or CSV) |
scan
Turn an exports folder into AI-readable JSON (no TIA Portal needed)
tiax scan <exports-folder> [options]
Reads exported SIMATIC ML XML and writes a .tiax/ cache:
.tiax/project.json inventory, fidelity roll-up, failure ledger
.tiax/index.jsonl one compact line per artifact — read this first
.tiax/blocks/*.json full record per artifact, with real SCL for LAD/FBD
Needs no TIA Portal, no Openness licence and no running TIA. It reads a folder
'tiax export' (or TiaTool) already produced, so it is safe to run anywhere.
ARGUMENTS
<exports-folder> Folder containing one subfolder per PLC.
OPTIONS
--out <folder> Where to write. Default: a '.tiax' folder beside <exports-folder>.
--quiet Only print the summary.
--full Re-parse every file (default: delta scan, unchanged files reused by content hash).
--threads <n> Parser threads (default: all cores).
--trace Print full stack traces on failure.
EXIT CODES
0 every artifact parsed and serialized
2 output written, but some artifacts failed — see project.json 'failures'
1 nothing usable produced
EXAMPLE
tiax scan "C:\Workspaces\MyProject\exports"
scl
Print a block's logic as SCL (no TIA Portal needed)
tiax scl <file.xml | folder> [options]
Converts exported SIMATIC ML to readable SCL and prints it. LAD and FBD are
reconstructed from the wire graph; SCL and STL come through as source text.
ARGUMENTS
<file.xml|folder> A single exported block, or a folder to convert recursively.
OPTIONS
--out <folder> Write .scl files instead of printing to stdout.
--author <name> Stamp AUTHOR on every block instead of carrying the original
through. A converted block is new work under new ownership.
--block-version <v>
Stamp VERSION on every block, e.g. 3.0. Without it the block's
own version is carried through, and a source that omits VERSION
comes back from TIA reset to 0.1.
--allow-lossy Exit 0 even when a LAD/FBD rendering is flagged TIAX-LOSSY.
--trace Print full stack traces on failure.
EXIT CODES
0 every file converted and no rendering was flagged lossy
2 partial: a file failed, or a LAD/FBD network was flagged TIAX-LOSSY
(the wire graph contains logic the SCL does not show)
1 nothing converted
NOTE
For LAD/FBD this output is a RECONSTRUCTION, not source. It is reliable for bit
logic, timers, counters and comparisons. Verify before trusting it for arithmetic.
EXAMPLES
tiax scl "exports\PLC_1\Blocks\Pump_01_Ctrl.xml"
tiax scl "exports" --out "src" --author DEV --block-version 3.0
query
Ask questions about a scanned project (no TIA Portal needed)
tiax query <what> [argument] [options]
Runs against the .tiax cache produced by 'tiax scan'.
WHAT
writes <symbol> Every place a tag is WRITTEN — the question PLC work turns on
reads <symbol> Every place a tag is read
tag <symbol> Both directions
block <name|id> The full record for one block
callers <block> Which blocks call this one (from CallInfo, not name matching)
calls <block> Which blocks this one calls
unreachable Code blocks never reached from any OB — dead code
search <text> Free-text across names, titles, comments, logic and HMI content
stats Inventory and fidelity roll-up
WHAT (HMI — needs a cache scanned with tiax >= 0.2.0)
screens [filter] HMI screens/templates/popups, optionally filtered by name
screen <name> The full record for one HMI screen
hmi-map [filter] Every HMI tag with its table, connection and the screens using it
hmi-uses <symbol> Where a PLC symbol appears on the HMI — matched by NAME (the
export does not carry the HMI→PLC tag link)
OPTIONS
--tiax <folder> Cache location. Default: ./.tiax, or a .tiax beside the given path.
--exact Match the symbol exactly instead of by substring.
--device <name> (screens) Only this HMI device.
--json Emit raw JSON (the default is a readable table).
--limit <n> Cap results (default 50).
EXAMPLES
tiax query writes TankLevel --tiax "C:\Workspaces\MyProject\.tiax"
tiax query callers FB_AlarmCollectable
tiax query unreachable
tiax query screens
tiax query hmi-uses SystemOn
report
Generate a visual explorer and Markdown docs (no TIA Portal needed)
tiax report [options]
Produces human-readable output from a .tiax cache.
explorer.html One self-contained file — double-click to open. Search, block browser,
interface trees, SCL with highlighting, call graph, tag tracking, I/O map.
No server, no internet, no dependencies.
docs/ Markdown + Mermaid. Renders in VS Code, GitHub, or any Markdown viewer.
One page per block, plus call graph, I/O map, tag cross-reference and
dead-code pages. Good for handover and for committing alongside the project.
OPTIONS
--tiax <folder> Cache to read. Default: ./.tiax or a .tiax beside the given path.
--out <folder> Where to write. Default: alongside the cache.
--html-only Skip the Markdown set.
--md-only Skip the HTML explorer.
--open Open the explorer when done.
EXAMPLES
tiax report --tiax "C:\tiax-test\.tiax" --out "C:\tiax-test\report" --open
tiax report --md-only --out docs
mcp
Serve a project to Claude over MCP (stdio): cache queries + live TIA tools
tiax mcp [options]
Runs a Model Context Protocol server over stdio: cache tools answer questions about
your PLC code instantly from the scanned .tiax cache, and live tools drive the real
project (export, compile, build, import) by spawning tiax CLI verbs as child
processes — the server itself never holds TIA Portal open between calls.
OPTIONS
--tiax <folder> Cache to serve. Default: ./.tiax or a .tiax beside the given path.
SETUP (Claude Code)
claude mcp add tia -- "C:\path\to\tiax.exe" mcp --tiax "C:\Workspaces\MyProject\.tiax"
Or add to your MCP config:
{
"mcpServers": {
"tia": {
"command": "C:\\path\\to\\tiax.exe",
"args": ["mcp", "--tiax", "C:\\Workspaces\\MyProject\\.tiax"]
}
}
}
Run 'tiax scan' once before starting the server. After that it can refresh itself:
the refresh_scan tool re-scans the exports folder and reloads the index in place.
Long-running live tools (export, compile, build) may need the client's tool-call
timeout raised (Claude Code: MCP_TOOL_TIMEOUT=600000; MCP_TIMEOUT is only the
server start-up timeout).
TOOLS EXPOSED
Cache (instant, no TIA Portal):
project_stats · list_blocks · get_block · who_writes_tag · who_reads_tag
who_calls · what_block_calls · unreachable_blocks · search_project
list_screens · get_screen · hmi_tag_map · where_is_tag_used_on_hmi
Live (drive the real project; write tools always back up first and refuse to
run while TIA Portal is open — neither rail can be disabled over MCP):
tia_status · refresh_scan · backup_project · export_project · list_devices
compile_project · clean_sources · build_from_source · import_block · hmi_import_screens
hmi_import_tags · add_project_languages
ARGUMENT RAILS
Every call is checked against the tool's inputSchema before the licence gate and
before anything runs: undeclared arguments, wrong types and values outside an enum
are refused, and so is any path, name or target that starts with '-'. dry_run and
what_if exist only on the tools that honour them. Child processes get --key=value
arguments on a command line escaped the way Windows splits it.
TRUST CONTROLS
Policy %ProgramData%\TIATool\policy.json (admin-owned; /etc/tiatool/policy.json on
Linux) over <workspace>\policy.json: allow_tools / deny_tools, read_only,
allow_online (default false: plc_download, plc_online and plc_compare_online
are refused),
allow_scripts, allowed_project_roots / allowed_output_roots,
require_confirmation, max_writes_per_hour, confirm_mode. Checked before the
licence; tools it denies outright are not listed. tia_status shows it.
'tiax-agent policy show' prints it with the file behind every value;
'tiax-agent policy init [--machine | --workspace <dir>] [--allow-online]'
writes a commented example.
Approval plc_download, an in-place restore and whatever require_confirmation lists
need a person's yes. This server cannot ask the user itself: the result names
a request the user approves with 'tiax-agent approve <id>', then the same call
is repeated (tiax-agent asks through the client when the client can).
Journal Writes are journaled with the OS user, host, MCP client and approval, in
a hash chain ('tiax journal verify'). Without a workspace the first write to a
project creates one under %LOCALAPPDATA%\TIATool\workspaces.
Project text (comments, titles, HMI texts) comes back fenced as UNTRUSTED PROJECT DATA.
devices
List a project's devices, modules and I/O addresses (needs TIA Portal)
tiax devices <project.apXX> [options]
Opens the project read-only and prints its hardware tree: every device, every plugged
module with its article number, and the I/O address ranges each module occupies.
ARGUMENTS
<project.apXX> Target project. Its version must match an installed Openness version.
OPTIONS
--json Emit JSON instead of a tree, for scripting.
--catalog <text> Instead of the tree, list hardware-catalog entries matching <text>,
with the firmware versions this TIA release offers for them.
--hmi-tag <name> Instead of the tree, dump every Openness attribute of one HMI tag.
Use this to find out how a link (e.g. to a PLC tag) is represented,
since the Simatic ML export only writes a subset of the attributes.
--attach Read through the TIA Portal UI that has this project open instead of
refusing because a Portal is running (read-only; detaches afterwards,
the UI and the project stay open). Headless as usual when no Portal runs.
--allow-tia-running
Proceed even though a TIA Portal process is running. Read-only,
but opening a project the UI holds locked still fails or hangs.
--timeout <min> Abort if the operation exceeds this many minutes (default 10).
--trace Print full stack traces on failure.
WHAT IT DOES
Opens the project headless, walks Devices -> DeviceItems recursively, and closes.
Nothing is written to the project.
TIA Portal must be CLOSED (the project cannot be open in the UI).
EXIT CODES
0 the tree was printed 1 the project could not be opened or read
EXAMPLE
tiax devices "...\MyProject.ap21"
export
Export a TIA project's PLC data to SIMATIC ML XML (needs TIA Portal)
tiax export <project.apXX> <output-folder> [options]
Exports all PLC blocks, tag tables, types, watch/force tables and external sources
to SIMATIC ML XML, one file per artifact, grouped per PLC.
ARGUMENTS
<project.apXX> TIA Portal project file. Its version must match an installed
Openness version — tiax will not upgrade it for you.
<output-folder> Destination. Created if missing. Existing files are overwritten.
OPTIONS
--mirror Make the destination hold exactly what this run exported: files of
blocks, tables and types the project no longer has (deleted or
renamed in TIA) are REMOVED and listed as removed. Only files tiax
owns are touched — those in the previous .tiax-export.json, and
export files inside the PLC/HMI folders this run wrote; never .git,
.tiax or anything else. Skipped when the run exported nothing.
Default ON when the destination is in a git work tree or holds a
.tiax-export.json from an earlier export.
--no-mirror Keep stale files (the pre-0.8 behaviour).
--incremental Export only what changed since the destination's .tiax-export.json:
blocks, tag tables and PLC data types whose Openness ModifiedDate
(and interface/code dates) match the manifest and whose file still
has the recorded SHA-256 are kept, not exported again; everything
new or changed is exported, and the files of objects the project no
longer has are removed (mirror semantics, manifest-owned files only).
Watch tables, external sources and HMI artifacts carry no dates and
are exported every run. Falls back to a full export (and says why)
when the manifest is missing or unreadable, describes another project
file (another project, or another TIA version) or was written by
another TIATool version. Implies --mirror.
--attach READ through the TIA Portal UI that has this project open instead of
refusing because a Portal is running (read-only: --compile is refused).
Without a running Portal the project is opened headless as usual.
--compile Compile the project before exporting. This MODIFIES the project
(opt-in). Without it the project is left untouched, but blocks
TIA considers inconsistent are skipped and listed in the summary.
--no-compile Accepted for backward compatibility; this is now the default.
--keep-volatile Do not strip volatile timestamps (CreationDate, CompileDate, ...).
By default they are blanked so git records semantic changes only.
--allow-tia-running
Proceed even though a TIA Portal process is running. Only for
deliberate attach scenarios; you own the coordination then.
--timeout <min> Abort if the whole operation exceeds this many minutes (default 30).
--trace Print full stack traces on failure.
MANIFEST
Every run writes <output-folder>\.tiax-export.json: for each exported file its
type, device, name, sha256 and (blocks, tag tables, PLC data types) the Openness
ModifiedDate. It is the ownership record --mirror relies on and the baseline
--incremental compares against, and carries no run timestamp, so re-exporting
an unchanged project does not change it.
EXIT CODES
0 every artifact exported (incremental: or kept unchanged)
2 exported, but at least one artifact failed — see the summary
1 nothing usable produced
EXAMPLE
tiax export "C:\Projects\Line_01\Line_01.ap19" "C:\Projects\Line_01\exports"
tiax export "C:\Projects\Line_01\Line_01.ap19" "C:\Projects\Line_01\exports" --incremental
build
Generate hardware, tags and SCL blocks into a project (WRITES; needs TIA Portal)
tiax build <project.apXX> <source-folder> [options]
Applies a source folder to a project, in this order:
1. hardware.json — plug/remove signal modules and set their start addresses
2. TagTables\*.xml — PLC tag tables (overwritten by name)
3. HmiTags\*.xml — HMI tag tables (needs the blocks, so it runs after them)
4. compile — every PLC and HMI target
The PLC work is saved before the HMI stage runs, so a failure there cannot roll back
the tag table and the generated blocks.
ARGUMENTS
<project.apXX> Target project. Version must match an installed Openness version.
<source-folder> Folder holding hardware.json, TagTables\ and .scl files.
OPTIONS
--plc <name> The PLC that receives the tag tables, SCL sources and deletes
(its name, device item or station). Required when the project
has more than one PLC: tiax never picks one, so an unnamed or
unknown target fails with AMBIGUOUS_TARGET / NOT_FOUND and the
list of candidates, before anything is changed. Also selects the
station when hardware.json names none.
--hmi <name> The HMI that receives HmiTags\ (same rules as --plc).
--dry-run Print what WOULD happen — the SCL files and the block names
inside them, the tag tables, the hardware.json plan and the
delete list — then exit 0 without starting TIA Portal at all.
Costs seconds, opens nothing, modifies nothing. Run it first.
--no-hardware Skip step 1.
--no-hmi-tags Skip step 3 (HMI tag tables).
--no-compile Skip step 4.
--keep-sources Keep the external source files 'build' adds (one per .scl).
By default they are DELETED right after generation, because
leftover sources break TIA's Search and Cross-references.
Use 'tiax clean-sources' to clean projects built earlier.
--delete-blocks <a,b,c>
Delete these blocks by name after the SCL sources have been
generated. Use it when a restructure leaves the previous
program's blocks behind: they are orphans, but they still
compile and they still contain assignments to the same
outputs, so leaving them is how a project ends up with two
programs in it. Names only, never a pattern.
--delete-types <a,b,c>
Delete these PLC data types (UDTs) by name, after the blocks above.
A restructure that renames or drops types leaves the old ones behind;
they are invisible until one references a constant the new tag table
no longer defines, and then the project stops compiling against a type
nobody calls. Multi-pass, so orphans that reference each other resolve.
--messages <n> How many compiler messages to print (default 60; 0 = all).
A restructure produces thousands and the default hides them.
--no-backup Skip the automatic zip backup. NOT recommended.
--backup-dir <d> Where to write the backup zip (default: beside the project folder).
--allow-tia-running
Proceed even though a TIA Portal process is running. Only for
deliberate attach scenarios; you own the coordination then.
--timeout <min> Abort if the operation exceeds this many minutes (default 30).
--trace Print full stack traces on failure.
hardware.json FORMAT
{
"station": "S7-1200 station_1",
"remove": [ "U21", "U22" ],
"modules": [
{ "articleNumber": "6ES7222-1BF32-0XB0", "name": "U21",
"position": 2, "outputStartByte": 2 }
]
}
"station" may be omitted: the station holding the target PLC is used. A named
station must exist (no fallback) and must hold the --plc PLC when both are given.
TIA Portal must be CLOSED (the project cannot be open in the UI).
EXIT CODES
0 built and compiled clean 2 built, but the compile reported errors
1 failed (restore the backup)
EXAMPLE
tiax build "...\MyProject.ap21" "...\PLC Source"
tiax build "...\Line2.ap19" "...\Line2 Source" --plc PLC_Line2 --hmi HMI_Line2
compile
Compile every PLC and HMI target and save (WRITES; needs TIA Portal)
tiax compile <project.apXX> [options]
Compiles every PLC and HMI target in the project (or only the ones named with
--plc / --hmi), including WinCC Unified panels, prints the compiler's messages,
and saves. The project is saved EITHER WAY — a compile that reports errors still
changes system blocks and timestamps, and pretending otherwise by not saving would
leave the on-disk state half-updated. Exit code 2 is how you learn it was not clean.
ARGUMENTS
<project.apXX> Target project. Version must match an installed Openness version.
OPTIONS
--plc <name> Compile only this PLC (its name, device item or station).
--hmi <name> Compile only this HMI — classic WinCC, or WinCC Unified (compiled
through its station, where Openness exposes the compiler).
Give both to compile both. With neither, everything is compiled.
A name that matches nothing fails with NOT_FOUND and the candidates.
--block <names> Compile only these blocks (comma-separated) of one PLC — the --plc
one, or the only one. A block the PLC does not have fails with
NOT_FOUND before anything is compiled. Not with --hmi.
--result-json <file>
Also write the compile as JSON: counts, targets and every error and
warning as {target, block, network, line, severity, text, path,
kb_hits[]} (knowledge-base entries matching the text).
--messages <n> How many compiler messages to print (default 60; 0 = all).
A restructure produces thousands and the default hides them.
--no-backup Skip the automatic zip backup. NOT recommended.
--backup-dir <d> Where to write the backup zip (default: beside the project folder).
--allow-tia-running
Proceed even though a TIA Portal process is running. Only for
deliberate attach scenarios; you own the coordination then.
--timeout <min> Abort if the operation exceeds this many minutes (default 30).
--trace Print full stack traces on failure.
TIA Portal must be CLOSED (the project cannot be open in the UI).
EXIT CODES
0 compiled clean 2 compile reported errors (project saved either way)
1 failed (restore the backup if in doubt)
EXAMPLE
tiax compile "...\MyProject.ap21"
tiax compile "...\TwoLines.ap19" --plc PLC_Line2
tiax compile "...\TwoLines.ap19" --plc=PLC_Line2 --block=FB_Pump,Main --result-json=compile.json
import-block
Import one edited block XML back into a project (WRITES; needs TIA Portal)
tiax import-block <project.apXX> <block.xml> [options]
Overrides the existing block OR PLC data type (UDT) of the same name, in place, with
the given XML. The surgical writing verb: exactly one named block/type changes, nothing
else. Which tree (Program blocks vs PLC data types) is auto-detected from the XML's
root element, so FB/FC/DB/OB and PlcStruct exports both go through this same verb.
(For bulk generation from SCL sources use 'build'; for HMI content use 'hmi'.)
ARGUMENTS
<project.apXX> Target project. Its version must match an installed Openness version.
<block.xml> Edited SIMATIC ML block or PLC-data-type export.
OPTIONS
--plc <name> The PLC to import into (its name, device item or station). Without
it the block/type (or the --sibling-of object) must exist in exactly
one PLC: a name found in several PLCs (every PLC has a Main) fails
with AMBIGUOUS_TARGET and the list of PLCs, before anything changes.
An unknown name fails with NOT_FOUND.
--sibling-of <name>
Import into the group that holds this EXISTING block or type, instead
of locating the target by the imported object's own name. Required for
anything that does not exist in the project yet -- both a new PLC data
type and a new block, e.g. a DB authored as SIMATIC ML because SCL
cannot express its exact layout or remanence. Naming a sibling keeps a
typo from dropping the object at the tree root.
--no-backup Skip the automatic zip backup. NOT recommended.
--backup-dir <d> Where to write the backup zip (default: beside the project folder).
--allow-tia-running
Proceed even though a TIA Portal process is running. Only for
deliberate attach scenarios; you own the coordination then.
--timeout <min> Abort if the operation exceeds this many minutes (default 20).
--trace Print full stack traces on failure.
WHAT IT DOES
1. Zips the whole project folder to a timestamped backup (unless --no-backup).
2. Opens the project headless, finds the group holding the block/type, imports with
Override inside a transaction, saves, and closes.
TIA Portal must be CLOSED (the project cannot be open in the UI).
EXIT CODES
0 imported and saved 1 failed (project unchanged if it failed before save; else restore the backup)
EXAMPLE
tiax import-block "...\OtherProject.ap19" "...\IDB_ModbusServer.xml"
tiax import-block "...\OtherProject.ap19" "...\UDT_DriveDiag.xml" --sibling-of UDT_Modbus_PumpControl
tiax import-block "...\TwoLines.ap19" "...\Main.xml" --plc PLC_Line2
hmi
Add project languages and import HMI screens (WRITES; needs TIA Portal)
tiax hmi <project.apXX> [options]
With no options it just reports the project's active languages and the HMI targets it
found — a safe way to check the tool can see the panel before writing anything.
ARGUMENTS
<project.apXX> Target project. Version must match an installed Openness version.
OPTIONS
--hmi <name> The HMI that receives --screens / --tag-files / --tags (its name,
device item or station). Required when the project has more than
one HMI: tiax never picks one — screens used to be imported into
EVERY panel — so an unnamed or unknown target fails with
AMBIGUOUS_TARGET / NOT_FOUND and the candidates, before anything
is changed. Languages are project-wide and need no target.
--languages <a,b> Add these cultures to the project's active languages, e.g.
"de-DE,en-US". Only adds; never removes, because removing a
language discards every text in it.
--screens <folder> Import every *.xml in <folder> as a screen, overwriting by name.
--tag-files <dir> Import HMI tags ONE PER FILE. Layout is
<dir>\<TagTableName>\<TagName>.xml — the subfolder names the
table, which must already exist. Each tag is overwritten by
name; every other tag in the table is untouched. This is the
safe way to add tags, and the only one that has worked.
--tags <folder> Import every *.xml in <folder> as a whole HMI tag table.
AVOID. A table is replaced wholesale, the exported form of a
table does not carry each tag's PLC link, and a table document
containing <ControllerTag> was observed to hang TIA Portal
indefinitely. Use --tag-files instead.
--no-compile Skip the compile at the end.
--no-backup Skip the automatic zip backup. NOT recommended.
--backup-dir <d> Where to write the backup zip (default: beside the project folder).
--allow-tia-running
Proceed even though a TIA Portal process is running. Only for
deliberate attach scenarios; you own the coordination then.
--timeout <min> Abort if the operation exceeds this many minutes (default 30).
--trace Print full stack traces on failure.
ORDER MATTERS
A screen carries its tag bindings, but not the tags themselves. Importing a screen
that binds a tag which does not exist yet leaves a dangling reference that only
surfaces at compile time. Create the tags in TIA first, then import the screens.
TIA Portal must be CLOSED (the project cannot be open in the UI).
EXIT CODES
0 done and compiled clean 2 done, but the compile reported errors
1 failed
EXAMPLE
tiax hmi "...\MyProject.ap21" --languages "de-DE,en-US"
tiax hmi "...\TwoLines.ap19" --hmi HMI_Line2 --screens "...\Screens"
clean-sources
Delete leftover external sources + stale XRef cache (WRITES; needs TIA Portal)
tiax clean-sources <project.apXX> [options]
Deletes the external source files in every PLC's 'External source files' folder,
saves and closes the project, then deletes <project>\XRef\XRef.db so TIA Portal
rebuilds its cross-reference index on the next open. Leftover sources (one per
.scl from every 'tiax build') break project-wide Search and Cross-references.
OPTIONS
--only <a,b,c> Delete only these sources (names, case-insensitive).
--dry-run List what would be deleted; modify nothing.
--keep-xref Do not delete XRef\XRef.db.
--no-backup Skip the automatic zip backup. NOT recommended.
--backup-dir <d> Where to write the backup zip.
--allow-tia-running
Proceed although a TIA Portal process is running.
--timeout <min> Abort after this many minutes (default 30).
EXIT CODES
0 cleaned (or nothing to clean) 2 sources deleted but XRef cache could not be removed
1 failed (restore the backup)
EXAMPLE
tiax clean-sources "...\MyProject.ap21" --dry-run
engine
Persistent TIA session server for tiax-agent (named pipe; internal)
tiax engine [options]
Runs a persistent TIA Portal session and serves tiax verbs over a named pipe to
tiax-agent. Normally started by the agent, not by hand.
OPTIONS
--pipe <name> Pipe name (default tiax-engine-<flavour>-<user>).
--idle-minutes <n> Close project + Portal after n idle minutes (default 15).
--parent-pid <pid> Exit when this process exits (the agent).
--oneshot Do not keep TIA open: every call opens and closes (debug/fallback).
ENVIRONMENT
TIAX_ENGINE_SECRET Shared secret the client must present in its hello message.
doctor
Check TIA Portal, Openness, user group, versions and license
tiax doctor
Checks everything tiax needs on this PC: Windows x64, .NET Framework 4.8, installed
TIA Portal Openness versions (V19/V21), membership of the 'Siemens TIA Openness'
group, running Portal processes, the tiax flavours and the license.
EXIT CODES
0 all good 2 warnings 1 at least one blocking problem
setup
Write the MCP server config for Claude Desktop, Cursor and VS Code
tiax setup --tiax <cache-folder> [options]
Adds (or updates) a 'tiatool' MCP server entry in the configuration of Claude
Desktop, Cursor and VS Code. Other servers are preserved; the old file is kept
as *.bak. Uses tiax-agent.exe when it is installed beside tiax, else 'tiax mcp'.
OPTIONS
--tiax <folder> The scanned .tiax cache to serve (required).
--client <list> claude,cursor,vscode (default: all three).
--http <url> Point Cursor/VS Code at the agent's HTTP endpoint instead of stdio,
e.g. http://127.0.0.1:8765/mcp (needs --token).
--token <token> Bearer token for --http (see 'tiax-agent token').
--name <name> Server name (default tiatool).
--dry-run Show what would change; write nothing.
pro
CAx import, library types, alarm texts, online/download, WinCC Unified (needs TIA Portal)
tiax pro <action> <project.apXX> [options]
ACTIONS
cax-import --aml <file> [--mode parking|retain|overwrite] Hardware from AutomationML (WRITES)
library-list [--global <lib.alXX>] List library types + versions
library-use --type <path> [--plc <name>] [--global <lib>] [--version <x.y>] [--update]
Instantiate a type, or update instances (WRITES)
alarm-texts-export --xlsx <file> [--plc <name>] PLC alarm text lists to XLSX
alarm-texts-import --xlsx <file> [--plc <name>] XLSX into the PLC (WRITES)
online-state [--plc <name>] Online state + PC interfaces
online-compare [--plc <name>] [--interface <PC interface>] [--interface-number 1]
Offline vs online differences (Labs;
read-only, goes online, never downloads)
download --plc <name> --interface <PC interface> [--interface-number 1] [--ip <addr>]
[--hardware] [--no-software] [--allow-stop] [--allow-reinit] [--no-start] --confirmed
Download to a PLC or PLCSIM (ONLINE)
unified-build --spec <file.json> [--what-if] Screens/items/bindings/alarms (WRITES)
COMMON OPTIONS
--allow-tia-running Proceed although a TIA Portal UI is running.
--no-backup Skip the automatic backup (CLI only; MCP never passes it).
--timeout <min> Default 30.
SAFETY
Every WRITES action backs the project up first and saves only when the action succeeded.
download never runs without --confirmed, answers only the TIA prompts you allowed
(--allow-stop; --allow-reinit for a download that re-initialises data blocks or has to
download ALL blocks, which resets their actual values to the start values), and cancels
on anything else (passwords, system data, firmware, reset).
plcsim
PLCSIM Advanced: list/start/stop instances, read/write tags, run test specs
tiax plcsim <action> [options]
ACTIONS
list List registered instances.
start --instance <name> Register (if new), power on and RUN.
stop --instance <name> [--power-off]
read --instance <name> --tags "a,b,c"
write --instance <name> --set '{"tag": value, ...}'
test --instance <name> --spec <file.json> Run cases: set inputs, wait, assert outputs.
Exit 0 all passed, 2 failures.
Tag names are symbolic, as PLCSIM lists them: PLC tags by name, DB members as "DB".member.
Requires S7-PLCSIM Advanced V4+ (the API DLL is located from the registry).
selftest
Live selftest on a copy of a scratch project; promotes capabilities on this PC
tiax selftest --live --template <scratch.apXX> [options]
Copies the template project to a short scratch path and runs, step by step: doctor, devices,
backup + verify, export, scan, generate equipment, build (dry run, real), compile,
re-export + verify_change, import-block round trip, clean-sources, project languages,
read-only/what-if pro actions, CAx import (--include-risky), PLCSIM (if installed),
restore, every built-in template, and the 0.8 steps: incremental export (a second run
changes nothing), project create/archive/retrieve, Openness explorer browse/get, C#
scripts (read mode rolls back, write mode commits), every built-in script extension
compiled against this PC's Openness DLLs with the read-only ones run, and scl_lint +
scl_apply of a tiny FC + compile of that block. Steps 21-22 need tiax-agent beside tiax
and a licence for their write half. The template itself is never modified. Use a
throwaway project with exactly one PLC.
OPTIONS
--live Required: the selftest opens TIA Portal and writes the scratch copy.
--template <apXX> Scratch project (V19 .ap19 or V21 .ap21; flavour follows the extension).
--work <dir> Short working root (default <system drive>\tiaxst).
--report <file> Also write the report here (default selftest-report.json).
--include-risky Run step 14 (CAx import) — needs --aml <file>.
--aml <file> AutomationML file for step 14.
OUTPUT
The report (schema tiatool.selftest/1) is also stored as
%LOCALAPPDATA%\TIATool\selftest\latest-<flavour>.json; tiax-agent overlays it on the
capability registry (selftest_verified / REGRESSION). Then:
python tools\capabilities.py apply selftest-report.json
EXIT CODES
0 all steps passed or skipped · 2 at least one step failed · 64 usage
restore
Restore a project from a backup (new folder, or in place with --in-place --confirmed)
tiax restore <project.apXX> [options]
Restores from one of the timestamped restore points every write takes
(<name>_tiax_backup_<yyyyMMdd-HHmmss>.zip beside the project folder).
OPTIONS
--list List the restore points and exit.
--backup <zip> Restore point to use (default: the newest).
--in-place Replace the project folder. Takes a pre-restore backup first and keeps the
current folder as <folder>.replaced-<time> (never deleted). Needs --confirmed.
--confirmed Required with --in-place.
--allow-tia-running Proceed although a TIA Portal UI is running (not recommended).
Without --in-place the backup is extracted to <folder>_restored_<time> beside the project and
nothing else is touched.
EXIT CODES 0 ok · 1 failed (the project is unchanged; in place: rolled back) · 64 usage
openness
Browse, read, write and invoke anything in the Openness object model by path (needs TIA Portal)
tiax openness <project.apXX> <browse|get|set|invoke> --path=<path> [options]
Reaches every object Openness exposes through one path syntax, using the Openness
reflection API (attributes, compositions, actions) plus typed .NET properties.
ACTIONS
browse Type, attributes (values of simple types), compositions (count + first 50
child names and paths), links and actions with parameter types. Read-only.
get One attribute value (--name, or end the path with @Attribute). Read-only.
set Write one attribute: --name=<attribute> --value-json=<json>. WRITES.
invoke Run one Openness action: --name=<action> [--args-json=<json array|object>].
WRITES, except GetAttributes (reads several attributes; args = array of names).
PATHS (from the Project; segments separated by '/'; positions are 0-based)
Devices["PLC_1"]/DeviceItems[0]/DeviceItems["PLC_1"]
plc:PLC_1/BlockGroup/Blocks["Main"] plc: = the PlcSoftware of that PLC
plc:PLC_1/TagTableGroup/TagTables["Default tag table"]/Tags["Start"]@LogicalAddress
hmi:HMI_1/... hmi: = that HMI's software
plc: (no name) is the only PLC. Names may use 'single' quotes; \" \' \\ escape.
A path ending in a composition (e.g. .../Blocks) lists its items.
OPTIONS
--path=<path> Object path (empty = the Project).
--name=<name> Attribute (get/set) or action (invoke).
--value-json=<json> set: the new value as JSON. Enums by NAME ("Sequential"),
numbers, true/false, strings, or {"path": "<object path>"}.
--args-json=<json> invoke: [positional] or {"parameterName": value}.
--depth=<0-3> browse: 0 = counts only, 1 = child names (default), 2-3 = nested.
--result-file=<file> Also write the JSON result to this file.
--allow-tia-running Proceed although a TIA Portal UI is running.
--no-backup set/invoke: skip the automatic backup (CLI only; MCP never passes it).
--backup-dir=<dir> Where the backup goes (default: beside the project folder).
--timeout=<min> Default 10.
SAFETY
set and invoke take a timestamped backup first and save only when Openness accepted the
change. If Openness throws during the change the project is NOT saved (the engine session
is discarded). A request refused before any change (unknown path, attribute, action or a
value that does not convert) exits 64 and touches nothing. There is no --dry-run: browse
and get are already read-only, and the MCP tools plan + confirm before set/invoke.
EXIT CODES
0 done 1 Openness failed (nothing saved) 64 refused before any change
EXAMPLES
tiax openness "...\MyProject.ap19" browse --path=plc:PLC_1/BlockGroup --depth=2
tiax openness "...\MyProject.ap19" get --path=plc:PLC_1/BlockGroup/Blocks['Main']@ProgrammingLanguage
tiax openness "...\MyProject.ap19" set --path=plc:PLC_1/BlockGroup/Blocks['Main'] --name=AutoNumber --value-json=false
script
Run a compiled TIATool script against a project in an Openness transaction (needs TIA Portal)
tiax script <project.apXX> --assembly=<script.dll> --result-file=<result.json> [options]
Runs a script assembly built by tiax-agent (MCP script_run / extension_run) against the
project. The script is C# with a public static class Script { public static object
Run(ScriptContext ctx) }, compiled for this Openness version. You normally do not call
this verb yourself: the MCP tools compile the script, check it against the guard rail,
and ask for confirmation before a write.
ARGUMENTS
<project.apXX> Target project. Its version must match an installed Openness version.
OPTIONS
--assembly=<dll> The compiled script (required).
--result-file=<json> Where the result is written (tiatool.script-result/1; required).
--mode=read|write read (default): runs inside an Openness transaction that is NEVER
committed, and the project is never saved. write: needs a licence,
takes a backup first, commits only when Run returned without an
exception, then saves. There is no --dry-run: read mode is the way
to try a script.
--args-file=<json> JSON object handed to the script as ctx.Args.
--no-transaction Run without ExclusiveAccess/Transaction, for Openness calls that are
not allowed inside a transaction (for example compiling; check the
Openness manual's transaction restrictions). Read mode then closes the
project without saving afterwards, because nothing can be rolled back;
write mode still takes the backup, and a failure is never saved.
--timeout=<min> Abort after this many minutes (default 10 read, 30 write; max 240).
ctx.Cancellation fires at 90% of it.
--backup-dir=<dir> Where the write-mode backup zip goes (default: beside the project folder).
--allow-tia-running Proceed although a TIA Portal UI is running (CLI only; MCP never passes it).
EXIT CODES
0 the script ran (write: committed and saved)
2 the script threw; the result file has the error and log; nothing was committed or saved
1 fatal: project, transaction or save failed (the result file says why when it could be written)
64 bad arguments
project
Create, archive (.zapNN) or retrieve a TIA project (needs TIA Portal)
tiax project create <folder\Name\Name.apNN> [options]
tiax project archive <project.apNN> --out=<file.zapNN> [options]
tiax project retrieve <archive.zapNN> --out-dir=<new folder> [options]
ACTIONS
create A new, empty project (Projects.Create). TIA keeps a project in a folder
of its own name, so the path is <folder>\<Name>\<Name>.apNN, and the
extension picks the TIA version (.ap19 = V19). The <Name> folder must not
exist yet. Needs a licence (it writes a project).
archive A compressed archive of the project (Project.Archive, Compressed). The
project is only read. The archive must be a NEW file of the project's own
version (.zap19 for a .ap19), outside the project folder. Free.
retrieve Unpacks an archive (Projects.Retrieve) into a NEW folder — missing or
empty — and prints the project file found there. Nothing that exists is
ever written over. Free.
OPTIONS
--out=<file.zapNN> archive: the archive file to write.
--out-dir=<folder> retrieve: the folder to unpack into.
--allow-tia-running Proceed although a TIA Portal UI is running (CLI only).
--timeout <min> Abort after this many minutes (default 30).
--trace Print full stack traces on failure.
TIA Portal must be CLOSED. Openness opens only projects of its own version; an
archive or project of another version is refused, never upgraded.
EXIT CODES
0 done 1 failed 64 bad arguments or a target that exists (nothing done)
EXAMPLES
tiax project create "C:\Projects\Line2\Line2.ap19"
tiax project archive "C:\Projects\Line1\Line1.ap19" --out="D:\Archive\Line1_2026-10-13.zap19"
tiax project retrieve "D:\Archive\Line1_2026-10-13.zap19" --out-dir="C:\Projects\Line1_restored"
scl-apply
Lint, generate and compile one SCL source into a PLC (WRITES; needs TIA Portal)
tiax scl-apply <project.apXX> <source.scl> [options]
Applies an SCL source (any mix of FUNCTION_BLOCK, FUNCTION, DATA_BLOCK, TYPE and
ORGANIZATION_BLOCK) to ONE PLC:
1. lint (the checks of 'scl_lint': unbalanced blocks, a three-part VERSION that
generates an EMPTY block, global constants as CASE labels, undeclared #symbols,
unquoted names with spaces, empty statements). Errors stop the run; warnings
stop it too unless --accept-warnings. Nothing has been touched at that point.
2. backup (timestamped zip beside the project folder)
3. generate the blocks through a temporary external source, which is deleted
again afterwards — no leftover source breaks TIA's Search / Cross-references
4. compile that PLC (only that PLC), then save. Blocks that already existed are
updated where they are; with --group, NEW blocks move into that block group.
OPTIONS
--plc <name> The PLC (name, device item or station). Needed when the project
has several; an unknown or ambiguous name changes nothing.
--group <A/B> Block group for NEW blocks (created when missing). Openness has no
move: a block is exported and re-imported into the group inside a
transaction, which TIA allows only for a block that compiles; the
PLC is then compiled again.
--no-compile Generate only (the blocks stay uncompiled). Not with --group.
--accept-warnings Apply although the lint reported warnings.
--result-json <file> Also write the result as JSON: lint findings, generated / new /
updated blocks, and compiler messages {target, block, network, line,
severity, text, path, kb_hits[]}.
--no-backup Skip the automatic backup (CLI only). NOT recommended.
--backup-dir <d> Where to write the backup zip (default: beside the project folder).
--allow-tia-running Proceed although a TIA Portal UI is running (CLI only).
--timeout <min> Abort after this many minutes (default 30).
--trace Print full stack traces on failure.
EXIT CODES
0 applied and compiled clean
2 applied, but the compile reported errors (saved; the backup is the way back)
1 failed — the project was NOT saved
64 refused by the lint or by bad arguments — nothing was touched
EXAMPLE
tiax scl-apply "C:\Projects\Line1\Line1.ap19" FB_Pump.scl --plc=PLC_1 --group=Equipment
journal
Verify a workspace journal's hash chain, or export it (JSON lines or CSV)
tiax journal verify [where] [--json]
tiax journal export [where] [--csv] [--out <file>]
The MCP servers journal every project write (journal.jsonl in the workspace; without a
configured workspace, in the project's implicit workspace under %LOCALAPPDATA%\TIATool\
workspaces), plus policy refusals and approval requests. Each line records who acted
(OS user, host, MCP client), the approval a write carried, and prev_hash: the SHA-256
of the line before it. Editing, inserting or deleting a line breaks that chain.
WHERE (default: the workspace containing the current folder)
--workspace <dir> A workspace folder (or a folder inside one).
--project <file.apXX> The implicit workspace of that project.
--journal <file> A journal.jsonl file directly.
verify
Checks every line: valid JSON, seq one more than the line before, prev_hash equal to
the hash of the line before. Lines written before 0.8 carry no hash; the chain starts
at the first hashed line. Prints the head hash: record it elsewhere (a ticket, an
e-mail) to detect a journal that was cut short later — the chain alone cannot.
--json The result as JSON.
export
Writes the journal as JSON lines (default) or --csv (one row per entry; columns seq,
at, kind, tool, ok, task, verdict, os_user, host, mcp_client, approval, approver,
backup, prev_hash, data). Cells a spreadsheet would read as a formula are prefixed
with an apostrophe.
--out <file> Write to a file instead of standard output.
EXIT CODES 0 ok (verify: chain intact) · 1 no journal · 2 verify found problems · 64 usage
Built from docs/tiax-reference.md in the product repository. Links to files that are not published here are shown as plain text.