acm_mcp
Allows building PLC automation project plans using the Rockwell Automation Application Code Manager (ACM) library catalog, including browsing, resolving dependencies, and assembling project hierarchies.
Click on "Install Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@acm_mcpsearch for safety relay libraries"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
acm_mcp
MCP server for building PLC automation project plans using the Rockwell Automation ACM (Application Code Manager) library catalog.
An LLM client connects to this server to browse the ACM catalog, resolve linked library dependencies, and assemble a project hierarchy — controllers, tasks, programs, routines, and AOI definitions — with automatic placement rules and deduplication.
Quick Start
cd acm_mcp
uv sync # install dependencies (creates .venv)
uv run python server.py # start server on port 8012The server loads the library catalog from data/data.db on startup and exposes tools over streamable-http at http://127.0.0.1:8012/mcp.
Related MCP server: mcpdeployment
Configuration
All settings are in config.yaml:
server:
host: "127.0.0.1"
port: 8012
log_level: "INFO"
transport: "streamable-http"
ssl_certfile: "" # path to TLS cert for HTTPS (optional)
ssl_keyfile: "" # path to TLS key for HTTPS (optional)
acm_browser:
working_dir: "data" # relative to this directory
pull_libraries: false # set true to re-export from ACM
pull_templates: false
pull_database: false
resolver:
max_depth: 10 # linked library recursion limitPopulating the Database
The server relies on a SQLite database (data/data.db) built from ACM library exports. On startup, it reads the three pull_* flags in config.yaml to decide whether to re-run each step of the pipeline:
Flag | What it does | ACM Browser call |
| Runs ACMConsole to export registered libraries (HSL4 files) into the working directory |
|
| Converts exported HSL4 files into XML templates using |
|
| Clears and rebuilds |
|
First-time setup (no existing data.db)
Set all three flags to true in config.yaml to run the full pipeline:
acm_browser:
working_dir: "data"
pull_libraries: true
pull_templates: true
pull_database: trueThen start the server:
uv run python server.pyThis will export libraries from ACM, convert them to templates, and populate data.db. The process requires ACM to be installed on the machine.
Subsequent runs (data.db already exists)
Set all flags to false to skip re-export and reuse the existing database:
acm_browser:
working_dir: "data"
pull_libraries: false
pull_templates: false
pull_database: falseThis is the default configuration and makes startup much faster.
Refreshing the catalog
To pick up newly registered ACM libraries, set all three flags back to true and restart the server. You can also selectively re-run steps — for example, set only pull_database: true if you've manually updated template files and just need to rebuild the database.
Tools
# | Tool | Description |
1 |
| Preview a library's dependencies before adding it. Returns tiered results: tier_1_mandatory (REQUIRED, AOI_AUTO_ADDED, DEDUP, SELECT), tier_2_optional (user decides), tier_3_conditional (conditionals, SELECTs). |
2 |
| Search the catalog by text query, LibraryType, Category, or ContentType. |
3 |
| Fuzzy name search across the catalog. Use when you have an approximate or misspelled name. Returns results ranked by similarity score. |
4 |
| List all available controller types (plain and MachineBuilder variants). |
5 |
| Add a controller as the root node. Accepts optional |
6 |
| Create an empty task under a controller (PERIODIC, EVENT, or CONTINUOUS). |
7 |
| Create an empty program under a task. |
8 |
| Add a library item with automatic placement. AOI dependencies are auto-registered; all other dependencies appear in |
9 |
| Bind an unresolved dependency on a node to a specific instance in the project. Replaces |
10 |
| List all unresolved dependency links across the entire project, with existing instances that match each link's candidates. |
11 |
| Remove a node and all children (cascade). Automatically unresolves any links on remaining nodes that pointed to a removed node, restoring them to their original tag. Reports broken links in the response. |
12 |
| Render the project as two text trees: Class View (by type) and Preview (hierarchy). |
13 |
| Get the full project state as structured JSON. |
14 |
| Rename any node in the project. |
15 |
| Set the project name (used as filename on export). |
16 |
| Save the project state to |
17 |
| Load a previously saved project from disk. |
18 |
| List all saved project files. |
19 |
| Generate ACM XML scripts from an exported project JSON and invoke ACMConsole to instantiate the project in ACM. Uses separate BEGINCREATE/ENDCREATE blocks for project, controller, and objects so the controller's pre-built tasks are fully instantiated before objects reference them. Pre-built items (CLX auto-created tasks/programs) are excluded from the objects XML — their parent HSL4 definitions create them automatically. Does not generate an ACD file — use |
20 |
| Export the ACM project to an ACD file. Must be called after |
21 |
| Reset the project, clearing all in-memory state. Use |
Typical Workflow
Server injects planning context automatically via FastMCP
instructions(loaded fromprompts/context_injection.md)Client clarifies vague requests before making tool calls — asks the user what they want, where it goes, and any configuration choices
Client searches the catalog with
search_libraries,fuzzy_search_libraries, orlist_controllers— presents results to user, never assumes first matchClient calls
resolve_libraryto inspect dependencies before committingClient adds a controller with
add_controllerClient creates tasks/programs with
add_task/add_program(required for plain controllers; MachineBuilder controllers come with pre-built tasks)Client adds library items with
add_item— placement is automatic, AOI dependencies are auto-registeredClient presents
todoitems to the user for eachadd_itemresponse — never silently resolves linksClient adds all needed items (in any order), then resolves dependencies with
resolve_linkafter presenting binding choices to the userClient calls
get_unresolved_linksto see all pending dependencies across the projectClient calls
get_project_viewsafter each change to show the userClient calls
export_projectto save (blocks if mandatory links are unresolved)Optionally, client calls
instantiate_in_acmto instantiate the project in ACM, thenexport_acdto generate an ACD file
Project Structure
acm_mcp/
├── server.py # MCP server entry point (21 tools)
├── config.yaml # Server and ACM configuration
├── pyproject.toml # uv project definition
├── uv.lock # Locked dependencies
├── .python-version # Python 3.13
├── models/
│ ├── library.py # Library, PlacementRole, LinkedLibraryRef
│ └── project_state.py # InstanceNode, ProjectState tree
├── services/
│ ├── library_store.py # In-memory catalog with search indexes
│ ├── resolver.py # Recursive linked library resolution
│ ├── project_manager.py # Stateful project builder + export/load
│ └── renderer.py # Class View and Preview tree rendering
├── prompts/
│ └── context_injection.md # LLM planning context (loaded as FastMCP instructions)
├── data/
│ ├── data.db # SQLite catalog (524 libraries)
│ ├── Templates/ # 524 Template.xml source files
│ └── instance_templates/ # XML templates for ACD generation (project, controller, object)
└── projects/ # Saved project files (JSON)Key Concepts
Routine-First Thinking: The routine is the fundamental working piece — the function call that invokes the AOI (the function definition). When a user asks to "add a conveyor," start by finding the routine and work outward to program, task, and controller.
PlacementRole: Determined by ContentType + LibraryType. Controls where items go in the hierarchy (controller, task, program, routine, AOI).
Linked Library Resolution: Recursive (max depth 10) with explicit, generic (wildcard), template, and conditional resolution modes. Recursion only enters AOI_AUTO_ADDED dependencies — REQUIRED items get their own resolution when manually added, preventing transitive dependencies from leaking onto parent nodes as duplicate ILLib entries.
Dependency Tags: Each dependency gets one tag:
AOI_AUTO_ADDED,DEDUP,REQUIRED,OPTIONAL,CONDITIONAL-MET,CONDITIONAL-SKIP,CONDITIONAL-UNKNOWN,SELECT,TEMPLATE,NOT-FOUND, orRESOLVED. AOIs are auto-handled; all others require explicit user decisions.Instance-Level Binding: Links bind to specific project instances via
target_node_id, not catalog numbers. This supports many-to-many scenarios (e.g., multiple Equipment Modules linking to different Unit Modules).No Auto-Resolver: Dependencies are not silently resolved. The agent must present choices to the user and call
resolve_linkexplicitly. Items can be added in any order.AOI Deduplication: Asset-Control items are globally deduplicated — one definition serves all instances. Tier 1 and tier 3 condition-met AOIs are auto-registered; tier 2 AOIs require user confirmation.
Cascade Removal with Link Cleanup:
remove_itemdeletes the target node and all its children, then walks the remaining project tree to find any resolved links that pointed to a removed node. Those links are automatically unresolved and restored to their original tag (e.g., SELECT, REQUIRED). Broken links are reported in the response. Orphaned AOI definitions are not auto-removed — they must be cleaned up manually if no longer needed.Parameter Overrides: Both
add_controllerandadd_itemacceptparameter_overrides(JSON string). You may include parameters not present in the library definition — ACM will accept them if the names are valid. Parameter names are case-sensitive and must match exactly; incorrect casing causes ACM to silently ignore the parameter.MachineBuilder Controllers: Come with pre-built periodic tasks at various scan rates. Guard variants include a SafetyTask.
CLX Auto-Created Children: Some libraries (e.g.,
raM_Robot_Dvc_DeviceHandler) define CLX children — tasks and programs that ACM's HSL4 engine creates automatically during instantiation. These are flaggedis_prebuilt=Truein the project state and excluded from the objects XML to avoid conflicts with unresolvable substitution tokens (e.g.,{MotionGroupName},{RbtDvcItf$RobotName}). ACM resolves these tokens internally through its interface link chain.ACM Console Script Structure: The instantiation script uses separate BEGINCREATE/ENDCREATE blocks for project, controller, and objects. This ensures the controller's HSL4 fully executes (creating pre-built tasks like
ms0008p08,PowerUp_Handler,SafetyTask) before CREATEOBJECTS runs, allowing objects to reference those tasks as ParObj/Task.Export Ordering: The
catalog_itemsin exported JSON preserve insertion order (the order items were added by the user), not alphabetical order. This has no effect on ACM instantiation — ACM parses all objects into an insert list before processing — but reflects the logical build sequence.State: In-memory during the session. Use
export_project/load_projectto persist across sessions.
Client Configuration
{
"mcpServers": {
"acm_mcp": {
"command": "npx.cmd",
"args": [
"mcp-remote",
"http://127.0.0.1:8012/mcp",
"--allow-http"
]
}
}
}Dependencies
mcp[cli]— FastMCP frameworkpyyaml— Configuration loadinguvicorn— ASGI server for streamable-http transportacm-browser— Local .whl for ACM library catalog extraction (SQLAlchemy + lxml)
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
- Your AI Chatbot Just Exposed Your CEO's Salary to an InternBy Om-Shree-0709 on .Agent IdentityMCP SecurityOAuth Delegation
- Why MCP Servers Need Execution Sandboxing (And Why Your Current Stack Isn't Enough)By Om-Shree-0709 on .Agentic AiPrompt InjectionWebAssembly
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/DPBeahr-rok/acm_mcp'
If you have feedback or need assistance with the MCP directory API, please join our Discord server