| Version | 2.26.1 |
| Protocol | MCP 2024-11-05 (stdio) |
| Runtime | .NET Framework 4.8 |
| TIA Portal | V15.1 – V21* (Openness API, tested on V19) |
| License | Proprietary (free beta) |
*V15.1–V18 and V20–V21 are expected to work as TIA Portal maintains backward-compatible Openness APIs across versions, but have not been tested. Only V19 is fully tested.
TiaCommander is an MCP server that connects AI assistants to Siemens TIA Portal via the Openness API. It enables AI-assisted PLC programming, project management, library operations, hardware configuration, cross-reference analysis, and deployment — all through natural language.
Tested AI clients: Claude Desktop, Claude Code, VS Code (Copilot), Cursor, Windsurf, Codex CLI, Gemini CLI.
16 tools, 166 actions covering the full TIA Portal project lifecycle.
TiaCommander-v2.26.1-portable/
├── docs/
│ ├── configs/
│ │ ├── claude_code.txt
│ │ ├── claude_desktop_config.json
│ │ ├── codex_cli_config.toml
│ │ ├── cursor_mcp.json
│ │ ├── gemini_cli_settings.json
│ │ ├── generic_stdio.json
│ │ ├── vscode_copilot_mcp.json
│ │ └── windsurf_mcp_config.json
│ ├── 1-QUICKSTART.md
│ ├── KNOWN_LIMITATIONS.md
│ ├── LICENSE.txt
│ └── README.md
├── data/
│ └── exports/ ← Export output folders
│ ├── alarm_text/
│ ├── hardware/
│ ├── tag/
│ └── watch/
├── help/
│ ├── github-offline.html
│ └── readme-offline.html
├── Resources/
│ ├── logoBlack.png
│ └── tiacommander.png
├── runtimes/ ← WebView2 native loaders
├── Templates/ ← Block XML + alarm templates
├── x64/ ← SQLite native library (64-bit)
├── x86/ ← SQLite native library (32-bit)
├── CHANGELOG.md
├── EPPlus.dll
├── EPPlus.Interfaces.dll
├── LICENSE.txt
├── Microsoft.Bcl.AsyncInterfaces.dll
├── Microsoft.IO.RecyclableMemoryStream.dll
├── Microsoft.Web.WebView2.Core.dll
├── Microsoft.Web.WebView2.WinForms.dll
├── QUICKSTART.md
├── README.md
├── System.Buffers.dll
├── System.ComponentModel.Annotations.dll
├── System.Data.SQLite.dll
├── System.IO.Pipelines.dll
├── System.Memory.dll
├── System.Numerics.Vectors.dll
├── System.Runtime.CompilerServices.Unsafe.dll
├── System.Security.Cryptography.Xml.dll
├── System.Text.Encodings.Web.dll
├── System.Text.Json.dll
├── System.Threading.Tasks.Extensions.dll
├── TiaCommander.exe ← MCP server + Manager GUI
└── TiaCommander.exe.config
No installer, no registry changes, no system modifications. Extract, configure, and run. Download the latest .zip from GitHub Releases.
Prerequisite: Siemens TIA Portal V15.1 or later must be installed on your machine. TiaCommander loads Siemens Openness libraries directly from your TIA Portal installation at runtime — it will not start without TIA Portal.
First things first — we are software developers and automation engineers who use Siemens products daily — in our own facilities, at client sites, and in every project that needs industrial automation. We love it. With Siemens, it's simple — it just works. Every time. All the time.
During years of hands-on programming, wiring, testing, debugging and making things happen with Siemens PLCs, we have built TiaCommander just for our own internal needs. That's the honest reason why it exists — we built it for ourselves, and we find it awesome. It speeds things up tenfold, sometimes twentyfold, and sometimes more — until you ask yourself: how the hell were we getting things done before?!
You can get full project context through your AI assistant in under a minute. Create any block in seconds — SCL, LAD, FBD, DB — get interface structures, build multi-instance DBs, run cross-references, compile, debug, retrieve errors, and a lot more.
Every tool you see in the tool map below is built from what we actually need or use in our daily operations with Siemens PLCs. Whether you're working with S7-1200 or S7-1500 series — it doesn't matter. If Siemens TIA Portal supports it, you can use TiaCommander to manage it.
Now that we're making this tool public — we're genuinely keen on what features you're missing for your development workflow. Don't be shy — submit a feature request, file a bug report, or just tell us what you think. As an Engineer to Engineer — we read every line of feedback.
Enjoy TiaCommander.
AI Clients
Claude Desktop / Code · Cursor · VS Code / Copilot · Windsurf · Codex CLI · Gemini CLI
│
│ JSON-RPC 2.0 · stdio
▼
TiaCommander MCP Server
16 tools · 166 actions · standalone I/O · .NET Framework 4.8
│
│ Siemens Openness API
▼
TIA Portal (V15.1 – V21*, tested on V19)
│
▼
S7-1200 · S7-1500 · S7-300 · S7-400 · ET 200
| Tool / Action | # | Description |
|---|---|---|
open_manager |
— | Launch Manager GUI for registration, license, configuration |
get_info |
— | Server version, tool count, license status |
session |
15 | Entry point — connect to TIA Portal, manage projects |
connect |
Attach to running TIA Portal (withUI=true by default) | |
launch |
Start new TIA Portal instance (withUI=true by default) | |
disconnect |
Release handle, optionally close TIA | |
↳ closeTia |
Also terminate TIA Portal process | |
↳ saveChanges |
prompt / save / discard / auto | |
open |
Open .ap19 project (auto-launch TIA if needed, idempotent) | |
close_project |
Close with save/discard/auto | |
get_project |
Current project name, path, version | |
list_devices |
Enumerate devices — needed by all other tools | |
save |
Save project | |
is_dirty |
Check unsaved changes | |
create |
Create new project (withUI=true by default) | |
save_as |
Save under new name/location | |
archive |
Export .zap19 archive | |
↳ archivationMode |
None / Compressed / DiscardRestorableData | |
configure |
Set default paths (projects, archives, exports, libraries) | |
list_archives |
List .zap* archives from configured root | |
blocks_read |
14 | Inspect, compile, export blocks |
list |
List all blocks with type/number/language | |
↳ typeFilter |
all / code / OB / FB / FC / DB / GlobalDB / InstanceDB | |
↳ includeInstanceDbs |
Expand instance DB roll-up | |
get_details |
Block info, size, timestamps | |
get_interface |
Full interface structure (In/Out/Static/Temp) | |
get_all_interfaces_summary |
Summary across all blocks | |
get_xml_raw |
Raw XML content inline | |
export_xml_inline |
Parsed XML structure inline | |
export_xml_file |
Export XML to file or inline (returnInline) | |
export_source |
Export SCL/STL source | |
export_all_xml |
Export all blocks to directory or inline | |
compile_block |
Compile single block | |
compile_all |
Compile all blocks | |
check_consistency |
Block consistency status | |
get_compiler_messages |
All compiler messages | |
get_compiler_errors |
Errors only | |
blocks_write |
15 | Create, delete, import, modify blocks |
create_fb |
Create function block (number auto-assigned if omitted) | |
create_fc |
Create function (number auto-assigned if omitted) | |
create_ob |
Create organization block (number auto-assigned if omitted) | |
create_block |
Full block creation with interface + logic | |
↳ blockType |
FB / FC / OB | |
↳ language |
LAD / SCL / FBD / STL (69 LAD/FBD instruction types) | |
↳ memoryLayout |
Optimized (default) / Standard | |
↳ interface |
Custom In/Out/InOut/Static/Temp/Constant sections | |
↳ networks[] |
Multi-network blocks with per-network SCL/title/comment | |
delete_block |
Delete any block (optional force for orphaned instance DBs) | |
import_xml_inline |
Import block from XML string | |
import_xml_file |
Import block from file or export DB (exportId) | |
add_multi_instance_member |
Add static member to FB (bulk: members[]) | |
remove_multi_instance_member |
Remove static member from FB | |
rename_block |
Rename block and/or change number | |
update_network |
Update network title/comment | |
update_network_element |
Surgical edit of Call elements | |
↳ newTarget |
Retarget to different FB/FC | |
↳ newInstance |
Swap instance DB | |
↳ pinWires |
Rewire input/output pins to tags | |
add_network |
Insert empty network at position | |
delete_network |
Remove network by index | |
replace_network |
Replace network title/comment | |
db |
9 | Data block operations |
list |
List all global and instance DBs | |
get_structure |
Full DB structure via XML parse | |
create |
Create new global DB (number auto-assigned if omitted) | |
create_instance_db |
Create instance DB for an FB | |
delete |
Delete data block | |
add_member |
Add member to global DB (bulk: members[]) | |
delete_member |
Remove member from global DB (bulk: memberNames[]) | |
update_member |
Update member type, start value, comment, access flags | |
update_member_comment |
Update member comment only | |
tag |
12 | Tag tables, tags, assignment list |
list_tables |
List all tag tables | |
get_table_details |
Tags in a table with addresses/types | |
search |
Search tags by name (partial match) | |
create_table |
Create new tag table | |
delete_table |
Delete tag table | |
add_tag |
Add tag to table (bulk: tags[]) | |
delete_tag |
Remove tag from table (bulk: tagNames[]) | |
update_comment |
Update tag comment | |
set_access |
Set external access flags (accessible, visible, writable) | |
get_assignment_list |
Address occupancy for M/I/Q areas + HW I/O | |
↳ mode=declared |
All declared tag addresses (default) | |
↳ mode=used |
Only addresses referenced in block code | |
↳ mode=conflicts |
Detect addresses in 2+ blocks (Q=error, M=info, I=hidden) | |
find_next_free |
Next free address with alignment (Bool/Byte/Word/DWord) | |
↳ mode=declared |
Skip all declared tag addresses (default, safest) | |
↳ mode=used |
Skip only code-referenced addresses | |
export_tag_table_data |
Export tag table to CSV or XLSX | |
udt |
10 | User-defined type operations |
list |
List all UDTs | |
get_structure |
UDT member structure | |
create |
Create new UDT | |
delete |
Delete UDT | |
add_member |
Add member to UDT (bulk: members[]) | |
delete_member |
Remove member (bulk: memberNames[]) | |
update_member |
Update member type, initial value, comment | |
update_member_comment |
Update member comment | |
export_xml |
Export UDT to XML (file or inline) | |
import_xml |
Import UDT from XML (filePath / xmlContent / exportId) | |
watch |
13 | Watch and force table debugging |
list_tables |
List all watch + force tables | |
create_table |
Create watch table | |
delete_table |
Delete watch table | |
rename_table |
Rename watch table | |
clear_table |
Remove all entries | |
import_table |
Import from XML (filePath / xmlContent / exportId) | |
get_entries |
List entries with addresses/formats | |
add_entry |
Add watch/force entry | |
update_entry |
Update entry fields | |
delete_entry |
Remove entry by address | |
export_table |
Export to XML (file or inline) | |
export_watch_data |
Export watch table to CSV or XLSX | |
export_force_data |
Export force table to CSV or XLSX | |
hardware |
12 | Hardware config, network, I/O |
get_device |
Single device configuration | |
get_rack_slot_details |
Rack/slot topology + I/O assignments | |
get_full_config |
All devices configuration | |
get_network |
Subnets, nodes, IO systems | |
get_io_map |
Full I/O address map | |
compile_device |
Compile single device HW | |
compile_all |
Compile all HW | |
export_csv |
Device list to CSV | |
export_xlsx |
Device list to Excel | |
export_io_map |
Full device I/O map (rack/slot + tags) to CSV or XLSX | |
export_hardware_map |
Raw CAx/AML hardware data to CSV or XLSX | |
set_network_config |
Set IP, subnet, PROFINET name, station name | |
library |
26 | Library types, master copies, lifecycle |
list_libraries |
List project + open global libraries | |
get_info |
Library details + counts | |
list_folder |
Browse folder contents | |
↳ section |
types / master_copies / both | |
get_tree |
Recursive tree dump | |
↳ section |
types / master_copies / both | |
↳ nested |
Flat list (default) or indented hierarchy | |
↳ includeItems |
false = folder structure only (fast orientation) | |
find |
Search by glob pattern (* and ?) | |
↳ section |
types / master_copies / both | |
get_type |
Type details + version list | |
↳ includeXml |
Inline XML body (capped ~30KB) | |
↳ version |
latest_committed (default) / explicit / latest_any | |
get_master_copy |
Master copy metadata | |
publish_block_as_master_copy |
Publish FB/FC/OB to library | |
↳ onCollision |
autoRename / replace / fail | |
publish_plc_type_as_master_copy |
Publish UDT to library | |
delete_master_copy |
Delete master copy | |
instantiate_master_copy |
Copy master copy into project | |
instantiate_library_type |
Instantiate versioned type | |
add_to_multi_instance_fb |
Add type as multi-instance member | |
create_library_folder |
Create folder in library | |
delete_library_folder |
Delete folder (recursive option) | |
export_type_xml |
Export type version to XML file | |
open_global_library |
Open .al19 file | |
↳ openMode |
ReadOnly (default) / ReadWrite | |
close_global_library |
Close global library | |
create_global_library |
Create new .al19 | |
save_global_library |
Save global library | |
archive_global_library |
Archive to .zal19 | |
update_check |
Preview what update_project would change | |
update_project |
Apply library updates to project (destructive) | |
↳ deleteUnusedVersions |
Auto-delete versions with no instances | |
promote_to_global |
Copy types to global library | |
↳ forceUpdateMode |
SetOnlyHigher / ForceSetAny / NoDefaultVersionChange | |
↳ structureConflictMode |
CancelIfConflicts / UpdateStructure / RetainStructure | |
compare_to_target |
Diff two libraries | |
delete_unused_types |
Remove types with no instances (dry-run + confirm) | |
xref |
4 | Cross-reference analysis |
get_references |
Cross-refs for one block (who it calls, what it reads/writes) | |
↳ filter |
all / with_refs / without_refs / unused | |
find_unused |
All blocks not called from any OB chain | |
find_callers |
Which blocks call/reference a target block | |
find_orphaned_instance_dbs |
Instance DBs whose owning FB is missing | |
alarm_text |
15 | PLC alarm text lists, entries, alarm classes |
list_textlists |
List system + user text lists | |
create_textlist |
Create text list (optionally with entries) | |
↳ listRange |
Decimal (default) / Binary / Bit | |
get_entries |
Read entries for a text list | |
add_entries |
Add entries to text list | |
update_entries |
Update entries by From value | |
delete_entries |
Delete entries by From value | |
update_textlist_comment |
Update comment (direct API) | |
delete_textlist |
Delete user text list | |
export_alarm_texts |
Export alarm instance texts to XLSX | |
import_alarm_texts |
Import alarm texts from XLSX | |
export_textlists |
Export text lists to XLSX | |
import_textlists |
Import text lists from XLSX | |
export_alarm_classes |
Export alarm class definitions | |
import_alarm_classes |
Import alarm class definitions | |
export_alarm_data |
Export alarm data to CSV or XLSX (scope: texts/lists/classes) | |
admin |
11 | Server administration, usage analytics, export storage |
get_stats |
Call statistics per tool+action (counts, errors, avg duration) | |
get_recent_errors |
Last N failed calls with device/firmware context | |
get_device_profiles |
All unique devices seen (order number, firmware, TIA version) | |
get_version |
Server version, DB path, DB size | |
get_system_info |
OS, .NET, TIA Portal version, uptime, memory | |
list_exports |
Recent exports stored in DB (with size, format, timestamp) | |
get_export |
Retrieve export content with paging | |
↳ raw |
Content only, no metadata header | |
delete_export |
Delete single export | |
clear_exports |
Delete expired exports | |
save_export |
Save export to file (auto-decodes base64 for XLSX) | |
open_file |
Open exported file with default Windows application | |
diagnostics |
6 | Runtime PLC state, network scan, connection config, compare |
scan_devices |
Network scan — discover accessible PLCs | |
configure_connection |
Set up download connection programmatically | |
get_plc_status |
Online/offline state | |
go_online |
Connect to PLC | |
go_offline |
Disconnect from PLC | |
compare_online_offline |
Compare project vs PLC — all blocks, tags, UDTs | |
download_upload |
4 | Download to PLC, upload station into project |
download_check |
Pre-flight: connection, compile status | |
download_to_device |
Download to PLC (requires confirm) | |
↳ mode |
software_changes (default) / software / hardware_software / hardware | |
↳ stopModules |
Stop PLC before download (default: false) | |
upload_check |
Enumerate upload connection options | |
upload_station |
Upload PLC station into project (requires confirm) |
Total: 16 tools (14 meta-tools + 2 standalone), 166 actions
Each meta-tool groups related actions behind a single action parameter. get_info and open_manager are standalone utilities that work without a license. Start with session to connect, then use any other tool.
TiaCommander should work with any PLC supported by TIA Portal and the Openness API. The following devices have been tested in-house with full tool coverage:
| Device | Order Number | Firmware | TIA Portal |
|---|---|---|---|
| S7-1200 CPU 1212C DC/DC/Rly | 6ES7 212-1BE31-0XB0 | V3.0 | V19 |
| S7-1200 CPU 1214C DC/DC/DC | 6ES7 214-1AG31-0XB0 | V3.0 | V19 |
| S7-1200 CPU 1214C DC/DC/DC | 6ES7 214-1HG40-0XB0 | V4.5 | V19 |
| S7-1200 CPU 1215C DC/DC/DC | 6ES7 215-1AG31-0XB0 | V3.0 | V19 |
| S7-1200 CPU 1215C DC/DC/Rly | 6ES7 215-1BG31-0XB0 | V3.0 | V19 |
| S7-1200 CPU 1217C DC/DC/DC | 6ES7 217-1AG40-0XB0 | V4.2 | V19 |
This list will grow as we collect telemetry data from users and expand testing across more device families, firmware versions, and TIA Portal editions.
TiaCommander creates complete PLC blocks from structured JSON descriptions:
- SCL blocks — via External Source API (firmware-agnostic)
- LAD/FBD blocks — via FlgNet XML builder with 69 verified instruction types:
- Bit logic, timers (TON/TOF/TP), counters (CTU/CTD/CTUD)
- Math (Add, Sub, Mul, Div, Mod, Abs, Sqrt, Sin, Cos, etc.)
- Comparators (EQ, NE, GT, GE, LT, LE)
- Move & conversion, word logic, shift & rotate, selection
- Program flow (FB/FC calls with parameter wiring, JMP/JMPN, RET, LABEL)
- Block numbers — auto-assigned if omitted, or explicit
- Custom interfaces — Input, Output, InOut, Static, Temp, Constant sections
The MCP server treats PLC deployment operations as destructive. These actions require explicit confirmation strings before execution:
| Action | What it does |
|---|---|
download_to_device |
Downloads software/hardware to a live PLC |
upload_station |
Uploads a PLC station into the project |
delete_unused_types |
Removes library types with zero instances |
All other operations work within the TIA Portal project and are reversible before download.
TiaCommander works fully standalone — no external file management tools required.
Three input modes for every import: file path, inline content, or export database reference.
Three output modes for every export: inline (default), export database, or file.
Exports auto-expire after 24 hours. Manage via admin tool actions.
However, we strongly recommend pairing TiaCommander with Desktop Commander (GitHub) for your daily AI agent workflow. Desktop Commander gives your AI assistant terminal access, file management, and code editing capabilities across your entire OS. This is not a paid promotion — we use Desktop Commander every day in our own work, and it happens to be created by our fellow Latvian, Eduards Ruzga. It's free, open-source, and it makes everything better.
All data stays on your machine. The local SQLite database stores tool call statistics, device profiles, error log, and temporary export cache.
TiaCommander collects limited telemetry to improve the product:
- Error reports — when a tool call fails, the error type and context are sent so we can identify and fix issues.
- Tool usage statistics — which tools and actions are used most often, to understand what is most valuable.
- AI client information — which AI assistant is connected (client name and version), to ensure compatibility.
No PLC program data, project files, or block contents are ever transmitted.
Your personal information (name, surname, email) provided during registration is governed by European Union GDPR rules. We do not share, sell, or disclose your data to third parties. We will never send you marketing materials or anything not directly relevant to your use of TiaCommander — unless you explicitly ask us to.
TiaCommander is actively developed. Here's what we're working on:
- HMI integration — Openness API access to HMI screens, tags, and alarm views
- Runtime monitoring — live PLC data via Web API and OPC UA (S7-1200 V4.4+, S7-1500)
- TIA Portal V20 support — updated Openness DLLs and new API features
- PLCSIM Advanced — simulation control for offline development and testing
- S7-1500 expanded testing — broader device family coverage with telemetry-driven validation
Have a feature idea? Submit it on GitHub.
Download the latest release and see the Quick Start Guide — everything you need to get up and running in 5 minutes: extract, Openness group setup, AI client configuration for all 7 tested clients, license activation, and first commands.
Ready-to-use config files for each AI client are in the configs/ folder.
TiaCommander is proprietary software published by SIA A4 Studio. During the beta period, the tool is completely free with unlimited usage and all tools available — no restrictions.
In return, we count on you to help us make TiaCommander better. If you encounter a bug, have an idea for a new feature, or just want to share how you use the tool in your workflow — we want to hear from you:
- Bug reports: github.com/a4webdev/tiacommander-mcp/issues
- Feature requests: github.com/a4webdev/tiacommander-mcp/issues
- Testimonials & feedback: tiacommander.com/wf/github
Every report, every suggestion, every comment helps us build a better tool for the Siemens automation community.
See LICENSE.txt for full terms. Visit tiacommander.com for more information.
TiaCommander™ is a trademark of SIA A4 Studio. Siemens, TIA Portal, SIMATIC, S7-1200, S7-1500 are trademarks of Siemens AG. TiaCommander is not affiliated with, endorsed by, or sponsored by Siemens AG.