cito-mcp 0.4.4 → 0.4.6

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/scrub.js ADDED
@@ -0,0 +1,111 @@
1
+ const INTERNAL_KEYS = new Set([
2
+ 'emptyCardHeal',
3
+ 'llmValidation',
4
+ 'workerHostHint',
5
+ 'scrapeMeta',
6
+ 'fetchMeta',
7
+ 'cacheKey',
8
+ 'failureSteps',
9
+ 'htmlSnapshotFile',
10
+ 'latestHtmlSnapshotFile',
11
+ 'lastSyncedAt',
12
+ 'sourceUrl',
13
+ 'sourceUrls',
14
+ 'sourceIds',
15
+ 'wikiUrl',
16
+ 'wiki_url',
17
+ 'jsonLd',
18
+ '_mergeSource',
19
+ '_provenance',
20
+ 'duplicateOf',
21
+ 'duplicate_of',
22
+ 'identityConfidence',
23
+ 'identity_confidence',
24
+ 'roleSource',
25
+ 'role_source',
26
+ 'verifiedCompetitive',
27
+ 'verified_competitive',
28
+ 'profileAttemptedAt',
29
+ 'profileFailureMessage',
30
+ 'profileFailureReason',
31
+ 'profileFetchStatus',
32
+ 'profileImageAttemptedAt',
33
+ 'profileImageAttempts',
34
+ 'profileImageError',
35
+ 'profileImageSteamAttemptedAt',
36
+ 'profileImageWorker',
37
+ 'ratingSource',
38
+ 'requiredSourceData',
39
+ 'rawText',
40
+ 'raw_text',
41
+ 'scrapedAt',
42
+ 'scraped_at',
43
+ 'sourceSummary',
44
+ 'sourceNote',
45
+ 'durableStatsTables',
46
+ 'lineupSource',
47
+ 'mapMediaSource',
48
+ 'rosterSource',
49
+ 'upstream',
50
+ 'liveCandidateWindowMinutes',
51
+ 'rowHash',
52
+ 'row_hash',
53
+ 'snapshotHash',
54
+ 'snapshot_hash',
55
+ 'syncRunId',
56
+ 'sync_run_id',
57
+ 'discoveredSources',
58
+ 'sidecarAvailable',
59
+ 'imageCandidates',
60
+ 'image_candidates',
61
+ 'source_url',
62
+ ]);
63
+ const SCRAPE_PARENTS = new Set(['dataAvailability', 'health']);
64
+ const SCRAPE_KEYS = new Set(['strategy', 'samples']);
65
+ const MEDIA_PARENT = /image|photo|portrait|picture/i;
66
+ const ERROR_KEYS = new Set(['errors', 'error', 'lastError', 'bodyPreview']);
67
+ const INTERNAL_ERROR_TEXT = /prisma|raw query failed|invocation|ECONNREFUSED|\bat \S+ \(/i;
68
+ export const INTERNAL_ERROR_PLACEHOLDER = 'internal_error';
69
+ function isInternal(key, parentKey) {
70
+ if (key === 'sourceUrl' && MEDIA_PARENT.test(parentKey))
71
+ return false;
72
+ return INTERNAL_KEYS.has(key) || (SCRAPE_KEYS.has(key) && SCRAPE_PARENTS.has(parentKey));
73
+ }
74
+ function scrub(node, parentKey, inError) {
75
+ if (typeof node === 'string') {
76
+ return inError && INTERNAL_ERROR_TEXT.test(node) ? INTERNAL_ERROR_PLACEHOLDER : node;
77
+ }
78
+ if (Array.isArray(node)) {
79
+ let out = null;
80
+ for (let i = 0; i < node.length; i++) {
81
+ const value = node[i];
82
+ const next = scrub(value, parentKey, inError);
83
+ if (next !== value) {
84
+ out ??= node.slice();
85
+ out[i] = next;
86
+ }
87
+ }
88
+ return out ?? node;
89
+ }
90
+ if (!node || typeof node !== 'object' || node instanceof Date)
91
+ return node;
92
+ const src = node;
93
+ let out = null;
94
+ for (const key of Object.keys(src)) {
95
+ const value = src[key];
96
+ if (isInternal(key, parentKey)) {
97
+ out ??= { ...src };
98
+ delete out[key];
99
+ continue;
100
+ }
101
+ const next = scrub(value, key, inError || ERROR_KEYS.has(key));
102
+ if (next !== value) {
103
+ out ??= { ...src };
104
+ out[key] = next;
105
+ }
106
+ }
107
+ return out ?? node;
108
+ }
109
+ export function scrubInternalFields(value) {
110
+ return scrub(value, '', false);
111
+ }
package/dist/tools/cs2.js CHANGED
@@ -1,20 +1,6 @@
1
- /**
2
- * Dedicated CS2 esports analytics & live scorebot MCP tools.
3
- *
4
- * Exposes deep CS2 domain data from the 161 backend endpoints:
5
- * - Live real-time scoreboards & round state
6
- * - Round-by-round tactical economies & buy classifications
7
- * - First blood / opening duels per player & map
8
- * - 1vX clutch success rates (1v1 through 1v5)
9
- * - Team map pool analytics (Mirage, Inferno, Nuke, Dust2, Ancient, Anubis, Vertigo)
10
- * - Sub-second utility & flashbang efficiency leaderboard
11
- * - Match map pick/ban veto sequence
12
- * - Pro roster changes & transfers
13
- */
14
1
  import { asRecord, clampInt, fetchJson, unwrapPayload, } from '../client.js';
15
2
  import { errorEnvelope, mapHttpToCode, newRequestId, successEnvelope, } from '../envelope.js';
16
3
  import { limitSchema, READ_TOOL_ANNOTATIONS, stringSchema, } from './types.js';
17
- /** Unwraps Cito envelope whether inner entity is an object or array */
18
4
  function unwrap(val) {
19
5
  const p = unwrapPayload(val);
20
6
  const r = asRecord(p);
@@ -24,10 +10,6 @@ function unwrap(val) {
24
10
  return r.items;
25
11
  return p;
26
12
  }
27
- /**
28
- * 1. cs2_live_scoreboard
29
- * Real-time round state, bomb status, and player combat stats for an active match.
30
- */
31
13
  export const cs2LiveScoreboard = {
32
14
  name: 'cs2_live_scoreboard',
33
15
  description: 'Live real-time in-game scoreboard for an active CS2 match. Returns current round, bomb status, team scores, and individual player stats (K/A/D, ADR, HS%, alive status, HP, armor, weapon, and equipment value).',
@@ -75,10 +57,6 @@ export const cs2LiveScoreboard = {
75
57
  });
76
58
  },
77
59
  };
