cito-mcp 0.4.2 → 0.4.3
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 +21 -3
- package/dist/tools/player.js +19 -6
- package/dist/tools/resolve.js +14 -4
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -213,9 +213,27 @@ When a key is `null` the image does not exist for that entity; when the whole
|
|
|
213
213
|
never partially shaped — if any image exists, all four keys are present.
|
|
214
214
|
|
|
215
215
|
Tennis is the exception on purpose: the feed supplies a single `portrait_url`
|
|
216
|
-
(Wikimedia) and no square crop, so that one URL fills both `headshotUrl`
|
|
217
|
-
`imageUrl`, and `proxiedImageUrl` stays `null` because only `ufc.com` URLs have
|
|
218
|
-
a proxy.
|
|
216
|
+
(Wikimedia Commons) and no square crop, so that one URL fills both `headshotUrl`
|
|
217
|
+
and `imageUrl`, and `proxiedImageUrl` stays `null` because only `ufc.com` URLs have
|
|
218
|
+
a proxy.
|
|
219
|
+
|
|
220
|
+
**Tennis images carry their licence and credit** — and a UI is expected to render
|
|
221
|
+
them:
|
|
222
|
+
|
|
223
|
+
```jsonc
|
|
224
|
+
"images": {
|
|
225
|
+
"headshotUrl": "https://commons.wikimedia.org/wiki/Special:FilePath/Hoang_WMQ18_%2833%29_%2842647295495%29.jpg?width=400",
|
|
226
|
+
"license": "CC BY-SA 2.0",
|
|
227
|
+
"attribution": "si.robi",
|
|
228
|
+
"sourceUrl": "https://commons.wikimedia.org/wiki/File:Hoang_WMQ18_(33)_(42647295495).jpg"
|
|
229
|
+
}
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
Commons portraits are mostly CC BY / CC BY-SA, which for commercial display
|
|
233
|
+
generally requires naming the author and stating the licence. `attribution` is
|
|
234
|
+
`null` for public-domain and CC0 images, which need no credit — that is a fact,
|
|
235
|
+
not missing data. Anything without a defensible licence has its URL removed
|
|
236
|
+
upstream, so a non-null `headshotUrl` always has a `license` beside it.
|
|
219
237
|
|
|
220
238
|
### Games
|
|
221
239
|
|
package/dist/tools/player.js
CHANGED
|
@@ -54,16 +54,29 @@ function identityFrom(game, raw, idHint, slugHint) {
|
|
|
54
54
|
*/
|
|
55
55
|
images: {
|
|
56
56
|
// Tennis supplies exactly one likeness, `portrait_url` (a Wikimedia
|
|
57
|
-
// portrait), and no separate square headshot crop. Before this,
|
|
58
|
-
// read only headshotUrl/bodyImageUrl/imageUrl/photoUrl — none of
|
|
59
|
-
// tennis route emits — so every tennis profile shipped four
|
|
60
|
-
// while a perfectly good photo sat one key away
|
|
61
|
-
// tennis had no images at all. The portrait fills the headshot slot too:
|
|
62
|
-
// a card with the real photo slightly cropped beats a faceless card.
|
|
57
|
+
// Commons portrait), and no separate square headshot crop. Before this,
|
|
58
|
+
// the shaper read only headshotUrl/bodyImageUrl/imageUrl/photoUrl — none of
|
|
59
|
+
// which the tennis route emits — so every tennis profile shipped four
|
|
60
|
+
// explicit nulls while a perfectly good photo sat one key away.
|
|
63
61
|
headshotUrl: pickString(r.headshotUrl, r.headshot, r.portrait_url) ?? null,
|
|
64
62
|
bodyImageUrl: pickString(r.bodyImageUrl, r.fullBodyImageUrl) ?? null,
|
|
65
63
|
imageUrl: pickString(r.imageUrl, r.image, r.photoUrl, r.portrait_url) ?? null,
|
|
66
64
|
proxiedImageUrl: pickString(r.proxiedImageUrl, r.proxiedHeadshotUrl) ?? null,
|
|
65
|
+
/**
|
|
66
|
+
* The licence and the credit, carried with the URL.
|
|
67
|
+
*
|
|
68
|
+
* Commons portraits are mostly CC BY / CC BY-SA, which for commercial
|
|
69
|
+
* display generally obliges you to name the author and state the licence.
|
|
70
|
+
* Handing back a bare URL and letting a builder render it silently is what
|
|
71
|
+
* gets a product a takedown letter, so the fields a UI must show travel in
|
|
72
|
+
* the same object as the image. `attribution` is null for public-domain
|
|
73
|
+
* and CC0 images, which need no credit — that is a fact, not missing data.
|
|
74
|
+
* Anything without a defensible licence has its URL removed upstream, so a
|
|
75
|
+
* non-null headshotUrl here always has a licence beside it.
|
|
76
|
+
*/
|
|
77
|
+
license: pickString(r.portrait_license) ?? null,
|
|
78
|
+
attribution: pickString(r.portrait_attribution) ?? null,
|
|
79
|
+
sourceUrl: pickString(r.portrait_source_url) ?? null,
|
|
67
80
|
},
|
|
68
81
|
};
|
|
69
82
|
}
|
package/dist/tools/resolve.js
CHANGED
|
@@ -892,15 +892,25 @@ Example: { "game": "ufc", "q": "Jon Jones", "type": "fighter", "limit": 10 }`,
|
|
|
892
892
|
const upstreamTotal = total;
|
|
893
893
|
let droppedBelowFloor = [];
|
|
894
894
|
/**
|
|
895
|
-
* The
|
|
895
|
+
* The upstream's own top ENTITY row is exempt from the floor.
|
|
896
896
|
*
|
|
897
897
|
* The upstream's dedicated search knows aliases the payload does not carry:
|
|
898
898
|
* `q=Nole` returns Novak Djokovic first, and rankScore cannot see why, so a
|
|
899
899
|
* pure floor would delete the correct answer and keep substring collisions
|
|
900
|
-
* instead.
|
|
901
|
-
*
|
|
900
|
+
* instead.
|
|
901
|
+
*
|
|
902
|
+
* This used to be the global items[0], which was wrong: search_entities
|
|
903
|
+
* merges several sources CONCURRENTLY (for tennis, /players/search and
|
|
904
|
+
* /competitions), so whichever promise settled first decided which row got
|
|
905
|
+
* protected. The live gate caught it as a flaky "first result is Jannik
|
|
906
|
+
* Sinner" — a competition could land at index 0 and the alias protection
|
|
907
|
+
* would guard the wrong thing. Only entity rows (player/team/fighter) are
|
|
908
|
+
* alias-matched at all; tournaments are matched by name and have no
|
|
909
|
+
* nicknames, so taking the first entity row is both deterministic and the
|
|
910
|
+
* row the rule was written for.
|
|
902
911
|
*/
|
|
903
|
-
const
|
|
912
|
+
const ENTITY_TYPES = new Set(['player', 'team', 'fighter']);
|
|
913
|
+
const protectedRow = q ? items.find((it) => ENTITY_TYPES.has(it.type)) ?? null : null;
|
|
904
914
|
const protectedKey = protectedRow ? `${protectedRow.game}:${protectedRow.type}:${protectedRow.id}` : null;
|
|
905
915
|
if (q) {
|
|
906
916
|
// Publish the score on every row, not just the ones the scored branch
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cito-mcp",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.3",
|
|
4
4
|
"description": "Standalone MCP server for the Cito esports and sports API — 42 curated outcome tools for agents (live scoreboards, round economy, opening duels, clutches, vetoes, rosters, tennis, mma).",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|