MCP Server
Description
# MCP Server A lightweight wrapper around DroneKit that exposes vehicle APIs as asynchronous MCP tools over HTTP (SSE) or messaging. ## 📖 Overview `mcp_server.py` does the following: 1. Loads configuration from a `.env` file (expects `DRONE_CONN` and `GOOGLE_MAPS_API_KEY`). 2…
About
# MCP Server A lightweight wrapper around DroneKit that exposes vehicle APIs as asynchronous MCP tools over HTTP (SSE) or messaging. ## 📖 Overview `mcp_server.py` does the following: 1. Loads configuration from a `.env` file (expects `DRONE_CONN` and `GOOGLE_MAPS_API_KEY`). 2. Connects to a DroneKit `Vehicle` using…
Details
- Author
- Real-Time-Robotics
- Downloads
- 116
- Categories
- Other
Jump to
- Exposes arm, takeoff, land, and mode switching tools
- Retrieves global and local position, home location, and distance to home
- Returns attitude, battery status, and full vehicle status summary
- Supports mission upload and set home operations
- Works over HTTP/SSE with DroneKit and ArduPilot SITL
- Integrates with Claude Desktop for natural‑language drone control
Setting up with Highlight
This MCP is not yet compatible with Highlight’s one-click setup. However, you can still use it with Highlight by following these steps:
- Download and install Highlight from highlightai.com/download
- Navigate to the plugins tab and select "Add Custom Plugin"
-
Configure the plugin with the settings below
Plugin Name
MCP ServerCommand (node, npx, python, etc.)Please refer to the README for specific instructions on how to obtain API keys or other required environment variables.
- Enable "Start Automatically" if you want the plugin to start when Highlight launches
From the repository
Clone the repository, create a Python virtual environment (3.8+), install dependencies from requirement.txt, and create a .env file with DRONE_CONN (MAVLink connection string) and GOOGLE_MAPS_API_KEY. Run mcp_server.py; it listens on http://0.0.0.0:8080 by default. Configure Claude Desktop by setting the command and argument fields in claude_desktop_config.json using the paths from which python and pwd.
Claude Desktop / Cursor
Paste into your MCP client config file to install this server.
{
"mcpServers": {
"mcp server": {
"rtr-mcp-server": {
"command": "python3",
"args": [
"-m",
"venv",
"venv"
]
}
}
}
}
McpServers
{
"rtr-mcp-server": {
"command": "python3",
"args": [
"-m",
"venv",
"venv"
]
}
}
MCP Server
A lightweight wrapper around DroneKit that exposes vehicle APIs as asynchronous MCP tools over HTTP (SSE) or messaging.
📖 Overview
mcp_server.py does the following:
1. Loads configuration from a .env file (expects DRONE_CONN and GOOGLE_MAPS_API_KEY).
2. Connects to a DroneKit Vehicle using DRONE_CONN.
3. Instantiates a FastMCP server (mcp = FastMCP(name="drone-mcp")).
4. Registers a suite of async functions decorated with @mcp.tool()—each corresponding to a common flight-controller operation (e.g., arm, takeoff, goto, mission upload).
5. Runs the MCP server (mcp.run()), which listens to http://0.0.0.0:8080 by default and exposes those tools over SSE/HTTP.
Clients (for example, Claude Desktop or any HTTP/SSE-capable tool) can send simple text commands or JSON payloads to invoke these MCP tools.
📋 Prerequisites
Before you begin, ensure your system meets the following requirements:
- Operating System: Windows 10/11, macOS 10.15+, or a modern Linux distribution (Ubuntu 20.04+ recommended).
- Python 3.8+ installed and accessible on your PATH.
- Git (for cloning this repository).
- Internet connection (for downloading libraries, geocoding, and connecting Claude Desktop).
- A Google Maps API Key with the Geocoding API enabled. Create or retrieve one from Google Cloud Console → APIs & Services → Credentials.
- Claude Desktop (follow this link for download)
Supported Platforms
- Linux / Ubuntu (20.04+ recommended) - Windows 10/11 - macOS 10.15+ (Intel or Apple silicon)> [!NOTE]Important for macOS users: Because ArduPilot’s SITL and many DroneKit tools are
> tested primarily on Linux, macOS machines should run a Linux VM.
> The steps below explain how to set up Ubuntu inside VMware Fusion.
---
🖥️ Install ArduPilot for macOS users
1. Install VMware Fusion - Visit VMware Fusion Download - Download the installer for your macOS version (Intel or Apple Silicon). - Follow the on-screen instructions to install VMware Fusion.2. Download Ubuntu ISO
- Go to Ubuntu Releases (or a later LTS version, e.g., 22.04).
- Download the Desktop ISO (e.g., ubuntu-20.04.6-desktop-amd64.iso).
3. Create a New VM in VMware Fusion
- Open VMware Fusion → File → New → Create a custom virtual machine.
- Select the downloaded Ubuntu ISO as the installation source.
- Allocate at least 2 CPU cores and 4 GB RAM (6 GB+ recommended if you plan to run SITL and other tools).
- Assign a virtual disk of at least 20 GB.
- Finish the VM creation wizard and install Ubuntu inside the VM.
4. Setup ArduPilot by following this document
---
🧭 Install QGroundControl (QGC)
1. Visit this site to install QGroundControl.
2. Setup connection between VMware Fusion with QGC
- Open QGC → Logo on the top left → Application Settings → Comm Links → Add → Provide required info to init the connection.