78
- /**
79
- * 2. cs2_round_economy
80
- * Tactical round-by-round buy classification and equipment values for a map.
81
- */
82
60
  export const cs2RoundEconomy = {
83
61
  name: 'cs2_round_economy',
84
62
  description: 'Round-by-round tactical economy for a CS2 map. Classifies every round buy type (Full Buy, Force Buy, Semi-Eco, Full Eco), team equipment spend, freeze-time equipment values, and loss bonus counter.',
@@ -128,10 +106,6 @@ export const cs2RoundEconomy = {
128
106
  });
129
107
  },
130
108
  };
131
- /**
132
- * 3. cs2_opening_duels
133
- * First blood / opening kill statistics by player or overall leaderboard.
134
- */
135
109
  export const cs2OpeningDuels = {
136
110
  name: 'cs2_opening_duels',
137
111
  description: 'First blood and opening duel statistics. Pass playerId to view a pro player\'s First Kills (FK), First Deaths (FD), and opening duel conversion %, or omit playerId to view the global CS2 opening duel leaderboard.',
@@ -172,10 +146,6 @@ export const cs2OpeningDuels = {
172
146
  });
173
147
  },
174
148
  };
175
- /**
176
- * 4. cs2_clutches
177
- * 1vX clutch situation success records (1v1 through 1v5).
178
- */
179
149
  export const cs2Clutches = {
180
150
  name: 'cs2_clutches',
181
151
  description: '1vX clutch situation success records. Pass playerId for a specific player\'s clutch breakdown (1v1, 1v2, 1v3, 1v4, 1v5 attempted vs won), or omit to view the global clutch leaderboard.',
@@ -216,17 +186,13 @@ export const cs2Clutches = {
216
186
  });
217
187
  },
218
188
  };
