@claudinho/mcp 0.9.4 → 0.10.0
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/index.js +22 -12
- package/package.json +6 -6
package/dist/index.js
CHANGED
|
@@ -6,7 +6,7 @@ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js"
|
|
|
6
6
|
// src/server.ts
|
|
7
7
|
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
8
8
|
import { types as utilTypes } from "util";
|
|
9
|
-
import { z } from "zod";
|
|
9
|
+
import { z } from "zod/v3";
|
|
10
10
|
|
|
11
11
|
// ../core/dist/index.js
|
|
12
12
|
var REGIONAL_INDICATOR_A = 127462;
|
|
@@ -3425,7 +3425,7 @@ function parseEspnStandings(raw) {
|
|
|
3425
3425
|
complete = false;
|
|
3426
3426
|
}
|
|
3427
3427
|
const entries = takeBounded(rawEntries, MAX_GROUP_ROWS);
|
|
3428
|
-
const
|
|
3428
|
+
const seenCodes = /* @__PURE__ */ new Map();
|
|
3429
3429
|
const seenRanks = /* @__PURE__ */ new Set();
|
|
3430
3430
|
const ranked = [];
|
|
3431
3431
|
for (const e of entries) {
|
|
@@ -3434,14 +3434,17 @@ function parseEspnStandings(raw) {
|
|
|
3434
3434
|
if (r.kind !== "definitive-none") complete = false;
|
|
3435
3435
|
continue;
|
|
3436
3436
|
}
|
|
3437
|
-
const
|
|
3438
|
-
|
|
3437
|
+
const { providerId, providerRank } = r.value;
|
|
3438
|
+
const code = r.value.team.code;
|
|
3439
|
+
const priorHadId = seenCodes.get(code);
|
|
3440
|
+
const codeCollision = priorHadId !== void 0 && (providerId === void 0 || priorHadId === false);
|
|
3441
|
+
if (codeCollision || seenRanks.has(providerRank) || providerId !== void 0 && seenProviderIds.has(providerId)) {
|
|
3439
3442
|
complete = false;
|
|
3440
3443
|
continue;
|
|
3441
3444
|
}
|
|
3442
|
-
|
|
3443
|
-
seenRanks.add(
|
|
3444
|
-
if (
|
|
3445
|
+
seenCodes.set(code, providerId !== void 0);
|
|
3446
|
+
seenRanks.add(providerRank);
|
|
3447
|
+
if (providerId !== void 0) seenProviderIds.add(providerId);
|
|
3445
3448
|
const { providerId: _dropId, providerRank: rank, ...row } = r.value;
|
|
3446
3449
|
ranked.push({ row, rank });
|
|
3447
3450
|
}
|
|
@@ -3469,7 +3472,7 @@ function parseEspnStandings(raw) {
|
|
|
3469
3472
|
var ESPN_SOCCER = "https://site.api.espn.com/apis/site/v2/sports/soccer";
|
|
3470
3473
|
var DEFAULT_COMPETITION = "fifa.world";
|
|
3471
3474
|
var DEFAULT_BASE = `${ESPN_SOCCER}/${DEFAULT_COMPETITION}`;
|
|
3472
|
-
var USER_AGENT = `claudinho/${"0.
|
|
3475
|
+
var USER_AGENT = `claudinho/${"0.10.0"} (+https://github.com/arturogarrido/claudinho)`;
|
|
3473
3476
|
var MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
3474
3477
|
function competitionBase(slug) {
|
|
3475
3478
|
return `${ESPN_SOCCER}/${slug}`;
|
|
@@ -4387,12 +4390,12 @@ function resolveCompetition(explicit) {
|
|
|
4387
4390
|
return DEFAULT_COMPETITION;
|
|
4388
4391
|
}
|
|
4389
4392
|
var KNOWN_SOURCES = ["espn"];
|
|
4390
|
-
function makeAdapter(source = "espn") {
|
|
4393
|
+
function makeAdapter(source = "espn", opts = {}) {
|
|
4391
4394
|
switch (source) {
|
|
4392
4395
|
case "espn": {
|
|
4393
4396
|
const competition = resolveCompetition();
|
|
4394
4397
|
const baseUrl = competition === DEFAULT_COMPETITION ? void 0 : competitionBase(competition);
|
|
4395
|
-
return new EspnAdapter({ baseUrl });
|
|
4398
|
+
return new EspnAdapter({ baseUrl, enrichGroups: opts.enrichGroups });
|
|
4396
4399
|
}
|
|
4397
4400
|
default:
|
|
4398
4401
|
throw new Error(
|
|
@@ -5237,6 +5240,10 @@ function numberish(v) {
|
|
|
5237
5240
|
}
|
|
5238
5241
|
return void 0;
|
|
5239
5242
|
}
|
|
5243
|
+
var MARKET_COMPETITIONS = /* @__PURE__ */ new Set([DEFAULT_COMPETITION]);
|
|
5244
|
+
function marketsCoverCompetition(competition = resolveCompetition()) {
|
|
5245
|
+
return MARKET_COMPETITIONS.has(competition);
|
|
5246
|
+
}
|
|
5240
5247
|
function resolveMarketSource(explicit) {
|
|
5241
5248
|
if (explicit) return explicit;
|
|
5242
5249
|
if (typeof process !== "undefined" && process.env?.CLAUDINHO_MARKETS_SOURCE) {
|
|
@@ -5253,6 +5260,7 @@ function makeMarketProvider(source) {
|
|
|
5253
5260
|
return new FakeMarketProvider();
|
|
5254
5261
|
// no synth → yields no signals, no network
|
|
5255
5262
|
default:
|
|
5263
|
+
if (!marketsCoverCompetition()) return new FakeMarketProvider();
|
|
5256
5264
|
return new PolymarketProvider();
|
|
5257
5265
|
}
|
|
5258
5266
|
}
|
|
@@ -5584,7 +5592,9 @@ function marketText(m, sig, args) {
|
|
|
5584
5592
|
return `${marketHeader(m, args)}
|
|
5585
5593
|
${marketBlock(sig, m).join("\n")}`;
|
|
5586
5594
|
}
|
|
5595
|
+
var MARKETS_SCOPE_NOTE = "Market signals cover the World Cup only; none are read for this competition.";
|
|
5587
5596
|
function noSignalText(m, args, now) {
|
|
5597
|
+
if (!marketsCoverCompetition()) return `${marketHeader(m, args)} \u2014 ${MARKETS_SCOPE_NOTE}`;
|
|
5588
5598
|
if (marketRelevant(m, now)) return `No reliable market signal for ${marketHeader(m, args)}.`;
|
|
5589
5599
|
const verb = isFinished(m.status) ? "has finished" : "appears to have finished";
|
|
5590
5600
|
return `${marketHeader(m, args)} ${verb} \u2014 market signals are pre-match and in-play reads.`;
|
|
@@ -5929,7 +5939,7 @@ ${shown.items.map(({ match, signal }) => marketText(match, signal, args)).join("
|
|
|
5929
5939
|
// so "we could not reach the market data" rendered as the confident
|
|
5930
5940
|
// "there is none", which is the failure this project refuses everywhere
|
|
5931
5941
|
// else.
|
|
5932
|
-
batch.complete ? `No reliable market signals on ${date}.` : `Market data unavailable or incomplete for ${date} \u2014 not all fixtures could be checked.`
|
|
5942
|
+
!marketsCoverCompetition() ? `${MARKETS_SCOPE_NOTE} (${date})` : batch.complete ? `No reliable market signals on ${date}.` : `Market data unavailable or incomplete for ${date} \u2014 not all fixtures could be checked.`
|
|
5933
5943
|
);
|
|
5934
5944
|
if (shown.shown > 0 && !batch.complete) {
|
|
5935
5945
|
text += `
|
|
@@ -6187,7 +6197,7 @@ async function toolGetShareSnippet(args) {
|
|
|
6187
6197
|
|
|
6188
6198
|
// src/server.ts
|
|
6189
6199
|
var SERVER_NAME = "claudinho";
|
|
6190
|
-
var SERVER_VERSION = "0.
|
|
6200
|
+
var SERVER_VERSION = "0.10.0";
|
|
6191
6201
|
var VOICE = asFlavorLevel(process.env.CLAUDINHO_FLAVOR) === "off" ? "" : `
|
|
6192
6202
|
Voice: when relaying scores, narrate with lively, regionally-appropriate football-commentary energy in the user's language. Each match line may end with a short exclamation ("\u2014 \xA1GOOOOL!") \u2014 use it as a tone cue. Keep every fact exact; never invent details and never impersonate or name a real commentator.`;
|
|
6193
6203
|
var INSTRUCTIONS = `Claudinho serves live scores, fixtures, and group standings for the 2026 men's football tournament.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudinho/mcp",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"mcpName": "io.github.arturogarrido/claudinho",
|
|
5
5
|
"description": "World Cup MCP server for the 2026 men's football tournament — live scores, fixtures, standings, read-only prediction-market signals, and paste-ready match cards. Works with Claude Code, Cursor, Codex, Windsurf, Zed. Not affiliated with FIFA or Anthropic.",
|
|
6
6
|
"type": "module",
|
|
@@ -51,15 +51,15 @@
|
|
|
51
51
|
],
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@modelcontextprotocol/sdk": "^1.30.0",
|
|
54
|
-
"zod": "^
|
|
54
|
+
"zod": "^4.6.2"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
|
-
"@types/node": "^22.20.
|
|
58
|
-
"@vitest/coverage-v8": "^4.1.
|
|
57
|
+
"@types/node": "^22.20.2",
|
|
58
|
+
"@vitest/coverage-v8": "^4.1.11",
|
|
59
59
|
"tsup": "^8.0.0",
|
|
60
60
|
"typescript": "^5.7.0",
|
|
61
|
-
"vitest": "^4.1.
|
|
62
|
-
"@claudinho/core": "0.
|
|
61
|
+
"vitest": "^4.1.11",
|
|
62
|
+
"@claudinho/core": "0.10.0"
|
|
63
63
|
},
|
|
64
64
|
"scripts": {
|
|
65
65
|
"build": "tsup",
|