Use this skill BEFORE calling `list_cruise_sailings`, `list_stateroom_categories`, `explore_rates` (with sailingId), or `create_alert` (kind:"cruise") for any Disney Cruise Line trip — Disney Wish, Disney Fantasy, Disney Treasure, Disney Dream, Disney Magic, Disney Wonder, Disney Destiny, Disney Adventure — or any DCL itinerary (Bahamian, Caribbean, Alaskan, Mediterranean, Transatlantic, Castaway Cay, Lookout Cay, Port Canaveral). Cruise flow is STRUCTURALLY DIFFERENT from hotels: no ticket days, no dining plan toggle, no Memory Maker — the cruise fare already bundles those. Contains the DCL questionnaire (months array for search, party, optional ship/nights; then sailingId + category + mode for pricing), stateroom category structure (Inside/Oceanview/Verandah/Concierge), ship codes (WW=Wish, WD=Destiny, DF=Fantasy, DA=Adventure, DD=Dream, DT=Treasure, DM=Magic, DW=Wonder), and kid-pricing nuances.
Layer this on top of room-genie-core. DCL is structurally different from hotels: you book a sailing (a specific ship + departure date) and pick a stateroom category (a room type code like "O9C").
| Code | Ship | Typical routes |
|---|---|---|
WD | Disney Destiny | (New 2025) — Caribbean, Bahamas |
WW | Disney Wish | Bahamas, Caribbean |
DF | Disney Fantasy | 7-night Caribbean |
DA | Disney Adventure | (New) — Asia-Pacific |
DD | Disney Dream | Europe |
DT | Disney Treasure | Caribbean |
DM | Disney Magic | Europe, transatlantic |
DW |
| Disney Wonder |
| Alaska, Mexico, Pacific |
Pass the 2-letter code as ships filter on list_cruise_sailings when the user wants a specific ship.
| Type | Letter prefix | Examples | Typical vibe |
|---|---|---|---|
| Inside | I, 11 | 11C, 11B, 11A | No window, cheapest |
| Oceanview | O, 8, 9 | O9C, 8D, 9B | Porthole or window, no verandah |
| Verandah | V, 4, 5, 6, 7 | V7A, 5C, 4A | Private balcony |
| Concierge | T, V1, V2, V3 | V3B, T, R | Concierge lounge access, top decks, pricier |
The exact category codes come from list_stateroom_categories — never guess; always call the tool to get the current list for a specific sailing.
list_cruise_sailings or explore_rates)DCL questionnaire is different from hotels. Before searching, confirm:
For sailing search (list_cruise_sailings):
YYYY-MM format, at least one. Ask "what month(s) are you flexible on?".Search performance note: list_cruise_sailings scrapes DCL live. Scope directly drives latency:
When the user asks for a specific target date (e.g. "closest to April 8"): The tool returns every matching sailing for the month filters, which can be 30–50 rows for a popular ship. Don't dump all of them. Instead:
|departureDate - targetDate| in JavaScript (mentally) and show only the 3–5 closest sailings — nearest match first, then nearest alternatives on either side.This also dodges the overfetch problem where Render returns 51 sailings for a full month but the user only cares about 2–3 of them.
For pricing a specific sailing (explore_rates with sailingId):
Sailing ID — from the search result.
Stateroom preference — Inside (cheapest), Oceanview, Verandah, or Concierge (pricey, limited). Ask which category fits their budget.
Mode:
availability — "is the category open, how many left" — free.package — full pricing with tax. Requires Explorer.Placeholder discount? — REQUIRED ASK before pricing. Phrase it like:
"Are you booking this with a Disney Cruise Line placeholder (also called Booking a Future Cruise Onboard)? It gets you 10% off the voyage fare and a $250-reduced deposit since you prepaid that on your prior cruise. Or is this your first DCL cruise / no placeholder?"
explore_rates({ ..., placeholder: true }). The placeholder flag is what triggers the tool to compute the adjusted prices.placeholder (or placeholder: false) so the user sees Disney's standard pricing.explore_rates. Don't speculatively fetch.Claude's instinct is to be helpful by saying "while you answer, I'll start fetching" and immediately calling explore_rates. Don't. The placeholder flag is part of the tool input — calling without it means the prices are wrong, and you'll have to recall the tool (each call is 30–120s). That's a worse experience than waiting 5 seconds for the user's reply.
What IS safe to do in parallel with the placeholder question:
list_cruise_sailings (only if you don't already have the sailingId) — it doesn't take a placeholder param.get_my_profile — for notification setup later.What is NOT safe to do until the user answers:
explore_rates({ sailingId, ... }) — placeholder is part of the input.When you ask the question, say "I'll wait on that before pulling pricing — meanwhile I'm finding the sailing" (if running list_cruise_sailings in parallel) or just (if you already have the sailingId). Never say — that's the wrong call.
If the user wants a price-drop alert:
list_stateroom_categories first — alerts track one category.list_cruise_sailings({ months: ["2026-09"], adults: 2, children: 0, childAges: [] })
ships, nights, destinations, portslist_stateroom_categories({ sailingId, adults, children, childAges }) → show category pricing + room counts.category field (e.g. O9C) + often a human-friendly stateroomType (e.g. OUTSIDE-DELUXE).list_cruise_sailings.list_stateroom_categories → get category, stateroomType.create_alert({ alert: { kind: "cruise", sailingId, stateroomCategory: "O9C", stateroomType: "OUTSIDE-DELUXE", shipName: "Disney Wish", sailingName: "4-Night Bahamian Cruise", checkIn: "2026-09-07", checkOut: "2026-09-11", adults: 2, children: 0, childAges: [], alertType: "price_drop", currentPrice: 3200, notificationMethod: "email", clientNote: "" } })explore_rates({ mode, sailingId, checkIn, checkOut, adults, children, childAges }) — two modes:
availability — lightweight check: which categories are open and how many rooms left.package — full cruise pricing across categories. The cruise itself is the "package" at DCL; there are no separate tickets or dining plans.room-only is not meaningful for DCL; if the user asks for it, use availability instead.
WW0509 (Wish, sailing 0509). Don't invent them — always pull from list_cruise_sailings.roomCount is often 2–5 for Concierge categories. Sellout risk is real; an availability alert is valuable.list_cruise_sailings response when applicable. Surface them when present.list_stateroom_categories / explore_rates (cruise) outputRender the tool's content[0].text verbatim. Do NOT re-format it into a tighter summary table of your own. The tool already emits a hybrid layout per group: a compact summary table and a detailed block per category. Keep BOTH. Keep EVERY column. Keep EVERY row.
| separators, not a fenced code block). Columns: Cat, Name, Total, Tax, Deposit, Gratuities, Rooms. Markdown renderers display this as an actual bordered table — that's intentional; the user specifically wants a real table, not fenced plain text.### <Cat> — <Name>) followed by a fenced code block for each category with aligned key: value rows. Fields: Total, Fare, Tax, Gratuities, Out-the-door, Deposit, Final payment, Availability, Size, Sleeps, View, Decks, Location.DO NOT:
·-separated lines~ to any priceClaude has been caught (a) compressing the table to 4–5 columns, (b) flattening the detail blocks into single lines, and (c) converting the H3 heading to plain text prefixed with "Category:". Every previous attempt to fix via skill-only directives failed; the table + fenced-detail structure is now enforced in the format code. Pass it through exactly.
Do NOT write intro text like "Gratuities auto-apply at Disney's default rate: $80/guest standard, $136.25/guest concierge (sailing total, ~$16/night and ~$27.25/night)" before the table. The per-category Gratuities column and the detail block's Gratuities row already carry that information with the EXACT rate for the sailing. Inventing a summary preamble introduces:
If the user asks specifically for the gratuity rate, cite the value from the tool's structuredContent (gratuitiesRate or conciergeGratuitiesRate) — never a computed average.
~.gratuitiesRate and conciergeGratuitiesRate in the tool's structured content are Disney's actual per-sailing rates, not rounded averages~$X,XXX or approximately $X,XXX or about $X,XXX when rendering a number from the tool. They are exact figures for this sailing + party + category combinationfallback: not returned by Disney — never invent a tildeSpecial note on gratuities. DCL auto-applies gratuities to every booking at the rate returned by Disney's sailing-details API. Removing gratuities is an explicit opt-out the user has to make at checkout — it's not optional-by-default. So the tool emits a line labeled "Out-the-door (fare + tax + default gratuities): $X" — render it as-is. Do NOT:
Same rule for the "X rooms available · Y sq ft" line — no tildes on sq ft. Disney's stateroom-details API returns exact square footage.
Those numbers come from Disney's own payment-calculator API via the tool and are already in the text output (and in structuredContent.categories[].deposit / .price.tax / the gratuitiesRate field). Disney's deposit, gratuity, and final-payment formulas vary per sailing, per category, and per concierge tier — there is no single percentage you can apply. Pass through whatever the tool emitted. Full stop.
Each detailed block from the tool contains — and ALL of this must reach the user:
11C)If you absolutely must summarize (e.g. the user explicitly asks "just show me the cheapest per group"), confirm the trim with a sentence first — "I'll collapse the full category list into just the cheapest per group. Want the full list instead?" Default behavior is full rendering.
After list_cruise_sailings returns multiple sailings:
After list_stateroom_categories returns pricing for a sailing:
After explore_rates in availability mode for a cruise:
mode: "package" for the categories you care about."After a full cruise price quote:
After the user seems stuck between two ships:
When the party includes young kids (under 3):
After create_alert for a cruise:
When the user mentions they're flexible on dates:
The tool emits a callout line above the per-group blocks like:
📅 Final payment due Jan 5, 2027 for all priced categories on this sailing.
You MUST keep that callout in your response verbatim — it's the single most important piece of payment-timing info for the user. The same date also appears inside each detail block on the "Final payment" row. If you've been editing the detail block (which you shouldn't), at minimum keep the standalone 📅 callout.
Do not drop, edit, or paraphrase the 📅 line. Do not move it into a footer or trailing note. Do not summarize it as "due before sailing" — the user wants the exact date. This was being dropped as recently as v0.20; if you find yourself trimming the response, this line is the LAST thing to cut.
Disney's APIs do NOT return placeholder pricing. Disney has no idea which user holds a placeholder; they always return standard fare/tax/total. The placeholder math is computed by the tool inside format.ts using Disney's exact pricing as the input. The formula is:
netFare = total - tax
discount = netFare × 0.10
adjustedTotal = total - discount
adjustedFare = adjustedTotal - tax
standardDep = adjustedFare × 0.10
placeholderDep = max(0, standardDep - 250)
When you call explore_rates with placeholder: true, the tool's text output already contains the adjusted values. The summary table headers swap to Total (10% off) and Placeholder Deposit, and each detail block adds 10% off fare, Adjusted total, Adjusted fare, Standard deposit, and Placeholder deposit rows. Render those rows as-is.
These are wrong. Disney never returns placeholder pricing, by design. The math happens in the tool. If the placeholder rows aren't in your output, it's because you forgot to pass placeholder: true — re-call the tool with the flag set. Don't write an excuse.
Do NOT ask: ticket days, dining plan, Memory Maker, travel protection — DCL doesn't offer these as toggles. The cruise fare already includes onboard dining (rotational dining + Cabanas + QSRs). Gratuities are extra but not configurable.