Skip to main content

DJI FlightHub 2 OpenAPI client, CLI and MCP server — control docks, drones, waylines, flight tasks, livestreams and 3D models from the terminal or from an AI agent.

Project description

DJI FlightHub 2 CLI — fh2

An unofficial, complete command-line client, Python SDK and MCP server for the DJI FlightHub 2 OpenAPI.

Manage projects, docks, aircraft, flight routes, missions, livestreams, map annotations and 3D reconstruction — from your terminal, from Python, or from an AI agent.

PyPI Python License CI

pip install flighthub2-cli
export FLIGHTHUB2_TOKEN="<your organization key>"

fh2 project list
fh2 device list --org
fh2 task list --sn 7CTXXXXXXXXXX --days 30

Why this exists

DJI publishes the FlightHub 2 OpenAPI reference on Apifox, but the documentation does not state the API base URL — the examples point at 127.0.0.1:30812. This project fills that gap and everything around it:

Base URL, documented https://es-flight-api-eu.djigate.com (EU) and https://es-flight-api-us.djigate.com (US). Pick with --region, or set --base-url for on-premises.
All 42 documented endpoints Every operation in the FlightHub 2 OpenAPI v0.1 reference, none omitted — verified by a test that diffs the code against the published spec.
Business errors handled FlightHub 2 answers HTTP 200 with code != 0 for most real failures. This client raises on those instead of silently returning junk.
Verified against the real API Not just mocks: every operation was run against a live FlightHub 2 organization, including the two object-storage upload flows DJI documents only half of. See docs/LIVE_VALIDATION.md — it also records the undocumented behaviour found on the way, and the four documented endpoints DJI's EU gateway does not actually serve.
Built for AI agents A machine-readable operation catalogue, a generic fh2 call, and a built-in MCP server — with a risk model that keeps an agent from launching an aircraft by accident.

Disclaimer. This is an independent project, not affiliated with or endorsed by SZ DJI Technology Co., Ltd. It talks to real drones and docks. Read Safety before using the write operations.


Install

pip install flighthub2-cli

With the MCP server for AI agents:

pip install "flighthub2-cli[mcp]"

Requires Python 3.11+.

Authentication

FlightHub 2 authenticates with an organization key (a JWT) sent as X-User-Token, plus a project UUID sent as X-Project-Uuid for project-scoped endpoints.

Get the organization key from: FlightHub 2 → My Organization → Organization Settings → FlightHub Sync → Organization Key

export FLIGHTHUB2_TOKEN="eyJhbGciOi..."
export FLIGHTHUB2_PROJECT_UUID="fa863413-0c9c-40ae-ba41-bfce0d078d48"
export FLIGHTHUB2_REGION="eu"          # or us

Or persist it in a config file (~/.config/flighthub2/config.toml):

fh2 config set --token "eyJhbGciOi..." --region eu
fh2 config set --project "fa863413-..." --profile production
fh2 config show          # token is redacted

Verify the whole chain in one command:

fh2 system ping

A key issued by the EU cloud is rejected by the US gateway with 401. If you get 401 with a token you know is valid, try the other --region.


Usage

Output is a table on a terminal and JSON when piped, so the same command serves people and scripts:

fh2 project list                    # pretty table
fh2 project list | jq '.[].uuid'    # JSON
fh2 project list -o json            # force JSON

Projects and devices

fh2 project list                              # all projects in the organization
fh2 project find "Nazionale_TEST"             # resolve a name to a UUID
fh2 project devices                           # devices in the current project
fh2 project sts-token                         # storage credentials for wayline upload
fh2 project add-member 1922165135267708928 --role project-admin

fh2 device list --org                         # every dock/aircraft in the organization
fh2 device state 7CTXXXXXXXXXX                # live state payload
fh2 device hms 7CTXXXXXXXXXX --language en    # health alerts

Flight routes (waylines)

fh2 wayline list
fh2 wayline find "Ricerca Primaria"
fh2 wayline download "Ricerca Primaria" -o ./routes/

Uploading a route takes three steps, because the file goes straight to object storage and only then gets registered. examples/upload_wayline.py does the whole thing:

pip install boto3
python examples/upload_wayline.py route.kmz "New Route"

Missions

fh2 task list --sn 7CTXXXXXXXXXX --days 30
fh2 task get <task-uuid>
fh2 task media <task-uuid>
fh2 task track <task-uuid> --geojson > flight.geojson

# always dry-run first
fh2 task create --name "Patrol" --sn 7CTX... --wayline "Ricerca Primaria" --dry-run
fh2 task create --name "Patrol" --sn 7CTX... --wayline "Ricerca Primaria" --yes

Livestream and forwarding

