ESP32MCPServer: Connect AI Agents to Real-World Sensors
Architecture diagram showing an AI agent connecting over WebSocket to the ESP32 MCP server, which reads I2C sensors, parses NMEA 0183 and NMEA 2000 bus data, decodes OBD-II frames, and stores history in LittleFS.
- ESP32-S3-DevKitC-1
- ESP32-DevKitC V4
- ESP32-C3-DevKitM-1
- Adafruit HUZZAH32
- M5Stack Core ESP32
- Nordic nRF52840-DK
- Adafruit Feather nRF52840
- BME280 breakout
- MPU6050 breakout
- TJA1050 CAN transceiver
- SN65HVD230 CAN transceiver
- GPS module (3.3 V UART)
- 4.7 kΩ resistors
What You Will Build
This project puts a Model Context Protocol (MCP) server directly on an ESP32. MCP is the open standard that AI assistants use to call external tools and read live data — the same mechanism that lets a chatbot search the web or query a database. Here, the "database" is your physical hardware.
Once flashed, your ESP32 advertises itself on your WiFi network and listens on WebSocket port 9000 for JSON-RPC 2.0 requests. Any MCP-compatible AI agent can then call methods to scan I2C sensors, read temperature and humidity, parse NMEA 0183 GPS sentences from a chart plotter or GPS module, decode NMEA 2000 marine CAN bus frames (position, heading, depth, wind, water temperature), or pull live OBD-II diagnostics from a vehicle's CAN bus — all without any cloud service in the middle.
Practical uses range from asking an AI assistant what the engine RPM is, to letting an agent log marine conditions at anchor, to building a smart home sensor hub that an AI automation pipeline can interrogate on demand.
What You Need
Hardware (from the project's bill of materials):
| Part | Purpose |
|---|---|
| ESP32-S3-DevKitC-1 | Main MCU — recommended for full feature support |
| BME280 breakout | Temperature, humidity, pressure |
| MPU6050 breakout | 6-axis IMU (optional) |
| TJA1050 or SN65HVD230 | CAN bus transceiver — needed for NMEA 2000 or OBD-II (optional) |
| GPS module (3.3 V UART) | NMEA 0183 position and time (optional) |
| 2 × 4.7 kΩ resistors | I2C pull-ups |
| Breadboard and jumpers | — |
Other supported ESP32 boards (ESP32-DevKitC V4, ESP32-C3-DevKitM-1, Adafruit HUZZAH32, M5Stack Core) work for WiFi and I2C use cases, though the M5Stack does not support CAN. Nordic nRF52840-DK and Adafruit Feather nRF52840 boards run in sensor-only mode (no WiFi, no MCP server).
Software prerequisites:
- PlatformIO Core CLI or the PlatformIO IDE plugin for VS Code
- Python 3.8+
- Git
Install PlatformIO with:
pip install platformio
Typical use cases
Connect the ESP32 to an NMEA 2000 backbone and let an AI agent answer questions about vessel position, depth, wind, and water temperature in natural language.
Wire a CAN transceiver to an OBD-II port and give an AI agent access to engine RPM, vehicle speed, and over 60 decoded OBD-II PIDs for real-time monitoring.
Auto-scan up to six I2C sensor types — temperature, humidity, pressure, IMU, light, and current — and expose them all through a single MCP endpoint for any AI automation pipeline.
Run the MCP server on your LAN with mDNS discovery so any MCP-compatible AI agent on the same network can find and query your hardware sensors without cloud dependencies.
How It Works
The firmware runs several cooperating subsystems inside the ESP32:
- MCP Server — listens on WebSocket port 9000, parses JSON-RPC 2.0 requests, and routes them to the correct subsystem.
- Sensor Manager — auto-scans the I2C bus on demand and loads drivers for detected devices (BME280, MPU6050, ADS1115, SHT31, BH1750, INA219).
- Bus Reader — performs time-bounded reads from UART (NMEA 0183) or the CAN TWAI peripheral (NMEA 2000 / OBD-II), returning raw or parsed JSON.
- Bus History — stores frames and messages in circular RAM buffers backed by LittleFS, so an AI agent can replay recent bus traffic even if it connects after the fact.
- Network Manager — handles the WiFi access point setup UI (port 80) and station mode, storing credentials in NVS flash.
- Discovery Manager — announces the server via mDNS (
_mcp._tcp) and UDP broadcast so clients can find it automatically.
An AI agent connects once with initialize, calls resources/list to discover what is available, then issues sensors/read or bus/history/read calls as needed. Subscriptions are also supported for push-based updates.
Wiring and Build
Pin assignments for the ESP32-S3-DevKitC-1:
| GPIO | Function | Connect to |
|---|---|---|
| IO8 | I2C SDA | All I2C sensors |
| IO9 | I2C SCL | All I2C sensors |
| IO16 | UART1 RX | GPS / chart plotter TX |
| IO17 | UART1 TX | GPS / chart plotter RX (optional) |
| IO4 | CAN RX | TJA1050 / SN65HVD230 CRXD |
| IO5 | CAN TX | TJA1050 / SN65HVD230 CTXD |
All I2C sensors share one bus. Add 4.7 kΩ pull-up resistors from SDA and SCL to 3.3 V. If your GPS or chart plotter outputs RS-232 levels instead of 3.3 V TTL, use a MAX3232 level shifter — never connect RS-232 directly to ESP32 GPIO. NMEA 2000 runs at 250 kbps; OBD-II runs at 500 kbps — set the correct baud rate in your CANBusReader configuration.
Clone, build, and flash:
# 1. Clone the repository
git clone https://github.com/navado/ESP32MCPServer.git
cd ESP32MCPServer
# 2. Install library dependencies
pio pkg install
# 3. Upload web assets to LittleFS (optional but recommended)
pio run -t uploadfs -e esp32-s3-devkitc-1
# 4. Build firmware
pio run -e esp32-s3-devkitc-1
# 5. Flash
pio run -t upload -e esp32-s3-devkitc-1
# 6. Monitor serial output
pio device monitor --baud 115200
For nRF52840 sensor-only targets:
pio run -e nrf52840-dk
pio run -t upload -e nrf52840-dk
Replace esp32-s3-devkitc-1 with any supported PlatformIO environment name from the board table (esp32-devkitc, esp32-c3-devkitm-1, adafruit-huzzah32, m5stack-core) to target a different board.
First Connection and Testing
After flashing:
- Power on the board. It broadcasts a WiFi access point named
ESP32_XXXXXXwhere the last six characters are the MAC address suffix. - Connect your computer or phone to that AP and open
http://192.168.4.1in a browser. - Enter your WiFi credentials and click Save. The board reboots into station mode and prints its assigned IP address on the serial monitor.
- Point an MCP client at
ws://<IP>:9000.
The web dashboard at http://<IP>/app gives you four tabs without needing an AI agent: Sensors (scan the I2C bus and see live readings), Metrics (heap, uptime, RSSI), Logs, and MCP Console (an interactive JSON-RPC console with preset requests).
To test the MCP interface directly, send an I2C scan request:
{"jsonrpc":"2.0","method":"sensors/i2c/scan","id":1}
The server responds with detected devices and their supported parameters. Then read a specific sensor:
{"jsonrpc":"2.0","method":"sensors/read","id":2,"params":{"sensorId":"bme280_0x76"}}
For bus history, query recent CAN frames or decoded NMEA 2000 messages:
{"jsonrpc":"2.0","method":"bus/history/read","id":3,"params":{"type":"nmea2000"}}
All responses follow JSON-RPC 2.0 and include units, timestamps, and validity flags.
Ideas to Extend It and Known Limitations
Ways to go further:
- Marine AI assistant — pair with an AI agent to answer natural-language queries about your vessel's position, depth, wind speed, and water temperature in real time from the NMEA 2000 backbone.
- Vehicle diagnostics chatbot — connect to an OBD-II CAN transceiver and let an AI agent monitor engine RPM, vehicle speed, and 60+ other PIDs, then flag anomalies in plain language.
- Multi-sensor data logger — use bus history ring buffers and LittleFS persistence to have an AI agent replay and summarize sensor trends over time without a separate logging server.
- nRF52840 sensor node — run the nRF52840 target as a low-power I2C and UART sensor node, bridge its UART output to an ESP32-C3 in AT-command mode for WiFi uplink, as described in the README.
- Home automation integration — the mDNS and UDP discovery means any automation platform on your LAN that speaks MCP can find and query the device automatically.
Limitations to be aware of:
- The nRF52840 targets have no WiFi, no MCP server, no LittleFS, and no bus history — they output sensor data over serial only.
- M5Stack Core does not support CAN/TWAI, so NMEA 2000 and OBD-II are unavailable on that board.
- If your GPS or marine instrument uses RS-232 signal levels, you must add a MAX3232 level shifter before connecting to ESP32 UART pins.
- Bus history buffer sizes are limited by available RAM; the configuration can be tuned via
bus/history/config/setbut cannot exceed the board's heap.
ESP32MCPServer is a well-executed bridge between AI tooling and physical hardware, covering an unusually wide range of protocols — I2C, NMEA 0183, NMEA 2000, and OBD-II — under one consistent MCP interface. The PlatformIO build system, detailed wiring diagrams, and interactive web dashboard make it approachable for makers who are comfortable with embedded development. If you want AI agents to reason about the real world without a cloud intermediary, this is a solid foundation to build on.
Sources
github.comnavado/ESP32MCPServer — repository & READMEFacts in this article come from the project's public README and GitHub metadata at the time of writing. Images belong to their respective owners and link back to the original source.



