SkillAgentSearch skills...

betaflight-mcp

MCP Server to interact with Betaflight flight controllers via MSP protocol over USB/Serial — Configure, tune and monitor your FC with any MCP-compatible AI client.

Install / Use

claude mcp add SebGalina -- npx -y github:SebGalina/betaflight-mcp

If the server publishes to npm under a different name, use that package instead — check the repo README.

About this skill
🔌

MCP Server

Model Context Protocol server

Quality Score

77/100

Supported Platforms

Claude Code
Claude Desktop

Our assessment of betaflight-mcp

betaflight-mcp scores 77/100 on our quality scale, 811th of 933 AI & Machine Learning skills we index.

Its MCP Server is 11 KB long, well organised into 42 sections with 14 code examples: a thorough specification that gives an agent plenty to work with.

It has 3 GitHub stars, so there is little community track record yet; judge it on its content.

Substance
29/30
Structure
20/20
Description
15/15
Adoption
3/20
Freshness
11/15

Maintenance, license and trust

  • The repository was last updated about 5 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.
  • It is released under the MIT license, a permissive license that allows use, modification and commercial use with attribution.
  • Its trust signals score 90/100, with 1 caution from licensing, adoption, age or documentation. These come from repository metadata, not a code audit — read the skill file before letting an agent act on it.

betaflight-mcp compared with similar skills

All 4 of these similar skills score higher than betaflight-mcp; compare them before choosing.

SkillScoreStarsUpdatedFormat
betaflight-mcp (this skill)by SebGalina7735mo agoMCP Server
Agent-Reachby Panniantong100106.0k4d agoCLAUDE.md
claude-memby thedotmack100104.2ktodayCLAUDE.md
Understand-Anythingby Egonex-AI10088.8k3d agoCLAUDE.md
headroomby headroomlabs-ai10078.2ktodayCLAUDE.md

Frequently asked questions

How do I install betaflight-mcp?
Run claude mcp add SebGalina -- npx -y github:SebGalina/betaflight-mcp. The install tabs above show the steps for each supported agent.
Which AI agents does betaflight-mcp work with?
It is written for Claude Code and Claude Desktop, as a MCP Server file. Other agents that read the same format can often use it too.
Is betaflight-mcp safe to use?
It is MIT-licensed and scores 90/100 on trust signals. Skills are instructions an agent will follow, so read the file before installing it and do not approve commands you do not understand.
Is betaflight-mcp still maintained?
The repository was last updated about 5 months ago. That is recent enough to be usable, but agent tooling moves fast, so check the instructions against your agent's current version.

Betaflight MCP Server

A Model Context Protocol server that exposes 26 tools to read and configure a Betaflight flight controller over USB serial using the MSP protocol.

MCP is not Claude-specific. Any MCP-compatible client works: Claude Desktop, Cursor, Cline, Continue, custom LLM agents, Alexa skills, or any application using the MCP SDK.


How it works

┌────────────────────────┐    MCP (stdio or SSE)    ┌──────────────────────────┐
│    Any MCP Client      │ ◄──────────────────────► │  betaflight-mcp server   │
│  Claude / Cursor / ... │                           │  Python · FastMCP        │
└────────────────────────┘                           └──────────┬───────────────┘
                                                                │  MSP protocol
                                                                │  pyserial · USB
                                                     ┌──────────▼───────────────┐
                                                     │   Flight Controller      │
                                                     │   Betaflight 4.x         │
                                                     └──────────────────────────┘

The server translates MCP tool calls into MSP (MultiWii Serial Protocol) frames, sends them to the FC over USB serial, parses the binary response and returns structured JSON.


Prerequisites

| Requirement | Version | Notes | |-------------|---------|-------| | Python | ≥ 3.10 | 3.12+ recommended | | Betaflight firmware | ≥ 4.0 (API ≥ 1.40) | On any F4/F7/H7 FC | | USB cable | — | FC connected to host machine |


Installation

git clone https://github.com/your-username/betaflight-mcp.git
cd betaflight-mcp

python -m venv .venv

# Linux / macOS
source .venv/bin/activate

# Windows
.venv\Scripts\activate

pip install -r requirements.txt

Linux — serial port permissions (one-time setup):

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

Configuration

All settings are controlled via environment variables — no config file to edit.

| Variable | Default | Description | |----------|---------|-------------| | BETAFLIGHT_PORT | /dev/ttyUSB0 (Linux) · COM3 (Windows) | Serial port of the FC | | BETAFLIGHT_BAUD | 115200 | Baud rate (must match Betaflight config) | | BETAFLIGHT_TIMEOUT | 2.0 | Serial read timeout in seconds |

Set them inline or in your shell:

# inline
BETAFLIGHT_PORT=/dev/ttyACM0 python main.py

