Getting Started¶
Prerequisites¶
Network access to a Beckhoff TwinCAT PLC — not required for the simulated quick start below
(Optional) An OIDC identity provider (Keycloak, Entra ID, etc.)
Try It Without a PLC¶
Adsify’s ADS access is provided by the Dahlke.TwinCAT.Ads
library, which supports simulated, in-memory PLC targets alongside real ones. The
appsettings.Simulation.json profile configures a demo target with Mode: "Simulated"
and seeded values, so you can run most of the API — no TwinCAT installation, no
hardware, no ADS router:
git clone https://github.com/patdhlk/adsify.git
cd adsify
dotnet build Adsify.sln
ASPNETCORE_ENVIRONMENT=Simulation dotnet run --project src/Adsify.Api --urls "http://localhost:5000"
curl http://localhost:5000/api/plcs
curl http://localhost:5000/api/plcs/demo/variables/MAIN.Speed
curl http://localhost:5000/api/plcs/demo/symbols
On macOS, port 5000 is already taken. AirPlay Receiver binds it and answers with a
bare 403, which looks like an authentication failure rather than a port collision. Pick
another port (--urls "http://localhost:5080") or disable AirPlay Receiver under
System Settings → General → AirDrop & Handoff.
Simulation is unauthenticated — it bypasses authentication the same way
Development does, so every request gets full admin access with no token required.
This profile is for local development only; never expose it on a shared network.
Simulation is per-target configuration, not a separate connection type: set
"Mode": "Simulated" on any target in PlcTargets and seed it with InitialValues.
Real and simulated targets can coexist in one configuration — see
Configuration for the full PlcTargets reference.
Simulated responses are not type-identical to real ones. InitialValues seeded
from a JSON file binds through IConfiguration, which stores every value as a string
with no memory of its original JSON type. Every seeded value — numbers, booleans,
strings alike — reads back as a JSON string with typeName: "STRING": a seeded
1500 returns "1500", not 1500; a seeded true returns "True", not true. A
real PLC (or a target seeded programmatically in code) returns properly typed values
with a real PLC type name. Don’t expect simulated and real responses to be
byte-for-byte identical for the same nominal value.
Quick Start¶
1. Clone and build¶
git clone https://github.com/patdhlk/adsify.git
cd adsify
dotnet build Adsify.sln
2. Configure your PLC connection¶
Edit src/Adsify.Api/appsettings.Development.json:
{
"AmsRouter": {
"Name": "Adsify",
"NetId": "192.168.1.78.1.1",
"TcpPort": 48898,
"LoopbackIP": "127.0.0.1",
"LoopbackPort": 48898,
"ChannelPortType": "Loopback",
"Routes": [
{
"Name": "MyPLC",
"Address": "192.168.1.136",
"NetId": "192.168.1.136.1.1"
}
]
},
"PlcTargets": {
"MyPLC": {
"AmsNetId": "192.168.1.136.1.1",
"Port": 851,
"DisplayName": "My TwinCAT PLC"
}
}
}
Replace the IP addresses and AMS Net IDs with your actual PLC values.
3. Run¶
ASPNETCORE_ENVIRONMENT=Development dotnet run --project src/Adsify.Api --urls "http://localhost:5000"
4. Test¶
# List connected PLCs
curl http://localhost:5000/api/plcs
# Read a variable
curl http://localhost:5000/api/plcs/MyPLC/variables/MAIN.nCounter
# Browse symbols
curl http://localhost:5000/api/plcs/MyPLC/symbols
# Device info
curl http://localhost:5000/api/plcs/MyPLC/device/info
5. Explore the API¶
Open the Swagger UI at http://localhost:5000/swagger to see all available endpoints with AI-optimized descriptions.
In Development mode without an OIDC Authority configured, authentication is bypassed with full admin access. See Authentication to set up proper auth for production.
MCP for AI Assistants¶
Adsify includes a built-in Model Context Protocol (MCP) server that lets AI assistants interact with PLCs through natural language.
Enable the MCP server in your configuration:
{
"Features": {
"Mcp": { "Enabled": true }
}
}
Then configure your AI assistant to connect to the /mcp endpoint. See the MCP Server documentation for client setup instructions and the full list of available tools and resources.
Try asking your AI assistant: “List all PLCs and show their status.”