# Connecting AI Agents & MCP Integration Guide

Traveate treats AI agents—whether built by the platform, a partner, or the hotel itself—as **Digital Team Members** (`agents` table) with scoped permissions, hourly read/write budgets, and mandatory two-step confirmation for all state-mutating actions.

---

## 1. Two Ways to Connect an AI Agent

### Option A: Model Context Protocol (MCP) over `stdio`
Connect any MCP-compatible host (Claude Desktop, Cursor, Google Antigravity, Windsurf, or custom MCP clients) directly to [`src/mcp/server.ts`](../src/mcp/server.ts):

```json
{
  "mcpServers": {
    "traveate-hospitality": {
      "command": "node",
      "args": ["src/mcp/server.ts"],
      "env": {
        "TRAVEATE_API_URL": "https://traveate.com",
        "TRAVEATE_AGENT_API_KEY": "traveate_ak_concierge_dev_key"
      }
    }
  }
}
```

> **Stateless Bridge Invariant:** The MCP server in `src/mcp/server.ts` never imports `node:sqlite` or touches the database directly. Every MCP tool call is forwarded over HTTP to `POST /api/v1/agent-actions/:tool_name` with the `x-agent-api-key` header.

### Option B: Direct HTTP Agent Gateway (`POST /api/v1/agent-actions/:tool_name`)
Any custom agent (Python, TypeScript, LangGraph, CrewAI, OpenAI Responses API, or webhook worker) can call the HTTP Agent Gateway directly:

```bash
curl -X POST https://traveate.com/api/v1/agent-actions/get_availability \
  -H "Content-Type: application/json" \
  -H "x-agent-api-key: traveate_ak_concierge_dev_key" \
  -d '{
    "property_id": "hope-homestay",
    "check_in_date": "2026-11-22",
    "check_out_date": "2026-11-24",
    "adults": 4
  }'
```

---

## 2. Digital Team Member Authentication & Scopes

Each agent is registered in the `agents` table with:
- `api_key_hash`: SHA-256 hash of its bearer token (plaintext keys are never stored).
- `property_id`: `null` for organization-wide agents (can manage both `hope-homestay` and `rock-hyrax-hotel`), or a specific `property_id` to isolate an agent to a single property.
- `allowed_tools`: Explicit allow-list of MCP tools the agent can invoke. Calling an unlisted tool returns `403 TOOL_SCOPE_FORBIDDEN`.
- `max_calls_per_hour` & `max_writes_per_hour`: Enforced via `agent_usage_events`. Exceeding the budget returns `429 AGENT_RATE_LIMIT_EXCEEDED`.

### Seeded Development API Keys

| Agent Role | API Key (`x-agent-api-key`) | Scope | Budgets |
| :--- | :--- | :--- | :--- |
| **Hope Front Desk Concierge & Host Copilot Agent** | `traveate_ak_concierge_dev_key` | All 32 read + preview/confirm write tools + `remember_property_knowledge` across the organization | `300` calls/hr, `30` writes/hr |
| **Guest Website & WhatsApp Concierge Agent (Guest-Safe)** | `traveate_ak_guest_widget_dev_key` | Strictly Guest-Safe tools (`get_property`, `list_unit_types`, `get_availability`, `get_distance_and_nearby`, `list_property_knowledge`, `create_booking_preview`, `send_message_preview`) | `300` calls/hr, `20` writes/hr |
| **Discovery & Content Agent (Read-Only)** | `traveate_ak_readonly_dev_key` | Read-only tools (`get_property`, `list_properties`, `list_unit_types`, `get_availability`, `get_rate_plan`, `get_booking`, `list_bookings`, `get_guest`, `get_distance_and_nearby`, `get_reviews`, `list_messages`, `export_ical_feed`, `list_channel_feeds`, `list_property_knowledge`) | `300` calls/hr, `0` writes/hr |

---

## 3. Dual-Persona Split: Guest Concierge vs. Host Operations Copilot

Traveate separates guest-facing conversational booking from host-facing property operations using two distinct personas backed by MCP tool-scope enforcement:

1. **🛎️ Guest Website & WhatsApp Concierge (`mode: "guest_concierge"`, `POST /api/v1/public/properties/:slug/chat`, `GET /widget/:slug`):**
   - Uses `traveate_ak_guest_widget_dev_key` and is hard-locked to the target property's slug (`hope-homestay` or `rock-hyrax-hotel`).
   - Can quote real-time availability & channel rates, answer property edge-case FAQs from `property_knowledge`, and create zero-form conversational booking previews (`create_booking_preview`).
   - Strictly blocked from host-admin actions (`property_onboarding`, `teach_property_rule`, `set_rate_calendar_preview`, ` *_confirm`).
2. **👷 Host Operations Copilot (`mode: "host_copilot"`, `POST /api/v1/host/copilot`):**
   - Uses `traveate_ak_concierge_dev_key` inside the authenticated operator dashboard.
   - Can teach new operational rules in natural language (*"Remember for Hope Homestay: Airport pickup from JKIA Terminal 1A is $20 flat..."* → calls `remember_property_knowledge`), stage autonomous property onboarding (`onboard_property_preview`), and manage multi-property operations.

---

## 4. Living Property Memory & Continuous Feedback Learning (`property_knowledge`)

Every property has unique operational nuances and edge cases. Traveate stores these in the `property_knowledge` table (`pricing_quirk`, `checkin_checkout`, `house_rule`, `guest_faq`, `operations_sop`, `feedback_learned`) and grows smarter through three feedback loops:
1. **Rejection-Feedback Learning (`POST /api/v1/previews/:id/reject`):** When a host rejects an `ActionPreview` in the dashboard and provides a `rejection_reason`, Traveate automatically saves a `feedback_learned` rule linked to `source_preview_id`.
2. **Natural-Language Copilot Training:** Hosts can tell the Copilot *"Remember for Hope Homestay: ..."* to invoke `remember_property_knowledge`.
3. **Automatic Consultation:** Both the Guest Concierge and Host Copilot call `list_property_knowledge` to cite verified rules when answering inquiries.

---

## 5. Two-Step `Preview -> Confirm` Safety Protocol

Agents **cannot** mutate bookings, rates, calendar blocks, reviews, messages, or property settings in a single step. Every write requires two calls:

1. **`*_preview` Tool Call:**
   - Validates all business rules and calculates the exact financial/operational diff (`resolved_proposal`).
   - Computes a SHA-256 `state_hash` of the underlying inventory/entity state.
   - Saves a `pending` row in `action_previews` (15-minute TTL) and logs `*.previewed` in `audit_logs`.
2. **`*_confirm` Tool Call (or Human Click in `/dashboard`):**
   - Re-computes the current `state_hash`. If another booking, rate change, or block occurred since the preview was generated, confirmation fails with **`409 STALE_PREVIEW`**.
   - Applies the mutation inside a SQLite transaction and writes an immutable `audit_logs` record with `before` and `after` snapshots.
