{
  "ucp": {
    "version": "2026-04-08",
    "services": {
      "dev.ucp.shopping": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.dev/2026-04-08/specification/overview",
          "transport": "mcp",
          "schema": "https://ucp.dev/2026-04-08/services/shopping/mcp.openrpc.json",
          "endpoint": "https://mcp.ucp.travel/mcp"
        }
      ]
    },
    "capabilities": {
      "dev.ucp.shopping.checkout": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.dev/2026-04-08/specification/checkout",
          "schema": "https://ucp.dev/2026-04-08/schemas/shopping/checkout.json"
        }
      ],
      "dev.ucp.shopping.order": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.dev/2026-04-08/specification/order",
          "schema": "https://ucp.dev/2026-04-08/schemas/shopping/order.json"
        }
      ],
      "travel.ucp.order": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.travel/specs/travel/order.html",
          "schema": "https://ucp.travel/schemas/travel/order.json",
          "extends": "dev.ucp.shopping.order",
          "config": {
            "cancellation": "two_step",
            "settlement": "operator_billing"
          }
        }
      ],
      "dev.ucp.shopping.ap2_mandate": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.dev/2026-04-08/specification/ap2-mandates",
          "schema": "https://ucp.dev/2026-04-08/schemas/shopping/ap2_mandate.json",
          "extends": "dev.ucp.shopping.checkout"
        }
      ],
      "dev.ucp.common.identity_linking": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.dev/2026-04-08/specification/identity-linking",
          "schema": "https://ucp.dev/2026-04-08/schemas/common/identity_linking.json",
          "config": {
            "authorization_server": "https://api.ucp.travel/.well-known/oauth-authorization-server",
            "jwks_uri": "https://api.ucp.travel/oauth/jwks",
            "scopes": {
              "dev.ucp.shopping.checkout:manage": [],
              "dev.ucp.shopping.order:read": [],
              "dev.ucp.shopping.order:manage": []
            }
          }
        }
      ],
      "travel.ucp.offer": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.travel/specs/travel/offer.html",
          "schema": "https://ucp.travel/schemas/travel/offer.json",
          "extends": "dev.ucp.shopping.checkout",
          "config": {
            "ttl_enforced": true,
            "revalidation_required": true
          }
        }
      ],
      "travel.ucp.flight": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.travel/specs/travel/flight.html",
          "schema": "https://ucp.travel/schemas/travel/flight.json",
          "extends": "dev.ucp.shopping.checkout"
        }
      ],
      "travel.ucp.passenger": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.travel/specs/travel/passenger.html",
          "schema": "https://ucp.travel/schemas/travel/passenger.json",
          "extends": "dev.ucp.shopping.checkout"
        }
      ],
      "travel.ucp.mandate": [
        {
          "version": "2026-04-08",
          "spec": "https://ucp.travel/specs/travel/mandate.html",
          "schema": "https://ucp.travel/schemas/travel/mandate.json",
          "extends": "dev.ucp.shopping.ap2_mandate"
        }
      ]
    },
    "supported_versions": {
      "2026-04-08": "https://ucp.travel/.well-known/ucp?version=2026-04-08"
    },
    "payment_handlers": {
      "travel.ucp.provider_payment": [
        {
          "id": "ucp_travel_provider",
          "version": "2026-04-08",
          "spec": "https://ucp.travel/specs/travel/provider-payment.html",
          "schema": "https://ucp.travel/schemas/travel/provider_payment.json",
          "available_instruments": [
            {
              "type": "card"
            },
            {
              "type": "balance"
            }
          ]
        }
      ]
    },
    "instructions": "Travel booking adapter for autonomous AI agents. Use search_flights to find bookable offers, get_offer_ancillaries to load confirmed bags and seats for a selected flight, update_checkout to stage chosen ancillaries into the active checkout, and complete_checkout only for the final irreversible booking step. Always use born_on for passengers; never infer or send type: adult as a substitute for age. Treat stays pricing as indicative until the provider confirms rates. If an offer expires or revalidation fails, re-search instead of retrying the same offer. If the user adds new requirements after search results are shown, such as extra baggage, vegan or special meals, seats, cabin changes, refundability, or schedule preferences, do not treat a numeric selection alone as booking consent; first re-check suitability and ask for explicit reconfirmation if the chosen offer no longer clearly matches those updated requirements. If the included baggage does not clearly cover all bags the traveler mentioned, warn before booking. If a meal preference such as vegan or vegetarian cannot be guaranteed through the current tools, state that before booking rather than after confirmation. If the user wants confirmed bags or seats, call get_offer_ancillaries with the exact selected offer_id and checkout_id, then call update_checkout with the chosen selected_services, confirm the updated total, and only then call complete_checkout. After update_checkout, treat those selected services as the active checkout state even if the final booking call omits them. If a booking call returns Bearer token has expired, stop and ask the traveler to reconnect authorization before retrying any authenticated booking action. If complete_checkout returns pending or 202-equivalent behavior, wait for webhook or recovery resolution and do not retry the booking call. After a successful complete_checkout response, use checkout.order.id as the booking identifier for any later get_booking call. Never use checkout_id as booking_id. Do not re-search or attempt a second purchase after a successful complete_checkout unless the provider explicitly says the first purchase did not complete. After completing a booking, never promise change or cancellation is available based on the offer's fare conditions alone. Always call get_booking first and inspect available_actions. Only offer change_booking if 'change' is in available_actions. Only offer cancel_booking if 'cancel' is in available_actions. If neither is present, tell the user the booking is not currently serviceable through this interface. Airline-initiated changes always require human escalation. Surface every booking reference returned by the provider, not just the primary PNR. To cancel a booking, call cancel_booking to get a preview with refund eligibility and expiry, then call confirm_cancellation before the preview expires. Do not confirm cancellation without first showing the traveler the refund quote and getting explicit confirmation. For change_booking, call it once to get a change preview and change_id. Then call confirm_change with the exact same booking_id and returned change_id pair. Never call change_booking a second time before attempting confirmation, because a new preview can invalidate the previous one. Never use a change_id as a booking_id. To add post-booking bags or other services, call list_booking_available_services first, show the traveler the returned options and total, then call add_booking_services with the chosen selected_services and explicit payment payload. Do not purchase post-booking services without first showing the traveler the service quote and getting explicit confirmation."
  },
  "signing_keys": [
    {
      "crv": "Ed25519",
      "x": "gXjzNfcPaRq-wQqJLzJm_1Mp5ojFa66ykwQbuQ1zyfI",
      "kty": "OKP",
      "kid": "oauth-ed25519",
      "use": "sig",
      "alg": "EdDSA"
    }
  ]
}