| # FleetMind MCP Server | |
| **Industry-standard Model Context Protocol server for AI-powered delivery dispatch management** | |
| [](https://github.com/jlowin/fastmcp) | |
| [](https://www.python.org/) | |
| [](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)** | |