MCP Hub
Back to servers

IoT-Edge-MCP-Server

MCP server for Industrial IoT, SCADA and PLC systems. Unifies MQTT sensors, Modbus devices and industrial equipment into a single AI-orchestrable API. Features real-time monitoring, alarms, time-series storage and actuator control.

Stars
9
Forks
5
Tools
13
Updated
Dec 3, 2025
Validated
Jan 9, 2026

MseeP.ai Security Assessment Badge

🏭 IoT/Edge MCP Server

Production-ready MCP server for Industrial IoT, Edge Computing and SCADA/PLC systems.

Secure, enterprise-grade Model Context Protocol (MCP) server that exposes a unified tool interface over HTTP (FastAPI) and integrates MQTT + Modbus with InfluxDB (time-series) and Redis (cache).

Designed to work seamlessly with PolyMCP - enabling AI agents (Claude, OpenAI, Ollama, and more) to control industrial infrastructure through natural language.


Features

Core Capabilities

ProtocolDescription
MQTTIoT sensors and actuators (optional TLS)
Modbus TCP/RTUPLCs and industrial devices
InfluxDB 2.xTime-series data storage
RedisHigh-performance caching
Simulation ModeFull testing without hardware

Security-First Design (Production Mode)

  • Authentication: API key (X-API-Key) + JWT bearer tokens
  • Access Control: IP allowlisting (CIDR), rate limiting
  • Data Protection: Input validation, Fernet encryption, HMAC signatures
  • Audit Trail: Tamper-evident logging with HMAC chaining

Industrial Operations

  • Real-time sensor monitoring
  • Historical queries with aggregation (mean, max, min, sum, count, median)
  • Actuator command execution
  • PLC register / coil read-write
  • Multi-priority alarm system with acknowledge workflow
  • Device topology and system status reporting

Requirements

Simulation Mode (No external dependencies)

RequirementNotes
Python 3.8+3.9+ recommended

Production Mode

RequirementNotes
Python 3.8+3.9+ recommended
MQTT BrokerOptional if using Modbus only
InfluxDB 2.0+Optional, for historical data
RedisOptional, for caching
Modbus DevicesOptional, for PLC integration

Installation

# Clone repository
git clone https://github.com/yourusername/iot-mcp-server.git
cd iot-mcp-server

# Create virtual environment
python -m venv venv
source venv/bin/activate  # Windows: venv\Scripts\activate

# Install dependencies
pip install -r requirements.txt

📦 requirements.txt

# MCP Server Framework
polymcp>=1.2.6

# Web Framework
fastapi>=0.104.1
uvicorn[standard]>=0.24.0
pydantic>=2.5.0
docstring-parser>=0.15
python-multipart>=0.0.6

# Protocols (Production Mode)
paho-mqtt>=1.6.1
pymodbus>=3.5.2
pyserial>=3.5

# Storage (Production Mode)
redis>=5.0.1
influxdb-client>=1.38.0

# Configuration
pyyaml>=6.0.1

# Security (Production Mode)
bleach>=6.0.0
cryptography>=41.0.0
passlib[bcrypt]>=1.7.4
pyjwt>=2.8.0

# Monitoring (Production Mode)
prometheus-client>=0.19.0

📦 requirements-sim.txt (Simulation Only)

# Minimal dependencies for simulation mode
polymcp>=1.2.6
fastapi>=0.104.1
uvicorn[standard]>=0.24.0
pydantic>=2.5.0
docstring-parser>=0.15

⚠️ Note: This project uses Pydantic v2 APIs. Pydantic v1 is not supported.


🚀 Quick Start

Option 1: Simulation Mode (No Hardware Required)

Perfect for testing and development:

python IoT_mcp_sim.py

Output:

============================================================
IoT/Edge MCP Server - MODALITÀ SIMULAZIONE
============================================================

Dispositivi simulati disponibili:
- 10 Sensori
- 6 Attuatori
- 1 PLC Modbus

Server in ascolto su http://localhost:8000
Documentazione API: http://localhost:8000/docs
============================================================

