@burdenoff/mcp-libs 2026.626.1 → 2026.627.1

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.
@@ -0,0 +1,1007 @@
1
+ import { mcpToolName, errorResult, jsonResult, mcpResourceUri, mcpPromptName } from '../../chunk-H2OYWLOA.js';
2
+ import { z } from 'zod';
3
+
4
+ // src/modules/ggnomad/operations.ts
5
+ var PROVIDER_FIELDS = `
6
+ id name type description contactEmail contactPhone website status
7
+ rating reviewCount listingCount totalRevenue workspaceId createdAt updatedAt
8
+ `;
9
+ var PROPERTY_FIELDS = `
10
+ id name type description address amenities bedrooms bathrooms maxGuests
11
+ pricePerNight currency checkInTime checkOutTime images rating reviewCount
12
+ status providerId workspaceId createdAt updatedAt
13
+ provider { id name type status }
14
+ `;
15
+ var ACTIVITY_FIELDS = `
16
+ id name category description duration difficulty price currency location
17
+ images includes requirements maxParticipants rating reviewCount safetyInfo
18
+ status providerId workspaceId createdAt updatedAt
19
+ provider { id name type status }
20
+ `;
21
+ var EVENT_FIELDS = `
22
+ id name category description venue startsAt endsAt price currency images
23
+ performers rating reviewCount status providerId workspaceId createdAt updatedAt
24
+ provider { id name type status }
25
+ `;
26
+ var TOUR_FIELDS = `
27
+ id name type description duration difficulty price currency location
28
+ highlights languages images maxGroupSize guideName rating reviewCount
29
+ status providerId workspaceId createdAt updatedAt
30
+ provider { id name type status }
31
+ `;
32
+ var TRIP_FIELDS = `
33
+ id name transportMode origin destination departureAt arrivalAt isRoundTrip
34
+ returnDepartureAt returnArrivalAt passengers class carrier price currency
35
+ ecoFriendly status workspaceId createdAt updatedAt
36
+ `;
37
+ var BOOKING_FIELDS = `
38
+ id bookingType referenceCode itemId itemName guestName guestEmail guestPhone
39
+ guests checkIn checkOut eventDate totalPrice currency paymentMethod
40
+ paymentStatus status specialRequests workspaceId createdAt updatedAt
41
+ `;
42
+ var ANALYTICS_FIELDS = `
43
+ conversionRate monthlyTrends revenueByCategory topDestinations
44
+ totalBookings totalRevenue totalUsers
45
+ `;
46
+ var OVERVIEW_FIELDS = `
47
+ bookings listings monthlyRevenue users
48
+ `;
49
+ var GET_PROVIDER = `
50
+ query GgnomadGetProvider($id: ID!) {
51
+ ggnomadProvider(id: $id) {
52
+ ${PROVIDER_FIELDS}
53
+ }
54
+ }
55
+ `;
56
+ var LIST_PROVIDERS = `
57
+ query GgnomadListProviders($pagination: GgnomadPaginationInput) {
58
+ ggnomadProviders(pagination: $pagination) {
59
+ ${PROVIDER_FIELDS}
60
+ }
61
+ }
62
+ `;
63
+ var CREATE_PROVIDER = `
64
+ mutation GgnomadCreateProvider($input: CreateGgnomadProviderInput!) {
65
+ createGgnomadProvider(input: $input) {
66
+ ${PROVIDER_FIELDS}
67
+ }
68
+ }
69
+ `;
70
+ var GET_PROPERTY = `
71
+ query GgnomadGetProperty($id: ID!) {
72
+ ggnomadProperty(id: $id) {
73
+ ${PROPERTY_FIELDS}
74
+ }
75
+ }
76
+ `;
77
+ var LIST_PROPERTIES = `
78
+ query GgnomadListProperties($pagination: GgnomadPaginationInput) {
79
+ ggnomadProperties(pagination: $pagination) {
80
+ ${PROPERTY_FIELDS}
81
+ }
82
+ }
83
+ `;
84
+ var CREATE_PROPERTY = `
85
+ mutation GgnomadCreateProperty($input: CreateGgnomadPropertyInput!) {
86
+ createGgnomadProperty(input: $input) {
87
+ ${PROPERTY_FIELDS}
88
+ }
89
+ }
90
+ `;
91
+ var GET_ACTIVITY = `
92
+ query GgnomadGetActivity($id: ID!) {
93
+ ggnomadActivity(id: $id) {
94
+ ${ACTIVITY_FIELDS}
95
+ }
96
+ }
97
+ `;
98
+ var LIST_ACTIVITIES = `
99
+ query GgnomadListActivities($pagination: GgnomadPaginationInput) {
100
+ ggnomadActivities(pagination: $pagination) {
101
+ ${ACTIVITY_FIELDS}
102
+ }
103
+ }
104
+ `;
105
+ var GET_EVENT = `
106
+ query GgnomadGetEvent($id: ID!) {
107
+ ggnomadEvent(id: $id) {
108
+ ${EVENT_FIELDS}
109
+ }
110
+ }
111
+ `;
112
+ var LIST_EVENTS = `
113
+ query GgnomadListEvents($pagination: GgnomadPaginationInput) {
114
+ ggnomadEvents(pagination: $pagination) {
115
+ ${EVENT_FIELDS}
116
+ }
117
+ }
118
+ `;
119
+ var GET_TOUR = `
120
+ query GgnomadGetTour($id: ID!) {
121
+ ggnomadTour(id: $id) {
122
+ ${TOUR_FIELDS}
123
+ }
124
+ }
125
+ `;
126
+ var LIST_TOURS = `
127
+ query GgnomadListTours($pagination: GgnomadPaginationInput) {
128
+ ggnomadTours(pagination: $pagination) {
129
+ ${TOUR_FIELDS}
130
+ }
131
+ }
132
+ `;
133
+ var LIST_TRIPS = `
134
+ query GgnomadListTrips($pagination: GgnomadPaginationInput) {
135
+ ggnomadTrips(pagination: $pagination) {
136
+ ${TRIP_FIELDS}
137
+ }
138
+ }
139
+ `;
140
+ var LIST_BOOKINGS = `
141
+ query GgnomadListBookings($pagination: GgnomadPaginationInput) {
142
+ ggnomadBookings(pagination: $pagination) {
143
+ ${BOOKING_FIELDS}
144
+ }
145
+ }
146
+ `;
147
+ var CREATE_BOOKING = `
148
+ mutation GgnomadCreateBooking($input: CreateGgnomadBookingInput!) {
149
+ createGgnomadBooking(input: $input) {
150
+ ${BOOKING_FIELDS}
151
+ }
152
+ }
153
+ `;
154
+ var CANCEL_BOOKING = `
155
+ mutation GgnomadCancelBooking($id: ID!, $reason: String) {
156
+ cancelGgnomadBooking(id: $id, reason: $reason) {
157
+ ${BOOKING_FIELDS}
158
+ }
159
+ }
160
+ `;
161
+ var LIST_FAVORITES = `
162
+ query GgnomadListFavorites($pagination: GgnomadFavoritesPaginationInput) {
163
+ ggnomadFavorites(pagination: $pagination)
164
+ }
165
+ `;
166
+ var TOGGLE_FAVORITE = `
167
+ mutation GgnomadToggleFavorite($input: ToggleGgnomadFavoriteInput!) {
168
+ toggleGgnomadFavorite(input: $input)
169
+ }
170
+ `;
171
+ var ANALYTICS = `
172
+ query GgnomadAnalytics {
173
+ ggnomadAnalytics {
174
+ ${ANALYTICS_FIELDS}
175
+ }
176
+ }
177
+ `;
178
+ var OVERVIEW_STATS = `
179
+ query GgnomadOverviewStats {
180
+ ggnomadOverviewStats {
181
+ ${OVERVIEW_FIELDS}
182
+ }
183
+ }
184
+ `;
185
+
186
+ // src/modules/ggnomad/tools/providers.ts
187
+ function registerProviderTools(server, ctx, track) {
188
+ server.registerTool(
189
+ track(mcpToolName(ctx.productName, "providers_get")),
190
+ {
191
+ title: "Get Provider",
192
+ description: "Fetch a single GGNomad hospitality provider by ID.",
193
+ inputSchema: { id: z.string().describe("Provider ID") }
194
+ },
195
+ async ({ id }) => {
196
+ try {
197
+ const data = await ctx.gql.workspace.request(GET_PROVIDER, { id });
198
+ if (!data.ggnomadProvider) return errorResult(`Provider ${id} not found`);
199
+ return jsonResult(data.ggnomadProvider);
200
+ } catch (error) {
201
+ ctx.logger.error("ggnomad providers_get failed", { error: String(error) });
202
+ return errorResult(
203
+ `Failed to get provider: ${error instanceof Error ? error.message : String(error)}`
204
+ );
205
+ }
206
+ }
207
+ );
208
+ server.registerTool(
209
+ track(mcpToolName(ctx.productName, "providers_list")),
210
+ {
211
+ title: "List Providers",
212
+ description: "List hospitality providers in the bound workspace, with first/skip pagination.",
213
+ inputSchema: {
214
+ first: z.number().int().optional().describe("Page size (default 20)"),
215
+ skip: z.number().int().optional().describe("Records to skip (default 0)")
216
+ }
217
+ },
218
+ async ({ first, skip }) => {
219
+ try {
220
+ const data = await ctx.gql.workspace.request(LIST_PROVIDERS, { pagination: { first: first ?? 20, skip: skip ?? 0 } });
221
+ return jsonResult(data.ggnomadProviders);
222
+ } catch (error) {
223
+ ctx.logger.error("ggnomad providers_list failed", { error: String(error) });
224
+ return errorResult(
225
+ `Failed to list providers: ${error instanceof Error ? error.message : String(error)}`
226
+ );
227
+ }
228
+ }
229
+ );
230
+ server.registerTool(
231
+ track(mcpToolName(ctx.productName, "providers_create")),
232
+ {
233
+ title: "Create Provider",
234
+ description: 'Onboard a new hospitality provider. `name` and `type` are required (type is a free-form provider class, e.g. "hotel", "tour_operator", "transport").',
235
+ inputSchema: {
236
+ name: z.string().min(1).describe("Provider display name"),
237
+ type: z.string().min(1).describe('Provider type, e.g. "hotel", "tour_operator", "transport"'),
238
+ description: z.string().optional().describe("Provider description"),
239
+ contactEmail: z.string().optional().describe("Contact email"),
240
+ contactPhone: z.string().optional().describe("Contact phone"),
241
+ website: z.string().optional().describe("Provider website URL")
242
+ }
243
+ },
244
+ async ({ name, type, description, contactEmail, contactPhone, website }) => {
245
+ try {
246
+ const input = { name, type };
247
+ if (description !== void 0) input.description = description;
248
+ if (contactEmail !== void 0) input.contactEmail = contactEmail;
249
+ if (contactPhone !== void 0) input.contactPhone = contactPhone;
250
+ if (website !== void 0) input.website = website;
251
+ const data = await ctx.gql.workspace.request(CREATE_PROVIDER, { input });
252
+ return jsonResult(data.createGgnomadProvider);
253
+ } catch (error) {
254
+ ctx.logger.error("ggnomad providers_create failed", { error: String(error) });
255
+ return errorResult(
256
+ `Failed to create provider: ${error instanceof Error ? error.message : String(error)}`
257
+ );
258
+ }
259
+ }
260
+ );
261
+ }
262
+ z.enum(["CANCELLED", "CHECKED_IN", "COMPLETED", "CONFIRMED", "NO_SHOW", "PENDING", "REFUNDED"]).describe("Lifecycle status of a booking");
263
+ var GgnomadBookingTypeEnum = z.enum(["ACTIVITY", "EVENT", "PROPERTY", "TOUR", "TRIP"]).describe("The kind of listing a booking or favorite targets");
264
+ z.enum(["ACTIVE", "ARCHIVED", "DRAFT", "PAUSED", "PENDING_REVIEW"]).describe("Lifecycle/moderation status of a listing (property, activity, event, tour)");
265
+ var JsonObject = z.record(z.string(), z.unknown());
266
+
267
+ // src/modules/ggnomad/tools/properties.ts
268
+ function registerPropertyTools(server, ctx, track) {
269
+ server.registerTool(
270
+ track(mcpToolName(ctx.productName, "properties_get")),
271
+ {
272
+ title: "Get Property",
273
+ description: "Fetch a single bookable property (stay listing) by ID.",
274
+ inputSchema: { id: z.string().describe("Property ID") }
275
+ },
276
+ async ({ id }) => {
277
+ try {
278
+ const data = await ctx.gql.workspace.request(GET_PROPERTY, { id });
279
+ if (!data.ggnomadProperty) return errorResult(`Property ${id} not found`);
280
+ return jsonResult(data.ggnomadProperty);
281
+ } catch (error) {
282
+ ctx.logger.error("ggnomad properties_get failed", { error: String(error) });
283
+ return errorResult(
284
+ `Failed to get property: ${error instanceof Error ? error.message : String(error)}`
285
+ );
286
+ }
287
+ }
288
+ );
289
+ server.registerTool(
290
+ track(mcpToolName(ctx.productName, "properties_list")),
291
+ {
292
+ title: "List Properties",
293
+ description: "List bookable properties in the bound workspace, with first/skip pagination.",
294
+ inputSchema: {
295
+ first: z.number().int().optional().describe("Page size (default 20)"),
296
+ skip: z.number().int().optional().describe("Records to skip (default 0)")
297
+ }
298
+ },
299
+ async ({ first, skip }) => {
300
+ try {
301
+ const data = await ctx.gql.workspace.request(LIST_PROPERTIES, { pagination: { first: first ?? 20, skip: skip ?? 0 } });
302
+ return jsonResult(data.ggnomadProperties);
303
+ } catch (error) {
304
+ ctx.logger.error("ggnomad properties_list failed", { error: String(error) });
305
+ return errorResult(
306
+ `Failed to list properties: ${error instanceof Error ? error.message : String(error)}`
307
+ );
308
+ }
309
+ }
310
+ );
311
+ server.registerTool(
312
+ track(mcpToolName(ctx.productName, "properties_create")),
313
+ {
314
+ title: "Create Property",
315
+ description: 'List a new bookable property. `address` is required JSON; `amenities`/`images` are required arrays; `type` is a free-form class (e.g. "apartment", "villa", "hostel").',
316
+ inputSchema: {
317
+ name: z.string().min(1).describe("Property display name"),
318
+ type: z.string().min(1).describe('Property type, e.g. "apartment", "villa", "hostel"'),
319
+ address: JsonObject.describe("Address JSON ({ line1, city, country, lat, lng, ... })"),
320
+ amenities: z.array(z.string()).describe("Amenity tags (e.g. wifi, kitchen, parking)"),
321
+ images: z.array(z.string()).describe("Image URLs"),
322
+ maxGuests: z.number().int().describe("Maximum guest capacity"),
323
+ pricePerNight: z.number().describe("Nightly price"),
324
+ bedrooms: z.number().int().optional().describe("Number of bedrooms"),
325
+ bathrooms: z.number().int().optional().describe("Number of bathrooms"),
326
+ checkInTime: z.string().optional().describe('Check-in time, e.g. "15:00"'),
327
+ checkOutTime: z.string().optional().describe('Check-out time, e.g. "11:00"'),
328
+ currency: z.string().optional().describe("ISO currency code (default service currency)"),
329
+ description: z.string().optional().describe("Property description"),
330
+ providerId: z.string().optional().describe("Owning provider ID")
331
+ }
332
+ },
333
+ async ({
334
+ name,
335
+ type,
336
+ address,
337
+ amenities,
338
+ images,
339
+ maxGuests,
340
+ pricePerNight,
341
+ bedrooms,
342
+ bathrooms,
343
+ checkInTime,
344
+ checkOutTime,
345
+ currency,
346
+ description,
347
+ providerId
348
+ }) => {
349
+ try {
350
+ const input = {
351
+ name,
352
+ type,
353
+ address,
354
+ amenities,
355
+ images,
356
+ maxGuests,
357
+ pricePerNight
358
+ };
359
+ if (bedrooms !== void 0) input.bedrooms = bedrooms;
360
+ if (bathrooms !== void 0) input.bathrooms = bathrooms;
361
+ if (checkInTime !== void 0) input.checkInTime = checkInTime;
362
+ if (checkOutTime !== void 0) input.checkOutTime = checkOutTime;
363
+ if (currency !== void 0) input.currency = currency;
364
+ if (description !== void 0) input.description = description;
365
+ if (providerId !== void 0) input.providerId = providerId;
366
+ const data = await ctx.gql.workspace.request(CREATE_PROPERTY, { input });
367
+ return jsonResult(data.createGgnomadProperty);
368
+ } catch (error) {
369
+ ctx.logger.error("ggnomad properties_create failed", { error: String(error) });
370
+ return errorResult(
371
+ `Failed to create property: ${error instanceof Error ? error.message : String(error)}`
372
+ );
373
+ }
374
+ }
375
+ );
376
+ }
377
+ function registerActivityTools(server, ctx, track) {
378
+ server.registerTool(
379
+ track(mcpToolName(ctx.productName, "activities_get")),
380
+ {
381
+ title: "Get Activity",
382
+ description: "Fetch a single bookable activity/experience by ID.",
383
+ inputSchema: { id: z.string().describe("Activity ID") }
384
+ },
385
+ async ({ id }) => {
386
+ try {
387
+ const data = await ctx.gql.workspace.request(GET_ACTIVITY, { id });
388
+ if (!data.ggnomadActivity) return errorResult(`Activity ${id} not found`);
389
+ return jsonResult(data.ggnomadActivity);
390
+ } catch (error) {
391
+ ctx.logger.error("ggnomad activities_get failed", { error: String(error) });
392
+ return errorResult(
393
+ `Failed to get activity: ${error instanceof Error ? error.message : String(error)}`
394
+ );
395
+ }
396
+ }
397
+ );
398
+ server.registerTool(
399
+ track(mcpToolName(ctx.productName, "activities_list")),
400
+ {
401
+ title: "List Activities",
402
+ description: "List bookable activities/experiences in the bound workspace (first/skip pagination).",
403
+ inputSchema: {
404
+ first: z.number().int().optional().describe("Page size (default 20)"),
405
+ skip: z.number().int().optional().describe("Records to skip (default 0)")
406
+ }
407
+ },
408
+ async ({ first, skip }) => {
409
+ try {
410
+ const data = await ctx.gql.workspace.request(LIST_ACTIVITIES, { pagination: { first: first ?? 20, skip: skip ?? 0 } });
411
+ return jsonResult(data.ggnomadActivities);
412
+ } catch (error) {
413
+ ctx.logger.error("ggnomad activities_list failed", { error: String(error) });
414
+ return errorResult(
415
+ `Failed to list activities: ${error instanceof Error ? error.message : String(error)}`
416
+ );
417
+ }
418
+ }
419
+ );
420
+ }
421
+ function registerEventTools(server, ctx, track) {
422
+ server.registerTool(
423
+ track(mcpToolName(ctx.productName, "events_get")),
424
+ {
425
+ title: "Get Event",
426
+ description: "Fetch a single ticketed event by ID.",
427
+ inputSchema: { id: z.string().describe("Event ID") }
428
+ },
429
+ async ({ id }) => {
430
+ try {
431
+ const data = await ctx.gql.workspace.request(GET_EVENT, { id });
432
+ if (!data.ggnomadEvent) return errorResult(`Event ${id} not found`);
433
+ return jsonResult(data.ggnomadEvent);
434
+ } catch (error) {
435
+ ctx.logger.error("ggnomad events_get failed", { error: String(error) });
436
+ return errorResult(
437
+ `Failed to get event: ${error instanceof Error ? error.message : String(error)}`
438
+ );
439
+ }
440
+ }
441
+ );
442
+ server.registerTool(
443
+ track(mcpToolName(ctx.productName, "events_list")),
444
+ {
445
+ title: "List Events",
446
+ description: "List ticketed events in the bound workspace (first/skip pagination).",
447
+ inputSchema: {
448
+ first: z.number().int().optional().describe("Page size (default 20)"),
449
+ skip: z.number().int().optional().describe("Records to skip (default 0)")
450
+ }
451
+ },
452
+ async ({ first, skip }) => {
453
+ try {
454
+ const data = await ctx.gql.workspace.request(LIST_EVENTS, { pagination: { first: first ?? 20, skip: skip ?? 0 } });
455
+ return jsonResult(data.ggnomadEvents);
456
+ } catch (error) {
457
+ ctx.logger.error("ggnomad events_list failed", { error: String(error) });
458
+ return errorResult(
459
+ `Failed to list events: ${error instanceof Error ? error.message : String(error)}`
460
+ );
461
+ }
462
+ }
463
+ );
464
+ }
465
+ function registerTourTools(server, ctx, track) {
466
+ server.registerTool(
467
+ track(mcpToolName(ctx.productName, "tours_get")),
468
+ {
469
+ title: "Get Tour",
470
+ description: "Fetch a single guided tour by ID.",
471
+ inputSchema: { id: z.string().describe("Tour ID") }
472
+ },
473
+ async ({ id }) => {
474
+ try {
475
+ const data = await ctx.gql.workspace.request(GET_TOUR, { id });
476
+ if (!data.ggnomadTour) return errorResult(`Tour ${id} not found`);
477
+ return jsonResult(data.ggnomadTour);
478
+ } catch (error) {
479
+ ctx.logger.error("ggnomad tours_get failed", { error: String(error) });
480
+ return errorResult(
481
+ `Failed to get tour: ${error instanceof Error ? error.message : String(error)}`
482
+ );
483
+ }
484
+ }
485
+ );
486
+ server.registerTool(
487
+ track(mcpToolName(ctx.productName, "tours_list")),
488
+ {
489
+ title: "List Tours",
490
+ description: "List guided tours in the bound workspace (first/skip pagination).",
491
+ inputSchema: {
492
+ first: z.number().int().optional().describe("Page size (default 20)"),
493
+ skip: z.number().int().optional().describe("Records to skip (default 0)")
494
+ }
495
+ },
496
+ async ({ first, skip }) => {
497
+ try {
498
+ const data = await ctx.gql.workspace.request(LIST_TOURS, { pagination: { first: first ?? 20, skip: skip ?? 0 } });
499
+ return jsonResult(data.ggnomadTours);
500
+ } catch (error) {
501
+ ctx.logger.error("ggnomad tours_list failed", { error: String(error) });
502
+ return errorResult(
503
+ `Failed to list tours: ${error instanceof Error ? error.message : String(error)}`
504
+ );
505
+ }
506
+ }
507
+ );
508
+ }
509
+ function registerTripTools(server, ctx, track) {
510
+ server.registerTool(
511
+ track(mcpToolName(ctx.productName, "trips_list")),
512
+ {
513
+ title: "List Trips",
514
+ description: "List transport/travel trips in the bound workspace (first/skip pagination).",
515
+ inputSchema: {
516
+ first: z.number().int().optional().describe("Page size (default 20)"),
517
+ skip: z.number().int().optional().describe("Records to skip (default 0)")
518
+ }
519
+ },
520
+ async ({ first, skip }) => {
521
+ try {
522
+ const data = await ctx.gql.workspace.request(LIST_TRIPS, { pagination: { first: first ?? 20, skip: skip ?? 0 } });
523
+ return jsonResult(data.ggnomadTrips);
524
+ } catch (error) {
525
+ ctx.logger.error("ggnomad trips_list failed", { error: String(error) });
526
+ return errorResult(
527
+ `Failed to list trips: ${error instanceof Error ? error.message : String(error)}`
528
+ );
529
+ }
530
+ }
531
+ );
532
+ }
533
+ function registerBookingTools(server, ctx, track) {
534
+ server.registerTool(
535
+ track(mcpToolName(ctx.productName, "bookings_list")),
536
+ {
537
+ title: "List Bookings",
538
+ description: "List bookings in the bound workspace (first/skip pagination).",
539
+ inputSchema: {
540
+ first: z.number().int().optional().describe("Page size (default 20)"),
541
+ skip: z.number().int().optional().describe("Records to skip (default 0)")
542
+ }
543
+ },
544
+ async ({ first, skip }) => {
545
+ try {
546
+ const data = await ctx.gql.workspace.request(LIST_BOOKINGS, { pagination: { first: first ?? 20, skip: skip ?? 0 } });
547
+ return jsonResult(data.ggnomadBookings);
548
+ } catch (error) {
549
+ ctx.logger.error("ggnomad bookings_list failed", { error: String(error) });
550
+ return errorResult(
551
+ `Failed to list bookings: ${error instanceof Error ? error.message : String(error)}`
552
+ );
553
+ }
554
+ }
555
+ );
556
+ server.registerTool(
557
+ track(mcpToolName(ctx.productName, "bookings_create")),
558
+ {
559
+ title: "Create Booking",
560
+ description: "Create a guest booking against a listing. `itemId`/`itemName` snapshot the booked listing; `bookingType` selects the listing kind; supply `checkIn`/`checkOut` for stays, `eventDate` for events/activities.",
561
+ inputSchema: {
562
+ bookingType: GgnomadBookingTypeEnum.describe("Kind of listing being booked"),
563
+ itemId: z.string().min(1).describe("ID of the booked listing"),
564
+ itemName: z.string().min(1).describe("Snapshot name of the booked listing"),
565
+ guestName: z.string().min(1).describe("Lead guest name"),
566
+ guests: z.number().int().describe("Number of guests"),
567
+ totalPrice: z.number().describe("Total booking price"),
568
+ guestEmail: z.string().optional().describe("Guest email"),
569
+ guestPhone: z.string().optional().describe("Guest phone"),
570
+ checkIn: z.string().optional().describe("Check-in datetime (ISO 8601) \u2014 stays"),
571
+ checkOut: z.string().optional().describe("Check-out datetime (ISO 8601) \u2014 stays"),
572
+ eventDate: z.string().optional().describe("Event/activity datetime (ISO 8601) \u2014 events, activities, tours"),
573
+ currency: z.string().optional().describe("ISO currency code (default service currency)"),
574
+ paymentMethod: z.string().optional().describe('Payment method, e.g. "card", "upi"'),
575
+ specialRequests: z.string().optional().describe("Free-text special requests")
576
+ }
577
+ },
578
+ async ({
579
+ bookingType,
580
+ itemId,
581
+ itemName,
582
+ guestName,
583
+ guests,
584
+ totalPrice,
585
+ guestEmail,
586
+ guestPhone,
587
+ checkIn,
588
+ checkOut,
589
+ eventDate,
590
+ currency,
591
+ paymentMethod,
592
+ specialRequests
593
+ }) => {
594
+ try {
595
+ const input = {
596
+ bookingType,
597
+ itemId,
598
+ itemName,
599
+ guestName,
600
+ guests,
601
+ totalPrice
602
+ };
603
+ if (guestEmail !== void 0) input.guestEmail = guestEmail;
604
+ if (guestPhone !== void 0) input.guestPhone = guestPhone;
605
+ if (checkIn !== void 0) input.checkIn = checkIn;
606
+ if (checkOut !== void 0) input.checkOut = checkOut;
607
+ if (eventDate !== void 0) input.eventDate = eventDate;
608
+ if (currency !== void 0) input.currency = currency;
609
+ if (paymentMethod !== void 0) input.paymentMethod = paymentMethod;
610
+ if (specialRequests !== void 0) input.specialRequests = specialRequests;
611
+ const data = await ctx.gql.workspace.request(CREATE_BOOKING, { input });
612
+ return jsonResult(data.createGgnomadBooking);
613
+ } catch (error) {
614
+ ctx.logger.error("ggnomad bookings_create failed", { error: String(error) });
615
+ return errorResult(
616
+ `Failed to create booking: ${error instanceof Error ? error.message : String(error)}`
617
+ );
618
+ }
619
+ }
620
+ );
621
+ server.registerTool(
622
+ track(mcpToolName(ctx.productName, "bookings_cancel")),
623
+ {
624
+ title: "Cancel Booking",
625
+ description: "Cancel a booking by ID, with an optional cancellation reason.",
626
+ inputSchema: {
627
+ id: z.string().describe("Booking ID"),
628
+ reason: z.string().optional().describe("Cancellation reason")
629
+ }
630
+ },
631
+ async ({ id, reason }) => {
632
+ try {
633
+ const data = await ctx.gql.workspace.request(CANCEL_BOOKING, { id, reason });
634
+ return jsonResult(data.cancelGgnomadBooking);
635
+ } catch (error) {
636
+ ctx.logger.error("ggnomad bookings_cancel failed", { error: String(error) });
637
+ return errorResult(
638
+ `Failed to cancel booking: ${error instanceof Error ? error.message : String(error)}`
639
+ );
640
+ }
641
+ }
642
+ );
643
+ }
644
+ function registerFavoriteTools(server, ctx, track) {
645
+ server.registerTool(
646
+ track(mcpToolName(ctx.productName, "favorites_list")),
647
+ {
648
+ title: "List Favorites",
649
+ description: "List the calling user's favorited listings (first/skip pagination, default page 50).",
650
+ inputSchema: {
651
+ first: z.number().int().optional().describe("Page size (default 50)"),
652
+ skip: z.number().int().optional().describe("Records to skip (default 0)")
653
+ }
654
+ },
655
+ async ({ first, skip }) => {
656
+ try {
657
+ const data = await ctx.gql.workspace.request(LIST_FAVORITES, { pagination: { first: first ?? 50, skip: skip ?? 0 } });
658
+ return jsonResult(data.ggnomadFavorites);
659
+ } catch (error) {
660
+ ctx.logger.error("ggnomad favorites_list failed", { error: String(error) });
661
+ return errorResult(
662
+ `Failed to list favorites: ${error instanceof Error ? error.message : String(error)}`
663
+ );
664
+ }
665
+ }
666
+ );
667
+ server.registerTool(
668
+ track(mcpToolName(ctx.productName, "favorites_toggle")),
669
+ {
670
+ title: "Toggle Favorite",
671
+ description: "Toggle a listing in the calling user's favorites. Returns true if the listing is now favorited, false if it was removed.",
672
+ inputSchema: {
673
+ targetId: z.string().min(1).describe("ID of the listing to favorite/un-favorite"),
674
+ targetType: GgnomadBookingTypeEnum.describe("Kind of listing being targeted")
675
+ }
676
+ },
677
+ async ({ targetId, targetType }) => {
678
+ try {
679
+ const data = await ctx.gql.workspace.request(
680
+ TOGGLE_FAVORITE,
681
+ { input: { targetId, targetType } }
682
+ );
683
+ return jsonResult({ favorited: data.toggleGgnomadFavorite });
684
+ } catch (error) {
685
+ ctx.logger.error("ggnomad favorites_toggle failed", { error: String(error) });
686
+ return errorResult(
687
+ `Failed to toggle favorite: ${error instanceof Error ? error.message : String(error)}`
688
+ );
689
+ }
690
+ }
691
+ );
692
+ }
693
+
694
+ // src/modules/ggnomad/tools/analytics.ts
695
+ function registerAnalyticsTools(server, ctx, track) {
696
+ server.registerTool(
697
+ track(mcpToolName(ctx.productName, "analytics_metrics")),
698
+ {
699
+ title: "GGNomad Analytics",
700
+ description: "Marketplace-wide analytics: conversion rate, monthly trends, revenue by category, top destinations, and total users/bookings/revenue.",
701
+ inputSchema: {}
702
+ },
703
+ async () => {
704
+ try {
705
+ const data = await ctx.gql.workspace.request(ANALYTICS, {});
706
+ return jsonResult(data.ggnomadAnalytics);
707
+ } catch (error) {
708
+ ctx.logger.error("ggnomad analytics_metrics failed", { error: String(error) });
709
+ return errorResult(
710
+ `Failed to get analytics: ${error instanceof Error ? error.message : String(error)}`
711
+ );
712
+ }
713
+ }
714
+ );
715
+ server.registerTool(
716
+ track(mcpToolName(ctx.productName, "analytics_overview")),
717
+ {
718
+ title: "GGNomad Overview Stats",
719
+ description: "Headline marketplace KPIs: active listings, total bookings, total users, and monthly revenue.",
720
+ inputSchema: {}
721
+ },
722
+ async () => {
723
+ try {
724
+ const data = await ctx.gql.workspace.request(OVERVIEW_STATS, {});
725
+ return jsonResult(data.ggnomadOverviewStats);
726
+ } catch (error) {
727
+ ctx.logger.error("ggnomad analytics_overview failed", { error: String(error) });
728
+ return errorResult(
729
+ `Failed to get overview stats: ${error instanceof Error ? error.message : String(error)}`
730
+ );
731
+ }
732
+ }
733
+ );
734
+ }
735
+
736
+ // src/modules/ggnomad/resources.ts
737
+ function registerGgnomadResources(server, ctx, track) {
738
+ const schemaUri = track(mcpResourceUri(ctx.productName, "schema"));
739
+ const overviewUri = track(mcpResourceUri(ctx.productName, "overview"));
740
+ const analyticsUri = track(mcpResourceUri(ctx.productName, "analytics"));
741
+ const propertiesUri = track(mcpResourceUri(ctx.productName, "properties"));
742
+ server.registerResource(
743
+ "ggnomad-schema",
744
+ schemaUri,
745
+ {
746
+ title: "GGNomad Domain Schema",
747
+ description: "Overview of the GGNomad travel + hospitality marketplace domain \u2014 entities, enums, and the per-entity tool surface.",
748
+ mimeType: "text/plain"
749
+ },
750
+ async () => {
751
+ ctx.logger.debug(`Resource ${schemaUri} requested`);
752
+ const schema = `# GGNomad Domain (Overview)
753
+
754
+ Nomad travel + hospitality marketplace: bookable stays, activities, events,
755
+ guided tours, and trips, sold by providers and booked by guests.
756
+
757
+ ## Entities
758
+ - GgnomadProvider \u2014 a hospitality business (hotel, tour operator, transport)
759
+ - GgnomadProperty \u2014 a bookable stay listing
760
+ - GgnomadActivity \u2014 a bookable experience/activity
761
+ - GgnomadEvent \u2014 a ticketed event
762
+ - GgnomadTour \u2014 a guided tour
763
+ - GgnomadTrip \u2014 a transport/travel leg
764
+ - GgnomadBooking \u2014 a guest booking against any listing
765
+
766
+ ## Enums
767
+ - GgnomadBookingType: ACTIVITY, EVENT, PROPERTY, TOUR, TRIP
768
+ - GgnomadBookingStatus: PENDING, CONFIRMED, CHECKED_IN, COMPLETED, CANCELLED, NO_SHOW, REFUNDED
769
+ - GgnomadListingStatus: DRAFT, PENDING_REVIEW, ACTIVE, PAUSED, ARCHIVED
770
+
771
+ ## Tool groups
772
+ providers, properties, activities, events, tours, trips, bookings, favorites, analytics.
773
+ All run against the WORKSPACE gateway (workspace-scoped). Pagination is { first, skip }.
774
+ `;
775
+ return {
776
+ contents: [{ uri: schemaUri, text: schema, mimeType: "text/plain" }]
777
+ };
778
+ }
779
+ );
780
+ server.registerResource(
781
+ "ggnomad-overview",
782
+ overviewUri,
783
+ {
784
+ title: "GGNomad Overview Stats",
785
+ description: "Live headline marketplace KPIs (listings, bookings, users, monthly revenue).",
786
+ mimeType: "application/json"
787
+ },
788
+ async () => {
789
+ ctx.logger.debug(`Resource ${overviewUri} requested`);
790
+ try {
791
+ const data = await ctx.gql.workspace.request(
792
+ OVERVIEW_STATS,
793
+ {}
794
+ );
795
+ return {
796
+ contents: [
797
+ {
798
+ uri: overviewUri,
799
+ text: JSON.stringify(data.ggnomadOverviewStats, null, 2),
800
+ mimeType: "application/json"
801
+ }
802
+ ]
803
+ };
804
+ } catch (error) {
805
+ return {
806
+ contents: [
807
+ {
808
+ uri: overviewUri,
809
+ text: JSON.stringify({
810
+ error: error instanceof Error ? error.message : String(error)
811
+ }),
812
+ mimeType: "application/json"
813
+ }
814
+ ]
815
+ };
816
+ }
817
+ }
818
+ );
819
+ server.registerResource(
820
+ "ggnomad-analytics",
821
+ analyticsUri,
822
+ {
823
+ title: "GGNomad Analytics",
824
+ description: "Marketplace-wide analytics: conversion rate, monthly trends, revenue by category, top destinations, totals.",
825
+ mimeType: "application/json"
826
+ },
827
+ async () => {
828
+ ctx.logger.debug(`Resource ${analyticsUri} requested`);
829
+ try {
830
+ const data = await ctx.gql.workspace.request(ANALYTICS, {});
831
+ return {
832
+ contents: [
833
+ {
834
+ uri: analyticsUri,
835
+ text: JSON.stringify(data.ggnomadAnalytics, null, 2),
836
+ mimeType: "application/json"
837
+ }
838
+ ]
839
+ };
840
+ } catch (error) {
841
+ return {
842
+ contents: [
843
+ {
844
+ uri: analyticsUri,
845
+ text: JSON.stringify({
846
+ error: error instanceof Error ? error.message : String(error)
847
+ }),
848
+ mimeType: "application/json"
849
+ }
850
+ ]
851
+ };
852
+ }
853
+ }
854
+ );
855
+ server.registerResource(
856
+ "ggnomad-properties",
857
+ propertiesUri,
858
+ {
859
+ title: "GGNomad Property Directory",
860
+ description: "The first 50 bookable properties in the bound workspace.",
861
+ mimeType: "application/json"
862
+ },
863
+ async () => {
864
+ ctx.logger.debug(`Resource ${propertiesUri} requested`);
865
+ try {
866
+ const data = await ctx.gql.workspace.request(
867
+ LIST_PROPERTIES,
868
+ { pagination: { first: 50, skip: 0 } }
869
+ );
870
+ return {
871
+ contents: [
872
+ {
873
+ uri: propertiesUri,
874
+ text: JSON.stringify(data.ggnomadProperties, null, 2),
875
+ mimeType: "application/json"
876
+ }
877
+ ]
878
+ };
879
+ } catch (error) {
880
+ return {
881
+ contents: [
882
+ {
883
+ uri: propertiesUri,
884
+ text: JSON.stringify({
885
+ error: error instanceof Error ? error.message : String(error)
886
+ }),
887
+ mimeType: "application/json"
888
+ }
889
+ ]
890
+ };
891
+ }
892
+ }
893
+ );
894
+ }
895
+ function registerGgnomadPrompts(server, ctx, track) {
896
+ const p = ctx.productName;
897
+ const onboardingName = track(mcpPromptName(p, "provider-onboarding"));
898
+ const opsName = track(mcpPromptName(p, "marketplace-ops"));
899
+ server.registerPrompt(
900
+ onboardingName,
901
+ {
902
+ title: "Provider Onboarding",
903
+ description: "Guide for onboarding a new GGNomad hospitality provider end to end: create the provider and list its first bookable property.",
904
+ argsSchema: {
905
+ name: z.string().optional().describe("Provider/business name"),
906
+ type: z.string().optional().describe('Provider type, e.g. "hotel", "tour_operator"')
907
+ }
908
+ },
909
+ ({ name, type }) => {
910
+ ctx.logger.debug(`Prompt ${onboardingName} called`, { name, type });
911
+ const nameNote = name ? `Use the business name "${name}".` : "Ask the user for the business name.";
912
+ const typeNote = type ? `Use provider type "${type}".` : "Help the user pick a provider type.";
913
+ return {
914
+ messages: [
915
+ {
916
+ role: "user",
917
+ content: {
918
+ type: "text",
919
+ text: `Help me onboard a new GGNomad hospitality provider.
920
+
921
+ 1. **Create Provider**: Use ${p}_providers_create. ${nameNote} ${typeNote} Optionally add contactEmail, contactPhone, and website.
922
+ 2. **List a Property**: Use ${p}_properties_create for the first stay \u2014 set the providerId from step 1, plus address JSON, amenities, images, maxGuests, and pricePerNight.
923
+ 3. **Verify**: Use ${p}_properties_list to confirm the property appears, and ${p}_providers_get to confirm the provider's listingCount.
924
+
925
+ Show results at each step and confirm before listing more inventory.`
926
+ }
927
+ }
928
+ ]
929
+ };
930
+ }
931
+ );
932
+ server.registerPrompt(
933
+ opsName,
934
+ {
935
+ title: "Marketplace Operations",
936
+ description: "Daily operations workflow: review KPIs, triage the booking queue, manage cancellations, and scan inventory.",
937
+ argsSchema: {
938
+ providerId: z.string().optional().describe("Provider ID to focus on")
939
+ }
940
+ },
941
+ ({ providerId }) => {
942
+ ctx.logger.debug(`Prompt ${opsName} called`, { providerId });
943
+ const providerNote = providerId ? `Focus on provider "${providerId}".` : `First list providers with ${p}_providers_list and pick one.`;
944
+ return {
945
+ messages: [
946
+ {
947
+ role: "user",
948
+ content: {
949
+ type: "text",
950
+ text: `Run daily GGNomad marketplace operations. ${providerNote}
951
+
952
+ 1. **KPIs**: Use ${p}_analytics_overview for headline numbers and ${p}_analytics_metrics for trends, revenue by category, and top destinations.
953
+ 2. **Booking Queue**: Use ${p}_bookings_list to find PENDING/CONFIRMED bookings that need attention.
954
+ 3. **Cancellations**: For any booking that must be cancelled, use ${p}_bookings_cancel with a clear reason.
955
+ 4. **Inventory**: Scan ${p}_properties_list, ${p}_activities_list, ${p}_events_list, ${p}_tours_list, and ${p}_trips_list for listings needing updates.
956
+
957
+ Summarize what needs attention after each step.`
958
+ }
959
+ }
960
+ ]
961
+ };
962
+ }
963
+ );
964
+ }
965
+
966
+ // src/modules/ggnomad/index.ts
967
+ var ggnomadModule = {
968
+ id: "ggnomad",
969
+ version: "0.0.1",
970
+ displayName: "GGNomad",
971
+ dependsOn: ["auth"],
972
+ capabilities: { tools: {}, resources: {}, prompts: {} },
973
+ register(server, ctx) {
974
+ const tools = [];
975
+ const resources = [];
976
+ const prompts = [];
977
+ const trackTool = (n) => {
978
+ tools.push(n);
979
+ return n;
980
+ };
981
+ const trackResource = (uri) => {
982
+ resources.push(uri);
983
+ return uri;
984
+ };
985
+ const trackPrompt = (n) => {
986
+ prompts.push(n);
987
+ return n;
988
+ };
989
+ registerProviderTools(server, ctx, trackTool);
990
+ registerPropertyTools(server, ctx, trackTool);
991
+ registerActivityTools(server, ctx, trackTool);
992
+ registerEventTools(server, ctx, trackTool);
993
+ registerTourTools(server, ctx, trackTool);
994
+ registerTripTools(server, ctx, trackTool);
995
+ registerBookingTools(server, ctx, trackTool);
996
+ registerFavoriteTools(server, ctx, trackTool);
997
+ registerAnalyticsTools(server, ctx, trackTool);
998
+ registerGgnomadResources(server, ctx, trackResource);
999
+ registerGgnomadPrompts(server, ctx, trackPrompt);
1000
+ return { tools, resources, prompts };
1001
+ }
1002
+ };
1003
+ var ggnomad_default = ggnomadModule;
1004
+
1005
+ export { ggnomad_default as default };
1006
+ //# sourceMappingURL=index.js.map
1007
+ //# sourceMappingURL=index.js.map