Flight Control MCP
A read-only API for querying and retrieving contextual information about devices and fleets using the Flight Control MCP server.
mcp-server
Model Context Protocol (MCP) server for Flight Control
Overview
The MCP server provides a read-only API layer for querying and retrieving contextual information about devices and fleets managed by Flight Control. It is designed for safe external integration, reporting, and automation, exposing a REST API that supports filtering and selector-based queries. The MCP server leverages the flightctl-python-client for backend communication and enforces authentication compatible with Flight Control's authorization model.
Building locally
To build the container image locally using Podman, run:
podman build -t mcp-server:latest .
This will create a local image named mcp-server:latest
that you can use to run the server.
Pre-built Container Images
โ Ready-to-use images are automatically published to quay.io!
# Pull the latest stable image
docker pull quay.io/flightctl/flightctl-mcp:latest
# Run immediately with streamable-http transport
docker run -p 8000:8000 quay.io/flightctl/flightctl-mcp:latest
Automated Publishing
- ๐ Automatic builds: Every commit merged to
main
triggers a new build - โ Quality assured: Only builds after passing all tests (linting, type checking, unit tests)
- ๐ Security scanned: All images are scanned for vulnerabilities with Trivy
- ๐๏ธ Multi-platform: Available for both
linux/amd64
andlinux/arm64
- ๐ท๏ธ Smart tagging: Images tagged with
latest
, branch name, and commit SHA
For maintainers: See CONTAINER-PUBLISHING.md for setup instructions and workflow details.
Running with Podman or Docker
Example: Using Automatic Configuration (Recommended)
If you've run flightctl login
, you can mount the config directory. Note: The server now defaults to streamable-http
transport for better web-based integration.
{
"mcpServers": {
"mcp-server": {
"command": "podman",
"args": [
"run",
"-i",
"--rm",
"-p", "8000:8000",
"-v", "~/.config/flightctl:/root/.config/flightctl:ro",
"-e", "MCP_TRANSPORT",
"-e", "MCP_HOST",
"-e", "MCP_PORT",
"quay.io/flightctl/flightctl-mcp:latest"
],
"env": {
"MCP_TRANSPORT": "streamable-http",
"MCP_HOST": "0.0.0.0",
"MCP_PORT": "8000"
}
}
}
}
Example: Using Environment Variables
For environments where mounting the config file isn't possible:
{
"mcpServers": {
"mcp-server": {
"command": "podman",
"args": [
"run",
"-i",
"--rm",
"-p", "8000:8000",
"-e", "API_BASE_URL",
"-e", "OIDC_TOKEN_URL",
"-e", "OIDC_CLIENT_ID",
"-e", "REFRESH_TOKEN",
"-e", "INSECURE_SKIP_VERIFY",
"-e", "LOG_LEVEL",
"-e", "MCP_TRANSPORT",
"-e", "MCP_HOST",
"-e", "MCP_PORT",
"quay.io/flightctl/flightctl-mcp:latest"
],
"env": {
"API_BASE_URL": "https://api.flightctl.example.com",
"OIDC_TOKEN_URL": "https://auth.flightctl.example.com/realms/flightctl/protocol/openid-connect/token",
"OIDC_CLIENT_ID": "flightctl",
"REFRESH_TOKEN": "REDACTED",
"INSECURE_SKIP_VERIFY": "false",
"LOG_LEVEL": "INFO",
"MCP_TRANSPORT": "streamable-http",
"MCP_HOST": "0.0.0.0",
"MCP_PORT": "8000"
}
}
}
}
Transport Configuration
The MCP server supports three transport methods with stdio
as the default for maximum compatibility:
STDIO (Default - Most Compatible)
- Best for: Local tools, command-line scripts, integrations with clients like Claude Desktop
- Configuration: Set
MCP_TRANSPORT=stdio
(default) - Why default: Maximum compatibility with existing MCP clients
Streamable HTTP (Recommended for Web Deployments)
- Best for: Web-based deployments, microservices, exposing MCP over a network
- Default endpoint:
http://127.0.0.1:8000/mcp
- Configuration: Set
MCP_TRANSPORT=streamable-http
- Note: Requires MCP clients that support the new streamable-http transport
SSE (Server-Sent Events)
- Best for: Legacy deployments that specifically require SSE
- Configuration: Set
MCP_TRANSPORT=sse
- Default endpoint:
http://127.0.0.1:8000/sse
Authentication Setup
The MCP server uses OIDC/OAuth2 refresh tokens for authentication. To obtain the required credentials:
-
OIDC_TOKEN_URL: This is typically in the format
https://your-auth-server/realms/your-realm/protocol/openid-connect/token
- If you only have the base realm URL (e.g.,
https://auth.example.com/realms/flightctl
), the server will automatically append/protocol/openid-connect/token
- If you only have the base realm URL (e.g.,
-
REFRESH_TOKEN: Obtain this from your Flight Control authentication system
- This token should have appropriate permissions to read Flight Control resources
-
OIDC_CLIENT_ID: Usually
flightctl
(this is the default if not specified)
Configuration
The MCP server supports two configuration methods:
1. Automatic Configuration (Recommended)
If you've run flightctl login
, the server will automatically read configuration from ~/.config/flightctl/client.yaml
. This includes:
- API server URL
- OIDC authentication settings
- SSL certificate configuration
- Refresh tokens
2. Environment Variable Configuration
The following environment variables can override or supplement the automatic configuration:
- API_BASE_URL: Base URL for the Flight Control API (e.g.,
https://api.flightctl.example.com
) - Optional (read from config file) - OIDC_TOKEN_URL: Full URL to the OIDC token endpoint (e.g.,
https://auth.flightctl.example.com/realms/flightctl/protocol/openid-connect/token
) - Optional (read from config file) - OIDC_CLIENT_ID: OIDC client identifier (defaults to
flightctl
) - Optional - REFRESH_TOKEN: OAuth2 refresh token for authentication - Optional (read from config file)
- INSECURE_SKIP_VERIFY: Skip SSL certificate verification (
true
/false
) - Optional (read from config file) - CA_CERT_PATH: Path to custom CA certificate file for SSL verification - Optional
- LOG_LEVEL: Logging level (
DEBUG
,INFO
,WARNING
,ERROR
) - Optional (defaults toINFO
)
3. MCP Transport Configuration
The following environment variables control the MCP server transport and network settings:
- MCP_TRANSPORT: Transport mechanism (
stdio
,sse
,streamable-http
) - Optional (defaults tostdio
) - MCP_HOST: Host to bind to for HTTP transports - Optional (defaults to
127.0.0.1
) - MCP_PORT: Port to listen on for HTTP transports - Optional (defaults to
8000
) - MCP_PATH: Path for the MCP endpoint - Optional (defaults to
/mcp
for streamable-http) - MCP_LOG_LEVEL: Server log level (
debug
,info
,warning
,error
) - Optional (defaults toinfo
)
SSL Certificate Handling
The server properly handles SSL certificates in the following priority:
- Custom CA Certificate: If
CA_CERT_PATH
is set, uses the specified certificate file - Skip SSL Verification: If
INSECURE_SKIP_VERIFY=true
, disables certificate verification (useful for development) - System CA Bundle: Uses the system's default certificate authority bundle (production default)
Logging
The server uses file-based logging to avoid conflicts with the MCP protocol on stdio:
- Log Location:
~/.local/share/flightctl-mcp/flightctl-mcp.log
- Log Rotation: Automatic rotation at 10MB with 5 backup files
- Log Levels: Configurable via
LOG_LEVEL
environment variable - Structured Logging: Includes timestamps, component names, and detailed error context
Error Handling
The server provides robust error handling:
- Specific Exceptions: Uses typed exceptions (
AuthenticationError
,APIError
,FlightControlError
) - Detailed Logging: All errors are logged with full context
Running the Server
Local Development
# Run with default stdio transport
python main.py
# Run with streamable-http transport (for web deployments)
MCP_TRANSPORT=streamable-http python main.py
# Run with custom HTTP configuration
MCP_TRANSPORT=streamable-http MCP_HOST=0.0.0.0 MCP_PORT=8080 python main.py
Accessing the HTTP Endpoint
When running with HTTP transport, the MCP endpoint will be available at:
- Streamable HTTP:
http://127.0.0.1:8000/mcp
(default) - SSE:
http://127.0.0.1:8000/sse
Client Connection Examples
For HTTP clients (streamable-http):
from fastmcp import Client
# Connect to streamable-http server
client = Client("http://127.0.0.1:8000/mcp")
For Claude Desktop (stdio):
{
"mcpServers": {
"flightctl": {
"command": "python",
"args": ["main.py"],
"env": {
"MCP_TRANSPORT": "stdio"
}
}
}
}
API Endpoints
The MCP server exposes the following tool endpoints:
Device Management
query_devices
: Query and filter devices using label and field selectorsrun_command_on_device
: Execute Linux commands on specific devices
Fleet Management
query_fleets
: Query and filter fleet configurations
Events and Monitoring
query_events
: Query system events and audit logs
Enrollment
query_enrollment_requests
: Query device enrollment requests
Configuration Management
query_repositories
: Query configuration repositoriesquery_resource_syncs
: Query resource synchronization status
Testing
Live Instance Testing
To test against your actual Flight Control instance:
# Ensure you have logged in first
flightctl login
# Run the live integration test
python test_live_instance.py
Unit Testing
# Run unit tests
python -m pytest test_flightctl_mcp.py -v
# Run with coverage
python -m pytest test_flightctl_mcp.py --cov=resource_queries --cov=main --cov=cli --cov-report=html
MCP Client Testing
# Test the MCP server with a simple client
python -c "
from fastmcp import Client
import asyncio
async def test():
client = Client('http://127.0.0.1:8000/mcp')
async with client:
tools = await client.list_tools()
print(f'Available tools: {[t.name for t in tools]}')
asyncio.run(test())
"
Troubleshooting
Common Issues
-
Server not starting: Check if the port is already in use
lsof -i :8000
-
Authentication failures: Verify your Flight Control credentials
flightctl login
-
Connection refused: Ensure the server is running and accessible
curl -v http://127.0.0.1:8000/mcp
-
Transport issues: Verify the transport configuration matches your client
# Check server logs tail -f ~/.local/share/flightctl-mcp/flightctl-mcp.log
Debug Mode
Enable debug logging for more detailed information:
MCP_LOG_LEVEL=debug LOG_LEVEL=DEBUG python main.py
Migration from STDIO
If you're migrating from the previous stdio-only version:
- Update your client configuration to use HTTP endpoints instead of stdio
- Set environment variables for host/port configuration if needed
- Update firewall rules if running on a remote server
- Test the connection using the provided client examples
The server will still support stdio transport if you set MCP_TRANSPORT=stdio
, maintaining backward compatibility.
Features
- Read-only querying of devices, fleets, events, enrollment requests, repositories, and resource syncs from Flight Control
- Support for filtering by labels and fields using Kubernetes-style selectors
- Context-rich JSON responses including metadata and links to related resources
- Secure OIDC/OAuth2 refresh tokenโbased authentication
- Remote device console access for executing commands on managed devices
- Automatic pagination handling for large result sets
Documentation
API endpoints, filtering options, and example requests will be described in the docs/ directory or in the OpenAPI specification.
License
This project is open source. See LICENSE for details.
Contributing
Issues and pull requests are welcome! Please see CONTRIBUTING.md for guidelines.
Related Servers
Google Campaign Manager 360 by CData
A read-only MCP server for Google Campaign Manager 360, powered by the CData JDBC Driver.
Salesforce Order Concierge
An ecommerce assistant for Salesforce, enabling interaction with orders, returns, and customer service operations.
Crypto MCP Server
Fetches real-time cryptocurrency prices from the CoinGecko API.
Image Analysis Server
Analyzes images using the GPT-4o-mini model via the OpenAI API.
Google Play Store
Integrates with Google Play Store command-line tools, enabling AI assistants to manage apps via the Play Console API.
PrestaShop MCP Server
A server for managing PrestaShop e-commerce stores through a unified product API.
Alibaba Cloud Observability
Access Alibaba Cloud observability products such as SLS, ARMS, and CloudMonitor.
MCP Google Map Server
Integrates Google Maps API for location-based queries and data processing.
VixMCP.Ai.Bridge
An MCP server that exposes VMware VIX operations for AI assistants and automation workflows.
AniList
AniList MCP server for accessing AniList API data