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
访问服务器

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.

推荐服务器

Baidu Map

Baidu Map

百度地图核心API现已全面兼容MCP协议,是国内首家兼容MCP协议的地图服务商。

官方
精选
JavaScript
Playwright MCP Server

Playwright MCP Server

一个模型上下文协议服务器,它使大型语言模型能够通过结构化的可访问性快照与网页进行交互,而无需视觉模型或屏幕截图。

官方
精选
TypeScript
Magic Component Platform (MCP)

Magic Component Platform (MCP)

一个由人工智能驱动的工具,可以从自然语言描述生成现代化的用户界面组件,并与流行的集成开发环境(IDE)集成,从而简化用户界面开发流程。

官方
精选
本地
TypeScript
Audiense Insights MCP Server

Audiense Insights MCP Server

通过模型上下文协议启用与 Audiense Insights 账户的交互,从而促进营销洞察和受众数据的提取和分析,包括人口统计信息、行为和影响者互动。

官方
精选
本地
TypeScript
VeyraX

VeyraX

一个单一的 MCP 工具,连接你所有喜爱的工具:Gmail、日历以及其他 40 多个工具。

官方
精选
本地
graphlit-mcp-server

graphlit-mcp-server

模型上下文协议 (MCP) 服务器实现了 MCP 客户端与 Graphlit 服务之间的集成。 除了网络爬取之外,还可以将任何内容(从 Slack 到 Gmail 再到播客订阅源)导入到 Graphlit 项目中,然后从 MCP 客户端检索相关内容。

官方
精选
TypeScript
Kagi MCP Server

Kagi MCP Server

一个 MCP 服务器,集成了 Kagi 搜索功能和 Claude AI,使 Claude 能够在回答需要最新信息的问题时执行实时网络搜索。

官方
精选
Python
e2b-mcp-server

e2b-mcp-server

使用 MCP 通过 e2b 运行代码。

官方
精选
Neon MCP Server

Neon MCP Server

用于与 Neon 管理 API 和数据库交互的 MCP 服务器

官方
精选
Exa MCP Server

Exa MCP Server

模型上下文协议(MCP)服务器允许像 Claude 这样的 AI 助手使用 Exa AI 搜索 API 进行网络搜索。这种设置允许 AI 模型以安全和受控的方式获取实时的网络信息。

官方
精选