The Repository key named a repo that was never created and 404'd for everyone, which PyPI would have frozen into the version permanently. It now points at warehack.ing/mcbebop on Gitea, which is public and anonymously reachable, with Homepage on the docs site and an Issues link. All three verified with an unauthenticated request.
130 lines
3.8 KiB
TOML
130 lines
3.8 KiB
TOML
[project]
|
|
name = "mcbebop"
|
|
version = "2026.10.02"
|
|
description = "MCP server for the Parrot Bebop 2 drone: telemetry, camera, files, and every ARSDK command"
|
|
readme = "README.md"
|
|
requires-python = ">=3.12"
|
|
# Our own code is MIT. The vendored arsdk-xml/ is Parrot SA's, BSD-3-Clause,
|
|
# and it ships in both artifacts because the package cannot decode a single
|
|
# command without it, so the distribution as a whole is both.
|
|
license = "MIT AND BSD-3-Clause"
|
|
license-files = ["LICENSE", "LICENSE-arsdk-xml"]
|
|
authors = [{name = "Ryan Malloy", email = "ryan@supported.systems"}]
|
|
keywords = ["mcp", "drone", "parrot", "bebop", "arsdk", "fastmcp"]
|
|
classifiers = [
|
|
"Development Status :: 3 - Alpha",
|
|
"Intended Audience :: Developers",
|
|
"Programming Language :: Python :: 3.12",
|
|
"Programming Language :: Python :: 3.13",
|
|
"Topic :: Scientific/Engineering",
|
|
]
|
|
dependencies = [
|
|
# 4.x is the current family; <5 because FastMCP has moved import paths
|
|
# across majors before (mcvnc was broken by the 3 -> 4 move).
|
|
"fastmcp>=4.0.10,<5",
|
|
"pydantic-settings>=2.7",
|
|
"zeroconf>=0.147", # mDNS discovery of _arsdk-090c._udp
|
|
"pillow>=11.0", # downscale camera frames before they reach the model
|
|
]
|
|
|
|
[project.urls]
|
|
Homepage = "https://bebop-2.warehack.ing"
|
|
Repository = "https://git.supported.systems/warehack.ing/mcbebop"
|
|
Issues = "https://git.supported.systems/warehack.ing/mcbebop/issues"
|
|
|
|
[project.scripts]
|
|
mcbebop = "mcbebop.server:main"
|
|
|
|
[build-system]
|
|
requires = ["uv_build>=0.11.3,<0.12.0"]
|
|
build-backend = "uv_build"
|
|
|
|
[tool.uv.build-backend]
|
|
# Err toward excluding. This repo sits next to a real aircraft, and `captures/`
|
|
# holds video of the owner's home plus `ckcm.bin` system logs that carry the
|
|
# serial, the CPU id and a real GPS fix together. None of it may ever reach an
|
|
# sdist, which is immutable and mirrored within minutes of upload.
|
|
#
|
|
# `.gitignore` does NOT protect this: it governs git, and source-exclude
|
|
# governs the sdist. A file can easily be in one and not the other, so the
|
|
# patterns below are deliberately broader than the directories that exist
|
|
# today -- a capture dropped into a new directory next year is still excluded.
|
|
# test_packaging.py asserts both halves stay in agreement.
|
|
source-exclude = [
|
|
# Operator-private context and anything credential-shaped.
|
|
"CLAUDE.md",
|
|
".env",
|
|
".env.*",
|
|
".mcp.json",
|
|
".claude",
|
|
".claude/**",
|
|
# Dev-only trees. Tests carry fixtures copy-pasted from a live aircraft.
|
|
"tests",
|
|
"tests/**",
|
|
"docs",
|
|
"docs/**",
|
|
"scripts",
|
|
"scripts/**",
|
|
"*.ipynb",
|
|
# Captures off the aircraft, at any depth, plus log dumps.
|
|
"captures",
|
|
"captures/**",
|
|
"**/captures/**",
|
|
"**/logs/**",
|
|
"ckcm*",
|
|
"**/ckcm*",
|
|
# Recorded media and binary blobs by extension, so a stray file in a
|
|
# directory nobody thought to list is still caught.
|
|
"*.rtpcap",
|
|
"*.raw",
|
|
"*.h264",
|
|
"*.bin",
|
|
"*.pcap",
|
|
"*.pcapng",
|
|
"*.mp4",
|
|
"*.jpg",
|
|
"*.jpeg",
|
|
"*.png",
|
|
"*.wav",
|
|
"*.ulg",
|
|
"**/*.rtpcap",
|
|
"**/*.raw",
|
|
"**/*.h264",
|
|
"**/*.bin",
|
|
"**/*.jpg",
|
|
"**/*.jpeg",
|
|
"**/*.png",
|
|
# Caches and build output. .pyc files embed the absolute build path, which
|
|
# leaks a username and the local directory layout.
|
|
"**/__pycache__",
|
|
"**/__pycache__/**",
|
|
"*.pyc",
|
|
"**/*.pyc",
|
|
".pytest_cache",
|
|
".pytest_cache/**",
|
|
".ruff_cache",
|
|
".ruff_cache/**",
|
|
".venv",
|
|
".venv/**",
|
|
"dist",
|
|
"dist/**",
|
|
"build",
|
|
"build/**",
|
|
"*.egg-info",
|
|
]
|
|
|
|
[dependency-groups]
|
|
dev = ["ruff>=0.16", "pytest>=8.0", "pytest-asyncio>=0.25"]
|
|
|
|
[tool.pytest.ini_options]
|
|
asyncio_mode = "auto"
|
|
markers = ["drone: needs a real Bebop 2 on the network (run with '-m drone')"]
|
|
addopts = "-m 'not drone'"
|
|
|
|
[tool.ruff]
|
|
line-length = 110
|
|
target-version = "py312"
|
|
|
|
[tool.ruff.lint]
|
|
select = ["E", "F", "I", "W", "UP", "B", "SIM", "RUF"]
|