# FleetMind MCP Server **Industry-standard Model Context Protocol server for AI-powered delivery dispatch management** [![FastMCP](https://img.shields.io/badge/FastMCP-2.13.0-blue)](https://github.com/jlowin/fastmcp) [![Python](https://img.shields.io/badge/Python-3.10%2B-brightgreen)](https://www.python.org/) [![License](https://img.shields.io/badge/License-MIT-yellow)](LICENSE) --- ## Overview FleetMind MCP Server provides 18 AI tools and 2 real-time resources for managing delivery dispatch operations through any MCP-compatible client (Claude Desktop, Continue, Cline, etc.). **What is MCP?** The Model Context Protocol (MCP) is an open standard that enables AI assistants to securely connect to external data sources and tools. Think of it as a universal API for AI agents. --- ## Quick Start ### 1. Installation ```bash # Clone the repository git clone https://github.com/your-org/fleetmind-mcp.git cd fleetmind-mcp # Install dependencies pip install -r requirements.txt # Configure environment variables cp .env.example .env # Edit .env with your credentials ``` ### 2. Configure Environment Edit `.env` file: ```ini # Database (required) DB_HOST=your-postgres-host.com DB_PORT=5432 DB_NAME=fleetmind DB_USER=your_db_user DB_PASSWORD=your_db_password # Google Maps API (required for geocoding) GOOGLE_MAPS_API_KEY=your_google_maps_key ``` ### 3. Test the Server ```bash # Test server imports and database connectivity python -c "import server; print('FleetMind MCP Server ready!')" ``` ### 4. Run with Claude Desktop Add to your Claude Desktop config (`claude_desktop_config.json`): ```json { "mcpServers": { "fleetmind": { "command": "python", "args": ["F:\\path\\to\\fleetmind-mcp\\server.py"], "env": { "GOOGLE_MAPS_API_KEY": "your_api_key", "DB_HOST": "your-host.com", "DB_NAME": "fleetmind", "DB_USER": "your_user", "DB_PASSWORD": "your_password" } } } } ``` Restart Claude Desktop. You'll now see FleetMind tools available! --- ## Architecture ### **Before (Gradio UI):** ``` User → Gradio Web UI → ChatEngine → Gemini/Claude API → Tools → Database ``` ### **After (MCP Protocol):** ``` User → Claude Desktop (or any MCP client) → MCP Protocol → FleetMind Server → Tools → Database └→ Continue.dev ────────────────────────┘ └→ Cline ───────────────────────────────┘ └→ Custom Apps ──────────────────────────┘ ``` **Benefits:** - ✅ Use from multiple clients (Claude Desktop, VS Code, mobile apps) - ✅ 46% less code (no UI, no provider abstractions) - ✅ Industry-standard protocol (MCP) - ✅ Better testing (isolated tools) - ✅ Scalable architecture --- ## Features ### **18 AI Tools** #### Order Management (10 tools) - `geocode_address` - Convert addresses to GPS coordinates - `calculate_route` - Find shortest route between locations - `create_order` - Create new delivery orders - `count_orders` - Count orders with filters - `fetch_orders` - Retrieve orders with pagination - `get_order_details` - Get complete order information - `search_orders` - Search by customer/ID - `get_incomplete_orders` - List active deliveries - `update_order` - Update order details (auto-geocoding) - `delete_order` - Permanently remove orders #### Driver Management (8 tools) - `create_driver` - Onboard new drivers - `count_drivers` - Count drivers with filters - `fetch_drivers` - Retrieve drivers with pagination - `get_driver_details` - Get driver info + reverse-geocoded location - `search_drivers` - Search by name/plate/ID - `get_available_drivers` - List drivers ready for dispatch - `update_driver` - Update driver information - `delete_driver` - Remove drivers from fleet ### **2 Real-Time Resources** - `orders://all` - Live orders dataset (last 30 days, max 1000) - `drivers://all` - Live drivers dataset with locations Resources provide AI assistants with contextual data for smarter responses. --- ## Usage Examples ### Example 1: Create an Order **User (in Claude Desktop):** "Create an urgent delivery order for Sarah Johnson at 456 Oak Ave, San Francisco CA. Phone: 555-1234." **Claude automatically:** 1. Calls `geocode_address("456 Oak Ave, San Francisco CA")` 2. Gets coordinates: `(37.7749, -122.4194)` 3. Calls `create_order(customer_name="Sarah Johnson", delivery_address="456 Oak Ave, SF CA 94103", delivery_lat=37.7749, delivery_lng=-122.4194, customer_phone="555-1234", priority="urgent")` 4. Returns: `"Order ORD-20251114163800 created successfully!"` ### Example 2: Assign Driver **User:** "Assign order ORD-20251114163800 to the nearest available driver" **Claude automatically:** 1. Calls `get_order_details("ORD-20251114163800")` → Gets delivery location 2. Calls `get_available_drivers(limit=10)` → Lists available drivers 3. Calls `calculate_route()` for each driver → Finds nearest 4. Calls `update_order(order_id="ORD-20251114163800", assigned_driver_id="DRV-...", status="assigned")` 5. Returns: `"Order assigned to John Smith (DRV-20251110120000), 5.2 km away, ETA 12 mins"` ### Example 3: Track Orders **User:** "Show me all urgent orders that haven't been delivered yet" **Claude automatically:** 1. Calls `fetch_orders(status="pending", priority="urgent")` OR 2. Calls `fetch_orders(status="in_transit", priority="urgent")` 3. Returns formatted list with customer names, addresses, and deadlines --- ## API Reference ### Tool: `create_order` Create a new delivery order. **Parameters:** - `customer_name` (string, required): Full name - `delivery_address` (string, required): Complete address - `delivery_lat` (float, required): Latitude from geocoding - `delivery_lng` (float, required): Longitude from geocoding - `customer_phone` (string, optional): Phone number - `customer_email` (string, optional): Email address - `priority` (enum, optional): `standard` | `express` | `urgent` (default: `standard`) - `weight_kg` (float, optional): Package weight (default: 5.0) - `special_instructions` (string, optional): Delivery notes - `time_window_end` (string, optional): Deadline in ISO format (default: +6 hours) **Returns:** ```json { "success": true, "order_id": "ORD-20251114163800", "status": "pending", "customer": "Sarah Johnson", "address": "456 Oak Ave, San Francisco CA 94103", "deadline": "2025-11-14T22:38:00", "priority": "urgent", "message": "Order created successfully!" } ``` ### Tool: `calculate_route` Calculate shortest route between two locations. **Parameters:** - `origin` (string, required): Starting location (address or "lat,lng") - `destination` (string, required): Ending location (address or "lat,lng") - `mode` (enum, optional): `driving` | `walking` | `bicycling` | `transit` (default: `driving`) - `alternatives` (boolean, optional): Return multiple routes (default: false) - `include_steps` (boolean, optional): Include turn-by-turn directions (default: false) **Returns:** ```json { "success": true, "origin": "San Francisco City Hall, CA 94102, USA", "destination": "Oakland Airport, CA 94621, USA", "distance": {"meters": 25400, "text": "25.4 km"}, "duration": {"seconds": 1680, "text": "28 mins"}, "mode": "driving", "route_summary": "I-880 N", "confidence": "high (Google Maps API)" } ``` ### Resource: `orders://all` Real-time orders dataset for AI context. **Contains:** All orders from last 30 days (max 1000) **Fields:** order_id, customer_name, delivery_address, status, priority, created_at, assigned_driver_id **Usage:** AI automatically references this when answering questions like "How many pending orders?" or "What's the oldest unassigned order?" ### Resource: `drivers://all` Real-time drivers dataset with current locations. **Contains:** All drivers sorted alphabetically **Fields:** driver_id, name, status, vehicle_type, vehicle_plate, current_lat, current_lng, last_location_update **Usage:** AI automatically references this for questions like "How many active drivers?" or "Which driver is closest to downtown?" --- ## Database Schema ### `orders` table (26 columns) ```sql CREATE TABLE orders ( order_id VARCHAR(50) PRIMARY KEY, customer_name VARCHAR(255) NOT NULL, customer_phone VARCHAR(20), customer_email VARCHAR(255), delivery_address TEXT NOT NULL, delivery_lat DECIMAL(10,8), delivery_lng DECIMAL(11,8), status VARCHAR(20) CHECK (status IN ('pending','assigned','in_transit','delivered','failed','cancelled')), priority VARCHAR(20) CHECK (priority IN ('standard','express','urgent')), time_window_end TIMESTAMP, assigned_driver_id VARCHAR(50), payment_status VARCHAR(20) CHECK (payment_status IN ('pending','paid','cod')), weight_kg DECIMAL(10,2), special_instructions TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- ... additional fields ); ``` ### `drivers` table (15 columns) ```sql CREATE TABLE drivers ( driver_id VARCHAR(50) PRIMARY KEY, name VARCHAR(255) NOT NULL, phone VARCHAR(20), email VARCHAR(255), status VARCHAR(20) CHECK (status IN ('active','busy','offline','unavailable')), vehicle_type VARCHAR(50), vehicle_plate VARCHAR(20), capacity_kg DECIMAL(10,2), skills JSONB, current_lat DECIMAL(10,8), current_lng DECIMAL(11,8), last_location_update TIMESTAMP, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP, updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ); ``` --- ## Development ### Project Structure ``` fleetmind-mcp/ ├── server.py # Main MCP server (882 lines) ├── pyproject.toml # Package configuration ├── mcp_config.json # MCP metadata ├── requirements.txt # Dependencies ├── .env # Environment variables │ ├── chat/ │ ├── tools.py # 18 tool handlers (2099 lines) │ └── geocoding.py # Geocoding service (429 lines) │ ├── database/ │ ├── connection.py # Database layer (221 lines) │ └── schema.py # Schema definitions (213 lines) │ ├── logs/ # Server logs └── docs/ # Documentation ``` ### Running Tests ```bash # Install test dependencies pip install pytest pytest-asyncio # Run tests pytest tests/ ``` ### Testing with MCP Inspector ```bash # Official MCP protocol testing tool npx @modelcontextprotocol/inspector python server.py ``` --- ## Deployment ### Option 1: Local Development ```bash python server.py ``` ### Option 2: Docker Container ```dockerfile FROM python:3.11-slim WORKDIR /app COPY requirements.txt . RUN pip install --no-cache-dir -r requirements.txt COPY . . CMD ["python", "server.py"] ``` ```bash docker build -t fleetmind-mcp . docker run -d --env-file .env fleetmind-mcp ``` ### Option 3: Production Server For production, use a process manager like `supervisord` or `systemd`: ```ini # /etc/systemd/system/fleetmind-mcp.service [Unit] Description=FleetMind MCP Server After=network.target [Service] Type=simple User=fleetmind WorkingDirectory=/opt/fleetmind-mcp Environment="PATH=/opt/fleetmind-mcp/venv/bin" EnvironmentFile=/opt/fleetmind-mcp/.env ExecStart=/opt/fleetmind-mcp/venv/bin/python server.py Restart=always [Install] WantedBy=multi-user.target ``` --- ## Troubleshooting ### Error: "Cannot import name 'UserMessage'" **Solution:** Prompts are currently disabled pending FastMCP API confirmation. Tools and resources work perfectly. ### Error: "Database connection failed" **Check:** 1. `.env` file has correct credentials 2. PostgreSQL server is running 3. Database `fleetmind` exists 4. Network allows connection (check firewall/security groups) ### Error: "Geocoding failed" **Check:** 1. `GOOGLE_MAPS_API_KEY` is set in `.env` 2. API key has Geocoding API enabled 3. API key has sufficient quota **Fallback:** Server automatically uses mock geocoding if API unavailable. --- ## Migration from Gradio UI ### What Changed? | Component | Gradio Version | MCP Version | |-----------|----------------|-------------| | UI | Gradio web interface | Any MCP client | | AI Provider | Gemini/Claude via API | Client handles AI | | Tool Execution | chat/tools.py handlers | Same handlers | | Database | PostgreSQL/Neon | Same database | | Geocoding | Google Maps API | Same API | ### What Stayed the Same? - ✅ All 18 tool handlers (unchanged) - ✅ Database schema (identical) - ✅ Geocoding logic (same) - ✅ Business logic (preserved) - ✅ .env configuration (compatible) ### Migration Steps 1. **Backup your data:** `pg_dump fleetmind > backup.sql` 2. **Install MCP dependencies:** `pip install -r requirements.txt` 3. **Test server:** `python -c "import server"` 4. **Configure Claude Desktop:** Add server to `claude_desktop_config.json` 5. **Test with Claude:** Create a test order 6. **Archive old code:** Move `ui/`, `chat/providers/`, `chat/chat_engine.py` to `archive/` --- ## Contributing We welcome contributions! Please: 1. Fork the repository 2. Create a feature branch (`git checkout -b feature/amazing-feature`) 3. Commit your changes (`git commit -m 'Add amazing feature'`) 4. Push to the branch (`git push origin feature/amazing-feature`) 5. Open a Pull Request --- ## License MIT License - see [LICENSE](LICENSE) file for details. --- ## Support - **Issues:** https://github.com/your-org/fleetmind-mcp/issues - **Documentation:** https://docs.fleetmind.com - **Discord:** https://discord.gg/fleetmind --- ## Roadmap - [x] Convert all 18 tools to MCP format - [x] Add 2 real-time resources (orders, drivers) - [ ] Add prompt templates (pending FastMCP API confirmation) - [ ] Add assignment optimization algorithm - [ ] Add route optimization for multi-stop deliveries - [ ] Add real-time driver tracking via WebSocket - [ ] Add analytics dashboard - [] Mobile app MCP client --- **Built with ❤️ using [FastMCP](https://github.com/jlowin/fastmcp)**