cito-mcp 0.3.18 → 0.3.19
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/tools/team.js +44 -27
- package/package.json +1 -1
package/dist/tools/team.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* team_profile + head_to_head
|
|
3
3
|
*/
|
|
4
|
-
import { clampInt, extractRows, fetchJson, gameNotIncludedHint, asRecord, pickString, } from '../client.js';
|
|
4
|
+
import { clampInt, extractRows, fetchJson, gameNotIncludedHint, asRecord, pickString, unwrapPayload, } from '../client.js';
|
|
5
5
|
import { errorEnvelope, mapHttpToCode, newRequestId, partialFromRejection, successEnvelope, } from '../envelope.js';
|
|
6
6
|
import { normalizeMatch } from './normalize.js';
|
|
7
7
|
import { boolSchema, gameSchema, isPrimaryGame, limitSchema, parseGame, PRIMARY_GAMES, stringSchema, } from './types.js';
|
|
@@ -24,22 +24,36 @@ function teamIdentity(game, raw, idHint, slugHint) {
|
|
|
24
24
|
name,
|
|
25
25
|
game,
|
|
26
26
|
region: pickString(nested.region, nested.country) ?? null,
|
|
27
|
+
// CS2 publishes countryName/countryCode and worldRanking on the team
|
|
28
|
+
// resource and none of it reached this card: a team page rendered with no
|
|
29
|
+
// flag and no ladder position while the API had both. Spirit came back as
|
|
30
|
+
// {id, slug, name, game, region} with world #1 nowhere in sight.
|
|
31
|
+
country: pickString(nested.countryName, nested.country, nested.countryCode) ?? null,
|
|
32
|
+
countryCode: pickString(nested.countryCode) ?? null,
|
|
33
|
+
worldRanking: numberOrNull(nested.worldRanking ?? nested.ranking ?? nested.rank),
|
|
27
34
|
};
|
|
28
35
|
}
|
|
36
|
+
/** A finite number, or null. Ranks arrive as number or numeric string. */
|
|
37
|
+
function numberOrNull(value) {
|
|
38
|
+
if (value === null || value === undefined || value === '')
|
|
39
|
+
return null;
|
|
40
|
+
const parsed = Number(value);
|
|
41
|
+
return Number.isFinite(parsed) ? parsed : null;
|
|
42
|
+
}
|
|
29
43
|
export const teamProfile = {
|
|
30
44
|
name: 'team_profile',
|
|
31
|
-
description: `Team/org card: identity, roster, recent matches, and form/trends/radar when available.
|
|
32
|
-
|
|
33
|
-
When to use:
|
|
34
|
-
- Team page / "who is on this roster?"
|
|
35
|
-
- Builder team screen sample
|
|
36
|
-
|
|
37
|
-
Prefer over: separate roster + matches + detail via call_api.
|
|
38
|
-
|
|
39
|
-
Do not use when: UFC fighters → player_profile; unknown name → resolve_entity first.
|
|
40
|
-
Dota may return partial roster (API gap). Prefer slug for lol/cod; teamId for cs2.
|
|
41
|
-
|
|
42
|
-
Parallel-safe: yes. Upstream cost: 2–4.
|
|
45
|
+
description: `Team/org card: identity, roster, recent matches, and form/trends/radar when available.
|
|
46
|
+
|
|
47
|
+
When to use:
|
|
48
|
+
- Team page / "who is on this roster?"
|
|
49
|
+
- Builder team screen sample
|
|
50
|
+
|
|
51
|
+
Prefer over: separate roster + matches + detail via call_api.
|
|
52
|
+
|
|
53
|
+
Do not use when: UFC fighters → player_profile; unknown name → resolve_entity first.
|
|
54
|
+
Dota may return partial roster (API gap). Prefer slug for lol/cod; teamId for cs2.
|
|
55
|
+
|
|
56
|
+
Parallel-safe: yes. Upstream cost: 2–4.
|
|
43
57
|
Example: { "game": "lol", "slug": "t1", "recentLimit": 10 }`,
|
|
44
58
|
inputSchema: {
|
|
45
59
|
type: 'object',
|
|
@@ -374,8 +388,11 @@ Example: { "game": "lol", "slug": "t1", "recentLimit": 10 }`,
|
|
|
374
388
|
const res = await fetchJson(ctx, `/cs2/teams/${encodeURIComponent(tid)}/trends`);
|
|
375
389
|
upstreamCalls += 1;
|
|
376
390
|
rateLimit = { ...rateLimit, ...res.headers };
|
|
391
|
+
// res.data is the whole upstream body, so this nested
|
|
392
|
+
// {success, data:{...}} inside our own envelope. Every other field
|
|
393
|
+
// here is normalized; this one leaked the REST wrapper to the agent.
|
|
377
394
|
if (res.ok)
|
|
378
|
-
form = res.data;
|
|
395
|
+
form = unwrapPayload(res.data) ?? res.data;
|
|
379
396
|
else {
|
|
380
397
|
partial.push(partialFromRejection('form', {
|
|
381
398
|
code: mapHttpToCode(res.status),
|
|
@@ -545,19 +562,19 @@ function winnerSide(match, a) {
|
|
|
545
562
|
}
|
|
546
563
|
export const headToHead = {
|
|
547
564
|
name: 'head_to_head',
|
|
548
|
-
description: `Composed head-to-head record between two teams, two UFC fighters, or two tennis players. No first-class REST H2H exists — this tool filters match history server-side.
|
|
549
|
-
|
|
550
|
-
When to use:
|
|
551
|
-
- Rivalry / series record questions
|
|
552
|
-
- Supporting context for previews
|
|
553
|
-
|
|
554
|
-
Prefer over: agent-side double match-list filtering.
|
|
555
|
-
|
|
556
|
-
Do not use when: single-side form only → team_profile or player_profile.
|
|
557
|
-
|
|
558
|
-
Caveat: Dota filters are weaker; expect meta.warnings when data is sparse.
|
|
559
|
-
|
|
560
|
-
Parallel-safe: yes. Upstream cost: 2–4.
|
|
565
|
+
description: `Composed head-to-head record between two teams, two UFC fighters, or two tennis players. No first-class REST H2H exists — this tool filters match history server-side.
|
|
566
|
+
|
|
567
|
+
When to use:
|
|
568
|
+
- Rivalry / series record questions
|
|
569
|
+
- Supporting context for previews
|
|
570
|
+
|
|
571
|
+
Prefer over: agent-side double match-list filtering.
|
|
572
|
+
|
|
573
|
+
Do not use when: single-side form only → team_profile or player_profile.
|
|
574
|
+
|
|
575
|
+
Caveat: Dota filters are weaker; expect meta.warnings when data is sparse.
|
|
576
|
+
|
|
577
|
+
Parallel-safe: yes. Upstream cost: 2–4.
|
|
561
578
|
Example: { "game": "cs2", "sideA": "faze", "sideB": "navi", "limit": 20 }`,
|
|
562
579
|
inputSchema: {
|
|
563
580
|
type: 'object',
|
package/package.json
CHANGED