Container tracking API vs MCP: how AI agents track ocean freight
Someone in ops asks the assistant a simple question — “where’s MSCU1234567 and is it going to be late?” — and you have to decide how the machine answers it. That decision is really a choice between two shapes of integration, and the shapes are more different than the vendor pages let on. One makes your software do the tracking. The other lets the model do it.
I’ve built both. This is what actually changes when you move a container-tracking integration from a plain REST API to an MCP server — and where each one still earns its place.
What a tracking API asks of you
A REST tracking API is a set of endpoints. You send a container number, it sends back JSON. That’s a clean, well-understood contract, and for a backend service it’s often exactly right.
But the API doesn’t do anything on its own. Every question a user might ask, you have to anticipate in code: which endpoint, what parameters, how to page the timeline, how to turn a demurrage_free_until date into “you have three days.” When the model in your product wants to answer a freight question, it can’t call the carrier — it can only call your code, and your code calls the API. You are the glue, and the glue is where the bugs live.
What an MCP server asks of the model instead
Model Context Protocol flips the arrow. Instead of your code knowing which endpoint to hit, the tools describe themselves to the model, and the model picks. You register a tracking MCP server once; from then on the assistant can call get_container_detail or get_demurrage_free_time directly, in plain language, with no bespoke integration code sitting in the middle.
The practical upshot: the work of interpreting the freight data — is this ETA a real prediction or a stale promise, has the free-time clock started, is “delivered” backed by an event — moves out of your integration and into the tool, where it can be done once and done properly.
Where the two really diverge: interpretation
A raw tracking API hands back events. That’s honest, but it’s not an answer. Two events can both say “MOVE” and mean loading versus discharge; a milestone can read “delivered” because a system assumed it, not because a gate event fired. Turning events into a status a customer can act on is real work, and with a plain API that work is yours to write and yours to get wrong.
An MCP tool built for freight should hand back the interpreted view: events already normalised to the DCSA standard so “discharged” means the same thing on every line, an ETA labelled by how it was derived, and a free-time clock you don’t have to compute. The model asks one question and gets a reply-ready answer — because the interpretation lives in the tool, not in a prompt you maintain.
So which do you actually want?
Not a binary — the honest answer is you probably want both surfaces behind one key, and you pick per use case:
- Building an AI assistant or copilot that fields freight questions? MCP. The model calls the tool directly; you’re not writing and re-writing the glue every time someone asks a new kind of question.
- A backend batch job — syncing 5,000 boxes into your TMS every hour? A plain REST call in a loop is simpler and you don’t want a model in that path at all.
- Event-driven — react the instant an ETA moves? Neither poll nor tool-call; take the webhook and let it push.
The mistake is using the wrong shape for the job: hand-writing agent glue against a REST API when an MCP tool would remove the whole layer, or spinning up an agent to do what a cron job and an endpoint already do.
The point
A tracking API and a tracking MCP server can sit on the same carrier connectors and the same DCSA-normalised events. What changes is who does the work — your integration code, or the model calling a self-describing tool. If you’re putting ocean freight in front of an AI agent, MCP is the surface that stops you re-inventing the interpretation layer in a prompt.
That’s why we built TrackingMCP as a hosted MCP server first, with the same capabilities on REST and webhooks behind one key — so the assistant calls a tool, the batch job calls an endpoint, and the delay finds you by webhook, all off one clean, DCSA-normalised spine. If you want the argument for why the answers have to be honest before any of this matters, we made it here: why your tracking says “100% complete” on a box that hasn’t sailed.