@withinfocus/tba-mcp-server 0.2.5 → 0.3.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/dist/handlers.d.ts +8 -0
- package/dist/handlers.d.ts.map +1 -0
- package/dist/handlers.js +918 -0
- package/dist/handlers.js.map +1 -0
- package/dist/index.d.ts +1 -348
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -2449
- package/dist/index.js.map +1 -1
- package/dist/schemas.d.ts +443 -0
- package/dist/schemas.d.ts.map +1 -0
- package/dist/schemas.js +416 -0
- package/dist/schemas.js.map +1 -0
- package/dist/tools.d.ts +3 -0
- package/dist/tools.d.ts.map +1 -0
- package/dist/tools.js +996 -0
- package/dist/tools.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +62 -0
- package/dist/utils.js.map +1 -0
- package/package.json +11 -11
package/dist/index.js
CHANGED
|
@@ -2,2479 +2,46 @@
|
|
|
2
2
|
import { Server } from '@modelcontextprotocol/sdk/server/index.js';
|
|
3
3
|
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
|
|
4
4
|
import { CallToolRequestSchema, ListToolsRequestSchema, } from '@modelcontextprotocol/sdk/types.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
.regex(/^frc\d+$/, 'Team key must be in format frcXXXX');
|
|
9
|
-
export const EventKeySchema = z.string();
|
|
10
|
-
export const YearSchema = z
|
|
11
|
-
.number()
|
|
12
|
-
.int()
|
|
13
|
-
.min(1992)
|
|
14
|
-
.max(new Date().getFullYear() + 1);
|
|
15
|
-
export const TeamSchema = z.object({
|
|
16
|
-
key: z.string(),
|
|
17
|
-
team_number: z.number(),
|
|
18
|
-
nickname: z.string().nullish(),
|
|
19
|
-
name: z.string(),
|
|
20
|
-
city: z.string().nullish(),
|
|
21
|
-
state_prov: z.string().nullish(),
|
|
22
|
-
country: z.string().nullish(),
|
|
23
|
-
address: z.string().nullish(),
|
|
24
|
-
postal_code: z.string().nullish(),
|
|
25
|
-
gmaps_place_id: z.string().nullish(),
|
|
26
|
-
gmaps_url: z.string().nullish(),
|
|
27
|
-
lat: z.number().nullish(),
|
|
28
|
-
lng: z.number().nullish(),
|
|
29
|
-
location_name: z.string().nullish(),
|
|
30
|
-
website: z.string().nullish(),
|
|
31
|
-
rookie_year: z.number().nullish(),
|
|
32
|
-
motto: z.string().nullish(),
|
|
33
|
-
home_championship: z.record(z.string(), z.any()).nullish(),
|
|
34
|
-
});
|
|
35
|
-
export const EventSchema = z.object({
|
|
36
|
-
key: z.string(),
|
|
37
|
-
name: z.string(),
|
|
38
|
-
event_code: z.string(),
|
|
39
|
-
event_type: z.number(),
|
|
40
|
-
district: z
|
|
41
|
-
.object({
|
|
42
|
-
abbreviation: z.string(),
|
|
43
|
-
display_name: z.string(),
|
|
44
|
-
key: z.string(),
|
|
45
|
-
year: z.number(),
|
|
46
|
-
})
|
|
47
|
-
.nullish(),
|
|
48
|
-
city: z.string().nullish(),
|
|
49
|
-
state_prov: z.string().nullish(),
|
|
50
|
-
country: z.string().nullish(),
|
|
51
|
-
start_date: z.string(),
|
|
52
|
-
end_date: z.string(),
|
|
53
|
-
year: z.number(),
|
|
54
|
-
short_name: z.string().nullish(),
|
|
55
|
-
event_type_string: z.string(),
|
|
56
|
-
week: z.number().nullish(),
|
|
57
|
-
address: z.string().nullish(),
|
|
58
|
-
postal_code: z.string().nullish(),
|
|
59
|
-
gmaps_place_id: z.string().nullish(),
|
|
60
|
-
gmaps_url: z.string().nullish(),
|
|
61
|
-
lat: z.number().nullish(),
|
|
62
|
-
lng: z.number().nullish(),
|
|
63
|
-
location_name: z.string().nullish(),
|
|
64
|
-
timezone: z.string().nullish(),
|
|
65
|
-
website: z.string().nullish(),
|
|
66
|
-
first_event_id: z.string().nullish(),
|
|
67
|
-
first_event_code: z.string().nullish(),
|
|
68
|
-
webcasts: z
|
|
69
|
-
.array(z.object({
|
|
70
|
-
type: z.string(),
|
|
71
|
-
channel: z.string(),
|
|
72
|
-
date: z.string().nullish(),
|
|
73
|
-
file: z.string().nullish(),
|
|
74
|
-
}))
|
|
75
|
-
.nullish(),
|
|
76
|
-
division_keys: z.array(z.string()).nullish(),
|
|
77
|
-
parent_event_key: z.string().nullish(),
|
|
78
|
-
playoff_type: z.number().nullish(),
|
|
79
|
-
playoff_type_string: z.string().nullish(),
|
|
80
|
-
});
|
|
81
|
-
export const MatchSchema = z.object({
|
|
82
|
-
key: z.string(),
|
|
83
|
-
comp_level: z.string(),
|
|
84
|
-
set_number: z.number(),
|
|
85
|
-
match_number: z.number(),
|
|
86
|
-
alliances: z.object({
|
|
87
|
-
red: z.object({
|
|
88
|
-
score: z.number(),
|
|
89
|
-
team_keys: z.array(z.string()),
|
|
90
|
-
surrogate_team_keys: z.array(z.string()).nullish(),
|
|
91
|
-
dq_team_keys: z.array(z.string()).nullish(),
|
|
92
|
-
}),
|
|
93
|
-
blue: z.object({
|
|
94
|
-
score: z.number(),
|
|
95
|
-
team_keys: z.array(z.string()),
|
|
96
|
-
surrogate_team_keys: z.array(z.string()).nullish(),
|
|
97
|
-
dq_team_keys: z.array(z.string()).nullish(),
|
|
98
|
-
}),
|
|
99
|
-
}),
|
|
100
|
-
winning_alliance: z.string().nullish(),
|
|
101
|
-
event_key: z.string(),
|
|
102
|
-
time: z.number().nullish(),
|
|
103
|
-
actual_time: z.number().nullish(),
|
|
104
|
-
predicted_time: z.number().nullish(),
|
|
105
|
-
post_result_time: z.number().nullish(),
|
|
106
|
-
score_breakdown: z.record(z.string(), z.any()).nullish(),
|
|
107
|
-
videos: z
|
|
108
|
-
.array(z.object({
|
|
109
|
-
type: z.string(),
|
|
110
|
-
key: z.string(),
|
|
111
|
-
}))
|
|
112
|
-
.nullish(),
|
|
113
|
-
});
|
|
114
|
-
const AwardSchema = z.object({
|
|
115
|
-
name: z.string(),
|
|
116
|
-
award_type: z.number(),
|
|
117
|
-
event_key: z.string(),
|
|
118
|
-
recipient_list: z.array(z.object({
|
|
119
|
-
team_key: z.string().nullish(),
|
|
120
|
-
awardee: z.string().nullish(),
|
|
121
|
-
})),
|
|
122
|
-
year: z.number(),
|
|
123
|
-
});
|
|
124
|
-
const RankingSchema = z.object({
|
|
125
|
-
rankings: z.array(z.object({
|
|
126
|
-
team_key: z.string(),
|
|
127
|
-
rank: z.number(),
|
|
128
|
-
dq: z.number().nullish(),
|
|
129
|
-
matches_played: z.number(),
|
|
130
|
-
qual_average: z.number().nullish(),
|
|
131
|
-
record: z
|
|
132
|
-
.object({
|
|
133
|
-
losses: z.number(),
|
|
134
|
-
wins: z.number(),
|
|
135
|
-
ties: z.number(),
|
|
136
|
-
})
|
|
137
|
-
.nullish(),
|
|
138
|
-
extra_stats: z.array(z.number()).nullish(),
|
|
139
|
-
sort_orders: z.array(z.number()).nullish(),
|
|
140
|
-
})),
|
|
141
|
-
extra_stats_info: z
|
|
142
|
-
.array(z.object({
|
|
143
|
-
name: z.string(),
|
|
144
|
-
precision: z.number(),
|
|
145
|
-
}))
|
|
146
|
-
.nullish(),
|
|
147
|
-
sort_order_info: z
|
|
148
|
-
.array(z.object({
|
|
149
|
-
name: z.string(),
|
|
150
|
-
precision: z.number(),
|
|
151
|
-
}))
|
|
152
|
-
.nullish(),
|
|
153
|
-
});
|
|
154
|
-
const AllianceSchema = z.object({
|
|
155
|
-
name: z.string().nullish(),
|
|
156
|
-
backup: z
|
|
157
|
-
.object({
|
|
158
|
-
in: z.string().nullish(),
|
|
159
|
-
out: z.string().nullish(),
|
|
160
|
-
})
|
|
161
|
-
.nullish(),
|
|
162
|
-
declines: z.array(z.string()).nullish(),
|
|
163
|
-
picks: z.array(z.string()),
|
|
164
|
-
status: z
|
|
165
|
-
.object({
|
|
166
|
-
current_level_record: z
|
|
167
|
-
.object({
|
|
168
|
-
losses: z.number(),
|
|
169
|
-
ties: z.number(),
|
|
170
|
-
wins: z.number(),
|
|
171
|
-
})
|
|
172
|
-
.nullish(),
|
|
173
|
-
level: z.string().nullish(),
|
|
174
|
-
playoff_average: z.number().nullish(),
|
|
175
|
-
record: z
|
|
176
|
-
.object({
|
|
177
|
-
losses: z.number(),
|
|
178
|
-
ties: z.number(),
|
|
179
|
-
wins: z.number(),
|
|
180
|
-
})
|
|
181
|
-
.nullish(),
|
|
182
|
-
status: z.string().nullish(),
|
|
183
|
-
})
|
|
184
|
-
.nullish(),
|
|
185
|
-
});
|
|
186
|
-
const DistrictPointsSchema = z.object({
|
|
187
|
-
points: z.record(z.string(), z.object({
|
|
188
|
-
alliance_points: z.number(),
|
|
189
|
-
award_points: z.number(),
|
|
190
|
-
elim_points: z.number(),
|
|
191
|
-
qual_points: z.number(),
|
|
192
|
-
total: z.number(),
|
|
193
|
-
})),
|
|
194
|
-
tiebreakers: z
|
|
195
|
-
.record(z.string(), z.object({
|
|
196
|
-
highest_qual_scores: z.array(z.number()).nullish(),
|
|
197
|
-
qual_wins: z.number().nullish(),
|
|
198
|
-
}))
|
|
199
|
-
.nullish(),
|
|
200
|
-
});
|
|
201
|
-
const InsightsSchema = z.object({
|
|
202
|
-
qual: z.record(z.string(), z.any()).nullish(),
|
|
203
|
-
playoff: z.record(z.string(), z.any()).nullish(),
|
|
204
|
-
});
|
|
205
|
-
const MediaSchema = z.object({
|
|
206
|
-
type: z.string(),
|
|
207
|
-
foreign_key: z.string().nullish(),
|
|
208
|
-
details: z.record(z.string(), z.any()).nullish(),
|
|
209
|
-
preferred: z.boolean().nullish(),
|
|
210
|
-
direct_url: z.string().nullish(),
|
|
211
|
-
view_url: z.string().nullish(),
|
|
212
|
-
});
|
|
213
|
-
const RobotSchema = z.object({
|
|
214
|
-
year: z.number(),
|
|
215
|
-
robot_name: z.string(),
|
|
216
|
-
key: z.string(),
|
|
217
|
-
team_key: z.string(),
|
|
218
|
-
});
|
|
219
|
-
const DistrictSchema = z.object({
|
|
220
|
-
abbreviation: z.string(),
|
|
221
|
-
display_name: z.string(),
|
|
222
|
-
key: z.string(),
|
|
223
|
-
year: z.number(),
|
|
224
|
-
});
|
|
225
|
-
export const StatusSchema = z.object({
|
|
226
|
-
current_season: z.number(),
|
|
227
|
-
max_season: z.number(),
|
|
228
|
-
is_datafeed_down: z.boolean(),
|
|
229
|
-
down_events: z.array(z.string()),
|
|
230
|
-
ios: z.object({
|
|
231
|
-
latest_app_version: z.number(),
|
|
232
|
-
min_app_version: z.number(),
|
|
233
|
-
}),
|
|
234
|
-
android: z.object({
|
|
235
|
-
latest_app_version: z.number(),
|
|
236
|
-
min_app_version: z.number(),
|
|
237
|
-
}),
|
|
238
|
-
max_team_page: z.number(),
|
|
239
|
-
});
|
|
240
|
-
export const EventOPRsSchema = z.object({
|
|
241
|
-
oprs: z.record(z.string(), z.number()),
|
|
242
|
-
dprs: z.record(z.string(), z.number()),
|
|
243
|
-
ccwms: z.record(z.string(), z.number()),
|
|
244
|
-
});
|
|
245
|
-
export const TeamEventStatusSchema = z.object({
|
|
246
|
-
qual: z
|
|
247
|
-
.object({
|
|
248
|
-
num_teams: z.number().nullish(),
|
|
249
|
-
ranking: z
|
|
250
|
-
.object({
|
|
251
|
-
dq: z.number().nullish(),
|
|
252
|
-
matches_played: z.number(),
|
|
253
|
-
qual_average: z.number().nullish(),
|
|
254
|
-
rank: z.number(),
|
|
255
|
-
record: z
|
|
256
|
-
.object({
|
|
257
|
-
losses: z.number(),
|
|
258
|
-
ties: z.number(),
|
|
259
|
-
wins: z.number(),
|
|
260
|
-
})
|
|
261
|
-
.nullish(),
|
|
262
|
-
sort_orders: z.array(z.number()).nullish(),
|
|
263
|
-
team_key: z.string(),
|
|
264
|
-
})
|
|
265
|
-
.nullish(),
|
|
266
|
-
sort_order_info: z
|
|
267
|
-
.array(z.object({
|
|
268
|
-
name: z.string(),
|
|
269
|
-
precision: z.number(),
|
|
270
|
-
}))
|
|
271
|
-
.nullish(),
|
|
272
|
-
status: z.string().nullish(),
|
|
273
|
-
})
|
|
274
|
-
.nullish(),
|
|
275
|
-
alliance: z
|
|
276
|
-
.object({
|
|
277
|
-
backup: z
|
|
278
|
-
.object({
|
|
279
|
-
in: z.string().nullish(),
|
|
280
|
-
out: z.string().nullish(),
|
|
281
|
-
})
|
|
282
|
-
.nullish(),
|
|
283
|
-
name: z.string().nullish(),
|
|
284
|
-
number: z.number().nullish(),
|
|
285
|
-
pick: z.number().nullish(),
|
|
286
|
-
})
|
|
287
|
-
.nullish(),
|
|
288
|
-
playoff: z
|
|
289
|
-
.object({
|
|
290
|
-
current_level_record: z
|
|
291
|
-
.object({
|
|
292
|
-
losses: z.number(),
|
|
293
|
-
ties: z.number(),
|
|
294
|
-
wins: z.number(),
|
|
295
|
-
})
|
|
296
|
-
.nullish(),
|
|
297
|
-
level: z.string().nullish(),
|
|
298
|
-
playoff_average: z.number().nullish(),
|
|
299
|
-
record: z
|
|
300
|
-
.object({
|
|
301
|
-
losses: z.number(),
|
|
302
|
-
ties: z.number(),
|
|
303
|
-
wins: z.number(),
|
|
304
|
-
})
|
|
305
|
-
.nullish(),
|
|
306
|
-
status: z.string().nullish(),
|
|
307
|
-
})
|
|
308
|
-
.nullish(),
|
|
309
|
-
alliance_status_str: z.string(),
|
|
310
|
-
playoff_status_str: z.string(),
|
|
311
|
-
overall_status_str: z.string(),
|
|
312
|
-
next_match_key: z.string().nullish(),
|
|
313
|
-
last_match_key: z.string().nullish(),
|
|
314
|
-
});
|
|
315
|
-
export const DistrictRankingSchema = z.object({
|
|
316
|
-
team_key: z.string(),
|
|
317
|
-
rank: z.number(),
|
|
318
|
-
rookie_bonus: z.number().nullish(),
|
|
319
|
-
point_total: z.number(),
|
|
320
|
-
event_points: z.array(z.object({
|
|
321
|
-
district_cmp: z.boolean(),
|
|
322
|
-
total: z.number(),
|
|
323
|
-
alliance_points: z.number(),
|
|
324
|
-
elim_points: z.number(),
|
|
325
|
-
award_points: z.number(),
|
|
326
|
-
event_key: z.string(),
|
|
327
|
-
qual_points: z.number(),
|
|
328
|
-
})),
|
|
329
|
-
});
|
|
330
|
-
export const TeamSimpleSchema = z.object({
|
|
331
|
-
key: z.string(),
|
|
332
|
-
team_number: z.number(),
|
|
333
|
-
nickname: z.string().nullish(),
|
|
334
|
-
name: z.string(),
|
|
335
|
-
city: z.string().nullish(),
|
|
336
|
-
state_prov: z.string().nullish(),
|
|
337
|
-
country: z.string().nullish(),
|
|
338
|
-
});
|
|
339
|
-
export const EventSimpleSchema = z.object({
|
|
340
|
-
key: z.string(),
|
|
341
|
-
name: z.string(),
|
|
342
|
-
event_code: z.string(),
|
|
343
|
-
event_type: z.number(),
|
|
344
|
-
city: z.string().nullish(),
|
|
345
|
-
state_prov: z.string().nullish(),
|
|
346
|
-
country: z.string().nullish(),
|
|
347
|
-
start_date: z.string(),
|
|
348
|
-
end_date: z.string(),
|
|
349
|
-
year: z.number(),
|
|
350
|
-
});
|
|
351
|
-
export const MatchSimpleSchema = z.object({
|
|
352
|
-
key: z.string(),
|
|
353
|
-
comp_level: z.string(),
|
|
354
|
-
set_number: z.number(),
|
|
355
|
-
match_number: z.number(),
|
|
356
|
-
alliances: z.object({
|
|
357
|
-
red: z.object({
|
|
358
|
-
score: z.number(),
|
|
359
|
-
team_keys: z.array(z.string()),
|
|
360
|
-
}),
|
|
361
|
-
blue: z.object({
|
|
362
|
-
score: z.number(),
|
|
363
|
-
team_keys: z.array(z.string()),
|
|
364
|
-
}),
|
|
365
|
-
}),
|
|
366
|
-
winning_alliance: z.string().nullish(),
|
|
367
|
-
event_key: z.string(),
|
|
368
|
-
time: z.number().nullish(),
|
|
369
|
-
predicted_time: z.number().nullish(),
|
|
370
|
-
actual_time: z.number().nullish(),
|
|
371
|
-
});
|
|
372
|
-
export const ZebraSchema = z.object({
|
|
373
|
-
key: z.string(),
|
|
374
|
-
times: z.array(z.number()),
|
|
375
|
-
alliances: z.object({
|
|
376
|
-
red: z.array(z.object({
|
|
377
|
-
team_key: z.string(),
|
|
378
|
-
xs: z.array(z.number()).nullish(),
|
|
379
|
-
ys: z.array(z.number()).nullish(),
|
|
380
|
-
})),
|
|
381
|
-
blue: z.array(z.object({
|
|
382
|
-
team_key: z.string(),
|
|
383
|
-
xs: z.array(z.number()).nullish(),
|
|
384
|
-
ys: z.array(z.number()).nullish(),
|
|
385
|
-
})),
|
|
386
|
-
}),
|
|
387
|
-
});
|
|
388
|
-
export const PredictionSchema = z.object({
|
|
389
|
-
match_predictions: z
|
|
390
|
-
.record(z.string(), z.object({
|
|
391
|
-
red: z
|
|
392
|
-
.object({
|
|
393
|
-
score: z.number(),
|
|
394
|
-
})
|
|
395
|
-
.optional(),
|
|
396
|
-
blue: z
|
|
397
|
-
.object({
|
|
398
|
-
score: z.number(),
|
|
399
|
-
})
|
|
400
|
-
.optional(),
|
|
401
|
-
}))
|
|
402
|
-
.or(z.any())
|
|
403
|
-
.nullish(),
|
|
404
|
-
ranking_predictions: z
|
|
405
|
-
.record(z.string(), z.object({
|
|
406
|
-
rank: z.number(),
|
|
407
|
-
}))
|
|
408
|
-
.or(z.array(z.any()))
|
|
409
|
-
.nullish(),
|
|
410
|
-
stat_mean_vars: z.record(z.string(), z.any()).nullish(),
|
|
411
|
-
});
|
|
412
|
-
export const TeamHistorySchema = z.object({
|
|
413
|
-
awards: z.array(AwardSchema).nullish(),
|
|
414
|
-
events: z.array(EventSchema).nullish(),
|
|
415
|
-
matches: z.array(MatchSchema).nullish(),
|
|
416
|
-
robots: z.array(RobotSchema).nullish(),
|
|
417
|
-
});
|
|
418
|
-
let API_KEY;
|
|
419
|
-
function getApiKey() {
|
|
420
|
-
if (!API_KEY) {
|
|
421
|
-
API_KEY = process.env['TBA_API_KEY'];
|
|
422
|
-
if (!API_KEY) {
|
|
423
|
-
const errorMessage = 'TBA_API_KEY environment variable is required but not set. Please set the TBA_API_KEY environment variable with your The Blue Alliance API key.';
|
|
424
|
-
console.error(errorMessage);
|
|
425
|
-
throw new Error(errorMessage);
|
|
426
|
-
}
|
|
427
|
-
if (API_KEY.trim() === '') {
|
|
428
|
-
const errorMessage = 'TBA_API_KEY environment variable is set but empty. Please provide a valid The Blue Alliance API key.';
|
|
429
|
-
console.error(errorMessage);
|
|
430
|
-
throw new Error(errorMessage);
|
|
431
|
-
}
|
|
432
|
-
}
|
|
433
|
-
return API_KEY;
|
|
434
|
-
}
|
|
435
|
-
export async function makeApiRequest(endpoint) {
|
|
436
|
-
try {
|
|
437
|
-
const apiKey = getApiKey();
|
|
438
|
-
const url = `https://www.thebluealliance.com/api/v3${endpoint}`;
|
|
439
|
-
const response = await fetch(url, {
|
|
440
|
-
headers: {
|
|
441
|
-
'X-TBA-Auth-Key': apiKey,
|
|
442
|
-
Accept: 'application/json',
|
|
443
|
-
},
|
|
444
|
-
});
|
|
445
|
-
if (!response.ok) {
|
|
446
|
-
const errorMessage = `TBA API request failed: ${response.status} ${response.statusText} for endpoint ${endpoint}`;
|
|
447
|
-
console.error(errorMessage);
|
|
448
|
-
throw new Error(errorMessage);
|
|
449
|
-
}
|
|
450
|
-
return response.json();
|
|
451
|
-
}
|
|
452
|
-
catch (error) {
|
|
453
|
-
if (error instanceof Error) {
|
|
454
|
-
console.error(`API request error for endpoint ${endpoint}: ${error.message}`);
|
|
455
|
-
throw error;
|
|
456
|
-
}
|
|
457
|
-
const errorMessage = `Unknown error during API request for endpoint ${endpoint}`;
|
|
458
|
-
console.error(`${errorMessage}: ${error}`);
|
|
459
|
-
throw new Error(errorMessage);
|
|
460
|
-
}
|
|
461
|
-
}
|
|
5
|
+
import { getApiKey, log } from './utils.js';
|
|
6
|
+
import { tools } from './tools.js';
|
|
7
|
+
import { handleToolCall } from './handlers.js';
|
|
462
8
|
async function runServer() {
|
|
463
9
|
// Create server first so we can use its logging method
|
|
464
10
|
let server = null;
|
|
465
|
-
// Common logging method that uses MCP server's sendLoggingMessage
|
|
466
|
-
const log = async (level, data, logger) => {
|
|
467
|
-
if (server) {
|
|
468
|
-
try {
|
|
469
|
-
await server.sendLoggingMessage({ level, data, logger });
|
|
470
|
-
}
|
|
471
|
-
catch {
|
|
472
|
-
// Fallback to console if MCP logging fails
|
|
473
|
-
console.error(data);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
else {
|
|
477
|
-
// Fallback to console if server not initialized yet
|
|
478
|
-
console.error(data);
|
|
479
|
-
}
|
|
480
|
-
};
|
|
481
11
|
try {
|
|
482
|
-
await log('info', 'The Blue Alliance MCP Server starting ...');
|
|
12
|
+
await log('info', 'The Blue Alliance MCP Server starting ...', server);
|
|
483
13
|
// Validate API key availability early
|
|
484
14
|
try {
|
|
485
15
|
getApiKey();
|
|
486
|
-
await log('info', 'TBA API key validated successfully');
|
|
16
|
+
await log('info', 'TBA API key validated successfully', server);
|
|
487
17
|
}
|
|
488
18
|
catch (error) {
|
|
489
19
|
const errorMessage = 'Failed to get TBA API key';
|
|
490
|
-
await log('error', `${errorMessage}: ${error instanceof Error ? error.message : error}
|
|
20
|
+
await log('error', `${errorMessage}: ${error instanceof Error ? error.message : error}`, server);
|
|
491
21
|
throw new Error(errorMessage);
|
|
492
22
|
}
|
|
493
|
-
await log('info', 'Initializing MCP server ...');
|
|
23
|
+
await log('info', 'Initializing MCP server ...', server);
|
|
494
24
|
server = new Server({
|
|
495
25
|
name: 'The Blue Alliance MCP Server',
|
|
496
|
-
version: '0.
|
|
26
|
+
version: '0.3.0',
|
|
497
27
|
}, {
|
|
498
28
|
capabilities: {
|
|
499
29
|
tools: {},
|
|
500
30
|
},
|
|
501
31
|
});
|
|
502
|
-
await log('info', 'Setting up request handlers ...');
|
|
32
|
+
await log('info', 'Setting up request handlers ...', server);
|
|
503
33
|
server.setRequestHandler(ListToolsRequestSchema, async () => {
|
|
504
|
-
return {
|
|
505
|
-
tools: [
|
|
506
|
-
{
|
|
507
|
-
name: 'get_team',
|
|
508
|
-
description: 'Get detailed information about a specific FRC team',
|
|
509
|
-
inputSchema: {
|
|
510
|
-
type: 'object',
|
|
511
|
-
properties: {
|
|
512
|
-
team_key: {
|
|
513
|
-
type: 'string',
|
|
514
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
515
|
-
pattern: '^frc\\d+$',
|
|
516
|
-
},
|
|
517
|
-
},
|
|
518
|
-
required: ['team_key'],
|
|
519
|
-
},
|
|
520
|
-
},
|
|
521
|
-
{
|
|
522
|
-
name: 'get_team_events',
|
|
523
|
-
description: 'Get events that a team has participated in for a given year',
|
|
524
|
-
inputSchema: {
|
|
525
|
-
type: 'object',
|
|
526
|
-
properties: {
|
|
527
|
-
team_key: {
|
|
528
|
-
type: 'string',
|
|
529
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
530
|
-
pattern: '^frc\\d+$',
|
|
531
|
-
},
|
|
532
|
-
year: {
|
|
533
|
-
type: 'number',
|
|
534
|
-
description: 'Competition year',
|
|
535
|
-
minimum: 1992,
|
|
536
|
-
maximum: new Date().getFullYear() + 1,
|
|
537
|
-
},
|
|
538
|
-
},
|
|
539
|
-
required: ['team_key', 'year'],
|
|
540
|
-
},
|
|
541
|
-
},
|
|
542
|
-
{
|
|
543
|
-
name: 'get_team_awards',
|
|
544
|
-
description: 'Get awards won by a team in a specific year',
|
|
545
|
-
inputSchema: {
|
|
546
|
-
type: 'object',
|
|
547
|
-
properties: {
|
|
548
|
-
team_key: {
|
|
549
|
-
type: 'string',
|
|
550
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
551
|
-
pattern: '^frc\\d+$',
|
|
552
|
-
},
|
|
553
|
-
year: {
|
|
554
|
-
type: 'number',
|
|
555
|
-
description: 'Competition year',
|
|
556
|
-
minimum: 1992,
|
|
557
|
-
maximum: new Date().getFullYear() + 1,
|
|
558
|
-
},
|
|
559
|
-
},
|
|
560
|
-
required: ['team_key', 'year'],
|
|
561
|
-
},
|
|
562
|
-
},
|
|
563
|
-
{
|
|
564
|
-
name: 'get_team_matches',
|
|
565
|
-
description: 'Get matches played by a team in a specific year',
|
|
566
|
-
inputSchema: {
|
|
567
|
-
type: 'object',
|
|
568
|
-
properties: {
|
|
569
|
-
team_key: {
|
|
570
|
-
type: 'string',
|
|
571
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
572
|
-
pattern: '^frc\\d+$',
|
|
573
|
-
},
|
|
574
|
-
year: {
|
|
575
|
-
type: 'number',
|
|
576
|
-
description: 'Competition year',
|
|
577
|
-
minimum: 1992,
|
|
578
|
-
maximum: new Date().getFullYear() + 1,
|
|
579
|
-
},
|
|
580
|
-
},
|
|
581
|
-
required: ['team_key', 'year'],
|
|
582
|
-
},
|
|
583
|
-
},
|
|
584
|
-
{
|
|
585
|
-
name: 'get_events',
|
|
586
|
-
description: 'Get all FRC events for a specific year',
|
|
587
|
-
inputSchema: {
|
|
588
|
-
type: 'object',
|
|
589
|
-
properties: {
|
|
590
|
-
year: {
|
|
591
|
-
type: 'number',
|
|
592
|
-
description: 'Competition year',
|
|
593
|
-
minimum: 1992,
|
|
594
|
-
maximum: new Date().getFullYear() + 1,
|
|
595
|
-
},
|
|
596
|
-
},
|
|
597
|
-
required: ['year'],
|
|
598
|
-
},
|
|
599
|
-
},
|
|
600
|
-
{
|
|
601
|
-
name: 'get_event',
|
|
602
|
-
description: 'Get detailed information about a specific event',
|
|
603
|
-
inputSchema: {
|
|
604
|
-
type: 'object',
|
|
605
|
-
properties: {
|
|
606
|
-
event_key: {
|
|
607
|
-
type: 'string',
|
|
608
|
-
description: 'Event key (e.g., 2023casj)',
|
|
609
|
-
},
|
|
610
|
-
},
|
|
611
|
-
required: ['event_key'],
|
|
612
|
-
},
|
|
613
|
-
},
|
|
614
|
-
{
|
|
615
|
-
name: 'get_event_teams',
|
|
616
|
-
description: 'Get teams participating in a specific event',
|
|
617
|
-
inputSchema: {
|
|
618
|
-
type: 'object',
|
|
619
|
-
properties: {
|
|
620
|
-
event_key: {
|
|
621
|
-
type: 'string',
|
|
622
|
-
description: 'Event key (e.g., 2023casj)',
|
|
623
|
-
},
|
|
624
|
-
},
|
|
625
|
-
required: ['event_key'],
|
|
626
|
-
},
|
|
627
|
-
},
|
|
628
|
-
{
|
|
629
|
-
name: 'get_event_rankings',
|
|
630
|
-
description: 'Get team rankings for a specific event',
|
|
631
|
-
inputSchema: {
|
|
632
|
-
type: 'object',
|
|
633
|
-
properties: {
|
|
634
|
-
event_key: {
|
|
635
|
-
type: 'string',
|
|
636
|
-
description: 'Event key (e.g., 2023casj)',
|
|
637
|
-
},
|
|
638
|
-
},
|
|
639
|
-
required: ['event_key'],
|
|
640
|
-
},
|
|
641
|
-
},
|
|
642
|
-
{
|
|
643
|
-
name: 'get_event_matches',
|
|
644
|
-
description: 'Get matches for a specific event',
|
|
645
|
-
inputSchema: {
|
|
646
|
-
type: 'object',
|
|
647
|
-
properties: {
|
|
648
|
-
event_key: {
|
|
649
|
-
type: 'string',
|
|
650
|
-
description: 'Event key (e.g., 2023casj)',
|
|
651
|
-
},
|
|
652
|
-
},
|
|
653
|
-
required: ['event_key'],
|
|
654
|
-
},
|
|
655
|
-
},
|
|
656
|
-
{
|
|
657
|
-
name: 'get_event_alliances',
|
|
658
|
-
description: 'Get elimination alliances for a specific event',
|
|
659
|
-
inputSchema: {
|
|
660
|
-
type: 'object',
|
|
661
|
-
properties: {
|
|
662
|
-
event_key: {
|
|
663
|
-
type: 'string',
|
|
664
|
-
description: 'Event key (e.g., 2023casj)',
|
|
665
|
-
},
|
|
666
|
-
},
|
|
667
|
-
required: ['event_key'],
|
|
668
|
-
},
|
|
669
|
-
},
|
|
670
|
-
{
|
|
671
|
-
name: 'get_event_insights',
|
|
672
|
-
description: 'Get event-specific insights and statistics',
|
|
673
|
-
inputSchema: {
|
|
674
|
-
type: 'object',
|
|
675
|
-
properties: {
|
|
676
|
-
event_key: {
|
|
677
|
-
type: 'string',
|
|
678
|
-
description: 'Event key (e.g., 2023casj)',
|
|
679
|
-
},
|
|
680
|
-
},
|
|
681
|
-
required: ['event_key'],
|
|
682
|
-
},
|
|
683
|
-
},
|
|
684
|
-
{
|
|
685
|
-
name: 'get_event_district_points',
|
|
686
|
-
description: 'Get district points for teams at an event',
|
|
687
|
-
inputSchema: {
|
|
688
|
-
type: 'object',
|
|
689
|
-
properties: {
|
|
690
|
-
event_key: {
|
|
691
|
-
type: 'string',
|
|
692
|
-
description: 'Event key (e.g., 2023casj)',
|
|
693
|
-
},
|
|
694
|
-
},
|
|
695
|
-
required: ['event_key'],
|
|
696
|
-
},
|
|
697
|
-
},
|
|
698
|
-
{
|
|
699
|
-
name: 'get_team_years_participated',
|
|
700
|
-
description: 'Get years that a team has participated in competition',
|
|
701
|
-
inputSchema: {
|
|
702
|
-
type: 'object',
|
|
703
|
-
properties: {
|
|
704
|
-
team_key: {
|
|
705
|
-
type: 'string',
|
|
706
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
707
|
-
pattern: '^frc\\d+$',
|
|
708
|
-
},
|
|
709
|
-
},
|
|
710
|
-
required: ['team_key'],
|
|
711
|
-
},
|
|
712
|
-
},
|
|
713
|
-
{
|
|
714
|
-
name: 'get_team_districts',
|
|
715
|
-
description: 'Get district history for a team',
|
|
716
|
-
inputSchema: {
|
|
717
|
-
type: 'object',
|
|
718
|
-
properties: {
|
|
719
|
-
team_key: {
|
|
720
|
-
type: 'string',
|
|
721
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
722
|
-
pattern: '^frc\\d+$',
|
|
723
|
-
},
|
|
724
|
-
},
|
|
725
|
-
required: ['team_key'],
|
|
726
|
-
},
|
|
727
|
-
},
|
|
728
|
-
{
|
|
729
|
-
name: 'get_team_robots',
|
|
730
|
-
description: 'Get robot names for a team by year',
|
|
731
|
-
inputSchema: {
|
|
732
|
-
type: 'object',
|
|
733
|
-
properties: {
|
|
734
|
-
team_key: {
|
|
735
|
-
type: 'string',
|
|
736
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
737
|
-
pattern: '^frc\\d+$',
|
|
738
|
-
},
|
|
739
|
-
},
|
|
740
|
-
required: ['team_key'],
|
|
741
|
-
},
|
|
742
|
-
},
|
|
743
|
-
{
|
|
744
|
-
name: 'get_team_media',
|
|
745
|
-
description: 'Get media for a team in a specific year',
|
|
746
|
-
inputSchema: {
|
|
747
|
-
type: 'object',
|
|
748
|
-
properties: {
|
|
749
|
-
team_key: {
|
|
750
|
-
type: 'string',
|
|
751
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
752
|
-
pattern: '^frc\\d+$',
|
|
753
|
-
},
|
|
754
|
-
year: {
|
|
755
|
-
type: 'number',
|
|
756
|
-
description: 'Competition year',
|
|
757
|
-
minimum: 1992,
|
|
758
|
-
maximum: new Date().getFullYear() + 1,
|
|
759
|
-
},
|
|
760
|
-
},
|
|
761
|
-
required: ['team_key', 'year'],
|
|
762
|
-
},
|
|
763
|
-
},
|
|
764
|
-
{
|
|
765
|
-
name: 'get_team_event_matches',
|
|
766
|
-
description: 'Get matches for a team at a specific event',
|
|
767
|
-
inputSchema: {
|
|
768
|
-
type: 'object',
|
|
769
|
-
properties: {
|
|
770
|
-
team_key: {
|
|
771
|
-
type: 'string',
|
|
772
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
773
|
-
pattern: '^frc\\d+$',
|
|
774
|
-
},
|
|
775
|
-
event_key: {
|
|
776
|
-
type: 'string',
|
|
777
|
-
description: 'Event key (e.g., 2023casj)',
|
|
778
|
-
},
|
|
779
|
-
},
|
|
780
|
-
required: ['team_key', 'event_key'],
|
|
781
|
-
},
|
|
782
|
-
},
|
|
783
|
-
{
|
|
784
|
-
name: 'get_teams',
|
|
785
|
-
description: 'Get list of teams with pagination',
|
|
786
|
-
inputSchema: {
|
|
787
|
-
type: 'object',
|
|
788
|
-
properties: {
|
|
789
|
-
page_num: {
|
|
790
|
-
type: 'number',
|
|
791
|
-
description: 'Page number (0-indexed)',
|
|
792
|
-
minimum: 0,
|
|
793
|
-
},
|
|
794
|
-
},
|
|
795
|
-
required: ['page_num'],
|
|
796
|
-
},
|
|
797
|
-
},
|
|
798
|
-
{
|
|
799
|
-
name: 'get_status',
|
|
800
|
-
description: 'Get TBA API status information',
|
|
801
|
-
inputSchema: {
|
|
802
|
-
type: 'object',
|
|
803
|
-
properties: {},
|
|
804
|
-
},
|
|
805
|
-
},
|
|
806
|
-
{
|
|
807
|
-
name: 'get_match',
|
|
808
|
-
description: 'Get detailed information about a specific match',
|
|
809
|
-
inputSchema: {
|
|
810
|
-
type: 'object',
|
|
811
|
-
properties: {
|
|
812
|
-
match_key: {
|
|
813
|
-
type: 'string',
|
|
814
|
-
description: 'Match key (e.g., 2023casj_qm1)',
|
|
815
|
-
},
|
|
816
|
-
},
|
|
817
|
-
required: ['match_key'],
|
|
818
|
-
},
|
|
819
|
-
},
|
|
820
|
-
{
|
|
821
|
-
name: 'get_event_oprs',
|
|
822
|
-
description: 'Get OPR, DPR, and CCWM ratings for teams at an event',
|
|
823
|
-
inputSchema: {
|
|
824
|
-
type: 'object',
|
|
825
|
-
properties: {
|
|
826
|
-
event_key: {
|
|
827
|
-
type: 'string',
|
|
828
|
-
description: 'Event key (e.g., 2023casj)',
|
|
829
|
-
},
|
|
830
|
-
},
|
|
831
|
-
required: ['event_key'],
|
|
832
|
-
},
|
|
833
|
-
},
|
|
834
|
-
{
|
|
835
|
-
name: 'get_event_awards',
|
|
836
|
-
description: 'Get awards from a specific event',
|
|
837
|
-
inputSchema: {
|
|
838
|
-
type: 'object',
|
|
839
|
-
properties: {
|
|
840
|
-
event_key: {
|
|
841
|
-
type: 'string',
|
|
842
|
-
description: 'Event key (e.g., 2023casj)',
|
|
843
|
-
},
|
|
844
|
-
},
|
|
845
|
-
required: ['event_key'],
|
|
846
|
-
},
|
|
847
|
-
},
|
|
848
|
-
{
|
|
849
|
-
name: 'get_team_awards_all',
|
|
850
|
-
description: 'Get all awards won by a team across all years',
|
|
851
|
-
inputSchema: {
|
|
852
|
-
type: 'object',
|
|
853
|
-
properties: {
|
|
854
|
-
team_key: {
|
|
855
|
-
type: 'string',
|
|
856
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
857
|
-
pattern: '^frc\\d+$',
|
|
858
|
-
},
|
|
859
|
-
},
|
|
860
|
-
required: ['team_key'],
|
|
861
|
-
},
|
|
862
|
-
},
|
|
863
|
-
{
|
|
864
|
-
name: 'get_team_events_all',
|
|
865
|
-
description: 'Get all events a team has participated in across all years',
|
|
866
|
-
inputSchema: {
|
|
867
|
-
type: 'object',
|
|
868
|
-
properties: {
|
|
869
|
-
team_key: {
|
|
870
|
-
type: 'string',
|
|
871
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
872
|
-
pattern: '^frc\\d+$',
|
|
873
|
-
},
|
|
874
|
-
},
|
|
875
|
-
required: ['team_key'],
|
|
876
|
-
},
|
|
877
|
-
},
|
|
878
|
-
{
|
|
879
|
-
name: 'get_team_event_status',
|
|
880
|
-
description: 'Get team competition rank and status at a specific event',
|
|
881
|
-
inputSchema: {
|
|
882
|
-
type: 'object',
|
|
883
|
-
properties: {
|
|
884
|
-
team_key: {
|
|
885
|
-
type: 'string',
|
|
886
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
887
|
-
pattern: '^frc\\d+$',
|
|
888
|
-
},
|
|
889
|
-
event_key: {
|
|
890
|
-
type: 'string',
|
|
891
|
-
description: 'Event key (e.g., 2023casj)',
|
|
892
|
-
},
|
|
893
|
-
},
|
|
894
|
-
required: ['team_key', 'event_key'],
|
|
895
|
-
},
|
|
896
|
-
},
|
|
897
|
-
{
|
|
898
|
-
name: 'get_districts',
|
|
899
|
-
description: 'Get all districts for a specific year',
|
|
900
|
-
inputSchema: {
|
|
901
|
-
type: 'object',
|
|
902
|
-
properties: {
|
|
903
|
-
year: {
|
|
904
|
-
type: 'number',
|
|
905
|
-
description: 'Competition year',
|
|
906
|
-
minimum: 1992,
|
|
907
|
-
maximum: new Date().getFullYear() + 1,
|
|
908
|
-
},
|
|
909
|
-
},
|
|
910
|
-
required: ['year'],
|
|
911
|
-
},
|
|
912
|
-
},
|
|
913
|
-
{
|
|
914
|
-
name: 'get_district_rankings',
|
|
915
|
-
description: 'Get team rankings within a district',
|
|
916
|
-
inputSchema: {
|
|
917
|
-
type: 'object',
|
|
918
|
-
properties: {
|
|
919
|
-
district_key: {
|
|
920
|
-
type: 'string',
|
|
921
|
-
description: 'District key (e.g., 2023fim)',
|
|
922
|
-
},
|
|
923
|
-
},
|
|
924
|
-
required: ['district_key'],
|
|
925
|
-
},
|
|
926
|
-
},
|
|
927
|
-
{
|
|
928
|
-
name: 'get_teams_simple',
|
|
929
|
-
description: 'Get simplified list of teams with pagination',
|
|
930
|
-
inputSchema: {
|
|
931
|
-
type: 'object',
|
|
932
|
-
properties: {
|
|
933
|
-
page_num: {
|
|
934
|
-
type: 'number',
|
|
935
|
-
description: 'Page number (0-indexed)',
|
|
936
|
-
minimum: 0,
|
|
937
|
-
},
|
|
938
|
-
},
|
|
939
|
-
required: ['page_num'],
|
|
940
|
-
},
|
|
941
|
-
},
|
|
942
|
-
{
|
|
943
|
-
name: 'get_teams_keys',
|
|
944
|
-
description: 'Get list of team keys with pagination',
|
|
945
|
-
inputSchema: {
|
|
946
|
-
type: 'object',
|
|
947
|
-
properties: {
|
|
948
|
-
page_num: {
|
|
949
|
-
type: 'number',
|
|
950
|
-
description: 'Page number (0-indexed)',
|
|
951
|
-
minimum: 0,
|
|
952
|
-
},
|
|
953
|
-
},
|
|
954
|
-
required: ['page_num'],
|
|
955
|
-
},
|
|
956
|
-
},
|
|
957
|
-
{
|
|
958
|
-
name: 'get_teams_by_year',
|
|
959
|
-
description: 'Get teams that competed in a specific year',
|
|
960
|
-
inputSchema: {
|
|
961
|
-
type: 'object',
|
|
962
|
-
properties: {
|
|
963
|
-
year: {
|
|
964
|
-
type: 'number',
|
|
965
|
-
description: 'Competition year',
|
|
966
|
-
minimum: 1992,
|
|
967
|
-
maximum: new Date().getFullYear() + 1,
|
|
968
|
-
},
|
|
969
|
-
page_num: {
|
|
970
|
-
type: 'number',
|
|
971
|
-
description: 'Page number (0-indexed)',
|
|
972
|
-
minimum: 0,
|
|
973
|
-
},
|
|
974
|
-
},
|
|
975
|
-
required: ['year', 'page_num'],
|
|
976
|
-
},
|
|
977
|
-
},
|
|
978
|
-
{
|
|
979
|
-
name: 'get_teams_by_year_simple',
|
|
980
|
-
description: 'Get simplified teams that competed in a specific year',
|
|
981
|
-
inputSchema: {
|
|
982
|
-
type: 'object',
|
|
983
|
-
properties: {
|
|
984
|
-
year: {
|
|
985
|
-
type: 'number',
|
|
986
|
-
description: 'Competition year',
|
|
987
|
-
minimum: 1992,
|
|
988
|
-
maximum: new Date().getFullYear() + 1,
|
|
989
|
-
},
|
|
990
|
-
page_num: {
|
|
991
|
-
type: 'number',
|
|
992
|
-
description: 'Page number (0-indexed)',
|
|
993
|
-
minimum: 0,
|
|
994
|
-
},
|
|
995
|
-
},
|
|
996
|
-
required: ['year', 'page_num'],
|
|
997
|
-
},
|
|
998
|
-
},
|
|
999
|
-
{
|
|
1000
|
-
name: 'get_teams_by_year_keys',
|
|
1001
|
-
description: 'Get team keys that competed in a specific year',
|
|
1002
|
-
inputSchema: {
|
|
1003
|
-
type: 'object',
|
|
1004
|
-
properties: {
|
|
1005
|
-
year: {
|
|
1006
|
-
type: 'number',
|
|
1007
|
-
description: 'Competition year',
|
|
1008
|
-
minimum: 1992,
|
|
1009
|
-
maximum: new Date().getFullYear() + 1,
|
|
1010
|
-
},
|
|
1011
|
-
page_num: {
|
|
1012
|
-
type: 'number',
|
|
1013
|
-
description: 'Page number (0-indexed)',
|
|
1014
|
-
minimum: 0,
|
|
1015
|
-
},
|
|
1016
|
-
},
|
|
1017
|
-
required: ['year', 'page_num'],
|
|
1018
|
-
},
|
|
1019
|
-
},
|
|
1020
|
-
{
|
|
1021
|
-
name: 'get_team_simple',
|
|
1022
|
-
description: 'Get simplified information about a specific team',
|
|
1023
|
-
inputSchema: {
|
|
1024
|
-
type: 'object',
|
|
1025
|
-
properties: {
|
|
1026
|
-
team_key: {
|
|
1027
|
-
type: 'string',
|
|
1028
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1029
|
-
pattern: '^frc\\d+$',
|
|
1030
|
-
},
|
|
1031
|
-
},
|
|
1032
|
-
required: ['team_key'],
|
|
1033
|
-
},
|
|
1034
|
-
},
|
|
1035
|
-
{
|
|
1036
|
-
name: 'get_event_simple',
|
|
1037
|
-
description: 'Get simplified information about a specific event',
|
|
1038
|
-
inputSchema: {
|
|
1039
|
-
type: 'object',
|
|
1040
|
-
properties: {
|
|
1041
|
-
event_key: {
|
|
1042
|
-
type: 'string',
|
|
1043
|
-
description: 'Event key (e.g., 2023casj)',
|
|
1044
|
-
},
|
|
1045
|
-
},
|
|
1046
|
-
required: ['event_key'],
|
|
1047
|
-
},
|
|
1048
|
-
},
|
|
1049
|
-
{
|
|
1050
|
-
name: 'get_events_simple',
|
|
1051
|
-
description: 'Get simplified list of events for a year',
|
|
1052
|
-
inputSchema: {
|
|
1053
|
-
type: 'object',
|
|
1054
|
-
properties: {
|
|
1055
|
-
year: {
|
|
1056
|
-
type: 'number',
|
|
1057
|
-
description: 'Competition year',
|
|
1058
|
-
minimum: 1992,
|
|
1059
|
-
maximum: new Date().getFullYear() + 1,
|
|
1060
|
-
},
|
|
1061
|
-
},
|
|
1062
|
-
required: ['year'],
|
|
1063
|
-
},
|
|
1064
|
-
},
|
|
1065
|
-
{
|
|
1066
|
-
name: 'get_events_keys',
|
|
1067
|
-
description: 'Get list of event keys for a year',
|
|
1068
|
-
inputSchema: {
|
|
1069
|
-
type: 'object',
|
|
1070
|
-
properties: {
|
|
1071
|
-
year: {
|
|
1072
|
-
type: 'number',
|
|
1073
|
-
description: 'Competition year',
|
|
1074
|
-
minimum: 1992,
|
|
1075
|
-
maximum: new Date().getFullYear() + 1,
|
|
1076
|
-
},
|
|
1077
|
-
},
|
|
1078
|
-
required: ['year'],
|
|
1079
|
-
},
|
|
1080
|
-
},
|
|
1081
|
-
{
|
|
1082
|
-
name: 'get_match_simple',
|
|
1083
|
-
description: 'Get simplified information about a specific match',
|
|
1084
|
-
inputSchema: {
|
|
1085
|
-
type: 'object',
|
|
1086
|
-
properties: {
|
|
1087
|
-
match_key: {
|
|
1088
|
-
type: 'string',
|
|
1089
|
-
description: 'Match key (e.g., 2023casj_qm1)',
|
|
1090
|
-
},
|
|
1091
|
-
},
|
|
1092
|
-
required: ['match_key'],
|
|
1093
|
-
},
|
|
1094
|
-
},
|
|
1095
|
-
{
|
|
1096
|
-
name: 'get_team_events_simple',
|
|
1097
|
-
description: 'Get simplified events for a team in a specific year',
|
|
1098
|
-
inputSchema: {
|
|
1099
|
-
type: 'object',
|
|
1100
|
-
properties: {
|
|
1101
|
-
team_key: {
|
|
1102
|
-
type: 'string',
|
|
1103
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1104
|
-
pattern: '^frc\\d+$',
|
|
1105
|
-
},
|
|
1106
|
-
year: {
|
|
1107
|
-
type: 'number',
|
|
1108
|
-
description: 'Competition year',
|
|
1109
|
-
minimum: 1992,
|
|
1110
|
-
maximum: new Date().getFullYear() + 1,
|
|
1111
|
-
},
|
|
1112
|
-
},
|
|
1113
|
-
required: ['team_key', 'year'],
|
|
1114
|
-
},
|
|
1115
|
-
},
|
|
1116
|
-
{
|
|
1117
|
-
name: 'get_team_events_keys',
|
|
1118
|
-
description: 'Get event keys for a team in a specific year',
|
|
1119
|
-
inputSchema: {
|
|
1120
|
-
type: 'object',
|
|
1121
|
-
properties: {
|
|
1122
|
-
team_key: {
|
|
1123
|
-
type: 'string',
|
|
1124
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1125
|
-
pattern: '^frc\\d+$',
|
|
1126
|
-
},
|
|
1127
|
-
year: {
|
|
1128
|
-
type: 'number',
|
|
1129
|
-
description: 'Competition year',
|
|
1130
|
-
minimum: 1992,
|
|
1131
|
-
maximum: new Date().getFullYear() + 1,
|
|
1132
|
-
},
|
|
1133
|
-
},
|
|
1134
|
-
required: ['team_key', 'year'],
|
|
1135
|
-
},
|
|
1136
|
-
},
|
|
1137
|
-
{
|
|
1138
|
-
name: 'get_team_event_awards',
|
|
1139
|
-
description: 'Get awards won by a team at a specific event',
|
|
1140
|
-
inputSchema: {
|
|
1141
|
-
type: 'object',
|
|
1142
|
-
properties: {
|
|
1143
|
-
team_key: {
|
|
1144
|
-
type: 'string',
|
|
1145
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1146
|
-
pattern: '^frc\\d+$',
|
|
1147
|
-
},
|
|
1148
|
-
event_key: {
|
|
1149
|
-
type: 'string',
|
|
1150
|
-
description: 'Event key (e.g., 2023casj)',
|
|
1151
|
-
},
|
|
1152
|
-
},
|
|
1153
|
-
required: ['team_key', 'event_key'],
|
|
1154
|
-
},
|
|
1155
|
-
},
|
|
1156
|
-
{
|
|
1157
|
-
name: 'get_team_matches_simple',
|
|
1158
|
-
description: 'Get simplified matches for a team in a specific year',
|
|
1159
|
-
inputSchema: {
|
|
1160
|
-
type: 'object',
|
|
1161
|
-
properties: {
|
|
1162
|
-
team_key: {
|
|
1163
|
-
type: 'string',
|
|
1164
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1165
|
-
pattern: '^frc\\d+$',
|
|
1166
|
-
},
|
|
1167
|
-
year: {
|
|
1168
|
-
type: 'number',
|
|
1169
|
-
description: 'Competition year',
|
|
1170
|
-
minimum: 1992,
|
|
1171
|
-
maximum: new Date().getFullYear() + 1,
|
|
1172
|
-
},
|
|
1173
|
-
},
|
|
1174
|
-
required: ['team_key', 'year'],
|
|
1175
|
-
},
|
|
1176
|
-
},
|
|
1177
|
-
{
|
|
1178
|
-
name: 'get_team_matches_keys',
|
|
1179
|
-
description: 'Get match keys for a team in a specific year',
|
|
1180
|
-
inputSchema: {
|
|
1181
|
-
type: 'object',
|
|
1182
|
-
properties: {
|
|
1183
|
-
team_key: {
|
|
1184
|
-
type: 'string',
|
|
1185
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1186
|
-
pattern: '^frc\\d+$',
|
|
1187
|
-
},
|
|
1188
|
-
year: {
|
|
1189
|
-
type: 'number',
|
|
1190
|
-
description: 'Competition year',
|
|
1191
|
-
minimum: 1992,
|
|
1192
|
-
maximum: new Date().getFullYear() + 1,
|
|
1193
|
-
},
|
|
1194
|
-
},
|
|
1195
|
-
required: ['team_key', 'year'],
|
|
1196
|
-
},
|
|
1197
|
-
},
|
|
1198
|
-
{
|
|
1199
|
-
name: 'get_team_social_media',
|
|
1200
|
-
description: 'Get social media information for a team',
|
|
1201
|
-
inputSchema: {
|
|
1202
|
-
type: 'object',
|
|
1203
|
-
properties: {
|
|
1204
|
-
team_key: {
|
|
1205
|
-
type: 'string',
|
|
1206
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1207
|
-
pattern: '^frc\\d+$',
|
|
1208
|
-
},
|
|
1209
|
-
},
|
|
1210
|
-
required: ['team_key'],
|
|
1211
|
-
},
|
|
1212
|
-
},
|
|
1213
|
-
{
|
|
1214
|
-
name: 'get_team_media_by_tag',
|
|
1215
|
-
description: 'Get media for a team filtered by tag',
|
|
1216
|
-
inputSchema: {
|
|
1217
|
-
type: 'object',
|
|
1218
|
-
properties: {
|
|
1219
|
-
team_key: {
|
|
1220
|
-
type: 'string',
|
|
1221
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1222
|
-
pattern: '^frc\\d+$',
|
|
1223
|
-
},
|
|
1224
|
-
media_tag: {
|
|
1225
|
-
type: 'string',
|
|
1226
|
-
description: 'Media tag to filter by',
|
|
1227
|
-
},
|
|
1228
|
-
},
|
|
1229
|
-
required: ['team_key', 'media_tag'],
|
|
1230
|
-
},
|
|
1231
|
-
},
|
|
1232
|
-
{
|
|
1233
|
-
name: 'get_team_media_by_tag_year',
|
|
1234
|
-
description: 'Get media for a team filtered by tag and year',
|
|
1235
|
-
inputSchema: {
|
|
1236
|
-
type: 'object',
|
|
1237
|
-
properties: {
|
|
1238
|
-
team_key: {
|
|
1239
|
-
type: 'string',
|
|
1240
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1241
|
-
pattern: '^frc\\d+$',
|
|
1242
|
-
},
|
|
1243
|
-
media_tag: {
|
|
1244
|
-
type: 'string',
|
|
1245
|
-
description: 'Media tag to filter by',
|
|
1246
|
-
},
|
|
1247
|
-
year: {
|
|
1248
|
-
type: 'number',
|
|
1249
|
-
description: 'Competition year',
|
|
1250
|
-
minimum: 1992,
|
|
1251
|
-
maximum: new Date().getFullYear() + 1,
|
|
1252
|
-
},
|
|
1253
|
-
},
|
|
1254
|
-
required: ['team_key', 'media_tag', 'year'],
|
|
1255
|
-
},
|
|
1256
|
-
},
|
|
1257
|
-
{
|
|
1258
|
-
name: 'get_event_teams_simple',
|
|
1259
|
-
description: 'Get simplified teams participating in an event',
|
|
1260
|
-
inputSchema: {
|
|
1261
|
-
type: 'object',
|
|
1262
|
-
properties: {
|
|
1263
|
-
event_key: {
|
|
1264
|
-
type: 'string',
|
|
1265
|
-
description: 'Event key (e.g., 2023casj)',
|
|
1266
|
-
},
|
|
1267
|
-
},
|
|
1268
|
-
required: ['event_key'],
|
|
1269
|
-
},
|
|
1270
|
-
},
|
|
1271
|
-
{
|
|
1272
|
-
name: 'get_event_teams_keys',
|
|
1273
|
-
description: 'Get team keys participating in an event',
|
|
1274
|
-
inputSchema: {
|
|
1275
|
-
type: 'object',
|
|
1276
|
-
properties: {
|
|
1277
|
-
event_key: {
|
|
1278
|
-
type: 'string',
|
|
1279
|
-
description: 'Event key (e.g., 2023casj)',
|
|
1280
|
-
},
|
|
1281
|
-
},
|
|
1282
|
-
required: ['event_key'],
|
|
1283
|
-
},
|
|
1284
|
-
},
|
|
1285
|
-
{
|
|
1286
|
-
name: 'get_event_matches_simple',
|
|
1287
|
-
description: 'Get simplified matches for an event',
|
|
1288
|
-
inputSchema: {
|
|
1289
|
-
type: 'object',
|
|
1290
|
-
properties: {
|
|
1291
|
-
event_key: {
|
|
1292
|
-
type: 'string',
|
|
1293
|
-
description: 'Event key (e.g., 2023casj)',
|
|
1294
|
-
},
|
|
1295
|
-
},
|
|
1296
|
-
required: ['event_key'],
|
|
1297
|
-
},
|
|
1298
|
-
},
|
|
1299
|
-
{
|
|
1300
|
-
name: 'get_event_matches_keys',
|
|
1301
|
-
description: 'Get match keys for an event',
|
|
1302
|
-
inputSchema: {
|
|
1303
|
-
type: 'object',
|
|
1304
|
-
properties: {
|
|
1305
|
-
event_key: {
|
|
1306
|
-
type: 'string',
|
|
1307
|
-
description: 'Event key (e.g., 2023casj)',
|
|
1308
|
-
},
|
|
1309
|
-
},
|
|
1310
|
-
required: ['event_key'],
|
|
1311
|
-
},
|
|
1312
|
-
},
|
|
1313
|
-
{
|
|
1314
|
-
name: 'get_event_predictions',
|
|
1315
|
-
description: 'Get TBA-generated predictions for an event',
|
|
1316
|
-
inputSchema: {
|
|
1317
|
-
type: 'object',
|
|
1318
|
-
properties: {
|
|
1319
|
-
event_key: {
|
|
1320
|
-
type: 'string',
|
|
1321
|
-
description: 'Event key (e.g., 2023casj)',
|
|
1322
|
-
},
|
|
1323
|
-
},
|
|
1324
|
-
required: ['event_key'],
|
|
1325
|
-
},
|
|
1326
|
-
},
|
|
1327
|
-
{
|
|
1328
|
-
name: 'get_match_zebra',
|
|
1329
|
-
description: 'Get Zebra MotionWorks data for a match',
|
|
1330
|
-
inputSchema: {
|
|
1331
|
-
type: 'object',
|
|
1332
|
-
properties: {
|
|
1333
|
-
match_key: {
|
|
1334
|
-
type: 'string',
|
|
1335
|
-
description: 'Match key (e.g., 2023casj_qm1)',
|
|
1336
|
-
},
|
|
1337
|
-
},
|
|
1338
|
-
required: ['match_key'],
|
|
1339
|
-
},
|
|
1340
|
-
},
|
|
1341
|
-
{
|
|
1342
|
-
name: 'get_team_history',
|
|
1343
|
-
description: 'Get historical data for a team across all years',
|
|
1344
|
-
inputSchema: {
|
|
1345
|
-
type: 'object',
|
|
1346
|
-
properties: {
|
|
1347
|
-
team_key: {
|
|
1348
|
-
type: 'string',
|
|
1349
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1350
|
-
pattern: '^frc\\d+$',
|
|
1351
|
-
},
|
|
1352
|
-
},
|
|
1353
|
-
required: ['team_key'],
|
|
1354
|
-
},
|
|
1355
|
-
},
|
|
1356
|
-
{
|
|
1357
|
-
name: 'get_team_event_statuses',
|
|
1358
|
-
description: 'Get team event statuses for all events in a year',
|
|
1359
|
-
inputSchema: {
|
|
1360
|
-
type: 'object',
|
|
1361
|
-
properties: {
|
|
1362
|
-
team_key: {
|
|
1363
|
-
type: 'string',
|
|
1364
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1365
|
-
pattern: '^frc\\d+$',
|
|
1366
|
-
},
|
|
1367
|
-
year: {
|
|
1368
|
-
type: 'number',
|
|
1369
|
-
description: 'Competition year',
|
|
1370
|
-
minimum: 1992,
|
|
1371
|
-
maximum: new Date().getFullYear() + 1,
|
|
1372
|
-
},
|
|
1373
|
-
},
|
|
1374
|
-
required: ['team_key', 'year'],
|
|
1375
|
-
},
|
|
1376
|
-
},
|
|
1377
|
-
{
|
|
1378
|
-
name: 'get_team_event_matches_simple',
|
|
1379
|
-
description: 'Get simplified matches for a team at a specific event',
|
|
1380
|
-
inputSchema: {
|
|
1381
|
-
type: 'object',
|
|
1382
|
-
properties: {
|
|
1383
|
-
team_key: {
|
|
1384
|
-
type: 'string',
|
|
1385
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1386
|
-
pattern: '^frc\\d+$',
|
|
1387
|
-
},
|
|
1388
|
-
event_key: {
|
|
1389
|
-
type: 'string',
|
|
1390
|
-
description: 'Event key (e.g., 2023casj)',
|
|
1391
|
-
},
|
|
1392
|
-
},
|
|
1393
|
-
required: ['team_key', 'event_key'],
|
|
1394
|
-
},
|
|
1395
|
-
},
|
|
1396
|
-
{
|
|
1397
|
-
name: 'get_team_event_matches_keys',
|
|
1398
|
-
description: 'Get match keys for a team at a specific event',
|
|
1399
|
-
inputSchema: {
|
|
1400
|
-
type: 'object',
|
|
1401
|
-
properties: {
|
|
1402
|
-
team_key: {
|
|
1403
|
-
type: 'string',
|
|
1404
|
-
description: 'Team key in format frcXXXX (e.g., frc86)',
|
|
1405
|
-
pattern: '^frc\\d+$',
|
|
1406
|
-
},
|
|
1407
|
-
event_key: {
|
|
1408
|
-
type: 'string',
|
|
1409
|
-
description: 'Event key (e.g., 2023casj)',
|
|
1410
|
-
},
|
|
1411
|
-
},
|
|
1412
|
-
required: ['team_key', 'event_key'],
|
|
1413
|
-
},
|
|
1414
|
-
},
|
|
1415
|
-
{
|
|
1416
|
-
name: 'get_district_events',
|
|
1417
|
-
description: 'Get events in a specific district',
|
|
1418
|
-
inputSchema: {
|
|
1419
|
-
type: 'object',
|
|
1420
|
-
properties: {
|
|
1421
|
-
district_key: {
|
|
1422
|
-
type: 'string',
|
|
1423
|
-
description: 'District key (e.g., 2023fim)',
|
|
1424
|
-
},
|
|
1425
|
-
},
|
|
1426
|
-
required: ['district_key'],
|
|
1427
|
-
},
|
|
1428
|
-
},
|
|
1429
|
-
{
|
|
1430
|
-
name: 'get_district_events_simple',
|
|
1431
|
-
description: 'Get simplified events in a specific district',
|
|
1432
|
-
inputSchema: {
|
|
1433
|
-
type: 'object',
|
|
1434
|
-
properties: {
|
|
1435
|
-
district_key: {
|
|
1436
|
-
type: 'string',
|
|
1437
|
-
description: 'District key (e.g., 2023fim)',
|
|
1438
|
-
},
|
|
1439
|
-
},
|
|
1440
|
-
required: ['district_key'],
|
|
1441
|
-
},
|
|
1442
|
-
},
|
|
1443
|
-
{
|
|
1444
|
-
name: 'get_district_events_keys',
|
|
1445
|
-
description: 'Get event keys in a specific district',
|
|
1446
|
-
inputSchema: {
|
|
1447
|
-
type: 'object',
|
|
1448
|
-
properties: {
|
|
1449
|
-
district_key: {
|
|
1450
|
-
type: 'string',
|
|
1451
|
-
description: 'District key (e.g., 2023fim)',
|
|
1452
|
-
},
|
|
1453
|
-
},
|
|
1454
|
-
required: ['district_key'],
|
|
1455
|
-
},
|
|
1456
|
-
},
|
|
1457
|
-
{
|
|
1458
|
-
name: 'get_district_teams',
|
|
1459
|
-
description: 'Get teams in a specific district',
|
|
1460
|
-
inputSchema: {
|
|
1461
|
-
type: 'object',
|
|
1462
|
-
properties: {
|
|
1463
|
-
district_key: {
|
|
1464
|
-
type: 'string',
|
|
1465
|
-
description: 'District key (e.g., 2023fim)',
|
|
1466
|
-
},
|
|
1467
|
-
},
|
|
1468
|
-
required: ['district_key'],
|
|
1469
|
-
},
|
|
1470
|
-
},
|
|
1471
|
-
{
|
|
1472
|
-
name: 'get_district_teams_simple',
|
|
1473
|
-
description: 'Get simplified teams in a specific district',
|
|
1474
|
-
inputSchema: {
|
|
1475
|
-
type: 'object',
|
|
1476
|
-
properties: {
|
|
1477
|
-
district_key: {
|
|
1478
|
-
type: 'string',
|
|
1479
|
-
description: 'District key (e.g., 2023fim)',
|
|
1480
|
-
},
|
|
1481
|
-
},
|
|
1482
|
-
required: ['district_key'],
|
|
1483
|
-
},
|
|
1484
|
-
},
|
|
1485
|
-
{
|
|
1486
|
-
name: 'get_district_teams_keys',
|
|
1487
|
-
description: 'Get team keys in a specific district',
|
|
1488
|
-
inputSchema: {
|
|
1489
|
-
type: 'object',
|
|
1490
|
-
properties: {
|
|
1491
|
-
district_key: {
|
|
1492
|
-
type: 'string',
|
|
1493
|
-
description: 'District key (e.g., 2023fim)',
|
|
1494
|
-
},
|
|
1495
|
-
},
|
|
1496
|
-
required: ['district_key'],
|
|
1497
|
-
},
|
|
1498
|
-
},
|
|
1499
|
-
],
|
|
1500
|
-
};
|
|
34
|
+
return { tools };
|
|
1501
35
|
});
|
|
1502
36
|
server.setRequestHandler(CallToolRequestSchema, async (request) => {
|
|
1503
37
|
const { name, arguments: args } = request.params;
|
|
1504
|
-
await log('debug', `Processing tool request: ${name}
|
|
38
|
+
await log('debug', `Processing tool request: ${name}`, server);
|
|
1505
39
|
try {
|
|
1506
|
-
|
|
1507
|
-
case 'get_team': {
|
|
1508
|
-
const { team_key } = z
|
|
1509
|
-
.object({ team_key: TeamKeySchema })
|
|
1510
|
-
.parse(args);
|
|
1511
|
-
const data = await makeApiRequest(`/team/${team_key}`);
|
|
1512
|
-
const team = TeamSchema.parse(data);
|
|
1513
|
-
return {
|
|
1514
|
-
content: [
|
|
1515
|
-
{
|
|
1516
|
-
type: 'text',
|
|
1517
|
-
text: JSON.stringify(team, null, 2),
|
|
1518
|
-
},
|
|
1519
|
-
],
|
|
1520
|
-
};
|
|
1521
|
-
}
|
|
1522
|
-
case 'get_team_events': {
|
|
1523
|
-
const { team_key, year } = z
|
|
1524
|
-
.object({
|
|
1525
|
-
team_key: TeamKeySchema,
|
|
1526
|
-
year: YearSchema,
|
|
1527
|
-
})
|
|
1528
|
-
.parse(args);
|
|
1529
|
-
const data = await makeApiRequest(`/team/${team_key}/events/${year}`);
|
|
1530
|
-
const events = z.array(EventSchema).parse(data);
|
|
1531
|
-
return {
|
|
1532
|
-
content: [
|
|
1533
|
-
{
|
|
1534
|
-
type: 'text',
|
|
1535
|
-
text: JSON.stringify(events, null, 2),
|
|
1536
|
-
},
|
|
1537
|
-
],
|
|
1538
|
-
};
|
|
1539
|
-
}
|
|
1540
|
-
case 'get_team_awards': {
|
|
1541
|
-
const { team_key, year } = z
|
|
1542
|
-
.object({
|
|
1543
|
-
team_key: TeamKeySchema,
|
|
1544
|
-
year: YearSchema,
|
|
1545
|
-
})
|
|
1546
|
-
.parse(args);
|
|
1547
|
-
const data = await makeApiRequest(`/team/${team_key}/awards/${year}`);
|
|
1548
|
-
const awards = z.array(AwardSchema).parse(data);
|
|
1549
|
-
return {
|
|
1550
|
-
content: [
|
|
1551
|
-
{
|
|
1552
|
-
type: 'text',
|
|
1553
|
-
text: JSON.stringify(awards, null, 2),
|
|
1554
|
-
},
|
|
1555
|
-
],
|
|
1556
|
-
};
|
|
1557
|
-
}
|
|
1558
|
-
case 'get_team_matches': {
|
|
1559
|
-
const { team_key, year } = z
|
|
1560
|
-
.object({
|
|
1561
|
-
team_key: TeamKeySchema,
|
|
1562
|
-
year: YearSchema,
|
|
1563
|
-
})
|
|
1564
|
-
.parse(args);
|
|
1565
|
-
const data = await makeApiRequest(`/team/${team_key}/matches/${year}`);
|
|
1566
|
-
const matches = z.array(MatchSchema).parse(data);
|
|
1567
|
-
return {
|
|
1568
|
-
content: [
|
|
1569
|
-
{
|
|
1570
|
-
type: 'text',
|
|
1571
|
-
text: JSON.stringify(matches, null, 2),
|
|
1572
|
-
},
|
|
1573
|
-
],
|
|
1574
|
-
};
|
|
1575
|
-
}
|
|
1576
|
-
case 'get_events': {
|
|
1577
|
-
const { year } = z.object({ year: YearSchema }).parse(args);
|
|
1578
|
-
const data = await makeApiRequest(`/events/${year}`);
|
|
1579
|
-
const events = z.array(EventSchema).parse(data);
|
|
1580
|
-
return {
|
|
1581
|
-
content: [
|
|
1582
|
-
{
|
|
1583
|
-
type: 'text',
|
|
1584
|
-
text: JSON.stringify(events, null, 2),
|
|
1585
|
-
},
|
|
1586
|
-
],
|
|
1587
|
-
};
|
|
1588
|
-
}
|
|
1589
|
-
case 'get_event': {
|
|
1590
|
-
const { event_key } = z
|
|
1591
|
-
.object({ event_key: EventKeySchema })
|
|
1592
|
-
.parse(args);
|
|
1593
|
-
const data = await makeApiRequest(`/event/${event_key}`);
|
|
1594
|
-
const event = EventSchema.parse(data);
|
|
1595
|
-
return {
|
|
1596
|
-
content: [
|
|
1597
|
-
{
|
|
1598
|
-
type: 'text',
|
|
1599
|
-
text: JSON.stringify(event, null, 2),
|
|
1600
|
-
},
|
|
1601
|
-
],
|
|
1602
|
-
};
|
|
1603
|
-
}
|
|
1604
|
-
case 'get_event_teams': {
|
|
1605
|
-
const { event_key } = z
|
|
1606
|
-
.object({ event_key: EventKeySchema })
|
|
1607
|
-
.parse(args);
|
|
1608
|
-
const data = await makeApiRequest(`/event/${event_key}/teams`);
|
|
1609
|
-
const teams = z.array(TeamSchema).parse(data);
|
|
1610
|
-
return {
|
|
1611
|
-
content: [
|
|
1612
|
-
{
|
|
1613
|
-
type: 'text',
|
|
1614
|
-
text: JSON.stringify(teams, null, 2),
|
|
1615
|
-
},
|
|
1616
|
-
],
|
|
1617
|
-
};
|
|
1618
|
-
}
|
|
1619
|
-
case 'get_event_rankings': {
|
|
1620
|
-
const { event_key } = z
|
|
1621
|
-
.object({ event_key: EventKeySchema })
|
|
1622
|
-
.parse(args);
|
|
1623
|
-
const data = await makeApiRequest(`/event/${event_key}/rankings`);
|
|
1624
|
-
const rankings = RankingSchema.parse(data);
|
|
1625
|
-
return {
|
|
1626
|
-
content: [
|
|
1627
|
-
{
|
|
1628
|
-
type: 'text',
|
|
1629
|
-
text: JSON.stringify(rankings, null, 2),
|
|
1630
|
-
},
|
|
1631
|
-
],
|
|
1632
|
-
};
|
|
1633
|
-
}
|
|
1634
|
-
case 'get_event_matches': {
|
|
1635
|
-
const { event_key } = z
|
|
1636
|
-
.object({ event_key: EventKeySchema })
|
|
1637
|
-
.parse(args);
|
|
1638
|
-
const data = await makeApiRequest(`/event/${event_key}/matches`);
|
|
1639
|
-
const matches = z.array(MatchSchema).parse(data);
|
|
1640
|
-
return {
|
|
1641
|
-
content: [
|
|
1642
|
-
{
|
|
1643
|
-
type: 'text',
|
|
1644
|
-
text: JSON.stringify(matches, null, 2),
|
|
1645
|
-
},
|
|
1646
|
-
],
|
|
1647
|
-
};
|
|
1648
|
-
}
|
|
1649
|
-
case 'get_event_alliances': {
|
|
1650
|
-
const { event_key } = z
|
|
1651
|
-
.object({ event_key: EventKeySchema })
|
|
1652
|
-
.parse(args);
|
|
1653
|
-
const data = await makeApiRequest(`/event/${event_key}/alliances`);
|
|
1654
|
-
const alliances = z.array(AllianceSchema).parse(data);
|
|
1655
|
-
return {
|
|
1656
|
-
content: [
|
|
1657
|
-
{
|
|
1658
|
-
type: 'text',
|
|
1659
|
-
text: JSON.stringify(alliances, null, 2),
|
|
1660
|
-
},
|
|
1661
|
-
],
|
|
1662
|
-
};
|
|
1663
|
-
}
|
|
1664
|
-
case 'get_event_insights': {
|
|
1665
|
-
const { event_key } = z
|
|
1666
|
-
.object({ event_key: EventKeySchema })
|
|
1667
|
-
.parse(args);
|
|
1668
|
-
const data = await makeApiRequest(`/event/${event_key}/insights`);
|
|
1669
|
-
const insights = InsightsSchema.parse(data);
|
|
1670
|
-
return {
|
|
1671
|
-
content: [
|
|
1672
|
-
{
|
|
1673
|
-
type: 'text',
|
|
1674
|
-
text: JSON.stringify(insights, null, 2),
|
|
1675
|
-
},
|
|
1676
|
-
],
|
|
1677
|
-
};
|
|
1678
|
-
}
|
|
1679
|
-
case 'get_event_district_points': {
|
|
1680
|
-
const { event_key } = z
|
|
1681
|
-
.object({ event_key: EventKeySchema })
|
|
1682
|
-
.parse(args);
|
|
1683
|
-
const data = await makeApiRequest(`/event/${event_key}/district_points`);
|
|
1684
|
-
const districtPoints = DistrictPointsSchema.parse(data);
|
|
1685
|
-
return {
|
|
1686
|
-
content: [
|
|
1687
|
-
{
|
|
1688
|
-
type: 'text',
|
|
1689
|
-
text: JSON.stringify(districtPoints, null, 2),
|
|
1690
|
-
},
|
|
1691
|
-
],
|
|
1692
|
-
};
|
|
1693
|
-
}
|
|
1694
|
-
case 'get_team_years_participated': {
|
|
1695
|
-
const { team_key } = z
|
|
1696
|
-
.object({ team_key: TeamKeySchema })
|
|
1697
|
-
.parse(args);
|
|
1698
|
-
const data = await makeApiRequest(`/team/${team_key}/years_participated`);
|
|
1699
|
-
const years = z.array(z.number()).parse(data);
|
|
1700
|
-
return {
|
|
1701
|
-
content: [
|
|
1702
|
-
{
|
|
1703
|
-
type: 'text',
|
|
1704
|
-
text: JSON.stringify(years, null, 2),
|
|
1705
|
-
},
|
|
1706
|
-
],
|
|
1707
|
-
};
|
|
1708
|
-
}
|
|
1709
|
-
case 'get_team_districts': {
|
|
1710
|
-
const { team_key } = z
|
|
1711
|
-
.object({ team_key: TeamKeySchema })
|
|
1712
|
-
.parse(args);
|
|
1713
|
-
const data = await makeApiRequest(`/team/${team_key}/districts`);
|
|
1714
|
-
const districts = z.array(DistrictSchema).parse(data);
|
|
1715
|
-
return {
|
|
1716
|
-
content: [
|
|
1717
|
-
{
|
|
1718
|
-
type: 'text',
|
|
1719
|
-
text: JSON.stringify(districts, null, 2),
|
|
1720
|
-
},
|
|
1721
|
-
],
|
|
1722
|
-
};
|
|
1723
|
-
}
|
|
1724
|
-
case 'get_team_robots': {
|
|
1725
|
-
const { team_key } = z
|
|
1726
|
-
.object({ team_key: TeamKeySchema })
|
|
1727
|
-
.parse(args);
|
|
1728
|
-
const data = await makeApiRequest(`/team/${team_key}/robots`);
|
|
1729
|
-
const robots = z.array(RobotSchema).parse(data);
|
|
1730
|
-
return {
|
|
1731
|
-
content: [
|
|
1732
|
-
{
|
|
1733
|
-
type: 'text',
|
|
1734
|
-
text: JSON.stringify(robots, null, 2),
|
|
1735
|
-
},
|
|
1736
|
-
],
|
|
1737
|
-
};
|
|
1738
|
-
}
|
|
1739
|
-
case 'get_team_media': {
|
|
1740
|
-
const { team_key, year } = z
|
|
1741
|
-
.object({
|
|
1742
|
-
team_key: TeamKeySchema,
|
|
1743
|
-
year: YearSchema,
|
|
1744
|
-
})
|
|
1745
|
-
.parse(args);
|
|
1746
|
-
const data = await makeApiRequest(`/team/${team_key}/media/${year}`);
|
|
1747
|
-
const media = z.array(MediaSchema).parse(data);
|
|
1748
|
-
return {
|
|
1749
|
-
content: [
|
|
1750
|
-
{
|
|
1751
|
-
type: 'text',
|
|
1752
|
-
text: JSON.stringify(media, null, 2),
|
|
1753
|
-
},
|
|
1754
|
-
],
|
|
1755
|
-
};
|
|
1756
|
-
}
|
|
1757
|
-
case 'get_team_event_matches': {
|
|
1758
|
-
const { team_key, event_key } = z
|
|
1759
|
-
.object({
|
|
1760
|
-
team_key: TeamKeySchema,
|
|
1761
|
-
event_key: EventKeySchema,
|
|
1762
|
-
})
|
|
1763
|
-
.parse(args);
|
|
1764
|
-
const data = await makeApiRequest(`/team/${team_key}/event/${event_key}/matches`);
|
|
1765
|
-
const matches = z.array(MatchSchema).parse(data);
|
|
1766
|
-
return {
|
|
1767
|
-
content: [
|
|
1768
|
-
{
|
|
1769
|
-
type: 'text',
|
|
1770
|
-
text: JSON.stringify(matches, null, 2),
|
|
1771
|
-
},
|
|
1772
|
-
],
|
|
1773
|
-
};
|
|
1774
|
-
}
|
|
1775
|
-
case 'get_teams': {
|
|
1776
|
-
const { page_num } = z
|
|
1777
|
-
.object({ page_num: z.number().min(0) })
|
|
1778
|
-
.parse(args);
|
|
1779
|
-
const data = await makeApiRequest(`/teams/${page_num}`);
|
|
1780
|
-
const teams = z.array(TeamSchema).parse(data);
|
|
1781
|
-
return {
|
|
1782
|
-
content: [
|
|
1783
|
-
{
|
|
1784
|
-
type: 'text',
|
|
1785
|
-
text: JSON.stringify(teams, null, 2),
|
|
1786
|
-
},
|
|
1787
|
-
],
|
|
1788
|
-
};
|
|
1789
|
-
}
|
|
1790
|
-
case 'get_status': {
|
|
1791
|
-
const data = await makeApiRequest('/status');
|
|
1792
|
-
const status = StatusSchema.parse(data);
|
|
1793
|
-
return {
|
|
1794
|
-
content: [
|
|
1795
|
-
{
|
|
1796
|
-
type: 'text',
|
|
1797
|
-
text: JSON.stringify(status, null, 2),
|
|
1798
|
-
},
|
|
1799
|
-
],
|
|
1800
|
-
};
|
|
1801
|
-
}
|
|
1802
|
-
case 'get_match': {
|
|
1803
|
-
const { match_key } = z
|
|
1804
|
-
.object({ match_key: z.string() })
|
|
1805
|
-
.parse(args);
|
|
1806
|
-
const data = await makeApiRequest(`/match/${match_key}`);
|
|
1807
|
-
const match = MatchSchema.parse(data);
|
|
1808
|
-
return {
|
|
1809
|
-
content: [
|
|
1810
|
-
{
|
|
1811
|
-
type: 'text',
|
|
1812
|
-
text: JSON.stringify(match, null, 2),
|
|
1813
|
-
},
|
|
1814
|
-
],
|
|
1815
|
-
};
|
|
1816
|
-
}
|
|
1817
|
-
case 'get_event_oprs': {
|
|
1818
|
-
const { event_key } = z
|
|
1819
|
-
.object({ event_key: EventKeySchema })
|
|
1820
|
-
.parse(args);
|
|
1821
|
-
const data = await makeApiRequest(`/event/${event_key}/oprs`);
|
|
1822
|
-
const oprs = EventOPRsSchema.parse(data);
|
|
1823
|
-
return {
|
|
1824
|
-
content: [
|
|
1825
|
-
{
|
|
1826
|
-
type: 'text',
|
|
1827
|
-
text: JSON.stringify(oprs, null, 2),
|
|
1828
|
-
},
|
|
1829
|
-
],
|
|
1830
|
-
};
|
|
1831
|
-
}
|
|
1832
|
-
case 'get_event_awards': {
|
|
1833
|
-
const { event_key } = z
|
|
1834
|
-
.object({ event_key: EventKeySchema })
|
|
1835
|
-
.parse(args);
|
|
1836
|
-
const data = await makeApiRequest(`/event/${event_key}/awards`);
|
|
1837
|
-
const awards = z.array(AwardSchema).parse(data);
|
|
1838
|
-
return {
|
|
1839
|
-
content: [
|
|
1840
|
-
{
|
|
1841
|
-
type: 'text',
|
|
1842
|
-
text: JSON.stringify(awards, null, 2),
|
|
1843
|
-
},
|
|
1844
|
-
],
|
|
1845
|
-
};
|
|
1846
|
-
}
|
|
1847
|
-
case 'get_team_awards_all': {
|
|
1848
|
-
const { team_key } = z
|
|
1849
|
-
.object({ team_key: TeamKeySchema })
|
|
1850
|
-
.parse(args);
|
|
1851
|
-
const data = await makeApiRequest(`/team/${team_key}/awards`);
|
|
1852
|
-
const awards = z.array(AwardSchema).parse(data);
|
|
1853
|
-
return {
|
|
1854
|
-
content: [
|
|
1855
|
-
{
|
|
1856
|
-
type: 'text',
|
|
1857
|
-
text: JSON.stringify(awards, null, 2),
|
|
1858
|
-
},
|
|
1859
|
-
],
|
|
1860
|
-
};
|
|
1861
|
-
}
|
|
1862
|
-
case 'get_team_events_all': {
|
|
1863
|
-
const { team_key } = z
|
|
1864
|
-
.object({ team_key: TeamKeySchema })
|
|
1865
|
-
.parse(args);
|
|
1866
|
-
const data = await makeApiRequest(`/team/${team_key}/events`);
|
|
1867
|
-
const events = z.array(EventSchema).parse(data);
|
|
1868
|
-
return {
|
|
1869
|
-
content: [
|
|
1870
|
-
{
|
|
1871
|
-
type: 'text',
|
|
1872
|
-
text: JSON.stringify(events, null, 2),
|
|
1873
|
-
},
|
|
1874
|
-
],
|
|
1875
|
-
};
|
|
1876
|
-
}
|
|
1877
|
-
case 'get_team_event_status': {
|
|
1878
|
-
const { team_key, event_key } = z
|
|
1879
|
-
.object({
|
|
1880
|
-
team_key: TeamKeySchema,
|
|
1881
|
-
event_key: EventKeySchema,
|
|
1882
|
-
})
|
|
1883
|
-
.parse(args);
|
|
1884
|
-
const data = await makeApiRequest(`/team/${team_key}/event/${event_key}/status`);
|
|
1885
|
-
const status = TeamEventStatusSchema.parse(data);
|
|
1886
|
-
return {
|
|
1887
|
-
content: [
|
|
1888
|
-
{
|
|
1889
|
-
type: 'text',
|
|
1890
|
-
text: JSON.stringify(status, null, 2),
|
|
1891
|
-
},
|
|
1892
|
-
],
|
|
1893
|
-
};
|
|
1894
|
-
}
|
|
1895
|
-
case 'get_districts': {
|
|
1896
|
-
const { year } = z.object({ year: YearSchema }).parse(args);
|
|
1897
|
-
const data = await makeApiRequest(`/districts/${year}`);
|
|
1898
|
-
const districts = z.array(DistrictSchema).parse(data);
|
|
1899
|
-
return {
|
|
1900
|
-
content: [
|
|
1901
|
-
{
|
|
1902
|
-
type: 'text',
|
|
1903
|
-
text: JSON.stringify(districts, null, 2),
|
|
1904
|
-
},
|
|
1905
|
-
],
|
|
1906
|
-
};
|
|
1907
|
-
}
|
|
1908
|
-
case 'get_district_rankings': {
|
|
1909
|
-
const { district_key } = z
|
|
1910
|
-
.object({ district_key: z.string() })
|
|
1911
|
-
.parse(args);
|
|
1912
|
-
const data = await makeApiRequest(`/district/${district_key}/rankings`);
|
|
1913
|
-
const rankings = z.array(DistrictRankingSchema).parse(data);
|
|
1914
|
-
return {
|
|
1915
|
-
content: [
|
|
1916
|
-
{
|
|
1917
|
-
type: 'text',
|
|
1918
|
-
text: JSON.stringify(rankings, null, 2),
|
|
1919
|
-
},
|
|
1920
|
-
],
|
|
1921
|
-
};
|
|
1922
|
-
}
|
|
1923
|
-
case 'get_teams_simple': {
|
|
1924
|
-
const { page_num } = z
|
|
1925
|
-
.object({ page_num: z.number().min(0) })
|
|
1926
|
-
.parse(args);
|
|
1927
|
-
const data = await makeApiRequest(`/teams/${page_num}/simple`);
|
|
1928
|
-
const teams = z.array(TeamSimpleSchema).parse(data);
|
|
1929
|
-
return {
|
|
1930
|
-
content: [
|
|
1931
|
-
{
|
|
1932
|
-
type: 'text',
|
|
1933
|
-
text: JSON.stringify(teams, null, 2),
|
|
1934
|
-
},
|
|
1935
|
-
],
|
|
1936
|
-
};
|
|
1937
|
-
}
|
|
1938
|
-
case 'get_teams_keys': {
|
|
1939
|
-
const { page_num } = z
|
|
1940
|
-
.object({ page_num: z.number().min(0) })
|
|
1941
|
-
.parse(args);
|
|
1942
|
-
const data = await makeApiRequest(`/teams/${page_num}/keys`);
|
|
1943
|
-
const keys = z.array(z.string()).parse(data);
|
|
1944
|
-
return {
|
|
1945
|
-
content: [
|
|
1946
|
-
{
|
|
1947
|
-
type: 'text',
|
|
1948
|
-
text: JSON.stringify(keys, null, 2),
|
|
1949
|
-
},
|
|
1950
|
-
],
|
|
1951
|
-
};
|
|
1952
|
-
}
|
|
1953
|
-
case 'get_teams_by_year': {
|
|
1954
|
-
const { year, page_num } = z
|
|
1955
|
-
.object({
|
|
1956
|
-
year: YearSchema,
|
|
1957
|
-
page_num: z.number().min(0),
|
|
1958
|
-
})
|
|
1959
|
-
.parse(args);
|
|
1960
|
-
const data = await makeApiRequest(`/teams/${year}/${page_num}`);
|
|
1961
|
-
const teams = z.array(TeamSchema).parse(data);
|
|
1962
|
-
return {
|
|
1963
|
-
content: [
|
|
1964
|
-
{
|
|
1965
|
-
type: 'text',
|
|
1966
|
-
text: JSON.stringify(teams, null, 2),
|
|
1967
|
-
},
|
|
1968
|
-
],
|
|
1969
|
-
};
|
|
1970
|
-
}
|
|
1971
|
-
case 'get_teams_by_year_simple': {
|
|
1972
|
-
const { year, page_num } = z
|
|
1973
|
-
.object({
|
|
1974
|
-
year: YearSchema,
|
|
1975
|
-
page_num: z.number().min(0),
|
|
1976
|
-
})
|
|
1977
|
-
.parse(args);
|
|
1978
|
-
const data = await makeApiRequest(`/teams/${year}/${page_num}/simple`);
|
|
1979
|
-
const teams = z.array(TeamSimpleSchema).parse(data);
|
|
1980
|
-
return {
|
|
1981
|
-
content: [
|
|
1982
|
-
{
|
|
1983
|
-
type: 'text',
|
|
1984
|
-
text: JSON.stringify(teams, null, 2),
|
|
1985
|
-
},
|
|
1986
|
-
],
|
|
1987
|
-
};
|
|
1988
|
-
}
|
|
1989
|
-
case 'get_teams_by_year_keys': {
|
|
1990
|
-
const { year, page_num } = z
|
|
1991
|
-
.object({
|
|
1992
|
-
year: YearSchema,
|
|
1993
|
-
page_num: z.number().min(0),
|
|
1994
|
-
})
|
|
1995
|
-
.parse(args);
|
|
1996
|
-
const data = await makeApiRequest(`/teams/${year}/${page_num}/keys`);
|
|
1997
|
-
const keys = z.array(z.string()).parse(data);
|
|
1998
|
-
return {
|
|
1999
|
-
content: [
|
|
2000
|
-
{
|
|
2001
|
-
type: 'text',
|
|
2002
|
-
text: JSON.stringify(keys, null, 2),
|
|
2003
|
-
},
|
|
2004
|
-
],
|
|
2005
|
-
};
|
|
2006
|
-
}
|
|
2007
|
-
case 'get_team_simple': {
|
|
2008
|
-
const { team_key } = z
|
|
2009
|
-
.object({ team_key: TeamKeySchema })
|
|
2010
|
-
.parse(args);
|
|
2011
|
-
const data = await makeApiRequest(`/team/${team_key}/simple`);
|
|
2012
|
-
const team = TeamSimpleSchema.parse(data);
|
|
2013
|
-
return {
|
|
2014
|
-
content: [
|
|
2015
|
-
{
|
|
2016
|
-
type: 'text',
|
|
2017
|
-
text: JSON.stringify(team, null, 2),
|
|
2018
|
-
},
|
|
2019
|
-
],
|
|
2020
|
-
};
|
|
2021
|
-
}
|
|
2022
|
-
case 'get_event_simple': {
|
|
2023
|
-
const { event_key } = z
|
|
2024
|
-
.object({ event_key: EventKeySchema })
|
|
2025
|
-
.parse(args);
|
|
2026
|
-
const data = await makeApiRequest(`/event/${event_key}/simple`);
|
|
2027
|
-
const event = EventSimpleSchema.parse(data);
|
|
2028
|
-
return {
|
|
2029
|
-
content: [
|
|
2030
|
-
{
|
|
2031
|
-
type: 'text',
|
|
2032
|
-
text: JSON.stringify(event, null, 2),
|
|
2033
|
-
},
|
|
2034
|
-
],
|
|
2035
|
-
};
|
|
2036
|
-
}
|
|
2037
|
-
case 'get_events_simple': {
|
|
2038
|
-
const { year } = z.object({ year: YearSchema }).parse(args);
|
|
2039
|
-
const data = await makeApiRequest(`/events/${year}/simple`);
|
|
2040
|
-
const events = z.array(EventSimpleSchema).parse(data);
|
|
2041
|
-
return {
|
|
2042
|
-
content: [
|
|
2043
|
-
{
|
|
2044
|
-
type: 'text',
|
|
2045
|
-
text: JSON.stringify(events, null, 2),
|
|
2046
|
-
},
|
|
2047
|
-
],
|
|
2048
|
-
};
|
|
2049
|
-
}
|
|
2050
|
-
case 'get_events_keys': {
|
|
2051
|
-
const { year } = z.object({ year: YearSchema }).parse(args);
|
|
2052
|
-
const data = await makeApiRequest(`/events/${year}/keys`);
|
|
2053
|
-
const keys = z.array(z.string()).parse(data);
|
|
2054
|
-
return {
|
|
2055
|
-
content: [
|
|
2056
|
-
{
|
|
2057
|
-
type: 'text',
|
|
2058
|
-
text: JSON.stringify(keys, null, 2),
|
|
2059
|
-
},
|
|
2060
|
-
],
|
|
2061
|
-
};
|
|
2062
|
-
}
|
|
2063
|
-
case 'get_match_simple': {
|
|
2064
|
-
const { match_key } = z
|
|
2065
|
-
.object({ match_key: z.string() })
|
|
2066
|
-
.parse(args);
|
|
2067
|
-
const data = await makeApiRequest(`/match/${match_key}/simple`);
|
|
2068
|
-
const match = MatchSimpleSchema.parse(data);
|
|
2069
|
-
return {
|
|
2070
|
-
content: [
|
|
2071
|
-
{
|
|
2072
|
-
type: 'text',
|
|
2073
|
-
text: JSON.stringify(match, null, 2),
|
|
2074
|
-
},
|
|
2075
|
-
],
|
|
2076
|
-
};
|
|
2077
|
-
}
|
|
2078
|
-
case 'get_team_events_simple': {
|
|
2079
|
-
const { team_key, year } = z
|
|
2080
|
-
.object({
|
|
2081
|
-
team_key: TeamKeySchema,
|
|
2082
|
-
year: YearSchema,
|
|
2083
|
-
})
|
|
2084
|
-
.parse(args);
|
|
2085
|
-
const data = await makeApiRequest(`/team/${team_key}/events/${year}/simple`);
|
|
2086
|
-
const events = z.array(EventSimpleSchema).parse(data);
|
|
2087
|
-
return {
|
|
2088
|
-
content: [
|
|
2089
|
-
{
|
|
2090
|
-
type: 'text',
|
|
2091
|
-
text: JSON.stringify(events, null, 2),
|
|
2092
|
-
},
|
|
2093
|
-
],
|
|
2094
|
-
};
|
|
2095
|
-
}
|
|
2096
|
-
case 'get_team_events_keys': {
|
|
2097
|
-
const { team_key, year } = z
|
|
2098
|
-
.object({
|
|
2099
|
-
team_key: TeamKeySchema,
|
|
2100
|
-
year: YearSchema,
|
|
2101
|
-
})
|
|
2102
|
-
.parse(args);
|
|
2103
|
-
const data = await makeApiRequest(`/team/${team_key}/events/${year}/keys`);
|
|
2104
|
-
const keys = z.array(z.string()).parse(data);
|
|
2105
|
-
return {
|
|
2106
|
-
content: [
|
|
2107
|
-
{
|
|
2108
|
-
type: 'text',
|
|
2109
|
-
text: JSON.stringify(keys, null, 2),
|
|
2110
|
-
},
|
|
2111
|
-
],
|
|
2112
|
-
};
|
|
2113
|
-
}
|
|
2114
|
-
case 'get_team_event_awards': {
|
|
2115
|
-
const { team_key, event_key } = z
|
|
2116
|
-
.object({
|
|
2117
|
-
team_key: TeamKeySchema,
|
|
2118
|
-
event_key: EventKeySchema,
|
|
2119
|
-
})
|
|
2120
|
-
.parse(args);
|
|
2121
|
-
const data = await makeApiRequest(`/team/${team_key}/event/${event_key}/awards`);
|
|
2122
|
-
const awards = z.array(AwardSchema).parse(data);
|
|
2123
|
-
return {
|
|
2124
|
-
content: [
|
|
2125
|
-
{
|
|
2126
|
-
type: 'text',
|
|
2127
|
-
text: JSON.stringify(awards, null, 2),
|
|
2128
|
-
},
|
|
2129
|
-
],
|
|
2130
|
-
};
|
|
2131
|
-
}
|
|
2132
|
-
case 'get_team_matches_simple': {
|
|
2133
|
-
const { team_key, year } = z
|
|
2134
|
-
.object({
|
|
2135
|
-
team_key: TeamKeySchema,
|
|
2136
|
-
year: YearSchema,
|
|
2137
|
-
})
|
|
2138
|
-
.parse(args);
|
|
2139
|
-
const data = await makeApiRequest(`/team/${team_key}/matches/${year}/simple`);
|
|
2140
|
-
const matches = z.array(MatchSimpleSchema).parse(data);
|
|
2141
|
-
return {
|
|
2142
|
-
content: [
|
|
2143
|
-
{
|
|
2144
|
-
type: 'text',
|
|
2145
|
-
text: JSON.stringify(matches, null, 2),
|
|
2146
|
-
},
|
|
2147
|
-
],
|
|
2148
|
-
};
|
|
2149
|
-
}
|
|
2150
|
-
case 'get_team_matches_keys': {
|
|
2151
|
-
const { team_key, year } = z
|
|
2152
|
-
.object({
|
|
2153
|
-
team_key: TeamKeySchema,
|
|
2154
|
-
year: YearSchema,
|
|
2155
|
-
})
|
|
2156
|
-
.parse(args);
|
|
2157
|
-
const data = await makeApiRequest(`/team/${team_key}/matches/${year}/keys`);
|
|
2158
|
-
const keys = z.array(z.string()).parse(data);
|
|
2159
|
-
return {
|
|
2160
|
-
content: [
|
|
2161
|
-
{
|
|
2162
|
-
type: 'text',
|
|
2163
|
-
text: JSON.stringify(keys, null, 2),
|
|
2164
|
-
},
|
|
2165
|
-
],
|
|
2166
|
-
};
|
|
2167
|
-
}
|
|
2168
|
-
case 'get_team_social_media': {
|
|
2169
|
-
const { team_key } = z
|
|
2170
|
-
.object({ team_key: TeamKeySchema })
|
|
2171
|
-
.parse(args);
|
|
2172
|
-
const data = await makeApiRequest(`/team/${team_key}/social_media`);
|
|
2173
|
-
const media = z.array(MediaSchema).parse(data);
|
|
2174
|
-
return {
|
|
2175
|
-
content: [
|
|
2176
|
-
{
|
|
2177
|
-
type: 'text',
|
|
2178
|
-
text: JSON.stringify(media, null, 2),
|
|
2179
|
-
},
|
|
2180
|
-
],
|
|
2181
|
-
};
|
|
2182
|
-
}
|
|
2183
|
-
case 'get_team_media_by_tag': {
|
|
2184
|
-
const { team_key, media_tag } = z
|
|
2185
|
-
.object({
|
|
2186
|
-
team_key: TeamKeySchema,
|
|
2187
|
-
media_tag: z.string(),
|
|
2188
|
-
})
|
|
2189
|
-
.parse(args);
|
|
2190
|
-
const data = await makeApiRequest(`/team/${team_key}/media/tag/${media_tag}`);
|
|
2191
|
-
const media = z.array(MediaSchema).parse(data);
|
|
2192
|
-
return {
|
|
2193
|
-
content: [
|
|
2194
|
-
{
|
|
2195
|
-
type: 'text',
|
|
2196
|
-
text: JSON.stringify(media, null, 2),
|
|
2197
|
-
},
|
|
2198
|
-
],
|
|
2199
|
-
};
|
|
2200
|
-
}
|
|
2201
|
-
case 'get_team_media_by_tag_year': {
|
|
2202
|
-
const { team_key, media_tag, year } = z
|
|
2203
|
-
.object({
|
|
2204
|
-
team_key: TeamKeySchema,
|
|
2205
|
-
media_tag: z.string(),
|
|
2206
|
-
year: YearSchema,
|
|
2207
|
-
})
|
|
2208
|
-
.parse(args);
|
|
2209
|
-
const data = await makeApiRequest(`/team/${team_key}/media/tag/${media_tag}/${year}`);
|
|
2210
|
-
const media = z.array(MediaSchema).parse(data);
|
|
2211
|
-
return {
|
|
2212
|
-
content: [
|
|
2213
|
-
{
|
|
2214
|
-
type: 'text',
|
|
2215
|
-
text: JSON.stringify(media, null, 2),
|
|
2216
|
-
},
|
|
2217
|
-
],
|
|
2218
|
-
};
|
|
2219
|
-
}
|
|
2220
|
-
case 'get_event_teams_simple': {
|
|
2221
|
-
const { event_key } = z
|
|
2222
|
-
.object({ event_key: EventKeySchema })
|
|
2223
|
-
.parse(args);
|
|
2224
|
-
const data = await makeApiRequest(`/event/${event_key}/teams/simple`);
|
|
2225
|
-
const teams = z.array(TeamSimpleSchema).parse(data);
|
|
2226
|
-
return {
|
|
2227
|
-
content: [
|
|
2228
|
-
{
|
|
2229
|
-
type: 'text',
|
|
2230
|
-
text: JSON.stringify(teams, null, 2),
|
|
2231
|
-
},
|
|
2232
|
-
],
|
|
2233
|
-
};
|
|
2234
|
-
}
|
|
2235
|
-
case 'get_event_teams_keys': {
|
|
2236
|
-
const { event_key } = z
|
|
2237
|
-
.object({ event_key: EventKeySchema })
|
|
2238
|
-
.parse(args);
|
|
2239
|
-
const data = await makeApiRequest(`/event/${event_key}/teams/keys`);
|
|
2240
|
-
const keys = z.array(z.string()).parse(data);
|
|
2241
|
-
return {
|
|
2242
|
-
content: [
|
|
2243
|
-
{
|
|
2244
|
-
type: 'text',
|
|
2245
|
-
text: JSON.stringify(keys, null, 2),
|
|
2246
|
-
},
|
|
2247
|
-
],
|
|
2248
|
-
};
|
|
2249
|
-
}
|
|
2250
|
-
case 'get_event_matches_simple': {
|
|
2251
|
-
const { event_key } = z
|
|
2252
|
-
.object({ event_key: EventKeySchema })
|
|
2253
|
-
.parse(args);
|
|
2254
|
-
const data = await makeApiRequest(`/event/${event_key}/matches/simple`);
|
|
2255
|
-
const matches = z.array(MatchSimpleSchema).parse(data);
|
|
2256
|
-
return {
|
|
2257
|
-
content: [
|
|
2258
|
-
{
|
|
2259
|
-
type: 'text',
|
|
2260
|
-
text: JSON.stringify(matches, null, 2),
|
|
2261
|
-
},
|
|
2262
|
-
],
|
|
2263
|
-
};
|
|
2264
|
-
}
|
|
2265
|
-
case 'get_event_matches_keys': {
|
|
2266
|
-
const { event_key } = z
|
|
2267
|
-
.object({ event_key: EventKeySchema })
|
|
2268
|
-
.parse(args);
|
|
2269
|
-
const data = await makeApiRequest(`/event/${event_key}/matches/keys`);
|
|
2270
|
-
const keys = z.array(z.string()).parse(data);
|
|
2271
|
-
return {
|
|
2272
|
-
content: [
|
|
2273
|
-
{
|
|
2274
|
-
type: 'text',
|
|
2275
|
-
text: JSON.stringify(keys, null, 2),
|
|
2276
|
-
},
|
|
2277
|
-
],
|
|
2278
|
-
};
|
|
2279
|
-
}
|
|
2280
|
-
case 'get_team_history': {
|
|
2281
|
-
const { team_key } = z
|
|
2282
|
-
.object({ team_key: TeamKeySchema })
|
|
2283
|
-
.parse(args);
|
|
2284
|
-
const data = await makeApiRequest(`/team/${team_key}/history`);
|
|
2285
|
-
const history = TeamHistorySchema.parse(data);
|
|
2286
|
-
return {
|
|
2287
|
-
content: [
|
|
2288
|
-
{
|
|
2289
|
-
type: 'text',
|
|
2290
|
-
text: JSON.stringify(history, null, 2),
|
|
2291
|
-
},
|
|
2292
|
-
],
|
|
2293
|
-
};
|
|
2294
|
-
}
|
|
2295
|
-
case 'get_team_event_statuses': {
|
|
2296
|
-
const { team_key, year } = z
|
|
2297
|
-
.object({
|
|
2298
|
-
team_key: TeamKeySchema,
|
|
2299
|
-
year: YearSchema,
|
|
2300
|
-
})
|
|
2301
|
-
.parse(args);
|
|
2302
|
-
const data = await makeApiRequest(`/team/${team_key}/events/${year}/statuses`);
|
|
2303
|
-
const statuses = z
|
|
2304
|
-
.record(z.string(), TeamEventStatusSchema)
|
|
2305
|
-
.parse(data);
|
|
2306
|
-
return {
|
|
2307
|
-
content: [
|
|
2308
|
-
{
|
|
2309
|
-
type: 'text',
|
|
2310
|
-
text: JSON.stringify(statuses, null, 2),
|
|
2311
|
-
},
|
|
2312
|
-
],
|
|
2313
|
-
};
|
|
2314
|
-
}
|
|
2315
|
-
case 'get_team_event_matches_simple': {
|
|
2316
|
-
const { team_key, event_key } = z
|
|
2317
|
-
.object({
|
|
2318
|
-
team_key: TeamKeySchema,
|
|
2319
|
-
event_key: EventKeySchema,
|
|
2320
|
-
})
|
|
2321
|
-
.parse(args);
|
|
2322
|
-
const data = await makeApiRequest(`/team/${team_key}/event/${event_key}/matches/simple`);
|
|
2323
|
-
const matches = z.array(MatchSimpleSchema).parse(data);
|
|
2324
|
-
return {
|
|
2325
|
-
content: [
|
|
2326
|
-
{
|
|
2327
|
-
type: 'text',
|
|
2328
|
-
text: JSON.stringify(matches, null, 2),
|
|
2329
|
-
},
|
|
2330
|
-
],
|
|
2331
|
-
};
|
|
2332
|
-
}
|
|
2333
|
-
case 'get_team_event_matches_keys': {
|
|
2334
|
-
const { team_key, event_key } = z
|
|
2335
|
-
.object({
|
|
2336
|
-
team_key: TeamKeySchema,
|
|
2337
|
-
event_key: EventKeySchema,
|
|
2338
|
-
})
|
|
2339
|
-
.parse(args);
|
|
2340
|
-
const data = await makeApiRequest(`/team/${team_key}/event/${event_key}/matches/keys`);
|
|
2341
|
-
const keys = z.array(z.string()).parse(data);
|
|
2342
|
-
return {
|
|
2343
|
-
content: [
|
|
2344
|
-
{
|
|
2345
|
-
type: 'text',
|
|
2346
|
-
text: JSON.stringify(keys, null, 2),
|
|
2347
|
-
},
|
|
2348
|
-
],
|
|
2349
|
-
};
|
|
2350
|
-
}
|
|
2351
|
-
case 'get_district_events': {
|
|
2352
|
-
const { district_key } = z
|
|
2353
|
-
.object({ district_key: z.string() })
|
|
2354
|
-
.parse(args);
|
|
2355
|
-
const data = await makeApiRequest(`/district/${district_key}/events`);
|
|
2356
|
-
const events = z.array(EventSchema).parse(data);
|
|
2357
|
-
return {
|
|
2358
|
-
content: [
|
|
2359
|
-
{
|
|
2360
|
-
type: 'text',
|
|
2361
|
-
text: JSON.stringify(events, null, 2),
|
|
2362
|
-
},
|
|
2363
|
-
],
|
|
2364
|
-
};
|
|
2365
|
-
}
|
|
2366
|
-
case 'get_district_events_simple': {
|
|
2367
|
-
const { district_key } = z
|
|
2368
|
-
.object({ district_key: z.string() })
|
|
2369
|
-
.parse(args);
|
|
2370
|
-
const data = await makeApiRequest(`/district/${district_key}/events/simple`);
|
|
2371
|
-
const events = z.array(EventSimpleSchema).parse(data);
|
|
2372
|
-
return {
|
|
2373
|
-
content: [
|
|
2374
|
-
{
|
|
2375
|
-
type: 'text',
|
|
2376
|
-
text: JSON.stringify(events, null, 2),
|
|
2377
|
-
},
|
|
2378
|
-
],
|
|
2379
|
-
};
|
|
2380
|
-
}
|
|
2381
|
-
case 'get_district_events_keys': {
|
|
2382
|
-
const { district_key } = z
|
|
2383
|
-
.object({ district_key: z.string() })
|
|
2384
|
-
.parse(args);
|
|
2385
|
-
const data = await makeApiRequest(`/district/${district_key}/events/keys`);
|
|
2386
|
-
const keys = z.array(z.string()).parse(data);
|
|
2387
|
-
return {
|
|
2388
|
-
content: [
|
|
2389
|
-
{
|
|
2390
|
-
type: 'text',
|
|
2391
|
-
text: JSON.stringify(keys, null, 2),
|
|
2392
|
-
},
|
|
2393
|
-
],
|
|
2394
|
-
};
|
|
2395
|
-
}
|
|
2396
|
-
case 'get_district_teams': {
|
|
2397
|
-
const { district_key } = z
|
|
2398
|
-
.object({ district_key: z.string() })
|
|
2399
|
-
.parse(args);
|
|
2400
|
-
const data = await makeApiRequest(`/district/${district_key}/teams`);
|
|
2401
|
-
const teams = z.array(TeamSchema).parse(data);
|
|
2402
|
-
return {
|
|
2403
|
-
content: [
|
|
2404
|
-
{
|
|
2405
|
-
type: 'text',
|
|
2406
|
-
text: JSON.stringify(teams, null, 2),
|
|
2407
|
-
},
|
|
2408
|
-
],
|
|
2409
|
-
};
|
|
2410
|
-
}
|
|
2411
|
-
case 'get_district_teams_simple': {
|
|
2412
|
-
const { district_key } = z
|
|
2413
|
-
.object({ district_key: z.string() })
|
|
2414
|
-
.parse(args);
|
|
2415
|
-
const data = await makeApiRequest(`/district/${district_key}/teams/simple`);
|
|
2416
|
-
const teams = z.array(TeamSimpleSchema).parse(data);
|
|
2417
|
-
return {
|
|
2418
|
-
content: [
|
|
2419
|
-
{
|
|
2420
|
-
type: 'text',
|
|
2421
|
-
text: JSON.stringify(teams, null, 2),
|
|
2422
|
-
},
|
|
2423
|
-
],
|
|
2424
|
-
};
|
|
2425
|
-
}
|
|
2426
|
-
case 'get_district_teams_keys': {
|
|
2427
|
-
const { district_key } = z
|
|
2428
|
-
.object({ district_key: z.string() })
|
|
2429
|
-
.parse(args);
|
|
2430
|
-
const data = await makeApiRequest(`/district/${district_key}/teams/keys`);
|
|
2431
|
-
const keys = z.array(z.string()).parse(data);
|
|
2432
|
-
return {
|
|
2433
|
-
content: [
|
|
2434
|
-
{
|
|
2435
|
-
type: 'text',
|
|
2436
|
-
text: JSON.stringify(keys, null, 2),
|
|
2437
|
-
},
|
|
2438
|
-
],
|
|
2439
|
-
};
|
|
2440
|
-
}
|
|
2441
|
-
case 'get_match_zebra': {
|
|
2442
|
-
const { match_key } = z
|
|
2443
|
-
.object({ match_key: z.string() })
|
|
2444
|
-
.parse(args);
|
|
2445
|
-
const data = await makeApiRequest(`/match/${match_key}/zebra`);
|
|
2446
|
-
const zebra = ZebraSchema.parse(data);
|
|
2447
|
-
return {
|
|
2448
|
-
content: [
|
|
2449
|
-
{
|
|
2450
|
-
type: 'text',
|
|
2451
|
-
text: JSON.stringify(zebra, null, 2),
|
|
2452
|
-
},
|
|
2453
|
-
],
|
|
2454
|
-
};
|
|
2455
|
-
}
|
|
2456
|
-
case 'get_event_predictions': {
|
|
2457
|
-
const { event_key } = z
|
|
2458
|
-
.object({ event_key: EventKeySchema })
|
|
2459
|
-
.parse(args);
|
|
2460
|
-
const data = await makeApiRequest(`/event/${event_key}/predictions`);
|
|
2461
|
-
const predictions = PredictionSchema.parse(data);
|
|
2462
|
-
return {
|
|
2463
|
-
content: [
|
|
2464
|
-
{
|
|
2465
|
-
type: 'text',
|
|
2466
|
-
text: JSON.stringify(predictions, null, 2),
|
|
2467
|
-
},
|
|
2468
|
-
],
|
|
2469
|
-
};
|
|
2470
|
-
}
|
|
2471
|
-
default:
|
|
2472
|
-
throw new Error(`Unknown tool: ${name}`);
|
|
2473
|
-
}
|
|
40
|
+
return await handleToolCall(name, args);
|
|
2474
41
|
}
|
|
2475
42
|
catch (error) {
|
|
2476
43
|
const errorMessage = `Tool execution error for '${name}': ${error instanceof Error ? error.message : String(error)}`;
|
|
2477
|
-
await log('error', errorMessage);
|
|
44
|
+
await log('error', errorMessage, server);
|
|
2478
45
|
return {
|
|
2479
46
|
content: [
|
|
2480
47
|
{
|
|
@@ -2486,15 +53,15 @@ async function runServer() {
|
|
|
2486
53
|
};
|
|
2487
54
|
}
|
|
2488
55
|
});
|
|
2489
|
-
await log('info', 'Setting up transport connection ...');
|
|
56
|
+
await log('info', 'Setting up transport connection ...', server);
|
|
2490
57
|
try {
|
|
2491
58
|
const transport = new StdioServerTransport();
|
|
2492
59
|
await server.connect(transport);
|
|
2493
|
-
await log('info', 'The Blue Alliance MCP Server running on stdio');
|
|
60
|
+
await log('info', 'The Blue Alliance MCP Server running on stdio', server);
|
|
2494
61
|
}
|
|
2495
62
|
catch (error) {
|
|
2496
63
|
const errorMessage = 'Failed to connect to transport';
|
|
2497
|
-
await log('error', `${errorMessage}: ${error instanceof Error ? error.message : error}
|
|
64
|
+
await log('error', `${errorMessage}: ${error instanceof Error ? error.message : error}`, server);
|
|
2498
65
|
throw new Error(errorMessage);
|
|
2499
66
|
}
|
|
2500
67
|
// Set up error handlers for the server
|