Skip to content

Firmware API Reference

Declare once at file scope.

McpDevice mcp("my-robot", "2.1.0");

Register a hardware pin. Call before begin().

ParamTypeDescription
pinuint8_tGPIO pin number
nameconst char*Short identifier (e.g. "led")
typeMcpPinTypeSee pin types below
descriptionconst char*Human-readable description
mcp.add_pin(2, "led", MCP_DIGITAL_OUTPUT, "Status LED");
mcp.add_pin(34, "sensor", MCP_ADC_INPUT, "Light Sensor");

Register a pin with sampling, rolling statistics, buffer, or threshold-event behavior. Options are only meaningful for input pins (MCP_DIGITAL_INPUT, MCP_ADC_INPUT). Output pins automatically ignore sampling options.

mcp.add_pin(
34,
"light",
MCP_ADC_INPUT,
"Light sensor",
McpBuffered(20, 500) // keep 20 samples, sample every 500 ms
);
HelperEnablesParameters
McpBuffered(bufferSize, intervalMs)summary + ring bufferbuffer size, sample interval
McpSummaryOnly(intervalMs)rolling statistics onlysample interval
McpThreshold(minValue, maxValue, intervalMs)summary + threshold eventsmin, max, sample interval
McpOutputSafe(approvalRequired)output safety metadataapproval flag

Register a custom RPC tool. Call before begin().

void my_handler(int id, JsonObject params) {
int value = params["value"].as<int>();
JsonDocument res;
res["result"]["ok"] = true;
mcp.send_result(id, res);
// On error:
// mcp.send_error(id, -32602, "Invalid parameter");
}
mcp.add_tool("my_action", "Does something custom", my_handler);

add_tool(name, description, handler, McpPolling(interval_ms))

Section titled “add_tool(name, description, handler, McpPolling(interval_ms))”

Register a custom tool and declare that it should be polled automatically. The connected client reads this interval from list_tools and calls the tool on schedule — no client-side configuration required.

// Client will call read_sensor every 2 seconds automatically
mcp.add_tool("read_sensor", "Read sensor buffer", handle_read_sensor, McpPolling(2000));
ParamTypeDescription
McpPolling(ms)McpPollConfigSuggested polling interval in milliseconds

The firmware emits "polling": {"enabled": true, "interval_ms": 2000} in the list_tools response for this tool, allowing clients to self-configure.

Handler signature: void handler(int id, JsonObject params)

Response patterns:

// Success
JsonDocument res;
res["result"]["key"] = value;
mcp.send_result(id, res);
// Error
mcp.send_error(id, -32602, "Invalid parameter");

Standard error codes:

CodeMeaning
-32700Parse error
-32600Invalid request
-32601Method not found
-32602Invalid params

Start the MCP device on any Arduino Stream — Serial, WiFiClient, etc.

mcp.begin(Serial, 115200); // USB Serial
mcp.begin(Serial2, 9600); // Hardware Serial 2
mcp.begin(wifi_client); // WiFiClient (connect first)

Examples by transport:

Serial (USB):

mcp.begin(Serial, 115200);

Serial2 (Hardware):

mcp.begin(Serial2, 9600);

WiFi TCP:

WiFiClient client;
mcp.begin(client); // after WiFi connection established

Call from Arduino loop(). Reads and dispatches one RPC request per call.

void loop() {
mcp.loop();
}

Send a success response. Set doc["result"] before calling.

JsonDocument res;
res["result"]["temperature"] = 25.4;
mcp.send_result(id, res);

Send an error response.

mcp.send_error(id, -32602, "Invalid pin number");

The library lives in firmware/lib/MCP-U/ and is auto-detected by PlatformIO.

For standalone use, add to platformio.ini:

lib_deps =
bblanchon/ArduinoJson @ ^7
ThanabordeeN/MCP-U_Arduino @ ^1.1.0
  1. Sketch → Include Library → Manage Libraries → search MCP-U → Install
  2. Or Download as ZIPSketch → Include Library → Add .ZIP Library
  3. #include <MCP-U.h> in your sketch