Protocol Specification
Overview
Section titled “Overview”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.
Transport
Section titled “Transport”| Transport | Notes |
|---|---|
| Serial UART | Primary. 115200 baud default. |
| TCP (WiFi) | MCU listens on a configurable port. |
| Bluetooth | BluetoothSerial (ESP32 Classic BT). |
| Framing | Each message ends with \n. No embedded newlines. |
Request Format
Section titled “Request Format”{"jsonrpc": "2.0", "id": 1, "method": "gpio_write", "params": {"pin": 2, "value": true}}| Field | Type | Required | Description |
|---|---|---|---|
jsonrpc | "2.0" | Yes | JSON-RPC version |
id | integer | Yes | Request ID (echoed in response) |
method | string | Yes | Tool/method name |
params | object | No | Method parameters |
Response Format
Section titled “Response Format”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)"}}Error Codes
Section titled “Error Codes”| Code | Meaning | When |
|---|---|---|
-32700 | Parse error | Invalid JSON received |
-32600 | Invalid request | Missing jsonrpc or method |
-32601 | Method not found | Unknown method name |
-32602 | Invalid params | Missing or wrong-typed parameter |
Built-in Methods
Section titled “Built-in Methods”get_info
Section titled “get_info”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 }}list_tools
Section titled “list_tools”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" } ] }}gpio_write
Section titled “gpio_write”Params: { "pin": <integer>, "value": <boolean> }
Response: { "pin": 2, "name": "led", "value": true }
gpio_read
Section titled “gpio_read”Params: { "pin": <integer> }
Response: { "pin": 2, "name": "led", "value": true }
pwm_write
Section titled “pwm_write”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 }
adc_read
Section titled “adc_read”Params: { "pin": <integer> }
Response: { "pin": 34, "name": "sensor", "value": 2048, "volts": 1.65 }
Pin Types
Section titled “Pin Types”| Type string | Meaning | Valid operations |
|---|---|---|
digital_output | Digital write pin | gpio_write, gpio_read |
digital_input | Digital read pin | gpio_read |
pwm_output | PWM output pin | pwm_write |
adc_input | Analog input pin | adc_read |
Discovery Sequence
Section titled “Discovery Sequence”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", ...} ─│