-
Building an MCP Server on ESP32: Connecting AI Assistants to Real-World Devices
Connecting AI to the Physical World with Model Context Protocol
As detailed in StickyMCP: Notes That Stick, Even in the Cloud, MCP servers open the door for AI systems to interact with real-world tools far beyond their usual diet of static training data and existential boredom.
This project brings together two cutting-edge technologies: the Model Context Protocol (MCP) and Arduino Microcontroller. The result is an MCP server running directly on an Arduino Nano ESP32, allowing AI assistants control physical hardware in real-time.
(Some prompts were typed a bit wrong because I had the camera in the way, but Copilot Chat did not mind at all)
Since there is no MCP SDK for C++, I implemented the RPC protocol myself, kept it small and readable, and made it work to run simple tools like switching lights on and off.
What is it?
This project implements a fully-compliant JSON-RPC 2.0 MCP server on an Arduino Nano ESP32 microcontroller. It exposes hardware controls (LEDs in this case) as MCP "tools" that can be invoked by AI assistants through natural language commands.
Key Features
- MCP Protocol Support: Implements the MCP 2024-11-05 specification with proper initialization, tool listing, and tool execution
- JSON-RPC 2.0 Compliance: Standard protocol interface for reliable communication
- WiFi-Enabled: Runs a web server on port 8000, making it accessible over the network
- Server-Sent Events (SSE): Real-time notifications and logging stream for monitoring
- Multiple LED Controls: Manages built-in LED plus RGB LEDs (red, green, blue) independently
- Echo Tool: Simple text echo for testing and demonstration
Technical Implementation
The server uses the ESPAsyncWebServer library for handling HTTP requests and ArduinoJson for JSON parsing/serialization. It exposes two main endpoints:
POST /mcp- Main JSON-RPC 2.0 endpoint for all MCP methodsGET /sse- Server-Sent Events stream for real-time notifications
Each LED is implemented as an MCP tool with a simple boolean parameter to turn it on or off. The server handles all the MCP lifecycle methods including initialization, capability negotiation, and tool invocation.
Real-World Applications
This project demonstrates how AI assistants can seamlessly control physical devices. Instead of writing custom scripts or manual API calls, you can simply tell an AI assistant "turn on the red LED" and it happens. This opens up possibilities for:
- Smart home automation controlled by natural language
- Laboratory equipment control through AI assistants
- Educational demonstrations of AI-hardware integration
- Rapid prototyping of IoT devices with conversational interfaces
Technical Stack:
- Arduino Nano ESP32
- ESPAsyncWebServer
- ArduinoJson
- Model Context Protocol (MCP) 2024-11-05
- JSON-RPC 2.0
-
Seattle Skyline and Market on a Sunny Sunday
The day began bright and clear, the kind of winter light that makes everything sharp and calm. We drove toward Seattle with the skyline slowly rising ahead, glass and steel catching the sun as the streets narrowed into the heart of the city.
1/500s f/8 ISO 100/21° 16-50mm f/2,8 VR f=50mm/75mm
1/400s f/7,1 ISO 100/21° 16-50mm f/2,8 VR f=27mm/40mm
Pike Place Market was alive with its familiar rhythm. Old wooden storefronts and neon signs stood like markers of time, while the scent of coffee drifted through the crowd. Vendors called out, voices mingling with the hum of conversation, and for a moment it felt like the city was speaking in its own language.
1/500s f/8 ISO 200/24° 16-50mm f/2,8 VR f=50mm/75mm
1/250s f/5 ISO 200/24° 16-50mm f/2,8 VR f=31mm/47mm
1/125s f/2,8 ISO 400/27° 16-50mm f/2,8 VR f=16mm/24mm
1/125s f/2,8 ISO 900 16-50mm f/2,8 VR f=16mm/24mm
From the Overlook Walk, the view opened wide. The waterfront stretched below, ferries tracing slow lines across the bay, and behind it all the skyline stood still against the pale sky. The skyline panorama frames capture the city in one continuous sweep, holding its full breadth in a single image.
1/500s f/8 ISO 100/21° 16-50mm f/2,8 VR f=23mm/35mm
1/320s f/6,3 ISO 100/21° 16-50mm f/2,8 VR f=16mm/24mm
1/1000s f/5,6 ISO 100/21° 16-50mm f/2,8 VR f=18mm/27mm
1/400s f/7,1 ISO 100/21° 16-50mm f/2,8 VR f=16mm/24mm
1/500s f/8 ISO 100/21°
1/400s f/8 ISO 100/21°
1/800s f/5,6 ISO 100/21° 16-50mm f/2,8 VR f=16mm/24mm
1/400s f/7,1 ISO 100/21° 16-50mm f/2,8 VR f=35mm/52mm
1/500s f/8 ISO 100/21° f=16mm/17mm
1/400s f/7,1 ISO 100/21° 16-50mm f/2,8 VR f=16mm/24mm
On the way back, the Space Needle appeared again, sudden and familiar against the clear blue. One last glance, one last photo, and the day folded into the drive home: simple, bright, and easy to remember.
1/320s f/6,3 ISO 100/21° 16-50mm f/2,8 VR f=16mm/24mm
-
The Evolution of the Turkey 🦃
Every masterpiece begins in silence. The 👩🏻🍳 sets the stage, then time, heat and patience compose a quiet piece of culinary art.
Stage 1: Raw Ambition
A turkey in its natural state is like an unread book, full of potential, but mostly cold and uninviting. At this point, the only evolution is your growing doubt about oven size.
1/13s f/2,8 ISO 250/25° 16-50mm f/2,8 VR f=28mm/42mm
Stage 2: The Great Migration
It moves from countertop to oven, a journey as inevitable as Monday mornings. Here, transformation begins quietly under heat and time.
1/10s f/2,8 ISO 250/25° 16-50mm f/2,8 VR f=44mm/66mm
Stage 3: The Slow Enlightenment
Hours pass. The turkey meditates in 170°C silence, contemplating its purpose. It emerges wiser, crispier, and slightly golden, proof that patience and heat can turn blandness into brilliance.
1/40s f/3,2 ISO 250/25° 16-50mm f/2,8 VR f=50mm/75mm1
Stage 4: The Final Form
On the table, surrounded by sides and expectations, the turkey achieves peak relevance. For a brief moment, it is the influencer of the dining room. Then, like all trends, it is consumed and forgotten.
1/20s f/2,8 ISO 400/27° 16-50mm f/2,8 VR f=34mm/51mm
A picture impossible to make with a single exposure
1/25s f/2,8 ISO 400/27° 16-50mm f/2,8 VR f=27mm/41mm
The shallow depth of field creates a beautifully blurred background, something that gives the image its depth and character. To achieve sharpness across the entire plate without losing that blur, two shots were taken: one focused on the front, the other on the back of the plate and then combined using Focus Stacking
Simply stopping down the aperture for more depth of field would have rendered the plate sharp, but also flattened the scene, turning it into the kind of phone photo where the background looks lifeless. This blend keeps the plate crisp while preserving the softness behind it.
Back to the kitchen:
At first it hides its promise. Add time, heat, and a little seasoning and it becomes a quiet piece of culinary work.
-
Focused manually because autofocus would have locked on the oven glass instead of the turkey inside.
And absolutely no permission from the chef to open the oven for a quick snap. This picture had to be captured through the glass, in the heat and haze, without disturbing the masterpiece in progress. ↩
-
-
Nikon Z DX 16-50mm f/2.8 VR
The day Nikon announced their new DX 16-50mm f/2.8 lens2, I opened the optical upgrade protocol with a preorder 🚀
My previous lenses lined up for eBay, forming a support group titled "Former Stars of the Camera Bag". They successfully negotiated their exit strategy with descriptions that read like dating profiles: "Still sharp, loves sunsets, seeks photographer who appreciates vintage charm and no diffraction tests under f/8".
Inside the Upgrade Shop3
Announcement - October 16, 2025 📰
The new NIKKOR DX lens is available soon. Compact, fast, and ready to redefine the setup.
Optical upgrade protocol signaled.
Preorder - October 16, 2025 🛒
Optical upgrade protocol opened.
Shipping date: October 30, just in time for the Halloween magic4
Delivery - November 5, 2025 📦
Signature required delivery confirmed, package has achieved indoor status.
The First Light 🌅
Optical upgrade protocol in progress: lens mounted and ready for action.
Lens on a Z30 and Z50 IIThrough the New Lens
First Frames In: Precision and Agility from the Start
(All pictures taken with the Nikon Z50 II)1/160s f/6,3 ISO 100/21° 16-50mm f/2,8 VR f=16mm/24mm
1/320s f/2,8 ISO 100/21° 16-50mm f/2,8 VR f=23mm/35mm
1/125s f/5,6 ISO 100/21° 16-50mm f/2,8 VR f=50mm/75mm
1/160s f/5,6 ISO 100/21° 16-50mm f/2,8 VR f=32mm/48mm
1/3200s
f/2,8ISO 100/21° 16-50mm f/2,8 VRf=50mm/75mm1/400s f/2,8 ISO 100/21° 16-50mm f/2,8 VR f=50mm/75mm
1/80s f/6,3 ISO 100/21° 16-50mm f/2,8 VR f=25mm/37mm
1/640s
f/2,8ISO 100/21° 16-50mm f/2,8 VR f=50mm/75mm1/640s
f/11ISO 1600/33° 16-50mm f/2,8 VR f=50mm/75mm1/320s
f/16ISO 1600/33° 16-50mm f/2,8 VR f=50mm/75mm1/160s
f/22ISO 1600/33° 16-50mm f/2,8 VR f=50mm/75mm1/80s f/4 ISO 100/21° 16-50mm f/2,8 VR f=24mm/36mm
1/200s f/4 ISO 100/21° 16-50mm f/2,8 VR f=50mm/75mm
1/640s f/2,8 ISO 100/21° 16-50mm f/2,8 VR f=50mm/75mm
1/160s f/6,3 ISO 100/21° 16-50mm f/2,8 VR f=16mm/24mm
1/125s f/6,3 ISO 100/21° 16-50mm f/2,8 VR f=16mm/24mm
1/200s f/6,3 ISO 100/21° 16-50mm f/2,8 VR f=50mm/75mm
1/400s f/5,6 ISO 100/21° 16-50mm f/2,8 VR f=50mm/75mm
1/320s f/2,8 ISO 100/21° 16-50mm f/2,8 VR f=50mm/75mm
Why Does This Lens Show Strong Vignetting at 50mm f/2.8?
Observe the heavy vignetting at 50mm f/2.8, along with the visible distortion. Zoom in and it disappears. Left side is without correction, right side with correction using NX Studio.
The sample image shows noticeable darkening in the corners at 50mm and f/2.8. This effect is called vignetting and it is an unfortunate but common characteristic of optical design, especially in compact zoom lenses with a bright aperture.
The NIKKOR Z DX 16-50mm f/2.8 VR combines a constant f/2.8 aperture with a small, lightweight form factor. To achieve this, the front element is relatively small. At longer focal lengths and wide apertures, light rays entering from the edges are partially blocked, which results in corner shading.
Vignetting increases when the angle of light hitting the sensor becomes steeper, as happens when zooming in. Eliminating this effect completely would require much larger lens elements and a heavier construction. A lens designed to avoid vignetting at f/2.8 would be significantly bigger, heavier, and more expensive, which goes against the goal of a compact DX zoom.
For this reason, some level of vignetting is considered acceptable and is typically corrected in-camera or during post-processing. If you shoot RAW, most software applies lens profiles to fix this. For JPEGs, Nikon's vignette control can reduce the effect.
Protocol Complete ✅
Adding this lens makes the setup minimal and faster, ready for decisive moments.
The 16-50mm f/2.8 combines a constant aperture with a compact design for a balanced, practical setup. From landscapes to portraits, the zoom range provides complete framing control while keeping everything light and portable. No lens swaps, just a responsive system that adapts quickly. Vibration Reduction works together with the bright aperture to maintain sharp, balanced results even in challenging light.
-
Nikon also announced the NIKKOR Z DX MC 35mm f/1.7 on the same day. ↩
-
The Bag Chronicles
↩ -
Actually shipped November 3, no tricks, just treats 🎃
↩
-
-
Adobe RGB: Just Add _
Understanding Adobe RGB: When a Filename Starts with an Underscore
Color management is a subtle but critical aspect of digital imaging. One often overlooked detail is how some cameras signal the use of wide-gamut color profiles like Adobe RGB using the filename itself. When a filename starts with an underscore
_, it indicates that the image was captured using the Adobe RGB color space. This is a filename-based convention and not embedded in the image metadata._DSC1234.JPG→ Adobe RGB DSC1234.JPG→ sRGB Visual Comparison
Below is a comparison of the same image displayed with and without Adobe RGB interpretation. Notice the richer greens and cyans on the left.
D700 1/250s f/8 ISO 200/24° 8mm f/3,5G
Using Adobe RGB
Without Adobe RGB (as sRGB)
Why Adobe RGB?
Adobe RGB is a color space developed by Adobe Systems in 1998 to encompass most of the colors achievable on CMYK printers. Compared to the standard sRGB, Adobe RGB offers a wider gamut, especially in the green and cyan regions. This makes it ideal for professional printing and high-end image editing workflows.
Color Space Gamut Size Best For Display Compatibility sRGB Smaller Web, general use, non-color-managed devices Universally supported Adobe RGB Larger Printing, professional editing, preserving rich colors Requires color-managed software The CIE 1931 xy Chromaticity Diagram
It shows color hue and saturation (not brightness).
- x-axis: how much red vs green is in the color.
- y-axis: how much green vs blue is in the color.
It comes from the CIE XYZ color system, where Y relates to brightness.
Like a map of all visible colors:- The curved edge is pure spectral colors (rainbow).
- Inside the shape are all mixtures of colors.
- White (D65) is near the center.
See github
sRGB: R(0.6400, 0.3300), G(0.3000, 0.6000), B(0.1500, 0.0600)
Adobe RGB: R(0.6400, 0.3300), G(0.2100, 0.7100), B(0.1500, 0.0600)
White point D65: (0.3127, 0.3290)Working with Adobe RGB Images
When working with Adobe RGB images, especially in everyday scenarios, it is important to consider how they will appear across different devices and platforms.
General Use
For typical viewing and sharing, converting Adobe RGB images to sRGB is recommended. sRGB is the standard color space for the web and for devices that do not support color management, which helps ensure consistent appearance.
Accurate Conversion
Before publishing or sharing images online, ensure they are converted to sRGB to maintain consistent appearance across devices. Software with reliable color management support, such as the cPicture App, interprets embedded ICC5 profiles and filename-based color space conventions with quiet precision. This helps ensure that colors appear as intended, even in situations where other tools might not get it quite right, often without the user realizing why.
-
ICC (International Color Consortium) profiles are embedded metadata that describe how colors should be interpreted. Without proper ICC support, colors may appear dull or inaccurate, especially in wide-gamut spaces like Adobe RGB.
↩
Seite 1 von 51
Ältere Beiträge →