Command Palette

Search for a command to run...

UnylyUnyly
Весь каталог

Te1000

БесплатноНе проверен

MCP server for Beckhoff TwinCAT XAE / TE1000 Automation Interface, enabling control of XAE Shell, TwinCAT tree manipulation, PLC operations, and build actions v

GitHubEmbed

Описание

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

te1000-mcp

A Model Context Protocol server for Beckhoff TwinCAT 3 engineering automation — drive the TE1000 / XAE Automation Interface from an AI agent or any MCP client.

CI MCP Node TwinCAT License: MIT

te1000-mcp exposes the TwinCAT XAE engineering surface — the System Manager tree, PLC project authoring, IO/EtherCAT configuration, variable linking, builds, and runtime deployment — as a compact set of MCP tools. It talks to a running XAE Shell through the TE1000 Automation Interface (COM/DTE), so an agent can configure and build a TwinCAT project the same way an engineer would in the GUI.

A Node MCP front (index.js) owns the MCP protocol, tool schemas, and confirmation guards; the COM/DTE work runs in a persistent native C#/.NET daemon (Te1000Daemon.exe) that the front talks to over a Windows named pipe. The daemon is the sole backend. See How it works.

[!IMPORTANT] This server drives a real engineering tool and can activate or download to a TwinCAT runtime. Every action that touches the target runtime (activate, restart, download, deletes, licensing) is confirmation-gated and off by default. See Safety & guards.


Contents


Highlights

  • 25 noun-grouped tools covering the automatable TE1000 surface — tree, IO/EtherCAT, linking, PLC project & POU authoring, libraries, tasks, mapping, routes, fieldbuses, TcCOM, C++, measurement/scope, licensing, and variants.
  • Batch-first — every multi-item operation has a *_batch form that runs N operations in one DTE attach and returns a compact continue-on-error roll-up, instead of paying a process spawn + attach per call.
  • Native EtherCAT buildertc_ethercat creates fully-populated EtherCAT boxes (correct identity, SyncManagers, FMMUs, PDOs) for any device class by the GUI's own "Add Box" route, driven from the device's ESI.
  • Surgical PLC code editsplc_pou reads, greps, and patches declaration/implementation text in place and returns only the changed region, keeping agent context small.
  • Safe by default — destructive and runtime-affecting actions are confirmation-gated; the safety project is never written to, by policy.
  • Resilient to GUI modals — a dialog watchdog detects and (optionally) auto-dismisses modal dialogs that would otherwise hang a synchronous COM call forever.
  • Persistent native daemon — a long-lived C#/.NET daemon holds the COM session and caches the project tree and POU source text, so warm plc_pou search runs roughly 500× faster than the old per-call spawn model.

How it works

  MCP client (agent)
        │  stdio (JSON-RPC, MCP)
        ▼
  index.js ───────────────► Te1000Daemon.exe ──COM/DTE──► XAE Shell (TE1000)
   (Node 20)  named pipe     (persistent, x64,            running TwinCAT project
   daemonClient.js           net472, STA COM session)
   toolSchemas.js

Two cooperating processes:

  • Node MCP front (index.js) — speaks MCP/JSON-RPC over stdio, validates input with zod, single-sources every tool's input schema from toolSchemas.js, enforces the confirmation-token guards, and maps each tool action onto a fine-grained bridge action name. It routes those actions to the daemon over a named pipe (daemonClient.js).
  • Native daemon (daemon/Te1000Daemon.exe) — a persistent net472/x64 process that acquires the DTE + ITcSysManager once and keeps them, runs the dialog watchdog on an internal thread, caches the System Manager tree and POU source text, and serves the front over the pipe. It implements the same 164 bridge actions and returns the same JSON, so the tool surface is unchanged.

Pipe protocol

The front and daemon exchange newline-delimited JSON over \\.\pipe\te1000-mcp (name overridable via TE1000_DAEMON_PIPE):

  request:   {"id": "<n>", "action": "<bridge_action>", "payload": { … }}
  response:  {"id": "<n>", "ok": true,  "result": { … }}
           | {"id": "<n>", "ok": false, "error": "…", "errorKind": "com_error|dialog_blocked|timeout", "dialog": { … }}

