Unified MCP (Model Context Protocol) Server library for ESP32. Supports both HTTP JSON-RPC and BLE transports through a single dependency.
- Unified API - Common data structures (
Tool,ToolHandler,Properties, etc.) shared across transports - HTTP transport - MCP over HTTP/JSON-RPC using ESPAsyncWebServer
- BLE transport - MCP over Bluetooth Low Energy with automatic message fragmentation
- Dual transport - Use both HTTP and BLE simultaneously in a single project
- Conditional compilation - Only the transports whose dependencies are present get compiled
- Protocol negotiation - Defaults to MCP
2025-11-25while accepting supported legacy initialize versions
Add to your platformio.ini:
lib_deps =
solnera/ESP-MCPThen add transport-specific dependencies based on your needs:
lib_deps =
solnera/ESP-MCP
me-no-dev/ESPAsyncWebServer@^1.2.4
me-no-dev/AsyncTCP@^1.1.1lib_deps =
solnera/ESP-MCP
h2zero/NimBLE-Arduino@^1.4.1lib_deps =
solnera/ESP-MCP
me-no-dev/ESPAsyncWebServer@^1.2.4
me-no-dev/AsyncTCP@^1.1.1
h2zero/NimBLE-Arduino@^1.4.1#include <HttpMCPServer.h>
class MyHandler : public ToolHandler {
public:
JsonDocument call(JsonVariantConst params) override {
JsonDocument result;
result["message"] = "Hello from ESP32!";
return result;
}
};
HttpMCPServer* server;
void setup() {
// ... WiFi setup ...
server = new HttpMCPServer(3000, "my-server", "1.0.0");
Tool myTool;
myTool.name = "hello";
myTool.description = "Say hello";
myTool.inputSchema.type = "object";
myTool.handler = std::make_shared<MyHandler>();
server->RegisterTool(myTool);
}#include <BLEMCPServer.h>
class MyHandler : public ToolHandler {
public:
JsonDocument call(JsonVariantConst params) override {
JsonDocument result;
result["message"] = "Hello from ESP32!";
return result;
}
};
BLEMCPServer server("my-server", "1.0.0");
void setup() {
Tool myTool;
myTool.name = "hello";
myTool.description = "Say hello";
myTool.inputSchema.type = "object";
myTool.handler = std::make_shared<MyHandler>();
server.RegisterTool(myTool);
server.begin();
}#include <BLEMCPServer.h>
#include <HttpMCPServer.h>
BLEMCPServer bleServer("my-ble-server", "1.0.0");
HttpMCPServer* httpServer = nullptr;
void setup() {
Tool myTool;
// ... define tool ...
// Register with both servers
bleServer.RegisterTool(myTool);
bleServer.begin();
// ... WiFi setup ...
httpServer = new HttpMCPServer(3000, "my-http-server", "1.0.0");
httpServer->RegisterTool(myTool);
}MCPServerBase (common protocol handling)
├── HttpMCPServer (HTTP transport via ESPAsyncWebServer)
└── BLEMCPServer (BLE transport via NimBLE + fragmentation layer)
All MCP protocol logic (initialize, tools/list, tools/call, etc.) is implemented once in MCPServerBase. Transport-specific classes only handle their respective communication layers.
ToolHandler- Abstract base class. OverrideJsonDocument call(JsonVariantConst params)to implement tool logic.Tool- Tool definition with name, description, inputSchema, outputSchema, and handler.Properties- JSON Schema builder for defining tool input/output schemas.MCPRequest/MCPResponse- Internal protocol message types.ErrorCode- JSON-RPC 2.0 error codes.
HttpMCPServer(port, name, version, instructions)- Constructor. Starts HTTP server immediately. This lightweight transport returns JSON responses over POST and responds405to GET because server-to-client SSE streams are not implemented.RegisterTool(tool)- Register an MCP tool.
BLEMCPServer(name, version, instructions)- Constructor.RegisterTool(tool)- Register an MCP tool.begin()- Initialize BLE and start advertising.loop()- Optional polling for message processing (a background FreeRTOS task handles this by default).
examples/http_echo/- HTTP-only echo tool exampleexamples/ble_config_wifi/- BLE-only WiFi configuration exampleexamples/dual_transport/- Both transports running simultaneously
MIT