In the last two parts of this series I covered how the Model Context Protocol maps onto a freight API and then tore down the freight MCP servers that shipped in 2026. Both ended on the same open question, so this part answers it directly: once an agent can book real freight, how do you stop it booking the wrong thing for the wrong person? Security is where a freight MCP server stops looking like a developer toy and starts looking like a system that moves money and trucks.

I run this from the seat of a marketplace that exposes an API, so my bias is practical rather than academic. The threats below are the ones we actually model when we decide which tool an agent may call without a human in the loop.

Why a freight server raises the stakes

A generic MCP server that reads your calendar leaks information when it fails. A freight server that books a load does something costlier. A bad call can dispatch a truck to the wrong yard, change a consignee on a live shipment, cancel a booking a customer is counting on, or pull a bill of lading that should never have left the account. These are not data-exposure bugs. They are money and physical goods moving on an instruction nobody typed.

Why a freight server raises the stakes

That difference reframes the whole problem. With a chat assistant, the worst case is an embarrassing answer. With freight, the worst case has a freight invoice attached and a shipment somewhere it should not be. So the question is never "is this server secure" in the abstract. It is "which specific actions can an agent take, and what does each one cost if it goes wrong."

The two failure modes worth losing sleep over

Most MCP risk in 2026 reduces to two patterns, and freight makes both worse.

The two failure modes worth losing sleep over

Prompt injection is the old web problem wearing new clothes. An agent reads text from somewhere it does not fully control, a shipment note, a PDF, an email body, and that text contains an instruction the model obeys. In freight the poisoned text arrives through legitimate channels all day long: a booking comment, a customs description, a carrier's status update. If your booking tool trusts whatever the model passes it, a sentence buried in a delivery note can become a real cancellation.

Tool poisoning is subtler and specific to MCP. The protocol lets a server describe its own tools, and the agent reads those descriptions to decide what to call. A malicious or compromised server can write a description that quietly tells the model to exfiltrate an API key or re-route a shipment, and the user never sees that text. Anthropic and independent researchers spent early 2026 documenting variants of this, and the lesson for freight is blunt: the description layer is executable, so treat a third-party tool description with the same suspicion you would treat third-party code.

Read versus write: the line that should decide your auth

The single most useful security decision I made was to stop thinking about "the MCP server" as one trust boundary and split it by what each tool does to the world.

Read versus write: the line that should decide your auth

What can stay open

Quoting a lane, listing capacity, calculating a transit estimate, looking up a port code. None of these change anything. Letting an agent reach them with little or no friction is the whole point, and it is where the daily value sits. A reader who wants to compare three routes should not have to mint a token to do it. Across the servers in the teardown, the serious ones kept quoting and reference tools low-friction for exactly this reason.

What must be gated

Booking, cancelling, changing a consignee, editing an address, pulling a document, anything that touches an invoice. Every one of these writes to the real world, and every one needs an authenticated, authorised, auditable call behind it. The rule we follow is simple to state and harder to enforce: a read tool can be open, a write tool never is.

OAuth 2.1 and PKCE, not a long-lived key in a config file

The MCP authorization spec settled on OAuth 2.1 for remote servers, and that choice carries real weight for freight. A static API key pasted into a config file is fine for a solo developer running a server over stdio on their own machine. It is the wrong model the moment the server is reachable over HTTP and an agent acts on behalf of a named user inside a shared account.

Three properties do the heavy lifting. Scoped tokens mean a token minted for quoting cannot book. Short-lived tokens mean a leaked credential expires on its own instead of living forever in a log. Revocable tokens mean that when something looks wrong, you cut access in seconds rather than rotating a shared key everyone depends on. OAuth 2.1 also requires PKCE on the authorisation-code flow, which closes the interception gap that older OAuth deployments left open. None of this is exotic. It is the same hardening any payments API went through, applied to the moment an agent says "book it."

Here is the shape of the boundary we enforce, written as the table I wish every freight server published.

Agent actionReads or writesAuth we requireIf it goes wrong
Get a quoteReadOpen or basic keyWasted call, no harm
Check capacity, transit, trackingReadOpen or basic keyStale answer at worst
Book a shipmentWriteScoped OAuth token, confirmation stepReal cost, real truck
Cancel or re-bookWriteScoped token, idempotency keyLost slot, penalty
Change consignee or addressWriteScoped token, human confirmMisdelivery, fraud
Pull a bill of lading or invoiceRead sensitiveScoped token, per-document checkData and document leak

