Skip to content

Spoke Dispatch MCP by usefulapi

by usefulapi.io · remote · no sign-in to list tools · v1.3.3 · published by io.usefulapi

Read Spoke Dispatch plans, stops, routes and drivers; create and optimize plans; send routes.

Deletes · 3Changes · 3

23 tools: 3 can delete or cancel things, 3 change things and 17 only read.

Scanned Oct 21, 2026

No check matched anything in the tool definitions. No finding is not a safety guarantee. How the checks work.

claude mcp add --transport http spoke-dispatch https://spoke-dispatch.usefulapi.io/mcp

Tools

Open a tool for its reasons and full description. Descriptions are the publisher's own words, shown as they are.

23 tools

Deletes or cancels 3Claude Code: deny
  • spoke_distribute_planWRITE (SENDS TO REAL PEOPLE): distribute an optimized plan, which immediately sends each driver of the plan their route on their phone (push notification / message) and locks the p…No findings

    Why it is in this group

    • The description's first verb is "write": a word for a change.
    • The description says "Cannot be undone".
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    WRITE (SENDS TO REAL PEOPLE): distribute an optimized plan, which immediately sends each driver of the plan their route on their phone (push notification / message) and locks the plan for edits. Cannot be undone. Only for a plan with 1-10 drivers, and only after the user has explicitly said to send the routes: set confirm_send_to_drivers to true. POST /plans/{planId}:distribute.

    Annotations the server declares

    • title: Distribute plan to drivers
    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: true
  • spoke_optimize_planWRITE: start the route optimization of a plan (orders and assigns its stops to its drivers).No findings

    Why it is in this group

    • The description's first verb is "write": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    WRITE: start the route optimization of a plan (orders and assigns its stops to its drivers). Rewrites the plan's routes if it was optimized before, and uses Spoke's optimization quota (30 per minute, 100 per 10 minutes). Does NOT send anything to drivers. Returns an operation: poll spoke_get_operation until done. Needs at least one driver and one stop. POST /plans/{planId}:optimize.

    Annotations the server declares

    • title: Optimize plan
    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: true
  • spoke_update_planWRITE: change a plan's title, date, drivers and/or depot.No findings

    Why it is in this group

    • The name "spoke_update_plan" says "update": a word for a change.
    • The server marks it destructive (destructiveHint: true).
    Description, as the server wrote it
    WRITE: change a plan's title, date, drivers and/or depot. Only the fields you pass change, but driver_ids REPLACES the plan's whole driver list. Fails if the plan is not writable (already distributed). Nothing is sent to drivers. PATCH /plans/{planId}.

    Annotations the server declares

    • title: Update plan
    • readOnlyHint: false
    • destructiveHint: true
    • idempotentHint: false
    • openWorldHint: true
Changes things 3Claude Code: ask
  • spoke_create_planWRITE: create a new route plan for a date (no stops yet, nothing is sent to drivers).No findings

    Why it is in this group

    • The name "spoke_create_plan" says "create": a word for a change.
    Description, as the server wrote it
    WRITE: create a new route plan for a date (no stops yet, nothing is sent to drivers). Optionally assign drivers (up to 50, they must be active and share the plan's depot) and a depot (default: the team's main depot). Does not optimize or distribute. POST /plans.

    Annotations the server declares

    • title: Create plan
    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: true
  • spoke_create_stopWRITE: add one stop to a writable (not yet distributed) plan.No findings

    Why it is in this group

    • The name "spoke_create_stop" says "create": a word for a change.
    Description, as the server wrote it
    WRITE: add one stop to a writable (not yet distributed) plan. Needs an address (text fields or latitude+longitude). The recipient's phone/e-mail are stored on the stop and Spoke may contact the recipient later when the route runs; nothing is sent now. For many stops use spoke_import_stops. POST /plans/{planId}/stops.

    Annotations the server declares

    • title: Create stop
    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: true
  • spoke_import_stopsWRITE: add up to 100 stops to a writable (not yet distributed) plan in one request (better geocoding than one at a time; Spoke limits imports to 30 requests a minute).No findings

    Why it is in this group

    • The name "spoke_import_stops" says "import": a word for a change.
    Description, as the server wrote it
    WRITE: add up to 100 stops to a writable (not yet distributed) plan in one request (better geocoding than one at a time; Spoke limits imports to 30 requests a minute). Returns the created stop ids and any failures. Recipient contact data is stored on the stops; nothing is sent now. POST /plans/{planId}/stops:import.

    Annotations the server declares

    • title: Import stops
    • readOnlyHint: false
    • destructiveHint: false
    • idempotentHint: false
    • openWorldHint: true
