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.
23 tools: 3 can delete or cancel things, 3 change things and 17 only read.
Scanned Oct 21, 2026
- Deletes or cancels3Claude Code: deny: see these tools
- Can't be undone0Claude Code: ask
- Changes things3Claude Code: ask: see these tools
- Only reads17Claude Code: allow: see these tools
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/mcpTools
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/mcpRun in a terminal.
Claude Code permissions
Allow the reads, ask before a change, deny the deletes. Paste into .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.