fh2 livestream start 7CTXXXXXXXXXX 52-0-0 --quality ultra_high_definition
fh2 converter create --name push-01 --sn 7CTX... --camera-index 52-0-0 --url rtmp://…
fh2 converter set <converter-id> --auto-push
fh2 converter list

Map annotations and 3D models

fh2 annotation create --name "Staging area" --type 0 --coordinates "[9.19,45.46]"
fh2 annotation create --name "Perimeter" --type 2 \
    --coordinates "[[[9.19,45.46],[9.20,45.46],[9.20,45.47]]]"

fh2 model list
fh2 model get 3279378
fh2 openmodel running

Run fh2 --help or fh2 <group> --help for the full reference.


For AI agents

This is the part that makes fh2 different from a hand-rolled wrapper. Three layers, from most to least structured.

1. MCP server

pip install "flighthub2-cli[mcp]"
fh2 mcp serve                  # read + write operations
fh2 mcp serve --read-only      # reads only
fh2 mcp serve --allow-dangerous # everything, including flight commands

Register it with any MCP client (Claude Desktop, Claude Code, Cursor):

{
  "mcpServers": {
    "flighthub2": {
      "command": "fh2",
      "args": ["mcp", "serve"],
      "env": {
        "FLIGHTHUB2_TOKEN": "eyJhbGciOi...",
        "FLIGHTHUB2_PROJECT_UUID": "fa863413-...",
        "FLIGHTHUB2_REGION": "eu"
      }
    }
  }
}

Each operation becomes one tool with a proper JSON Schema. Preview the surface without starting a server:

fh2 mcp tools --read-only

2. Discover and call from a shell

An agent that can run one shell command needs no integration at all:

fh2 schema                       # every operation + JSON Schema
fh2 schema --risk read           # only safe ones
fh2 schema -o task.create        # one operation in detail

fh2 call project.list
fh2 call task.list -a sn=7CTX... -a begin_at=1750000000 -a end_at=1760000000
fh2 call device.command --args-json '{"device_sn":"1ZN...","command":"return_home"}' --yes

3. Risk model

Every operation is classified, and the classification is enforced in the CLI, in fh2 call and in the MCP server:

Risk Meaning Guard
read Read-only. none
write Changes stored data. Reversible. none
dangerous Moves aircraft, takes control from an on-site pilot, spends reconstruction quota, or deletes data. requires --yes; hidden from MCP unless --allow-dangerous

--dry-run short-circuits every write: the request is built, validated and printed, but never sent.

fh2 --dry-run call task.create --args-json '{"name":"T","sn":"7CT...","wayline_uuid":"..."}'

Stable exit codes let a script branch on the failure type: 0 ok, 2 usage, 3 config, 4 auth, 5 not found, 6 FlightHub business error, 7 connection.


Python library

from flighthub2 import FlightHub2Client

with FlightHub2Client(token="...", project_uuid="...", region="eu") as fh:
    assert fh.system.status().healthy

    for project in fh.organization.list_projects(all_pages=True):
        print(project.uuid, project.name)

    for wayline in fh.waylines.list():
        print(wayline.id, wayline.name, wayline.template_types)

    task = fh.flight_tasks.get("<task-uuid>")
    print(task.status, task.folder_info)

Everything is typed with Pydantic models and tolerant of new server-side fields. Errors map to a real hierarchy:

from flighthub2 import BusinessError, AuthenticationError

try:
    fh.devices.command("1ZN...", "return_home")
except AuthenticationError as exc:
    print("bad token", exc.request_id)
except BusinessError as exc:
    print("FlightHub refused:", exc.code, exc.message)

Configuration reference

Environment variable CLI option Default
FLIGHTHUB2_TOKEN --token — (required)
FLIGHTHUB2_PROJECT_UUID --project / -p
FLIGHTHUB2_REGION --region eu
FLIGHTHUB2_BASE_URL --base-url from region
FLIGHTHUB2_LANGUAGE --language en
FLIGHTHUB2_TIMEOUT --timeout 30
FLIGHTHUB2_MAX_RETRIES 3
FLIGHTHUB2_CONFIG ~/.config/flighthub2/config.toml

Precedence: CLI option > environment > config file profile > default.


Safety

This tool drives real hardware. A few things worth knowing before you automate it:

  • device.command acts on a flying aircraft immediately.
  • device.acquire-control takes payload control away from whoever holds it, including an operator on site.
  • task.create with task_type=immediate launches the aircraft now.
  • model.create and openmodel.start consume reconstruction quota.
  • openmodel.delete / resource-delete destroy data.

All of the above are marked dangerous, need --yes, and are hidden from the MCP server by default. Use --dry-run while developing, and give agents a token scoped to a test project.