Responses are correlated by id. The daemon serializes every COM call through a single STA worker thread, so concurrent pipe clients are safe (XAE serializes anyway). The daemon also answers two COM-free meta actions used for health checks: ping and list_actions.

Why a daemon — the performance win

An earlier model spawned a fresh 32-bit powershell.exe bridge (plus a second watcher process) on every call. Each spawn re-acquired the DTE/ITcSysManager COM handles (a Running-Object-Table walk + Marshal.GetActiveObject), JIT-compiled the inline Add-Type Win32 helpers, and — for plc_pou.find/search — re-walked the entire project tree from the root (O(tree-size), ~2,900 COM round-trips on a full project), so latency grew with project size.

The persistent daemon removes all of that from the hot path:

  • Persistent COM session (ComSession.cs) — the DTE + sysmanager are acquired once, health-checked with a cheap property read, and transparently reconnected if stale.
  • Two-layer tree cache (TreeCache.cs) — per-object decl/impl source text and a flat enumeration of the project's code objects are memoized, so a warm full-project search does zero COM tree-walk. This is the ~500× warm-search speed-up.
  • Edit watcher (EditWatcher.cs) — an on-demand DTE.Documents/.Saved dirty check plus a FileSystemWatcher over the project directory invalidate the cache so it never serves stale source for an object you are editing in the IDE (or that changed on disk).
  • Internal dialog watcher (DialogWatcher.cs) — runs on its own thread, so there is no per-call watcher process. See Reliability.

Build the daemon with daemon/build.ps1 (in-box .NET Framework MSBuild — no SDK/NuGet). The daemon requires the 64-bit TcXaeShell (DTE.17.0). See docs/architecture.md for the end-to-end design and docs/csharp-daemon-validation.md for the build/cut-over/validation guide.

Requirements

OS Windows
TwinCAT TwinCAT 3 XAE Shell / XAE installed, with the TE1000 Automation Interface
Node.js 20 or newer (the MCP front; the daemon does not remove the Node dependency)
A running XAE Shell the server attaches to an already-open instance (it does not launch XAE)
Daemon (required backend) the 64-bit TcXaeShell, a .NET Framework 4.x install (for the in-box MSBuild + net472 runtime), and TCatSysManagerLib.dll (ships with TwinCAT)

The XAE ProgID defaults to TcXaeShell.DTE.17.0. Override it with the TE1000_PROGID environment variable if your installation differs.

The daemon is not auto-built — build it once with daemon/build.ps1 (see Build the daemon); thereafter the MCP front auto-spawns the prebuilt Te1000Daemon.exe on first use. If the exe is absent, build it before the front can serve calls.

Install

git clone https://github.com/Edge-JB/TwinCAT-XAE-MCP.git
cd TwinCAT-XAE-MCP
npm install

Verify the server starts:

node index.js
# -> te1000-mcp server running on stdio   (Ctrl-C to exit)

The server communicates over stdio and is normally launched by an MCP client, not by hand. Running it directly just waits for a client on stdin.

Build the daemon

The native daemon is the backend, which you build once:

powershell -ExecutionPolicy Bypass -File daemon\build.ps1
# -> daemon\bin\Release\Te1000Daemon.exe   (Release, x64, net472)
  • Uses the in-box .NET Framework MSBuild (C:\Windows\Microsoft.NET\Framework64\v4.0.30319\MSBuild.exe) — no .NET SDK, no NuGet, no internet. The csproj is old-style (non-SDK) and targets net472; the produced x64 exe also runs on the net48 runtime.

  • References TCatSysManagerLib.dll (embedded interop) for the handful of vtable-only IUnknown interfaces that late-bound dynamic can't reach (ITcPlcProject, etc.). build.ps1 probes the known TwinCAT install paths; if yours differs, edit the <HintPath> in daemon/Te1000Daemon.csproj and rebuild. Pass -Debug for a Debug build.

  • After building, the MCP front auto-spawns the exe (detached, windowsHide) on the first call and connects to its pipe. The daemon is single-instance per pipe name (named mutex), so duplicate spawns are harmless, and it is detached so it survives an MCP-front restart. Verify it independently with no XAE attached:

    node daemon\test-ping.js     # spawns the daemon on a test pipe, round-trips ping
    

