# directrate MCP server — install

Endpoint: POST https://api.directrate.dev/mcp (Model Context Protocol, Streamable HTTP, stateless). Auth: the header `x-api-key: <key>` (or `Authorization: Bearer <key>`). The key is a directrate API key.

## 1. Get a key

If the user does not have a key: they sign in at https://directrate.dev/login (magic link or Google, no card), open https://directrate.dev/dashboard/keys and create one. The Free plan gives 250 credits a month. The key is shown once; ask the user to put it in their environment, never to paste it into chat:

```bash
export DIRECTRATE_API_KEY=<the key>
```

Do not write the key into a config file in plain text when the client can read it from the environment or a prompt (the snippets below do that).

## 2. Add the server to the client

Claude.ai, Claude Desktop, Claude mobile and ChatGPT need no key at all: add a custom connector with the URL above and sign in when asked (OAuth; the consent page creates or picks the API key the connection will use). The header-based clients follow.

### Claude.ai

```
Settings → Connectors → Add custom connector
Name:  directrate
URL:   https://api.directrate.dev/mcp
→ Add → Connect → sign in to directrate → choose the API key it may use → Allow
```

Claude.ai, Claude Desktop and the Claude mobile apps sign in with OAuth: no key to paste. The consent page creates a key for the connector (or you pick one); revoke that key in the dashboard to disconnect. ChatGPT: Settings → Connectors → Create, the same URL, the same sign-in.

### Claude Code

```bash
claude mcp add --transport http directrate https://api.directrate.dev/mcp --header 'x-api-key: ${DIRECTRATE_API_KEY}'
```

One command. Keep the single quotes: Claude Code stores the header as written and expands ${DIRECTRATE_API_KEY} each time it starts, so the key never lands in ~/.claude.json.

### Cursor

```json
{
  "mcpServers": {
    "directrate": {
      "url": "https://api.directrate.dev/mcp",
      "headers": {
        "x-api-key": "${env:DIRECTRATE_API_KEY}"
      }
    }
  }
}
```

~/.cursor/mcp.json, or .cursor/mcp.json in the project. Cursor fills ${env:DIRECTRATE_API_KEY} from the environment it was started in.

### VS Code

```json
{
  "servers": {
    "directrate": {
      "type": "http",
      "url": "https://api.directrate.dev/mcp",
      "headers": {
        "x-api-key": "${input:directrate-key}"
      }
    }
  },
  "inputs": [
    {
      "id": "directrate-key",
      "type": "promptString",
      "description": "directrate API key",
      "password": true
    }
  ]
}
```

.vscode/mcp.json. VS Code asks for the key once and keeps it in its secret store.

### Windsurf / stdio

```json
{
  "mcpServers": {
    "directrate": {
      "command": "npx",
      "args": [
        "-y",
        "@directrate/mcp"
      ],
      "env": {
        "DIRECTRATE_API_KEY": "<your key>"
      }
    }
  }
}
```

For clients that only run local stdio servers (Windsurf, older Cursor, Claude Desktop without a connector): the @directrate/mcp package on npm bridges to the HTTP endpoint and forwards everything unchanged. The key sits in the file's env block (no environment expansion there), so keep the file private.

### Any other client

Remote Streamable HTTP with a static header: URL https://api.directrate.dev/mcp, header `x-api-key`. A client that only runs local stdio servers: `npx -y @directrate/mcp` with DIRECTRATE_API_KEY in its environment (the npm package bridges to the same endpoint).

## 3. Check it

Call the `chains` tool (free): it lists the 16 sources with their credit weights. Then `usage` (free) for the credits left. Then, for example, `shop` with chain hyatt, hotel_code CHIZP, checkin a date next month — 1 credit.

From a script, without an MCP client: a JSON-RPC POST. The transport insists on `Accept: application/json, text/event-stream` (both, even though the answer is always JSON) and `Content-Type: application/json`; otherwise it answers 406 or 415.

```bash
curl -s https://api.directrate.dev/mcp -H "x-api-key: $DIRECTRATE_API_KEY" \
  -H 'content-type: application/json' -H 'accept: application/json, text/event-stream' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"chains","arguments":{}}}'
```

## The tools

- `shop` — POST /v1/shop: Every rate plan of one hotel night: public, member, after tax. Credits: the source's shop weight (1 credit on most; radisson 3, bestwestern 5, wyndham 6); cached 0.25×.
- `award` — POST /v1/award: The same night in points, with cents-per-point and certificates. Credits: as shop.
- `parity` — POST /v1/parity: The direct rate beside Booking.com, Expedia, Hotels.com, Trip.com, Agoda. Credits: the direct shop + 1 per channel; +1 when an id was resolved live.
- `calendar` — POST /v1/calendar: Lowest per night over up to 60 nights. Credits: 0.1–0.25 a night on priced-calendar chains at los 1; the shop weight per live night elsewhere.
- `compset` — POST /v1/compset: Up to 25 hotels of one chain, lowest each. Credits: 0.25–0.5 per hotel returned, minimum 1 a call.
- `stay` — POST /v1/stay: A 2–14 night stay as one vs its nights alone. Credits: the shop weight + the calendar nights.
- `hotels` — GET /v1/hotels: The chain's hotel codes around a place. Credits: 1 a search (wyndham, bestwestern: the shop weight); a repeat within 24 h 0.25×.
- `hotel` — GET /v1/hotel: Name, address, rating, amenities for one code. Credits: 0 from the table; 1 for a live detail fetch.
- `matrix` — POST /v1/matrix: Up to 200 hotels × 366 nights as a batch job. Credits: the job's worst case reserved up front; cells from the store at the cache-hit rate.
- `job` — GET /v1/jobs/{id}: A batch job's progress and spend. Credits: free.
- `job_cells` — GET /v1/jobs/{id}/cells: A job's cells, paged. Credits: free.
- `watches` — GET /v1/watches: The key's watches and what they cost a day. Credits: free.
- `watch_create` — POST /v1/watches: Refresh nights on a schedule, webhook on a condition. Credits: credits_per_refresh, every refresh, while active.
- `watch_delete` — DELETE /v1/watches/{id}: Stop a watch. Credits: free.
- `chains` — GET /v1/chains: Every source with its credit weights and capabilities. Credits: free.
- `usage` — GET /v1/usage: Credits used and remaining this month. Credits: free.

Every tool is one REST call and is billed exactly like REST; the result states credits_charged. Errors, unknown hotel codes and sold-out answers cost nothing. Dates are YYYY-MM-DD; a hotel code is the chain's own property code (find it with `hotels`).

Docs: https://directrate.dev/docs/mcp · Price list as data: https://directrate.dev/pricing.json · REST reference: https://api.directrate.dev/openapi.json