Development

git clone https://github.com/alecad/dji-flighthub2-cli
cd dji-flighthub2-cli
python -m venv .venv
source .venv/bin/activate       # Windows: .venv\Scripts\activate
pip install -e ".[dev,mcp]"

pytest                          # 372 unit tests, no network
ruff check . && ruff format --check . && mypy

The repository ships .vscode/launch.json and .vscode/settings.json, which Cursor and VS Code both read: open the folder and you get run/debug configurations for the CLI, the MCP server and the test suite, with breakpoints working out of the box.

Live tests run against the real API and are opt-in:

export FLIGHTHUB2_TOKEN=... FLIGHTHUB2_PROJECT_UUID=...
pytest --run-live                    # read-only calls
pytest --run-live --run-mutating     # also creates and deletes test data

See CONTRIBUTING.md.


Endpoint coverage

All 42 endpoints of the FlightHub 2 OpenAPI v0.1 reference (plus project.find and wayline.find, convenience lookups built on the list endpoints):

Group Operations
System system.status
Organization & projects project.list, project.find, project.sts-token, project.add-member, device.list-org, device.list
Device management device.state, device.hms, device.command, device.change-camera, device.change-lens, device.acquire-control, device.release-control, device.stream-quality, device.rtk-calibrate
Livestream livestream.start, converter.create, converter.set, converter.list, converter.delete ⚠️
Flight tasks task.create, task.update-status, task.list, task.get, task.media, task.track
Flight routes wayline.finish-upload, wayline.list, wayline.get, wayline.find
Map models model.list, model.get, model.create
Annotations annotation.create
Open modeling openmodel.obtain-token, openmodel.upload-callback, openmodel.resource-get, openmodel.resource-delete, openmodel.start, openmodel.stop, openmodel.get, openmodel.running, openmodel.delete

fh2 schema prints this catalogue as JSON, always in sync with the code — a test asserts it.

⚠️ The four converter.* (stream forwarder) endpoints are documented by DJI but returned 404 on the EU gateway during validation, while livestream.start on the same path prefix worked. They appear to be gated by region or licence tier. They are implemented and kept in the client because they may work on your deployment; the CLI explains the 404 if they do not. Details in docs/LIVE_VALIDATION.md.


Credits

Created and maintained by Alessio Caddeo.

If this saved you time, a ⭐ on the repository helps other people find it.

License

Licensed under the Apache License 2.0.

You may use, modify and redistribute this software freely, including commercially, provided you keep the copyright notice and the NOTICE file, which credit the original author and repository.

Copyright 2026 Alessio Caddeo
https://github.com/alecad/dji-flighthub2-cli

Keywords: DJI FlightHub 2 API, FlightHub 2 CLI, FlightHub 2 Python SDK, DJI Dock 2 / Dock 3 automation, DJI drone-in-a-box, FlightHub Sync OpenAPI, DJI wayline API, DJI flight task API, DJI livestream RTMP forwarding, DJI 3D reconstruction API, FlightHub 2 MCP server, DJI drone AI agent.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

flighthub2_cli-0.1.2.tar.gz (85.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

flighthub2_cli-0.1.2-py3-none-any.whl (80.7 kB view details)

Uploaded Python 3

File details

Details for the file flighthub2_cli-0.1.2.tar.gz.

File metadata

  • Download URL: flighthub2_cli-0.1.2.tar.gz
  • Upload date:
  • Size: 85.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for flighthub2_cli-0.1.2.tar.gz
Algorithm Hash digest
SHA256 ba1060a9a6fbd50bc6e0bfc61441925759762075c02e28d065a1942748fba425
MD5 64959adb51bee49ba7f1c68196b30ce8
BLAKE2b-256 576e25139b4d80cedc4b6776485e56771558c46a493193b64b83880cfc9f4e4b

See more details on using hashes here.

Provenance

The following attestation bundles were made for flighthub2_cli-0.1.2.tar.gz:

Publisher: release.yml on alecad/dji-flighthub2-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file flighthub2_cli-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: flighthub2_cli-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 80.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.14

File hashes

Hashes for flighthub2_cli-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 4fe48ae2e30dcfe517d4b1fbd5dbfc45542dce2fd8e7e148d5a5f97128f87240
MD5 dc46f22f2c35e78753197017d9e43e82
BLAKE2b-256 ee2b5759d28458ed0b5c3a31a47662b0cafca459bbff4dc17c1081bd5f1ad79b

See more details on using hashes here.

Provenance

The following attestation bundles were made for flighthub2_cli-0.1.2-py3-none-any.whl:

Publisher: release.yml on alecad/dji-flighthub2-cli

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page