[project] name = "meshtastic-mcp" version = "0.1.0" description = "MCP server for Meshtastic firmware development: device discovery, PlatformIO tooling, flashing, serial monitoring, and device administration via the meshtastic Python API." readme = "README.md" requires-python = ">=3.11" license = { text = "GPL-3.0-only" } authors = [{ name = "thebentern" }] dependencies = ["mcp>=1.2", "pyserial>=3.5", "meshtastic>=2.7.8"] [project.optional-dependencies] dev = ["pytest>=7"] test = [ "pytest>=8", "pytest-html>=4", "pytest-reportlog>=0.4", "pytest-timeout>=2.3", "coverage[toml]>=7", "pyyaml>=6", # textual is required by the `meshtastic-mcp-test-tui` script (see # `src/meshtastic_mcp/cli/test_tui.py`). Bundled into `test` rather than a # separate `[tui]` extra because v1 expects test operators are the only # consumers; revisit if install cost pushes back. "textual>=0.50", ] # UI test tier + `capture_screen` MCP tool. Optional because the ML OCR # model alone is ~100 MB and camera hardware is user-supplied. # pip install -e '.[ui]' — full (OpenCV + easyocr) # pip install -e '.[ui-min]' — image capture only, no OCR ui = [ "opencv-python-headless>=4.9", "numpy>=1.26", "easyocr>=1.7", "Pillow>=10.0", # Renders the latest camera capture as Unicode half-blocks in the TUI # (MESHTASTIC_UI_TUI_CAMERA=1). Terminal-agnostic — no kitty / sixel # dependency. Pure Python, tiny. "rich-pixels>=3.0", ] ui-min = ["opencv-python-headless>=4.9", "numpy>=1.26"] [project.scripts] meshtastic-mcp = "meshtastic_mcp.__main__:main" # Live TUI wrapping run-tests.sh — shells out to the same script the plain # CLI uses, tails pytest-reportlog for per-test state, and polls the device # list at startup + post-run (port lock forces it to stay idle during the run). meshtastic-mcp-test-tui = "meshtastic_mcp.cli.test_tui:main" [build-system] requires = ["hatchling"] build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/meshtastic_mcp"]