Option 2: Production Mode (Real Hardware)

# Set required environment variables
export IOT_ENV=production
export JWT_SECRET_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
export ENCRYPTION_KEY=$(python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())")
export AUDIT_HMAC_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
export MQTT_COMMAND_HMAC_KEY=$(python -c "import secrets; print(secrets.token_urlsafe(32))")
export ALLOWED_IP_RANGES="10.0.0.0/8,192.168.0.0/16"
export API_KEYS='{"admin":"your-secure-api-key"}'

# Start server
python IoT_mcp.py

Default bind: http://0.0.0.0:8000


🤖 Using with PolyMCP

This MCP server is designed to work seamlessly with PolyMCP - a powerful framework for orchestrating MCP servers with AI agents.

Install PolyMCP

pip install polymcp>=1.2.8

Example: AI-Controlled Industrial System

#!/usr/bin/env python3
"""IoT MCP Chat - Control industrial equipment with AI"""
import asyncio
from polymcp.polyagent import UnifiedPolyAgent, OllamaProvider

async def main():
    # Initialize your LLM provider
    llm = OllamaProvider(model="llama3.1:8b", temperature=0.1)
    
    # Connect to IoT MCP server
    agent = UnifiedPolyAgent(
        llm_provider=llm, 
        mcp_servers=["http://localhost:8000/mcp"],  
        verbose=True
    )
    
    async with agent:
        print("✅ IoT MCP Server connected!\n")
        
        # Chat loop
        while True:
            user_input = input("\n🏭 You: ")
            
            if user_input.lower() in ['exit', 'quit']:
                print("Goodbye!")
                break
            
            result = await agent.run_async(user_input, max_steps=5)
            print(f"\n🤖 System: {result}")

if __name__ == "__main__":
    asyncio.run(main())

Using with Different LLM Providers

PolyMCP supports multiple LLM providers out of the box:

Ollama (Local)

from polymcp.polyagent import UnifiedPolyAgent, OllamaProvider

llm = OllamaProvider(model="llama3.1:8b", temperature=0.1)
agent = UnifiedPolyAgent(llm_provider=llm, mcp_servers=["http://localhost:8000/mcp"])

OpenAI

from polymcp.polyagent import UnifiedPolyAgent, OpenAIProvider

llm = OpenAIProvider(model="gpt-4", api_key="your-api-key")
agent = UnifiedPolyAgent(llm_provider=llm, mcp_servers=["http://localhost:8000/mcp"])

Anthropic Claude

from polymcp.polyagent import UnifiedPolyAgent, AnthropicProvider

llm = AnthropicProvider(model="claude-3-5-sonnet-20241022", api_key="your-api-key")
agent = UnifiedPolyAgent(llm_provider=llm, mcp_servers=["http://localhost:8000/mcp"])

Example Natural Language Commands

Once connected, you can ask the AI agent to:

CommandWhat it does
"Check all temperature sensors"Reads values from all temp sensors
"What's the average pressure in tank 1 over the last 6 hours?"Queries historical data with aggregation
"Open the main valve to 75%"Executes actuator command
"Show me all critical alarms"Lists active alarms filtered by priority
"Read Modbus registers 0-10 from PLC 01"Direct PLC communication
"If temperature exceeds 50°C, alert me"Conditional monitoring
"Generate a status report"Gets system topology and status

That's it! PolyMCP handles all the complexity of:

  • Tool discovery and selection
  • Multi-step industrial process automation
  • Real-time monitoring and alerting
  • Complex decision logic implementation

📡 MCP HTTP API

This server exposes MCP tools through HTTP endpoints provided by polymcp-toolkit:

EndpointMethodDescription
/mcp/list_toolsGETList all available tools
/mcp/invoke/{tool_name}POSTInvoke a tool (JSON body)
/healthGETHealth check
/metricsGETPrometheus metrics (production)
/docsGETOpenAPI documentation

🛠️ Available MCP Tools

📊 Sensor Operations

