# MCP server

A rental's own AI agent, or a tool such as Claude Code or Cursor, can use the API through the Model Context Protocol (MCP). The server also gives Mellow's agent skills: how to do one job, step by step. The server is at:

```
https://api.mellow.is/mcp
```

It uses the streamable HTTP transport and answers each post with JSON. Every post carries the same bearer key as the REST API:

```
Authorization: Bearer sk_live_…
```

Mellow turns on MCP for a rental. A rental where MCP is off is not in `list_rentals`, and a tool call on it is refused. A reseller's key gets no MCP server.

## Connecting a client

Claude Code:

```
claude mcp add --transport http mellow https://api.mellow.is/mcp \
  --header "Authorization: Bearer sk_live_…"
```

A client that reads a JSON file, such as Cursor:

```json
{
  "mcpServers": {
    "mellow": {
      "url": "https://api.mellow.is/mcp",
      "headers": { "Authorization": "Bearer sk_live_…" }
    }
  }
}
```

The server does not have OAuth sign-in yet. A client that can only sign in with OAuth, such as a claude.ai connector, cannot connect yet.

## Tools

Each tool is one endpoint of the API. The tool takes the path and query parameters by name, and the request body as `body`. Its answer is the endpoint's JSON. A failed call gives the status and the problem object, such as `403: {"error":{"code":"forbidden",…}}`.

| Tool                   | Endpoint                                               |
| ---------------------- | ------------------------------------------------------ |
| `list_rentals`         | `GET /rentals`                                         |
| `list_car_types`       | `GET /rentals/{slug}/car-types`                        |
| `list_locations`       | `GET /rentals/{slug}/locations`                        |
| `list_products`        | `GET /rentals/{slug}/products`                         |
| `list_fees`            | `GET /rentals/{slug}/fees`                             |
| `list_currencies`      | `GET /rentals/{slug}/currencies`                       |
| `get_availability`     | `GET /rentals/{slug}/availability`                     |
| `get_quote`            | `POST /rentals/{slug}/quotes`                          |
| `get_availability_all` | `GET /availability`                                    |
| `get_quotes_all`       | `POST /quotes`                                         |
| `create_booking`       | `POST /rentals/{slug}/bookings`                        |
| `list_bookings`        | `GET /rentals/{slug}/bookings`                         |
| `get_booking`          | `GET /rentals/{slug}/bookings/{id}`                    |
| `change_booking`       | `PATCH /rentals/{slug}/bookings/{id}`                  |
| `cancel_booking`       | `POST /rentals/{slug}/bookings/{id}/cancel`            |
| `ask_payment`          | `POST /rentals/{slug}/bookings/{id}/payments`          |
| `hold_car`             | `POST /rentals/{slug}/holds`                           |
| `get_hold`             | `GET /rentals/{slug}/holds/{id}`                       |
| `give_back_hold`       | `DELETE /rentals/{slug}/holds/{id}`                    |
| `ask_hold_payment`     | `POST /rentals/{slug}/holds/{id}/payments`             |
| `book_hold`            | `POST /rentals/{slug}/holds/{id}/book`                 |
| `find_booking`         | `POST /rentals/{slug}/bookings/find`                   |
| `get_booking_choices`  | `GET /rentals/{slug}/bookings/{id}/manage`             |
| `price_booking_change` | `POST /rentals/{slug}/bookings/{id}/manage/quote`      |
| `save_booking_change`  | `POST /rentals/{slug}/bookings/{id}/manage`            |
| `get_checkin_content`  | `GET /rentals/{slug}/checkin/content`                  |
| `mark_checkin_content` | `POST /rentals/{slug}/bookings/{id}/checkin/content`   |
| `list_affiliates`      | `GET /rentals/{slug}/affiliates`                       |
| `get_affiliate`        | `GET /rentals/{slug}/affiliates/{id}`                  |
| `add_affiliate`        | `POST /rentals/{slug}/affiliates`                      |
| `list_commissions`     | `GET /rentals/{slug}/commissions`                      |
| `approve_commission`   | `POST /rentals/{slug}/commissions/{bookingId}/approve` |
| `reject_commission`    | `POST /rentals/{slug}/commissions/{bookingId}/reject`  |
| `list_price_lists`     | `GET /rentals/{slug}/price-lists`                      |
| `list_rate_periods`    | `GET /rentals/{slug}/rate-periods`                     |
| `get_rates`            | `GET /rentals/{slug}/price-lists/{id}/rates`           |
| `list_price_rules`     | `GET /rentals/{slug}/price-rules`                      |
| `set_rates`            | `PUT /rentals/{slug}/price-lists/{id}/rates`           |
| `add_rate_period`      | `POST /rentals/{slug}/rate-periods`                    |
| `change_rate_period`   | `PATCH /rentals/{slug}/rate-periods/{id}`              |
| `remove_rate_period`   | `DELETE /rentals/{slug}/rate-periods/{id}`             |
| `add_price_rule`       | `POST /rentals/{slug}/price-rules`                     |
| `change_price_rule`    | `PATCH /rentals/{slug}/price-rules/{id}`               |
| `remove_price_rule`    | `DELETE /rentals/{slug}/price-rules/{id}`              |
| `order_price_rules`    | `PUT /rentals/{slug}/price-rules/order`                |

The four hold tools take a Website channel's key, as their routes do. The organization's key gets `channel_only`.

`read_skill` gives one of the skills below. It runs no endpoint.

## Scopes

The key's [scopes](/authentication#scopes) hold for every tool. The tool list leaves out the tools the key may not call: a scope it lacks, or a route for the organization's key alone, such as `set_rates`. A key with only `booking.read` does not see `create_booking` or `cancel_booking`. Each call runs the real endpoint, so every check of the REST API runs too: the rentals the key reaches, a paused channel, and idempotency. Each tool call counts as one API call.

Give `create_booking` an `idempotencyKey`. A call tried again with the same key gets the same booking back.

A tool that writes a price takes `preview: "true"`. It answers the change and writes nothing. See [Price setup](/prices).

## Skills

The server's instructions list Mellow's agent skills, and `read_skill` gives one by name. Read a skill before you start its job.

| Skill                 | When to use it                                                                   |
| --------------------- | -------------------------------------------------------------------------------- |
| `change-season-rates` | Change the daily rates of car types in rate periods on a price list.             |
| `change-rate-periods` | Add, move or remove a rate period, and see what goes with a removal.             |
| `add-price-rule`      | Add or change a price rule, such as +10% on two car types for two weeks in July. |

The skills are written in the repository at `docs/skills/`.