🐍 Model Context Protocol (MCP) Server Setup
1. Clone this repository (or download and unzip):
git clone https://github.com/Real-Time-Robotics/rtr-mcp-server.git
cd rtr-mcp-server
2. Create and activate a Python virtual environment (recommended):
python3 -m venv venv
source venv/bin/activate # on macOS/Linux
.\venv\Scripts\Activate.ps1 # on Windows PowerShell
3. Install dependencies (make sure you’re inside the activated venv):
pip3 install --upgrade pip
pip3 install -r requirement.txt
> Note: If you plan to add more MCP tools (e.g., survey missions), you may need additional Python libraries. Refer to the code comments in mcp_server.py for any extra imports.
⚙️ Configuration
1. Create a file named .env in the project root with exactly these two variables:
touch .env
2. Set the MAVLink connection string in .env (the code expects DRONE_CONN)
DRONE_CONN="tcp:192.168.2.129:5763"
> Replace tcp:192.168.2.129:5763 with your ArduPilot’s address/port (e.g., udp:127.0.0.1:14550 or a real-hardware endpoint).
3. You must also set a Google Maps API key for geocoding:
GOOGLE_MAPS_API_KEY=<your Google Maps Geocoding API key>
Get an API key from Google Cloud Console and ensure the Geocoding API is enabled.

⚒️ Configure Claude to Connect with the MCP Server
1. In the rtr-mcp project, open a terminal and run:
which python
- Copy the full path displayed (e.g.,
/Users/yourname/projects/rtr-mcp/venv/bin/python). - You will use this value for the
"command" field in claude_desktop_config.json.2. Get the Project Root Path
- Still in the same terminal, run:
pwd
- Copy the printed directory (e.g.,
/Users/yourname/projects/rtr-mcp). - You will use this value for the
"argument" field in claude_desktop_config.json.
3. Open Claude Desktop → Claude → Settings → Developer → Edit Config

