te1000-mcp
MCP server for Beckhoff TwinCAT XAE / TE1000 Automation Interface, enabling control of XAE Shell, TwinCAT tree manipulation, PLC operations, and build actions via natural language.
README
te1000-mcp
MCP server for Beckhoff TwinCAT XAE / TE1000 Automation Interface.
This server uses the locally verified TwinCAT XAE Shell COM ProgID and calls it through 32-bit PowerShell, which matches Beckhoff's TE1000 requirements.
What It Can Do
- attach to a running XAE Shell instance
- open a solution in XAE Shell
- list and execute XAE/DTE commands
- inspect the active document and selected items
- read the current Error List when available
- clear the visible Error List
- inspect TwinCAT tree items
- list tree children
- export and import tree item XML with
ProduceXml/ConsumeXml - create, import, export, and delete TwinCAT child items
- link and unlink TwinCAT variables
- get and set the target NetId
- trigger PLC rescans and I/O box scans
- inspect NC tasks and axes
- save the active solution
- clean, build, and rebuild the active solution configuration
- PLC login, download, and logout through XAE commands
- activate configuration
- start or restart the TwinCAT runtime
v2 Tool Surface (2026-06-11)
The MCP surface was consolidated for agent-context efficiency: 36 tools -> 10,
grouped by noun with action enums, compact outputs (raw XML, pruned compact
JSON). The PowerShell bridge is unchanged and still answers the original
fine-grained action names; index.js maps onto them (the original v1 tool
surface is preserved in this repo's git history). Old tool names appearing later in this README map as:
twincat_*_tree_item*/twincat_*_child -> tc_tree, twincat_link/unlink/ resolve_variable* -> tc_link, netid/errors/rescan/scan tools -> tc_system,
nc_* -> nc, xae_solution_build -> xae_build, xae_execute_command ->
xae_command, remaining xae_* -> xae.
xae— status / open_solution / save_all / active_document / selected_items / error_list / clear_error_list / list_commandsxae_build— clean / build / rebuildxae_command— raw DTE command (guarded)tc_tree— get / children / exists / get_xml / set_xml / create / delete / import / export / focustc_link— link / unlink / resolvetc_system— get_netid / set_netid / errors / rescan_plc / scan_io_boxesnc— tasks / axes / axisplc_download— bootproject (default, headless ITcPlcProject deploy) or legacy command routetwincat_activate_configuration,twincat_restart_runtime
plc_login/plc_logout were dropped from the surface (the 64-bit shell's DTE
exposes no window automation, so they never worked here); use xae_command
with OtherContextMenus.PlcProject.Login/.Logout on shells where it does.
progId is no longer a tool parameter — set env TE1000_PROGID to override
the default TcXaeShell.DTE.17.0.
High-impact tools are guarded:
twincat_activate_configurationrequiresconfirm="ALLOW_TWINCAT_ACTIVATE"twincat_restart_runtimerequiresconfirm="ALLOW_TWINCAT_RESTART"xae_commandrequiresconfirm="ALLOW_XAE_COMMAND_EXEC"
Requirements
- Windows
- Beckhoff TwinCAT XAE Shell / XAE installed
- TE1000 Automation Interface available through
TcXaeShell.DTE.15.0 - 32-bit Windows PowerShell present at:
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\powershell.exe - Node.js 20+
Install
git clone https://github.com/Edge-JB/tc1000-MCP-TC-4026.git
cd tc1000-MCP-TC-4026
npm install
Run
node index.js
The server speaks MCP over stdio, so it is normally launched by an MCP client
(see below) rather than run by hand. Running it directly just prints
te1000-mcp server running on stdio and waits for a client on stdin.
MCP Client Config Example
Point your MCP client at the absolute path of index.js in your clone:
{
"mcpServers": {
"te1000": {
"command": "node",
"args": [
"C:\\path\\to\\tc1000-MCP-TC-4026\\index.js"
]
}
}
}
Tool Notes
twincat_set_tree_item_xml is the main path for IO edits. Typical workflow:
- call
twincat_get_tree_item_xml - edit the returned XML
- call
twincat_set_tree_item_xml - call
xae_save_all - optionally call
twincat_activate_configuration
Example TwinCAT tree path:
TIID^Device 1 (EtherCAT)^Term 1 (EK1100)
The exact path depends on the project tree in the active XAE session.
Useful discovery helpers:
xae_list_commandsxae_get_selected_itemsxae_get_error_listxae_clear_error_listtwincat_test_item_pathtwincat_resolve_variable_pathnc_list_tasksnc_list_axes
PLC Variable Paths
PLC struct variables are not always exposed to ITcSysManager::LinkVariables with IEC dot syntax all the way down. The top-level PLC variable can use dot syntax after the POU name, but child fields under a mapped struct may be XAE tree subitems and require ^.
Example:
TIPC^MyPlc^MyPlc Instance^PlcTask Inputs^MAIN.stSlot02_DI^In00
not:
TIPC^MyPlc^MyPlc Instance^PlcTask Inputs^MAIN.stSlot02_DI.In00
Use twincat_resolve_variable_path to test a candidate path and see the valid alternatives. twincat_link_variables also resolves these alternatives by default before linking.
Modal-dialog watchdog
A bridge call drives XAE through a synchronous DTE/COM call. If that call makes XAE raise a modal dialog (save-changes, "file changed externally", activate confirm, a license prompt, etc.), the COM call blocks inside XAE's modal message loop until a human clicks the dialog — so the MCP call, and the calling agent, hang indefinitely with no idea why.
powershell/dialog-watch.ps1 closes that gap. It runs as a short-lived process
alongside every bridge call and, each poll, looks for an application-modal
dialog owned by the XAE process (precise signal: a visible/enabled window whose
owner window is disabled — docked tool windows and non-modal popups don't
qualify). On finding one it either:
- auto-dismisses it — if the dialog matches a rule in
powershell/dialog-allowlist.json, the watcher clicks that rule's button, releasing the blocked COM call so the operation completes normally; or - reports it — for any dialog with no matching rule,
index.jswaits a short grace period (TE1000_DIALOG_GRACE_MS, default 4000 ms), then abandons the bridge call and returns an error containing the dialog's title, body text, and buttons, so the agent knows exactly what is blocking it. The dialog is left open on the machine for a human to clear; the operation result is indeterminate.
Detection is dialog-driven, not a wall-clock timeout, so long legitimate operations (a multi-minute build) are never killed just for taking a while.
Pre-flight gate
The watcher above catches dialogs that appear during a call. But a dialog that
is already open before the command (you edited a file outside XAE, the target
connection dropped, an earlier prompt was never cleared) corrupts the next
command's result — e.g. a build returns a bogus "No solution is open" — and on
the old code simply hung. So before every bridge call, index.js runs a one-shot
pre-flight probe: it auto-dismisses an allowlisted dialog, and otherwise
refuses to run the command, returning the dialog's title/text/buttons instead
of firing into a poisoned XAE.
Allowlist (powershell/dialog-allowlist.json)
Ships with one rule — the "file has been changed outside the environment →
reload?" prompt is auto-answered Yes, so an agent's own source edits load
into XAE. Each rule: match (regex on the title, required), optional textMatch
(regex on the body), and button (exact label to click). First matching rule
wins; unmatched dialogs are reported, never clicked.
Live cell. Only add dialogs that are safe to auto-answer unattended. Never allowlist Activate Configuration / Run-mode / restart / download / safety prompts — those must stay human-confirmed. Prefer the non-destructive button.
Env toggles
| Var | Default | Effect |
|---|---|---|
TE1000_DIALOG_WATCH |
on | 0 disables the watchdog entirely |
TE1000_DIALOG_AUTODISMISS |
on | 0 = detect + report only, never auto-click |
TE1000_DIALOG_GRACE_MS |
4000 |
how long a blocking dialog must persist before the call is abandoned |
TE1000_BRIDGE_TIMEOUT_MS |
0 (off) |
optional wall-clock backstop for non-dialog hangs |
Run dialog-watch.ps1 -Mode probe at any time to see the current dialog (if any)
as JSON — useful for discovering the exact title/button strings for a new
allowlist rule.
PLC session control (auto-logout)
While the IDE is logged in to the PLC, TwinCAT will not load source edited
outside the editor — it defers it ("File will be loaded after logout"). So an
agent that edits a POU mid-session can't get that change compiled or deployed
until a logout happens. On the 64-bit TcXaeShell the DTE Login/Logout commands
are unreachable (they never report IsAvailable=true and have no key binding),
which is why they were dropped from the tool surface.
powershell/plc-session.ps1 works around this with UI Automation: the IDE's
Login/Logout toolbar buttons are reachable even when the DTE commands are not.
Their enabled state is also a reliable session detector (Logout enabled ⇒ logged
in; the two flip on logout).
plc_sessiontool —action: "status"(read-only{ loggedIn }) oraction: "logout"(invoke the Logout button; guarded withconfirm="ALLOW_PLC_LOGOUT"). It never invokes Login — there is no auto-login by design.plc_downloadauto-logout — withautoLogout(defaulttrue), the deploy first checks the session and, if logged in, logs out so any deferred source edits are applied before the boot project is generated. It never logs back in; passautoLogout: falseto skip.
Build Support
Use xae_solution_build with:
action: "clean"action: "build"action: "rebuild"
This runs through the Visual Studio SolutionBuild automation layer, which is the same side Beckhoff points to when PLC compilation is needed through automation.
PLC Session Commands
The server exposes these non-ADS PLC actions through XAE command execution:
plc_loginplc_downloadplc_logout
Current command mappings found in the live XAE shell on this machine:
- login:
OtherContextMenus.PlcProject.Login - download:
PLC.Downloadnone - logout:
OtherContextMenus.PlcProject.Logout
These depend on XAE context. If a command is unavailable because the wrong node/editor is active, pass a different commandName override or change the active selection in XAE.
Tree Manipulation
The server exposes TwinCAT tree operations through ITcSmTreeItem:
twincat_create_childtwincat_delete_childtwincat_import_childtwincat_export_child
These are powerful but parent-type-specific. subType and import compatibility must match what the parent node accepts.
Targeting And Rescan
twincat_get_target_netidtwincat_set_target_netidtwincat_rescan_plc_projecttwincat_scan_io_boxes
twincat_rescan_plc_project defaults to TIPC.
twincat_scan_io_boxes should target a device node such as:
TIID^Device 1 (EtherCAT)
NC Helpers
The server includes NC convenience tools:
nc_list_tasksnc_list_axesnc_get_axis_info
A typical NC root pattern is:
TINC^NC-Task 1 SAF^Axes^Axis 1
TwinCAT quirk:
- some container/root nodes such as
TIIDand major EtherCAT boxes may return descendant collections rather than a single scalar item payload through COM - leaf nodes and specific IO terminals are the safer targets for
ProduceXml/ConsumeXml - if a broad path returns too much data, step down one level and target the exact terminal, box, or variable node
xae_focus_tree_itemis best effort only; this environment exposes expand/focus behavior through the backing VS project item, but not a reliable true selection APIxae_get_error_listuses typedEnvDTE80interop loaded from the XAEPublicAssembliesfolder because late-boundToolWindows.ErrorListwas returningnullin this shellxae_clear_error_listclears the visible Visual Studio/XAE Error List throughOtherContextMenus.ErrorList.Clear, which is different fromTwinCAT.ClearErrorList
Safety
This server intentionally does not auto-activate or auto-restart TwinCAT.
If you expose it to an agent, keep the confirmation guards in place unless you are willing to accept live target changes.
The modal-dialog watchdog (above) is held to the same standard: its allowlist ships empty, and you should never add rules for Activate Configuration, Run-mode, restart, download, or safety prompts — those stay human-confirmed.
License
MIT.
推荐服务器
Baidu Map
百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。
Playwright MCP Server
一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。
Magic Component Platform (MCP)
一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。
Audiense Insights MCP Server
通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。
VeyraX
一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。
graphlit-mcp-server
模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。
Kagi MCP Server
一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。
e2b-mcp-server
使用 MCP 通过 e2b 运行代码。
Neon MCP Server
用于与 Neon 管理 API 和数据库交互的 MCP 服务器
Exa MCP Server
模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。