The pattern in that table is the actual product decision. Reads sit on the left and stay cheap. Writes sit on the right and earn their friction.

The exposed-instance problem

A surprising amount of MCP risk is not clever at all. It is a server that was meant to run locally, exposed to the open internet without authentication, because shipping it that way was easier. The protocol supports two transports. A stdio server runs as a local process the client launches, which keeps it on your machine and off the network. A hosted HTTP server is reachable by anything that can find its URL.

For a read-only utility server the HTTP exposure is mostly harmless. For one with booking tools it is the whole ballgame. If your write tools are reachable over public HTTP, authentication is not a feature you add later, it is the thing standing between a stranger and your dispatch queue. Our rule is that booking and document tools are never served over an unauthenticated HTTP endpoint, full stop. When in doubt, a write-capable server should default to stdio and local launch, and only graduate to hosted HTTP once the OAuth flow above is in place.

Defending the description layer against tool poisoning

Because tool descriptions steer the model, they deserve the same controls as code you deploy. Three habits cover most of the exposure.

  • Pin and review the servers you connect. An agent wired to a curated set of known servers is a smaller target than one that installs whatever a registry offers. Treat a new server like a new dependency, because that is what it is.
  • Keep a human on every write. A confirmation step before booking, cancelling or changing a consignee turns a silent injected instruction into a visible request the user can refuse. It is the cheapest control with the highest payoff.
  • Validate at the API, not in the prompt. The server should re-check every parameter it receives against the account's real permissions and the booking's real state, rather than trusting that the model assembled a sensible call. The model proposes, the API decides.

What a marketplace server has to enforce that a single carrier can skip

A single-carrier server only ever acts on its own network, so its blast radius is one operator. A marketplace server quotes and books across many carriers on behalf of many users, which changes the security job in two ways.

First, scoping has to be per-user and per-carrier, not per-server. A token that lets an agent book with one carrier should not silently reach another, and one customer's agent must never see another customer's documents. Second, the audit trail matters more, because when an agent books across a marketplace you need to answer "which user, which token, which carrier, at what time" for every write. We treat that log as part of the product, not an afterthought, since it is what lets us revoke narrowly instead of pulling the plug on everyone.

A practical checklist before you expose booking

  • Split tools by read and write, and write the split down where the agent and your team can both see it.
  • Keep quoting and reference tools low-friction so the daily value survives.
  • Put every write behind a scoped, short-lived, revocable OAuth 2.1 token with PKCE.
  • Require a confirmation step on booking, cancellation, consignee and address changes.
  • Re-validate every parameter at the API against real permissions and real shipment state.
  • Never serve write tools over unauthenticated HTTP, and default write-capable servers to local stdio.
  • Pin the servers your agent connects to, and review new ones like new code.
  • Log every write with user, token, carrier and time, and rehearse revocation before you need it.

None of these are unique to artificial intelligence. They are the controls freight and payments already use, pointed at the new place where an instruction can originate. The agent is a new caller, not a new set of rules.

Frequently asked questions

Is it safe to let an AI agent book freight at all?

Yes, when booking sits behind an authenticated and authorised call with a confirmation step, and when the server re-checks every parameter rather than trusting the model. The unsafe version is an open write tool with no human in the loop. Treat booking like any other money-moving action and the agent becomes another authenticated caller.

Why use OAuth 2.1 instead of a simple API key?

A static key tends to be long-lived, broadly scoped and hard to revoke without disrupting everyone who shares it. OAuth 2.1 gives you scoped, short-lived, revocable tokens and requires PKCE on the authorisation flow. For a local stdio server a key is acceptable, but anything reachable over HTTP that can write should use the OAuth model.

What is tool poisoning in MCP?

Tool poisoning is when a server's tool description, which the agent reads to decide what to call, contains hidden instructions that steer the model toward harmful actions such as leaking a key or re-routing a shipment. Because the description influences behaviour, you defend it the way you defend code: pin trusted servers, keep a human on writes, and validate at the API.

Should a freight MCP server run as stdio or hosted HTTP?

A read-only utility server is fine over hosted HTTP. A server with booking or document tools should default to local stdio and only move to hosted HTTP once scoped OAuth is in place, because an exposed write endpoint without authentication is reachable by anyone who finds the URL.

That closes the loop this series opened. If you have not read the earlier parts, the protocol primer explains how a freight API becomes a set of tools, and the teardown shows where the shipped servers drew these lines in practice.