[!NOTE] The running daemon locks Te1000Daemon.exe. To rebuild after a code change, stop any running instance first: Get-Process Te1000Daemon | Stop-Process.

Configure your MCP client

Point your client at the absolute path of index.js in your clone. Example (Claude Desktop / Claude Code / any MCP client that reads this shape):

{
  "mcpServers": {
    "te1000": {
      "command": "node",
      "args": ["C:\\path\\to\\TwinCAT-XAE-MCP\\index.js"]
    }
  }
}

A ready-to-edit copy lives at examples/mcp-config.json.

Environment variables

All optional. The first group is read by the Node front (index.js / daemonClient.js); the second by the native daemon process. Defaults are from the source.

Read by the Node front:

Variable Default Purpose
TE1000_PROGID TcXaeShell.DTE.17.0 XAE Shell COM ProgID to attach to (passed through to the daemon as progId).
TE1000_DAEMON_PIPE te1000-mcp Named-pipe name. The front and the daemon it spawns share this, so a custom value applies to both.
TE1000_DAEMON_CONNECT_MS 20000 How long the client waits to connect to (and, if needed, spawn) the daemon before failing the request.
TE1000_DAEMON_REQUEST_MS 1900000 Node-side per-request ceiling: if no matching response arrives, the request is failed. Set comfortably above the daemon's own ~180 s ceiling so it never pre-empts a legitimately long call. 0 disables it.
TE1000_DIALOG_WATCH on 0 disables the daemon's internal modal-dialog watchdog.
TE1000_DIALOG_AUTODISMISS on 0 = detect + report dialogs only, never auto-click an allowlisted one.
TE1000_DIALOG_GRACE_MS 4000 How long a blocking dialog must persist before the daemon recycles its COM worker.

Read by the daemon:

Variable Default Purpose
TE1000_MCP_SOLUTION_PATH unset When multiple XAE instances are running, prefer the one whose open solution's full path matches this (otherwise the daemon prefers any instance with an open solution).
TE1000_DAEMON_DEBUG unset 1 enables a diagnostic log at %TEMP%\te1000-daemon-<pipe>.log.
TE1000_DAEMON_LOG unset Explicit path for the daemon diagnostic log (implies logging on, overrides the default location).

The daemon also accepts CLI flags (--pipe, --no-watch, --no-autodismiss, --grace-ms, --allowlist). The front sets these from the dialog-watch env vars above when it spawns the daemon — you normally don't pass them by hand.

Caveat — spawn-time only. TE1000_DIALOG_WATCH, TE1000_DIALOG_AUTODISMISS, and TE1000_DIALOG_GRACE_MS are read by the Node front only when it spawns the daemon, and are translated into the daemon's --no-watch / --no-autodismiss / --grace-ms flags. The daemon is single-instance per pipe, so changing one of these has no effect on an already-running daemon — kill that daemon process and let the front re-spawn it before the new value takes effect.

Quickstart

With XAE Shell open on your solution, an agent can drive a full configure → build loop. A typical session (tool name + arguments shown):

# 1. Confirm the server is attached and a solution is open
xae            action: "status"

# 2. Inspect the IO tree
tc_tree        action: "children"  path: "TIID^Device 2 (EtherCAT)"

# 3. Add a populated EtherCAT rack from its ESI (digital in/out + analog)
tc_ethercat    racks: [{
                 parent: "TIID^Device 2 (EtherCAT)^R01.Main.N01 (EK1200)",
                 modules: [{ type: "EL1008" }, { type: "EL2008" }, { type: "EL3064" }]
               }]
               save: true

