# AITravel.az — MCP Tools Specification

> **MCP-ready architecture — a Model Context Protocol server is PLANNED, not yet live.**
> The same capabilities are available today via the REST / OpenAPI endpoints described in
> [`agent-tools.md`](./agent-tools.md). This document specifies the 8 MCP tools that the
> planned server will expose and shows exactly how each maps onto a live endpoint today.

- Site: <https://aitravel.az>
- Working agent API base URL (live): `https://zdzwsxpbnebhbclomdcy.supabase.co/functions/v1/agent`
- OpenAPI spec: <https://aitravel.az/openapi.json>
- Agent manifest: <https://aitravel.az/.well-known/ai-agent.json>
- Planned MCP endpoint: <https://mcp.aitravel.az> (not live yet)

## Conventions

- All prices are **approximate**. No tool finalizes a price or completes a booking.
- Booking always requires **human / operator confirmation**.
- Read tools require no authentication; CORS is open. The OpenAI key for planning is
  server-side only.
- Tools must never modify prices, delete user data, expose private data, or claim final prices.

---

## Tool 1 — `search_destinations`

**Description:** Search the destination catalog by category, budget, season, or free text.

**Input schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "category":   { "type": "string", "description": "Category filter, e.g. beach, culture." },
    "budget_max": { "type": "number", "description": "Maximum approximate budget." },
    "season":     { "type": "string", "description": "Season filter, e.g. summer." },
    "q":          { "type": "string", "description": "Free-text search query." }
  },
  "additionalProperties": false
}
```

**Output schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "destinations": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "name": { "type": "string" },
          "country": { "type": "string" },
          "city": { "type": "string" },
          "short_description": { "type": "string" },
          "best_for": { "type": "array", "items": { "type": "string" } },
          "approximate_budget_from": { "type": "number" },
          "currency": { "type": "string" },
          "duration_options": { "type": "array", "items": { "type": "string" } },
          "season": { "type": "string" },
          "disclaimer": { "type": "string" }
        }
      }
    },
    "disclaimer": { "type": "string" }
  }
}
```

**Safety notes:** Read-only. `approximate_budget_from` is an estimate, not a quote.

**Example request (tool call args):**

```json
{ "category": "culture", "budget_max": 1000, "season": "summer", "q": "georgia" }
```

**Example response:**

```json
{
  "destinations": [
    {
      "slug": "tbilisi",
      "name": "Tbilisi",
      "country": "Georgia",
      "city": "Tbilisi",
      "short_description": "Historic capital with thermal baths and wine culture.",
      "best_for": ["culture", "food"],
      "approximate_budget_from": 600,
      "currency": "USD",
      "duration_options": ["3 days", "5 days"],
      "season": "all year",
      "disclaimer": "Prices are approximate."
    }
  ],
  "disclaimer": "Prices are approximate. Booking requires operator confirmation."
}
```

---

## Tool 2 — `search_tours`

**Description:** Search packaged tours by destination, category, or budget.

**Input schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "destination": { "type": "string" },
    "category":    { "type": "string" },
    "budget_max":  { "type": "number" }
  },
  "additionalProperties": false
}
```

**Output schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "tours": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "title": { "type": "string" },
          "destination": { "type": "string" },
          "category": { "type": "string" },
          "duration": { "type": "string" },
          "approximate_price_from": { "type": "number" },
          "currency": { "type": "string" },
          "includes": { "type": "array", "items": { "type": "string" } },
          "disclaimer": { "type": "string" }
        }
      }
    },
    "disclaimer": { "type": "string" }
  }
}
```

**Safety notes:** Read-only. `approximate_price_from` is an estimate, not a quote.

**Example request (tool call args):**

```json
{ "destination": "georgia", "category": "culture", "budget_max": 1000 }
```

**Example response:**

```json
{
  "tours": [
    {
      "slug": "georgia-classic-5d",
      "title": "Georgia Classic 5 Days",
      "destination": "Georgia",
      "category": "culture",
      "duration": "5 days",
      "approximate_price_from": 750,
      "currency": "USD",
      "includes": ["hotels", "breakfast", "guided tours"],
      "disclaimer": "Prices are approximate."
    }
  ],
  "disclaimer": "Prices are approximate. Booking requires operator confirmation."
}
```

---

## Tool 3 — `search_excursions`

**Description:** Search day excursions by city or category.

**Input schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "city":     { "type": "string" },
    "category": { "type": "string" }
  },
  "additionalProperties": false
}
```

**Output schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "excursions": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "slug": { "type": "string" },
          "title": { "type": "string" },
          "city": { "type": "string" },
          "duration": { "type": "string" },
          "approximate_price_from": { "type": "number" },
          "currency": { "type": "string" },
          "disclaimer": { "type": "string" }
        }
      }
    },
    "disclaimer": { "type": "string" }
  }
}
```

**Safety notes:** Read-only. `approximate_price_from` is an estimate, not a quote.

**Example request (tool call args):**

