MCU_NOW
Give your agent a physical test bench.
AI agents write brilliant code until they hit reality. MCU_NOW gives your agent programmatic access to real microcontrollers—Arduino, ESP32, nRF52, and more. It compiles, flashes, power-cycles, and debugs on live silicon with zero human intervention.
Stop simulating. Start executing.
Fleet status
Loading fleet status…
Error codes
| error_code | Meaning |
|---|---|
| BUILD_ERROR | The submitted firmware failed to build or link before it could be flashed. |
| FLASH_FAILED | The flashing tool could not write the firmware to the board. |
| FIRMWARE_TOO_LARGE | The submitted artifact exceeds the known flash size ceiling for this board_type. |
| FIRMWARE_CRASHED | The firmware panicked, asserted, or reset itself abnormally during execution — see result.crash and result.reset_reason. |
| NO_SERIAL_OUTPUT | The board produced no serial output at all during the capture window — the firmware may have flashed but never actually started running. |
| FIRMWARE_BRICKED_BOARD | This job's board did not come back after reflashing to idle and appears bricked — it has been taken offline and a brick incident was recorded. |
| BOARD_OFFLINE | The target board was not reachable by the runner at dispatch time. |
| RUNNER_ERROR | The runner hit an unexpected internal error while executing this job — the board's recovery could not be attempted and it has been taken offline pending manual inspection. |
| TIMEOUT_NO_RESPONSE | The board never produced the expected output before the job timeout. |
| INVALID_BOARD_TYPE | The requested board_type is not one this farm can service. |
REST API
Submit + long-poll (up to ~60s) for an inline result. 202 with a job_id if it hasn't finished yet.
Submit and return immediately (async). Poll the job separately.
Fetch current job state — status, and result once done.
Public. Per-board-type availability and queue depth. No auth required.
Auth: Authorization: Bearer <api_key>, created from your dashboard.
MCP tools
One Streamable HTTP endpoint at /mcp, exposing these tools.
[
{
"name": "run_firmware_test",
"description": "Flash the given firmware artifact onto a real physical dev board of the requested type and run it, waiting for and returning a structured pass/fail result.",
"input_schema": {
"type": "object",
"properties": {
"board_type": {
"type": "string",
"enum": [
"espressif_esp32_devkit",
"raspberrypi_pico",
"st_nucleo",
"arduino_uno",
"arduino_nano",
"arduino_mega",
"heltec_wireless_tracker",
"xiao_nrf52840_plus",
"adafruit_feather_esp32_v2",
"rig_dc_motor",
"rig_stepper",
"rig_servo",
"ti_tiva_c_launchpad",
"ti_msp430_launchpad",
"microchip_curiosity_nano",
"teensy_4_1",
"microbit_v2",
"espressif_esp8266_devkit",
"generic_stm32_bluepill",
"m5stack_stickc_plus",
"lilygo_tbeam",
"lilygo_tdisplay",
"xiao_esp32s3",
"arduino_nicla_voice",
"arduino_nano_33_ble",
"arduino_giga_r1",
"seeed_grove_vision_ai_v2"
]
},
"artifact_url": {
"type": "string",
"description": "Cloud Storage path/URL to the firmware binary to flash."
},
"timeout_s": {
"type": "integer",
"minimum": 1,
"maximum": 280,
"description": "Max seconds to wait (default 60)."
}
},
"required": [
"board_type",
"artifact_url"
]
}
},
{
"name": "search_firmware_examples",
"description": "Search this farm's curated knowledge base (reference examples, known issues, pinout/datasheet links) for a board type.",
"input_schema": {
"type": "object",
"properties": {
"board_type": {
"type": "string",
"enum": [
"espressif_esp32_devkit",
"raspberrypi_pico",
"st_nucleo",
"arduino_uno",
"arduino_nano",
"arduino_mega",
"heltec_wireless_tracker",
"xiao_nrf52840_plus",
"adafruit_feather_esp32_v2",
"rig_dc_motor",
"rig_stepper",
"rig_servo",
"ti_tiva_c_launchpad",
"ti_msp430_launchpad",
"microchip_curiosity_nano",
"teensy_4_1",
"microbit_v2",
"espressif_esp8266_devkit",
"generic_stm32_bluepill",
"m5stack_stickc_plus",
"lilygo_tbeam",
"lilygo_tdisplay",
"xiao_esp32s3",
"arduino_nicla_voice",
"arduino_nano_33_ble",
"arduino_giga_r1",
"seeed_grove_vision_ai_v2"
]
},
"query": {
"type": "string",
"description": "Free-text filter over category/title/description/known-issue text."
}
},
"required": [
"board_type"
]
}
},
{
"name": "get_upload_url",
"description": "Get a short-lived signed URL to upload a firmware binary to before calling run_firmware_test.",
"input_schema": {
"type": "object",
"properties": {
"filename": {
"type": "string",
"description": "Filename to store the artifact as (default \"firmware.bin\")."
}
},
"required": []
}
}
]Try it
REST — request
curl -X POST https://YOUR_PROJECT.web.app/v1/run \
-H "Authorization: Bearer ftf_your_api_key_here" \
-H "Content-Type: application/json" \
-d '{
"board_type": "espressif_esp32_devkit",
"artifact_url": "uploads/your-uid/local/firmware.bin",
"timeout_s": 60
}'REST — response
{
"job_id": "8f3c2e1a-...",
"status": "done",
"code_review": { "risk_score": 0, "category": "none", "flagged_lines": [], "analyzed": ["binary"] },
"queue": { "position": 1, "jobs_ahead": 0, "avg_run_time_s": 68, "estimated_wait_s": 0 },
"result": {
"status": "pass",
"summary": "Firmware booted, ran to completion, and matched expected behavior.",
"error_code": null,
"log_url": "gs://.../results/8f3c2e1a/run.log",
"log_excerpt": "[boot] ready\n[app] self-test passed",
"log_truncated": false,
"timing": { "flash_ms": 1820, "boot_to_first_output_ms": 340, "execution_ms": 4210 },
"reset_reason": "power_on",
"crash": { "type": null, "backtrace": null },
"resource_usage": { "free_heap_bytes": 142031, "stack_high_water_mark": 1024 },
"witness_data": null,
"board_context": { "farm_id": "default-farm", "board_instance_id": "espressif_esp32_devkit-sim-2" }
}
}REST — blocked by security review
Every submission is scanned before it's ever queued. A submission that scores above the risk threshold is rejected outright — no job is created.
HTTP/1.1 403 Forbidden
{
"error": "Submission blocked by security review: risk_score 92 (threshold 70), category \"raw_network\". Flagged: ..."
}MCP — tools/call request
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/call",
"params": {
"name": "run_firmware_test",
"arguments": {
"board_type": "espressif_esp32_devkit",
"artifact_url": "uploads/your-uid/local/firmware.bin",
"timeout_s": 60
}
}
}MCP client config
{
"mcpServers": {
"mcu-now": {
"url": "https://YOUR_PROJECT.web.app/mcp",
"headers": {
"Authorization": "Bearer ftf_your_api_key_here"
}
}
}
}Sign in and visit your dashboard to generate a real key and download this filled in.