使用说明
ads-mcp-server
CLI-first MCP server that connects to Beckhoff TwinCAT PLCs via ADS and exposes on-demand reads plus guarded write confirmation for LLM agents.
Scope
- ADS read access and guarded write confirmation flow
- On-demand reads only
- Machine config in JSON (
data/machines) - Curated memory JSON (
data/memory) - MCP tool surface for machine, catalog, and memory
Install
pip install -e .
CLI commands
Use documentation/example addresses in public configurations and replace them with values for your own lab environment.
ads-mcp setup-machine --machine Machine1 --ip 127.0.0.1 --ams-net-id 192.168.1.100.1.1 --ads-port 851
ads-mcp set-write-permission --machine Machine1 --enabled
ads-mcp set-write-permission --machine Machine1 --disabled
ads-mcp discover --machine Machine1
ads-mcp list-groups --machine Machine1
ads-mcp list-tags --machine Machine1
ads-mcp list-tags --machine Machine1 --group Globals
ads-mcp memory add-tag --machine Machine1 --tag Globals.bRun
ads-mcp memory add-group --machine Machine1 --group Globals
ads-mcp memory remove-tag --machine Machine1 --tag Globals.bRun
ads-mcp memory list --machine Machine1
ads-mcp memory clear --machine Machine1
ads-mcp read --machine Machine1 --tag Globals.bRun
ads-mcp read-memory --machine Machine1
ads-mcp serve
Notes
pyadsis required for live PLC communication.- PLC writes require two-step confirmation (
request_tag_writethenconfirm_tag_write) and are blocked unless:- machine config sets
mcp.read_onlytofalse - resolved tag exists in
discovered_tags - resolved tag name contains
button(case-insensitive)
- machine config sets
Write example (MCP tools)
Writes are exposed through MCP tools (not direct CLI write commands).
- Request write:
{
"tool": "request_tag_write",
"args": {
"machine_id": "Machine1",
"tag_name": "MAIN.StartButton",
"value": true
}
}
Response (example):
{
"status": "pending",
"request_id": "f0f4f8d3-7f2f-4e8a-93c8-6d8028e2d2e7",
"resolved_tag_name": "MAIN.StartButton",
"guardrail_passed": true
}
- Confirm write:
{
"tool": "confirm_tag_write",
"args": {
"machine_id": "Machine1",
"request_id": "f0f4f8d3-7f2f-4e8a-93c8-6d8028e2d2e7",
"confirmed": true
}
}
Response (example):
{
"status": "written",
"tag_name": "MAIN.StartButton"
}