```json
{ "city": "tbilisi", "category": "walking" }
```

**Example response:**

```json
{
  "excursions": [
    {
      "slug": "tbilisi-old-town-walk",
      "title": "Tbilisi Old Town Walking Tour",
      "city": "Tbilisi",
      "duration": "3 hours",
      "approximate_price_from": 25,
      "currency": "USD",
      "disclaimer": "Prices are approximate."
    }
  ],
  "disclaimer": "Prices are approximate. Booking requires operator confirmation."
}
```

---

## Tool 4 — `plan_trip`

**Description:** Generate a structured, day-by-day trip plan from a natural-language query.

**Input schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "query":     { "type": "string" },
    "lang":      { "type": "string", "enum": ["az", "ru", "en"] },
    "dates":     { "type": "string" },
    "budget":    { "type": "string" },
    "travelers": { "type": "string" }
  },
  "required": ["query"],
  "additionalProperties": false
}
```

**Output schema (JSON Schema):** `TripPlan`

```json
{
  "type": "object",
  "properties": {
    "summary": { "type": "string" },
    "destinations": { "type": "array", "items": { "type": "string" } },
    "budget": {
      "type": "object",
      "properties": {
        "currency": { "type": "string" },
        "total": { "type": "number" },
        "perPerson": { "type": "number" }
      }
    },
    "itinerary": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "day": { "type": "integer" },
          "city": { "type": "string" },
          "morning": { "type": "string" },
          "afternoon": { "type": "string" },
          "evening": { "type": "string" },
          "tips": { "type": "string" }
        }
      }
    },
    "hotels": { "type": "array", "items": { "type": "string" } },
    "activities": { "type": "array", "items": { "type": "string" } },
    "disclaimer": { "type": "string" }
  }
}
```

**Safety notes:** Budget figures are approximate estimates. The plan reserves nothing and
is not a booking. Never present a figure as final.

**Example request (tool call args):**

```json
{
  "query": "5-day cultural trip to Georgia for two people",
  "lang": "en",
  "dates": "2026-06-10 to 2026-06-15",
  "budget": "1500 USD",
  "travelers": "2 adults"
}
```

**Example response:**

```json
{
  "summary": "5-day cultural trip to Georgia for two travelers.",
  "destinations": ["Tbilisi", "Kazbegi"],
  "budget": { "currency": "USD", "total": 1450, "perPerson": 725 },
  "itinerary": [
    {
      "day": 1,
      "city": "Tbilisi",
      "morning": "Arrive, check in, walk the Old Town.",
      "afternoon": "Narikala Fortress cable car.",
      "evening": "Dinner on Shardeni Street.",
      "tips": "Wear comfortable shoes."
    }
  ],
  "hotels": ["Example Boutique Hotel, Tbilisi"],
  "activities": ["Sulfur bath visit", "Wine tasting tour"],
  "disclaimer": "Prices are approximate. Booking requires operator confirmation."
}
```

---

## Tool 5 — `calculate_budget`

**Description:** Produce an approximate budget breakdown for a trip. Today this is
**derived from the `budget` field of `plan_trip` output**; a dedicated budget endpoint is
planned.

**Input schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "query":     { "type": "string", "description": "Natural-language trip description." },
    "lang":      { "type": "string", "enum": ["az", "ru", "en"] },
    "dates":     { "type": "string" },
    "budget":    { "type": "string" },
    "travelers": { "type": "string" }
  },
  "required": ["query"],
  "additionalProperties": false
}
```

**Output schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "currency": { "type": "string" },
    "total": { "type": "number" },
    "perPerson": { "type": "number" },
    "disclaimer": { "type": "string" }
  }
}
```

**Safety notes:** Output is an approximate estimate only, never a quote. Derived from
`plan_trip`, so the same disclaimers apply.

**Example request (tool call args):**

```json
{ "query": "5-day cultural trip to Georgia for two people", "travelers": "2 adults" }
```

**Example response:**

```json
{
  "currency": "USD",
  "total": 1450,
  "perPerson": 725,
  "disclaimer": "Prices are approximate. Booking requires operator confirmation."
}
```

---

## Tool 6 — `create_travel_request`

**Description:** Create a travel request (lead). Always produces an operator-reviewed draft.

**Input schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "name":        { "type": "string" },
    "contact":     { "type": "string" },
    "destination": { "type": "string" },
    "dates":       { "type": "string" },
    "travelers":   { "type": "number" },
    "budget":      { "type": "string" },
    "message":     { "type": "string" },
    "lang":        { "type": "string" }
  },
  "required": ["contact", "message"],
  "additionalProperties": false
}
```

