Deep Dive: The MES AI Plugin Model

The plugin model is the architectural decision that most distinguishes MES AI from a conventional MES codebase. Rather than hard-coding integrations and site-specific behaviors into a monolithic core, MES AI delegates them to plugins that the platform discovers, loads, and manages at runtime. This post walks through how that system works from a technical standpoint.

Why Plugins?

Every manufacturing site is different. The ERP system might be SAP, Oracle, or a custom in-house system. Equipment might speak OPC UA, Modbus, MQTT, Kafka, or a proprietary protocol. Dispatch priority rules vary by plant type and business process. Storing all of these variations in the core codebase with complex configurations creates a maintenance burden and makes upgrades risky. Plugins move the variation to the edges, where it belongs.

Plugin Structure

Each plugin lives in its own directory under server/plugins/. A plugin directory contains:

A minimal manifest looks like this:

id: oracle-erp-simulator
name: Oracle ERP Simulator
version: 1.0.0
category: erp
extension_points:
  - type: erp_inbound
    class: oracle_erp_simulator_inbound
  - type: erp_outbound
    class: oracle_erp_simulator_outbound

The Plugin Manager

The PluginManager is the central runtime coordinator. At server startup it scans the system and user plugin directories, parses each manifest, and instantiates the corresponding plugin class. It then calls initialize and start in sequence, passing the configuration values from the manifest (or from the database if the plugin has been configured through the design-time UI).

The manager tracks each plugin's state — whether it is loaded, running, or faulted — and exposes that state through the /health endpoint and the design-time plugins page.

Adapter Resolution

When a server-side service or a route handler needs an ERP or equipment adapter, it asks the plugin manager rather than holding a direct reference to a plugin. The manager resolves the request by iterating running plugins in priority order:

  1. Preferred — a plugin whose ID matches the X-MES-ERP-PLUGIN request header.
  2. Primary — running plugins that provide the requested adapter type and are not simulators.
  3. Simulator — running plugins in the simulator bucket (ERP plugins whose ID ends in -simulator).

This ordering means a real ERP adapter takes precedence over a simulator when both are running, but a simulator is used automatically in development environments where no real adapter is configured. The /erp/simulator/options endpoint explicitly resolves against the simulator bucket, so the ERP simulator client app always talks to a simulator regardless of what other adapters are loaded.

Lifecycle and Health Checks

Each plugin implements health_check() -> bool. The platform calls this on a background schedule and surfaces the results on the /health endpoint. A plugin can fail its health check without being unloaded — the platform marks it as degraded and continues serving requests that do not depend on it. This is important in production, where a temporary ERP connectivity issue should not take down the entire MES server.

Adding a Plugin

Adding a new plugin does not require changes to the core. A developer creates a new directory under server/plugins/user/, writes a manifest and a plugin class, and restarts the server. The plugin manager picks it up automatically. If the plugin provides ERP adapters, the design-time plugins page will show it immediately; enabling it registers the adapters into the running pool.

This extensibility is what makes MES AI viable as a shared foundation for teams with different integration requirements. The core handles the universal concerns; the plugins handle the rest.