ToolParametersDescription
read_sensorsensor_idRead current value from a sensor
read_multiple_sensorssensor_ids (list)Batch read multiple sensors
get_sensor_historysensor_id, hours, aggregationQuery historical data (max 168h)

⚡ Actuator Control

ToolParametersDescription
execute_actuator_commandactuator_id, command, parametersSend command to actuator

🖥️ Device Management

ToolParametersDescription
get_device_topology-View complete system architecture
list_devicesdevice_type (optional)List devices filtered by type
get_system_status-System health and statistics

🚨 Alarm Management

ToolParametersDescription
get_active_alarmspriority (optional)View active alarms
acknowledge_alarmalarm_idAcknowledge an alarm

🔧 Modbus Operations

ToolParametersDescription
read_modbus_registersdevice_id, address, countRead holding registers
write_modbus_registerdevice_id, address, valueWrite single register

Production mode adds:

ToolParametersDescription
read_modbus_coilsdevice_id, address, countRead coils (digital inputs)
write_modbus_coildevice_id, address, valueWrite single coil

🎮 Simulated Devices

In simulation mode, the following devices are available for testing:

Sensors

IDTypeLocation
temp_sensor_01Temperatureproduction_line_1
temp_sensor_02Temperatureproduction_line_2
humidity_sensor_01Humidityroom_a
pressure_sensor_01Pressuretank_1
pressure_sensor_02Pressuretank_2
flow_sensor_01Flowmain_pipe
level_sensor_01Leveltank_1
vibration_sensor_01Vibrationmotor_1
current_sensor_01Currentmotor_1
voltage_sensor_01Voltagemain_panel

Actuators

IDTypeCommands
valve_01Valveopen, close, set_position
valve_02Valveopen, close, set_position
pump_01Pumpon, off, set_speed
motor_01Motorstart, stop, set_speed
motor_02Motorstart, stop, set_speed
relay_01Relayon, off

PLC

IDTypeRegisters
plc_01Modbus PLC0-99 (simulated)

🔧 Production Configuration

🔑 Environment Variables

Required for Production (IOT_ENV=production)

export IOT_ENV=production
export JWT_SECRET_KEY="your-jwt-secret"
export ENCRYPTION_KEY="your-fernet-key"
export AUDIT_HMAC_KEY="your-audit-hmac-key"
export MQTT_COMMAND_HMAC_KEY="your-mqtt-hmac-key"

Strongly Recommended

export ALLOWED_IP_RANGES="10.0.0.0/8,192.168.0.0/16"
export API_KEYS='{"monitoring":"key1","automation":"key2"}'

Optional Configuration

# MQTT
export MQTT_BROKER="localhost"
export MQTT_PORT="8883"
export MQTT_USE_TLS="true"
export MQTT_USERNAME="user"
export MQTT_PASSWORD="password"

# InfluxDB
export INFLUX_URL="https://localhost:8086"
export INFLUX_TOKEN="your-token"
export INFLUX_ORG="iot"
export INFLUX_BUCKET="sensors"

# Redis
export REDIS_HOST="localhost"
export REDIS_PORT="6379"
export REDIS_PASSWORD="redis-password"

# Rate Limits
export MAX_REQUESTS_PER_MINUTE="60"
export MAX_COMMANDS_PER_MINUTE="10"

🔐 Generating Keys

# ENCRYPTION_KEY (Fernet)
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"

# JWT_SECRET_KEY / AUDIT_HMAC_KEY / MQTT_COMMAND_HMAC_KEY
python -c "import secrets; print(secrets.token_urlsafe(32))"

📄 Configuration File

Create iot_config.yaml:

mqtt:
  broker: localhost
  port: 8883
  use_tls: true
  ca_cert: /path/to/ca.crt
  client_cert: /path/to/client.crt
  client_key: /path/to/client.key
  username: iot_user
  password_encrypted: null

modbus:
  devices:
    - device_id: plc_01
      type: tcp
      host: 192.168.1.100
      port: 502
      unit: 1
      max_read_registers: 100
      allowed_addresses: [0, 1, 2, 3, 4, 5]

