cito-mcp 0.5.7 → 0.5.8

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/README.md CHANGED
@@ -550,6 +550,10 @@ claude mcp add cito -e CITO_API_KEY=cito_… "--" npx -y cito-mcp
550
550
 
551
551
  ## Changelog (summary)
552
552
 
553
+ ### 0.5.8
554
+
555
+ - Tennis `player_rankings_history` asks `/tennis/rankings/history/{id}` for one page (`limit`, new `page`, `since` sent as `from`) instead of downloading the whole career and slicing it; page 1 is the newest `limit` rows, returned oldest-first as before. `omittedOlder` counts rows at the old end, new `omittedNewer` the rows on earlier (newer) pages, `hasMore` is the route's own `has_next`.
556
+
553
557
  ### 0.5.7
554
558
 
555
559
  - Tennis `event_card`: `event.drawSize` and `draw.drawSize` are the API's stored draw size, the same value `/tennis/tournaments/{id}` serves (it is now corrected to the proven size: Paris 56, Shanghai 96). `drawSizeVerified` says a proof stands behind it; `draw.drawSizeDerived` is what the edition's own bracket shows.
@@ -256,10 +256,11 @@ Prefer over: standings (latest snapshot only); rankings_movers (week-over-week d
256
256
  Do not use when: the current top-N table → standings with game tennis.
257
257
 
258
258
  Tennis-only. Rows arrive oldest-first (chronological), which is the order a chart
259
- wants; the newest entries are the tail. limit keeps the most RECENT N rows (the
260
- route itself ignores ?limit=, so the bound is applied here) — hasMore and
261
- oldestReturned/newestReturned say exactly which window came back, and
262
- omittedOlder counts the rows left behind at the old end.
259
+ wants; the newest entries are the tail. limit + page walk the series from the most
260
+ RECENT end (page 1 = the newest limit rows, page 2 the ones before them); the route
261
+ pages itself. hasMore and oldestReturned/newestReturned say exactly which window came
262
+ back, omittedOlder counts the rows left at the old end and omittedNewer the rows on
263
+ earlier (newer) pages.
263
264
 
264
265
  Parallel-safe: yes. Upstream cost: 1.`,
265
266
  inputSchema: {
@@ -271,6 +272,7 @@ Parallel-safe: yes. Upstream cost: 1.`,
271
272
  playerId: stringSchema('Tennis player id, e.g. "atp_207989" or "wta_214544".', 'atp_207989'),
272
273
  since: stringSchema('Only rows on or after this date (YYYY-MM-DD).', '2026-01-01'),
273
274
  limit: limitSchema({ default: 20, max: 500, description: 'Max history rows (default 20, max 500).' }),
275
+ page: { type: 'integer', minimum: 1, default: 1, description: 'Page from the newest end (1 = the most recent limit rows).' },
274
276
  },
275
277
  },
276
278
  handler: async (args, ctx) => {
@@ -323,8 +325,9 @@ Parallel-safe: yes. Upstream cost: 1.`,
323
325
  });
324
326
  }
325
327
  const limit = clampInt(args.limit, 20, 1, 500);
328
+ const page = clampInt(args.page, 1, 1, 100000);
326
329
  const res = await fetchJson(ctx, `/tennis/rankings/history/${encodeURIComponent(playerId)}`, {
327
- query: { limit },
330
+ query: { limit, page, ...(sinceRaw ? { from: sinceRaw } : {}) },
328
331
  });
329
332
  if (!res.ok) {
330
333
  return errorEnvelope({
@@ -354,8 +357,21 @@ Parallel-safe: yes. Upstream cost: 1.`,
354
357
  const inWindow = sinceRaw
355
358
  ? allHistory.filter((h) => h.date !== null && h.date >= sinceRaw)
356
359
  : allHistory;
357
- const total = inWindow.length;
358
- const history = total > limit ? inWindow.slice(total - limit) : inWindow;
360
+ const pagedUpstream = typeof body.total === 'number' && typeof body.order === 'string';
361
+ let total;
362
+ let history;
363
+ if (pagedUpstream) {
364
+ total = body.total;
365
+ history = body.order === 'desc' ? [...inWindow].reverse() : inWindow;
366
+ }
367
+ else {
368
+ total = inWindow.length;
369
+ const end = Math.max(0, total - (page - 1) * limit);
370
+ history = inWindow.slice(Math.max(0, end - limit), end);
371
+ }
372
+ const omittedNewer = Math.min(total, (page - 1) * limit);
373
+ const omittedOlder = Math.max(0, total - omittedNewer - history.length);
374
+ const hasMore = pagedUpstream && typeof body.has_next === 'boolean' ? body.has_next : omittedOlder > 0;
359
375
  const best = history.reduce((acc, h) => {
360
376
  if (h.rank === null)
361
377
  return acc;
@@ -366,9 +382,9 @@ Parallel-safe: yes. Upstream cost: 1.`,
366
382
  return successEnvelope({
367
383
  pagination: {
368
384
  limit,
369
- offset: total - history.length,
385
+ offset: omittedNewer,
370
386
  total,
371
- hasMore: total > history.length,
387
+ hasMore,
372
388
  nextCursor: null,
373
389
  prevCursor: null,
374
390
  },
@@ -391,7 +407,9 @@ Parallel-safe: yes. Upstream cost: 1.`,
391
407
  history,
392
408
  totalInWindow: total,
393
409
  returned: history.length,
394
- omittedOlder: total - history.length,
410
+ omittedOlder,
411
+ omittedNewer,
412
+ page,
395
413
  oldestReturned: history.length ? history[0].date : null,
396
414
  newestReturned: history.length ? history[history.length - 1].date : null,
397
415
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cito-mcp",
3
- "version": "0.5.7",
3
+ "version": "0.5.8",
4
4
  "description": "Standalone MCP server for the Cito esports and sports API — curated outcome tools for agents (live scoreboards, round economy, opening duels, clutches, vetoes, rosters, tennis, mma).",
5
5
  "type": "module",
6
6
  "homepage": "https://cito.gg",