All files / src/tools tracking.ts

100% Statements 37/37
84.21% Branches 32/38
100% Functions 2/2
100% Lines 37/37

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95          2x           11x                           5x 5x 4x   5x 1x     3x       5x 3x 3x 1x   3x 1x       3x 1x     3x 1x     3x 1x     3x 1x     3x 1x     3x 1x 1x 1x 1x       3x 5x 1x 1x 1x 1x       3x         1x          
import type { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
import * as z from "zod/v4";
import type { PostNLClient } from "../postnl-client.js";
import { toTextResult, toErrorResult } from "../tool-result.js";
 
export const registerTrackingTools = (
  server: McpServer,
  client: PostNLClient,
  _customerCode: string,
  _customerNumber: string,
): void => {
  server.registerTool(
    "get_shipment_status",
    {
      title: "Get Shipment Status",
      description:
        "Track a PostNL shipment by barcode. Returns the current status, expected delivery date, " +
        "and status history of the shipment.",
      annotations: { readOnlyHint: true, openWorldHint: true },
 
      inputSchema: z.object({
        barcode: z.string().min(1).describe("The PostNL barcode/tracking number of the shipment"),
      }),
    },
    async ({ barcode }) => {
      try {
        const result = await client.getShipmentStatus(barcode);
        const shipment = result.CurrentStatus?.Shipment;
 
        if (!shipment) {
          return toTextResult(`No status information found for barcode: ${barcode}`);
        }
 
        const lines: string[] = [
          `Barcode: ${shipment.Barcode ?? barcode}`,
        ];
 
        if (shipment.Status) {
          lines.push(`Status: ${shipment.Status.StatusDescription ?? shipment.Status.StatusCode ?? "Unknown"}`);
          if (shipment.Status.PhaseDescription) {
            lines.push(`Phase: ${shipment.Status.PhaseDescription}`);
          }
          if (shipment.Status.TimeStamp) {
            lines.push(`Updated: ${shipment.Status.TimeStamp}`);
          }
        }
 
        if (shipment.ProductDescription) {
          lines.push(`Product: ${shipment.ProductDescription}`);
        }
 
        if (shipment.ExpectedDeliveryDate) {
          lines.push(`Expected delivery: ${shipment.ExpectedDeliveryDate}`);
        }
 
        if (shipment.ExpectedDeliveryTimeStampStart && shipment.ExpectedDeliveryTimeStampEnd) {
          lines.push(`Delivery window: ${shipment.ExpectedDeliveryTimeStampStart} - ${shipment.ExpectedDeliveryTimeStampEnd}`);
        }
 
        if (shipment.DeliveryDate) {
          lines.push(`Delivered: ${shipment.DeliveryDate}`);
        }
 
        if (shipment.Reference) {
          lines.push(`Reference: ${shipment.Reference}`);
        }
 
        if (shipment.OldStatuses && shipment.OldStatuses.length > 0) {
          lines.push("");
          lines.push("Status history:");
          for (const status of shipment.OldStatuses) {
            lines.push(`  - ${status.TimeStamp ?? ""}: ${status.StatusDescription ?? status.StatusCode ?? "Unknown"}`);
          }
        }
 
        const warnings = result.Warnings ?? [];
        if (warnings.length > 0) {
          lines.push("");
          lines.push("Warnings:");
          for (const warn of warnings) {
            lines.push(`  - [${warn.Code}] ${warn.Description}`);
          }
        }
 
        return toTextResult(
          lines.join("\n"),
          result as unknown as Record<string, unknown>,
        );
      } catch (error) {
        return toErrorResult(error);
      }
    },
  );
};