acm_mcp

acm_mcp

MCP server for building Rockwell Automation PLC project plans by browsing the ACM catalog, resolving library dependencies, and assembling project hierarchies with automatic placement.

Category
Visit Server

README

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 8012

The 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.

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 limit

Populating 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
pull_libraries Runs ACMConsole to export registered libraries (HSL4 files) into the working directory ExportRegisteredLibraries()
pull_templates Converts exported HSL4 files into XML templates using ACMTemplateGen.CLI.exe ParseHSL4IntoTemplate()
pull_database Clears and rebuilds data.db by parsing templates, extracting parameters, decoding PDF docs, and linking everything fillDatabase()

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: true

Then start the server:

uv run python server.py

This 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: false

This 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 resolve_library 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_libraries Search the catalog by text query, LibraryType, Category, or ContentType.
3 fuzzy_search_libraries Fuzzy name search across the catalog. Use when you have an approximate or misspelled name. Returns results ranked by similarity score.
4 list_controllers List all available controller types (plain and MachineBuilder variants).
5 add_controller Add a controller as the root node. Accepts optional parameter_overrides (JSON string). MachineBuilder controllers auto-create pre-built tasks.
6 add_task Create an empty task under a controller (PERIODIC, EVENT, or CONTINUOUS).
7 add_program Create an empty program under a task.
8 add_item Add a library item with automatic placement. AOI dependencies are auto-registered; all other dependencies appear in todo for explicit linking via resolve_link.
9 resolve_link Bind an unresolved dependency on a node to a specific instance in the project. Replaces resolve_select — works with all link types (REQUIRED, SELECT, CONDITIONAL-MET, OPTIONAL).
10 get_unresolved_links List all unresolved dependency links across the entire project, with existing instances that match each link's candidates.
11 remove_item 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 get_project_views Render the project as two text trees: Class View (by type) and Preview (hierarchy).
13 get_project_state Get the full project state as structured JSON.
14 rename_instance Rename any node in the project.
15 set_project_name Set the project name (used as filename on export).
16 export_project Save the project state to projects/{name}/{name}.json.
17 load_project Load a previously saved project from disk.
18 list_projects List all saved project files.
19 instantiate_in_acm 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 export_acd for that.
20 export_acd Export the ACM project to an ACD file. Must be called after instantiate_in_acm.
21 reset_project Reset the project, clearing all in-memory state. Use export_project first to save work.

Typical Workflow

  1. Server injects planning context automatically via FastMCP instructions (loaded from prompts/context_injection.md)
  2. Client clarifies vague requests before making tool calls — asks the user what they want, where it goes, and any configuration choices
  3. Client searches the catalog with search_libraries, fuzzy_search_libraries, or list_controllers — presents results to user, never assumes first match
  4. Client calls resolve_library to inspect dependencies before committing
  5. Client adds a controller with add_controller
  6. Client creates tasks/programs with add_task / add_program (required for plain controllers; MachineBuilder controllers come with pre-built tasks)
  7. Client adds library items with add_item — placement is automatic, AOI dependencies are auto-registered
  8. Client presents todo items to the user for each add_item response — never silently resolves links
  9. Client adds all needed items (in any order), then resolves dependencies with resolve_link after presenting binding choices to the user
  10. Client calls get_unresolved_links to see all pending dependencies across the project
  11. Client calls get_project_views after each change to show the user
  12. Client calls export_project to save (blocks if mandatory links are unresolved)
  13. Optionally, client calls instantiate_in_acm to instantiate the project in ACM, then export_acd to 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, or RESOLVED. 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_link explicitly. 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_item deletes 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_controller and add_item accept parameter_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 flagged is_prebuilt=True in 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_items in 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_project to 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 framework
  • pyyaml — Configuration loading
  • uvicorn — ASGI server for streamable-http transport
  • acm-browser — Local .whl for ACM library catalog extraction (SQLAlchemy + lxml)

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
E2B

E2B

Using MCP to run code via e2b.

Official
Featured
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured