PingPoint Freight MCP Server

PingPoint Freight MCP Server

Provides real-time freight tracking and load visibility for logistics and AI agents: create loads, get live GPS positions, trip stats, and confirm deliveries via geofenced statuses.

Category
Visit Server

README

PingPoint — freight tracking MCP server and SDK

Real-time freight tracking and load visibility for logistics software and AI agents: an MCP server and a TypeScript SDK that give any agent live driver GPS position for a truckload shipment in US trucking — create a load over the API, the driver connects from an SMS link in about a minute, and from then on position, ETA, stop timeline and post-trip stats are one call away. No ELD provider integration, no corporate contract, no sales call.

Package npm What it is
@suverselabs/pingpoint-mcp npm i @suverselabs/pingpoint-mcp MCP server — 7 tools over stdio, for Claude and any MCP-capable agent
@suverselabs/pingpoint-sdk npm i @suverselabs/pingpoint-sdk Typed API client — zero dependencies, typed errors, idempotent retries

Full API documentation: https://pingpoint.suverse.io/docs · OpenAPI 3.1 spec: /docs/openapi.json

The problem

Most carriers in US trucking are one- or two-truck companies. They have no corporate telematics stack, no visibility contract, and no IT department — the truck is the company. When a broker needs to know where a load is, the only reliable instrument is a phone call to the driver.

That is why "AI track & trace" from most vendors today means a robot that calls a human and asks. The position data itself never becomes machine-readable — it lives in one driver's head, one call at a time. PingPoint makes the position itself available over an API: the driver installs one app from an SMS link, and from that moment any software — or any AI agent through MCP — reads live GPS instead of asking someone to dial.

How it works

1. A load is created over the API

POST /v1/agent/loads with the driver's phone and the stops. Required: driverPhone (E.164 — the driver link is texted to this number) and the pickups / deliveries arrays; every stop needs address, city, state, zip. Multi-stop loads are supported — several pickups and several deliveries, in array order.

The response carries the loadNumber (used in every later call), a public trackingLink for the customer, and the driver web/app links. Two safety nets against double-charging:

  • customerRef doubles as a dedup key — re-sending the same reference returns the existing load (deduplicated: true) instead of creating a duplicate;
  • an Idempotency-Key header makes retries after a network failure safe — the balance is debited and the load created at most once.

2. The driver connects from an SMS link

PingPoint texts the driver a link automatically. The link opens onboarding: install the app, tap through consent, done — about a minute of the driver's time, once. Under the hood the link carries a one-time load token which the app exchanges for a persistent device token, so the next load to the same phone number binds without any new setup.

3. Position flows in over two independent channels

  • The driver's phone — background geolocation from the app.
  • An ELD dongle on the truck's diagnostic port — streams vehicle data over Bluetooth to the app, which relays it. Tested with IOSiX and Pacific Track PT30 hardware. The dongle emits frames at 1 Hz; the app thins them before upload so the stored track stays dense enough for geofencing without drowning the pipeline.

The phone stays the gateway for both channels — the dongle talks to the app, not to the network. The point of two sources is that they fail differently: the dongle keeps positions coming for as long as the engine runs even when the phone's GPS can't get a fix or the OS has throttled background geolocation. Dongle frames also carry their own timestamps, taken from the frame itself rather than the moment of upload — so when a buffered backlog is flushed after an offline stretch, the recorded times are the real ones.

4. Statuses advance from geofences — never from a keyboard

Every pickup and delivery stop gets a geofence. Entering the pickup zone moves the load to AT_PICKUP, leaving it moves to IN_TRANSIT, entering the delivery zone to AT_DELIVERY — and DELIVERED is set when the truck departs the final delivery zone, not on arrival. The one shortcut is the explicit (free) delivery-confirm call (BOL in hand), which completes the load once the truck is at its delivery stop. Stop arrivedAt / departedAt timestamps come from the same geofence events.

External status writes are closed on purpose: PATCH …/status always answers 410 STATUS_DOOR_CLOSED. This is a data-integrity guarantee, not a missing feature — a status you read was never hand-set by anyone; there is recorded position behind it.

5. Reading it back

GET /v1/agent/loads/{loadNumber} returns the live state: status, the GPS track (up to the 500 most recent points), the stop timeline with arrival/departure timestamps, distance covered, dwell times, on-time flag and an ETA block computed from the stored route geometry and the latest position. After the trip, GET …/trip-stats returns an aggregated summary computed over every recorded ping. Webhooks can push load events to your endpoint as they happen (see the docs).

 SMS link          +---------------------+
 (sent by  ------> |  Driver phone app   |--- background GPS ---+
  PingPoint)       +---------------------+                      |
                                                                v
                   +---------------------+   1 Hz frames   +--------------------+
                   |  ELD dongle on the  |---------------->| ingest (thinning)  |
                   |  diagnostic port,   |   via the app   +--------------------+
                   |  BLE (IOSiX, PT30)  |                      |
                   +---------------------+                      v
                                                       +-----------------+
                                                       |  position store |
                                                       +-----------------+
                                                            |        |
                                     geofence engine <------+        |
                                            |                        |
        PLANNED -> AT_PICKUP -> IN_TRANSIT -> AT_DELIVERY -> DELIVERED
                                            |                        |
                                            v                        v
                  webhooks -> your endpoint      GET /v1/agent/loads/{n}   (position, ETA)
                                                 GET .../trip-stats        (post-trip summary)

Quick start

Get a key

  1. Sign up at pingpoint.suverse.io (e-mail or Google/GitHub).
  2. In the cabinet open Integrations → Agent API and press Issue key.
  3. The sup_agent_… key arrives by e-mail. PingPoint never stores the secret — if it's lost, re-issue a new one from the same page.

First call

curl -X POST https://api.suverse.io/v1/agent/loads \
  -H "Authorization: Bearer sup_agent_…" \
  -H "Content-Type: application/json" \
  -d '{
    "driverPhone": "+15551234567",
    "pickups":    [{ "address": "6492 Tower Lane", "city": "Claremore", "state": "OK", "zip": "74017" }],
    "deliveries": [{ "address": "6499 Caldwell Park Dr", "city": "Charlotte", "state": "NC", "zip": "28269" }],
    "customerRef": "PO-483920"
  }'
{
  "success": true,
  "loadId": "3b9f6a2e-1c47-4d8a-9e02-7f5b1c8d4a63",
  "loadNumber": "LD-2026-042317",
  "trackingLink": "https://pingpoint.suverse.io/track/trk_…",
  "driverWebLink": "https://pingpoint.suverse.io/driver/drv_…",
  "driverAppLink": "pingpoint://driver/drv_…",
  "driverResolution": "none"
}

The driver link is already on its way to +15551234567 by SMS. From here, GET /v1/agent/loads/LD-2026-042317 reads the live position.

Connect the MCP server

Claude Code, one line:

claude mcp add pingpoint --env PINGPOINT_AGENT_KEY=sup_agent_… -- npx -y @suverselabs/pingpoint-mcp

Claude Desktop (claude_desktop_config.json) or any MCP-capable agent:

{
  "mcpServers": {
    "pingpoint": {
      "command": "npx",
      "args": ["-y", "@suverselabs/pingpoint-mcp"],
      "env": {
        "PINGPOINT_AGENT_KEY": "sup_agent_…"
      }
    }
  }
}

Restart the agent and the tools appear.

MCP tools

Detailed per-tool reference with full request/response examples: docs/tools/.

Tool What it does Parameters Returns Price
create_load Creates a freight load; PingPoint texts the driver link to driverPhone driverPhone, pickups[], deliveries[] (required); shipperName, carrierName, equipmentType, customerRef, rate, miles, weight, truckNumber, idempotencyKey (optional) loadNumber, public trackingLink, driver web/app links, driverResolution, dedup flag $0.65
get_load_position Live state of a load loadNumber status, GPS track (last 500 points), stops with arrive/depart timestamps, distance, on-time flag, dwell times, ETA block $0.02
get_trip_stats Aggregated summary of the whole GPS trip (meant for a DELIVERED load; mid-trip returns the trip so far) loadNumber stats: distance, duration, avg/max speed, hard accel/brake counts, city/highway/parked/night shares, GPS coverage, first/last ping $0.02
update_load_status Intentionally closed — statuses are GPS-verified loadNumber, status always HTTP 410 STATUS_DOOR_CLOSED free
confirm_delivery BOL received → load at its delivery stop flips to DELIVERED (idempotent) loadNumber, bolReceivedAt (optional, ISO 8601) { ok, oldStatus, newStatus: "DELIVERED" } free
get_pricing Current USD price list { currency, prices } free
get_balance Prepaid balance { currency, balanceUsd } free

Tool descriptions are written for the calling model: each one states what it costs, when to use it and when not to (e.g. get_load_position answers "where is the truck now", get_trip_stats answers "how did the finished trip go", and both warn against polling in a loop because every call is billed).

SDK

npm install @suverselabs/pingpoint-sdk
import { PingPointAgent, InsufficientFundsError, DeliveryNotReadyError } from "@suverselabs/pingpoint-sdk";

const pp = new PingPointAgent({ apiKey: process.env.PINGPOINT_AGENT_KEY! });

// $0.65 — driver gets the app link by SMS
const load = await pp.createLoad(
  {
    driverPhone: "+15551234567",
    pickups: [{ address: "6492 Tower Lane", city: "Claremore", state: "OK", zip: "74017" }],
    deliveries: [{ address: "6499 Caldwell Park Dr", city: "Charlotte", state: "NC", zip: "28269" }],
    customerRef: "PO-483920",
  },
  { idempotencyKey: "PO-483920" },
);

const pos = await pp.getPosition(load.loadNumber);   // $0.02
const trip = await pp.getTripStats(load.loadNumber); // $0.02, best after DELIVERED
await pp.confirmDelivery(load.loadNumber, { bolReceivedAt: new Date() }); // free

Methods: createLoad(input, { idempotencyKey? }), getPosition(loadNumber), getTripStats(loadNumber), updateStatus(loadNumber, status) (documented to throw the intentional 410), confirmDelivery(loadNumber, { bolReceivedAt? }), getPricing(), getBalance(). Full reference: docs/sdk.md.

Every non-2xx answer throws a typed subclass of PingPointAgentError carrying .status and the raw .body:

try {
  await pp.createLoad(input);
} catch (err) {
  if (err instanceof InsufficientFundsError) {
    console.log(`balance $${err.balanceUsd}, need $${err.priceUsd} — nothing was charged`);
  } else if (err instanceof DeliveryNotReadyError) {
    // driver hasn't arrived yet — do NOT retry; the load completes automatically when the truck departs the delivery zone
  }
}

Node ≥ 18 (uses global fetch), ESM + CJS, zero runtime dependencies.

Data model

Position (get_load_position / getPosition)

Field Unit / format Meaning
status enum PLANNED, AT_PICKUP, IN_TRANSIT, AT_DELIVERY, DELIVERED, CANCELLED — advanced automatically from GPS and geofence events
gpsTrack[] Up to the 500 most recent points, oldest first
gpsTrack[].lat / lng degrees Position fix
gpsTrack[].speed mph, 1 decimal Ground speed; null when the fix carries none
gpsTrack[].heading degrees 0–359, 0 = north null when unknown
gpsTrack[].ts ISO 8601 UTC Fix timestamp
distanceMiles miles Haversine over the full track (not just the 500 returned points); null until ≥ 2 pings
stops[].arrivedAt / departedAt ISO 8601 UTC Set by geofence arrival/departure
stops[].windowFrom / windowTo ISO 8601 UTC Planned windows, null when not set
onTime boolean Delivered within the delivery window (15 min grace); null until delivered or without a window
delayMinutes, pickupDwellMinutes, deliveryDwellMinutes minutes null when not yet known
pingCount count Total pings recorded for the load
eta object Next stop, distance to it (mi), drive time (h), moving flag, ETA window; fail-soft — degrades to a reason-only object when there is not enough data

Trip stats (get_trip_stats / getTripStats)

Field Unit Meaning
dataPoints count GPS pings recorded for the load
durationSeconds s lastAt − firstAt
estimatedDistanceMiles miles Haversine over the full recorded track
avgSpeedMph mph Over the whole span, stops included
maxSpeedMph mph Maximum recorded ground speed
hardAccelCount count Speed gain > +15 mph/min while moving > 20 mph
hardBrakeCount count Speed drop < −20 mph/min while moving > 20 mph
cityMilesPct % 0–100 Share of miles at 5–45 mph
highwayMilesPct % 0–100 Share of miles above 45 mph
parkedTimePct % 0–100 Share of pings at ≤ 5 mph
nightPct % 0–100 Share of pings between 23:00–07:00 UTC
coveragePct % ≤ 100 Pings vs. a one-per-minute expectation over the span
firstAt / lastAt ISO 8601 UTC First/last recorded ping; null when no pings

Error codes

Code Meaning
400 MISSING_FIELDS Required fields absent — the body lists them in fields[] (dotted paths, e.g. pickups.0.zip). Also 400 INVALID_DRIVER_PHONE when the phone is not E.164.
401 Missing or invalid key.
402 INSUFFICIENT_FUNDS Prepaid balance can't cover the operation. Nothing was charged and nothing was created. Body carries balanceUsd, priceUsd, billingUrl.
403 The load belongs to another account.
404 No such load.
410 STATUS_DOOR_CLOSED Answer to any external status write. Not an outage — by design. Don't retry.
422 UNKNOWN_BROKER The key's account is not registered on PingPoint.
422 + reason: bol_received_before_geofence_arrive Delivery confirm before the truck reached the delivery stop. Don't retry — once the truck is at the stop the confirm succeeds, and without it the load completes automatically on departure from the delivery zone.
503 BILLING_UNAVAILABLE Billing backend temporarily unreachable — nothing was charged, retry later.

Billing

Prepaid balance, per-call pricing, no subscription. Details: docs/billing.md.

Operation Price
Create a load $0.65
Read load position $0.02 per request
Trip summary stats $0.02 per request
Delivery confirm, status endpoint, pricing, balance free
  • Top up in the cabinet under Billing. Free operations work at zero balance.
  • A 402 means the call was rejected before anything happened: nothing created, nothing charged.
  • createLoad retries are safe with the same Idempotency-Key — the debit happens at most once; customerRef deduplicates at the business level.
  • Prices are served live by GET /v1/agent/pricing — treat that as the source of truth, never hardcode them.

What this is not

  • Not a certified ELD. PingPoint reads GPS (and, through the dongle, engine-bus data) for visibility. It is not an FMCSA-registered ELD and does not produce HOS/RODS compliance records.
  • Not carrier vetting. A live position tells you where the truck is, not whether the carrier is safe, insured or real. Keep whatever onboarding checks you run today.
  • The driver has to install the app. One SMS link, one install, about a minute — but it is a real step that requires the driver's cooperation. A load with no connected phone and no dongle produces no positions.

How this compares

Enterprise visibility platforms assume the carrier already has telematics and the broker already has a contract; call-based tracking vendors put a phone call (human or robotic) in the loop for every check. PingPoint's trade is different: one driver-side install in exchange for a per-call API with published prices and no minimums. A factual, cell-by-cell comparison with both groups — key issuance, public pricing, API surface, MCP/SDK availability — is maintained at pingpoint.suverse.io/compare.

Links

  • API documentation: https://pingpoint.suverse.io/docs
  • OpenAPI 3.1 spec: https://pingpoint.suverse.io/docs/openapi.json
  • Comparison with alternatives: https://pingpoint.suverse.io/compare
  • MCP server on npm: https://www.npmjs.com/package/@suverselabs/pingpoint-mcp
  • SDK on npm: https://www.npmjs.com/package/@suverselabs/pingpoint-sdk
  • In-repo docs: architecture · billing · SDK reference · MCP tools
  • Contact: info@suverse.io

License

MIT © 2026 Sudzik Group Inc.

Recommended Servers

playwright-mcp

playwright-mcp

A Model Context Protocol server that enables LLMs to interact with web pages through structured accessibility snapshots without requiring vision models or screenshots.

Official
Featured
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

Enables interaction with Audiense Insights accounts via the Model Context Protocol, facilitating the extraction and analysis of marketing insights and audience data including demographics, behavior, and influencer engagement.

Official
Featured
Local
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

An AI-powered tool that generates modern UI components from natural language descriptions, integrating with popular IDEs to streamline UI development workflow.

Official
Featured
Local
TypeScript
VeyraX MCP

VeyraX MCP

Single MCP tool to connect all your favorite tools: Gmail, Calendar and 40 more.

Official
Featured
Local
graphlit-mcp-server

graphlit-mcp-server

The Model Context Protocol (MCP) Server enables integration between MCP clients and the Graphlit service. Ingest anything from Slack to Gmail to podcast feeds, in addition to web crawling, into a Graphlit project - and then retrieve relevant contents from the MCP client.

Official
Featured
TypeScript
Kagi MCP Server

Kagi MCP Server

An MCP server that integrates Kagi search capabilities with Claude AI, enabling Claude to perform real-time web searches when answering questions that require up-to-date information.

Official
Featured
Python
Neon Database

Neon Database

MCP server for interacting with Neon Management API and databases

Official
Featured
Exa Search

Exa Search

A Model Context Protocol (MCP) server lets AI assistants like Claude use the Exa AI Search API for web searches. This setup allows AI models to get real-time web information in a safe and controlled way.

Official
Featured
Qdrant Server

Qdrant Server

This repository is an example of how to create a MCP server for Qdrant, a vector search engine.

Official
Featured
E2B

E2B

Using MCP to run code via e2b.

Official
Featured