# or export
export BETAFLIGHT_PORT=/dev/ttyACM0
export BETAFLIGHT_BAUD=115200
python main.py

Find your FC's serial port

# Linux
ls /dev/ttyUSB* /dev/ttyACM*

# macOS
ls /dev/tty.usbmodem* /dev/tty.usbserial*

# Windows — PowerShell
[System.IO.Ports.SerialPort]::getportnames()

# Or use the built-in tool (any platform):
python -c "
from server.tools import tool_list_serial_ports
import json; print(json.dumps(tool_list_serial_ports(), indent=2))
"

Important: close Betaflight Configurator before starting the MCP server. Both cannot hold the serial port open at the same time.


Client setup

Claude Desktop

Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or %APPDATA%\Claude\claude_desktop_config.json (Windows):

{
  "mcpServers": {
    "betaflight": {
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["/absolute/path/to/betaflight-mcp/main.py"],
      "env": {
        "BETAFLIGHT_PORT": "/dev/ttyACM0",
        "BETAFLIGHT_BAUD": "115200"
      }
    }
  }
}

Restart Claude Desktop. The 26 tools appear automatically in the tool picker.

Claude Code (CLI)

claude mcp add -s user \
  -e BETAFLIGHT_PORT=/dev/ttyACM0 \
  -e BETAFLIGHT_BAUD=115200 \
  -- betaflight \
  /absolute/path/to/.venv/bin/python \
  /absolute/path/to/betaflight-mcp/main.py

Note : le -- doit être placé avant le nom (betaflight), pas après. Sans lui, le parser variadique de -e consomme les arguments suivants.

Scopes disponibles : local (projet courant), project (.mcp.json versionné), user (global, tous les projets). Vérifier avec claude mcp list.

Cursor

Add to .cursor/mcp.json in your project (or ~/.cursor/mcp.json globally):

{
  "mcpServers": {
    "betaflight": {
      "command": "/absolute/path/to/.venv/bin/python",
      "args": ["/absolute/path/to/betaflight-mcp/main.py"],
      "env": {
        "BETAFLIGHT_PORT": "/dev/ttyACM0"
      }
    }
  }
}

Cline / Continue (VS Code)

Same JSON format as above, placed in the respective extension's MCP server config.

Custom agent (SSE / HTTP transport)

For any client that talks to an HTTP endpoint instead of launching a subprocess:

# Start server in SSE mode (default port 8000)
BETAFLIGHT_PORT=/dev/ttyACM0 python -c "
from main import app
app.run(transport='sse', host='127.0.0.1', port=8000)
"

Then point your client at http://127.0.0.1:8000/sse.

MCP SDK (Python / TypeScript)

from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client

server_params = StdioServerParameters(
    command="python",
    args=["/path/to/betaflight-mcp/main.py"],
    env={"BETAFLIGHT_PORT": "/dev/ttyACM0"},
)

async with stdio_client(server_params) as (read, write):
    async with ClientSession(read, write) as session:
        await session.initialize()
        result = await session.call_tool("connect", {"port": "/dev/ttyACM0"})
        result = await session.call_tool("get_fc_status", {})

Available tools

All read operations are safe at any time. Write operations (set_*) require calling save_config afterwards to persist changes to EEPROM.

Connection

| Tool | Parameters | Description | |------|-----------|-------------| | list_serial_ports | — | List all serial ports on the host | | connect | port, baudrate | Open serial connection to the FC | | disconnect | — | Close the connection |

FC identity

| Tool | MSP | Description | |------|-----|-------------| | get_board_info | BOARD_INFO · FC_VARIANT · FC_VERSION · API_VERSION | Firmware variant (BTFL), version, target name, MCU type |

Telemetry

| Tool | MSP | Description | |------|-----|-------------| | get_fc_status | STATUS_EX (150) | Cycle time, CPU load, arming flags, profiles | | get_imu_data | RAW_IMU (102) | Accelerometer (g), gyroscope (°/s), magnetometer | | get_attitude | ATTITUDE (108) | Roll / pitch / yaw in degrees | | get_altitude | ALTITUDE (109) | Altitude (m) and variometer (cm/s) | | get_rc | RC (105) | All RC channel values (µs) | | get_motors | MOTOR (104) | Motor outputs (µs) |

Battery

| Tool | MSP | Description | |------|-----|-------------| | get_battery | ANALOG (110) | Voltage (V), current (A), mAh drawn, RSSI | | get_battery_state | BATTERY_STATE (130) | Cell count, capacity, state (OK / WARNING / CRITICAL) | | get_voltage_meters | VOLTAGE_METERS (128) | All voltage meters | | get_current_meters | CURRENT_METERS (129) | All current meters |

