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

# Terminal49 MCP Server Quickstart

> Set up the Terminal49 MCP server in Claude, ChatGPT, Cursor, Copilot, or any MCP client to query live shipment and container tracking data from your AI tool.

This guide covers everything you need to connect an MCP client to Terminal49's container tracking data.

<Note>
  Just want to get started fast? See the per-tool setup guides for [Claude](/mcp/setup/claude), [Claude Code](/mcp/setup/claude-code), [ChatGPT](/mcp/setup/chatgpt), [Cursor](/mcp/setup/cursor), [Microsoft Copilot](/mcp/setup/microsoft-copilot), and [VS Code](/mcp/setup/vs-code), or the [MCP Overview](/mcp/home) for a 5-minute setup.
</Note>

## Prerequisites

Before you begin, make sure you have:

<CardGroup cols={2}>
  <Card title="Terminal49 account" icon="user">
    You sign in with your Terminal49 credentials during the OAuth flow — no API key needed
  </Card>

  <Card title="API key (optional)" icon="key">
    Only needed for clients without OAuth support or the local stdio server — create one in the [developer portal](https://app.terminal49.com/developers/api-keys)
  </Card>

  <Card title="Node.js 24.x" icon="node-js">
    Required if running the MCP server locally
  </Card>

  <Card title="MCP client" icon="robot">
    Claude, ChatGPT, Cursor, Microsoft Copilot, VS Code, or any MCP-compatible client
  </Card>
</CardGroup>

**Technical Details:**

* **MCP SDK**: `@modelcontextprotocol/sdk ^1.29.0`
* **TypeScript SDK**: `@terminal49/sdk 0.3.0`
* **Sentry MCP Monitoring**: `@sentry/node ^10.55.0` (optional)
* **Runtime**: Node.js 24.x

***

## Transports

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

**Authentication**: OAuth 2.1 (recommended) or API key.

* **OAuth 2.1** – no API key needed. Add `https://mcp.terminal49.com` to your client; it discovers the authorization server (`https://auth.terminal49.com`) via protected resource metadata, registers itself with Dynamic Client Registration, and opens your browser so you can sign in with your Terminal49 credentials. Tokens are stored and refreshed by the client.
* **API key** – for clients that can't run a browser OAuth flow, pass `Authorization: Token YOUR_API_KEY`. Use the `Token` scheme for API keys; the `Bearer` scheme is used for OAuth access tokens, which OAuth clients obtain automatically.

Only the [local stdio server](#local-stdio-development) reads the `T49_API_TOKEN` environment variable instead of a header.

<Tip>
  For hosted production usage, connect to `https://mcp.terminal49.com` — the root origin is the canonical connector URL and OAuth resource identifier.
</Tip>

***

## Observability

The MCP server supports optional [Sentry MCP Monitoring](https://docs.sentry.io/ai/monitoring/mcp/). Set `SENTRY_DSN` to capture MCP server connections, tool executions, resource access, prompts, performance spans, and errors in Sentry.

```bash theme={null}
SENTRY_DSN=___PUBLIC_DSN___
SENTRY_TRACES_SAMPLE_RATE=1.0
SENTRY_MCP_RECORD_INPUTS=false
SENTRY_MCP_RECORD_OUTPUTS=false
SENTRY_SEND_DEFAULT_PII=false
```

<Warning>
  `SENTRY_MCP_RECORD_INPUTS` and `SENTRY_MCP_RECORD_OUTPUTS` are disabled by default because MCP payloads can include shipment identifiers, references, and customer data. Enable them only if your Sentry project is approved for that data.
</Warning>

***

## Configure your MCP client

### OAuth setup (recommended)

Most clients connect with just the server URL and a browser sign-in — no API key. Follow the guide for your tool:

* [Claude](/mcp/setup/claude) – claude.ai and Claude Desktop
* [Claude Code](/mcp/setup/claude-code) – one `claude mcp add` command
* [ChatGPT](/mcp/setup/chatgpt) – custom connector with Developer mode
* [Cursor](/mcp/setup/cursor) – `mcp.json` or Cursor Settings → MCP
* [Microsoft Copilot](/mcp/setup/microsoft-copilot) – Copilot Studio agent tools
* [VS Code](/mcp/setup/vs-code) – GitHub Copilot agent mode
* [Agent plugins](/mcp/setup/agent-plugins) – Terminal49 plugin for Claude Code, Cursor, Codex, and GitHub Copilot CLI
* [Other MCP clients](/mcp/setup/other-clients) – generic configuration

The manual configurations below use an API key instead. Use them for clients or environments where the browser OAuth flow isn't practical.

<Warning>
  claude.ai and Claude Desktop cannot send a static API-key header — they always authenticate through the OAuth connector flow. Follow the [Claude setup guide](/mcp/setup/claude) to connect them. For API-key-based local development in Claude Desktop, use the [local stdio server](#local-stdio-development) below instead.
</Warning>

### Cursor IDE (manual, API key)

Add to `.cursor/mcp.json` in your project (or `~/.cursor/mcp.json` for all projects):

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

### Local stdio (development)

For local development without a hosted server:

```json theme={null}
{
  "mcpServers": {
    "terminal49": {
      "command": "node",
      "args": ["/path/to/API/packages/mcp/dist/index.js"],
      "env": {
        "T49_API_TOKEN": "YOUR_API_KEY"
      }
    }
  }
}
```

<Warning>
  Build the MCP server first:
  `cd packages/mcp && npm install && T49_SDK_SOURCE=published npm run sdk:setup && npm run build`
</Warning>

<Accordion title="Contributor mode: switch SDK source">
  Use published SDK by default:

  ```bash theme={null}
  cd packages/mcp
  T49_SDK_SOURCE=published npm run sdk:setup
  ```

  Use local SDK build during development:

  ```bash theme={null}
  cd packages/mcp
  T49_SDK_SOURCE=local npm run sdk:setup
  ```
</Accordion>

***

## Test your setup

Once configured, verify everything works:

<Steps>
  <Step title="Restart your MCP client">
    Close and reopen Claude Desktop or Cursor to load the new config.
  </Step>

  <Step title="Ask Claude to list tools">
    > "List the tools available in the Terminal49 MCP server."

    Claude should respond with a list of 10 tools including `search_container`, `track_container`, and list tools.
  </Step>

  <Step title="Search for a test container">
    > "Using the Terminal49 MCP server, search for container TCLU1234567 and summarize its status."

    If configured correctly, Claude will call `search_container` and return container details.
  </Step>

  <Step title="Try a multi-step query">
    > "Using Terminal49, find container CAIU1234567, check its demurrage risk, and tell me if I need to pick it up urgently."

    Claude should chain multiple tools together to answer.
  </Step>
</Steps>

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

***

## Troubleshooting

| Symptom                        | Likely Cause                                      | How to Fix                                                                                                                                                                                                                                           |
| ------------------------------ | ------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| "Cannot connect to MCP server" | Wrong URL or config path                          | Confirm URL is `https://mcp.terminal49.com` and config file path matches your OS                                                                                                                                                                     |
| `401 Unauthorized`             | Expired OAuth session, or missing/invalid API key | Disconnect and reconnect the connector to re-run the OAuth sign-in. If using an API key, create a new one in the [developer portal](https://app.terminal49.com/developers/api-keys) and ensure the `Authorization: Token YOUR_API_KEY` header is set |
| `429 Too Many Requests`        | Rate limit exceeded                               | See [Rate Limiting](/api-docs/in-depth-guides/rate-limiting); use webhooks instead of polling                                                                                                                                                        |
| Tools list is empty            | Config not loaded                                 | Restart Claude/Cursor; check MCP inspector for errors                                                                                                                                                                                                |
| "Tool not found"               | Typo in tool name                                 | Use exact names: `search_container`, `get_container`, etc.                                                                                                                                                                                           |
| Slow responses                 | Large data requests                               | Use `include` parameter to load only what you need                                                                                                                                                                                                   |

<Accordion title="Check MCP server logs">
  If using the hosted server, check your Terminal49 dashboard for API logs.

  If running locally:

  ```bash theme={null}
  cd packages/mcp
  T49_API_TOKEN=YOUR_API_KEY npm run mcp:stdio 2>&1 | head -20
  ```
</Accordion>

***

## MCP capabilities

### Tools

| Tool                             | Description                                    | Parameters                                                                                     |
| -------------------------------- | ---------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| `search_container`               | Find containers by number, BL, booking, or ref | `query: string`                                                                                |
| `track_container`                | Start tracking a container                     | `number`, `numberType?`, `scac?`, `refNumbers?`                                                |
| `get_container`                  | Get container with optional includes           | `id: uuid`, `include?: ['shipment', 'pod_terminal', 'transport_events']`                       |
| `get_shipment_details`           | Get shipment and containers                    | `id: uuid`, `include_containers?: boolean`                                                     |
| `get_container_transport_events` | Get event timeline                             | `id: uuid`                                                                                     |
| `get_supported_shipping_lines`   | List carriers with SCAC codes                  | `search?: string`                                                                              |
| `get_container_route`            | Get multi-leg routing (paid feature)           | `id: uuid`                                                                                     |
| `list_shipments`                 | List shipments with filters + pagination       | `status?`, `port?`, `carrier?`, `updated_after?`, `include_containers?`, `page?`, `page_size?` |
| `list_containers`                | List containers with filters + pagination      | `status?`, `port?`, `carrier?`, `updated_after?`, `include?`, `page?`, `page_size?`            |
| `list_tracking_requests`         | List tracking requests with filters            | `filters?`, `status?`, `request_type?`, `page?`, `page_size?`                                  |

### Prompts

| Prompt            | Description             | Arguments                      |
| ----------------- | ----------------------- | ------------------------------ |
| `track-shipment`  | Quick tracking workflow | `container_number`, `carrier?` |
| `check-demurrage` | Demurrage risk analysis | `container_id`                 |
| `analyze-delays`  | Journey delay analysis  | `container_id`                 |

### Resources

| URI                                    | Description                |
| -------------------------------------- | -------------------------- |
| `terminal49://container/{id}`          | Container data as resource |
| `terminal49://docs/milestone-glossary` | Event/milestone reference  |

For detailed examples and response formats, see [MCP Overview → Tools Reference](/mcp/home#tools-reference).

***

## SDK usage

The TypeScript SDK provides the same capabilities as MCP tools, plus additional APIs not yet exposed via MCP.

```bash theme={null}
npm install @terminal49/sdk
```

```typescript theme={null}
import { Terminal49Client } from '@terminal49/sdk';

const client = new Terminal49Client({
  apiToken: process.env.T49_API_TOKEN!,
  defaultFormat: 'mapped'
});

// Get container with shipment and terminal
const container = await client.containers.get(
  'container-uuid',
  ['shipment', 'pod_terminal']
);

// Search for containers
const results = await client.search('CAIU1234567');

// List shipments with filters (not available via MCP)
const shipments = await client.shipments.list({
  status: 'in_transit',
  carrier: 'MAEU'
});
```

### Response formats

| Format   | Description                                                  |
| -------- | ------------------------------------------------------------ |
| `raw`    | JSON:API response with `data`, `attributes`, `relationships` |
| `mapped` | Simplified, camelCase objects with IDs resolved              |
| `both`   | `{ raw, mapped }` for debugging                              |

<Accordion title="Raw vs Mapped example">
  **Raw format:**

  ```json theme={null}
  {
    "data": {
      "type": "container",
      "id": "abc-123",
      "attributes": {
        "container_number": "CAIU1234567",
        "available_for_pickup": true
      }
    }
  }
  ```

  **Mapped format:**

  ```json theme={null}
  {
    "id": "abc-123",
    "containerNumber": "CAIU1234567",
    "availableForPickup": true
  }
  ```
</Accordion>

***

## Deployment

### Vercel (production)

The `vercel.json` configures the MCP server (excerpt):

```json theme={null}
{
  "installCommand": "npm ci",
  "buildCommand": "npm run build --workspace @terminal49/sdk && npm run build --workspace @terminal49/mcp",
  "functions": {
    "api/mcp.ts": { "maxDuration": 30 }
  },
  "rewrites": [
    { "source": "/mcp", "destination": "/api/mcp" },
    { "source": "/", "destination": "/api/mcp" }
  ]
}
```

### Environment variables

| Variable                    | Required        | Description                                                                                               |
| --------------------------- | --------------- | --------------------------------------------------------------------------------------------------------- |
| `T49_API_TOKEN`             | For local stdio | Terminal49 API key. The hosted HTTP endpoint authenticates callers via the `Authorization` header instead |
| `T49_API_BASE_URL`          | No              | Override API URL (default: `https://api.terminal49.com/v2`)                                               |
| `T49_MCP_ALLOWED_HOSTS`     | No              | Comma-separated host allowlist for request Host validation                                                |
| `T49_MCP_ALLOWED_ORIGINS`   | No              | Comma-separated origin allowlist for request Origin validation                                            |
| `SENTRY_DSN`                | No              | Enables Sentry MCP Monitoring                                                                             |
| `SENTRY_ENVIRONMENT`        | No              | Sentry environment name; defaults to `NODE_ENV`                                                           |
| `SENTRY_RELEASE`            | No              | Sentry release identifier; defaults to `VERCEL_GIT_COMMIT_SHA`                                            |
| `SENTRY_TRACES_SAMPLE_RATE` | No              | Trace sampling rate from `0` to `1`; defaults to `1.0`                                                    |
| `SENTRY_MCP_RECORD_INPUTS`  | No              | Records MCP inputs in Sentry when set to `true`; defaults to `false`                                      |
| `SENTRY_MCP_RECORD_OUTPUTS` | No              | Records MCP outputs in Sentry when set to `true`; defaults to `false`                                     |
| `SENTRY_SEND_DEFAULT_PII`   | No              | Enables Sentry default PII behavior; defaults to `false`                                                  |

***

## Testing locally

```bash theme={null}
# Build the MCP server
cd packages/mcp
npm install
npm run build

# Test tools/list
echo '{"jsonrpc":"2.0","method":"tools/list","id":1}' | T49_API_TOKEN=YOUR_API_KEY npm run mcp:stdio

# Test search_container
echo '{"jsonrpc":"2.0","method":"tools/call","params":{"name":"search_container","arguments":{"query":"CAIU1234567"}},"id":2}' | T49_API_TOKEN=YOUR_API_KEY npm run mcp:stdio

# Test the hosted endpoint
curl -X POST https://mcp.terminal49.com \
  -H "Authorization: Token $T49_API_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json, text/event-stream" \
  -H "MCP-Protocol-Version: 2025-06-18" \
  -d '{"jsonrpc":"2.0","method":"tools/list","id":1}'
```

***

## Related guides

* [MCP Overview](/mcp/home) – Quick start and tools reference
* Setup guides: [Claude](/mcp/setup/claude), [Claude Code](/mcp/setup/claude-code), [ChatGPT](/mcp/setup/chatgpt), [Cursor](/mcp/setup/cursor), [Microsoft Copilot](/mcp/setup/microsoft-copilot), [VS Code](/mcp/setup/vs-code), [Agent plugins](/mcp/setup/agent-plugins), [Other clients](/mcp/setup/other-clients)
* [Rate Limiting](/api-docs/in-depth-guides/rate-limiting) – API limits (same for MCP)
* [Test Numbers](/api-docs/useful-info/test-numbers) – Containers for testing
* [Webhooks](/api-docs/in-depth-guides/webhooks) – Real-time updates
* [API Data Sources](/api-docs/useful-info/api-data-sources-availability) – Data freshness and coverage