devices:
  mqtt:
    - id: temp_sensor_01
      name: "Temperature Sensor Zone A"
      type: sensor
      topic: sensors/zone_a/temperature
      metadata:
        sensor_type: temperature
        unit: celsius

    - id: valve_01
      name: "Main Water Valve"
      type: actuator
      topic: actuators/valves/main

🏗️ Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         AI Agent                                 │
│              (Claude / OpenAI / Ollama / etc.)                   │
└────────────────────────────┬────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────┐
│                          PolyMCP                                 │
│                (Tool Discovery & Orchestration)                  │
└────────────────────────────┬────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────┐
│                     IoT MCP Server                               │
│                  (FastAPI + polymcp-toolkit)                     │
└────────────────────────────┬────────────────────────────────────┘
                             │
         ┌───────────────────┼───────────────────┐
         │                   │                   │
         ▼                   ▼                   ▼
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
│  MQTT Connector │ │ Modbus Connector│ │   Data Store    │
│  (TLS, HMAC)    │ │ (TCP/RTU)       │ │ (Influx+Redis)  │
└────────┬────────┘ └────────┬────────┘ └─────────────────┘
         │                   │
         ▼                   ▼
┌─────────────────┐ ┌─────────────────┐
│  IoT Sensors &  │ │  PLCs & RTUs    │
│   Actuators     │ │                 │
└─────────────────┘ └─────────────────┘

🔐 Security Model (Production)

Request Flow

Incoming Request
       │
       ▼
┌─────────────────┐
│ Payload Size    │ → 413 if > 1MB
│ Check           │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Public Path?    │ → /health, /metrics allowed
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ IP Allowlist    │ → 403 if not in CIDR range
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Rate Limit      │ → 429 if exceeded
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Authentication  │ → 401 if invalid
│ (API Key / JWT) │
└────────┬────────┘
         │
         ▼
┌─────────────────┐
│ Tool Execution  │
└─────────────────┘

Rate Limiting

TypeScopeDefault Limit
HTTP RequestsPer IP60/minute
Actuator CommandsGlobal10/minute
Modbus OperationsPer device10/minute

🐛 Troubleshooting

Common Errors

ErrorCodeSolution
Service not ready503Wait for startup; check logs
IP not allowed403Add IP to ALLOWED_IP_RANGES
Unauthorized401Check API key or JWT
Rate limit exceeded429Reduce frequency
Sensor not found400Check list_devices() for valid IDs

Debug Commands

# Check health
curl http://localhost:8000/health

# List available tools
curl http://localhost:8000/mcp/list_tools

# View logs
tail -f iot_mcp_server.log

💡 Use Cases

Use CaseDescription
Smart FactoryAI-driven production line optimization
Building AutomationIntelligent HVAC and lighting control
Energy ManagementReal-time consumption monitoring
Predictive MaintenanceEquipment failure prediction
Quality ControlAutomated anomaly detection
Emergency ResponseAI-managed incident handling

📝 License

MIT License - See LICENSE file


🤝 Contributing

  1. Fork the repository
  2. Create a branch: git checkout -b feature/my-feature
  3. Commit changes: git commit -m "Add my feature"
  4. Push branch: git push origin feature/my-feature
  5. Open a Pull Request

🔗 Related Projects


💡 Why This Project?

This MCP server bridges Industrial IoT and AI agents. With PolyMCP, you can:

  1. Natural Language Control - "Check all pressure sensors and alert if any are abnormal"
  2. Complex Automation - AI orchestrates multi-step industrial processes
  3. Predictive Maintenance - AI analyzes trends and predicts failures
  4. Energy Optimization - AI optimizes equipment usage
  5. Incident Response - AI handles alarms and executes emergency procedures

No complex industrial protocols to learn - PolyMCP and AI handle everything!


⚠️ Production Deployment: Always use strong secrets, proper network isolation, and TLS termination via reverse proxy.


Designed for PolyMCP 🚀

Star ⭐ this repo if you find it useful!

Reviews

No reviews yet

Sign in to write a review