# 4. Link a PLC input to a terminal channel
tc_link        action: "link"
               a: "TIPC^MyPlc^MyPlc Instance^PlcTask Inputs^MAIN.bStart"
               b: "TIID^Device 2 (EtherCAT)^Term 1^Channel 1^Input"

# 5. Build the solution
xae_build      action: "build"

# 6. (Optional, guarded) download to the target runtime
plc_download   confirm: "ALLOW_PLC_DOWNLOAD"

More end-to-end recipes — bulk linking, parameter edits via set_xml, POU authoring — are in examples/.

Tool reference

Paths into the System Manager tree use ^ separators, e.g. TIID^Device 2 (EtherCAT)^Box 1^Term 5^Channel 1. The leading token is the tree root (TIPC = PLC, TIID = IO, TINC = NC, TIRC = realtime/license, …).

Engineering & build

Tool Purpose Key actions
xae XAE shell & solution control status, open_solution, save_all, active_document, selected_items, error_list, clear_error_list, list_commands
xae_build Compile the active configuration clean, build, rebuild
xae_command Run a raw DTE command 🔒 any command name (guarded)

System Manager tree, IO & linking

Tool Purpose Key actions
tc_tree Read/write any tree item (identity, XML params, rename, create, delete) get, children, exists, get_xml, set_xml, rename, create, delete, import, export, focus — each with a *_batch form
tc_ethercat Build fully-populated EtherCAT boxes from their ESI racks: [{ parent, modules: [{ type, name?, revision? }] }]
tc_link Link/unlink variables; verify existing links link, unlink, resolve, links, link_batch, unlink_batch
tc_system Target & rescan helpers get_netid, set_netid, errors, rescan_plc, scan_io_boxes
tc_mapping Bulk variable mapping produce, consume, clear
nc NC motion tree tasks, axes, axis

PLC project & code

Tool Purpose Key actions
plc_project PLC project lifecycle create_from_template, open, info, set_boot_flags, generate_boot_project 🔒, online 🔒, plcopen_export, plcopen_import, save_as_library
plc_pou Author + surgically edit POUs/DUTs/GVLs (offline) author (create, import_template), read (get_decl, get_impl, outline, get_graphical), surgical (replace, replace_lines, insert, append), discover (tree, find, search), lifecycle (rename, move, delete 🔒)
plc_library Library refs / placeholders / repos list, scan, add_library, add_placeholder, set_resolution, freeze, remove_reference, install_library 🔒, …
plc_download Deploy the active PLC project 🔒 boot-project (default) or legacy command route
plc_session Online-session control via UI Automation status, logout 🔒

Realtime, fieldbus & platform

Tool Purpose Key actions
tc_task RT tasks / cores / linked tasks list, get, create, set_params, add_image_var, get/set_rt_settings, bind_cpu, get/set_linked_task
tc_route ADS routes list, broadcast_search, search_host, add_route 🔒, add_project_route 🔒
tc_settings Engineering settings & archives get/set_silent_mode, get/set_target_platform, save_solution_archive, save_plc_archive, get/set_independent_file, get/set_disabled
tc_fieldbus Non-EtherCAT fieldbuses (PROFINET/PROFIBUS/CANopen/DeviceNet/EAP) create_device, create_gsd_box, add_netvar, set_station_address, import_dbc, get/set_xml
tc_module TcCOM module objects list, create, get/set_xml, enable_symbols, set_context 🔒
tc_cpp TwinCAT C++ projects/modules create_project, create_module, tmc_codegen, set_props, build, publish 🔒
tc_measurement Scope + Analytics (TIAN) scope_create, scope_record 🔒, analytics_create, logger_create, stream_create, …
tc_license TwinCAT licensing list, add, activate_response 🔒
tc_variant Project variant management get_config, get_current, set_config, select, enable, disable

Runtime (guarded)

Tool Purpose
twincat_activate_configuration 🔒 Activate the configuration on the target
twincat_restart_runtime 🔒 Start/restart the TwinCAT runtime