Only reads 17Claude Code: allow
  • spoke_get_depotOne depot by id.No findings

    Why it is in this group

    • The name "spoke_get_depot" says "get": a word for reading.
    Description, as the server wrote it
    One depot by id. GET /depots/{depotId}.

    Annotations the server declares

    • title: Get depot
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_get_driverOne driver by id.No findings

    Why it is in this group

    • The name "spoke_get_driver" says "get": a word for reading.
    Description, as the server wrote it
    One driver by id. Contains personal data. GET /drivers/{driverId}.

    Annotations the server declares

    • title: Get driver
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_get_operationOne operation, e.g.No findings

    Why it is in this group

    • The name "spoke_get_operation" says "get": a word for reading.
    Description, as the server wrote it
    One operation, e.g. the optimization started by spoke_optimize_plan: poll until done is true. GET /operations/{operationId}.

    Annotations the server declares

    • title: Get operation
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_get_planOne plan: title, start date, depot, driver ids, route ids, whether it is distributed/writable, optimization state and route overrides.No findings

    Why it is in this group

    • The name "spoke_get_plan" says "get": a word for reading.
    Description, as the server wrote it
    One plan: title, start date, depot, driver ids, route ids, whether it is distributed/writable, optimization state and route overrides. GET /plans/{planId}.

    Annotations the server declares

    • title: Get plan
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_get_routeOne route: title, driver, stop count and state (distributed, started, completed, recipients notified).No findings

    Why it is in this group

    • The name "spoke_get_route" says "get": a word for reading.
    Description, as the server wrote it
    One route: title, driver, stop count and state (distributed, started, completed, recipients notified). GET /routes/{routeId}.

    Annotations the server declares

    • title: Get route
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_get_stopOne stop of a plan with address, recipient, timing, ETA, route and delivery outcome (attempted, succeeded, notes, photo/signature links).No findings

    Why it is in this group

    • The name "spoke_get_stop" says "get": a word for reading.
    Description, as the server wrote it
    One stop of a plan with address, recipient, timing, ETA, route and delivery outcome (attempted, succeeded, notes, photo/signature links). Contains personal data. GET /plans/{planId}/stops/{stopId}.

    Annotations the server declares

    • title: Get stop
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_get_unassigned_stopOne unassigned stop by id.No findings

    Why it is in this group

    • The name "spoke_get_unassigned_stop" says "get": a word for reading.
    Description, as the server wrote it
    One unassigned stop by id. Contains personal data. GET /unassignedStops/{id}.

    Annotations the server declares

    • title: Get unassigned stop
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_list_custom_stop_propertiesThe team's custom stop property definitions (ids and names).No findings

    Why it is in this group

    • The name "spoke_list_custom_stop_properties" says "list": a word for reading.
    Description, as the server wrote it
    The team's custom stop property definitions (ids and names). Their ids are the keys of customProperties on stops. Needs a subscription that includes custom properties (HTTP 403 otherwise). GET /team/customStopProperties.

    Annotations the server declares

    • title: List custom stop properties
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_list_depotsList depots (start/end addresses, working hours, vehicle type, max stops), up to 20 per page.No findings

    Why it is in this group

    • The name "spoke_list_depots" says "list": a word for reading.
    Description, as the server wrote it
    List depots (start/end addresses, working hours, vehicle type, max stops), up to 20 per page. Use the ids when creating plans. GET /depots.

    Annotations the server declares

    • title: List depots
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_list_driversList the team's drivers (name, e-mail/phone, active flag, depots, route overrides), up to 50 per page.No findings

    Why it is in this group

    • The name "spoke_list_drivers" says "list": a word for reading.
    Description, as the server wrote it
    List the team's drivers (name, e-mail/phone, active flag, depots, route overrides), up to 50 per page. Contains personal data. GET /drivers.

    Annotations the server declares

    • title: List drivers
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_list_operationsList long-running operations (plan optimizations): type, done flag, who started it, result (optimized and skipped stops), up to 20 per page.No findings

    Why it is in this group

    • The name "spoke_list_operations" says "list": a word for reading.
    Description, as the server wrote it
    List long-running operations (plan optimizations): type, done flag, who started it, result (optimized and skipped stops), up to 20 per page. GET /operations.

    Annotations the server declares

    • title: List operations
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_list_plan_stopsList the stops of a plan, in pages of up to 10.No findings

    Why it is in this group

    • The name "spoke_list_plan_stops" says "list": a word for reading.
    Description, as the server wrote it
    List the stops of a plan, in pages of up to 10. Stops include recipient names, phones, e-mails and addresses (personal data): page only as far as needed. GET /plans/{planId}/stops.

    Annotations the server declares

    • title: List plan stops
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_list_plansList route plans (a plan = one day's delivery job: date, depot, drivers, routes), newest first, in pages of up to 20.No findings

    Why it is in this group

    • The name "spoke_list_plans" says "list": a word for reading.
    Description, as the server wrote it
    List route plans (a plan = one day's delivery job: date, depot, drivers, routes), newest first, in pages of up to 20. Filter with e.g. {"title":"Monday run"} or {"startsGte":"2026-10-01"}. GET /plans.

    Annotations the server declares

    • title: List plans
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_list_route_stopsList the stops of one route in driving order, in pages of up to 10.No findings

    Why it is in this group

    • The name "spoke_list_route_stops" says "list": a word for reading.
    Description, as the server wrote it
    List the stops of one route in driving order, in pages of up to 10. Contains personal data: page only as far as needed. GET /routes/{routeId}/stops.

    Annotations the server declares

    • title: List route stops
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_list_routesList routes (one driver's run of a plan: stop count, driver, distributed/started/completed state), up to 20 per page.No findings

    Why it is in this group

    • The name "spoke_list_routes" says "list": a word for reading.
    Description, as the server wrote it
    List routes (one driver's run of a plan: stop count, driver, distributed/started/completed state), up to 20 per page. GET /routes.

    Annotations the server declares

    • title: List routes
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_list_unassigned_stopsList stops that are not on any plan yet (the inbox of imported orders), in pages of up to 20 (default 20).No findings

    Why it is in this group

    • The name "spoke_list_unassigned_stops" says "list": a word for reading.
    Description, as the server wrote it
    List stops that are not on any plan yet (the inbox of imported orders), in pages of up to 20 (default 20). Contains personal data. GET /unassignedStops.

    Annotations the server declares

    • title: List unassigned stops
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true
  • spoke_search_stopsSearch all stops of the team (planned, unassigned, past) by keyword and/or Spoke's filter language, up to 20 per page.No findings

    Why it is in this group

    • The name "spoke_search_stops" says "search": a word for reading.
    Description, as the server wrote it
    Search all stops of the team (planned, unassigned, past) by keyword and/or Spoke's filter language, up to 20 per page. Example filter: address.countryCode = "DE" and deliveryInfo.attempted = false. Filterable: planId, routeId, type, activity, notes, address.*, createdAt, recipient.name/email/phone/externalId, deliveryInfo.state/attempted/succeeded, orderInfo.*. Results include personal data. The search index lags real time by a short while. GET /stops:search.

    Annotations the server declares

    • title: Search stops
    • readOnlyHint: true
    • destructiveHint: false
    • openWorldHint: true

This is not a safety rating, and no finding is not a safety guarantee. The groups and findings come from fixed checks of the tool definitions the server returned on the date shown, not from its code or what it does when called. How the checks work.

Install

Pinned to version 1.3.3. Values in angle brackets are yours to fill in.

claude mcp add --transport http spoke-dispatch https://spoke-dispatch.usefulapi.io/mcp

Run in a terminal.

Claude Code permissions

Allow the reads, ask before a change, deny the deletes. Paste into .claude/settings.json.

.claude/settings.json
{
  "permissions": {
    "allow": [
      "mcp__spoke-dispatch__spoke_list_plans",
      "mcp__spoke-dispatch__spoke_get_plan",
      "mcp__spoke-dispatch__spoke_list_plan_stops",
      "mcp__spoke-dispatch__spoke_get_stop",
      "mcp__spoke-dispatch__spoke_search_stops",
      "mcp__spoke-dispatch__spoke_list_unassigned_stops",
      "mcp__spoke-dispatch__spoke_get_unassigned_stop",
      "mcp__spoke-dispatch__spoke_list_drivers",
      "mcp__spoke-dispatch__spoke_get_driver",
      "mcp__spoke-dispatch__spoke_list_depots",
      "mcp__spoke-dispatch__spoke_get_depot",
      "mcp__spoke-dispatch__spoke_list_routes",
      "mcp__spoke-dispatch__spoke_get_route",
      "mcp__spoke-dispatch__spoke_list_route_stops",
      "mcp__spoke-dispatch__spoke_list_operations",
      "mcp__spoke-dispatch__spoke_get_operation",
      "mcp__spoke-dispatch__spoke_list_custom_stop_properties"
    ],
    "ask": [
      "mcp__spoke-dispatch__spoke_create_plan",
      "mcp__spoke-dispatch__spoke_create_stop",
      "mcp__spoke-dispatch__spoke_import_stops"
    ],
    "deny": [
      "mcp__spoke-dispatch__spoke_update_plan",
      "mcp__spoke-dispatch__spoke_optimize_plan",
      "mcp__spoke-dispatch__spoke_distribute_plan"
    ]
  }
}

Tools that only read are allowed, tools that change things ask first, tools that delete or cancel are denied. It assumes the server is installed as spoke-dispatch. Review it before you use it.