219
- /**
220
- * 5. cs2_team_map_stats
221
- * Team performance across the competitive map pool.
222
- */
223
189
  export const cs2TeamMapStats = {
224
190
  name: 'cs2_team_map_stats',
225
191
  description: 'Team win rates, round win rates, and CT/T side win splits across the competitive map pool (Mirage, Inferno, Nuke, Dust2, Ancient, Anubis, Vertigo) over the last 30 or 90 days.',
226
192
  inputSchema: {
227
193
  type: 'object',
228
194
  properties: {
229
- teamId: stringSchema('Team ID or slug (e.g. "hltv-team-4608", "cs2-team-4608", or "natus-vincere"). Required.', 'hltv-team-4608'),
195
+ teamId: stringSchema('Team ID or slug (e.g. "cs2-team-4608" or "natus-vincere"). Required.', 'cs2-team-4608'),
230
196
  days: {
231
197
  type: 'integer',
232
198
  description: 'Timeframe in days: 30, 90, 180, or 365 (default 90).',
@@ -272,10 +238,6 @@ export const cs2TeamMapStats = {
272
238
  });
273
239
  },
274
240
  };
275
- /**
276
- * 6. cs2_utility_leaderboard
277
- * Sub-second cached leaderboard for flashbang & utility efficiency.
278
- */
279
241
  export const cs2UtilityLeaderboard = {
280
242
  name: 'cs2_utility_leaderboard',
281
243
  description: 'Sub-second cached leaderboard of CS2 utility and flashbang efficiency. Returns pro player rankings for effective blind duration per flash, enemy blind time, flashes thrown, and grenade ADR.',
@@ -312,10 +274,6 @@ export const cs2UtilityLeaderboard = {
312
274
  });
313
275
  },
314
276
  };
315
- /**
316
- * 7. cs2_veto_sequence
317
- * Map pick/ban sequence and veto history for a match.
318
- */
319
277
  export const cs2VetoSequence = {
320
278
  name: 'cs2_veto_sequence',
321
279
  description: 'Map pick/ban veto sequence for a CS2 match. Shows which team banned which map, map picks, and decider map in chronological order.',
@@ -365,10 +323,6 @@ export const cs2VetoSequence = {
365
323
  });
366
324
  },
367
325
  };
368
- /**
369
- * 8. cs2_roster_transfers
370
- * Recent professional roster changes, benchings, and transfers.
371
- */
372
326
  export const cs2RosterTransfers = {
373
327
  name: 'cs2_roster_transfers',
374
328
  description: 'Recent professional CS2 roster changes, player benchings, stand-ins, and team transfers.',
@@ -408,7 +362,6 @@ export const cs2RosterTransfers = {
408
362
  });
409
363
  },
410
364
  };
411
- /** All curated CS2 tools */
412
365
  export const cs2Tools = [
413
366
  cs2LiveScoreboard,
414
367
  cs2RoundEconomy,
@@ -11,7 +11,6 @@ import { insightTools } from './insight.js';
11
11
  import { cs2Tools } from './cs2.js';
12
12
  import { tournamentTools } from './tournaments.js';
13
13
  import { scheduleTools } from './schedule.js';
14
- /** Curated outcome-tool catalog. Order matches preferred cold-start ladder. */
15
14
  export const allTools = [
16
15
  ...metaTools.filter((t) => t.name === 'list_capabilities' || t.name === 'api_health'),
17
16
  ...resolveTools,
@@ -22,20 +21,10 @@ export const allTools = [
22
21
  ...standingsTools,
23
22
  ...rankingsTools,
24
23
  ...leaderboardTools,
25
- // Tennis depth added after the coverage audit: odds, tournament discovery and
26
- // the daily schedule were reachable only through call_api.
27
- //
28
- // oddsTools REMOVED 2026-09-13. Tennis odds were withdrawn from the API
29
- // (/tennis/odds/* is unmounted), so the tool would only ever call a 404.
30
- // Betting data concentrates the legal risk and is the subject of every
31
- // significant dispute researched — Swish Analytics v OddsJam is a data vendor
32
- // suing rivals over scraped odds. See docs/tennis-risk-register.md.
33
- // To restore: re-add `...oddsTools,` here and remount odds_router in the API.
34
24
  ...tournamentTools,
35
25
  ...scheduleTools,
36
26
  ...insightTools,
37
27
  ...cs2Tools,
38
- // Escape-hatch pair last: discover routes, then call one.
39
28
  ...metaTools.filter((t) => t.name === 'list_routes' || t.name === 'call_api'),
40
29
  ];
41
30
  export function getTool(name) {