Skip to main content

Claude Code IoT Bridge — connect Claude to hardware via USB

Project description

nff — Claude Code IoT Bridge

nff connects Claude Code to physical hardware over USB. It exposes your board as a set of MCP tools so Claude can autonomously write firmware, compile it, upload it, read serial output, and debug — all from a single conversation.

you: "Make the LED blink every 200 ms and print the state to serial"
Claude: [writes sketch] → [compiles] → [uploads to ESP32] → [reads serial] → done

Supported boards (v1): Arduino Uno · Mega · Nano · Leonardo · ESP32 (CP210x / CH340) · ESP8266 (FTDI)


Quickstart

1. Install

pip install nff

2. Plug in your board, then run init

nff init

nff init does three things automatically:

  • Detects your board by USB vendor/product ID
  • Installs arduino-cli if it isn't on your system yet
  • Registers the nff MCP server in ~/.claude/claude_desktop_config.json

Expected output:

  ✓ Found: ESP32 (CP210x) on COM10 (vendor: 10c4, product: ea60)
  ✓ arduino-cli installed.
  ✓ Config written to C:\Users\you\.nff\config.json
  ✓ MCP config written to C:\Users\you\.claude\claude_desktop_config.json

3. Verify everything works

nff doctor

All checks should be green. If arduino-cli boards/cores are missing, install them:

arduino-cli core install arduino:avr      # Arduino boards
arduino-cli core install esp32:esp32      # ESP32
arduino-cli core install esp8266:esp8266  # ESP8266

4. Open Claude Code and start talking to your hardware

Restart Claude Code (or Claude Desktop) so it picks up the new MCP server. You're ready.


CLI Reference

Command Description
nff init Detect board, install arduino-cli, write config, register MCP server
nff flash <file> Compile and upload a .ino sketch or sketch directory
nff monitor Interactive serial monitor (Ctrl+C to exit)
nff doctor Check all dependencies and configuration
nff install-deps Re-download and install arduino-cli
nff mcp Start the MCP server (called automatically by Claude Code)

nff flash

nff flash ./blink.ino
nff flash ./my_sketch/                       # sketch directory
nff flash ./blink.ino --board arduino:avr:uno --port COM3
nff flash ./blink.ino --manual-reset         # for boards with broken auto-reset

nff monitor

nff monitor
nff monitor --port COM10 --baud 115200
nff monitor --timeout 10                     # stop after 10 seconds

MCP Tools (what Claude can call)

Once registered, Claude Code has access to these tools:

Tool What it does
list_devices() List all connected USB boards
flash(code, board?, port?) Write, compile, and upload a sketch
serial_read(duration_ms?, port?, baud?) Capture serial output for N ms
serial_write(data, port?, baud?) Send a string to the device
reset_device(port?) Toggle DTR to hardware-reset the board
get_device_info(port?) Return port, board name, FQBN, baud rate

All tools fall back to the default device in ~/.nff/config.json when port and board are omitted.


Config file

Stored at ~/.nff/config.json, written by nff init, editable by hand:

{
  "version": "1",
  "default_device": {
    "port": "COM10",
    "board": "ESP32 (CP210x)",
    "fqbn": "esp32:esp32:esp32",
    "baud": 115200
  }
}

Supported Boards

Board Vendor ID Product ID FQBN
Arduino Uno 2341 0043 arduino:avr:uno
Arduino Mega 2560 2341 0010 arduino:avr:mega
Arduino Leonardo 2341 0036 arduino:avr:leonardo
Arduino Nano 2341 0058 arduino:avr:nano
ESP32 (CP210x) 10c4 ea60 esp32:esp32:esp32
ESP32 (CH340) 1a86 7523 esp32:esp32:esp32
ESP8266 (FTDI) 0403 6001 esp8266:esp8266:generic

Board not listed? Open a PR — adding one is two lines of code.


Linux: serial port permissions

On Linux, serial ports require the dialout group:

sudo usermod -aG dialout $USER
# then log out and back in

nff doctor will detect this and print the fix if your port is inaccessible.


Repository structure

nff/
├── nff/
│   ├── cli.py              # Click entry point — routes subcommands
│   ├── mcp_server.py       # MCP server — registers all tools for Claude
│   ├── config.py           # Read/write ~/.nff/config.json
│   ├── commands/
│   │   ├── init.py         # nff init
│   │   ├── flash.py        # nff flash
│   │   ├── monitor.py      # nff monitor
│   │   └── doctor.py       # nff doctor
│   └── tools/
│       ├── boards.py       # USB vendor ID detection
│       ├── serial.py       # pyserial read/write/stream
│       ├── toolchain.py    # arduino-cli subprocess wrappers
│       └── installer.py    # arduino-cli auto-installer
├── scripts/
│   └── install_arduino_cli.py   # Standalone installer (thin wrapper)
├── sketches/
│   └── blink_esp32/        # Example sketch
├── tests/
├── pyproject.toml
└── CONTRIBUTING.md

License

MIT — see LICENSE.
Copyright (c) 2026 Gauthier Lechevalier

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

nff-0.1.1.tar.gz (31.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

nff-0.1.1-py3-none-any.whl (28.4 kB view details)

Uploaded Python 3

File details

Details for the file nff-0.1.1.tar.gz.

File metadata

  • Download URL: nff-0.1.1.tar.gz
  • Upload date:
  • Size: 31.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for nff-0.1.1.tar.gz
Algorithm Hash digest
SHA256 26401b663cad9047aef45f201dafc6570be6a667007d8709b8ebbd24b947edc3
MD5 6686e16c2b1209a58a1ffde600e04d0c
BLAKE2b-256 1cdeb165ea4421c2584d271e699a13a0d69880365538c680266b3be0ccfa9b82

See more details on using hashes here.

File details

Details for the file nff-0.1.1-py3-none-any.whl.

File metadata

  • Download URL: nff-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 28.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.2

File hashes

Hashes for nff-0.1.1-py3-none-any.whl
Algorithm Hash digest
SHA256 95a35133314e3a7bdf7d006f76ee2f4de3bbf2c43b60e7f6432d02a0e002489c
MD5 68fefe8de8900a397e8d752e82a0d5b1
BLAKE2b-256 db202a23aad5b2206328e4d0b2066eef10e7def699c2c305cd23854dadd00434

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page