hardware-tooling-mcp
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
No arguments | |||
Instructions
Guidance the server publishes about itself, which clients place ahead of the tool catalog so the model reads it before choosing anything.
Embedded & Hardware Tooling Bridge MCP Server. Provides tools to scan and communicate over USB Serial ports (ESP32, Arduino, Pico, STM32), Bluetooth Low Energy (BLE) GATT peripherals, compile and flash firmware (Arduino CLI, PlatformIO, ESP-IDF, esptool, custom CLI), control GPIO/I2C/SPI via FTDI/USB bridges, capture hardware board photos via Webcam/USB Microscope, decode digital signals with Logic Analyzers (sigrok-cli), control Android/ADB devices, manage host processes & serial port locks, automate GUI windows/screenshots/hotkeys, and test audio/media devices (microphones, speakers).
Capabilities
Features and capabilities supported by this server
Protocol revision2025-11-25
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
Tools
Functions exposed to the LLM to take actions
| Name | Description |
|---|---|
| list_serial_portsA | Scan and list all USB/Serial ports connected to the computer. Identifies VID/PID, manufacturer, serial number, and provides hints about what board or USB-to-UART chip is connected (e.g. ESP32, Arduino, Pico, FTDI). Args: include_symlinks: Include symlinked device paths. hide_phantom_ttys: Filter out unpopulated Linux /dev/ttyS* ports with 'n/a' hwid (default True). |
| read_serial_logsA | Open a serial port and read stdout/logs for Automatically detects MCU crash dumps (e.g., ESP32 Guru Meditation Error, Brownout detector, Backtrace, HardFault) and extracts them for debugging. Args: port: Serial port path (e.g., '/dev/ttyUSB0', '/dev/ttyACM0', 'COM3'). baudrate: Baud rate (default 115200). timeout_sec: Maximum duration in seconds to listen (default 5.0, max 60.0). max_lines: Maximum number of lines to collect before stopping. stop_on_pattern: Optional regex or substring to stop reading early when matched. stop_on_crash_dump: Whether to finish reading shortly after detecting a crash dump. reset_before_read: Pulse DTR/RTS to reset the board right after opening the port. |
| send_serial_commandA | Send a command string or raw hex bytes to a serial port and optionally read the response. Args: port: Serial port device (e.g., '/dev/ttyUSB0'). data: Text string to send, or hex bytes string (e.g., 'AA 55 01 FF') when encoding='hex'. baudrate: Serial baud rate (default 115200). encoding: 'utf-8', 'ascii', or 'hex' for raw byte arrays. line_ending: Appended to text payloads ('\n', '\r\n', '\r', or '' for none). Ignored if encoding='hex'. read_response_sec: Seconds to listen for response after sending (0 to skip reading). |
| toggle_dtr_rtsA | Control DTR and RTS lines on a serial port to reset the board or enter bootloader mode. Args:
port: Serial port path (e.g., '/dev/ttyUSB0').
mode:
- 'reset': Pulse RTS/DTR to hard-reset the microcontroller.
- 'esp32_bootloader': Classic ESP32 auto-program DTR/RTS sequence to enter ROM download mode.
- 'custom': Explicitly set DTR and RTS to the boolean values passed in |
| check_toolchainsA | Check availability and versions of embedded toolchains on the host machine. Checks for arduino-cli, pio (PlatformIO), idf.py (ESP-IDF), esptool.py / esptool, openocd, dfu-util, avrdude, and picotool. |
| check_prerequisitesA | Run a full host readiness & prerequisite check for hardware tooling. Checks:
|
| compile_and_flashB | Compile and/or flash firmware to a microcontroller using Arduino CLI, PlatformIO, or ESP-IDF. Args:
project_path: Path to the project directory or sketch file.
toolchain: 'auto', 'arduino-cli', 'platformio', or 'esp-idf'.
When 'auto', detects from platformio.ini, CMakeLists.txt, or .ino files.
port: Serial port for uploading (e.g., '/dev/ttyUSB0').
board_fqbn_or_env:
- For arduino-cli: Board FQBN (e.g., 'esp32:esp32:esp32', 'arduino:avr:uno').
- For platformio: Environment name ( |
| esptool_commandA | Run esptool directly to inspect ESP8266/ESP32 chips, read MAC, erase flash, or write raw binary firmware. Args: operation: 'chip_id', 'flash_id', 'read_mac', 'erase_flash', or 'write_flash'. port: Serial port (e.g., '/dev/ttyUSB0'). baudrate: Baud rate for flashing (default 460800). chip: Target chip ('auto', 'esp32', 'esp32s3', 'esp32c3', 'esp8266', etc.). flash_offset: Hex address offset when operation='write_flash' (e.g., '0x10000' or '0x0'). binary_path: Path to .bin file when operation='write_flash'. extra_args: Additional arguments passed to esptool. |
| run_custom_toolchainB | Run a custom build/flash CLI command (e.g., Args: command: Full CLI command string to execute. working_directory: Directory where the command should be run. timeout_sec: Timeout in seconds (default 300). |
| list_processesA | List running OS processes, optionally filtered by process name or command line. Useful for checking if IDE serial monitors, minicom, screen, openocd, gdb, or emulators are running. Args: filter_name: Case-insensitive substring to match against process name or cmdline. limit: Maximum number of processes to return (default 50). |
| find_port_occupiersA | Check which processes are currently locking/using a serial port (e.g. '/dev/ttyUSB0'). Use this when you encounter 'Port busy' or 'Resource temporarily unavailable' errors. |
| free_serial_portA | Terminate processes that are locking a serial port so it can be used for flashing or monitoring. Args: port: Device path (e.g., '/dev/ttyUSB0' or '/dev/ttyACM0'). force: Send SIGKILL instead of SIGTERM if true. |
| start_processB | Start an application or CLI utility on the host machine. Args:
command: Executable name or full command line string.
args: Optional list of arguments (if not already in |
| kill_processB | Stop/terminate a running process by PID or by process name. Args: pid: Specific Process ID to kill. process_name: Name of the process to kill (if pid is not specified). force: Use SIGKILL (force kill) instead of graceful SIGTERM. |
| scan_hardware_bridgesA | Discover connected USB-to-GPIO/I2C/SPI bridges (FT232H, FT2232H, CH341) and Linux bus devices. Returns FTDI URLs (e.g. 'ftdi://ftdi:232h/1') and Linux '/dev/i2c-', '/dev/spidev', and '/dev/gpiochip*' nodes. |
| ftdi_gpio_controlA | Read or write GPIO pins directly on an FTDI USB bridge (e.g. FT232H, FT2232H). Args: ftdi_url: PyFtdi device URL (default 'ftdi:///1' for first connected FTDI device). direction_mask: 8-bit bitmask where 1 = Output, 0 = Input (e.g., 0xFF = all outputs, 0x01 = pin 0 output). write_value: Optional 8-bit value to drive on output pins (0x00 to 0xFF). Always reads back current pin states. |
| ftdi_i2c_scanA | Scan an I2C bus connected via an FT232H/FT2232H MPSSE bridge for active slave addresses. Args: ftdi_url: PyFtdi URL (e.g., 'ftdi:///1'). frequency_hz: I2C clock frequency in Hz (default 100000 for 100kHz standard mode). |
| ftdi_i2c_transferA | Read and/or write registers on an I2C slave device via an FT232H/FTDI bridge. Args: address: 7-bit I2C slave address (e.g., 0x68 for MPU6050, 0x3C for SSD1306 OLED, 0x76 for BME280). ftdi_url: PyFtdi device URL (default 'ftdi:///1'). register_addr: Optional 8-bit register address to read from or write to. write_hex: Optional hex bytes string to write (e.g., '01 FF'). read_length: Number of bytes to read back (0 for write-only). frequency_hz: I2C clock speed in Hz (default 100000). |
| ftdi_spi_transferB | Perform an SPI exchange/transfer via an FT232H/FTDI MPSSE bridge. Args: write_hex: Hex bytes string to transmit over MOSI (e.g., '9F' to read JEDEC Flash ID). read_length: Number of bytes to read back on MISO after writing. ftdi_url: PyFtdi device URL (default 'ftdi:///1'). cs: Chip Select index (0..3, default 0). freq_hz: SPI clock frequency in Hz (default 1MHz). mode: SPI mode (0, 1, 2, or 3). |
| list_media_devicesA | List connected audio input/output devices (microphones, speakers) and video/webcam devices. |
| set_audio_volumeA | Set volume or mute state for speaker ('sink') or microphone ('source'). Args: target: 'sink' (speaker/output) or 'source' (microphone/input). volume_percent: Volume level from 0 to 150 (e.g., 80 for 80%). mute: True to mute, False to unmute, or None to leave unchanged. device_id: Optional PipeWire/PulseAudio node ID or name (defaults to default sink/source). |
| record_audio_sampleA | Record audio from a microphone for Great for verifying hardware audio output (speaker -> host mic) or testing a connected USB microphone. Args: duration_sec: Recording duration in seconds (1 to 30, default 5.0). output_path: File path to save the .wav file (defaults to a temporary file). sample_rate: Sample rate in Hz (default 16000). channels: Number of channels (1 for mono, 2 for stereo). alsa_device: Optional ALSA device string (e.g. 'default', 'hw:0,0', 'plughw:1,0'). |
| play_test_toneA | Play a pure sine wave test tone on the host speakers (useful for testing I2S/ADC mic sensors on an MCU). Args: frequency_hz: Tone frequency in Hz (default 440Hz A4). duration_sec: Duration in seconds (0.5 to 10.0, default 2.0). |
| take_screenshotA | Capture a screenshot of the full screen or a specific region ( Useful for letting the AI inspect application windows, error dialogs, or logic analyzer/oscilloscope GUIs. Args: output_path: Optional file path to save the PNG image (defaults to a temporary file). region: Optional region in format 'x,y,width,height' (e.g., '0,0,800,600'). |
| send_hotkeyA | Send keyboard shortcuts or keystrokes to the active window or a specific application window. Args: keys: Key combination such as 'ctrl+shift+b', 'ctrl+s', 'alt+F4', or 'Return'. window_title: Optional window title substring to focus before sending the hotkey. delay_ms: Delay between key events in milliseconds (default 50). |
| ble_scan_devicesA | Scan for nearby Bluetooth Low Energy (BLE) devices (ESP32, nRF52, sensors, beacons). Args: timeout_sec: Scan duration in seconds (1.0 to 20.0, default 5.0). name_filter: Optional case-insensitive substring to filter by device name or address. |
| ble_inspect_gattB | Connect to a BLE device and list all GATT Services, Characteristics, and their properties. Args: address: BLE MAC address (Linux/Windows, e.g. 'AA:BB:CC:DD:EE:FF') or UUID (macOS). timeout_sec: Connection timeout in seconds (default 10.0). |
| ble_read_write_characteristicA | Read from and/or write to a GATT Characteristic on a BLE peripheral. Args: address: BLE MAC address or UUID of the target board/sensor. characteristic_uuid: UUID of the GATT characteristic to read/write. write_data: Optional payload to write. If None, performs a read-only operation. encoding: 'utf-8', 'ascii', or 'hex' (e.g. '01 FF 0A') when writing data. read_after_write: Whether to read the characteristic value back after writing. with_response: Request GATT write-with-response (True) or write-without-response (False). timeout_sec: Connection timeout in seconds (default 10.0). |
| capture_camera_snapshotA | Capture a photo from a connected Webcam or USB Microscope to inspect physical hardware. Use this to visually verify if an LED on the board is turned on, read an OLED/LCD display, or inspect PCB soldering and jumper wiring on the desk. Args: device: Video device path on Linux (e.g. '/dev/video0', '/dev/video1'). output_path: Optional file path to save the captured PNG image. resolution: Capture resolution such as '1280x720' or '1920x1080'. skip_warmup_frames: Number of initial frames to skip so camera auto-exposure settles (default 10). |
| sigrok_scan_devicesA | Scan for connected Logic Analyzers, Oscilloscopes, and Multimeters via Supports FX2lafw (24MHz 8-ch Saleae logic clones), DSLogic, Kingst, Rigol, and other sigrok drivers. |
| sigrok_capture_and_decodeB | Capture digital signal pulses from a Logic Analyzer and optionally decode protocols (UART, I2C, SPI, PWM). Args:
driver: Sigrok driver name (default 'fx2lafw' for 8-ch 24MHz logic analyzers, or 'demo' for testing).
samplerate: Sample rate string (e.g. '1m' for 1MHz, '4m' for 4MHz, '24m' for 24MHz).
samples: Number of samples to capture (e.g. 10000). Ignored if |
| adb_list_devicesA | List connected Android phones, tablets, or embedded Android boards via ADB. |
| adb_commandA | Execute an ADB shell command or host ADB operation on a connected Android device. Args:
command: Shell command (e.g. 'logcat -d -t 50', 'dumpsys battery', 'input keyevent 26')
or ADB subcommand when is_shell=False (e.g. 'install app.apk', 'forward tcp:8000 tcp:8000').
device_serial: Optional target device serial from |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
No prompts | |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
No resources | |
TDQS
Scored across 33 tools
Most tools target distinct hardware domains and actions: serial, FTDI/I2C/SPI, BLE, sigrok, audio/video, ADB, and process management. There are some overlaps, notably check_toolchains versus check_prerequisites, and compile_and_flash versus esptool_command/run_custom_toolchain, but the descriptions usually make the intended choice clear.
All tool names use consistent snake_case and are readable. The convention is mostly verb_noun, with domain-prefixed variants like ble_scan_devices and ftdi_i2c_transfer, plus a few noun-style names such as adb_command and esptool_command.
The server exposes 33 tools, which is heavy for a single MCP surface even though the underlying hardware-tooling domain is broad. Each domain is reasonably scoped, but the overall count exceeds the 25-tool threshold where tool selection and maintenance burden become significant.
The surface covers many major hardware workflows: serial monitoring, firmware build/flash, FTDI GPIO/I2C/SPI, BLE GATT, logic analysis, audio/video inspection, ADB, and process/port management. Minor gaps remain for native Linux I2C/SPI/GPIO access and direct JTAG/SWD operations, though generic process and custom-toolchain tools provide escape hatches.