industrial-mcp

industrial-mcp

An MCP server that gives Claude (or any MCP-compatible AI host) read access to industrial sensor data and safety-gated control over motors and actuators.

Category
Visit Server

README

industrial-mcp

An MCP server that gives Claude (or any MCP-compatible AI host) read access to industrial sensor data and safety-gated control over motors and actuators.

The hard part of Physical AI isn't getting a language model to talk about a factory — it's getting it to act on one without anyone losing sleep. That requires three boring things working together:

  1. Tool schemas the model can understand and call correctly.
  2. Safety preconditions that block dangerous actions even when the model is confident.
  3. An audit trail that survives the next post-mortem.

This repo is a working implementation of all three, in under 500 lines of Python, using FastMCP. Default mode is read-only and ships with a deterministic mock adapter modeling a 7-silo grain storage facility, so it runs in CI with no infrastructure.


Architecture

┌─────────────────────────────────────────────────────────────────────┐
│  MCP host  (Claude Desktop, Claude Code, Cursor, etc.)              │
│   user prompt ──► model decides which tool to call                  │
└──────────────────────────────┬──────────────────────────────────────┘
                               │  stdio  (JSON-RPC over MCP)
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│  industrial-mcp  (this repo)                                        │
│                                                                     │
│   server.py ── wires tools, env config, audit log                   │
│      │                                                              │
│      ├── tools.py ── 5 read tools + 1 write tool (dry-run default)  │
│      │                                                              │
│      ├── safety.py ── preconditions, advisory warnings              │
│      │                                                              │
│      ├── audit.py ── append-only JSONL of executed actions          │
│      │                                                              │
│      └── adapters/                                                  │
│            ├── mock.py    ← default, deterministic demo data        │
│            ├── mqtt.py    ← (your impl) live ESP32 fleet            │
│            └── rest.py    ← (your impl) thin REST adapter           │
└──────────────────────────────┬──────────────────────────────────────┘
                               │
            ┌──────────────────┼──────────────────┐
            ▼                  ▼                  ▼
   [MQTT broker]      [internal REST API]   [historian / TSDB]

Quick start

Run the server, talk to it from Claude Desktop, see it work.

# 1. Run the server with the mock adapter (no infra required)
uvx industrial-mcp@latest

# 2. Add this to ~/Library/Application Support/Claude/claude_desktop_config.json
#    (macOS) — see examples/claude-desktop-config.json

Then in Claude Desktop:

¿Qué silos tienen alerta crítica hoy?

Claude calls list_plantsget_active_alerts → answers with the data. See examples/demo-transcript.md for a full session.

To enable live (non-dry-run) execution against the mock adapter:

INDUSTRIAL_MCP_ALLOW_WRITES=true uvx industrial-mcp@latest

This flag does not affect dry runs — those always work. It only unlocks the path where a tool call would actually mutate state.


Tools exposed over MCP

Tool Type Purpose
list_plants read List facilities the server can see.
list_silos read Silos at a plant with capacity in tons.
get_silo_thermometry read Latest thermometry snapshot (min/avg/max °C).
list_motors read Motors at a plant, optionally filtered by kind.
get_active_alerts read Active alerts, filterable by severity.
trigger_motor_action write Start/stop a motor — dry-run by default, safety-gated, audited.

Tool schemas live in src/industrial_mcp/tools.py. Keep their docstrings short and exact — they become the model's tool descriptions.


Why three layers of safety, not one

trigger_motor_action will only execute when all of the following hold:

  1. The LLM explicitly sets dry_run=False.
  2. The call includes an operator_id and a reason.
  3. The server itself was started with INDUSTRIAL_MCP_ALLOW_WRITES=true.
  4. Every precondition in safety.evaluate_motor_action passes.

Step 3 is the one that matters most. The model can hallucinate dry_run=False; the operator field can be spoofed by a clever prompt; the safety check can have a bug. But if the server was started read-only, none of that touches a motor. The deploy posture is the last word, not the prompt.

Every executed call is appended to an append-only JSONL audit log:

{"ts": 1779600000.12, "actor": "op-42", "action": "motor.start",
 "target": "fan-7-1", "outcome": "applied",
 "details": {"reason": "silo-7 at 32.1°C, manual fan-on"}}

Dry runs are not logged. They're not interesting and they'd dilute the signal.


Adapters

The mock adapter ships in src/industrial_mcp/adapters/mock.py and is the only one wired in the scaffold. It produces deterministic data so CI and demos behave identically.

To talk to a real plant, drop a sibling module (e.g. mqtt.py) implementing the same surface — list_plants, list_silos, get_silo_thermometry, list_motors, get_motor, get_plant_context, get_active_alerts, apply_motor_action — and select it with INDUSTRIAL_MCP_ADAPTER=mqtt.

A reference MQTT adapter (HiveMQ-compatible, paho-mqtt) is the next issue in the tracker.


Development

git clone https://github.com/brayangcastro/mcp-industrial-agent
cd mcp-industrial-agent
uv sync --extra dev
uv run pytest -v
uv run ruff check src tests

CI runs the same two commands on Python 3.11 and 3.12 — see .github/workflows/ci.yml.


FAQ

Why not just give the model raw API keys? Because then every prompt injection is one HTTP call away from a production motor. The MCP surface is narrow on purpose: the model sees six functions, not your AWS console.

Why a separate dry_run flag instead of a confirmation step? Confirmation steps add latency and break flow. The dry run returns the outcome the model would have caused — preconditions, warnings, state delta — as data the model can keep reasoning over. Live execution is then a one-line escalation, not a five-prompt dance.

Is the audit log enough for compliance? No. It's enough to reconstruct what happened. It is not enough on its own for IEC 62443, IATF 16949, or similar. Pair it with your plant's existing change-management system; this repo is a starting point, not a finished compliance story.

Mock adapter only? Where's MQTT / OPC UA? This scaffold deliberately stops at the shape of the surface. Real adapters belong in a follow-up issue and are usually plant-specific anyway — the broker URLs, topic structures, and ACLs you can publish publicly are usually zero.


Status

Active scaffold, not yet 1.0. The shapes are stable; expect breaking changes in non-public APIs until the first MQTT adapter lands.

Author

Built and maintained by Brayan Castro — Ing. Mecatrónica (ITESM Sonora Norte), operating BC Ingeniería from Guasave, Sinaloa. Background: 4+ years building IoT systems for agroindustrial grain handling (firmware ESP32 + thermocouple MUX + cloud), backend services for property management and POS, and conversational AI agents on top of Claude / GPT-4o. Reach out: info@ingebc.com.

License

MIT — see LICENSE.

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