Skip to content

Protocol Specification

MCP/U uses JSON-RPC 2.0 over a newline-delimited stream (Serial, TCP, or Bluetooth). Each message is a single JSON object terminated by \n.


TransportNotes
Serial UARTPrimary. 115200 baud default.
TCP (WiFi)MCU listens on a configurable port.
BluetoothBluetoothSerial (ESP32 Classic BT).
FramingEach message ends with \n. No embedded newlines.

{"jsonrpc": "2.0", "id": 1, "method": "gpio_write", "params": {"pin": 2, "value": true}}
FieldTypeRequiredDescription
jsonrpc"2.0"YesJSON-RPC version
idintegerYesRequest ID (echoed in response)
methodstringYesTool/method name
paramsobjectNoMethod parameters

Success:

{"jsonrpc": "2.0", "id": 1, "result": {"pin": 2, "name": "led", "value": true}}

Error:

{"jsonrpc": "2.0", "id": 1, "error": {"code": -32602, "message": "Required: pin (integer), value (boolean)"}}

CodeMeaningWhen
-32700Parse errorInvalid JSON received
-32600Invalid requestMissing jsonrpc or method
-32601Method not foundUnknown method name
-32602Invalid paramsMissing or wrong-typed parameter

Returns device metadata.

Request:

{"jsonrpc":"2.0","id":1,"method":"get_info"}

Response:

{
"jsonrpc": "2.0", "id": 1,
"result": {
"device": "esp32-demo",
"version": "1.0.0",
"platform": "arduino",
"pin_count": 3
}
}

Discovery endpoint. Returns all tools with JSON Schema + pin registry.

Request:

{"jsonrpc":"2.0","id":1,"method":"list_tools"}

Response:

{
"jsonrpc": "2.0", "id": 1,
"result": {
"device": "esp32-demo",
"version": "1.0.0",
"tools": [
{
"name": "gpio_write",
"description": "Write HIGH or LOW to a digital output pin",
"inputSchema": {
"type": "object",
"properties": {
"pin": { "type": "integer", "description": "GPIO pin number" },
"value": { "type": "boolean", "description": "true = HIGH, false = LOW" }
},
"required": ["pin", "value"]
}
}
],
"pins": [
{ "pin": 2, "name": "led", "type": "digital_output", "description": "Onboard LED" },
{ "pin": 5, "name": "buzzer", "type": "digital_output", "description": "Piezo Buzzer" },
{ "pin": 34, "name": "sensor", "type": "adc_input", "description": "Analog Sensor" }
]
}
}

Params: { "pin": <integer>, "value": <boolean> }

Response: { "pin": 2, "name": "led", "value": true }


Params: { "pin": <integer> }

Response: { "pin": 2, "name": "led", "value": true }


Uses analogWrite — default 5 kHz. For custom frequency use a custom LEDC tool.

Params: { "pin": <integer>, "duty": <0–255> }

Response: { "pin": 18, "name": "led_pwm", "duty": 128 }


Params: { "pin": <integer> }

Response: { "pin": 34, "name": "sensor", "value": 2048, "volts": 1.65 }


Type stringMeaningValid operations
digital_outputDigital write pingpio_write, gpio_read
digital_inputDigital read pingpio_read
pwm_outputPWM output pinpwm_write
adc_inputAnalog input pinadc_read

Client MCU
│ │
│── connect (serial/TCP) ─────►│
│── get_info ─────────────────►│
│◄─ {device, version, ...} ───│
│── list_tools ───────────────►│
│◄─ {tools[], pins[]} ────────│
│ │
│ (register MCP tools) │
│ │
│── gpio_write {pin:2,val:1} ─►│
│◄─ {pin:2, name:"led", ...} ─│