@striderlabs/mcp-booking 0.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.
package/README.md ADDED
@@ -0,0 +1,127 @@
1
+ # @striderlabs/mcp-booking
2
+
3
+ MCP server for Booking.com — search hotels, check availability, manage reservations, and more via AI agents.
4
+
5
+ By [Strider Labs](https://striderlabs.ai)
6
+
7
+ ---
8
+
9
+ ## Overview
10
+
11
+ This MCP (Model Context Protocol) server gives AI agents the ability to interact with Booking.com using browser automation (Playwright). It supports 14 tools covering the full hotel booking workflow.
12
+
13
+ ## Tools
14
+
15
+ | Tool | Description |
16
+ |------|-------------|
17
+ | `booking_status` | Check login/session status |
18
+ | `booking_login` | Initiate login flow (returns URL for manual login) |
19
+ | `booking_logout` | Clear saved session and cookies |
20
+ | `booking_search` | Search hotels by destination, dates, guests, rooms |
21
+ | `booking_get_property` | Get property details (amenities, description, policies) |
22
+ | `booking_check_availability` | Check room availability for specific dates |
23
+ | `booking_get_prices` | Get pricing for a property |
24
+ | `booking_filter_results` | Filter last search by price, rating, amenities |
25
+ | `booking_sort_results` | Sort last search by price/rating/distance/reviews |
26
+ | `booking_save_property` | Save to wishlist/favorites |
27
+ | `booking_book` | Book a room (requires `confirm=true`) |
28
+ | `booking_get_reservations` | List current/upcoming reservations |
29
+ | `booking_cancel_reservation` | Cancel a booking (requires `confirm=true`) |
30
+ | `booking_get_reviews` | Get guest reviews for a property |
31
+
32
+ ## Requirements
33
+
34
+ - Node.js 18+
35
+ - A Booking.com account (for bookings, reservations, and wishlist)
36
+
37
+ ## Installation
38
+
39
+ ```bash
40
+ npm install @striderlabs/mcp-booking
41
+ ```
42
+
43
+ Or install Playwright browsers after install:
44
+
45
+ ```bash
46
+ npx playwright install chromium
47
+ ```
48
+
49
+ ## Configuration
50
+
51
+ Add to your MCP config (e.g. `~/.claude/mcp_servers.json`):
52
+
53
+ ```json
54
+ {
55
+ "mcpServers": {
56
+ "booking": {
57
+ "command": "npx",
58
+ "args": ["-y", "@striderlabs/mcp-booking"]
59
+ }
60
+ }
61
+ }
62
+ ```
63
+
64
+ ## Authentication
65
+
66
+ The server uses cookie-based session persistence. Cookies are stored at `~/.strider/booking/`.
67
+
68
+ 1. Run `booking_login` to get the login URL
69
+ 2. Open the URL in your browser and sign in
70
+ 3. Run `booking_status` to verify the session is active
71
+
72
+ ## Usage Examples
73
+
74
+ ### Search hotels
75
+
76
+ ```
77
+ booking_search(destination="Paris", checkIn="2026-06-01", checkOut="2026-06-05", adults=2, rooms=1)
78
+ ```
79
+
80
+ ### Filter and sort results
81
+
82
+ ```
83
+ booking_filter_results(maxPrice=200, minRating=8.0, freeCancellation=true)
84
+ booking_sort_results(sortBy="rating")
85
+ ```
86
+
87
+ ### Check availability and prices
88
+
89
+ ```
90
+ booking_check_availability(propertyUrl="https://www.booking.com/hotel/fr/...", checkIn="2026-06-01", checkOut="2026-06-05")
91
+ booking_get_prices(propertyUrl="...", checkIn="2026-06-01", checkOut="2026-06-05")
92
+ ```
93
+
94
+ ### Book a room
95
+
96
+ ```
97
+ # Preview first (no confirm flag)
98
+ booking_book(propertyUrl="...", checkIn="2026-06-01", checkOut="2026-06-05", adults=2)
99
+
100
+ # Confirm booking (only after explicit user approval)
101
+ booking_book(propertyUrl="...", checkIn="2026-06-01", checkOut="2026-06-05", adults=2, confirm=true)
102
+ ```
103
+
104
+ ### Manage reservations
105
+
106
+ ```
107
+ booking_get_reservations()
108
+ booking_cancel_reservation(reservationId="12345678", confirm=true)
109
+ ```
110
+
111
+ ## Safety
112
+
113
+ - `booking_book` requires `confirm=true` and should only be called with explicit user confirmation
114
+ - `booking_cancel_reservation` requires `confirm=true` and is irreversible
115
+ - Both tools return a preview/warning when called without the confirm flag
116
+
117
+ ## Development
118
+
119
+ ```bash
120
+ npm install
121
+ npm run build
122
+ npm start
123
+ ```
124
+
125
+ ## License
126
+
127
+ MIT — Strider Labs
package/dist/auth.d.ts ADDED
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Strider Labs - Booking.com Auth/Session Management
3
+ *
4
+ * Handles cookie persistence and session management for Booking.com.
5
+ */
6
+ import type { BrowserContext } from "playwright";
7
+ export interface SessionInfo {
8
+ isLoggedIn: boolean;
9
+ userEmail?: string;
10
+ userName?: string;
11
+ lastUpdated: string;
12
+ currency?: string;
13
+ }
14
+ /**
15
+ * Save cookies from browser context to disk
16
+ */
17
+ export declare function saveCookies(context: BrowserContext): Promise<void>;
18
+ /**
19
+ * Load cookies from disk and apply to browser context
20
+ */
21
+ export declare function loadCookies(context: BrowserContext): Promise<boolean>;
22
+ /**
23
+ * Save session info to disk
24
+ */
25
+ export declare function saveSessionInfo(info: SessionInfo): void;
26
+ /**
27
+ * Load session info from disk
28
+ */
29
+ export declare function loadSessionInfo(): SessionInfo | null;
30
+ /**
31
+ * Clear all saved auth data
32
+ */
33
+ export declare function clearAuthData(): void;
34
+ /**
35
+ * Check if we have saved cookies (may or may not still be valid)
36
+ */
37
+ export declare function hasSavedCookies(): boolean;
38
+ /**
39
+ * Get the config directory path (useful for debugging)
40
+ */
41
+ export declare function getConfigDir(): string;
package/dist/auth.js ADDED
@@ -0,0 +1,96 @@
1
+ /**
2
+ * Strider Labs - Booking.com Auth/Session Management
3
+ *
4
+ * Handles cookie persistence and session management for Booking.com.
5
+ */
6
+ import * as fs from "fs";
7
+ import * as path from "path";
8
+ import * as os from "os";
9
+ const CONFIG_DIR = path.join(os.homedir(), ".strider", "booking");
10
+ const COOKIES_FILE = path.join(CONFIG_DIR, "cookies.json");
11
+ const SESSION_FILE = path.join(CONFIG_DIR, "session.json");
12
+ /**
13
+ * Ensure config directory exists
14
+ */
15
+ function ensureConfigDir() {
16
+ if (!fs.existsSync(CONFIG_DIR)) {
17
+ fs.mkdirSync(CONFIG_DIR, { recursive: true });
18
+ }
19
+ }
20
+ /**
21
+ * Save cookies from browser context to disk
22
+ */
23
+ export async function saveCookies(context) {
24
+ ensureConfigDir();
25
+ const cookies = await context.cookies();
26
+ fs.writeFileSync(COOKIES_FILE, JSON.stringify(cookies, null, 2));
27
+ }
28
+ /**
29
+ * Load cookies from disk and apply to browser context
30
+ */
31
+ export async function loadCookies(context) {
32
+ if (!fs.existsSync(COOKIES_FILE)) {
33
+ return false;
34
+ }
35
+ try {
36
+ const cookiesJson = fs.readFileSync(COOKIES_FILE, "utf-8");
37
+ const cookies = JSON.parse(cookiesJson);
38
+ // Filter out expired cookies
39
+ const now = Date.now() / 1000;
40
+ const validCookies = cookies.filter((c) => !c.expires || c.expires > now);
41
+ if (validCookies.length > 0) {
42
+ await context.addCookies(validCookies);
43
+ return true;
44
+ }
45
+ }
46
+ catch (error) {
47
+ console.error("Failed to load cookies:", error);
48
+ }
49
+ return false;
50
+ }
51
+ /**
52
+ * Save session info to disk
53
+ */
54
+ export function saveSessionInfo(info) {
55
+ ensureConfigDir();
56
+ fs.writeFileSync(SESSION_FILE, JSON.stringify(info, null, 2));
57
+ }
58
+ /**
59
+ * Load session info from disk
60
+ */
61
+ export function loadSessionInfo() {
62
+ if (!fs.existsSync(SESSION_FILE)) {
63
+ return null;
64
+ }
65
+ try {
66
+ const sessionJson = fs.readFileSync(SESSION_FILE, "utf-8");
67
+ return JSON.parse(sessionJson);
68
+ }
69
+ catch (error) {
70
+ console.error("Failed to load session info:", error);
71
+ return null;
72
+ }
73
+ }
74
+ /**
75
+ * Clear all saved auth data
76
+ */
77
+ export function clearAuthData() {
78
+ if (fs.existsSync(COOKIES_FILE)) {
79
+ fs.unlinkSync(COOKIES_FILE);
80
+ }
81
+ if (fs.existsSync(SESSION_FILE)) {
82
+ fs.unlinkSync(SESSION_FILE);
83
+ }
84
+ }
85
+ /**
86
+ * Check if we have saved cookies (may or may not still be valid)
87
+ */
88
+ export function hasSavedCookies() {
89
+ return fs.existsSync(COOKIES_FILE);
90
+ }
91
+ /**
92
+ * Get the config directory path (useful for debugging)
93
+ */
94
+ export function getConfigDir() {
95
+ return CONFIG_DIR;
96
+ }
@@ -0,0 +1,145 @@
1
+ /**
2
+ * Strider Labs - Booking.com Browser Automation
3
+ *
4
+ * Playwright-based browser automation for Booking.com operations.
5
+ */
6
+ import { type SessionInfo } from "./auth.js";
7
+ export interface PropertyResult {
8
+ propertyId: string;
9
+ name: string;
10
+ location: string;
11
+ rating?: number;
12
+ reviewScore?: number;
13
+ reviewCount?: number;
14
+ pricePerNight?: string;
15
+ totalPrice?: string;
16
+ currency?: string;
17
+ imageUrl?: string;
18
+ url?: string;
19
+ distanceFromCenter?: string;
20
+ stars?: number;
21
+ freeCancellation?: boolean;
22
+ breakfastIncluded?: boolean;
23
+ }
24
+ export interface RoomOption {
25
+ roomId?: string;
26
+ name: string;
27
+ maxGuests?: number;
28
+ bedType?: string;
29
+ price?: string;
30
+ totalPrice?: string;
31
+ freeCancellation?: boolean;
32
+ breakfastIncluded?: boolean;
33
+ available: boolean;
34
+ }
35
+ export interface Reservation {
36
+ reservationId: string;
37
+ propertyName: string;
38
+ checkIn: string;
39
+ checkOut: string;
40
+ guests?: number;
41
+ totalPrice?: string;
42
+ status: string;
43
+ confirmationNumber?: string;
44
+ }
45
+ export interface Review {
46
+ reviewer?: string;
47
+ date?: string;
48
+ score?: number;
49
+ title?: string;
50
+ positives?: string;
51
+ negatives?: string;
52
+ country?: string;
53
+ }
54
+ /**
55
+ * Close browser and save state
56
+ */
57
+ export declare function closeBrowser(): Promise<void>;
58
+ /**
59
+ * Check Booking.com login status
60
+ */
61
+ export declare function checkLoginStatus(): Promise<SessionInfo>;
62
+ /**
63
+ * Initiate login flow
64
+ */
65
+ export declare function initiateLogin(): Promise<{
66
+ loginUrl: string;
67
+ instructions: string;
68
+ }>;
69
+ /**
70
+ * Search hotels on Booking.com
71
+ */
72
+ export declare function searchProperties(destination: string, checkIn: string, checkOut: string, adults?: number, rooms?: number, children?: number, maxResults?: number): Promise<PropertyResult[]>;
73
+ /**
74
+ * Get property details by URL or property ID
75
+ */
76
+ export declare function getPropertyDetails(propertyUrlOrId: string): Promise<Record<string, unknown>>;
77
+ /**
78
+ * Check room availability for a property
79
+ */
80
+ export declare function checkAvailability(propertyUrlOrId: string, checkIn: string, checkOut: string, adults?: number, rooms?: number): Promise<{
81
+ available: boolean;
82
+ rooms: RoomOption[];
83
+ message: string;
84
+ }>;
85
+ /**
86
+ * Get prices for a property
87
+ */
88
+ export declare function getPrices(propertyUrlOrId: string, checkIn: string, checkOut: string, adults?: number, rooms?: number): Promise<{
89
+ prices: RoomOption[];
90
+ currency: string;
91
+ lowestPrice?: string;
92
+ }>;
93
+ /**
94
+ * Filter cached search results
95
+ */
96
+ export declare function filterResults(filters: {
97
+ minPrice?: number;
98
+ maxPrice?: number;
99
+ minRating?: number;
100
+ freeCancellation?: boolean;
101
+ breakfastIncluded?: boolean;
102
+ stars?: number;
103
+ keyword?: string;
104
+ }): PropertyResult[];
105
+ /**
106
+ * Sort cached search results
107
+ */
108
+ export declare function sortResults(sortBy: "price_asc" | "price_desc" | "rating" | "distance" | "reviews"): PropertyResult[];
109
+ /**
110
+ * Save a property to favorites (wishlist)
111
+ */
112
+ export declare function saveProperty(propertyUrlOrId: string): Promise<{
113
+ success: boolean;
114
+ message: string;
115
+ }>;
116
+ /**
117
+ * Book a room (with explicit confirmation required)
118
+ */
119
+ export declare function bookRoom(propertyUrlOrId: string, checkIn: string, checkOut: string, adults?: number, rooms?: number, confirmBooking?: boolean): Promise<{
120
+ requiresConfirmation: true;
121
+ summary: Record<string, unknown>;
122
+ } | {
123
+ success: boolean;
124
+ bookingId?: string;
125
+ message: string;
126
+ }>;
127
+ /**
128
+ * Get current reservations
129
+ */
130
+ export declare function getReservations(): Promise<Reservation[]>;
131
+ /**
132
+ * Cancel a reservation
133
+ */
134
+ export declare function cancelReservation(reservationId: string, confirmCancellation?: boolean): Promise<{
135
+ success: boolean;
136
+ message: string;
137
+ }>;
138
+ /**
139
+ * Get reviews for a property
140
+ */
141
+ export declare function getPropertyReviews(propertyUrlOrId: string, maxReviews?: number): Promise<{
142
+ reviews: Review[];
143
+ averageScore?: number;
144
+ totalReviews?: number;
145
+ }>;