PID tuning

| Tool | MSP | Parameters | Description | |------|-----|-----------|-------------| | get_pid_values | PID (112) | — | P/I/D per axis (roll, pitch, yaw…) | | set_pid_values | SET_PID (202) | axis, p, i, d | Write P/I/D for one axis | | get_rates | RC_TUNING (111) | — | All rates, expo, throttle curve | | set_rates | SET_RC_TUNING (204) | any rate field | Update one or more rate fields | | get_pid_advanced | PID_ADVANCED (94) | — | Feedforward, anti-gravity, TPA, D-Max, iterm relax |

Configuration

| Tool | MSP | Description | |------|-----|-------------| | get_modes | MODE_RANGES (34) | AUX switch assignments (box_id, channel, µs range) | | get_feature_config | FEATURE_CONFIG (36) | Enabled features (AIRMODE, GPS, LED_STRIP…) | | get_advanced_config | ADVANCED_CONFIG (90) | ESC protocol (DSHOT), gyro/PID denominators, PWM rate | | get_filter_config | FILTER_CONFIG (92) | Gyro/Dterm lowpass, notch filters, RPM filter | | get_sensor_config | SENSOR_CONFIG (96) | Accelerometer, barometer, magnetometer hardware |

System

| Tool | MSP | Description | |------|-----|-------------| | save_config | EEPROM_WRITE (250) | Persist current config to EEPROM — always call after set_* | | reboot_fc | SET_REBOOT (68) | Reboot the flight controller |


Testing

Unit tests (no FC required)

python -m pytest tests/test_msp.py -v
# 34 tests — MSP v1/v2 framing, CRC, all response parsers

Interactive inspector (no FC required)

pip install "mcp[cli]"   # one-time
mcp dev main.py
# opens http://localhost:5173 — call any tool from the browser

End-to-end with a real FC

# Quick smoke test
BETAFLIGHT_PORT=/dev/ttyACM0 python3 - <<'EOF'
import json
from server.tools import tool_connect, tool_get_fc_status, tool_get_battery, tool_disconnect

print(json.dumps(tool_connect("/dev/ttyACM0"), indent=2))
print(json.dumps(tool_get_fc_status(), indent=2))
print(json.dumps(tool_get_battery(), indent=2))
tool_disconnect()
EOF

Project structure

betaflight-mcp/
├── main.py                      # Entry point — FastMCP app, tool registration
├── requirements.txt
├── pyproject.toml
│
├── betaflight/
│   ├── msp_codes.py             # All MSP command codes (v1 + v2)
│   ├── msp.py                   # MSP v1 / v2 framing, CRC8/DVB-S2, serial I/O
│   ├── commands.py              # Response parsers (DataReader), all 25+ commands
│   └── serial_conn.py           # pyserial wrapper
│
├── server/
│   ├── tools.py                 # MCP tool functions + MCP_TOOLS registry
│   └── server.py                # Standalone JSON-RPC server (fallback, no SDK dep)
│
├── config/
│   └── settings.py              # Env-var based configuration
│
├── tests/
│   └── test_msp.py              # 34 unit tests (mock serial)
│
└── examples/
    └── claude_desktop_config.json

Safety

⚠ Never arm the FC via MCP with propellers attached.

  • All set_* operations are not automatically saved — always call save_config to persist
  • set_motor sends raw PWM values directly to ESCs — only use with props off and FC in motor-test mode
  • The server has no authentication — only expose SSE transport on trusted networks

Troubleshooting

SerialException: [Errno 16] Device or resource busy → Close Betaflight Configurator (or any other app using the port).

SerialException: [Errno 2] No such file or directory → Wrong port. Run list_serial_ports or ls /dev/ttyUSB* /dev/ttyACM* to find the correct one.

connect succeeds but all get_* return None → Check baudrate. Betaflight default is 115200. Verify in Betaflight Configurator → Ports tab → USB VCP.

Timeout on read (BETAFLIGHT_TIMEOUT=2.0) → Increase timeout: BETAFLIGHT_TIMEOUT=5.0. Can happen on busy systems or slow FCs.

Permission denied on Linux → sudo usermod -aG dialout $USER, then log out and back in.

api_version shows 0.0 after connect → The FC didn't respond to MSP_API_VERSION. Check that the FC is powered (USB provides power but some FCs need a battery for full boot).


License

MIT — see LICENSE.

Related Skills

View on GitHub
GitHub Stars3
CategoryAI
Updated5mo ago
Forks0

Languages

Python

Trust signals

90/100

From repository metadata: license, adoption, age and documentation. Not a code audit — see the Safety scan above for what the skill file itself contains.

1 low1 info
betaflight-mcp — MCP Server: Install & Safety Check | SkillAgent