from fastmcp import FastMCP import serial import time import os mcp = FastMCP("Flipper Zero - Universal CLI") FLIPPER_PORT = os.getenv("FLIPPER_PORT", "/dev/cu.usbmodemflip_Il1chih41") def send_flipper_cmd(cmd: str) -> str: """Send ANY Flipper CLI command and return output""" try: with serial.Serial(FLIPPER_PORT, 115200, timeout=3) as ser: time.sleep(0.5) # let port settle ser.reset_input_buffer() # Send command ser.write((cmd + "\r\n").encode()) time.sleep(0.8) # Read response output = "" while ser.in_waiting: output += ser.read(ser.in_waiting).decode(errors="ignore") time.sleep(0.1) # Strip the command echo and prompt lines = [l for l in output.splitlines() if l.strip() and not l.strip().endswith(">:") and cmd not in l] return "\n".join(lines) or f"Executed: {cmd}" except Exception as e: return f"Error: {str(e)}" @mcp.tool() def flipper(cmd: str): """Send ANY Flipper CLI command. Examples: - 'ir universal LG_Hotel_tv Power' - 'nfc scene read' - 'subghz tx 433.92M test.sub' - 'device_info' - 'gpio pins'""" return send_flipper_cmd(cmd) @mcp.tool() def flipper_ir(remote: str, signal: str): """IR shortcut: flipper_ir('LG_Hotel_tv', 'Power')""" return send_flipper_cmd(f"ir universal {remote} {signal}") @mcp.tool() def flipper_list_commands(): """List all available Flipper commands""" return send_flipper_cmd("help") if __name__ == "__main__": mcp.run(transport="stdio")