@gojinko/plugin 0.5.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jinko",
3
3
  "description": "Search flights, book trips, and manage bookings with the Jinko Travel API. Connects to the Jinko MCP server for live flight pricing, trip management, and payment.",
4
- "version": "0.5.0",
4
+ "version": "1.1.0",
5
5
  "author": {
6
6
  "name": "Jinko",
7
7
  "url": "https://gojinko.com"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "jinko",
3
3
  "description": "Search flights, book trips, and manage bookings with the Jinko Travel API. Connects to the Jinko MCP server for live flight pricing, trip management, and payment.",
4
- "version": "0.5.0",
4
+ "version": "1.1.0",
5
5
  "author": {
6
6
  "name": "Jinko",
7
7
  "url": "https://gojinko.com"
@@ -31,7 +31,7 @@
31
31
  "defaultPrompt": [
32
32
  "Find the cheapest flights from Paris to New York next month",
33
33
  "Book a round-trip flight from London to Tokyo",
34
- "Check my API usage and remaining quota"
34
+ "Can I get a refund on booking ORD-123?"
35
35
  ],
36
36
  "brandColor": "#2563EB"
37
37
  }
package/README.md CHANGED
@@ -41,7 +41,7 @@ codex plugin install @gojinko/plugin
41
41
  | `jinko:search-flights` | Find flights, explore destinations, compare prices | "Find flights from Paris to Tokyo in June" |
42
42
  | `jinko:book-trip` | Book a flight with travelers and payment | "Book the cheapest flight and pay" |
43
43
  | `jinko:manage-booking` | Check refund eligibility and process refunds | "Can I get a refund on booking ORD-123?" |
44
- | `jinko:account` | Manage API keys and check usage | "How many API calls do I have left?" |
44
+ | `jinko:account` | Account setup guide — API keys, quotas, dashboard | "How do I set up my Jinko API key?" |
45
45
 
46
46
  ## Authentication
47
47
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gojinko/plugin",
3
- "version": "0.5.0",
3
+ "version": "1.1.0",
4
4
  "description": "Jinko Travel plugin for Claude Code and OpenAI Codex — flight search, booking, and trip management via MCP",
5
5
  "private": false,
6
6
  "license": "MIT",
@@ -1,73 +1,39 @@
1
1
  ---
2
2
  name: account
3
- description: Manage your Jinko developer account — register, create and revoke API keys, check usage quotas. Use when the user asks about their API key, usage limits, or account setup.
3
+ description: Set up and manage your Jinko developer account — registration, API keys, usage quotas. Use when the user asks about their API key, usage limits, or account setup.
4
4
  ---
5
5
 
6
6
  # Developer Account
7
7
 
8
- Manage your Jinko developer platform account using the `dev_account` MCP tool.
8
+ Manage your Jinko developer account via the [Jinko Builders Dashboard](https://builders.gojinko.com).
9
9
 
10
- ## Actions
10
+ Account management is handled through the web dashboard — there are no MCP tools for account operations. Guide the user to the dashboard for any account-related tasks.
11
11
 
12
- ### Register — create a new account
13
-
14
- ```json
15
- {
16
- "action": "register",
17
- "email": "dev@example.com",
18
- "name": "Jane Developer"
19
- }
20
- ```
21
-
22
- New accounts start in `pending` status until approved. `email` is required, `name` is optional.
23
-
24
- ### List API keys
25
-
26
- ```json
27
- {
28
- "action": "list_keys"
29
- }
30
- ```
31
-
32
- Returns all keys with `id`, `name`, `prefix`, `status`, `key_type`, and `rate_limit`. Full key values are never shown after creation.
33
-
34
- ### Create a new API key
35
-
36
- ```json
37
- {
38
- "action": "create_key",
39
- "key_name": "my-project-key"
40
- }
41
- ```
42
-
43
- **The full API key is only shown once in the response.** Tell the user to save it immediately — it cannot be retrieved later. Keys use the `jnk_` prefix.
44
-
45
- ### Revoke an API key
12
+ ## Getting started
46
13
 
47
- ```json
48
- {
49
- "action": "delete_key",
50
- "key_id": 42
51
- }
52
- ```
14
+ 1. **Register** — go to [builders.gojinko.com](https://builders.gojinko.com) and sign up with your email.
15
+ 2. **Create an API key** — in the dashboard, go to API Keys and create a new key. The full key (prefixed `jnk_`) is shown only once — save it immediately.
16
+ 3. **Set your key** — configure your environment:
17
+ - CLI: `jinko auth login` (OAuth) or set `JINKO_API_KEY=jnk_...`
18
+ - API client: pass the key when creating the client
19
+ - MCP: use `Authorization: Bearer jnk_...` header
53
20
 
54
- `key_id` is the numeric ID from `list_keys`. This is irreversible — confirm with the user before proceeding.
21
+ ## What you can do on the dashboard
55
22
 
56
- ### Check usage
23
+ - **View and create API keys** — each key has a `jnk_` prefix
24
+ - **Revoke API keys** — irreversible, confirm before proceeding
25
+ - **Check usage** — see requests used, remaining quota, and reset date
26
+ - **Manage your profile** — update name, email, organization
57
27
 
58
- ```json
59
- {
60
- "action": "usage"
61
- }
62
- ```
28
+ ## Rate limits
63
29
 
64
- Returns `used`, `limit`, `remaining`, and `resets_at` for the current billing period.
30
+ - Default: **1,000 requests / 30 days** per API key
31
+ - Usage resets on a rolling 30-day window
32
+ - If you need a higher limit, contact support via the dashboard
65
33
 
66
- ## Getting started
34
+ ## CLI authentication
67
35
 
68
- If the user doesn't have a Jinko account yet, guide them through:
36
+ The CLI supports two auth methods:
69
37
 
70
- 1. `register` with their email
71
- 2. Wait for account approval (or direct them to [builders.gojinko.com](https://builders.gojinko.com))
72
- 3. `create_key` to get an API key
73
- 4. Set `JINKO_API_KEY=jnk_...` in their environment
38
+ 1. **OAuth** (recommended): `jinko auth login` opens a browser for WorkOS login, stores token locally
39
+ 2. **API key**: set `JINKO_API_KEY=jnk_...` in your environment simpler for scripts and CI
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: book-trip
3
- description: Book a flight trip end-to-end — live pricing, traveler details, ancillaries, and payment via the Jinko Travel API. Use when the user wants to book, price-check, or pay for a flight.
3
+ description: Book a trip end-to-end — flights, hotels, or both in one cart. Live pricing, traveler details, ancillaries, and payment via the Jinko Travel API. Use when the user wants to book, price-check, or pay for travel.
4
4
  ---
5
5
 
6
6
  # Book a Trip
@@ -10,9 +10,11 @@ Complete booking flow using Jinko MCP tools. Each step depends on the previous
10
10
  ## Booking Flow
11
11
 
12
12
  ```
13
- flight_search → trip (add_item) → trip (upsert_travelers) → trip (select_ancillaries) → book (quote) → book (fulfillment) → book (confirm_payment)
13
+ flight_search and/or hotel_search → trip (add_item) → trip (upsert_travelers) → [trip (select_ancillaries)] → book
14
14
  ```
15
15
 
16
+ **Multi-domain carts:** Flights (`trip_item_token` from `flight_search`) and hotels (`htl_*` offer_id from `hotel_search`) can be added to the same trip. One cart, one Stripe checkout. See the `search-hotels` skill for hotel search details.
17
+
16
18
  ## Step 1: Get live pricing — `flight_search`
17
19
 
18
20
  Two modes (use exactly one):
@@ -32,7 +34,7 @@ Two modes (use exactly one):
32
34
  }
33
35
  ```
34
36
 
35
- **Price-check** (user has an `offer_token` from search-flights):
37
+ **Price-check** (user has an `offer_token` from find_flight):
36
38
  ```json
37
39
  {
38
40
  "price_check": {
@@ -61,6 +63,15 @@ Two modes (use exactly one):
61
63
 
62
64
  Returns `trip_id`. Save it for all subsequent steps.
63
65
 
66
+ **Swap an item:** combine `remove_item` + `add_item` in one call. Remove runs first, then add.
67
+ ```json
68
+ {
69
+ "trip_id": "<existing trip>",
70
+ "remove_item": { "item_id": "<from trip response items[].item_id>" },
71
+ "add_item": { "trip_item_token": "<new token>" }
72
+ }
73
+ ```
74
+
64
75
  ## Step 3: Set travelers — `trip` with `upsert_travelers`
65
76
 
66
77
  **Never fabricate traveler data. Always ask the user for real passenger details.**
@@ -117,54 +128,27 @@ Check the trip response from step 3 for `available_ancillaries` on each trip ite
117
128
 
118
129
  Categories: `BAGGAGE`, `SEAT`, `MEAL`, etc.
119
130
 
120
- ## Step 5: Quote — `book` with `quote`
121
-
122
- ```json
123
- {
124
- "quote": {
125
- "trip_id": "<trip_id>"
126
- }
127
- }
128
- ```
129
-
130
- Returns final pricing with all items and ancillaries. Trip must have items and travelers set.
131
-
132
- ## Step 6: Pay — `book` with `fulfillment`
131
+ ## Step 5: Book — `book`
133
132
 
134
133
  ```json
135
134
  {
136
- "fulfillment": {
137
- "trip_id": "<trip_id>"
138
- }
135
+ "trip_id": "<trip_id>"
139
136
  }
140
137
  ```
141
138
 
142
- Returns `checkout_url` and `session_id`. The user completes payment in their browser at the checkout URL.
139
+ Single synchronous call. The BFF schedules the quote, polls until it completes, schedules fulfillment, and returns a Stripe checkout URL. The user opens this URL in a browser to complete payment. Stripe webhooks finalize the booking automatically — no client-side confirm step is required.
143
140
 
144
- ## Step 7: Confirm `book` with `confirm_payment`
141
+ **Response includes:** `checkout_url`, `session_id`, `total_amount`, `items`.
145
142
 
146
- After the user completes payment:
143
+ ## Optional: Check trip status — `get_trip`
147
144
 
148
145
  ```json
149
146
  {
150
- "confirm_payment": {
151
- "trip_id": "<trip_id>",
152
- "checkout_session_id": "cs_xxx"
153
- }
154
- }
155
- ```
156
-
157
- Or with payment intent:
158
- ```json
159
- {
160
- "confirm_payment": {
161
- "trip_id": "<trip_id>",
162
- "payment_intent_id": "pi_xxx"
163
- }
147
+ "trip_id": "<trip_id>"
164
148
  }
165
149
  ```
166
150
 
167
- Returns booking confirmation with `booking_reference`.
151
+ Returns the full trip lifecycle state: cart contents, travelers, quote status, fulfillment status, booking references. Use after booking to verify confirmation or anytime to inspect the trip.
168
152
 
169
153
  ## Important rules
170
154
 
@@ -0,0 +1,135 @@
1
+ ---
2
+ name: jinko-cli
3
+ description: Use the `jinko` CLI (npm `@gojinko/cli`) to search flights and hotels, build trips, book, refund, and look up bookings from the terminal. Use when the user wants to run travel operations in a shell, script, CI, or agent loop — or explicitly asks for the "jinko CLI", "jinko command", or running something as a command-line.
4
+ ---
5
+
6
+ # Jinko CLI
7
+
8
+ Command-line tool for the Jinko Travel platform. Same capabilities as the MCP tools, exposed as a shell binary. Built on Commander.js, calls the BFF (`api.gojinko.com`) directly — not via the MCP server.
9
+
10
+ ## Install + auth
11
+
12
+ ```bash
13
+ npm install -g @gojinko/cli # one-time install
14
+ jinko auth login # OAuth device flow → browser login
15
+ jinko auth status # verify
16
+ ```
17
+
18
+ Auth alternatives:
19
+ - **API key** (for scripts / CI): `jinko --api-key jnk_xxx <command>` or `export JINKO_API_KEY=jnk_xxx`.
20
+ - **OAuth (human)**: `jinko auth login` opens a browser, stores token in `~/.jinko/config.yaml`. Auto-refresh is built in. `jinko auth logout` to clear.
21
+
22
+ ## Global flags
23
+
24
+ - `--format json` (default) or `--format table` — output shape
25
+ - `--api-key <jnk_...>` — override stored creds
26
+ - `-V` / `--version`
27
+
28
+ ## Command surface
29
+
30
+ | Command | Purpose |
31
+ |---|---|
32
+ | `auth login / logout / status` | Credentials |
33
+ | `find-destination` | Discover destinations from origin(s) — inspiration |
34
+ | `flight-calendar` | Cheapest prices across a date range for a specific route |
35
+ | `find-flight` | Cached-flight search by route + dates (returns `offer_token`) |
36
+ | `flight-search` | Live pricing — by route or `--offer-token` price-check |
37
+ | `hotel-search` | Live hotel search by city/query/geo/hotel-ids |
38
+ | `trip` | Create / update a trip: add items, remove items, set travelers + contact |
39
+ | `select-ancillaries` | Add baggage / seats / meals to a trip item |
40
+ | `book` | Schedule checkout → returns Stripe payment URL |
41
+ | `trip-status` | Full status: cart, quote, fulfillment, bookings |
42
+ | `lookup-booking` | Look up a booking by `JNK-*` ref + last name (guest access) |
43
+ | `refund check / commit / status` | Voluntary refund flow |
44
+ | `schema <command>` | Print request/response schema for a command |
45
+ | `config` | Read/write CLI config |
46
+
47
+ Run `jinko <command> --help` for flags on any command.
48
+
49
+ ## Canonical booking flow
50
+
51
+ ```bash
52
+ # 1. Find a flight (live pricing, gives trip_item_token)
53
+ jinko flight-search --from PAR --to NYC --date 2026-06-15 --return 2026-06-22 --passengers 2
54
+
55
+ # 2. Create a trip with that item
56
+ jinko trip --trip-item-token "offer_xxx:fare_yyy"
57
+ # → response includes trip_id (tr_...)
58
+
59
+ # 3. Add travelers + contact to the trip
60
+ jinko trip --trip-id tr_ABC \
61
+ --travelers '[{"type":"ADT","first_name":"John","last_name":"Doe","date_of_birth":"1990-01-15"}]' \
62
+ --contact '{"email":"john@example.com","phone":"+33612345678"}'
63
+
64
+ # 4. Schedule checkout — returns Stripe URL
65
+ jinko book --trip-id tr_ABC
66
+ # → { checkout_url: "https://checkout.stripe.com/..." }
67
+
68
+ # 5. User pays in browser (or open the URL programmatically)
69
+ # 6. Poll status
70
+ jinko trip-status --trip-id tr_ABC
71
+ ```
72
+
73
+ ## Hotel flow
74
+
75
+ ```bash
76
+ # Search by city + dates + occupancy
77
+ jinko hotel-search --city "Paris" --checkin 2026-07-15 --checkout 2026-07-18 --adults 2 --nationality FR
78
+
79
+ # Add to trip (hotel items use htl_ prefixed tokens)
80
+ jinko trip --trip-item-token "htl_xxx:rate_yyy"
81
+ # Mixed carts work: add both flight and hotel items to the same trip_id → single Stripe checkout
82
+ ```
83
+
84
+ ## Multi-item / mixed carts
85
+
86
+ `jinko trip --trip-id <existing>` reuses the existing cart. Flight + hotel in one cart ships as ONE Stripe checkout.
87
+
88
+ ```bash
89
+ # Start with a flight
90
+ jinko trip --trip-item-token "offer_abc:fare_1" # returns trip_id
91
+ # Add a hotel to the same trip
92
+ jinko trip --trip-id tr_ABC --trip-item-token "htl_xyz:rate_2"
93
+ ```
94
+
95
+ ## Remove / swap items
96
+
97
+ ```bash
98
+ # Remove
99
+ jinko trip --trip-id tr_ABC --remove-item-id it_123
100
+
101
+ # Swap in one call
102
+ jinko trip --trip-id tr_ABC --remove-item-id it_123 --trip-item-token "offer_new:fare_new"
103
+ ```
104
+
105
+ ## Post-booking
106
+
107
+ ```bash
108
+ # Lookup (guest access — no auth needed beyond ref + last name)
109
+ jinko lookup-booking --ref JNK-A7B3X9 --last-name Doe
110
+
111
+ # Refund
112
+ jinko refund check --ref JNK-A7B3X9 --last-name Doe
113
+ jinko refund commit --ref JNK-A7B3X9 --last-name Doe
114
+ jinko refund status --ref JNK-A7B3X9 --last-name Doe
115
+ ```
116
+
117
+ ## Output tips
118
+
119
+ - Default is JSON — pipe to `jq` for filtering: `jinko find-destination --from PAR | jq '.destinations[0]'`
120
+ - `--format table` gives a compact human view for browsing
121
+ - Every command has a `--help` flag and `jinko schema <command>` dumps the full request/response shape
122
+
123
+ ## Common pitfalls
124
+
125
+ - **Two auth systems.** CLI OAuth tokens (WorkOS device flow, stored in `~/.jinko/config.yaml`) are NOT interchangeable with MCP OAuth tokens (DCR, different issuer). Don't paste a CLI token into an MCP Bearer header — it will fail with issuer mismatch. Use an API key (`jnk_*`) for cross-surface programmatic access.
126
+ - **IATA codes**: `--from PAR` uses a CITY code (matches CDG + ORY + BVA); `--from CDG` uses an airport. `flight-search` has `--origin-type city|airport` to disambiguate.
127
+ - **trip_item_token format**: `offer_xxx:fare_yyy` (flight) or `htl_xxx:rate_yyy` (hotel). Always the offer ID + fare/rate ID joined by colon.
128
+ - **Token expiry**: offers cached ~30 min. If `book` returns a quote failure, re-run `flight-search`/`hotel-search` to get a fresh token.
129
+ - **Script use**: set `JINKO_API_KEY` env var and use `--format json` so output parses cleanly.
130
+
131
+ ## See also
132
+
133
+ - MCP-tool equivalents: sibling skills `search-flights`, `search-hotels`, `book-trip`, `manage-booking`
134
+ - API docs: `https://builders.gojinko.com/docs`
135
+ - Source: `packages/cli/src/commands/` in the `jinko-dev-tools` repo
@@ -1,55 +1,231 @@
1
1
  ---
2
2
  name: manage-booking
3
- description: Check refund eligibility and process refunds for booked flights via the Jinko Travel API. Use when the user asks about refunds, cancellations, or booking modifications.
3
+ description: Look up bookings and manage post-booking operations (refunds, cancellations) via the Jinko Travel API. Use when the user asks about booking status, refunds, cancellations, or booking modifications.
4
4
  ---
5
5
 
6
6
  # Manage Booking
7
7
 
8
- Post-booking operations using the Jinko `refund_flight` MCP tool.
8
+ Post-booking operations using Jinko MCP tools.
9
9
 
10
- ## Refund Flow
10
+ ## Booking Lookup
11
11
 
12
- Always check eligibility first, then confirm with the user before committing.
12
+ Use `lookup_booking` to find a booking by its Jinko reference and the traveler's last name. No login required.
13
13
 
14
- ### Step 1: Check eligibility — `refund_flight` with `action: "check"`
14
+ ```json
15
+ {
16
+ "booking_ref": "JNK-A7B3X9",
17
+ "last_name": "Doe"
18
+ }
19
+ ```
20
+
21
+ **Response includes:**
22
+ - `booking_reference`: the Jinko booking reference
23
+ - `status`: current booking status (completed, processing, etc.)
24
+ - `customer_contact`: contact info on the booking
25
+ - `travelers`: list of travelers
26
+ - `items`: booked items with domain (flight/hotel), status, and confirmation details (PNR, confirmation number)
27
+
28
+ ## Auth model
29
+
30
+ `flight_refund` supports two auth modes — pick exactly one per call:
31
+
32
+ - **Guest auth** (default for end-users): `booking_ref` + `last_name`. Works without any DevPlatform credential — the server resolves the booking via `/bookings/lookup`.
33
+ - **Authenticated** (DevPlatform OAuth / `jnk_*` API keys): `order_id`. Skips the guest resolver.
34
+
35
+ Do NOT mix the two modes in one call. The BFF rejects mixed combinations up front.
36
+
37
+ ## Refund Flow — 3 actions: `check | commit | status`
38
+
39
+ Always check eligibility first, then confirm with the user before committing. Use `status` afterwards to poll async refunds.
40
+
41
+ ### Step 1: Check eligibility — `flight_refund` with `action: "check"`
15
42
 
16
43
  ```json
17
44
  {
18
45
  "action": "check",
19
- "booking_reference": "ORD-123456",
20
- "pnr": "ABC123"
46
+ "booking_ref": "JNK-ZNBGTP",
47
+ "last_name": "Doe"
21
48
  }
22
49
  ```
23
50
 
24
51
  **Response includes:**
52
+
25
53
  - `is_refundable`: whether a refund is possible
26
- - `refund_amount`: estimated refund value and currency
54
+ - `is_automatable`: whether the refund can be processed automatically (vs. manual CS)
55
+ - `support_level`: `"automatic"` | `"manual"` | `"unsupported"`
56
+ - `manual_reason`: explanation if not automatable
57
+ - `refund_amount`: estimated refund `{ value, currency, decimal_places }`
27
58
  - `penalty_amount`: cancellation fee if applicable
28
59
  - `total_paid`: original payment amount
29
- - `processing_type`: how the refund will be processed
60
+ - `expires_at`: eligibility quote expiry
61
+ - `warnings`: any caveats to surface to the user
62
+
63
+ **Present the refund details clearly** — show what they paid, what they'd get back, penalty, and any warnings. Ask for explicit confirmation before proceeding.
64
+
65
+ ### Step 2: Process refund — `flight_refund` with `action: "commit"`
66
+
67
+ Only after the user confirms:
68
+
69
+ ```json
70
+ {
71
+ "action": "commit",
72
+ "booking_ref": "JNK-ZNBGTP",
73
+ "last_name": "Doe"
74
+ }
75
+ ```
76
+
77
+ **Response includes:**
78
+
79
+ - `refund_status`: `"refunded"` | `"processing"` | `"failed"` | ...
80
+ - `confirmed_refund_amount`: actual refunded `{ value, currency, decimal_places }` (when available)
81
+ - `refund_reference`: opaque reference string — persist this to poll with `status`
82
+ - `warnings`: any post-commit caveats
83
+
84
+ If `refund_status` is not a terminal state, follow up with `status`.
85
+
86
+ ### Step 3: Poll refund — `flight_refund` with `action: "status"`
87
+
88
+ ```json
89
+ {
90
+ "action": "status",
91
+ "booking_ref": "JNK-ZNBGTP",
92
+ "last_name": "Doe",
93
+ "refund_reference": "<from commit response>"
94
+ }
95
+ ```
96
+
97
+ **Response includes:**
98
+
99
+ - `refund_status`: current lifecycle state
100
+ - `provider_status`: underlying connector status (if different)
101
+ - `refund_amount`: refunded amount (may update over time)
102
+ - `refund_reference`: echoed
103
+ - `warnings`
30
104
 
31
- **Present the refund details clearly to the user** — show what they paid, what they'd get back, and any penalty. Ask for explicit confirmation before proceeding.
105
+ ## Schema
32
106
 
33
- ### Step 2: Process refund `refund_flight` with `action: "commit"`
107
+ | Field | Type | Purpose |
108
+ |---|---|---|
109
+ | `action` | `"check"` \| `"commit"` \| `"status"` | Required. Which step of the flow. |
110
+ | `booking_ref` | string | Guest auth. Jinko booking reference (e.g. `JNK-ZNBGTP`). |
111
+ | `last_name` | string | Guest auth. Last name of the primary traveler. |
112
+ | `order_id` | string | Authenticated auth. DevPlatform order ID. |
113
+ | `ticket_numbers` | string[] | Optional. Scope refund to specific tickets. |
114
+ | `provider` | string | Optional. Override provider hint. |
115
+ | `refund_reference` | string | For `status` only. Returned by `commit`. |
116
+
117
+ ## Exchange Flow — 4 actions: `shop | price | commit | status`
118
+
119
+ Use `flight_exchange` to change flights on an existing booking. Always shop first, then price a specific offer, confirm with the user, commit, and poll status if needed.
120
+
121
+ ### Step 1: Shop for alternatives — `flight_exchange` with `action: "shop"`
122
+
123
+ ```json
124
+ {
125
+ "action": "shop",
126
+ "booking_ref": "JNK-ZNBGTP",
127
+ "last_name": "Doe",
128
+ "preferred_departure_date": "2026-06-15"
129
+ }
130
+ ```
131
+
132
+ **Response includes:**
133
+
134
+ - `support_level`: `"automatic"` | `"manual"` | `"unsupported"`
135
+ - `offers`: array of `{ offer_id, description, metadata }` — alternative flights
136
+ - `warnings`: any caveats to surface to the user
137
+
138
+ **Present available alternatives clearly** — show offer descriptions and let the user pick one.
139
+
140
+ ### Step 2: Price selected offer — `flight_exchange` with `action: "price"`
141
+
142
+ ```json
143
+ {
144
+ "action": "price",
145
+ "booking_ref": "JNK-ZNBGTP",
146
+ "last_name": "Doe",
147
+ "offer_id": "<from shop response>"
148
+ }
149
+ ```
150
+
151
+ **Response includes:**
152
+
153
+ - `payment_outcome`: `"additional_collection"` | `"even_exchange"` | `"refund"`
154
+ - `fare_difference`: price difference `{ value, currency, decimal_places }`
155
+ - `penalty_amount`: change fee if applicable
156
+ - `total_due`: amount the customer must pay (if additional collection)
157
+ - `total_refund`: amount refunded to customer (if fare decreased)
158
+ - `session_reference`: opaque reference — required for `commit`
159
+ - `expires_at`: pricing quote expiry
160
+ - `warnings`
161
+
162
+ **Present the pricing clearly** — show fare difference, penalties, total due/refund, and payment outcome. Ask for explicit confirmation before proceeding.
163
+
164
+ ### Step 3: Execute exchange — `flight_exchange` with `action: "commit"`
34
165
 
35
166
  Only after the user confirms:
36
167
 
37
168
  ```json
38
169
  {
39
170
  "action": "commit",
40
- "booking_reference": "ORD-123456",
41
- "pnr": "ABC123",
42
- "reason": "schedule change"
171
+ "booking_ref": "JNK-ZNBGTP",
172
+ "last_name": "Doe",
173
+ "offer_id": "<from shop response>",
174
+ "session_reference": "<from price response>"
175
+ }
176
+ ```
177
+
178
+ **Response includes:**
179
+
180
+ - `status`: `"CONFIRMED"` | `"PENDING"` | `"PARTIAL_FAILURE"`
181
+ - `exchange_reference`: opaque reference for status polling
182
+ - `new_order_id`: new order ID if exchange created a new booking
183
+ - `new_ticket_numbers`: new ticket numbers issued
184
+ - `original_ticket_status`: status of the original tickets
185
+ - `payment_outcome`: final payment action taken
186
+ - `warnings`
187
+
188
+ If `status` is not `CONFIRMED`, follow up with `status`.
189
+
190
+ ### Step 4: Poll exchange — `flight_exchange` with `action: "status"`
191
+
192
+ ```json
193
+ {
194
+ "action": "status",
195
+ "booking_ref": "JNK-ZNBGTP",
196
+ "last_name": "Doe"
43
197
  }
44
198
  ```
45
199
 
46
- **Params:**
47
- - `booking_reference`: the order ID (required)
48
- - `pnr`: Passenger Name Record (optional but recommended)
49
- - `reason`: why the user wants a refund (only for commit)
200
+ **Response includes:**
201
+
202
+ - `status`: current lifecycle state (`CONFIRMED` | `PENDING` | `PARTIAL_FAILURE` | `FAILED`)
203
+ - `new_ticket_numbers`: new tickets (when confirmed)
204
+ - `confirmed_payment_outcome`: final payment resolution
205
+ - `warnings`
206
+
207
+ ## Exchange Schema
208
+
209
+ | Field | Type | Purpose |
210
+ |---|---|---|
211
+ | `action` | `"shop"` \| `"price"` \| `"commit"` \| `"status"` | Required. Which step of the flow. |
212
+ | `booking_ref` | string | Guest auth. Jinko booking reference (e.g. `JNK-ZNBGTP`). |
213
+ | `last_name` | string | Guest auth. Last name of the primary traveler. |
214
+ | `order_id` | string | Authenticated auth. DevPlatform order ID. |
215
+ | `ticket_numbers` | string[] | Optional. Scope exchange to specific tickets. |
216
+ | `provider` | string | Optional. Override provider hint. |
217
+ | `offer_id` | string | For `price` and `commit`. Exchange offer from `shop`. |
218
+ | `session_reference` | string | For `commit` only. Returned by `price`. |
219
+ | `preferred_departure_date` | string | For `shop` only. Preferred new departure date. |
50
220
 
51
221
  ## Important rules
52
222
 
53
- - **Always check before committing** — never skip the eligibility check
54
- - **Get user confirmation** — show refund amount and penalty before processing
55
- - **Non-refundable bookings** — if `is_refundable` is false, inform the user and do not attempt commit
223
+ - **Always shop before pricing** — never skip the alternatives search.
224
+ - **Always price before committing** — never skip the pricing step.
225
+ - **Get user confirmation** — show fare difference, penalties, and payment outcome before committing.
226
+ - **Pick one auth mode** — never send both `order_id` and `booking_ref` in the same call.
227
+ - **Poll with `status`** when `commit` returns a non-terminal status.
228
+ - **Always check before committing refunds** — never skip the eligibility check.
229
+ - **Get user confirmation for refunds** — show refund amount and penalty before processing.
230
+ - **Non-refundable bookings** — if `is_refundable` is false, inform the user and do not attempt commit.
231
+ - **Poll refund with `status`** when `commit` returns a non-terminal `refund_status`.
@@ -0,0 +1,94 @@
1
+ ---
2
+ name: search-hotels
3
+ description: Search live hotel inventory and rates by destination, dates, and occupancy using the Jinko Travel API. Use when the user wants to find hotels, compare rates, or book a hotel.
4
+ ---
5
+
6
+ # Hotel Search
7
+
8
+ Search live hotel inventory using the `hotel_search` Jinko MCP tool. Returns hotels with rooms, rates, and `htl_*` offer tokens for booking.
9
+
10
+ ## hotel_search
11
+
12
+ Live search — returns real-time availability and pricing from hotel suppliers.
13
+
14
+ **Required params:**
15
+
16
+ - **Destination** (provide exactly one):
17
+ - `query`: free-text (e.g. `"Paris"`, `"beach resort near Barcelona"`)
18
+ - `city_name` + optional `country_code`: structured (e.g. `"New York"` + `"us"`)
19
+ - `latitude` + `longitude` + optional `radius_km`: geo-radius (max 50km)
20
+ - `place_id`: Google Places ID
21
+ - `hotel_ids`: re-shop specific hotels by ID
22
+
23
+ - `checkin`: check-in date (YYYY-MM-DD)
24
+ - `checkout`: check-out date (YYYY-MM-DD)
25
+
26
+ - **Occupancy** (provide one shape):
27
+ - Shorthand: `adults` (+ optional `children` ages array + `rooms`)
28
+ - Structured: `occupancies: [{ adults, children_ages? }, ...]` (one per room)
29
+
30
+ **Optional params:**
31
+ - `currency`: ISO 4217 (default USD)
32
+ - `guest_nationality`: ISO 3166-1 alpha-2 (affects rate availability)
33
+ - `filters`: `{ min_rating, star_rating, min_reviews, hotel_type_ids, chain_ids, facility_ids, max_results }`
34
+
35
+ **Examples:**
36
+
37
+ Simple city search:
38
+ ```json
39
+ {
40
+ "destination": { "query": "Paris" },
41
+ "checkin": "2026-07-15",
42
+ "checkout": "2026-07-18",
43
+ "adults": 2
44
+ }
45
+ ```
46
+
47
+ Two rooms with kids:
48
+ ```json
49
+ {
50
+ "destination": { "city_name": "Barcelona", "country_code": "es" },
51
+ "checkin": "2026-08-01",
52
+ "checkout": "2026-08-05",
53
+ "occupancies": [
54
+ { "adults": 2 },
55
+ { "adults": 1, "children_ages": [5, 7] }
56
+ ]
57
+ }
58
+ ```
59
+
60
+ 4+ star hotels with pool near a POI:
61
+ ```json
62
+ {
63
+ "destination": { "latitude": 41.4036, "longitude": 2.1744, "radius_km": 3 },
64
+ "checkin": "2026-09-10",
65
+ "checkout": "2026-09-12",
66
+ "adults": 2,
67
+ "filters": { "star_rating": 4, "facility_ids": ["7"] }
68
+ }
69
+ ```
70
+
71
+ **Response:** List of hotels with `hotel_id`, `name`, `address`, `star_rating`, `rating`, `review_count`, `main_photo`, and a `rooms[]` list. Each room has `rates[]` — each rate includes:
72
+ - `offer_id`: the `htl_*` token (use as `trip_item_token` for booking)
73
+ - `board_type` / `board_name`: meal plan (RO = Room Only, BB = Bed & Breakfast, etc.)
74
+ - `total_amount` + `currency`: total price for the stay
75
+ - `is_refundable` + `free_cancellation_until`
76
+
77
+ ## Booking flow
78
+
79
+ Hotels use the same cart as flights — multi-domain trips supported:
80
+
81
+ ```
82
+ hotel_search → trip(add_item, trip_item_token=<htl_* offer_id>) → trip(upsert_travelers) → book
83
+ ```
84
+
85
+ The `htl_*` offer_id from any rate works directly as the `trip_item_token`. Hotels and flights can coexist in the same cart for a single Stripe checkout.
86
+
87
+ See the `book-trip` skill for the full booking flow (steps 2-5 are identical for hotels and flights).
88
+
89
+ ## Important notes
90
+
91
+ - **Dates**: YYYY-MM-DD, check-in must be today or later, check-out must be after check-in
92
+ - **Occupancy**: use structured `occupancies[]` when room composition matters (families, groups); use shorthand `adults` for simple searches
93
+ - **Rates expire**: offer tokens have a cache TTL (~30 min). If `trip(add_item)` fails, re-search
94
+ - **No widget in v1**: responses are text/JSON only. Hotel widgets arrive in v1.5