Upper Route Planner MCP by usefulapi

Read Upper drivers and stops; create and optimize routes, assign drivers, share routes to the app.

¿Debería usar esto?

Calidad y seguridad

A
Calidad de la descripción
97%
Integridad del esquema
81%
Calidad de los nombres
80%
Riesgo de envenenamiento
100%
Coincidencia de permisos
100%
Cumplimiento del protocolo
100%

Basado en el análisis automatizado de las definiciones de herramientas y el cumplimiento del protocolo.

Costo de contexto

~4,049Tokens (definiciones de herramientas)
~2.7 KBTamaño de respuesta típico
Impacto significativo en la atención (3.16% del contexto de 128k)

Este es el número aproximado de tokens que se consumen cada vez que las herramientas del servidor se cargan en el contexto de un modelo. Los recuentos más altos reducen la atención disponible para otras tareas.

Instalar

Instalación con un clic

Agrega esto a tu archivo `claude_desktop_config.json`:

{
  "mcpServers": {
    "upper-route-planner": {
      "url": "https://upper-route-planner.usefulapi.io/mcp"
    }
  }
}

Puntos de conexión remotos

https://upper-route-planner.usefulapi.io/mcpstreamable-http

Qué puede hacer

Inventario de herramientas

Herramientas (12)

🟢 Solo lectura🟡 Escritura🔴 Eliminación⚪ Desconocido
🟢upper_list_drivers

List the active drivers on the Upper team that owns the API token: id, name, email and phone. Use the ids with upper_assign_drivers and upper_share_route_to_drivers. GET /ext-get-drivers.

Esquema de entrada

