cito-mcp 0.3.1 → 0.3.2

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.
@@ -177,6 +177,15 @@ Example: { "game": "cs2", "matchId": "cs2-match-123", "view": "summary", "includ
177
177
  primary = await getSection(ctx, `/tennis/matches/live/${encodeURIComponent(matchId)}`);
178
178
  upstreamCalls += 1;
179
179
  rateLimit = { ...rateLimit, ...primary.headers };
180
+ // Finished live matches archive under s365_{year}_{gid} while the live
181
+ // board handed out s365_{gid} — insert the year before giving up.
182
+ const gid = matchId.match(/^s365_(\d+)$/)?.[1];
183
+ if (!primary.ok && gid) {
184
+ const year = new Date().getUTCFullYear();
185
+ primary = await getSection(ctx, `/tennis/matches/${encodeURIComponent(`s365_${year}_${gid}`)}`);
186
+ upstreamCalls += 1;
187
+ rateLimit = { ...rateLimit, ...primary.headers };
188
+ }
180
189
  }
181
190
  if (!primary.ok) {
182
191
  return errorEnvelope({
@@ -529,6 +529,10 @@ Example: { "method": "GET", "path": "/cs2/rankings/teams", "queryJson": "{\\"pag
529
529
  default: '{}',
530
530
  description: 'Stringified JSON object of query params. Example: "{\\"page\\":1,\\"limit\\":20}".',
531
531
  },
532
+ query: {
533
+ type: 'object',
534
+ description: 'Query params as a plain object (alternative to queryJson). Example: {"year":2026}.',
535
+ },
532
536
  bodyJson: {
533
537
  type: 'string',
534
538
  description: 'Stringified JSON body for POST only (rare).',
@@ -572,6 +576,11 @@ Example: { "method": "GET", "path": "/cs2/rankings/teams", "queryJson": "{\\"pag
572
576
  });
573
577
  }
574
578
  let query = {};
579
+ // Agents pass query as a plain object at least as often as the stringified
580
+ // queryJson form; silently dropping it produced confusing upstream 422s.
581
+ if (args.query && typeof args.query === 'object' && !Array.isArray(args.query)) {
582
+ query = { ...args.query };
583
+ }
575
584
  if (typeof args.queryJson === 'string' && args.queryJson.trim()) {
576
585
  try {
577
586
  const parsed = JSON.parse(args.queryJson);
@@ -187,11 +187,17 @@ export function normalizeMatch(game, row, forcedStatus) {
187
187
  team2 = sideFrom(p2, pickString(p2obj?.id, r.player2_id), undefined, score2);
188
188
  }
189
189
  else {
190
- const w = pickString(r.winner_id);
191
- const l = pickString(r.loser_id);
192
- if (w || l) {
193
- team1 = sideFrom(w, w, undefined, undefined);
194
- team2 = sideFrom(l, l, undefined, undefined);
190
+ // Archive detail nests winner/loser objects with real names; list rows
191
+ // may only carry winner_id/loser_id (ids double as last-resort labels).
192
+ const wObj = asRecord(r.winner);
193
+ const lObj = asRecord(r.loser);
194
+ const wName = pickString(wObj?.name, r.winner_name);
195
+ const lName = pickString(lObj?.name, r.loser_name);
196
+ const wId = pickString(wObj?.id, r.winner_id);
197
+ const lId = pickString(lObj?.id, r.loser_id);
198
+ if (wName || lName || wId || lId) {
199
+ team1 = sideFrom(wName ?? wId, wId, undefined, undefined);
200
+ team2 = sideFrom(lName ?? lId, lId, undefined, undefined);
195
201
  }
196
202
  }
197
203
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cito-mcp",
3
- "version": "0.3.1",
3
+ "version": "0.3.2",
4
4
  "description": "Standalone MCP server for the Cito esports API — 15 curated outcome tools for agents (live, schedule, profiles, standings, previews, event cards).",
5
5
  "type": "module",
6
6
  "bin": {