pi-twincat-ads
Pi extension for reading and writing TwinCAT runtime values over ADS.
Package details
Install pi-twincat-ads from npm and Pi will load the resources declared by the package manifest.
$ pi install npm:pi-twincat-ads- Package
pi-twincat-ads- Version
0.4.8- Published
- Jun 9, 2026
- Downloads
- 442/mo · 218/wk
- Author
- auda29
- License
- MIT
- Types
- extension, skill
- Size
- 1.5 MB
- Dependencies
- 4 dependencies · 0 peers
Pi manifest JSON
{
"extensions": [
"./dist/pi-extension.js"
],
"skills": [
"./skills"
]
}Security note
Pi packages can execute code and influence agent behavior. Review the source before installing third-party packages.
README

pi-twincat-ads
Pi extension for reading, watching, and safely writing TwinCAT PLC values over ADS.
This package is the Pi adapter for the monorepo. ADS logic is provided by
twincat-mcp-core; this package owns Pi extension registration, tool wrappers,
lifecycle hooks, context injection, and the bundled skill.
Install
pi install npm:pi-twincat-ads
The package manifest registers:
- extension entry:
./dist/pi-extension.js - skill directory:
./skills
Bundled Skills
The package ships two Pi skills:
twincat-ads: Pi-specific Runtime/ADS tool guidance for PLC, NC, IO, watches, write gates, and TwinCAT runtime diagnostics.twincat-xae-project-guidelines: agent-neutral guidance for offline TwinCAT XAE/Visual Studio project-file work, including PLC project XML, POUs, GVLs, DUTs, tasks, I/O devices, boxes, and terminals.
The XAE skill source lives centrally under
packages/skills/twincat-xae-project-guidelines. It is copied into this
package by the Pi prepack lifecycle and removed again by postpack, so npm
artifacts contain the skill without maintaining a second manual copy.
Configuration
The Pi adapter accepts configuration through:
--plc-config ./plc.config.jsonPI_TWINCAT_ADS_CONFIG=./plc.config.jsonPI_TWINCAT_ADS_CONFIG_JSON='{"connectionMode":"router",...}'
Default local config:
{
"connectionMode": "router",
"targetAmsNetId": "localhost",
"targetAdsPort": 851,
"readOnly": true,
"writeAllowlist": [],
"contextSnapshotSymbols": [],
"notificationCycleTimeMs": 250,
"maxNotifications": 128,
"maxWaitUntilMs": 600000,
"services": {
"plc": {
"targetAdsPort": 851,
"symbolGroups": {}
},
"nc": {
"targetAdsPort": 500,
"axes": []
},
"io": {
"targetAdsPort": 300,
"dataPoints": [],
"groups": {}
}
},
"diagnostics": {
"maxEvents": 50,
"maxLogBytes": 65536,
"eventSources": [
{
"id": "local-windows-application",
"kind": "windowsEventLog",
"logName": "Application",
"providerNames": ["TwinCAT", "Beckhoff", "TcSysSrv", "TcSysUi", "TcIoSrv", "TcNc", "TcEvent"],
"commandTimeoutMs": 8000
}
],
"logSources": [
{
"id": "local-windows-application-log",
"kind": "windowsEventLog",
"logName": "Application",
"providerNames": ["TwinCAT", "Beckhoff", "TcSysSrv", "TcSysUi", "TcIoSrv", "TcNc", "TcEvent"],
"commandTimeoutMs": 8000
}
]
}
}
For direct mode, include routerAddress, routerTcpPort, localAmsNetId, and
localAdsPort.
Tools
Read and discovery:
plc_list_symbolsplc_describe_symbolplc_readplc_read_manyplc_list_groupsplc_read_groupplc_state
plc_state includes ADS connection state, write gates, watch count, and a
readable PLC runtime status summary such as Run or Stop.
Configured groups are created in config under services.plc.symbolGroups.
plc_list_groups lists those group names and plc_read_group reads all
symbols in one group.
NC read-only:
nc_statenc_list_axesnc_read_axis_positionnc_read_axis_statusnc_read_axisnc_read_axis_manync_read_error
Configure NC axes under services.nc.axes with name and id.
IO read-only:
io_list_groupsio_readio_read_manyio_read_group
Configure IO data points under services.io.dataPoints and group them under
services.io.groups.
TwinCAT runtime diagnostics:
tc_statetc_event_listtc_runtime_error_listtc_log_readtc_diagnose_errorstc_diagnose_runtime
Configure diagnostic sources under diagnostics. The default local source reads
the Windows Application Event Log for TwinCAT/Beckhoff entries when available;
otherwise tools return unavailable capability details.
Prefer individual commands when the target is already clear. Use
tc_diagnose_errors for a small bundle of runtime errors, recent events, and log
tail; use tc_diagnose_runtime for TC/PLC/NC/IO runtime health plus active
runtime errors. These are triage helpers, not global dump tools.
Write control:
plc_set_write_modeplc_write
Watches:
plc_watchplc_wait_untilplc_unwatchplc_list_watches
All tool operations delegate to twincat-mcp-core.
Hooks
session_start: connects and reads configured snapshot symbolsbefore_agent_start: returns startup state, snapshots, failed snapshots, and watchescontext: injects live snapshots, failed snapshot names, watch count, and write modetool_call: pre-evaluates write access for write-related toolssession_end: disconnects and releases ADS resources
In packaged Pi usage, session_shutdown maps to the internal session_end
cleanup.
Safety Model
Writes require all gates to pass:
readOnly=falsein config.plc_set_write_modehas switched runtime write mode toenabled.- The exact symbol name is present in
writeAllowlist.
The default behavior is read-only.
Local Smoke Test
Build the workspace and run the root smoke script against a reachable PLC:
npm run build
npm run smoke:local -- --config ./local.config.json --symbol MAIN.someValue --watch-symbol MAIN.someValue
Optional write smoke:
npm run smoke:local -- --config ./local.config.json --symbol MAIN.someValue --watch-symbol MAIN.someValue --enable-write --write-symbol MAIN.safeWriteValue --write-value 1
Only run the write path against a safe symbol with readOnly=false and a matching
writeAllowlist entry.
Migration Notes
Existing pi-twincat-ads users keep installing the same package name. The main
behavioral change is package structure: ADS service and config logic now live in
twincat-mcp-core, while Pi-specific hooks and tools remain here.
The old single-package src/ads and src/config imports are preserved as
compatibility re-exports for now, but new code should import core primitives
from twincat-mcp-core.
Development
npm run sync:skills -w pi-twincat-ads
npm run test:pi
npm run build
npm run pack:pi
npm run pack:pi runs the Pi package prepack/postpack hooks and verifies
that shared skills are present in the package tarball while keeping the
repository source of truth under packages/skills.
Live PLC smoke-test details are documented in the repository under
docs/local-dev-test.md and docs/manual-smoke-test.md.