sbb-mcp 0.4.0 → 0.4.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.
- package/dist/structured.d.ts +119 -0
- package/dist/structured.js +133 -0
- package/dist/structured.js.map +1 -0
- package/dist/tools.js +190 -156
- package/dist/tools.js.map +1 -1
- package/dist/widgets.d.ts +33 -0
- package/dist/widgets.js +120 -0
- package/dist/widgets.js.map +1 -0
- package/package.json +6 -3
- package/web/dist/widgets.css +1 -0
- package/web/dist/widgets.js +1 -0
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure extractors from SMAPI types to widget-friendly DTOs.
|
|
3
|
+
* Shape must stay in sync with web/src/types.ts.
|
|
4
|
+
*
|
|
5
|
+
* Keep these side-effect free. They're tested in unit tests and run on
|
|
6
|
+
* every tool invocation to populate `structuredContent` on responses.
|
|
7
|
+
*/
|
|
8
|
+
import type { SmapiPlace, SmapiTrip, SmapiTripsCollection, SmapiPriceResult } from './transport/smapi-types.js';
|
|
9
|
+
export interface StationDTO {
|
|
10
|
+
id: string;
|
|
11
|
+
name: string;
|
|
12
|
+
lat?: number;
|
|
13
|
+
lon?: number;
|
|
14
|
+
}
|
|
15
|
+
export interface StationsListDTO {
|
|
16
|
+
query: string;
|
|
17
|
+
stations: StationDTO[];
|
|
18
|
+
}
|
|
19
|
+
export interface LegDTO {
|
|
20
|
+
type: 'train' | 'walk';
|
|
21
|
+
line?: string;
|
|
22
|
+
platform?: string;
|
|
23
|
+
minutes: number;
|
|
24
|
+
}
|
|
25
|
+
export interface ConnectionDTO {
|
|
26
|
+
tripId: string;
|
|
27
|
+
departureTime: string;
|
|
28
|
+
arrivalTime: string;
|
|
29
|
+
durationMinutes: number;
|
|
30
|
+
transfers: number;
|
|
31
|
+
legs: LegDTO[];
|
|
32
|
+
}
|
|
33
|
+
export interface ConnectionListDTO {
|
|
34
|
+
origin: StationDTO;
|
|
35
|
+
destination: StationDTO;
|
|
36
|
+
date: string;
|
|
37
|
+
collectionId: string;
|
|
38
|
+
connections: ConnectionDTO[];
|
|
39
|
+
weather?: {
|
|
40
|
+
summary: string;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
export interface TripStopDTO {
|
|
44
|
+
name: string;
|
|
45
|
+
arrivalTime?: string;
|
|
46
|
+
departureTime?: string;
|
|
47
|
+
}
|
|
48
|
+
export interface TripLegDTO {
|
|
49
|
+
type: 'train' | 'walk';
|
|
50
|
+
line?: string;
|
|
51
|
+
operator?: string;
|
|
52
|
+
durationMinutes: number;
|
|
53
|
+
from?: {
|
|
54
|
+
name: string;
|
|
55
|
+
time: string;
|
|
56
|
+
platform?: string;
|
|
57
|
+
};
|
|
58
|
+
to?: {
|
|
59
|
+
name: string;
|
|
60
|
+
time: string;
|
|
61
|
+
platform?: string;
|
|
62
|
+
};
|
|
63
|
+
intermediateStops?: TripStopDTO[];
|
|
64
|
+
occupancy?: {
|
|
65
|
+
firstClass?: string;
|
|
66
|
+
secondClass?: string;
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
export interface TripDetailsDTO {
|
|
70
|
+
tripId: string;
|
|
71
|
+
origin: StationDTO;
|
|
72
|
+
destination: StationDTO;
|
|
73
|
+
departureTime: string;
|
|
74
|
+
arrivalTime: string;
|
|
75
|
+
durationMinutes: number;
|
|
76
|
+
transfers: number;
|
|
77
|
+
status: string;
|
|
78
|
+
legs: TripLegDTO[];
|
|
79
|
+
}
|
|
80
|
+
export interface PriceDTO {
|
|
81
|
+
tripId: string;
|
|
82
|
+
secondClass?: {
|
|
83
|
+
amount: number;
|
|
84
|
+
currency: string;
|
|
85
|
+
};
|
|
86
|
+
firstClass?: {
|
|
87
|
+
amount: number;
|
|
88
|
+
currency: string;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
export interface PricesTableDTO {
|
|
92
|
+
prices: PriceDTO[];
|
|
93
|
+
}
|
|
94
|
+
export interface TicketCardDTO {
|
|
95
|
+
tripId: string;
|
|
96
|
+
origin: StationDTO;
|
|
97
|
+
destination: StationDTO;
|
|
98
|
+
departureTime: string;
|
|
99
|
+
arrivalTime: string;
|
|
100
|
+
primaryLink: string;
|
|
101
|
+
affiliateLink?: string;
|
|
102
|
+
}
|
|
103
|
+
export declare function toStationsListDTO(query: string, places: SmapiPlace[]): StationsListDTO;
|
|
104
|
+
export declare function toConnectionListDTO(collection: SmapiTripsCollection, weather?: {
|
|
105
|
+
summary: string;
|
|
106
|
+
}): ConnectionListDTO;
|
|
107
|
+
export declare function toTripDetailsDTO(trip: SmapiTrip): TripDetailsDTO;
|
|
108
|
+
export declare function toPricesTableDTO(results: SmapiPriceResult[]): PricesTableDTO;
|
|
109
|
+
export declare function toTicketCardDTO(params: {
|
|
110
|
+
tripId: string;
|
|
111
|
+
fromName: string;
|
|
112
|
+
fromId: string;
|
|
113
|
+
toName: string;
|
|
114
|
+
toId: string;
|
|
115
|
+
departureTime: string;
|
|
116
|
+
arrivalTime: string;
|
|
117
|
+
primaryLink: string;
|
|
118
|
+
affiliateLink?: string;
|
|
119
|
+
}): TicketCardDTO;
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pure extractors from SMAPI types to widget-friendly DTOs.
|
|
3
|
+
* Shape must stay in sync with web/src/types.ts.
|
|
4
|
+
*
|
|
5
|
+
* Keep these side-effect free. They're tested in unit tests and run on
|
|
6
|
+
* every tool invocation to populate `structuredContent` on responses.
|
|
7
|
+
*/
|
|
8
|
+
// ──────────────────────────────────────────────────────────────────────
|
|
9
|
+
function toStation(p) {
|
|
10
|
+
return {
|
|
11
|
+
id: p.id,
|
|
12
|
+
name: p.name,
|
|
13
|
+
lat: p.geoPosition?.latitude,
|
|
14
|
+
lon: p.geoPosition?.longitude,
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
function parseIsoDurationMinutes(iso) {
|
|
18
|
+
const m = iso.match(/PT(?:(\d+)H)?(?:(\d+)M)?/);
|
|
19
|
+
if (!m)
|
|
20
|
+
return 0;
|
|
21
|
+
return parseInt(m[1] ?? '0', 10) * 60 + parseInt(m[2] ?? '0', 10);
|
|
22
|
+
}
|
|
23
|
+
function legToDTO(leg) {
|
|
24
|
+
if (leg.type === 'timed') {
|
|
25
|
+
const tl = leg;
|
|
26
|
+
return {
|
|
27
|
+
type: 'train',
|
|
28
|
+
line: tl.service.publishedLineName,
|
|
29
|
+
platform: tl.board.platform,
|
|
30
|
+
minutes: parseIsoDurationMinutes(tl.duration),
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
if (leg.type === 'transfer') {
|
|
34
|
+
const tr = leg;
|
|
35
|
+
return { type: 'walk', minutes: parseIsoDurationMinutes(tr.duration) };
|
|
36
|
+
}
|
|
37
|
+
return { type: 'walk', minutes: parseIsoDurationMinutes(leg.duration) };
|
|
38
|
+
}
|
|
39
|
+
export function toStationsListDTO(query, places) {
|
|
40
|
+
return { query, stations: places.map(toStation) };
|
|
41
|
+
}
|
|
42
|
+
export function toConnectionListDTO(collection, weather) {
|
|
43
|
+
const first = collection.trips[0];
|
|
44
|
+
const fallbackStation = { id: '', name: '—' };
|
|
45
|
+
return {
|
|
46
|
+
origin: first ? toStation(first.origin) : fallbackStation,
|
|
47
|
+
destination: first ? toStation(first.destination) : fallbackStation,
|
|
48
|
+
date: first?.startTime ?? '',
|
|
49
|
+
collectionId: collection.id,
|
|
50
|
+
connections: collection.trips.map((t) => ({
|
|
51
|
+
tripId: t.id,
|
|
52
|
+
departureTime: t.startTime,
|
|
53
|
+
arrivalTime: t.endTime,
|
|
54
|
+
durationMinutes: parseIsoDurationMinutes(t.duration),
|
|
55
|
+
transfers: t.transfers,
|
|
56
|
+
legs: t.legs.map(legToDTO),
|
|
57
|
+
})),
|
|
58
|
+
...(weather ? { weather } : {}),
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
export function toTripDetailsDTO(trip) {
|
|
62
|
+
return {
|
|
63
|
+
tripId: trip.id,
|
|
64
|
+
origin: toStation(trip.origin),
|
|
65
|
+
destination: toStation(trip.destination),
|
|
66
|
+
departureTime: trip.startTime,
|
|
67
|
+
arrivalTime: trip.endTime,
|
|
68
|
+
durationMinutes: parseIsoDurationMinutes(trip.duration),
|
|
69
|
+
transfers: trip.transfers,
|
|
70
|
+
status: trip.tripStatus,
|
|
71
|
+
legs: trip.legs.map((leg) => {
|
|
72
|
+
if (leg.type === 'timed') {
|
|
73
|
+
const tl = leg;
|
|
74
|
+
return {
|
|
75
|
+
type: 'train',
|
|
76
|
+
line: tl.service.publishedLineName,
|
|
77
|
+
operator: tl.service.operatorName,
|
|
78
|
+
durationMinutes: parseIsoDurationMinutes(tl.duration),
|
|
79
|
+
from: {
|
|
80
|
+
name: tl.board.stopPlace.name,
|
|
81
|
+
time: tl.board.departureTime,
|
|
82
|
+
platform: tl.board.platform,
|
|
83
|
+
},
|
|
84
|
+
to: {
|
|
85
|
+
name: tl.alight.stopPlace.name,
|
|
86
|
+
time: tl.alight.arrivalTime,
|
|
87
|
+
platform: tl.alight.platform,
|
|
88
|
+
},
|
|
89
|
+
intermediateStops: tl.intermediateStops?.map((s) => ({
|
|
90
|
+
name: s.stopPlace.name,
|
|
91
|
+
arrivalTime: s.arrivalTime,
|
|
92
|
+
departureTime: s.departureTime,
|
|
93
|
+
})),
|
|
94
|
+
occupancy: tl.occupancy
|
|
95
|
+
? {
|
|
96
|
+
firstClass: tl.occupancy.firstClass,
|
|
97
|
+
secondClass: tl.occupancy.secondClass,
|
|
98
|
+
}
|
|
99
|
+
: undefined,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
return {
|
|
103
|
+
type: 'walk',
|
|
104
|
+
durationMinutes: parseIsoDurationMinutes(leg.duration),
|
|
105
|
+
};
|
|
106
|
+
}),
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
export function toPricesTableDTO(results) {
|
|
110
|
+
return {
|
|
111
|
+
prices: results.map((r) => {
|
|
112
|
+
const second = r.prices.find((p) => p.class === '2');
|
|
113
|
+
const first = r.prices.find((p) => p.class === '1');
|
|
114
|
+
return {
|
|
115
|
+
tripId: r.tripId,
|
|
116
|
+
...(second ? { secondClass: { amount: second.amount, currency: second.currency } } : {}),
|
|
117
|
+
...(first ? { firstClass: { amount: first.amount, currency: first.currency } } : {}),
|
|
118
|
+
};
|
|
119
|
+
}),
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
export function toTicketCardDTO(params) {
|
|
123
|
+
return {
|
|
124
|
+
tripId: params.tripId,
|
|
125
|
+
origin: { id: params.fromId, name: params.fromName },
|
|
126
|
+
destination: { id: params.toId, name: params.toName },
|
|
127
|
+
departureTime: params.departureTime,
|
|
128
|
+
arrivalTime: params.arrivalTime,
|
|
129
|
+
primaryLink: params.primaryLink,
|
|
130
|
+
...(params.affiliateLink ? { affiliateLink: params.affiliateLink } : {}),
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
//# sourceMappingURL=structured.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structured.js","sourceRoot":"","sources":["../src/structured.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.js
CHANGED
|
@@ -1,30 +1,21 @@
|
|
|
1
1
|
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
2
|
import { z } from 'zod';
|
|
3
3
|
import { isSmapiConfigured, searchPlaces, searchTrips, getTrip, paginateTrips, getTripPrices, getTripOffers, mockSearchPlaces, mockSearchTrips, mockGetTripPrices, } from './transport/index.js';
|
|
4
|
-
import { formatStations, formatConnections, formatTripDetails, formatPrices, formatTicketLink, buildSbbDeepLink,
|
|
4
|
+
import { formatStations, formatConnections, formatTripDetails, formatPrices, formatTicketLink, buildSbbDeepLink, } from './formatters.js';
|
|
5
5
|
import { cacheGet, cacheSet, TTL } from './cache.js';
|
|
6
6
|
import { SmapiError } from './transport/smapi-client.js';
|
|
7
7
|
import { loadProfile, saveProfile, formatProfileSummary, isReductionCardExpired } from './profile.js';
|
|
8
8
|
import { isSwissTripConfigured, fetchProfile as fetchCloudProfile, fetchTravelers, toSmapiTraveler, formatTravelersList, formatCloudProfile, } from './swisstrip.js';
|
|
9
|
-
import {
|
|
9
|
+
import { getWeatherSummary } from 'swiss-weather-mcp';
|
|
10
|
+
import { toStationsListDTO, toConnectionListDTO, toTripDetailsDTO, toPricesTableDTO, toTicketCardDTO, } from './structured.js';
|
|
11
|
+
import { registerWidgets, widgetResponseMeta, widgetToolMeta, WIDGETS } from './widgets.js';
|
|
10
12
|
const useMock = !isSmapiConfigured();
|
|
11
13
|
const useCloud = isSwissTripConfigured();
|
|
12
|
-
const LANG_ENUM = z.enum(['de', 'fr', 'it', 'en', 'es', 'pt', 'ru', 'ar', 'zh']);
|
|
13
|
-
const LANG_DESC = "Output language (de/fr/it/en/es/pt/ru/ar/zh). Defaults to the user's saved profile language or English.";
|
|
14
|
-
/** Pick the effective language: tool arg > saved profile > English. */
|
|
15
|
-
function effectiveLang(arg, profile) {
|
|
16
|
-
if (arg)
|
|
17
|
-
return resolveLang(arg);
|
|
18
|
-
if (profile?.language)
|
|
19
|
-
return resolveLang(profile.language);
|
|
20
|
-
return 'en';
|
|
21
|
-
}
|
|
22
14
|
/** Match SwissTrip travelers by first name (case-insensitive, fuzzy) */
|
|
23
15
|
function matchTravelersByName(all, names) {
|
|
24
16
|
const matched = [];
|
|
25
17
|
for (const name of names) {
|
|
26
18
|
const lower = name.toLowerCase();
|
|
27
|
-
// Try exact first_name match, then label match, then partial match
|
|
28
19
|
const found = all.find(t => t.first_name?.toLowerCase() === lower ||
|
|
29
20
|
t.label?.toLowerCase() === lower) || all.find(t => t.first_name?.toLowerCase().startsWith(lower) ||
|
|
30
21
|
t.last_name?.toLowerCase() === lower);
|
|
@@ -43,12 +34,24 @@ function errorResult(err) {
|
|
|
43
34
|
const message = err instanceof Error ? err.message : String(err);
|
|
44
35
|
return { content: [{ type: 'text', text: `Error: ${message}` }], isError: true };
|
|
45
36
|
}
|
|
37
|
+
/** Compute Europe/Zurich ISO timestamp for a (date, HH:MM) pair. */
|
|
38
|
+
function zurichIso(date, time) {
|
|
39
|
+
const probe = new Date(`${date}T${time}:00Z`);
|
|
40
|
+
const zurichStr = probe.toLocaleString('en-US', { timeZone: 'Europe/Zurich' });
|
|
41
|
+
const zurichTime = new Date(zurichStr + ' UTC');
|
|
42
|
+
const offsetMs = zurichTime.getTime() - probe.getTime();
|
|
43
|
+
const offsetHours = Math.round(offsetMs / (60 * 60 * 1000));
|
|
44
|
+
const offsetStr = `${offsetHours >= 0 ? '+' : '-'}${String(Math.abs(offsetHours)).padStart(2, '0')}:00`;
|
|
45
|
+
return new Date(`${date}T${time}:00${offsetStr}`).toISOString();
|
|
46
|
+
}
|
|
46
47
|
export function createSbbMcpServer() {
|
|
47
48
|
const server = new McpServer({
|
|
48
49
|
name: 'sbb-mcp',
|
|
49
50
|
version: '0.4.0',
|
|
50
51
|
description: 'Swiss Federal Railways (SBB/CFF/FFS) — real-time train schedules, prices, and ticket purchase links for Switzerland',
|
|
51
52
|
});
|
|
53
|
+
// ─── Widget resources (ChatGPT Apps SDK) ───────────────────────────────
|
|
54
|
+
registerWidgets(server);
|
|
52
55
|
// ─── Prompts ───────────────────────────────────────────────────────────
|
|
53
56
|
server.prompt('plan_journey', 'Plan a train journey in Switzerland — finds connections, compares prices, and provides ticket links', {
|
|
54
57
|
from: z.string().describe('Origin station (e.g. "Zurich")'),
|
|
@@ -68,7 +71,6 @@ export function createSbbMcpServer() {
|
|
|
68
71
|
description: 'The user\'s saved travel profile (name, DOB, reduction card). Read this before showing prices or generating ticket links. If empty, ask the user for their details and save with save_profile.',
|
|
69
72
|
mimeType: 'text/plain',
|
|
70
73
|
}, async () => {
|
|
71
|
-
// Cloud profile takes precedence when SWISSTRIP_TOKEN is set
|
|
72
74
|
if (useCloud) {
|
|
73
75
|
try {
|
|
74
76
|
const cloudProfile = await fetchCloudProfile();
|
|
@@ -81,7 +83,7 @@ export function createSbbMcpServer() {
|
|
|
81
83
|
};
|
|
82
84
|
}
|
|
83
85
|
catch {
|
|
84
|
-
// Fall through
|
|
86
|
+
// Fall through
|
|
85
87
|
}
|
|
86
88
|
}
|
|
87
89
|
const profile = loadProfile();
|
|
@@ -108,14 +110,18 @@ export function createSbbMcpServer() {
|
|
|
108
110
|
};
|
|
109
111
|
});
|
|
110
112
|
// ─── Tool: save_profile ──────────────────────────────────────────────
|
|
111
|
-
server.
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
113
|
+
server.registerTool('save_profile', {
|
|
114
|
+
title: 'Save Travel Profile',
|
|
115
|
+
description: 'Save the user\'s travel profile locally for future sessions. Call this after asking the user for their details (name, date of birth, reduction card). Data is stored at ~/.sbb-mcp/profile.json.',
|
|
116
|
+
inputSchema: {
|
|
117
|
+
first_name: z.string().optional().describe('First name (for ticket booking)'),
|
|
118
|
+
last_name: z.string().optional().describe('Last name (for ticket booking)'),
|
|
119
|
+
date_of_birth: z.string().optional().describe('Date of birth YYYY-MM-DD (for age-based pricing)'),
|
|
120
|
+
reduction_card: z.enum(['HALF_FARE', 'GA', 'NONE']).optional().describe('Swiss reduction card: HALF_FARE (Halbtax), GA (General Abonnement), or NONE'),
|
|
121
|
+
reduction_card_valid_until: z.string().optional().describe('Reduction card expiry date YYYY-MM-DD (ask the user when their Halbtax/GA expires)'),
|
|
122
|
+
},
|
|
123
|
+
annotations: { readOnlyHint: false, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
124
|
+
}, async ({ first_name, last_name, date_of_birth, reduction_card, reduction_card_valid_until }) => {
|
|
119
125
|
try {
|
|
120
126
|
const updates = {};
|
|
121
127
|
if (first_name)
|
|
@@ -128,40 +134,43 @@ export function createSbbMcpServer() {
|
|
|
128
134
|
updates.reduction_card = reduction_card;
|
|
129
135
|
if (reduction_card_valid_until)
|
|
130
136
|
updates.reduction_card_valid_until = reduction_card_valid_until;
|
|
131
|
-
if (language)
|
|
132
|
-
updates.language = language;
|
|
133
137
|
saveProfile(updates);
|
|
134
138
|
const profile = loadProfile();
|
|
135
|
-
|
|
136
|
-
return { content: [{ type: 'text', text: formatProfileSummary(profile, lang) }] };
|
|
139
|
+
return { content: [{ type: 'text', text: formatProfileSummary(profile) }] };
|
|
137
140
|
}
|
|
138
141
|
catch (err) {
|
|
139
142
|
return errorResult(err);
|
|
140
143
|
}
|
|
141
144
|
});
|
|
142
145
|
// ─── Tool: get_profile ───────────────────────────────────────────────
|
|
143
|
-
server.
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
146
|
+
server.registerTool('get_profile', {
|
|
147
|
+
title: 'Get Travel Profile',
|
|
148
|
+
description: 'Read the user\'s saved travel profile. Check this before showing prices to use correct reduction card. If no profile exists, ask the user for their details.',
|
|
149
|
+
inputSchema: {},
|
|
150
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
151
|
+
}, async () => {
|
|
147
152
|
if (useCloud) {
|
|
148
153
|
try {
|
|
149
154
|
const cloudProfile = await fetchCloudProfile();
|
|
150
155
|
return { content: [{ type: 'text', text: formatCloudProfile(cloudProfile) }] };
|
|
151
156
|
}
|
|
152
157
|
catch {
|
|
153
|
-
// Fall through
|
|
158
|
+
// Fall through
|
|
154
159
|
}
|
|
155
160
|
}
|
|
156
161
|
const profile = loadProfile();
|
|
157
162
|
if (!profile) {
|
|
158
163
|
return { content: [{ type: 'text', text: 'No travel profile saved. Ask the user: "Do you have a Halbtax or GA travelcard?" Then use save_profile to store their details for next time.' }] };
|
|
159
164
|
}
|
|
160
|
-
|
|
161
|
-
return { content: [{ type: 'text', text: formatProfileSummary(profile, lang) }] };
|
|
165
|
+
return { content: [{ type: 'text', text: formatProfileSummary(profile) }] };
|
|
162
166
|
});
|
|
163
167
|
// ─── Tool: list_travelers (SwissTrip cloud only) ─────────────────────
|
|
164
|
-
server.
|
|
168
|
+
server.registerTool('list_travelers', {
|
|
169
|
+
title: 'List Travelers',
|
|
170
|
+
description: 'List all travelers in the user\'s SwissTrip account (self, partner, kids). Each traveler has their own reduction card. Use their names with get_prices for family trip pricing. Requires SWISSTRIP_TOKEN.',
|
|
171
|
+
inputSchema: {},
|
|
172
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
173
|
+
}, async () => {
|
|
165
174
|
if (!useCloud) {
|
|
166
175
|
return { content: [{ type: 'text', text: 'list_travelers requires a SwissTrip account connection (SWISSTRIP_TOKEN). Without it, use save_profile/get_profile for single-traveler local profiles.' }] };
|
|
167
176
|
}
|
|
@@ -172,7 +181,7 @@ export function createSbbMcpServer() {
|
|
|
172
181
|
return { content: [{ type: 'text', text: cached }] };
|
|
173
182
|
const travelers = await fetchTravelers();
|
|
174
183
|
const text = formatTravelersList(travelers);
|
|
175
|
-
cacheSet(cacheKey, text, TTL.STATIONS);
|
|
184
|
+
cacheSet(cacheKey, text, TTL.STATIONS);
|
|
176
185
|
return { content: [{ type: 'text', text }] };
|
|
177
186
|
}
|
|
178
187
|
catch (err) {
|
|
@@ -180,45 +189,51 @@ export function createSbbMcpServer() {
|
|
|
180
189
|
}
|
|
181
190
|
});
|
|
182
191
|
// ─── Tool 1: search_stations ──────────────────────────────────────────
|
|
183
|
-
server.
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
192
|
+
server.registerTool('search_stations', {
|
|
193
|
+
title: 'Search Stations',
|
|
194
|
+
description: 'Search for Swiss train stations, addresses, or points of interest by name. Returns station IDs needed for other tools.',
|
|
195
|
+
inputSchema: {
|
|
196
|
+
query: z.string().describe('Station name to search for (e.g. "Zurich", "Bern", "Interlaken")'),
|
|
197
|
+
limit: z.number().min(1).max(20).default(10).describe('Maximum number of results'),
|
|
198
|
+
},
|
|
199
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
200
|
+
_meta: widgetToolMeta(WIDGETS.STATIONS_LIST, 'Searching stations…', 'Stations ready'),
|
|
201
|
+
}, async ({ query, limit }) => {
|
|
188
202
|
try {
|
|
189
|
-
const lang = effectiveLang(language, loadProfile());
|
|
190
|
-
const cacheKey = `stations:${query.toLowerCase()}:${limit}:${lang}`;
|
|
191
|
-
const cached = cacheGet(cacheKey);
|
|
192
|
-
if (cached)
|
|
193
|
-
return { content: [{ type: 'text', text: cached }] };
|
|
194
203
|
const stations = useMock
|
|
195
204
|
? await mockSearchPlaces({ name: query })
|
|
196
|
-
: await searchPlaces({ name: query, type: 'STOP', numberOfResults: limit
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
205
|
+
: await searchPlaces({ name: query, type: 'STOP', numberOfResults: limit });
|
|
206
|
+
return {
|
|
207
|
+
content: [{ type: 'text', text: formatStations(stations) }],
|
|
208
|
+
structuredContent: toStationsListDTO(query, stations),
|
|
209
|
+
_meta: widgetResponseMeta(WIDGETS.STATIONS_LIST),
|
|
210
|
+
};
|
|
200
211
|
}
|
|
201
212
|
catch (err) {
|
|
202
213
|
return errorResult(err);
|
|
203
214
|
}
|
|
204
215
|
});
|
|
205
216
|
// ─── Tool 2: search_connections ───────────────────────────────────────
|
|
206
|
-
server.
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
217
|
+
server.registerTool('search_connections', {
|
|
218
|
+
title: 'Search Connections',
|
|
219
|
+
description: 'Find train connections between two Swiss stations. Returns schedules with departure/arrival times, duration, transfers, and trip IDs for pricing.',
|
|
220
|
+
inputSchema: {
|
|
221
|
+
from: z.string().describe('Origin station name or ID (e.g. "Zurich HB" or "8503000")'),
|
|
222
|
+
to: z.string().describe('Destination station name or ID (e.g. "Bern" or "8507000")'),
|
|
223
|
+
date: z.string().optional().describe('Travel date in YYYY-MM-DD format (default: today)'),
|
|
224
|
+
time: z.string().optional().describe('Departure time in HH:MM format (default: now)'),
|
|
225
|
+
arrival_time: z.boolean().optional().describe('If true, the time parameter is treated as desired arrival time'),
|
|
226
|
+
},
|
|
227
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
228
|
+
_meta: widgetToolMeta(WIDGETS.CONNECTION_LIST, 'Finding trains…', 'Connections ready'),
|
|
229
|
+
}, async ({ from, to, date, time, arrival_time }) => {
|
|
214
230
|
try {
|
|
215
|
-
const lang = effectiveLang(language, loadProfile());
|
|
216
231
|
let fromId = from;
|
|
217
232
|
let toId = to;
|
|
218
233
|
if (!/^\d{5,8}$/.test(from)) {
|
|
219
234
|
const stations = useMock
|
|
220
235
|
? await mockSearchPlaces({ name: from })
|
|
221
|
-
: await searchPlaces({ name: from, type: 'STOP', numberOfResults: 1
|
|
236
|
+
: await searchPlaces({ name: from, type: 'STOP', numberOfResults: 1 });
|
|
222
237
|
if (stations.length === 0) {
|
|
223
238
|
return { content: [{ type: 'text', text: `No station found matching "${from}". Try a different name.` }] };
|
|
224
239
|
}
|
|
@@ -227,7 +242,7 @@ export function createSbbMcpServer() {
|
|
|
227
242
|
if (!/^\d{5,8}$/.test(to)) {
|
|
228
243
|
const stations = useMock
|
|
229
244
|
? await mockSearchPlaces({ name: to })
|
|
230
|
-
: await searchPlaces({ name: to, type: 'STOP', numberOfResults: 1
|
|
245
|
+
: await searchPlaces({ name: to, type: 'STOP', numberOfResults: 1 });
|
|
231
246
|
if (stations.length === 0) {
|
|
232
247
|
return { content: [{ type: 'text', text: `No station found matching "${to}". Try a different name.` }] };
|
|
233
248
|
}
|
|
@@ -238,25 +253,12 @@ export function createSbbMcpServer() {
|
|
|
238
253
|
if (date || time) {
|
|
239
254
|
const d = date || new Date().toISOString().split('T')[0];
|
|
240
255
|
const t = time || '08:00';
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
const zurichStr = probe.toLocaleString('en-US', { timeZone: 'Europe/Zurich' });
|
|
244
|
-
const zurichTime = new Date(zurichStr + ' UTC');
|
|
245
|
-
const offsetMs = zurichTime.getTime() - probe.getTime();
|
|
246
|
-
const offsetHours = Math.round(offsetMs / (60 * 60 * 1000));
|
|
247
|
-
const offsetStr = `${offsetHours >= 0 ? '+' : '-'}${String(Math.abs(offsetHours)).padStart(2, '0')}:00`;
|
|
248
|
-
const dt = new Date(`${d}T${t}:00${offsetStr}`).toISOString();
|
|
249
|
-
if (arrival_time) {
|
|
256
|
+
const dt = zurichIso(d, t);
|
|
257
|
+
if (arrival_time)
|
|
250
258
|
arrivalTime = dt;
|
|
251
|
-
|
|
252
|
-
else {
|
|
259
|
+
else
|
|
253
260
|
departureTime = dt;
|
|
254
|
-
}
|
|
255
261
|
}
|
|
256
|
-
const cacheKey = `connections:${fromId}:${toId}:${departureTime || ''}:${arrivalTime || ''}:${lang}`;
|
|
257
|
-
const cached = cacheGet(cacheKey);
|
|
258
|
-
if (cached)
|
|
259
|
-
return { content: [{ type: 'text', text: cached }] };
|
|
260
262
|
const collection = useMock
|
|
261
263
|
? await mockSearchTrips({ origin: fromId, destination: toId, departureTime })
|
|
262
264
|
: await searchTrips({
|
|
@@ -264,129 +266,149 @@ export function createSbbMcpServer() {
|
|
|
264
266
|
destination: toId,
|
|
265
267
|
...(departureTime && { departureTime }),
|
|
266
268
|
...(arrivalTime && { arrivalTime }),
|
|
267
|
-
lang,
|
|
268
269
|
});
|
|
269
|
-
let text = formatConnections(collection
|
|
270
|
-
|
|
270
|
+
let text = formatConnections(collection);
|
|
271
|
+
let weatherSummary;
|
|
271
272
|
if (collection.trips.length > 0) {
|
|
272
273
|
const dest = collection.trips[0].destination;
|
|
273
274
|
if (dest.geoPosition) {
|
|
274
275
|
const travelDate = date || new Date().toISOString().split('T')[0];
|
|
275
|
-
|
|
276
|
+
const name = dest.name || to;
|
|
277
|
+
try {
|
|
278
|
+
const summary = await getWeatherSummary(dest.geoPosition.latitude, dest.geoPosition.longitude, travelDate);
|
|
279
|
+
if (summary) {
|
|
280
|
+
weatherSummary = summary;
|
|
281
|
+
text = text + `\n\n**${name} weather:** ${summary}`;
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
catch {
|
|
285
|
+
// Non-fatal
|
|
286
|
+
}
|
|
276
287
|
}
|
|
277
288
|
}
|
|
278
|
-
|
|
279
|
-
|
|
289
|
+
return {
|
|
290
|
+
content: [{ type: 'text', text }],
|
|
291
|
+
structuredContent: toConnectionListDTO(collection, weatherSummary ? { summary: weatherSummary } : undefined),
|
|
292
|
+
_meta: widgetResponseMeta(WIDGETS.CONNECTION_LIST),
|
|
293
|
+
};
|
|
280
294
|
}
|
|
281
295
|
catch (err) {
|
|
282
296
|
return errorResult(err);
|
|
283
297
|
}
|
|
284
298
|
});
|
|
285
299
|
// ─── Tool 3: get_trip_details ─────────────────────────────────────────
|
|
286
|
-
server.
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
300
|
+
server.registerTool('get_trip_details', {
|
|
301
|
+
title: 'Get Trip Details',
|
|
302
|
+
description: 'Get detailed information about a specific train connection including all intermediate stops, platforms, and occupancy. Use a trip ID from search_connections results.',
|
|
303
|
+
inputSchema: {
|
|
304
|
+
trip_id: z.string().describe('Trip ID from search_connections results'),
|
|
305
|
+
},
|
|
306
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
307
|
+
_meta: widgetToolMeta(WIDGETS.TRIP_DETAILS, 'Loading trip details…', 'Trip details ready'),
|
|
308
|
+
}, async ({ trip_id }) => {
|
|
290
309
|
try {
|
|
291
|
-
const lang = effectiveLang(language, loadProfile());
|
|
292
310
|
if (useMock) {
|
|
293
311
|
return { content: [{ type: 'text', text: 'Detailed trip information is available with live API access. In mock mode, use search_connections to see trip summaries.' }] };
|
|
294
312
|
}
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
cacheSet(cacheKey, text, TTL.TRIP_DETAILS);
|
|
302
|
-
return { content: [{ type: 'text', text }] };
|
|
313
|
+
const trip = await getTrip(trip_id, 'REAL_BOARDING_ALIGHTING');
|
|
314
|
+
return {
|
|
315
|
+
content: [{ type: 'text', text: formatTripDetails(trip) }],
|
|
316
|
+
structuredContent: toTripDetailsDTO(trip),
|
|
317
|
+
_meta: widgetResponseMeta(WIDGETS.TRIP_DETAILS),
|
|
318
|
+
};
|
|
303
319
|
}
|
|
304
320
|
catch (err) {
|
|
305
321
|
return errorResult(err);
|
|
306
322
|
}
|
|
307
323
|
});
|
|
308
324
|
// ─── Tool 4: get_more_connections ─────────────────────────────────────
|
|
309
|
-
server.
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
325
|
+
server.registerTool('get_more_connections', {
|
|
326
|
+
title: 'Get More Connections',
|
|
327
|
+
description: 'Load earlier or later train connections for a previous search. Use the collection ID from search_connections results.',
|
|
328
|
+
inputSchema: {
|
|
329
|
+
collection_id: z.string().describe('Collection ID from search_connections results'),
|
|
330
|
+
direction: z.enum(['next', 'previous']).describe('"next" for later trains, "previous" for earlier trains'),
|
|
331
|
+
},
|
|
332
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
333
|
+
_meta: widgetToolMeta(WIDGETS.CONNECTION_LIST, 'Loading more trains…', 'More connections ready'),
|
|
334
|
+
}, async ({ collection_id, direction }) => {
|
|
314
335
|
try {
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
336
|
+
const collection = useMock
|
|
337
|
+
? await mockSearchTrips({
|
|
338
|
+
origin: '8503000',
|
|
339
|
+
destination: '8507000',
|
|
340
|
+
departureTime: new Date(Date.now() + (direction === 'next' ? 3 : -3) * 60 * 60 * 1000).toISOString(),
|
|
341
|
+
})
|
|
342
|
+
: await paginateTrips(collection_id, direction);
|
|
343
|
+
return {
|
|
344
|
+
content: [{ type: 'text', text: formatConnections(collection) }],
|
|
345
|
+
structuredContent: toConnectionListDTO(collection),
|
|
346
|
+
_meta: widgetResponseMeta(WIDGETS.CONNECTION_LIST),
|
|
347
|
+
};
|
|
324
348
|
}
|
|
325
349
|
catch (err) {
|
|
326
350
|
return errorResult(err);
|
|
327
351
|
}
|
|
328
352
|
});
|
|
329
353
|
// ─── Tool 5: get_prices ───────────────────────────────────────────────
|
|
330
|
-
server.
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
354
|
+
server.registerTool('get_prices', {
|
|
355
|
+
title: 'Get Prices',
|
|
356
|
+
description: 'Get ticket prices for one or more train connections. Supports Half-Fare card (Halbtax) and GA travelcard discounts. When connected to SwissTrip (SWISSTRIP_TOKEN), pass traveler_names to get family pricing for multiple travelers.',
|
|
357
|
+
inputSchema: {
|
|
358
|
+
trip_ids: z.array(z.string()).min(1).max(10).describe('Trip IDs from search_connections results'),
|
|
359
|
+
traveler_type: z.enum(['ADULT', 'CHILD']).default('ADULT').describe('Traveler type (used when no traveler_names given)'),
|
|
360
|
+
reduction_card: z.enum(['HALF_FARE', 'GA', 'NONE']).default('HALF_FARE').describe('Swiss reduction card (used when no traveler_names given)'),
|
|
361
|
+
traveler_names: z.array(z.string()).optional().describe('Names of SwissTrip travelers to price for (e.g. ["Fabian", "Anna"]). Requires SWISSTRIP_TOKEN. Each traveler\'s reduction card is applied automatically.'),
|
|
362
|
+
},
|
|
363
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: true, openWorldHint: false },
|
|
364
|
+
_meta: widgetToolMeta(WIDGETS.PRICES_TABLE, 'Fetching prices…', 'Prices ready'),
|
|
365
|
+
}, async ({ trip_ids, traveler_type, reduction_card, traveler_names }) => {
|
|
337
366
|
try {
|
|
338
|
-
const lang = effectiveLang(language, loadProfile());
|
|
339
|
-
// Build travelers list — cloud multi-traveler or single manual
|
|
340
367
|
let travelers;
|
|
341
|
-
let cacheKey;
|
|
342
368
|
if (traveler_names && traveler_names.length > 0 && useCloud) {
|
|
343
|
-
// Fetch travelers from SwissTrip and match by name
|
|
344
369
|
const allTravelers = await fetchTravelers();
|
|
345
370
|
const matched = matchTravelersByName(allTravelers, traveler_names);
|
|
346
371
|
if (matched.length === 0) {
|
|
347
372
|
return { content: [{ type: 'text', text: `No matching travelers found. Available: ${allTravelers.map(t => t.first_name).filter(Boolean).join(', ')}. Use list_travelers to see all.` }] };
|
|
348
373
|
}
|
|
349
374
|
travelers = matched.map((t, i) => toSmapiTraveler(t, i));
|
|
350
|
-
cacheKey = `prices:${trip_ids.join(',')}:cloud:${matched.map(t => t.id).join(',')}:${lang}`;
|
|
351
375
|
}
|
|
352
376
|
else {
|
|
353
377
|
travelers = [{ id: 'traveler-1', type: traveler_type, reductionCard: reduction_card }];
|
|
354
|
-
cacheKey = `prices:${trip_ids.join(',')}:${traveler_type}:${reduction_card}:${lang}`;
|
|
355
378
|
}
|
|
356
|
-
const
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
}
|
|
365
|
-
const prices = await getTripPrices(trip_ids, travelers, lang);
|
|
366
|
-
const text = formatPrices(prices, lang);
|
|
367
|
-
cacheSet(cacheKey, text, TTL.PRICES);
|
|
368
|
-
return { content: [{ type: 'text', text }] };
|
|
379
|
+
const prices = useMock
|
|
380
|
+
? await mockGetTripPrices(trip_ids)
|
|
381
|
+
: await getTripPrices(trip_ids, travelers);
|
|
382
|
+
return {
|
|
383
|
+
content: [{ type: 'text', text: formatPrices(prices) }],
|
|
384
|
+
structuredContent: toPricesTableDTO(prices),
|
|
385
|
+
_meta: widgetResponseMeta(WIDGETS.PRICES_TABLE),
|
|
386
|
+
};
|
|
369
387
|
}
|
|
370
388
|
catch (err) {
|
|
371
389
|
return errorResult(err);
|
|
372
390
|
}
|
|
373
391
|
});
|
|
374
392
|
// ─── Tool 6: get_ticket_link ──────────────────────────────────────────
|
|
375
|
-
server.
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
393
|
+
server.registerTool('get_ticket_link', {
|
|
394
|
+
title: 'Get Ticket Link',
|
|
395
|
+
description: 'Get a direct purchase link to buy a train ticket on SBB.ch. Only call this when the user wants to buy a specific ticket. On mobile with SBB app installed, opens directly in the app with Halbtax/GA applied automatically. Pass traveler_names for family tickets when connected to SwissTrip.',
|
|
396
|
+
inputSchema: {
|
|
397
|
+
trip_id: z.string().describe('Trip ID to purchase'),
|
|
398
|
+
from_name: z.string().describe('Origin station name (e.g. "Zürich HB")'),
|
|
399
|
+
from_id: z.string().describe('Origin station ID (e.g. "8503000")'),
|
|
400
|
+
to_name: z.string().describe('Destination station name (e.g. "Bern")'),
|
|
401
|
+
to_id: z.string().describe('Destination station ID (e.g. "8507000")'),
|
|
402
|
+
date: z.string().describe('Travel date YYYY-MM-DD'),
|
|
403
|
+
time: z.string().describe('Departure time HH:MM'),
|
|
404
|
+
traveler_type: z.enum(['ADULT', 'CHILD']).default('ADULT').describe('Traveler type (used when no traveler_names given)'),
|
|
405
|
+
reduction_card: z.enum(['HALF_FARE', 'GA', 'NONE']).default('HALF_FARE').describe('Swiss reduction card (used when no traveler_names given)'),
|
|
406
|
+
traveler_names: z.array(z.string()).optional().describe('SwissTrip traveler names for family tickets. Requires SWISSTRIP_TOKEN.'),
|
|
407
|
+
},
|
|
408
|
+
annotations: { readOnlyHint: true, destructiveHint: false, idempotentHint: false, openWorldHint: true },
|
|
409
|
+
_meta: widgetToolMeta(WIDGETS.TICKET_CARD, 'Preparing ticket link…', 'Ticket link ready'),
|
|
410
|
+
}, async ({ trip_id, from_name, from_id, to_name, to_id, date, time, traveler_type, reduction_card, traveler_names }) => {
|
|
388
411
|
try {
|
|
389
|
-
const lang = effectiveLang(language, loadProfile());
|
|
390
412
|
const sbbLink = buildSbbDeepLink({
|
|
391
413
|
fromName: from_name,
|
|
392
414
|
fromId: from_id,
|
|
@@ -394,9 +416,7 @@ export function createSbbMcpServer() {
|
|
|
394
416
|
toId: to_id,
|
|
395
417
|
date,
|
|
396
418
|
time,
|
|
397
|
-
lang,
|
|
398
419
|
});
|
|
399
|
-
// Build travelers — cloud multi-traveler or single manual
|
|
400
420
|
let travelers;
|
|
401
421
|
if (traveler_names && traveler_names.length > 0 && useCloud) {
|
|
402
422
|
const allTravelers = await fetchTravelers();
|
|
@@ -408,18 +428,32 @@ export function createSbbMcpServer() {
|
|
|
408
428
|
else {
|
|
409
429
|
travelers = [{ id: 'traveler-1', type: traveler_type, reductionCard: reduction_card }];
|
|
410
430
|
}
|
|
411
|
-
// Try to get affiliate deep link from SMAPI (if live)
|
|
412
431
|
let affiliateLink;
|
|
413
432
|
if (!useMock) {
|
|
414
433
|
try {
|
|
415
|
-
const result = await getTripOffers(trip_id, travelers
|
|
434
|
+
const result = await getTripOffers(trip_id, travelers);
|
|
416
435
|
affiliateLink = result.affiliateDeepLink;
|
|
417
436
|
}
|
|
418
437
|
catch {
|
|
419
|
-
//
|
|
438
|
+
// Non-fatal
|
|
420
439
|
}
|
|
421
440
|
}
|
|
422
|
-
|
|
441
|
+
const depIso = zurichIso(date, time);
|
|
442
|
+
return {
|
|
443
|
+
content: [{ type: 'text', text: formatTicketLink(trip_id, affiliateLink, sbbLink) }],
|
|
444
|
+
structuredContent: toTicketCardDTO({
|
|
445
|
+
tripId: trip_id,
|
|
446
|
+
fromName: from_name,
|
|
447
|
+
fromId: from_id,
|
|
448
|
+
toName: to_name,
|
|
449
|
+
toId: to_id,
|
|
450
|
+
departureTime: depIso,
|
|
451
|
+
arrivalTime: depIso,
|
|
452
|
+
primaryLink: sbbLink,
|
|
453
|
+
affiliateLink,
|
|
454
|
+
}),
|
|
455
|
+
_meta: widgetResponseMeta(WIDGETS.TICKET_CARD),
|
|
456
|
+
};
|
|
423
457
|
}
|
|
424
458
|
catch (err) {
|
|
425
459
|
return errorResult(err);
|
package/dist/tools.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers ChatGPT Apps SDK widget resources on an McpServer.
|
|
3
|
+
*
|
|
4
|
+
* Each tool that returns structured data links to a widget via
|
|
5
|
+
* `_meta["openai/outputTemplate"] = "ui://widget/<name>.html"`.
|
|
6
|
+
*
|
|
7
|
+
* The HTML shell for every widget embeds the same JS bundle (dist/widgets.js)
|
|
8
|
+
* produced by `packages/sbb-mcp/web`. Routing to the right widget component
|
|
9
|
+
* happens in the bundle via `data-widget` on the root element.
|
|
10
|
+
*/
|
|
11
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
12
|
+
/** Registered widget IDs (mirrored in web/src/main.tsx). */
|
|
13
|
+
export declare const WIDGETS: {
|
|
14
|
+
readonly STATIONS_LIST: "stations-list";
|
|
15
|
+
readonly CONNECTION_LIST: "connection-list";
|
|
16
|
+
readonly TRIP_DETAILS: "trip-details";
|
|
17
|
+
readonly PRICES_TABLE: "prices-table";
|
|
18
|
+
readonly TICKET_CARD: "ticket-card";
|
|
19
|
+
};
|
|
20
|
+
export type WidgetId = (typeof WIDGETS)[keyof typeof WIDGETS];
|
|
21
|
+
export declare function widgetUri(id: WidgetId): string;
|
|
22
|
+
/**
|
|
23
|
+
* Descriptor `_meta` (on the tool and resource registrations).
|
|
24
|
+
* This is what tells ChatGPT to render a UI widget for the tool.
|
|
25
|
+
*/
|
|
26
|
+
export declare function widgetToolMeta(id: WidgetId, invoking: string, invoked: string): Record<string, unknown>;
|
|
27
|
+
/**
|
|
28
|
+
* Invocation `_meta` (on each CallTool response).
|
|
29
|
+
* Mirrors the tool-level template so ChatGPT associates the response with the widget.
|
|
30
|
+
*/
|
|
31
|
+
export declare function widgetResponseMeta(id: WidgetId): Record<string, unknown>;
|
|
32
|
+
/** Registers all widget resources on the given MCP server. Call once per server instance. */
|
|
33
|
+
export declare function registerWidgets(server: McpServer): void;
|
package/dist/widgets.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Registers ChatGPT Apps SDK widget resources on an McpServer.
|
|
3
|
+
*
|
|
4
|
+
* Each tool that returns structured data links to a widget via
|
|
5
|
+
* `_meta["openai/outputTemplate"] = "ui://widget/<name>.html"`.
|
|
6
|
+
*
|
|
7
|
+
* The HTML shell for every widget embeds the same JS bundle (dist/widgets.js)
|
|
8
|
+
* produced by `packages/sbb-mcp/web`. Routing to the right widget component
|
|
9
|
+
* happens in the bundle via `data-widget` on the root element.
|
|
10
|
+
*/
|
|
11
|
+
import { readFileSync, existsSync } from 'node:fs';
|
|
12
|
+
import { dirname, resolve } from 'node:path';
|
|
13
|
+
import { fileURLToPath } from 'node:url';
|
|
14
|
+
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
15
|
+
/** Widgets ship under packages/sbb-mcp/web/dist, i.e. two levels above dist/*.js at runtime. */
|
|
16
|
+
const WEB_DIST = resolve(__dirname, '..', 'web', 'dist');
|
|
17
|
+
/** Registered widget IDs (mirrored in web/src/main.tsx). */
|
|
18
|
+
export const WIDGETS = {
|
|
19
|
+
STATIONS_LIST: 'stations-list',
|
|
20
|
+
CONNECTION_LIST: 'connection-list',
|
|
21
|
+
TRIP_DETAILS: 'trip-details',
|
|
22
|
+
PRICES_TABLE: 'prices-table',
|
|
23
|
+
TICKET_CARD: 'ticket-card',
|
|
24
|
+
};
|
|
25
|
+
export function widgetUri(id) {
|
|
26
|
+
return `ui://widget/${id}.html`;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Descriptor `_meta` (on the tool and resource registrations).
|
|
30
|
+
* This is what tells ChatGPT to render a UI widget for the tool.
|
|
31
|
+
*/
|
|
32
|
+
export function widgetToolMeta(id, invoking, invoked) {
|
|
33
|
+
return {
|
|
34
|
+
'openai/outputTemplate': widgetUri(id),
|
|
35
|
+
'openai/toolInvocation/invoking': invoking,
|
|
36
|
+
'openai/toolInvocation/invoked': invoked,
|
|
37
|
+
'openai/widgetAccessible': true,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Invocation `_meta` (on each CallTool response).
|
|
42
|
+
* Mirrors the tool-level template so ChatGPT associates the response with the widget.
|
|
43
|
+
*/
|
|
44
|
+
export function widgetResponseMeta(id) {
|
|
45
|
+
return {
|
|
46
|
+
'openai/outputTemplate': widgetUri(id),
|
|
47
|
+
'openai/widgetAccessible': true,
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
let cachedBundles = null;
|
|
51
|
+
function loadBundles() {
|
|
52
|
+
if (cachedBundles)
|
|
53
|
+
return cachedBundles;
|
|
54
|
+
const jsPath = resolve(WEB_DIST, 'widgets.js');
|
|
55
|
+
const cssPath = resolve(WEB_DIST, 'widgets.css');
|
|
56
|
+
if (!existsSync(jsPath)) {
|
|
57
|
+
throw new Error(`Widget bundle not found at ${jsPath}. Run 'npm run build' in packages/sbb-mcp (which runs the web build first).`);
|
|
58
|
+
}
|
|
59
|
+
const js = readFileSync(jsPath, 'utf8');
|
|
60
|
+
const css = existsSync(cssPath) ? readFileSync(cssPath, 'utf8') : '';
|
|
61
|
+
cachedBundles = { js, css };
|
|
62
|
+
return cachedBundles;
|
|
63
|
+
}
|
|
64
|
+
function renderWidgetHtml(id) {
|
|
65
|
+
const { js, css } = loadBundles();
|
|
66
|
+
return [
|
|
67
|
+
`<div id="sbb-widget-root" data-widget="${id}"></div>`,
|
|
68
|
+
css ? `<style>${css}</style>` : '',
|
|
69
|
+
`<script>${js}</script>`,
|
|
70
|
+
].join('\n');
|
|
71
|
+
}
|
|
72
|
+
const DEFINITIONS = [
|
|
73
|
+
{
|
|
74
|
+
id: WIDGETS.STATIONS_LIST,
|
|
75
|
+
title: 'Stations',
|
|
76
|
+
description: 'Card view of Swiss train station search results.',
|
|
77
|
+
},
|
|
78
|
+
{
|
|
79
|
+
id: WIDGETS.CONNECTION_LIST,
|
|
80
|
+
title: 'Train connections',
|
|
81
|
+
description: 'Card list of Swiss train connections with times, duration, and transfers.',
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
id: WIDGETS.TRIP_DETAILS,
|
|
85
|
+
title: 'Trip details',
|
|
86
|
+
description: 'Timeline view of a single train journey with stops, platforms, and occupancy.',
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
id: WIDGETS.PRICES_TABLE,
|
|
90
|
+
title: 'Ticket prices',
|
|
91
|
+
description: 'Table view of 1st- and 2nd-class ticket prices for selected trips.',
|
|
92
|
+
},
|
|
93
|
+
{
|
|
94
|
+
id: WIDGETS.TICKET_CARD,
|
|
95
|
+
title: 'Buy ticket',
|
|
96
|
+
description: 'SBB ticket purchase card with deep link that opens SBB.ch or the SBB mobile app.',
|
|
97
|
+
},
|
|
98
|
+
];
|
|
99
|
+
/** Registers all widget resources on the given MCP server. Call once per server instance. */
|
|
100
|
+
export function registerWidgets(server) {
|
|
101
|
+
for (const def of DEFINITIONS) {
|
|
102
|
+
const uri = widgetUri(def.id);
|
|
103
|
+
server.registerResource(`widget-${def.id}`, uri, {
|
|
104
|
+
title: def.title,
|
|
105
|
+
description: def.description,
|
|
106
|
+
mimeType: 'text/html+skybridge',
|
|
107
|
+
_meta: widgetToolMeta(def.id, 'Loading…', 'Done'),
|
|
108
|
+
}, async () => ({
|
|
109
|
+
contents: [
|
|
110
|
+
{
|
|
111
|
+
uri,
|
|
112
|
+
mimeType: 'text/html+skybridge',
|
|
113
|
+
text: renderWidgetHtml(def.id),
|
|
114
|
+
_meta: widgetToolMeta(def.id, 'Loading…', 'Done'),
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
}));
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=widgets.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"widgets.js","sourceRoot":"","sources":["../src/widgets.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sbb-mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"mcpName": "io.github.Fabsbags/sbb-mcp",
|
|
5
5
|
"description": "MCP server for Swiss Federal Railways (SBB/CFF/FFS) — real-time train schedules, prices, and ticket purchase links for any AI assistant",
|
|
6
6
|
"type": "module",
|
|
@@ -14,11 +14,14 @@
|
|
|
14
14
|
},
|
|
15
15
|
"files": [
|
|
16
16
|
"dist",
|
|
17
|
+
"web/dist",
|
|
17
18
|
"README.md",
|
|
18
19
|
"LICENSE"
|
|
19
20
|
],
|
|
20
21
|
"scripts": {
|
|
21
|
-
"build": "
|
|
22
|
+
"build:widgets": "npm --prefix web install --no-audit --no-fund && npm --prefix web run build",
|
|
23
|
+
"build:server": "tsc -p tsconfig.build.json",
|
|
24
|
+
"build": "npm run build:widgets && npm run build:server",
|
|
22
25
|
"dev": "tsc -w -p tsconfig.build.json",
|
|
23
26
|
"start:http": "node dist/http.js",
|
|
24
27
|
"test": "vitest run",
|
|
@@ -58,7 +61,7 @@
|
|
|
58
61
|
"@modelcontextprotocol/sdk": "^1.12.1",
|
|
59
62
|
"express": "^5.1.0",
|
|
60
63
|
"sbb-i18n": "^0.1.0",
|
|
61
|
-
"swiss-weather-mcp": "^0.1.
|
|
64
|
+
"swiss-weather-mcp": "^0.1.1",
|
|
62
65
|
"zod": "^3.24.4"
|
|
63
66
|
},
|
|
64
67
|
"devDependencies": {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
:host,.sbb-root{--bg: #ffffff;--bg-raised: #f7f7f8;--border: #e5e5e7;--text: #0f172a;--text-muted: #6b7280;--accent: #eb0000;--accent-fg: #ffffff;--accent-muted: #fff0f0;--success: #0a9447;--warn: #b45309;--radius: 12px;--radius-sm: 8px;--gap: 12px;--gap-sm: 8px;color:var(--text);background:var(--bg);font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif;font-size:14px;line-height:1.45;-webkit-font-smoothing:antialiased}.sbb-root[data-theme=dark]{--bg: #0f1115;--bg-raised: #1a1d23;--border: #2a2e37;--text: #e5e7eb;--text-muted: #9ca3af;--accent: #ff4444;--accent-fg: #ffffff;--accent-muted: #2a1515;--success: #10b981;--warn: #f59e0b}.sbb-root{padding:0;margin:0;max-width:560px}.sbb-header{display:flex;align-items:baseline;justify-content:space-between;gap:var(--gap-sm);margin:0 0 var(--gap) 0;padding:0}.sbb-header__title{font-size:15px;font-weight:600;margin:0}.sbb-header__meta{color:var(--text-muted);font-size:12px}.sbb-card{background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius);padding:var(--gap);display:flex;flex-direction:column;gap:var(--gap-sm)}.sbb-list{display:flex;flex-direction:column;gap:var(--gap-sm)}.sbb-connection{display:grid;grid-template-columns:1fr auto;gap:var(--gap-sm);align-items:center;padding:var(--gap-sm) var(--gap);border:1px solid var(--border);border-radius:var(--radius-sm);background:var(--bg)}.sbb-connection__times{display:flex;align-items:baseline;gap:8px;font-variant-numeric:tabular-nums}.sbb-connection__time{font-weight:600;font-size:16px}.sbb-connection__arrow{color:var(--text-muted)}.sbb-connection__meta{color:var(--text-muted);font-size:12px;margin-top:2px;display:flex;flex-wrap:wrap;gap:6px}.sbb-connection__route{font-size:12px;color:var(--text-muted);display:flex;flex-wrap:wrap;gap:4px;align-items:center}.sbb-connection__actions{display:flex;gap:6px;justify-self:end}.sbb-badge{display:inline-flex;align-items:center;padding:2px 8px;border-radius:999px;background:var(--bg-raised);border:1px solid var(--border);font-size:11px;color:var(--text);white-space:nowrap}.sbb-badge--accent{background:var(--accent-muted);border-color:transparent;color:var(--accent);font-weight:600}.sbb-button{appearance:none;border:1px solid var(--border);background:var(--bg);color:var(--text);padding:6px 10px;font-size:12px;font-weight:500;border-radius:var(--radius-sm);cursor:pointer;display:inline-flex;align-items:center;gap:4px;text-decoration:none;font-family:inherit}.sbb-button:hover:not(:disabled){background:var(--bg-raised)}.sbb-button:disabled{opacity:.5;cursor:not-allowed}.sbb-button--primary{background:var(--accent);color:var(--accent-fg);border-color:var(--accent);padding:8px 14px;font-size:13px}.sbb-button--primary:hover:not(:disabled){background:var(--accent);filter:brightness(.95)}.sbb-footer{margin-top:var(--gap);padding:var(--gap-sm) 0;display:flex;gap:var(--gap-sm);flex-wrap:wrap}.sbb-table{width:100%;border-collapse:collapse;font-size:13px}.sbb-table th,.sbb-table td{padding:6px 10px;text-align:left;border-bottom:1px solid var(--border)}.sbb-table th{font-weight:600;color:var(--text-muted);font-size:12px;text-transform:uppercase;letter-spacing:.03em}.sbb-table td{font-variant-numeric:tabular-nums}.sbb-table tr:last-child td{border-bottom:0}.sbb-ticket-card{padding:16px;background:linear-gradient(135deg,var(--accent-muted),var(--bg-raised));border:1px solid var(--border);border-radius:var(--radius);display:flex;flex-direction:column;gap:var(--gap)}.sbb-ticket-card__route{font-size:16px;font-weight:600}.sbb-ticket-card__times{color:var(--text-muted);font-size:13px}.sbb-weather{padding:8px var(--gap);background:var(--bg-raised);border:1px solid var(--border);border-radius:var(--radius-sm);color:var(--text-muted);font-size:12px;margin-top:var(--gap-sm)}.sbb-timeline{display:flex;flex-direction:column;gap:4px;position:relative;padding-left:16px}.sbb-timeline:before{content:"";position:absolute;left:4px;top:6px;bottom:6px;width:2px;background:var(--border)}.sbb-timeline__stop{position:relative;display:flex;justify-content:space-between;padding:2px 0;font-size:13px}.sbb-timeline__stop:before{content:"";position:absolute;left:-16px;top:8px;width:10px;height:10px;border-radius:50%;background:var(--bg);border:2px solid var(--accent)}.sbb-timeline__stop--intermediate:before{background:var(--border);border-color:var(--border);width:6px;height:6px;left:-14px;top:10px}.sbb-timeline__stop--intermediate{color:var(--text-muted);font-size:12px}.sbb-timeline__time{font-variant-numeric:tabular-nums;color:var(--text-muted);margin-right:8px}.sbb-empty{color:var(--text-muted);padding:var(--gap);text-align:center;font-size:13px}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(){"use strict";var I,u,ee,T,ne,te,re,z,N,B,ie,Z,q,G,$={},E=[],ve=/acit|ex(?:s|g|n|p|$)|rph|grid|ows|mnc|ntw|ine[ch]|zoo|^ord|itera/i,A=Array.isArray;function w(e,n){for(var t in n)e[t]=n[t];return e}function V(e){e&&e.parentNode&&e.parentNode.removeChild(e)}function ye(e,n,t){var l,o,i,c={};for(i in n)i=="key"?l=n[i]:i=="ref"?o=n[i]:c[i]=n[i];if(arguments.length>2&&(c.children=arguments.length>3?I.call(arguments,2):t),typeof e=="function"&&e.defaultProps!=null)for(i in e.defaultProps)c[i]===void 0&&(c[i]=e.defaultProps[i]);return F(e,c,l,o,null)}function F(e,n,t,l,o){var i={type:e,props:n,key:t,ref:l,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:o??++ee,__i:-1,__u:0};return o==null&&u.vnode!=null&&u.vnode(i),i}function U(e){return e.children}function W(e,n){this.props=e,this.context=n}function P(e,n){if(n==null)return e.__?P(e.__,e.__i+1):null;for(var t;n<e.__k.length;n++)if((t=e.__k[n])!=null&&t.__e!=null)return t.__e;return typeof e.type=="function"?P(e):null}function ge(e){if(e.__P&&e.__d){var n=e.__v,t=n.__e,l=[],o=[],i=w({},n);i.__v=n.__v+1,u.vnode&&u.vnode(i),J(e.__P,i,n,e.__n,e.__P.namespaceURI,32&n.__u?[t]:null,l,t??P(n),!!(32&n.__u),o),i.__v=n.__v,i.__.__k[i.__i]=i,de(l,i,o),n.__e=n.__=null,i.__e!=t&&se(i)}}function se(e){if((e=e.__)!=null&&e.__c!=null)return e.__e=e.__c.base=null,e.__k.some(function(n){if(n!=null&&n.__e!=null)return e.__e=e.__c.base=n.__e}),se(e)}function le(e){(!e.__d&&(e.__d=!0)&&T.push(e)&&!H.__r++||ne!=u.debounceRendering)&&((ne=u.debounceRendering)||te)(H)}function H(){try{for(var e,n=1;T.length;)T.length>n&&T.sort(re),e=T.shift(),n=T.length,ge(e)}finally{T.length=H.__r=0}}function oe(e,n,t,l,o,i,c,a,h,_,p){var s,m,d,v,g,y,b,f=l&&l.__k||E,S=n.length;for(h=ke(t,n,f,h,S),s=0;s<S;s++)(d=t.__k[s])!=null&&(m=d.__i!=-1&&f[d.__i]||$,d.__i=s,y=J(e,d,m,o,i,c,a,h,_,p),v=d.__e,d.ref&&m.ref!=d.ref&&(m.ref&&Q(m.ref,null,d),p.push(d.ref,d.__c||v,d)),g==null&&v!=null&&(g=v),(b=!!(4&d.__u))||m.__k===d.__k?(h=ce(d,h,e,b),b&&m.__e&&(m.__e=null)):typeof d.type=="function"&&y!==void 0?h=y:v&&(h=v.nextSibling),d.__u&=-7);return t.__e=g,h}function ke(e,n,t,l,o){var i,c,a,h,_,p=t.length,s=p,m=0;for(e.__k=new Array(o),i=0;i<o;i++)(c=n[i])!=null&&typeof c!="boolean"&&typeof c!="function"?(typeof c=="string"||typeof c=="number"||typeof c=="bigint"||c.constructor==String?c=e.__k[i]=F(null,c,null,null,null):A(c)?c=e.__k[i]=F(U,{children:c},null,null,null):c.constructor===void 0&&c.__b>0?c=e.__k[i]=F(c.type,c.props,c.key,c.ref?c.ref:null,c.__v):e.__k[i]=c,h=i+m,c.__=e,c.__b=e.__b+1,a=null,(_=c.__i=we(c,t,h,s))!=-1&&(s--,(a=t[_])&&(a.__u|=2)),a==null||a.__v==null?(_==-1&&(o>p?m--:o<p&&m++),typeof c.type!="function"&&(c.__u|=4)):_!=h&&(_==h-1?m--:_==h+1?m++:(_>h?m--:m++,c.__u|=4))):e.__k[i]=null;if(s)for(i=0;i<p;i++)(a=t[i])!=null&&!(2&a.__u)&&(a.__e==l&&(l=P(a)),pe(a,a));return l}function ce(e,n,t,l){var o,i;if(typeof e.type=="function"){for(o=e.__k,i=0;o&&i<o.length;i++)o[i]&&(o[i].__=e,n=ce(o[i],n,t,l));return n}e.__e!=n&&(l&&(n&&e.type&&!n.parentNode&&(n=P(e)),t.insertBefore(e.__e,n||null)),n=e.__e);do n=n&&n.nextSibling;while(n!=null&&n.nodeType==8);return n}function we(e,n,t,l){var o,i,c,a=e.key,h=e.type,_=n[t],p=_!=null&&(2&_.__u)==0;if(_===null&&a==null||p&&a==_.key&&h==_.type)return t;if(l>(p?1:0)){for(o=t-1,i=t+1;o>=0||i<n.length;)if((_=n[c=o>=0?o--:i++])!=null&&!(2&_.__u)&&a==_.key&&h==_.type)return c}return-1}function _e(e,n,t){n[0]=="-"?e.setProperty(n,t??""):e[n]=t==null?"":typeof t!="number"||ve.test(n)?t:t+"px"}function R(e,n,t,l,o){var i,c;e:if(n=="style")if(typeof t=="string")e.style.cssText=t;else{if(typeof l=="string"&&(e.style.cssText=l=""),l)for(n in l)t&&n in t||_e(e.style,n,"");if(t)for(n in t)l&&t[n]==l[n]||_e(e.style,n,t[n])}else if(n[0]=="o"&&n[1]=="n")i=n!=(n=n.replace(ie,"$1")),c=n.toLowerCase(),n=c in e||n=="onFocusOut"||n=="onFocusIn"?c.slice(2):n.slice(2),e.l||(e.l={}),e.l[n+i]=t,t?l?t[B]=l[B]:(t[B]=Z,e.addEventListener(n,i?G:q,i)):e.removeEventListener(n,i?G:q,i);else{if(o=="http://www.w3.org/2000/svg")n=n.replace(/xlink(H|:h)/,"h").replace(/sName$/,"s");else if(n!="width"&&n!="height"&&n!="href"&&n!="list"&&n!="form"&&n!="tabIndex"&&n!="download"&&n!="rowSpan"&&n!="colSpan"&&n!="role"&&n!="popover"&&n in e)try{e[n]=t??"";break e}catch{}typeof t=="function"||(t==null||t===!1&&n[4]!="-"?e.removeAttribute(n):e.setAttribute(n,n=="popover"&&t==1?"":t))}}function ae(e){return function(n){if(this.l){var t=this.l[n.type+e];if(n[N]==null)n[N]=Z++;else if(n[N]<t[B])return;return t(u.event?u.event(n):n)}}}function J(e,n,t,l,o,i,c,a,h,_){var p,s,m,d,v,g,y,b,f,S,x,M,me,j,Y,k=n.type;if(n.constructor!==void 0)return null;128&t.__u&&(h=!!(32&t.__u),i=[a=n.__e=t.__e]),(p=u.__b)&&p(n);e:if(typeof k=="function")try{if(b=n.props,f=k.prototype&&k.prototype.render,S=(p=k.contextType)&&l[p.__c],x=p?S?S.props.value:p.__:l,t.__c?y=(s=n.__c=t.__c).__=s.__E:(f?n.__c=s=new k(b,x):(n.__c=s=new W(b,x),s.constructor=k,s.render=Te),S&&S.sub(s),s.state||(s.state={}),s.__n=l,m=s.__d=!0,s.__h=[],s._sb=[]),f&&s.__s==null&&(s.__s=s.state),f&&k.getDerivedStateFromProps!=null&&(s.__s==s.state&&(s.__s=w({},s.__s)),w(s.__s,k.getDerivedStateFromProps(b,s.__s))),d=s.props,v=s.state,s.__v=n,m)f&&k.getDerivedStateFromProps==null&&s.componentWillMount!=null&&s.componentWillMount(),f&&s.componentDidMount!=null&&s.__h.push(s.componentDidMount);else{if(f&&k.getDerivedStateFromProps==null&&b!==d&&s.componentWillReceiveProps!=null&&s.componentWillReceiveProps(b,x),n.__v==t.__v||!s.__e&&s.shouldComponentUpdate!=null&&s.shouldComponentUpdate(b,s.__s,x)===!1){n.__v!=t.__v&&(s.props=b,s.state=s.__s,s.__d=!1),n.__e=t.__e,n.__k=t.__k,n.__k.some(function(L){L&&(L.__=n)}),E.push.apply(s.__h,s._sb),s._sb=[],s.__h.length&&c.push(s);break e}s.componentWillUpdate!=null&&s.componentWillUpdate(b,s.__s,x),f&&s.componentDidUpdate!=null&&s.__h.push(function(){s.componentDidUpdate(d,v,g)})}if(s.context=x,s.props=b,s.__P=e,s.__e=!1,M=u.__r,me=0,f)s.state=s.__s,s.__d=!1,M&&M(n),p=s.render(s.props,s.state,s.context),E.push.apply(s.__h,s._sb),s._sb=[];else do s.__d=!1,M&&M(n),p=s.render(s.props,s.state,s.context),s.state=s.__s;while(s.__d&&++me<25);s.state=s.__s,s.getChildContext!=null&&(l=w(w({},l),s.getChildContext())),f&&!m&&s.getSnapshotBeforeUpdate!=null&&(g=s.getSnapshotBeforeUpdate(d,v)),j=p!=null&&p.type===U&&p.key==null?he(p.props.children):p,a=oe(e,A(j)?j:[j],n,t,l,o,i,c,a,h,_),s.base=n.__e,n.__u&=-161,s.__h.length&&c.push(s),y&&(s.__E=s.__=null)}catch(L){if(n.__v=null,h||i!=null)if(L.then){for(n.__u|=h?160:128;a&&a.nodeType==8&&a.nextSibling;)a=a.nextSibling;i[i.indexOf(a)]=null,n.__e=a}else{for(Y=i.length;Y--;)V(i[Y]);K(n)}else n.__e=t.__e,n.__k=t.__k,L.then||K(n);u.__e(L,n,t)}else i==null&&n.__v==t.__v?(n.__k=t.__k,n.__e=t.__e):a=n.__e=Ce(t.__e,n,t,l,o,i,c,h,_);return(p=u.diffed)&&p(n),128&n.__u?void 0:a}function K(e){e&&(e.__c&&(e.__c.__e=!0),e.__k&&e.__k.some(K))}function de(e,n,t){for(var l=0;l<t.length;l++)Q(t[l],t[++l],t[++l]);u.__c&&u.__c(n,e),e.some(function(o){try{e=o.__h,o.__h=[],e.some(function(i){i.call(o)})}catch(i){u.__e(i,o.__v)}})}function he(e){return typeof e!="object"||e==null||e.__b>0?e:A(e)?e.map(he):w({},e)}function Ce(e,n,t,l,o,i,c,a,h){var _,p,s,m,d,v,g,y=t.props||$,b=n.props,f=n.type;if(f=="svg"?o="http://www.w3.org/2000/svg":f=="math"?o="http://www.w3.org/1998/Math/MathML":o||(o="http://www.w3.org/1999/xhtml"),i!=null){for(_=0;_<i.length;_++)if((d=i[_])&&"setAttribute"in d==!!f&&(f?d.localName==f:d.nodeType==3)){e=d,i[_]=null;break}}if(e==null){if(f==null)return document.createTextNode(b);e=document.createElementNS(o,f,b.is&&b),a&&(u.__m&&u.__m(n,i),a=!1),i=null}if(f==null)y===b||a&&e.data==b||(e.data=b);else{if(i=i&&I.call(e.childNodes),!a&&i!=null)for(y={},_=0;_<e.attributes.length;_++)y[(d=e.attributes[_]).name]=d.value;for(_ in y)d=y[_],_=="dangerouslySetInnerHTML"?s=d:_=="children"||_ in b||_=="value"&&"defaultValue"in b||_=="checked"&&"defaultChecked"in b||R(e,_,null,d,o);for(_ in b)d=b[_],_=="children"?m=d:_=="dangerouslySetInnerHTML"?p=d:_=="value"?v=d:_=="checked"?g=d:a&&typeof d!="function"||y[_]===d||R(e,_,d,y[_],o);if(p)a||s&&(p.__html==s.__html||p.__html==e.innerHTML)||(e.innerHTML=p.__html),n.__k=[];else if(s&&(e.innerHTML=""),oe(n.type=="template"?e.content:e,A(m)?m:[m],n,t,l,f=="foreignObject"?"http://www.w3.org/1999/xhtml":o,i,c,i?i[0]:t.__k&&P(t,0),a,h),i!=null)for(_=i.length;_--;)V(i[_]);a||(_="value",f=="progress"&&v==null?e.removeAttribute("value"):v!=null&&(v!==e[_]||f=="progress"&&!v||f=="option"&&v!=y[_])&&R(e,_,v,y[_],o),_="checked",g!=null&&g!=e[_]&&R(e,_,g,y[_],o))}return e}function Q(e,n,t){try{if(typeof e=="function"){var l=typeof e.__u=="function";l&&e.__u(),l&&n==null||(e.__u=e(n))}else e.current=n}catch(o){u.__e(o,t)}}function pe(e,n,t){var l,o;if(u.unmount&&u.unmount(e),(l=e.ref)&&(l.current&&l.current!=e.__e||Q(l,null,n)),(l=e.__c)!=null){if(l.componentWillUnmount)try{l.componentWillUnmount()}catch(i){u.__e(i,n)}l.base=l.__P=null}if(l=e.__k)for(o=0;o<l.length;o++)l[o]&&pe(l[o],n,t||typeof e.type!="function");t||V(e.__e),e.__c=e.__=e.__e=void 0}function Te(e,n,t){return this.constructor(e,t)}function Se(e,n,t){var l,o,i,c;n==document&&(n=document.documentElement),u.__&&u.__(e,n),o=(l=!1)?null:n.__k,i=[],c=[],J(n,e=n.__k=ye(U,null,[e]),o||$,$,n.namespaceURI,o?null:n.firstChild?I.call(n.childNodes):null,i,o?o.__e:n.firstChild,l,c),de(i,e,c)}I=E.slice,u={__e:function(e,n,t,l){for(var o,i,c;n=n.__;)if((o=n.__c)&&!o.__)try{if((i=o.constructor)&&i.getDerivedStateFromError!=null&&(o.setState(i.getDerivedStateFromError(e)),c=o.__d),o.componentDidCatch!=null&&(o.componentDidCatch(e,l||{}),c=o.__d),c)return o.__E=o}catch(a){e=a}throw e}},ee=0,W.prototype.setState=function(e,n){var t;t=this.__s!=null&&this.__s!=this.state?this.__s:this.__s=w({},this.state),typeof e=="function"&&(e=e(w({},t),this.props)),e&&w(t,e),e!=null&&this.__v&&(n&&this._sb.push(n),le(this))},W.prototype.forceUpdate=function(e){this.__v&&(this.__e=!0,e&&this.__h.push(e),le(this))},W.prototype.render=U,T=[],te=typeof Promise=="function"?Promise.prototype.then.bind(Promise.resolve()):setTimeout,re=function(e,n){return e.__v.__b-n.__v.__b},H.__r=0,z=Math.random().toString(8),N="__d"+z,B="__a"+z,ie=/(PointerCapture)$|Capture$/i,Z=0,q=ae(!1),G=ae(!0);var xe=0;function r(e,n,t,l,o,i){n||(n={});var c,a,h=n;if("ref"in h)for(a in h={},n)a=="ref"?c=n[a]:h[a]=n[a];var _={type:e,props:h,key:t,ref:c,__k:null,__:null,__b:0,__e:null,__c:null,constructor:void 0,__v:--xe,__i:-1,__u:0,__source:o,__self:i};if(typeof e=="function"&&(c=e.defaultProps))for(a in c)h[a]===void 0&&(h[a]=c[a]);return u.vnode&&u.vnode(_),_}function D(){return window.openai??{}}function Pe({data:e}){return e.stations.length?r("div",{children:[r("header",{class:"sbb-header",children:[r("h2",{class:"sbb-header__title",children:['Stations matching "',e.query,'"']}),r("span",{class:"sbb-header__meta",children:[e.stations.length," result",e.stations.length===1?"":"s"]})]}),r("div",{class:"sbb-list",children:e.stations.map(n=>r("div",{class:"sbb-connection",children:r("div",{children:[r("div",{style:{fontWeight:600},children:n.name}),r("div",{class:"sbb-connection__meta",children:[r("span",{class:"sbb-badge",children:["ID ",n.id]}),typeof n.lat=="number"&&typeof n.lon=="number"&&r("span",{children:[n.lat.toFixed(3),", ",n.lon.toFixed(3)]})]})]})},n.id))})]}):r("div",{class:"sbb-empty",children:['No stations matched "',e.query,'".']})}function C(e){try{return new Date(e).toLocaleTimeString("de-CH",{hour:"2-digit",minute:"2-digit",timeZone:"Europe/Zurich"})}catch{return e}}function X(e){try{return new Date(e).toLocaleDateString("en-CH",{weekday:"short",day:"2-digit",month:"short",timeZone:"Europe/Zurich"})}catch{return e}}function O(e){if(!Number.isFinite(e)||e<0)return"—";const n=Math.floor(e/60),t=e%60;return n===0?`${t}m`:t===0?`${n}h`:`${n}h ${t}m`}function ue(e,n="CHF"){return`${n} ${e.toFixed(2)}`}function Le({legs:e}){const n=e.filter(t=>t.type==="train");return n.length===0?null:r("span",{class:"sbb-connection__route",children:n.map((t,l)=>r("span",{children:[l>0&&r("span",{style:{color:"var(--text-muted)",margin:"0 2px"},children:"›"}),r("span",{class:"sbb-badge",children:[t.line??"Train",t.platform?` · Pl. ${t.platform}`:""]})]},l))})}function Be({c:e,onPrice:n}){return r("div",{class:"sbb-connection",children:[r("div",{children:[r("div",{class:"sbb-connection__times",children:[r("span",{class:"sbb-connection__time",children:C(e.departureTime)}),r("span",{class:"sbb-connection__arrow",children:"→"}),r("span",{class:"sbb-connection__time",children:C(e.arrivalTime)})]}),r("div",{class:"sbb-connection__meta",children:[r("span",{class:"sbb-badge",children:O(e.durationMinutes)}),r("span",{class:"sbb-badge",children:[e.transfers," transfer",e.transfers===1?"":"s"]}),r(Le,{legs:e.legs})]})]}),r("div",{class:"sbb-connection__actions",children:r("button",{type:"button",class:"sbb-button",onClick:n,children:"Price"})})]})}function De({data:e,theme:n}){const t=D(),l=c=>{t.callTool?.("get_prices",{trip_ids:[c]})},o=c=>{t.callTool?.("get_more_connections",{collection_id:e.collectionId,direction:c})},i=()=>{const c=e.connections.slice(0,5).map(a=>a.tripId);c.length&&t.callTool?.("get_prices",{trip_ids:c})};return e.connections.length?r("div",{children:[r("header",{class:"sbb-header",children:[r("h2",{class:"sbb-header__title",children:[e.origin.name," → ",e.destination.name]}),r("span",{class:"sbb-header__meta",children:X(e.date)})]}),r("div",{class:"sbb-list",children:e.connections.map(c=>r(Be,{c,onPrice:()=>l(c.tripId)},c.tripId))}),e.weather?.summary&&r("div",{class:"sbb-weather",children:["☁ ",e.destination.name,": ",e.weather.summary]}),r("div",{class:"sbb-footer",children:[r("button",{type:"button",class:"sbb-button",onClick:()=>o("previous"),children:"← Earlier"}),r("button",{type:"button",class:"sbb-button",onClick:()=>o("next"),children:"Later →"}),r("button",{type:"button",class:"sbb-button sbb-button--primary",onClick:i,children:"See all prices"})]})]}):r("div",{class:"sbb-empty",children:"No connections found."})}function Me({leg:e,index:n}){return e.type==="walk"?r("div",{class:"sbb-card",style:{background:"var(--bg)"},children:r("div",{style:{fontWeight:600},children:["Transfer · walk ",O(e.durationMinutes)]})}):r("div",{class:"sbb-card",children:[r("div",{style:{display:"flex",alignItems:"baseline",justifyContent:"space-between",gap:8},children:[r("div",{children:[r("span",{class:"sbb-badge sbb-badge--accent",children:["Leg ",n+1]}),r("span",{style:{marginLeft:8,fontWeight:600},children:[e.line??"Train",e.operator?r("span",{class:"sbb-header__meta",children:[" · ",e.operator]}):null]})]}),r("span",{class:"sbb-header__meta",children:O(e.durationMinutes)})]}),r("div",{class:"sbb-timeline",children:[e.from&&r("div",{class:"sbb-timeline__stop",children:[r("span",{children:[r("strong",{children:e.from.name}),e.from.platform?r("span",{class:"sbb-header__meta",children:[" · Pl. ",e.from.platform]}):null]}),r("span",{class:"sbb-timeline__time",children:C(e.from.time)})]}),e.intermediateStops?.map((t,l)=>r("div",{class:"sbb-timeline__stop sbb-timeline__stop--intermediate",children:[r("span",{children:t.name}),r("span",{class:"sbb-timeline__time",children:t.arrivalTime?C(t.arrivalTime):""})]},l)),e.to&&r("div",{class:"sbb-timeline__stop",children:[r("span",{children:[r("strong",{children:e.to.name}),e.to.platform?r("span",{class:"sbb-header__meta",children:[" · Pl. ",e.to.platform]}):null]}),r("span",{class:"sbb-timeline__time",children:C(e.to.time)})]})]}),e.occupancy&&r("div",{class:"sbb-connection__meta",children:[e.occupancy.firstClass&&r("span",{class:"sbb-badge",children:["1st: ",e.occupancy.firstClass]}),e.occupancy.secondClass&&r("span",{class:"sbb-badge",children:["2nd: ",e.occupancy.secondClass]})]})]})}function Ie({data:e}){const n=D();return r("div",{children:[r("header",{class:"sbb-header",children:[r("h2",{class:"sbb-header__title",children:[e.origin.name," → ",e.destination.name]}),r("span",{class:"sbb-header__meta",children:X(e.departureTime)})]}),r("div",{class:"sbb-card",style:{marginBottom:"var(--gap)"},children:r("div",{style:{display:"flex",justifyContent:"space-between"},children:[r("div",{class:"sbb-connection__times",children:[r("span",{class:"sbb-connection__time",children:C(e.departureTime)}),r("span",{class:"sbb-connection__arrow",children:"→"}),r("span",{class:"sbb-connection__time",children:C(e.arrivalTime)})]}),r("div",{class:"sbb-connection__meta",children:[r("span",{class:"sbb-badge",children:O(e.durationMinutes)}),r("span",{class:"sbb-badge",children:[e.transfers," transfer",e.transfers===1?"":"s"]}),r("span",{class:"sbb-badge",children:e.status})]})]})}),r("div",{class:"sbb-list",children:e.legs.map((t,l)=>r(Me,{leg:t,index:l},l))}),r("div",{class:"sbb-footer",children:r("button",{type:"button",class:"sbb-button sbb-button--primary",onClick:()=>n.callTool?.("get_prices",{trip_ids:[e.tripId]}),children:"See price"})})]})}function Ne({data:e}){return e.prices.length?r("div",{children:[r("header",{class:"sbb-header",children:[r("h2",{class:"sbb-header__title",children:"Ticket prices"}),r("span",{class:"sbb-header__meta",children:[e.prices.length," trip",e.prices.length===1?"":"s"]})]}),r("div",{class:"sbb-card",children:r("table",{class:"sbb-table",children:[r("thead",{children:r("tr",{children:[r("th",{children:"Trip"}),r("th",{children:"2nd class"}),r("th",{children:"1st class"})]})}),r("tbody",{children:e.prices.map(n=>r("tr",{children:[r("td",{style:{fontFamily:"ui-monospace, monospace",fontSize:11},children:[n.tripId.slice(0,12),"…"]}),r("td",{children:n.secondClass?ue(n.secondClass.amount,n.secondClass.currency):"—"}),r("td",{children:n.firstClass?ue(n.firstClass.amount,n.firstClass.currency):"—"})]},n.tripId))})]})}),r("div",{class:"sbb-header__meta",style:{marginTop:8},children:"Prices are estimates. Ask for the ticket link to see the final price on SBB.ch."})]}):r("div",{class:"sbb-empty",children:"No price information available."})}function be(e){return`https://swisstrip.app/go?url=${encodeURIComponent(e)}`}function $e({data:e}){const n=e.affiliateLink??e.primaryLink;return r("div",{class:"sbb-ticket-card",children:[r("header",{class:"sbb-header",children:[r("h2",{class:"sbb-header__title",children:"Buy ticket on SBB"}),r("span",{class:"sbb-header__meta",children:X(e.departureTime)})]}),r("div",{children:[r("div",{class:"sbb-ticket-card__route",children:[e.origin.name," → ",e.destination.name]}),r("div",{class:"sbb-ticket-card__times",children:[C(e.departureTime)," – ",C(e.arrivalTime)]})]}),r("div",{style:{display:"flex",gap:8,flexWrap:"wrap"},children:[r("a",{class:"sbb-button sbb-button--primary",href:be(n),target:"_blank",rel:"noopener noreferrer",children:"Buy on SBB.ch →"}),e.affiliateLink&&e.affiliateLink!==e.primaryLink&&r("a",{class:"sbb-button",href:be(e.primaryLink),target:"_blank",rel:"noopener noreferrer",children:"Direct SBB link"})]}),r("div",{class:"sbb-header__meta",style:{fontSize:11},children:"Opens SBB.ch with this connection pre-filled. On mobile, the SBB app opens directly with your Halbtax/GA applied."})]})}function Ee(){const n=document.getElementById("sbb-widget-root")?.getAttribute("data-widget");if(n)return n;const l=D().toolName;return l?{search_stations:"stations-list",search_connections:"connection-list",get_more_connections:"connection-list",get_trip_details:"trip-details",get_prices:"prices-table",get_ticket_link:"ticket-card"}[l]??null:null}function Ae(){const e=Ee(),n=D(),t=n.toolOutput?.structuredContent,l=n.theme==="dark"?"dark":"light";if(!e)return r("div",{class:"sbb-empty",children:"Widget not initialised."});if(!t)return r("div",{class:"sbb-empty",children:"Loading…"});switch(e){case"stations-list":return r(Pe,{data:t});case"connection-list":return r(De,{data:t,theme:l});case"trip-details":return r(Ie,{data:t});case"prices-table":return r(Ne,{data:t});case"ticket-card":return r($e,{data:t})}}function fe(){const e=document.getElementById("sbb-widget-root");if(!e){console.warn("[sbb-widgets] #sbb-widget-root not found");return}const n=D().theme==="dark"?"dark":"light";e.classList.add("sbb-root"),e.setAttribute("data-theme",n),Se(r(Ae,{}),e)}document.readyState==="loading"?document.addEventListener("DOMContentLoaded",fe):fe()})();
|