🔒 = confirmation-gated. See Safety & guards. Full action signatures, batch semantics, and return shapes are documented in docs/tools.md.

Safety & guards

The server never auto-activates, auto-restarts, or auto-deploys. Any action that changes the target runtime, deletes a node, or alters licensing is blocked unless you pass the matching confirm token:

Confirm token Unlocks
ALLOW_TWINCAT_ACTIVATE twincat_activate_configuration
ALLOW_TWINCAT_RESTART twincat_restart_runtime
ALLOW_PLC_DOWNLOAD plc_download, plc_project boot/online
ALLOW_XAE_COMMAND_EXEC xae_command
ALLOW_PLC_LOGOUT plc_session logout
ALLOW_TWINCAT_DELETE node/object deletes (or use dryRun: true to preview)
ALLOW_PLC_LIBRARY_REPO machine-wide library repository administration
ALLOW_TWINCAT_ROUTE_WRITE ADS route writes
ALLOW_TWINCAT_MODULE_CONTEXT TcCOM context changes
ALLOW_CPP_PUBLISH C++ driver publish
ALLOW_MEASUREMENT_RECORD live scope acquisition
ALLOW_LICENSE_ACTIVATE license activation

Safety project policy. Nothing in this toolchain writes toward the TwinSAFE safety project. Every authoring tool refuses safety-rooted (TISC) paths via an internal guard. Safety remains read-only/diagnostic.

Reliability: dialog watchdog & PLC session control

A synchronous DTE/COM call blocks inside XAE's modal message loop if XAE raises a modal dialog (save-changes, "file changed externally", activate confirm, license prompt) — which would hang the MCP call and the calling agent indefinitely.

  • Dialog watchdog. This runs as an internal thread of the daemon (DialogWatcher.cs) that polls (~750 ms) for an application-modal dialog owned by the XAE process. It detects application-modal dialogs owned by XAE and either auto-dismisses them (if they match a rule in dialog-allowlist.json) or reports the dialog's title, body, and buttons back to the agent and abandons the call. If a non-allowlisted modal persists past TE1000_DIALOG_GRACE_MS, the daemon recycles its COM worker thread (re-acquiring the session on a fresh STA thread) without killing the daemon, so subsequent calls recover once the dialog is cleared. Detection is dialog-driven, not a wall-clock timeout, so long legitimate builds are never killed. The allowlist ships empty (report-only by default) and must never auto-answer Activate / Run-mode / restart / download / safety prompts.
  • Interactive resolution. When a dialog is not in the allowlist, the reported error tells the agent to ask the user which button to press (and whether to remember it), then call xae dialog_resolve {button, remember?}. That action clicks the chosen button on the live dialog; with remember:true it appends an auto-dismiss rule to dialog-allowlist.json and hot-applies it to the running watcher (no restart). Destructive prompts (activate / run-mode / restart / download / boot project / TwinSAFE / safety) are refused for auto-remember — the one-time chosen click still happens, but no rule is persisted (rememberRefused is reported). Use xae dialog_probe (read-only) to inspect the current dialog first.
  • PLC session control (powershell/plc-session.ps1) uses UI Automation to read and toggle the Login/Logout state (the DTE Login/Logout commands are unreachable on the 64-bit shell). plc_download auto-logs-out first (by default) so deferred source edits compile before the boot project is generated. It never logs back in.

Full details: docs/operations.md.

Troubleshooting

  • Te1000Daemon.exe not found — build it: daemon\build.ps1. The front cannot serve calls until the daemon is built.
  • Build fails on TCatSysManagerLib — the DLL wasn't found at the probed TwinCAT paths. Edit the <HintPath> in daemon/Te1000Daemon.csproj to your install and rebuild.
  • Rebuild fails with the exe locked — a daemon is still running. Stop it first: Get-Process Te1000Daemon | Stop-Process, then rebuild.
  • Daemon won't start / stale behavior — kill it (above) and let the front re-spawn a fresh one on the next call. Enable TE1000_DAEMON_DEBUG=1 to capture %TEMP%\te1000-daemon-<pipe>.log.
  • Wrong XAE instance picked (several open) — set TE1000_MCP_SOLUTION_PATH to the solution's full path to pin the daemon to that instance.
  • A modal dialog is blocking calls — clear it on the machine, or add a rule to dialog-allowlist.json (never for Activate / restart / download / safety prompts). The daemon picks up the allowlist on start.