{
  "type": "object",
  "properties": {},
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢upper_list_stops(route_id, scheduled, unscheduled, limit, offset)

List the team's stops in optimized order: address, coordinates, contact, time window, duration, status, route_id and custom ids. Pass route_id for one route (optionally scheduled=true/false); pass unscheduled=true (without route_id) for stops not on any route; with no filter all active stops are returned. Upper has no paging, so this tool pages locally: `limit` stops (default 100, max 500) starting at `offset`; the reply says if more remain (truncated, next_offset). GET /ext-get-stops.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "route_id": {
      "description": "Only the stops on this route.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "scheduled": {
      "description": "With route_id only: true = scheduled stops, false = unscheduled stops of that route.",
      "type": "boolean"
    },
    "unscheduled": {
      "description": "Without route_id: true = unscheduled stops across all routes.",
      "type": "boolean"
    },
    "limit": {
      "description": "Most stops to return, 1-500 (default 100).",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 500
    },
    "offset": {
      "description": "Skip this many stops (use next_offset from the previous reply to read on).",
      "type": "integer",
      "minimum": 0,
      "maximum": 9007199254740991
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢upper_get_optimization_status(route_id)

Check whether a route is optimized: status is optimized, pending (still running) or not_optimized, plus the queue_id of the last job. Poll this after upper_optimize_route. GET /ext-optimization-status.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "route_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991,
      "description": "The route id."
    }
  },
  "required": [
    "route_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢upper_get_custom_fields

The workspace's five stop custom-field slots (custom1 - custom5: type, label, enabled, required) and which are enabled. Needs the Custom fields feature in the Upper plan. GET /ext-get-custom-fields.

Esquema de entrada

{
  "type": "object",
  "properties": {},
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟢upper_get_capacity_fields

The workspace's five capacity-field slots (capacity1 - capacity5: label, unit, enabled) used for load planning. GET /ext-get-capacity-fields.

Esquema de entrada

{
  "type": "object",
  "properties": {},
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟡upper_create_route(route_name, route_date, optimize_for, units, pickup_settings, ...)

WRITE: create a new, empty route (name, date, optimization preference, units, pickup sequencing, service time). Omitted settings fall back to the account's defaults. Returns the new route_id; add stops with upper_create_stop. Calling it twice creates two routes. POST /ext-create-route.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "route_name": {
      "description": "Route name (default: New Route).",
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "route_date": {
      "description": "Route start date, yyyy-mm-dd (default today).",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "optimize_for": {
      "description": "Optimize for time or distance.",
      "type": "string",
      "enum": [
        "time",
        "distance"
      ]
    },
    "units": {
      "description": "Distance units: miles or km.",
      "type": "string",
      "enum": [
        "miles",
        "km"
      ]
    },
    "pickup_settings": {
      "description": "When pickups are sequenced: auto, before or after the deliveries.",
      "type": "string",
      "enum": [
        "auto",
        "before",
        "after"
      ]
    },
    "service_time": {
      "type": "integer",
      "minimum": 0,
      "maximum": 86400,
      "description": "Per-stop service (dwell) time in seconds."
    }
  },
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴upper_update_route(route_id, route_name, route_date, optimize_for, units, ...)

WRITE: change settings of an existing route (name, date, optimize_for, units, pickup_settings, service_time). Only the fields you pass change. POST /ext-update-route.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "route_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991,
      "description": "The route to update."
    },
    "route_name": {
      "description": "New route name.",
      "type": "string",
      "minLength": 1,
      "maxLength": 200
    },
    "route_date": {
      "description": "New start date, yyyy-mm-dd.",
      "type": "string",
      "pattern": "^\\d{4}-\\d{2}-\\d{2}$"
    },
    "optimize_for": {
      "description": "Optimize for time or distance.",
      "type": "string",
      "enum": [
        "time",
        "distance"
      ]
    },
    "units": {
      "description": "Distance units: miles or km.",
      "type": "string",
      "enum": [
        "miles",
        "km"
      ]
    },
    "pickup_settings": {
      "description": "When pickups are sequenced: auto, before or after.",
      "type": "string",
      "enum": [
        "auto",
        "before",
        "after"
      ]
    },
    "service_time": {
      "type": "integer",
      "minimum": 0,
      "maximum": 86400,
      "description": "Per-stop service (dwell) time in seconds."
    }
  },
  "required": [
    "route_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟡upper_create_stop(address, route_id, city, state, zipcode, ...)

WRITE: create a stop. The address is geocoded by Upper. Pass route_id to put it on a route (the route must not be active/in progress; an optimized route is flagged for re-optimization); omit it for an unscheduled stop. Calling it twice creates two stops. POST /ext-create-stop.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "address": {
      "type": "string",
      "minLength": 1,
      "maxLength": 500,
      "description": "Street address of the stop (geocoded by Upper)."
    },
    "route_id": {
      "description": "Route to attach the stop to; omit for an unscheduled stop.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "city": {
      "description": "City (overrides the geocoded value).",
      "type": "string",
      "maxLength": 200
    },
    "state": {
      "description": "State or region (overrides the geocoded value).",
      "type": "string",
      "maxLength": 200
    },
    "zipcode": {
      "description": "Postal code (overrides the geocoded value).",
      "type": "string",
      "maxLength": 40
    },
    "contact_name": {
      "description": "Contact (recipient) name.",
      "type": "string",
      "maxLength": 200
    },
    "phone": {
      "description": "Contact phone number; non-digits are stripped by Upper.",
      "type": "string",
      "maxLength": 40
    },
    "phone_country_code": {
      "description": "Phone dialing code, for example 1.",
      "type": "string",
      "pattern": "^\\d{1,4}$"
    },
    "email": {
      "description": "Contact email.",
      "type": "string",
      "maxLength": 254
    },
    "note": {
      "description": "Free-text note shown to the driver.",
      "type": "string",
      "maxLength": 2000
    },
    "company_name": {
      "description": "Company name for the stop.",
      "type": "string",
      "maxLength": 200
    },
    "nick_name": {
      "description": "Short label for the stop.",
      "type": "string",
      "maxLength": 100
    },
    "pin_color": {
      "description": "Map pin colour, hex like #FF6600.",
      "type": "string",
      "pattern": "^#[0-9a-fA-F]{6}$"
    },
    "start_time": {
      "description": "Earliest service time (time window start), HH:MM or HH:MM:SS.",
      "type": "string",
      "pattern": "^([01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$"
    },
    "end_time": {
      "description": "Latest service time (time window end), HH:MM or HH:MM:SS.",
      "type": "string",
      "pattern": "^([01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$"
    },
    "stop_duration": {
      "description": "Service duration at the stop, in seconds.",
      "type": "integer",
      "minimum": 0,
      "maximum": 86400
    },
    "stop_type": {
      "description": "Stop type, for example Delivery or Pickup.",
      "type": "string",
      "maxLength": 50
    },
    "stop_priority": {
      "description": "Stop priority, for example Normal, High, Urgent.",
      "type": "string",
      "maxLength": 50
    },
    "parcel_count": {
      "description": "Number of parcels at the stop.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000
    },
    "customer_system_id": {
      "description": "Your own identifier for the stop (for cross-referencing).",
      "type": "string",
      "maxLength": 200
    },
    "custom_fields": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64
      },
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 2000
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          }
        ]
      },
      "description": "Custom field values keyed by slot (custom1 - custom5). Only fields enabled in the workspace (and in the plan) are stored."
    },
    "capacity_fields": {
      "type": "object",
      "properties": {
        "capacity1": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "capacity2": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "capacity3": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "capacity4": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "capacity5": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        }
      },
      "description": "Capacity values (integers) for load planning, keys capacity1 - capacity5."
    }
  },
  "required": [
    "address"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴upper_update_stop(stop_id, address, route_id, city, state, ...)

WRITE: change an existing stop; only the fields you pass change. A new address is re-geocoded (city/state/zipcode you pass with it are ignored); city/state/zipcode apply only without an address. Passing route_id moves the stop to that route. Editing a stop on an optimized route flags the route for re-optimization; stops on an active route cannot be edited. POST /ext-update-stop.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "stop_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991,
      "description": "The stop to update."
    },
    "address": {
      "description": "New street address (re-geocoded).",
      "type": "string",
      "minLength": 1,
      "maxLength": 500
    },
    "route_id": {
      "description": "Move the stop to this route.",
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991
    },
    "city": {
      "description": "City (only used when no address is passed).",
      "type": "string",
      "maxLength": 200
    },
    "state": {
      "description": "State or region (only used when no address is passed).",
      "type": "string",
      "maxLength": 200
    },
    "zipcode": {
      "description": "Postal code (only used when no address is passed).",
      "type": "string",
      "maxLength": 40
    },
    "contact_name": {
      "description": "Contact (recipient) name.",
      "type": "string",
      "maxLength": 200
    },
    "phone": {
      "description": "Contact phone number; non-digits are stripped by Upper.",
      "type": "string",
      "maxLength": 40
    },
    "phone_country_code": {
      "description": "Phone dialing code, for example 1.",
      "type": "string",
      "pattern": "^\\d{1,4}$"
    },
    "email": {
      "description": "Contact email.",
      "type": "string",
      "maxLength": 254
    },
    "note": {
      "description": "Free-text note shown to the driver.",
      "type": "string",
      "maxLength": 2000
    },
    "company_name": {
      "description": "Company name for the stop.",
      "type": "string",
      "maxLength": 200
    },
    "nick_name": {
      "description": "Short label for the stop.",
      "type": "string",
      "maxLength": 100
    },
    "pin_color": {
      "description": "Map pin colour, hex like #FF6600.",
      "type": "string",
      "pattern": "^#[0-9a-fA-F]{6}$"
    },
    "start_time": {
      "description": "Earliest service time (time window start), HH:MM or HH:MM:SS.",
      "type": "string",
      "pattern": "^([01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$"
    },
    "end_time": {
      "description": "Latest service time (time window end), HH:MM or HH:MM:SS.",
      "type": "string",
      "pattern": "^([01]\\d|2[0-3]):[0-5]\\d(:[0-5]\\d)?$"
    },
    "stop_duration": {
      "description": "Service duration at the stop, in seconds.",
      "type": "integer",
      "minimum": 0,
      "maximum": 86400
    },
    "stop_type": {
      "description": "Stop type, for example Delivery or Pickup.",
      "type": "string",
      "maxLength": 50
    },
    "stop_priority": {
      "description": "Stop priority, for example Normal, High, Urgent.",
      "type": "string",
      "maxLength": 50
    },
    "parcel_count": {
      "description": "Number of parcels at the stop.",
      "type": "integer",
      "minimum": 0,
      "maximum": 100000
    },
    "customer_system_id": {
      "description": "Your own identifier for the stop (for cross-referencing).",
      "type": "string",
      "maxLength": 200
    },
    "custom_fields": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "minLength": 1,
        "maxLength": 64
      },
      "additionalProperties": {
        "anyOf": [
          {
            "type": "string",
            "maxLength": 2000
          },
          {
            "type": "number"
          },
          {
            "type": "boolean"
          }
        ]
      },
      "description": "Custom field values keyed by slot (custom1 - custom5). Only fields enabled in the workspace (and in the plan) are stored."
    },
    "capacity_fields": {
      "type": "object",
      "properties": {
        "capacity1": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "capacity2": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "capacity3": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "capacity4": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        },
        "capacity5": {
          "type": "integer",
          "minimum": -9007199254740991,
          "maximum": 9007199254740991
        }
      },
      "description": "Capacity values (integers) for load planning, keys capacity1 - capacity5."
    }
  },
  "required": [
    "stop_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴upper_assign_drivers(route_id, driver_ids)

WRITE: assign one or more drivers (ids from upper_list_drivers) to a route, replacing the route's drivers. Every id must be an active driver on the team. If the route was already optimized it is reset to unoptimized (needs_optimization: true), so run upper_optimize_route again. POST /ext-assign-drivers.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "route_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991,
      "description": "The route."
    },
    "driver_ids": {
      "minItems": 1,
      "maxItems": 100,
      "type": "array",
      "items": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "maximum": 9007199254740991
      },
      "description": "Driver ids to assign."
    }
  },
  "required": [
    "route_id",
    "driver_ids"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🔴upper_optimize_route(route_id, timezone)

WRITE: start optimizing a route's stop order. The route needs at least one stop and one assigned driver (upper_assign_drivers). It runs asynchronously: this returns status pending and a queue_id, then poll upper_get_optimization_status. If a job is already running, that job is returned. POST /ext-optimize-route.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "route_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991,
      "description": "The route to optimize."
    },
    "timezone": {
      "description": "IANA timezone for the optimization, for example America/New_York.",
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "pattern": "^[A-Za-z0-9_+\\-/]+$"
    }
  },
  "required": [
    "route_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}
🟡upper_share_route_to_drivers(route_id, driver_ids, timezone)

WRITE: push a route to the drivers' mobile app NOW, which sends each driver a notification. Without driver_ids the route's assigned drivers are used; with them, every id must be an active driver on the team. Sending twice notifies twice. Confirm with the user before calling. POST /ext-share-to-driver.

Esquema de entrada

{
  "type": "object",
  "properties": {
    "route_id": {
      "type": "integer",
      "exclusiveMinimum": 0,
      "maximum": 9007199254740991,
      "description": "The route to share."
    },
    "driver_ids": {
      "description": "Drivers to notify (default: the route's assigned drivers).",
      "minItems": 1,
      "maxItems": 100,
      "type": "array",
      "items": {
        "type": "integer",
        "exclusiveMinimum": 0,
        "maximum": 9007199254740991
      }
    },
    "timezone": {
      "description": "IANA timezone, for example America/New_York.",
      "type": "string",
      "minLength": 1,
      "maxLength": 64,
      "pattern": "^[A-Za-z0-9_+\\-/]+$"
    }
  },
  "required": [
    "route_id"
  ],
  "$schema": "https://json-schema.org/draft/2020-12/schema"
}

Comunidad

Califica este servidor

Evidencia

Observaciones recientes

verificadoversión no registrada12 herramientas