sbb-mcp 0.4.2 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +50 -57
- package/README.md +26 -296
- package/dist/index.js +47 -17
- package/package.json +10 -29
- package/dist/auth.d.ts +0 -2
- package/dist/auth.js +0 -44
- package/dist/auth.js.map +0 -1
- package/dist/cache.d.ts +0 -12
- package/dist/cache.js +0 -58
- package/dist/cache.js.map +0 -1
- package/dist/client.d.ts +0 -17
- package/dist/client.js +0 -70
- package/dist/client.js.map +0 -1
- package/dist/formatters.d.ts +0 -22
- package/dist/formatters.js +0 -210
- package/dist/formatters.js.map +0 -1
- package/dist/http.d.ts +0 -2
- package/dist/http.js +0 -61
- package/dist/http.js.map +0 -1
- package/dist/i18n.d.ts +0 -22
- package/dist/i18n.js +0 -36
- package/dist/i18n.js.map +0 -1
- package/dist/index.d.ts +0 -2
- package/dist/index.js.map +0 -1
- package/dist/journey.d.ts +0 -5
- package/dist/journey.js +0 -67
- package/dist/journey.js.map +0 -1
- package/dist/prices.d.ts +0 -3
- package/dist/prices.js +0 -51
- package/dist/prices.js.map +0 -1
- package/dist/profile.d.ts +0 -16
- package/dist/profile.js +0 -77
- package/dist/profile.js.map +0 -1
- package/dist/rate-limit.d.ts +0 -5
- package/dist/rate-limit.js +0 -44
- package/dist/rate-limit.js.map +0 -1
- package/dist/structured.d.ts +0 -119
- package/dist/structured.js +0 -133
- package/dist/structured.js.map +0 -1
- package/dist/swisstrip.d.ts +0 -41
- package/dist/swisstrip.js +0 -119
- package/dist/swisstrip.js.map +0 -1
- package/dist/tools.d.ts +0 -2
- package/dist/tools.js +0 -464
- package/dist/tools.js.map +0 -1
- package/dist/transport/index.d.ts +0 -9
- package/dist/transport/index.js +0 -9
- package/dist/transport/index.js.map +0 -1
- package/dist/transport/smapi-auth.d.ts +0 -2
- package/dist/transport/smapi-auth.js +0 -39
- package/dist/transport/smapi-auth.js.map +0 -1
- package/dist/transport/smapi-client.d.ts +0 -22
- package/dist/transport/smapi-client.js +0 -83
- package/dist/transport/smapi-client.js.map +0 -1
- package/dist/transport/smapi-journey.d.ts +0 -23
- package/dist/transport/smapi-journey.js +0 -82
- package/dist/transport/smapi-journey.js.map +0 -1
- package/dist/transport/smapi-mock.d.ts +0 -9
- package/dist/transport/smapi-mock.js +0 -151
- package/dist/transport/smapi-mock.js.map +0 -1
- package/dist/transport/smapi-prices.d.ts +0 -14
- package/dist/transport/smapi-prices.js +0 -73
- package/dist/transport/smapi-prices.js.map +0 -1
- package/dist/transport/smapi-types.d.ts +0 -153
- package/dist/transport/smapi-types.js +0 -2
- package/dist/transport/smapi-types.js.map +0 -1
- package/dist/types.d.ts +0 -139
- package/dist/types.js +0 -3
- package/dist/types.js.map +0 -1
- package/dist/widgets.d.ts +0 -33
- package/dist/widgets.js +0 -120
- package/dist/widgets.js.map +0 -1
- package/web/dist/widgets.css +0 -1
- package/web/dist/widgets.js +0 -1
package/dist/swisstrip.js
DELETED
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SwissTrip API client for sbb-mcp (Layer 3)
|
|
3
|
-
*
|
|
4
|
-
* When SWISSTRIP_TOKEN is set, sbb-mcp fetches traveler profiles from the
|
|
5
|
-
* SwissTrip cloud API instead of (or in addition to) the local file.
|
|
6
|
-
* This enables cloud-synced profiles and multi-traveler support (partner, kids).
|
|
7
|
-
*/
|
|
8
|
-
// ─── Config ─────────────────────────────────────────────────────────────────
|
|
9
|
-
const SWISSTRIP_TOKEN = process.env.SWISSTRIP_TOKEN;
|
|
10
|
-
const SWISSTRIP_URL = process.env.SWISSTRIP_URL || 'https://swisstrip.ch';
|
|
11
|
-
export function isSwissTripConfigured() {
|
|
12
|
-
return !!SWISSTRIP_TOKEN;
|
|
13
|
-
}
|
|
14
|
-
// ─── API calls ──────────────────────────────────────────────────────────────
|
|
15
|
-
async function fetchSwissTrip(path) {
|
|
16
|
-
const url = `${SWISSTRIP_URL}${path}`;
|
|
17
|
-
const res = await fetch(url, {
|
|
18
|
-
headers: {
|
|
19
|
-
'Authorization': `Bearer ${SWISSTRIP_TOKEN}`,
|
|
20
|
-
'Accept': 'application/json',
|
|
21
|
-
},
|
|
22
|
-
});
|
|
23
|
-
if (!res.ok) {
|
|
24
|
-
const body = await res.text().catch(() => '');
|
|
25
|
-
throw new Error(`SwissTrip API error: ${res.status} ${res.statusText}${body ? ` — ${body}` : ''}`);
|
|
26
|
-
}
|
|
27
|
-
return res.json();
|
|
28
|
-
}
|
|
29
|
-
export async function fetchProfile() {
|
|
30
|
-
return fetchSwissTrip('/api/mcp/profile');
|
|
31
|
-
}
|
|
32
|
-
export async function fetchTravelers() {
|
|
33
|
-
return fetchSwissTrip('/api/travelers');
|
|
34
|
-
}
|
|
35
|
-
// ─── Conversion helpers ─────────────────────────────────────────────────────
|
|
36
|
-
function parseReductionCard(card) {
|
|
37
|
-
if (!card)
|
|
38
|
-
return 'NONE';
|
|
39
|
-
const upper = card.toUpperCase();
|
|
40
|
-
if (upper === 'HALF_FARE' || upper === 'HALBTAX')
|
|
41
|
-
return 'HALF_FARE';
|
|
42
|
-
if (upper === 'GA')
|
|
43
|
-
return 'GA';
|
|
44
|
-
return 'NONE';
|
|
45
|
-
}
|
|
46
|
-
function isChild(dob) {
|
|
47
|
-
if (!dob)
|
|
48
|
-
return false;
|
|
49
|
-
const birth = new Date(dob);
|
|
50
|
-
const age = (Date.now() - birth.getTime()) / (365.25 * 24 * 60 * 60 * 1000);
|
|
51
|
-
return age < 16;
|
|
52
|
-
}
|
|
53
|
-
/** Convert a SwissTrip traveler to an SMAPI traveler for pricing/offers */
|
|
54
|
-
export function toSmapiTraveler(t, index) {
|
|
55
|
-
return {
|
|
56
|
-
id: `traveler-${index + 1}`,
|
|
57
|
-
type: isChild(t.date_of_birth) ? 'CHILD' : 'ADULT',
|
|
58
|
-
...(t.date_of_birth && { dateOfBirth: t.date_of_birth }),
|
|
59
|
-
reductionCard: parseReductionCard(t.reduction_card),
|
|
60
|
-
...(t.first_name && { firstName: t.first_name.slice(0, 30) }),
|
|
61
|
-
...(t.last_name && { lastName: t.last_name.slice(0, 30) }),
|
|
62
|
-
};
|
|
63
|
-
}
|
|
64
|
-
/** Convert the primary profile (from /api/mcp/profile) to an SMAPI traveler */
|
|
65
|
-
export function profileToSmapiTraveler(p) {
|
|
66
|
-
return {
|
|
67
|
-
id: 'traveler-1',
|
|
68
|
-
type: isChild(p.travel_date_of_birth) ? 'CHILD' : 'ADULT',
|
|
69
|
-
...(p.travel_date_of_birth && { dateOfBirth: p.travel_date_of_birth }),
|
|
70
|
-
reductionCard: parseReductionCard(p.travel_reduction_card),
|
|
71
|
-
...(p.travel_first_name && { firstName: p.travel_first_name.slice(0, 30) }),
|
|
72
|
-
...(p.travel_last_name && { lastName: p.travel_last_name.slice(0, 30) }),
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
// ─── Formatting ─────────────────────────────────────────────────────────────
|
|
76
|
-
export function formatTravelersList(travelers) {
|
|
77
|
-
if (travelers.length === 0) {
|
|
78
|
-
return 'No travelers found in your SwissTrip account. Add travelers at swisstrip.ch/settings.';
|
|
79
|
-
}
|
|
80
|
-
const lines = [`**Your Travelers** (${travelers.length})`, ''];
|
|
81
|
-
for (const t of travelers) {
|
|
82
|
-
const name = [t.first_name, t.last_name].filter(Boolean).join(' ') || 'Unnamed';
|
|
83
|
-
const label = t.label ? ` (${t.label})` : '';
|
|
84
|
-
const primary = t.is_primary ? ' ★' : '';
|
|
85
|
-
const card = parseReductionCard(t.reduction_card);
|
|
86
|
-
const cardStr = card === 'HALF_FARE' ? 'Halbtax' : card === 'GA' ? 'GA' : 'No card';
|
|
87
|
-
const type = isChild(t.date_of_birth) ? 'Child' : 'Adult';
|
|
88
|
-
lines.push(`- **${name}**${label}${primary} — ${type}, ${cardStr}`);
|
|
89
|
-
}
|
|
90
|
-
lines.push('');
|
|
91
|
-
lines.push('★ = primary traveler. Use traveler names with `get_prices` for family pricing.');
|
|
92
|
-
return lines.join('\n');
|
|
93
|
-
}
|
|
94
|
-
export function formatCloudProfile(profile) {
|
|
95
|
-
const lines = ['**Your Travel Profile** (synced from SwissTrip)', ''];
|
|
96
|
-
const name = [profile.travel_first_name, profile.travel_last_name].filter(Boolean).join(' ');
|
|
97
|
-
if (name)
|
|
98
|
-
lines.push(`Name: ${name}`);
|
|
99
|
-
if (profile.travel_date_of_birth)
|
|
100
|
-
lines.push(`Date of birth: ${profile.travel_date_of_birth}`);
|
|
101
|
-
const card = parseReductionCard(profile.travel_reduction_card);
|
|
102
|
-
if (card !== 'NONE') {
|
|
103
|
-
const cardName = card === 'HALF_FARE' ? 'Halbtax (Half-Fare)' : 'GA Travelcard';
|
|
104
|
-
let cardLine = `Reduction card: ${cardName}`;
|
|
105
|
-
if (profile.travel_reduction_card_valid_until) {
|
|
106
|
-
cardLine += ` (valid until ${profile.travel_reduction_card_valid_until})`;
|
|
107
|
-
}
|
|
108
|
-
lines.push(cardLine);
|
|
109
|
-
}
|
|
110
|
-
else {
|
|
111
|
-
lines.push('Reduction card: None');
|
|
112
|
-
}
|
|
113
|
-
if (profile.locale)
|
|
114
|
-
lines.push(`Locale: ${profile.locale}`);
|
|
115
|
-
lines.push('');
|
|
116
|
-
lines.push('*Profile managed at swisstrip.ch/settings.*');
|
|
117
|
-
return lines.join('\n');
|
|
118
|
-
}
|
|
119
|
-
//# sourceMappingURL=swisstrip.js.map
|
package/dist/swisstrip.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"swisstrip.js","sourceRoot":"","sources":["../src/swisstrip.ts"],"names":[],"mappings":"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"}
|
package/dist/tools.d.ts
DELETED
package/dist/tools.js
DELETED
|
@@ -1,464 +0,0 @@
|
|
|
1
|
-
import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import { z } from 'zod';
|
|
3
|
-
import { isSmapiConfigured, searchPlaces, searchTrips, getTrip, paginateTrips, getTripPrices, getTripOffers, mockSearchPlaces, mockSearchTrips, mockGetTripPrices, } from './transport/index.js';
|
|
4
|
-
import { formatStations, formatConnections, formatTripDetails, formatPrices, formatTicketLink, buildSbbDeepLink, } from './formatters.js';
|
|
5
|
-
import { cacheGet, cacheSet, TTL } from './cache.js';
|
|
6
|
-
import { SmapiError } from './transport/smapi-client.js';
|
|
7
|
-
import { loadProfile, saveProfile, formatProfileSummary, isReductionCardExpired } from './profile.js';
|
|
8
|
-
import { isSwissTripConfigured, fetchProfile as fetchCloudProfile, fetchTravelers, toSmapiTraveler, formatTravelersList, formatCloudProfile, } from './swisstrip.js';
|
|
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';
|
|
12
|
-
const useMock = !isSmapiConfigured();
|
|
13
|
-
const useCloud = isSwissTripConfigured();
|
|
14
|
-
/** Match SwissTrip travelers by first name (case-insensitive, fuzzy) */
|
|
15
|
-
function matchTravelersByName(all, names) {
|
|
16
|
-
const matched = [];
|
|
17
|
-
for (const name of names) {
|
|
18
|
-
const lower = name.toLowerCase();
|
|
19
|
-
const found = all.find(t => t.first_name?.toLowerCase() === lower ||
|
|
20
|
-
t.label?.toLowerCase() === lower) || all.find(t => t.first_name?.toLowerCase().startsWith(lower) ||
|
|
21
|
-
t.last_name?.toLowerCase() === lower);
|
|
22
|
-
if (found && !matched.includes(found)) {
|
|
23
|
-
matched.push(found);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
return matched;
|
|
27
|
-
}
|
|
28
|
-
function errorResult(err) {
|
|
29
|
-
if (err instanceof SmapiError) {
|
|
30
|
-
const msgs = err.displayMessages;
|
|
31
|
-
const detail = msgs.length ? msgs.join('. ') : err.message;
|
|
32
|
-
return { content: [{ type: 'text', text: `Error: ${detail} (HTTP ${err.status})` }], isError: true };
|
|
33
|
-
}
|
|
34
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
35
|
-
return { content: [{ type: 'text', text: `Error: ${message}` }], isError: true };
|
|
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
|
-
}
|
|
47
|
-
export function createSbbMcpServer() {
|
|
48
|
-
const server = new McpServer({
|
|
49
|
-
name: 'sbb-mcp',
|
|
50
|
-
version: '0.4.2',
|
|
51
|
-
description: 'Swiss Federal Railways (SBB/CFF/FFS) — real-time train schedules, prices, and ticket purchase links for Switzerland',
|
|
52
|
-
});
|
|
53
|
-
// ─── Widget resources (ChatGPT Apps SDK) ───────────────────────────────
|
|
54
|
-
registerWidgets(server);
|
|
55
|
-
// ─── Prompts ───────────────────────────────────────────────────────────
|
|
56
|
-
server.prompt('plan_journey', 'Plan a train journey in Switzerland — finds connections, compares prices, and provides ticket links', {
|
|
57
|
-
from: z.string().describe('Origin station (e.g. "Zurich")'),
|
|
58
|
-
to: z.string().describe('Destination station (e.g. "Bern")'),
|
|
59
|
-
date: z.string().optional().describe('Travel date YYYY-MM-DD'),
|
|
60
|
-
}, async ({ from, to, date }) => ({
|
|
61
|
-
messages: [{
|
|
62
|
-
role: 'user',
|
|
63
|
-
content: {
|
|
64
|
-
type: 'text',
|
|
65
|
-
text: `Plan a train journey from ${from} to ${to}${date ? ` on ${date}` : ' today'}. Search for connections, get prices with Half-Fare card, and provide a ticket purchase link for the best option.`,
|
|
66
|
-
},
|
|
67
|
-
}],
|
|
68
|
-
}));
|
|
69
|
-
// ─── Resource: user profile ────────────────────────────────────────────
|
|
70
|
-
server.resource('profile', 'sbb://profile', {
|
|
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.',
|
|
72
|
-
mimeType: 'text/plain',
|
|
73
|
-
}, async () => {
|
|
74
|
-
if (useCloud) {
|
|
75
|
-
try {
|
|
76
|
-
const cloudProfile = await fetchCloudProfile();
|
|
77
|
-
return {
|
|
78
|
-
contents: [{
|
|
79
|
-
uri: 'sbb://profile',
|
|
80
|
-
mimeType: 'text/plain',
|
|
81
|
-
text: formatCloudProfile(cloudProfile),
|
|
82
|
-
}],
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
|
-
catch {
|
|
86
|
-
// Fall through
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
const profile = loadProfile();
|
|
90
|
-
if (!profile) {
|
|
91
|
-
return {
|
|
92
|
-
contents: [{
|
|
93
|
-
uri: 'sbb://profile',
|
|
94
|
-
mimeType: 'text/plain',
|
|
95
|
-
text: 'No travel profile saved yet. Ask the user: "Do you have a Halbtax or GA travelcard?" and their name/date of birth. Then use save_profile to store it.',
|
|
96
|
-
}],
|
|
97
|
-
};
|
|
98
|
-
}
|
|
99
|
-
const expired = isReductionCardExpired(profile);
|
|
100
|
-
let text = formatProfileSummary(profile);
|
|
101
|
-
if (expired) {
|
|
102
|
-
text += '\n\n**Action needed:** Reduction card was confirmed over 1 year ago. Ask the user if they still have it.';
|
|
103
|
-
}
|
|
104
|
-
return {
|
|
105
|
-
contents: [{
|
|
106
|
-
uri: 'sbb://profile',
|
|
107
|
-
mimeType: 'text/plain',
|
|
108
|
-
text,
|
|
109
|
-
}],
|
|
110
|
-
};
|
|
111
|
-
});
|
|
112
|
-
// ─── Tool: save_profile ──────────────────────────────────────────────
|
|
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 }) => {
|
|
125
|
-
try {
|
|
126
|
-
const updates = {};
|
|
127
|
-
if (first_name)
|
|
128
|
-
updates.first_name = first_name;
|
|
129
|
-
if (last_name)
|
|
130
|
-
updates.last_name = last_name;
|
|
131
|
-
if (date_of_birth)
|
|
132
|
-
updates.date_of_birth = date_of_birth;
|
|
133
|
-
if (reduction_card)
|
|
134
|
-
updates.reduction_card = reduction_card;
|
|
135
|
-
if (reduction_card_valid_until)
|
|
136
|
-
updates.reduction_card_valid_until = reduction_card_valid_until;
|
|
137
|
-
saveProfile(updates);
|
|
138
|
-
const profile = loadProfile();
|
|
139
|
-
return { content: [{ type: 'text', text: formatProfileSummary(profile) }] };
|
|
140
|
-
}
|
|
141
|
-
catch (err) {
|
|
142
|
-
return errorResult(err);
|
|
143
|
-
}
|
|
144
|
-
});
|
|
145
|
-
// ─── Tool: get_profile ───────────────────────────────────────────────
|
|
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 () => {
|
|
152
|
-
if (useCloud) {
|
|
153
|
-
try {
|
|
154
|
-
const cloudProfile = await fetchCloudProfile();
|
|
155
|
-
return { content: [{ type: 'text', text: formatCloudProfile(cloudProfile) }] };
|
|
156
|
-
}
|
|
157
|
-
catch {
|
|
158
|
-
// Fall through
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
const profile = loadProfile();
|
|
162
|
-
if (!profile) {
|
|
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.' }] };
|
|
164
|
-
}
|
|
165
|
-
return { content: [{ type: 'text', text: formatProfileSummary(profile) }] };
|
|
166
|
-
});
|
|
167
|
-
// ─── Tool: list_travelers (SwissTrip cloud only) ─────────────────────
|
|
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 () => {
|
|
174
|
-
if (!useCloud) {
|
|
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.' }] };
|
|
176
|
-
}
|
|
177
|
-
try {
|
|
178
|
-
const cacheKey = 'swisstrip:travelers';
|
|
179
|
-
const cached = cacheGet(cacheKey);
|
|
180
|
-
if (cached)
|
|
181
|
-
return { content: [{ type: 'text', text: cached }] };
|
|
182
|
-
const travelers = await fetchTravelers();
|
|
183
|
-
const text = formatTravelersList(travelers);
|
|
184
|
-
cacheSet(cacheKey, text, TTL.STATIONS);
|
|
185
|
-
return { content: [{ type: 'text', text }] };
|
|
186
|
-
}
|
|
187
|
-
catch (err) {
|
|
188
|
-
return errorResult(err);
|
|
189
|
-
}
|
|
190
|
-
});
|
|
191
|
-
// ─── Tool 1: search_stations ──────────────────────────────────────────
|
|
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 }) => {
|
|
202
|
-
try {
|
|
203
|
-
const stations = useMock
|
|
204
|
-
? await mockSearchPlaces({ name: query })
|
|
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
|
-
};
|
|
211
|
-
}
|
|
212
|
-
catch (err) {
|
|
213
|
-
return errorResult(err);
|
|
214
|
-
}
|
|
215
|
-
});
|
|
216
|
-
// ─── Tool 2: search_connections ───────────────────────────────────────
|
|
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 }) => {
|
|
230
|
-
try {
|
|
231
|
-
let fromId = from;
|
|
232
|
-
let toId = to;
|
|
233
|
-
if (!/^\d{5,8}$/.test(from)) {
|
|
234
|
-
const stations = useMock
|
|
235
|
-
? await mockSearchPlaces({ name: from })
|
|
236
|
-
: await searchPlaces({ name: from, type: 'STOP', numberOfResults: 1 });
|
|
237
|
-
if (stations.length === 0) {
|
|
238
|
-
return { content: [{ type: 'text', text: `No station found matching "${from}". Try a different name.` }] };
|
|
239
|
-
}
|
|
240
|
-
fromId = stations[0].id;
|
|
241
|
-
}
|
|
242
|
-
if (!/^\d{5,8}$/.test(to)) {
|
|
243
|
-
const stations = useMock
|
|
244
|
-
? await mockSearchPlaces({ name: to })
|
|
245
|
-
: await searchPlaces({ name: to, type: 'STOP', numberOfResults: 1 });
|
|
246
|
-
if (stations.length === 0) {
|
|
247
|
-
return { content: [{ type: 'text', text: `No station found matching "${to}". Try a different name.` }] };
|
|
248
|
-
}
|
|
249
|
-
toId = stations[0].id;
|
|
250
|
-
}
|
|
251
|
-
let departureTime;
|
|
252
|
-
let arrivalTime;
|
|
253
|
-
if (date || time) {
|
|
254
|
-
const d = date || new Date().toISOString().split('T')[0];
|
|
255
|
-
const t = time || '08:00';
|
|
256
|
-
const dt = zurichIso(d, t);
|
|
257
|
-
if (arrival_time)
|
|
258
|
-
arrivalTime = dt;
|
|
259
|
-
else
|
|
260
|
-
departureTime = dt;
|
|
261
|
-
}
|
|
262
|
-
const collection = useMock
|
|
263
|
-
? await mockSearchTrips({ origin: fromId, destination: toId, departureTime })
|
|
264
|
-
: await searchTrips({
|
|
265
|
-
origin: fromId,
|
|
266
|
-
destination: toId,
|
|
267
|
-
...(departureTime && { departureTime }),
|
|
268
|
-
...(arrivalTime && { arrivalTime }),
|
|
269
|
-
});
|
|
270
|
-
let text = formatConnections(collection);
|
|
271
|
-
let weatherSummary;
|
|
272
|
-
if (collection.trips.length > 0) {
|
|
273
|
-
const dest = collection.trips[0].destination;
|
|
274
|
-
if (dest.geoPosition) {
|
|
275
|
-
const travelDate = date || new Date().toISOString().split('T')[0];
|
|
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
|
-
}
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
return {
|
|
290
|
-
content: [{ type: 'text', text }],
|
|
291
|
-
structuredContent: toConnectionListDTO(collection, weatherSummary ? { summary: weatherSummary } : undefined),
|
|
292
|
-
_meta: widgetResponseMeta(WIDGETS.CONNECTION_LIST),
|
|
293
|
-
};
|
|
294
|
-
}
|
|
295
|
-
catch (err) {
|
|
296
|
-
return errorResult(err);
|
|
297
|
-
}
|
|
298
|
-
});
|
|
299
|
-
// ─── Tool 3: get_trip_details ─────────────────────────────────────────
|
|
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 }) => {
|
|
309
|
-
try {
|
|
310
|
-
if (useMock) {
|
|
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.' }] };
|
|
312
|
-
}
|
|
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
|
-
};
|
|
319
|
-
}
|
|
320
|
-
catch (err) {
|
|
321
|
-
return errorResult(err);
|
|
322
|
-
}
|
|
323
|
-
});
|
|
324
|
-
// ─── Tool 4: get_more_connections ─────────────────────────────────────
|
|
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 }) => {
|
|
335
|
-
try {
|
|
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
|
-
};
|
|
348
|
-
}
|
|
349
|
-
catch (err) {
|
|
350
|
-
return errorResult(err);
|
|
351
|
-
}
|
|
352
|
-
});
|
|
353
|
-
// ─── Tool 5: get_prices ───────────────────────────────────────────────
|
|
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 }) => {
|
|
366
|
-
try {
|
|
367
|
-
let travelers;
|
|
368
|
-
if (traveler_names && traveler_names.length > 0 && useCloud) {
|
|
369
|
-
const allTravelers = await fetchTravelers();
|
|
370
|
-
const matched = matchTravelersByName(allTravelers, traveler_names);
|
|
371
|
-
if (matched.length === 0) {
|
|
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.` }] };
|
|
373
|
-
}
|
|
374
|
-
travelers = matched.map((t, i) => toSmapiTraveler(t, i));
|
|
375
|
-
}
|
|
376
|
-
else {
|
|
377
|
-
travelers = [{ id: 'traveler-1', type: traveler_type, reductionCard: reduction_card }];
|
|
378
|
-
}
|
|
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
|
-
};
|
|
387
|
-
}
|
|
388
|
-
catch (err) {
|
|
389
|
-
return errorResult(err);
|
|
390
|
-
}
|
|
391
|
-
});
|
|
392
|
-
// ─── Tool 6: get_ticket_link ──────────────────────────────────────────
|
|
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 }) => {
|
|
411
|
-
try {
|
|
412
|
-
const sbbLink = buildSbbDeepLink({
|
|
413
|
-
fromName: from_name,
|
|
414
|
-
fromId: from_id,
|
|
415
|
-
toName: to_name,
|
|
416
|
-
toId: to_id,
|
|
417
|
-
date,
|
|
418
|
-
time,
|
|
419
|
-
});
|
|
420
|
-
let travelers;
|
|
421
|
-
if (traveler_names && traveler_names.length > 0 && useCloud) {
|
|
422
|
-
const allTravelers = await fetchTravelers();
|
|
423
|
-
const matched = matchTravelersByName(allTravelers, traveler_names);
|
|
424
|
-
travelers = matched.length > 0
|
|
425
|
-
? matched.map((t, i) => toSmapiTraveler(t, i))
|
|
426
|
-
: [{ id: 'traveler-1', type: traveler_type, reductionCard: reduction_card }];
|
|
427
|
-
}
|
|
428
|
-
else {
|
|
429
|
-
travelers = [{ id: 'traveler-1', type: traveler_type, reductionCard: reduction_card }];
|
|
430
|
-
}
|
|
431
|
-
let affiliateLink;
|
|
432
|
-
if (!useMock) {
|
|
433
|
-
try {
|
|
434
|
-
const result = await getTripOffers(trip_id, travelers);
|
|
435
|
-
affiliateLink = result.affiliateDeepLink;
|
|
436
|
-
}
|
|
437
|
-
catch {
|
|
438
|
-
// Non-fatal
|
|
439
|
-
}
|
|
440
|
-
}
|
|
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
|
-
};
|
|
457
|
-
}
|
|
458
|
-
catch (err) {
|
|
459
|
-
return errorResult(err);
|
|
460
|
-
}
|
|
461
|
-
});
|
|
462
|
-
return server;
|
|
463
|
-
}
|
|
464
|
-
//# sourceMappingURL=tools.js.map
|
package/dist/tools.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tools.js","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export { isSmapiConfigured } from './smapi-auth.js';
|
|
2
|
-
export { searchPlaces } from './smapi-journey.js';
|
|
3
|
-
export { searchTrips } from './smapi-journey.js';
|
|
4
|
-
export { getTrip } from './smapi-journey.js';
|
|
5
|
-
export { paginateTrips } from './smapi-journey.js';
|
|
6
|
-
export { getTripPrices } from './smapi-prices.js';
|
|
7
|
-
export { getTripOffers } from './smapi-prices.js';
|
|
8
|
-
export { mockSearchPlaces, mockSearchTrips, mockGetTripPrices, mockGetTripOffers, } from './smapi-mock.js';
|
|
9
|
-
export type { SmapiPlace, SmapiTrip, SmapiTripsCollection, SmapiTripSearchParams, SmapiPlaceSearchParams, SmapiPriceResult, SmapiOfferResult, SmapiTraveler, SmapiReductionCard, SmapiTimedLeg, SmapiTransferLeg, SmapiTripLeg, } from './smapi-types.js';
|