Skip to main content
Glama
JPLopez23

delivery-mcp-server

by JPLopez23
README.md
# delivery-mcp-server

Servidor **MCP local** que planifica **rutas de vehiculos con capacidad y
ventanas de tiempo** (CVRPTW) para una flota de reparto de ultima milla. Hecho
para CC3067 *Redes* — Proyecto 1, punto 5 (servidor local propio, no trivial).

* Transporte: **stdio**, JSON delimitado por saltos de linea.
* Protocolo: **JSON-RPC 2.0 a mano** — sin SDK de MCP.
* Solver: **Google OR-Tools** (CVRPTW), con fallback automatico en Python puro
  **Clarke-Wright + 2-opt**.
* Almacenamiento: **SQLite**, creada y sembrada en el primer arranque.

Por que no es trivial: respeta capacidad por peso **y** por unidades, ventanas
de tiempo **duras** con tiempo de servicio por parada, el **turno del
conductor**, el retorno obligatorio al depot, y **reporta las entregas
infactibles con un motivo** en vez de fallar en silencio. Ademas permite
analisis "que pasaria si" (costo marginal de insertar una entrega) y
disrupciones de flota (vehiculo fuera de servicio -> reasignacion).

---

## Herramientas

| Herramienta | Parametros | Devuelve |
|---|---|---|
| `list_deliveries` | `date`, `status?` | entregas con peso, direccion y ventana horaria |
| `list_vehicles` | `depot_id?`, `only_active?` | flota con capacidad (kg/unidades) y turno |
| `plan_routes` | `date`, `vehicle_ids?`, `objective?` (`distance`\|`time`\|`balanced`), `traffic_factor?` | por vehiculo: secuencia de paradas, ETA, distancia, duracion; no asignadas + motivo; persiste el plan |
| `get_route_detail` | `route_id` | detalle parada por parada con carga acumulada |
| `evaluate_insertion` | `date`, `delivery_id` **o** `new_delivery` | km/min marginal por ruta activa, mejor posicion, factibilidad de capacidad y ventana |
| `commit_insertion` | `delivery_id`, `route_id`, `position` | inserta y recalcula los ETA |
| `mark_vehicle_out_of_service` | `vehicle_id`, `reason?` | marca inactivo, devuelve entregas huerfanas |
| `reassign_deliveries` | `delivery_ids[]`, `date` | redistribuye entre vehiculos activos; lista lo que no cupo |
| `update_delivery_status` | `delivery_id`, `status` | confirma el cambio |
| `export_route_sheet` | `route_id`, `format` (`md`\|`csv`) | hoja de ruta imprimible |

Ejemplos completos de request/response: [`examples/usage.md`](examples/usage.md).

---

## Instalacion

```bash
git clone https://github.com/JPLopez23/delivery-mcp-server.git
cd delivery-mcp-server

uv sync
# o: python -m venv .venv && source .venv/bin/activate && pip install -e .
```

Si **OR-Tools** no instala en tu plataforma, quitalo del `pyproject.toml`: el
servidor cae automaticamente a la heuristica Clarke-Wright (respeta capacidad;
reporta las violaciones de ventana pero no las fuerza).

La base SQLite se crea de `data/schema.sql` + `data/seed.sql` en el primer
arranque. Borra `data/routes.db` para reiniciar. La ruta se cambia con la
variable de entorno `ROUTE_DB`.

Opcional: define `OSRM_URL` apuntando a una instancia de OSRM para usar
distancias reales de calle en vez de haversine + factor de rodeo.

---

## Ejecucion

El servidor habla MCP por stdin/stdout; lo lanza un anfitrion (el chatbot, o
Claude Desktop). Prueba manual:

```bash
printf '%s\n' \
  '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"t","version":"0"}}}' \
  '{"jsonrpc":"2.0","method":"notifications/initialized"}' \
  '{"jsonrpc":"2.0","id":2,"method":"tools/list"}' \
  '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"plan_routes","arguments":{"date":"2026-08-30"}}}' \
| uv run python -m route_optimizer.server
```

### Uso desde el anfitrion (chatbot)

En el `config/servers.json` del anfitrion:

```json
{
  "name": "delivery",
  "transport": "stdio",
  "command": "uv",
  "args": ["run", "--directory", "../delivery-mcp-server", "python", "-m", "route_optimizer.server"],
  "env": { "ROUTE_DB": "data/routes.db" }
}
```

### Uso desde Claude Desktop

```json
{
  "mcpServers": {
    "delivery": {
      "command": "uv",
      "args": ["run", "--directory", "/ruta/absoluta/delivery-mcp-server", "python", "-m", "route_optimizer.server"]
    }
  }
}
```

---

## Especificacion

* **Transporte:** stdio. Un mensaje JSON-RPC 2.0 por linea, UTF-8.
* **Metodos:** `initialize`, `notifications/initialized`, `tools/list`,
  `tools/call`, `ping`.
* **Version de protocolo:** `2025-06-18`.
* **Errores:** codigos JSON-RPC estandar (`-32700` parse, `-32600` invalid
  request, `-32601` method not found, `-32602` invalid params, `-32603`
  internal). Los fallos de una herramienta vuelven como un `result` normal con
  `isError: true` y un texto, para que el LLM reaccione.
* **Coordenadas:** WGS-84 en grados decimales. Horas: `HH:MM`, 24h, local.

Modelo de datos: `depots`, `vehicles`, `deliveries`, `routes`, `route_stops`
(ver [`data/schema.sql`](data/schema.sql)).

## Pruebas

```bash
uv run --with pytest python -m pytest -q
```

18 pruebas en [`tests/test_tools.py`](tests/test_tools.py): cada herramienta,
los tres escenarios de la guia (planificar el dia de la flota / insercion
urgente con costo marginal / averia de vehiculo + reasignacion) y las
restricciones que hacen no trivial al servidor: capacidad por peso y unidades,
ventanas de tiempo duras con tiempo de servicio, turno del conductor, retorno
al depot y reporte explicito de infactibilidades.

## Integridad

Repositorio publico, desarrollo individual para CC3067. OR-Tools se usa bajo su
licencia Apache-2.0. Uso de IA generativa conforme al reglamento de la UVG.

TDQS

A3.7/5.0

Scored across 10 tools

Disambiguation5/5

Each tool has a clear, distinct purpose: listing deliveries/vehicles, planning routes, viewing route details, evaluating/committing insertions, managing vehicle status, reassigning, updating delivery status, and exporting. No overlapping or ambiguous tools.

Naming Consistency5/5

All tool names follow a consistent verb_noun snake_case pattern (list_, plan_, get_, evaluate_, commit_, mark_, reassign_, update_, export_). Verbs are specific and accurately describe actions.

Tool Count5/5

10 tools is well-scoped for a delivery route planning MCP server, covering the full workflow without unnecessary bloat or missing essentials.

Completeness4/5

The surface covers the main lifecycle: listing, planning, viewing, modifying, and exporting. Minor gaps exist such as directly adding/removing deliveries or canceling a route, but the core operations are well represented.

Maintenance

ActivityMaintained
ResponsivenessNo issues