**Output schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "request_id": { "type": "string" },
    "status": { "type": "string", "const": "draft_pending_operator" },
    "message": { "type": "string" },
    "disclaimer": { "type": "string" }
  }
}
```

**Safety notes:** Creates a draft with status `draft_pending_operator`. Nothing is booked
or finalized. Collect only contact info the user provides; never expose other users' data.

**Example request (tool call args):**

```json
{
  "name": "Aysel",
  "contact": "+994 50 000 00 00",
  "destination": "Georgia",
  "dates": "2026-06-10 to 2026-06-15",
  "travelers": 2,
  "budget": "1500 USD",
  "message": "Interested in a 5-day cultural trip.",
  "lang": "en"
}
```

**Example response:**

```json
{
  "request_id": "req_8f2a91",
  "status": "draft_pending_operator",
  "message": "Your request was received and is pending operator confirmation.",
  "disclaimer": "Prices are approximate. Booking requires operator confirmation."
}
```

---

## Tool 7 — `check_availability`

**Description:** Return an approximate availability indication for a destination and dates.

**Input schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "destination": { "type": "string" },
    "dates":       { "type": "string" },
    "travelers":   { "type": "number" }
  },
  "required": ["destination"],
  "additionalProperties": false
}
```

**Output schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "destination": { "type": "string" },
    "status": { "type": "string", "const": "approximate" },
    "available": { "type": "boolean" },
    "note": { "type": "string" },
    "disclaimer": { "type": "string" }
  }
}
```

**Safety notes:** `status` is always `approximate`; `available` is an indication, not a
guarantee. Real availability is confirmed only by a human operator.

**Example request (tool call args):**

```json
{ "destination": "Georgia", "dates": "2026-06-10 to 2026-06-15", "travelers": 2 }
```

**Example response:**

```json
{
  "destination": "Georgia",
  "status": "approximate",
  "available": true,
  "note": "Likely available; subject to operator confirmation.",
  "disclaimer": "Prices are approximate. Booking requires operator confirmation."
}
```

---

## Tool 8 — `request_vip_manager`

**Description:** Request a dedicated VIP travel manager. Creates an operator-reviewed draft.

**Input schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "name":        { "type": "string" },
    "contact":     { "type": "string" },
    "destination": { "type": "string" },
    "dates":       { "type": "string" },
    "travelers":   { "type": "number" },
    "budget":      { "type": "string" },
    "message":     { "type": "string" },
    "lang":        { "type": "string" }
  },
  "required": ["contact", "message"],
  "additionalProperties": false
}
```

**Output schema (JSON Schema):**

```json
{
  "type": "object",
  "properties": {
    "request_id": { "type": "string" },
    "status": { "type": "string", "const": "draft_pending_operator" },
    "message": { "type": "string" },
    "disclaimer": { "type": "string" }
  }
}
```

**Safety notes:** Creates a draft with status `draft_pending_operator`. Nothing is booked
or finalized. Collect only contact info the user provides; never expose other users' data.

**Example request (tool call args):**

```json
{
  "name": "Aysel",
  "contact": "aysel@example.com",
  "destination": "Maldives",
  "message": "Looking for a luxury honeymoon package with a personal manager.",
  "lang": "en"
}
```

**Example response:**

```json
{
  "request_id": "req_vip_3c10",
  "status": "draft_pending_operator",
  "message": "Your VIP manager request was received and is pending operator confirmation.",
  "disclaimer": "Prices are approximate. Booking requires operator confirmation."
}
```

---

## How this maps to live endpoints today

The MCP server is not live yet, but every tool already works through the live REST API:

| MCP tool                 | Live endpoint today                                  |
|--------------------------|------------------------------------------------------|
| `search_destinations`    | `GET /destinations`                                  |
| `search_tours`           | `GET /tours`                                         |
| `search_excursions`      | `GET /excursions`                                    |
| `plan_trip`              | `POST /plan-trip`                                    |
| `calculate_budget`       | derived from `plan_trip` output (`budget` field); dedicated endpoint planned |
| `create_travel_request`  | `POST /create-lead` (`type: "lead"`)                 |
| `check_availability`     | `POST /check-availability`                           |
| `request_vip_manager`    | `POST /create-lead` (`type: "vip_manager"`)          |

All endpoints are relative to the live base URL:
`https://zdzwsxpbnebhbclomdcy.supabase.co/functions/v1/agent`.

## Planned MCP server

A dedicated Model Context Protocol server is planned at:

```
https://mcp.aitravel.az
```

The planned server will:

- Expose all **8 tools** above through the standard MCP tool interface.
- Offer both a **stdio** transport (for local/desktop MCP clients) and an **HTTP**
  transport (for hosted/remote MCP clients).
- Act as a thin adapter that forwards each tool call to the corresponding live REST
  endpoint (per the mapping above), preserving all approximate-price and
  operator-confirmation disclaimers.
- Keep the OpenAI key server-side; the MCP server never returns secrets to clients.
- Add `calculate_budget` as a first-class tool once a dedicated budget endpoint ships;
  until then it derives from `plan_trip`.

Until the MCP server is live, AI agents should integrate via the REST / OpenAPI endpoints
documented in [`agent-tools.md`](./agent-tools.md) and `https://aitravel.az/openapi.json`.
