Typed boundary
Upstream DTOs map into domain models before they become MCP views.
A coding challenge that turned live DSV shipment data into tools for AI agents—and led to an interview.
I built this as a Sendify coding challenge. The team liked the solution enough to invite me to interview.
The brief was to make DSV shipment data available to an AI assistant. I chose MCP over a conversational wrapper so the integration would expose explicit, reusable capabilities that any compatible client could discover and call.
The result is a Go server that communicates over stdio and presents three focused tools: find shipments from a reference, fetch the full detail for a resolved shipment, and list the 21 reference formats accepted by DSV.

Separating search from detail keeps each call understandable and lets an agent disambiguate multiple matches before requesting a heavier response. Responses include freshness and retrieval time, while failures use stable codes such as INVALID_INPUT, SHIPMENT_NOT_FOUND, and UPSTREAM_UNAVAILABLE.

DSV's public tracking page uses JSON endpoints, but they sit behind Cap.js browser checks and proof-of-work. A conventional retrying HTTP client succeeded once, then returned repeated 429 responses. Retrying harder could not fix a client the upstream had classified as automation.
The working adapter runs a long-lived Chromium process through chromedp. DSV's own page completes its browser challenge, then the adapter captures the JSON responses through the Chrome DevTools Protocol. Reusing one browser session amortizes the five-to-ten-second cold start and preserves the solved session state for later calls.
Tradeoff: the browser path costs more memory and startup time than a direct HTTP client. It is isolated behind the upstream interface so the MCP and domain layers do not depend on how DSV data is retrieved.
The public API does not return sender or receiver names, so the server does not invent them. It returns the available place data and documents the limitation. Unknown transport modes and event codes are preserved instead of crashing, and event histories are sorted defensively because observed order is not a contractual guarantee.
Upstream DTOs map into domain models before they become MCP views.
Detail caching uses DSV's shipment ID because several input references can point to the same shipment.
Search and active detail responses have short TTLs; delivered shipments can safely remain cached for 24 hours.
Singleflight prevents duplicate fetches, stale data can cover a brief outage, and Prometheus metrics expose request behavior.
The repository includes fixtures for booked, dispatching, in-delivery, and delivered shipments across parcel and LTL freight. Unit tests cover mapping, chronological event ordering, cache expiry and stale fallback, MCP error contracts, and each tool's successful and failing paths.
A separate live verification harness ran both search and detail calls for all ten challenge waybills. It confirmed single- and multi-package results, empty event arrays for newly booked freight, heavy loads, and delivered shipments without missing goods blocks or unexpected response shapes.