Examples

The examples/ directory contains:

  • mcp-config.json — a drop-in client configuration.
  • README.md — copy-pasteable recipes: building an EtherCAT rack, bulk-linking IO, editing terminal parameters via set_xml, authoring a POU, and a safe build → activate → download flow.

Documentation

Document What's in it
docs/architecture.md The Node-front + persistent C#/.NET daemon design end to end — pipe protocol, COM session, caching, edit-watching
docs/tools.md Complete tool & action reference — signatures, batch semantics, return shapes
docs/operations.md Dialog watchdog, PLC session control, and the safety/guard model in depth
docs/automation-interface.md Survey of the full TE1000 Automation Interface surface (the menu these tools are carved from)
docs/csharp-daemon-coverage.md The 164-action port coverage checklist (bridge action → C# handler)
docs/csharp-daemon-validation.md Build, cut-over, and live-XAE smoke-test guide for the daemon
docs/notes.md Running engineering notes / backlog discovered on real projects
CHANGELOG.md Version history

Contributing

Contributions are welcome — see CONTRIBUTING.md for the architecture, the daemon build/dev loop, the action-handler contract, and the safety rules every change must respect. In short:

npm run check                                          # node --check index.js — syntax-validate the front
node daemon\test-ping.js                               # daemon process + pipe + JSON round-trip (no XAE)
powershell -ExecutionPolicy Bypass -File daemon\build.ps1   # rebuild the daemon after a C# change

License

MIT © Edge Automation.

Legal & trademarks

This is an independent, third-party project. It is not affiliated with, endorsed by, sponsored by, or supported by Beckhoff Automation GmbH & Co. KG.

All product names, logos, and brands are the property of their respective owners:

  • Beckhoff®, TwinCAT®, TE1000, and XAE Shell are trademarks or registered trademarks of Beckhoff Automation GmbH & Co. KG.
  • EtherCAT® is a registered trademark and patented technology, licensed by Beckhoff Automation GmbH, Germany.

These names are used for identification and descriptive purposes only; their use does not imply any affiliation with or endorsement by the trademark holders.

This project does not include, bundle, or redistribute any Beckhoff software. It automates a separately installed and licensed TwinCAT 3 / TE1000 environment that you must obtain from Beckhoff yourself. You are responsible for complying with all applicable Beckhoff license terms and for any action this tool performs against your engineering or runtime systems.

The software is provided "AS IS", without warranty of any kind, under the MIT License. See NOTICE for the full attributions.

from github.com/Edge-JB/TwinCAT-XAE-MCP

Установка Te1000

У этого сервера нет опубликованного пакета — он собирается из исходников. Открой репозиторий и следуй инструкции в README.

▸ github.com/Edge-JB/TwinCAT-XAE-MCP

FAQ

Te1000 MCP бесплатный?

Да, Te1000 MCP бесплатный — установка в пару кликов через Unyly без оплаты.

Нужен ли API-ключ для Te1000?

Нет, Te1000 работает без API-ключей и переменных окружения.

Te1000 — hosted или self-hosted?

Self-hosted: сервер запускается локально на твоей машине командой из раздела установки.

Как установить Te1000 в Claude Desktop, Claude Code или Cursor?

Открой Te1000 на unyly.org, выбери вкладку своего клиента (Claude Desktop, Claude Code, Cursor) и нажми Install — конфиг сгенерируется автоматически, без правки JSON.

Похожие MCP

Compare Te1000 with

Не уверен что выбрать?

Найди свой стек за 60 секунд

Автор?

Embed-бейдж для README

Похожее

Все в категории development