> ## Documentation Index
> Fetch the complete documentation index at: https://terminal49.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Terminal49 MCP Server

> Connect the Terminal49 MCP server to Claude Desktop or Cursor so AI tools can query, search, and answer questions with live shipment tracking data.

Use the Terminal49 MCP server to let Claude or Cursor answer questions with live container and shipment data—without writing custom glue code.

## TL;DR – get started in 5 minutes

<Steps>
  <Step title="Get your API key">
    Create an API key in the [developer portal](https://app.terminal49.com/developers/api-keys).
  </Step>

  <Step title="Pick your MCP client">
    * **Claude Desktop** (macOS / Windows / Linux)
    * **Cursor IDE**
  </Step>

  <Step title="Paste this config (Claude Desktop)">
    Edit the Claude Desktop config file for your operating system:

    | OS      | Config path                                                       |
    | ------- | ----------------------------------------------------------------- |
    | macOS   | `~/Library/Application Support/Claude/claude_desktop_config.json` |
    | Windows | `%APPDATA%\Claude\claude_desktop_config.json`                     |
    | Linux   | `~/.config/Claude/claude_desktop_config.json`                     |

    ```json theme={null}
    {
      "mcpServers": {
        "terminal49": {
          "url": "https://mcp.terminal49.com",
          "headers": {
            "Authorization": "Token YOUR_API_KEY"
          }
        }
      }
    }
    ```

    <Accordion title="Cursor IDE config">
      ```json theme={null}
      {
        "mcp": {
          "servers": {
            "terminal49": {
              "url": "https://mcp.terminal49.com",
              "headers": {
                "Authorization": "Token YOUR_API_KEY"
              }
            }
          }
        }
      }
      ```
    </Accordion>
  </Step>

  <Step title="Ask Claude">
    > "Using the Terminal49 MCP server, track container CAIU1234567 with Maersk."
  </Step>

  <Step title="Explore tools">
    Ask Claude:

    > "List the tools available in the Terminal49 MCP server and what they're for."
  </Step>
</Steps>

<Note>
  Need test container numbers? See [Test Numbers](/api-docs/useful-info/test-numbers) for containers you can use during development.
</Note>

For the full walkthrough (including local stdio dev, deployment, and SDK examples), see [MCP Server Quickstart](/api-docs/in-depth-guides/mcp).

***

## Transports

| Transport         | Endpoint                          | Best For                         |
| ----------------- | --------------------------------- | -------------------------------- |
| HTTP (streamable) | `POST https://mcp.terminal49.com` | Serverless, short-lived requests |

**Authentication**:

* API key only (OAuth not required for this release)
* Pass `Authorization: Token YOUR_API_KEY`. Use the `Token` scheme for API keys. The `Bearer` scheme is reserved for WorkOS OAuth access tokens — it currently accepts API keys for backward compatibility, but once OAuth is enabled, `Bearer` accepts only WorkOS tokens.
* The hosted endpoint always requires the `Authorization` header. Only the [local stdio server](/api-docs/in-depth-guides/mcp#local-stdio-development) reads the `T49_API_TOKEN` environment variable instead of a header.

<Tip>
  Connector URL: `https://mcp.terminal49.com`. It is the canonical OAuth resource identifier, so OAuth clients (ChatGPT, Claude connectors) bind to the correct token audience.
</Tip>

## Any MCP client

Use the same hosted Streamable HTTP endpoint in any MCP-compatible client:

```json theme={null}
{
  "url": "https://mcp.terminal49.com",
  "headers": {
    "Authorization": "Token YOUR_API_KEY"
  }
}
```

<Note>
  OAuth is not available for the hosted MCP server yet. Use a Terminal49 API key until OAuth support is published.
</Note>

The same [rate limits](/api-docs/in-depth-guides/rate-limiting) apply to MCP endpoints as the REST API.

***

## Monitoring

Self-hosted deployments can enable [Sentry MCP Monitoring](https://docs.sentry.io/ai/monitoring/mcp/) by setting `SENTRY_DSN`. This captures MCP tool calls, resource reads, prompt usage, performance spans, and errors in Sentry.

<Warning>
  Input and output recording is disabled by default. Leave `SENTRY_MCP_RECORD_INPUTS=false` and `SENTRY_MCP_RECORD_OUTPUTS=false` unless your Sentry project is approved to store shipment identifiers, references, and customer data.
</Warning>

***

## Tools reference

<Note>
  Every tool is read-only except `track_container`, which creates a tracking request. If a container for the number is already in your account, `track_container` returns it instead of creating a new request; otherwise it creates a tracking request, so repeated calls before a container links can create additional requests.
</Note>

### `search_container`

Find containers by container number, BL, booking, or your own reference. This is the fastest way to locate containers.

**Parameters**

* `query` *(string, required)* – container number, BL, booking, or reference

<Accordion title="Example MCP request">
  ```json theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "search_container",
      "arguments": {
        "query": "CAIU1234567"
      }
    }
  }
  ```
</Accordion>

<Accordion title="Example response">
  ```json theme={null}
  {
    "containers": [
      {
        "id": "abc-123-uuid",
        "containerNumber": "CAIU1234567",
        "status": "in_transit",
        "shippingLine": "Maersk",
        "podTerminal": "APM Terminals",
        "destination": "Los Angeles"
      }
    ],
    "shipments": [],
    "totalResults": 1
  }
  ```
</Accordion>

**Good for**

* "Find this container and tell me where it is"
* "Show all containers with reference PO-12345"

**REST equivalent**: [GET /containers](/api-docs/api-reference/containers/list-containers) with filters

***

### `track_container`

Start tracking a new container. Creates a tracking request and returns container details.

**Parameters**

* `number` *(string, required)* – container number, BL, or booking number
* `numberType` *(string, optional)* – override inference (`container`, `bill_of_lading`, `booking_number`)
* `scac` *(string, optional)* – shipping line code, e.g., `MAEU` for Maersk
* `refNumbers` *(string\[], optional)* – your reference numbers

<Accordion title="Example MCP request">
  ```json theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "track_container",
      "arguments": {
        "number": "CAIU1234567",
        "scac": "MAEU"
      }
    }
  }
  ```
</Accordion>

**Good for**

* "Track container CAIU1234567 with Maersk"
* "Start tracking this new shipment"

**REST equivalent**: [POST /tracking\_requests](/api-docs/api-reference/tracking-requests/create-a-tracking-request)

***

### `get_container`

Get detailed container information with flexible data loading. Choose what to include based on your question.

**Parameters**

* `id` *(uuid, required)* – Terminal49 container UUID
* `include` *(string\[], optional)* – what to load:
  * `shipment` – routing, BOL, line, ref numbers (lightweight)
  * `pod_terminal` – terminal name, location (lightweight)
  * `transport_events` – full event history (heavy, 50-100 events)

<Accordion title="Example MCP request">
  ```json theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "get_container",
      "arguments": {
        "id": "abc-123-uuid",
        "include": ["shipment", "pod_terminal"]
      }
    }
  }
  ```
</Accordion>

<Accordion title="Example response (mapped)">
  ```json theme={null}
  {
    "id": "abc-123-uuid",
    "number": "CAIU1234567",
    "status": "available_for_pickup",
    "equipment": {
      "type": "40HC",
      "length": "40",
      "height": "high_cube"
    },
    "location": {
      "currentLocation": "APM Terminals",
      "availableForPickup": true,
      "podArrivedAt": "2025-01-15T08:30:00Z",
      "podDischargedAt": "2025-01-16T14:20:00Z"
    },
    "demurrage": {
      "pickupLfd": "2025-01-22",
      "holds": [],
      "fees": []
    },
    "shipment": {
      "id": "shipment-uuid",
      "billOfLading": "MAEU123456789",
      "shippingLineScac": "MAEU"
    }
  }
  ```
</Accordion>

**Good for**

* "What's the status of this container?"
* "Is it available for pickup? Any holds?"
* "When does demurrage start?"

**REST equivalent**: [GET /containers/{id}](/api-docs/api-reference/containers/get-a-container)

***

### `get_container_transport_events`

Get the full event timeline for a container's journey.

**Parameters**

* `id` *(uuid, required)* – Terminal49 container UUID

<Accordion title="Example response">
  ```json theme={null}
  {
    "totalEvents": 47,
    "eventCategories": {
      "vesselEvents": 8,
      "railEvents": 12,
      "terminalEvents": 18
    },
    "milestones": {
      "vesselLoadedAt": "2024-12-08T10:30:00Z",
      "vesselDepartedAt": "2024-12-09T14:00:00Z",
      "vesselArrivedAt": "2024-12-22T08:30:00Z",
      "dischargedAt": "2024-12-23T11:15:00Z"
    },
    "timeline": [
      {
        "event": "container.transport.vessel_loaded",
        "timestamp": "2024-12-08T10:30:00Z",
        "location": { "name": "Shanghai", "locode": "CNSHA" }
      }
    ]
  }
  ```
</Accordion>

**Good for**

* "Show me the journey timeline"
* "What happened to this container?"
* "How long was the rail portion?"

**REST equivalent**: [GET /containers/{id}/transport\_events](/api-docs/api-reference/containers/get-a-containers-transport-events)

***

### `get_shipment_details`

Get shipment-level information including routing, BOL, and all containers.

**Parameters**

* `id` *(uuid, required)* – Terminal49 shipment UUID
* `include_containers` *(boolean, optional)* – include container list (default: true)

**Good for**

* "Tell me about this shipment"
* "What containers are on this BL?"
* "Show me the routing"

**REST equivalent**: [GET /shipments/{id}](/api-docs/api-reference/shipments/get-a-shipment)

***

### `get_supported_shipping_lines`

List carriers supported by Terminal49 with their SCAC codes.

**Parameters**

* `search` *(string, optional)* – filter by name or SCAC

**Good for**

* "What carriers do you support?"
* "What's the SCAC code for CMA CGM?"

**REST equivalent**: [GET /shipping\_lines](/api-docs/api-reference/shipping-lines/shipping-lines)

***

### `get_container_route`

Get detailed multi-leg routing with vessel itinerary.

<Warning>
  This is a **paid feature**. If not enabled for your account, use `get_container_transport_events` for historical movement data instead.

  See [Entitlements and Paid Features](/api-docs/useful-info/entitlements) for the related Routing Data entitlement.
</Warning>

**Parameters**

* `id` *(uuid, required)* – Terminal49 container UUID

**Good for**

* "What's the routing for this container?"
* "Which transshipment ports?"
* "What vessel is it on?"

**REST equivalent**: [GET /containers/{id}](/api-docs/api-reference/containers/get-a-container) (route data is included with the container)

***

### `list_shipments`

List shipments with optional filters and pagination.

**Parameters**

* `status`, `port`, `carrier`, `updated_after` *(string, optional)*
* `include_containers` *(boolean, optional)*
* `page`, `page_size` *(number, optional)*

**Good for**

* "List recent shipments"
* "Show in-transit shipments for MAEU"

**REST equivalent**: [GET /shipments](/api-docs/api-reference/shipments/list-shipments)

***

### `list_containers`

List containers with optional filters and pagination.

**Parameters**

* `status`, `port`, `carrier`, `updated_after` *(string, optional)*
* `include` *(string, optional)* – comma-separated include list
* `page`, `page_size` *(number, optional)*

**Good for**

* "List containers updated in the last 24h"
* "Show containers at a specific POD port"

**REST equivalent**: [GET /containers](/api-docs/api-reference/containers/list-containers)

***

### `list_tracking_requests`

List tracking requests with optional filters and pagination.

**Parameters**

* `filters` *(object, optional)* – raw query filters
* `page`, `page_size` *(number, optional)*

**Good for**

* "Show failed tracking requests"
* "List latest tracking activity"

**REST equivalent**: [GET /tracking\_requests](/api-docs/api-reference/tracking-requests/list-tracking-requests)

***

## Prompts reference

Prompts are pre-built workflows that guide the AI through multi-step analysis.

### `track-shipment`

Quick container tracking with optional carrier specification.

**Arguments**

* `container_number` *(string, required)* – e.g., `CAIU1234567`
* `carrier` *(string, optional)* – SCAC code, e.g., `MAEU`

**Try this in Claude:**

> "Using Terminal49, track container CAIU1234567 and show me its current status, location, and ETA."

***

### `check-demurrage`

Analyze demurrage/detention risk for a container.

**Arguments**

* `container_id` *(uuid, required)* – from `search_container` or `get_container`

**Try this in Claude:**

> "Using Terminal49, check demurrage risk for container CAIU1234567 and explain which fees apply and when."

***

### `analyze-delays`

Identify delays and root causes in a container's journey.

**Arguments**

* `container_id` *(uuid, required)* – Container UUID

**Try this in Claude:**

> "Using Terminal49, analyze delays for container CAIU1234567 and tell me what caused them."

***

## Resources reference

Resources provide static or dynamic data that AI clients can read.

| Resource URI                           | Description                             |
| -------------------------------------- | --------------------------------------- |
| `terminal49://container/{id}`          | Container data in markdown format       |
| `terminal49://docs/milestone-glossary` | Event/milestone reference documentation |

<Accordion title="Example resources/read request">
  ```json theme={null}
  {
    "jsonrpc": "2.0",
    "id": 1,
    "method": "resources/read",
    "params": {
      "uri": "terminal49://docs/milestone-glossary"
    }
  }
  ```
</Accordion>

***

## Not yet supported

These Terminal49 API capabilities are available via the [SDK](/api-docs/in-depth-guides/mcp#sdk-usage) but not yet exposed as MCP tools:

| API                 | Description                      | Workaround                                                                     |
| ------------------- | -------------------------------- | ------------------------------------------------------------------------------ |
| `update_shipment`   | Update shipment ref numbers/tags | Use [REST API](/api-docs/api-reference/shipments/edit-a-shipment)              |
| `stop_tracking`     | Stop tracking a shipment         | Use [REST API](/api-docs/api-reference/shipments/stop-tracking-shipment)       |
| `resume_tracking`   | Resume tracking a shipment       | Use [REST API](/api-docs/api-reference/shipments/resume-tracking-shipment)     |
| `raw_events`        | Get raw EDI event data           | Use [REST API](/api-docs/api-reference/containers/get-a-containers-raw-events) |
| `refresh_container` | Force refresh container data     | Use [REST API](/api-docs/api-reference/containers/refresh-container)           |
| Webhooks            | Real-time event notifications    | Configure via the [webhooks guide](/api-docs/in-depth-guides/webhooks)         |

<Info>
  Shipment/container list operations are available via MCP. Update/stop/resume tracking operations still require REST API or direct SDK usage.
</Info>

***

## Related guides

* [MCP Server Quickstart](/api-docs/in-depth-guides/mcp) – Full setup, local dev, deployment
* [Rate Limiting](/api-docs/in-depth-guides/rate-limiting) – Same limits apply to MCP
* [Test Numbers](/api-docs/useful-info/test-numbers) – Containers for testing
* [Webhooks](/api-docs/in-depth-guides/webhooks) – Real-time updates (use with MCP for best results)