▶️ Running
1. Open VMware Fusion sim_vehicle.py -v ArduPilot -f quad -L DUNE --out udp:127.0.0.1:145551
The server will listen on http://0.0.0.0:8080 by default.
📡 Available MCP Tools
| Tool | Signature | Description |
|-----------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------|
| arm() | — | Arm (or disarm) the vehicle. |
| takeoff(altitude: float) | altitude — target altitude in meters | Execute a takeoff operation to the given relative altitude. |
| land() | — | Command the vehicle to land. |
| set_home() | — | Set the current position as the home/origin (for relative altitude). |
| Location / Position | | |
| location_global() | — | Get the vehicle’s global location (latitude, longitude, altitude) relative to MSL. |
| location_global_relative() | — | Get the vehicle’s global location with altitude relative to home. |
| home_location() | — | Retrieve the current home location (latitude, longitude, altitude). |
| get_location_local() | — | Return the vehicle’s local‐frame (NED) position as a dict: { "north": …, "east": …, "down": … }. |
| distance_home() | — | Compute 3D (if available) or 2D distance from current location to home, in meters. |
| Mode & Status | | |
| switch_mode(mode: str) | mode — flight mode name (e.g. "GUIDED", "LOITER", "RTL", "AUTO") | Change the vehicle’s flight mode. |
| status() | — | Return a summary of vehicle status: mode, armed state, battery, GPS fix, etc. |
| api_exception_info() | — | Return APIException’s class name and docstring (useful for debugging error cases). |
| Attitude & Sensors | | |
| get_attitude() | — | Return current vehicle attitude as { "pitch": …, "roll": …, "yaw": … } (in radians). |
| get_battery() | — | Return battery status: { "voltage": …, "current": …, "level": … }. |
| get_rangefinder() | — | Return the rangefinder distance in meters (if the vehicle has a rangefinder sensor). |
| get_gps_info() | — | Return GPS info dict: { "eph": …, "epv": …, "fix_type": …, "satellites_visible": … }. |
| RC & Channels | | |
| get_channel_overrides() | — | Return any RC channel overrides (rc_override map). |
| Parameters | | |
| get_parameter(name: str) | name — MAVLink parameter key | Get the current value of the specified parameter. |
| set_parameter(name: str, value) | name, value — parameter key & new value | Set a specific vehicle parameter to value. |
| Gimbal Control | | |
| get_gimbal_attitude() | — | Return current gimbal orientation as { "pitch": …, "roll": …, "yaw": … }. |
| set_gimbal_orientation(pitch: float, roll: float, yaw: float) | pitch, roll, yaw (degrees or radians) | Point the gimbal to the specified orientation. |
| target_location(lat: float, lon: float, alt: float) | lat, lon, alt — target GPS coordinates & altitude | Point the gimbal to a geographic Region of Interest (ROI). |
| release_gimbal() | — | Release control of the gimbal back to RC/manual mode. |
| Home & Geo Utilities | | |
| set_home(lat: float, lon: float, alt: float) | lat, lon, alt — new home GPS location & altitude | Override (or initially set) the vehicle’s home location. |
| home_location() | — | Return the vehicle’s current home location (latitude, longitude, altitude). |
| distance_home() | — | (Duplicate of above; returns the distance from current location to home in meters.) |
| Mission / Waypoints | | |
| get_command_sequence() | — | Download and return the current mission’s list of Command items (one entry per waypoint/command). |
| clear_all_mission() | — | Clear all mission waypoints on the vehicle. |
| create_mission(cmds: List[Dict[str, Any]]) | cmds — list of mission items (each a dict with type or command, lat, lon, alt, etc.) | Upload a new mission plan; items must follow DroneKit’s Command format. |
| readmission(file_name: str) | file_name — path to a JSON mission file | Read and return a mission plan from the specified file (used internally by create_plan_from_prompt). |
| upload_mission(file_name: str) | file_name — path to a JSON mission file | Upload a mission to the vehicle from a local file. |
| waypoints_info() | — | Return the number of waypoints in the current mission. |
| mission_survey(prompt: str) | prompt — natural-language specification of survey area (e.g. polygon points, altitude, overlap, camera) | Generate a loose grid survey mission (zigzag pattern) over a polygon; clears any existing mission and uploads the new survey plan. |
| create_plan_from_prompt(prompt: str, file_path: str) | prompt, file_path — string and output .plan filename | Parse a simple mission language (e.g. takeoff at <address> at altitude Xm, waypoint …, return to launch) to build a plan and save it to a .plan file. |
> [!TIP] If you invoke any mission/tool that interacts with the file system
> (e.g., readmission, upload_mission, create_plan_from_prompt), ensure your
> working directory and file paths are correct, or supply absolute paths.
🔧 Extending
To add a new tool:
1. Define an async function in mcp_server.py.
2. Decorate it with @mcp.tool(), @mcp.resource(), or @mcp.prompt().
3. Use the global vehicle object and mavutil to implement the logic.
4. Restart the server.
🤝 Contributing
1. Fork the repo.
2. Create a feature branch or bugfix.
3. Submit a pull request with a clear description.
4. Ensure new tools include docstrings and basic error handling.
📄 License
MIT © Real-Time Robotics
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.



