@claudinho/mcp 0.11.1 → 0.11.2
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 +61 -44
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -769,7 +769,7 @@ function formatTime(iso, opts = {}) {
|
|
|
769
769
|
}).format(when);
|
|
770
770
|
}
|
|
771
771
|
var COUNTDOWN_NOW = "now";
|
|
772
|
-
function countdown(iso, from
|
|
772
|
+
function countdown(iso, from) {
|
|
773
773
|
const when = parsedDate(iso);
|
|
774
774
|
if (!when) return UNKNOWN_TIME;
|
|
775
775
|
const ms = when.getTime() - from.getTime();
|
|
@@ -782,7 +782,7 @@ function countdown(iso, from = /* @__PURE__ */ new Date()) {
|
|
|
782
782
|
if (hours > 0) return `${hours}h${mins}m`;
|
|
783
783
|
return `${mins}m`;
|
|
784
784
|
}
|
|
785
|
-
function countdownPhrase(lang, iso, from
|
|
785
|
+
function countdownPhrase(lang, iso, from) {
|
|
786
786
|
const left = countdown(iso, from);
|
|
787
787
|
return left === COUNTDOWN_NOW ? t(lang, "countdown.now") : t(lang, "next.in", { countdown: left });
|
|
788
788
|
}
|
|
@@ -4728,7 +4728,7 @@ function fetchMeta(result) {
|
|
|
4728
4728
|
}
|
|
4729
4729
|
var ESPN_SOCCER = "https://site.api.espn.com/apis/site/v2/sports/soccer";
|
|
4730
4730
|
var DEFAULT_COMPETITION = BUNDLED_SLUG;
|
|
4731
|
-
var USER_AGENT = `claudinho/${"0.11.
|
|
4731
|
+
var USER_AGENT = `claudinho/${"0.11.2"} (+https://github.com/arturogarrido/claudinho)`;
|
|
4732
4732
|
var MAX_RESPONSE_BYTES = 5 * 1024 * 1024;
|
|
4733
4733
|
var DEFAULT_COOLDOWN_MS = 5 * 6e4;
|
|
4734
4734
|
var MAX_COOLDOWN_MS = 15 * 6e4;
|
|
@@ -6217,6 +6217,9 @@ function mergeLive(base, live) {
|
|
|
6217
6217
|
function clockOf(adapter) {
|
|
6218
6218
|
return new Date(adapter.now?.() ?? Date.now());
|
|
6219
6219
|
}
|
|
6220
|
+
function requestClock(adapter, given) {
|
|
6221
|
+
return given ?? clockOf(adapter);
|
|
6222
|
+
}
|
|
6220
6223
|
function providerDayOf(adapter, instant) {
|
|
6221
6224
|
if (Number.isNaN(instant.getTime())) return "";
|
|
6222
6225
|
return adapter.bucketDay?.(instant) || instant.toISOString().slice(0, 10);
|
|
@@ -6391,7 +6394,7 @@ async function marketFixtureForTeam(adapter, code, now = /* @__PURE__ */ new Dat
|
|
|
6391
6394
|
});
|
|
6392
6395
|
let refreshRead = {};
|
|
6393
6396
|
if (candidate) {
|
|
6394
|
-
const { partial, served: _served, ...r } = await getMatchById(adapter, candidate.id);
|
|
6397
|
+
const { partial, served: _served, ...r } = await getMatchById(adapter, candidate.id, now);
|
|
6395
6398
|
refreshRead = partial ? { partial } : {};
|
|
6396
6399
|
const m = r.degraded ? candidate : r.match ?? candidate;
|
|
6397
6400
|
if (!isFinished(m.status)) return { ...r, match: m, ...bothReads(windowRead, refreshRead) };
|
|
@@ -8079,13 +8082,13 @@ var STATUS_KEY = {
|
|
|
8079
8082
|
function flairOptsOf(opts) {
|
|
8080
8083
|
return { level: opts.flavor, locale: opts.locale, kind: opts.teamKind, pin: opts.pin };
|
|
8081
8084
|
}
|
|
8082
|
-
function matchLine(m, opts
|
|
8085
|
+
function matchLine(m, opts, flair = matchFlair(m, flairOptsOf(opts))) {
|
|
8083
8086
|
const head = `${withFlag(m.home.name, m.home.flag, "home")} ${scoreline(m)} ${withFlag(m.away.name, m.away.flag, "away")}`;
|
|
8084
8087
|
const lang = opts.locale;
|
|
8085
8088
|
const stage = stageLabelI18n(lang, m);
|
|
8086
8089
|
let tail;
|
|
8087
8090
|
if (m.status === "SCHEDULED") {
|
|
8088
|
-
tail = `${formatKickoff(m.kickoff, opts)} (${countdownPhrase(lang, m.kickoff)})`;
|
|
8091
|
+
tail = `${formatKickoff(m.kickoff, opts)} (${countdownPhrase(lang, m.kickoff, opts.now)})`;
|
|
8089
8092
|
} else if (m.status === "LIVE") {
|
|
8090
8093
|
tail = m.minute ? `${t(lang, "status.live")} ${m.minute}'` : t(lang, "status.live");
|
|
8091
8094
|
} else {
|
|
@@ -8104,7 +8107,7 @@ function truncationNote(list) {
|
|
|
8104
8107
|
function headingLine(lang, title) {
|
|
8105
8108
|
return t(lang, "heading", { title });
|
|
8106
8109
|
}
|
|
8107
|
-
function matchRows(matches, empty, opts
|
|
8110
|
+
function matchRows(matches, empty, opts) {
|
|
8108
8111
|
if (matches.length === 0) return empty;
|
|
8109
8112
|
const shown = matches.slice(0, MAX_LIST_MATCHES);
|
|
8110
8113
|
const flairs = matchFlairs(shown, flairOptsOf(opts));
|
|
@@ -8114,7 +8117,7 @@ function listTruncation(matches) {
|
|
|
8114
8117
|
const overflow = matches.length - MAX_LIST_MATCHES;
|
|
8115
8118
|
return overflow > 0 ? `(list truncated \u2014 ${overflow} more not shown)` : void 0;
|
|
8116
8119
|
}
|
|
8117
|
-
function matchList(matches, empty, opts
|
|
8120
|
+
function matchList(matches, empty, opts) {
|
|
8118
8121
|
const rows = matchRows(matches, empty, opts);
|
|
8119
8122
|
const truncated = listTruncation(matches);
|
|
8120
8123
|
return truncated ? `${rows}
|
|
@@ -8370,9 +8373,8 @@ async function cachedMarketSignals(args, matches, providerFactory = makeMarketPr
|
|
|
8370
8373
|
}
|
|
8371
8374
|
return { signals: result, complete };
|
|
8372
8375
|
}
|
|
8373
|
-
async function reliableMarketData(args, matches) {
|
|
8376
|
+
async function reliableMarketData(args, matches, now) {
|
|
8374
8377
|
if (!marketsEnabled()) return { data: void 0, complete: true };
|
|
8375
|
-
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
8376
8378
|
const relevant = matches.filter((m) => marketRelevant(m, now));
|
|
8377
8379
|
if (relevant.length === 0) return { data: void 0, complete: true };
|
|
8378
8380
|
const result = await cachedMarketSignals(args, relevant);
|
|
@@ -8388,9 +8390,11 @@ async function reliableMarketData(args, matches) {
|
|
|
8388
8390
|
complete: result.complete
|
|
8389
8391
|
};
|
|
8390
8392
|
}
|
|
8391
|
-
function fmtOpts(args, competition) {
|
|
8393
|
+
function fmtOpts(args, competition, now) {
|
|
8392
8394
|
const pin = choiceOf(args).pin;
|
|
8393
8395
|
return {
|
|
8396
|
+
// The tool's clock, read once where the tool reads it: a line's countdown is relative to it.
|
|
8397
|
+
now,
|
|
8394
8398
|
tz: args.tz,
|
|
8395
8399
|
locale: args.lang,
|
|
8396
8400
|
flavor: asFlavorLevel(args.flavor ?? process.env.CLAUDINHO_FLAVOR),
|
|
@@ -8431,17 +8435,18 @@ function toolGetToday(args) {
|
|
|
8431
8435
|
}
|
|
8432
8436
|
async function todayAnswer(args) {
|
|
8433
8437
|
const adapter = resolveAdapter(args);
|
|
8434
|
-
const
|
|
8438
|
+
const now = requestClock(adapter, args.now);
|
|
8439
|
+
const date = args.date ?? localDate(now.toISOString(), args.tz);
|
|
8435
8440
|
const day = await getMatchesForDate(adapter, date, resolveTz(args.tz));
|
|
8436
8441
|
const { matches, degraded, source } = day;
|
|
8437
8442
|
const todays = fixturesByDate(date, matches, args.tz);
|
|
8438
8443
|
const shownToday = boundedRecords(todays);
|
|
8439
|
-
const opts = fmtOpts(args, adapter.competition);
|
|
8444
|
+
const opts = fmtOpts(args, adapter.competition, now);
|
|
8440
8445
|
const empty = verdictNotice(day, args.lang) ?? dateUnreached(day, date, args.lang) ?? dateNoneRead(day, date, args.lang) ?? t(args.lang, "today.none");
|
|
8441
8446
|
const text = `${headingLine(args.lang, t(args.lang, "today.onDate", { date }))}
|
|
8442
8447
|
${matchRows(todays, empty, opts)}`;
|
|
8443
8448
|
const degradedLine = degraded ? `(${t(args.lang, day.skeleton ? "feed.degraded" : "live.degraded")})` : void 0;
|
|
8444
|
-
const market = await reliableMarketData(args, todays);
|
|
8449
|
+
const market = await reliableMarketData(args, todays, now);
|
|
8445
8450
|
const marketLine2 = market.complete ? void 0 : "(Market data unavailable or incomplete \u2014 not all fixtures were checked.)";
|
|
8446
8451
|
const attribution = dayAttribution(day, shownToday.items, args.lang);
|
|
8447
8452
|
return {
|
|
@@ -8479,9 +8484,10 @@ function toolGetLive(args = {}) {
|
|
|
8479
8484
|
}
|
|
8480
8485
|
async function liveAnswer(args) {
|
|
8481
8486
|
const adapter = resolveAdapter(args);
|
|
8482
|
-
const
|
|
8487
|
+
const now = requestClock(adapter, args.now);
|
|
8488
|
+
const live = await getLiveMatches(adapter, now);
|
|
8483
8489
|
const { matches, degraded, source } = live;
|
|
8484
|
-
const opts = fmtOpts(args, adapter.competition);
|
|
8490
|
+
const opts = fmtOpts(args, adapter.competition, now);
|
|
8485
8491
|
const text = degraded ? t(args.lang, "live.degraded") : `${headingLine(args.lang, t(args.lang, "live.title"))}
|
|
8486
8492
|
${matchRows(matches, verdictNotice(live, args.lang) ?? liveNoneRead(live, args.lang) ?? t(args.lang, "live.none"), opts)}`;
|
|
8487
8493
|
const shownLive = boundedRecords(matches);
|
|
@@ -8504,7 +8510,8 @@ function toolGetMatch(args) {
|
|
|
8504
8510
|
}
|
|
8505
8511
|
async function matchAnswer(args) {
|
|
8506
8512
|
const adapter = resolveAdapter(args);
|
|
8507
|
-
const
|
|
8513
|
+
const now = requestClock(adapter, args.now);
|
|
8514
|
+
const found = await getMatchById(adapter, args.id, now);
|
|
8508
8515
|
const { match, degraded, source: liveSource } = found;
|
|
8509
8516
|
if (!match) {
|
|
8510
8517
|
const msg = verdictNotice(found, args.lang) ?? matchWindowSentence(found, args.id, args.lang) ?? matchNoneReadSentence(found, args.id, args.lang) ?? t(args.lang, degraded ? "match.unreachable" : "match.none", { id: args.id });
|
|
@@ -8520,8 +8527,7 @@ async function matchAnswer(args) {
|
|
|
8520
8527
|
}
|
|
8521
8528
|
};
|
|
8522
8529
|
}
|
|
8523
|
-
const opts = fmtOpts(args, adapter.competition);
|
|
8524
|
-
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
8530
|
+
const opts = fmtOpts(args, adapter.competition, now);
|
|
8525
8531
|
let marketSignal;
|
|
8526
8532
|
let marketComplete = true;
|
|
8527
8533
|
if (marketsEnabled() && marketRelevant(match, now)) {
|
|
@@ -8696,7 +8702,7 @@ async function nextAnswer(args) {
|
|
|
8696
8702
|
if (!query) throw new Error(NO_TEAM);
|
|
8697
8703
|
const asked = pin ? { code: query } : bundleApplies(adapter.competition) ? nationArg(query) : { code: query };
|
|
8698
8704
|
const code = "code" in asked ? asked.code : query;
|
|
8699
|
-
const now = args.now
|
|
8705
|
+
const now = requestClock(adapter, args.now);
|
|
8700
8706
|
const next = pin ? await nextFixtureForPin(adapter, pin, now) : "code" in asked ? await getNextFixtureForTeam(adapter, code, now) : asked.answer;
|
|
8701
8707
|
const { fixture, degraded, source } = next;
|
|
8702
8708
|
const label = nextTeamLabel(next, code);
|
|
@@ -8716,7 +8722,7 @@ ${msg}`, next, args.lang), void 0, args.lang),
|
|
|
8716
8722
|
data: { ...about, fixture: null, degraded, source: source ?? null, ...verdictExtras(next) }
|
|
8717
8723
|
};
|
|
8718
8724
|
}
|
|
8719
|
-
const opts = fmtOpts(args, adapter.competition);
|
|
8725
|
+
const opts = fmtOpts(args, adapter.competition, now);
|
|
8720
8726
|
return {
|
|
8721
8727
|
// `source` in data mirrors the text's "Live data: …" attribution (parity
|
|
8722
8728
|
// with CLI `next --json`); null for a static group fixture (no live source).
|
|
@@ -8760,7 +8766,6 @@ function toolGetMarketSignal(args) {
|
|
|
8760
8766
|
}
|
|
8761
8767
|
async function marketAnswer(args) {
|
|
8762
8768
|
const provider = resolveMarketProvider(args);
|
|
8763
|
-
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
8764
8769
|
if (args.matchId) {
|
|
8765
8770
|
const scope = marketScopeVerdict(competitionOf(args), 0);
|
|
8766
8771
|
const outOfScope = verdictNotice(scope, args.lang);
|
|
@@ -8776,13 +8781,15 @@ async function marketAnswer(args) {
|
|
|
8776
8781
|
}
|
|
8777
8782
|
};
|
|
8778
8783
|
}
|
|
8779
|
-
const
|
|
8784
|
+
const adapter2 = resolveAdapter(args);
|
|
8785
|
+
const now2 = requestClock(adapter2, args.now);
|
|
8786
|
+
const found = await getMatchById(adapter2, args.matchId, now2);
|
|
8780
8787
|
const { match } = found;
|
|
8781
|
-
const relevant = match ? marketRelevant(match,
|
|
8788
|
+
const relevant = match ? marketRelevant(match, now2) : false;
|
|
8782
8789
|
const batch2 = match && relevant ? await getMarketSignals(provider, [match], MARKETS_TOOL_OPTS) : { results: /* @__PURE__ */ new Map(), complete: true };
|
|
8783
8790
|
const sig = match ? resolvedValues(batch2).get(match.id) : void 0;
|
|
8784
8791
|
const shown2 = batch2.complete && match && sig && marketDisplayable(match, sig) ? sig : void 0;
|
|
8785
|
-
const text2 = !match ? verdictNotice(found, args.lang) ?? `No match found with id ${args.matchId}.` : !batch2.complete ? `Market data unavailable or incomplete for ${marketHeader(match, args)} \u2014 this match could not be checked.` : shown2 ? marketText(match, shown2, args) : noSignalText(match, args,
|
|
8792
|
+
const text2 = !match ? verdictNotice(found, args.lang) ?? `No match found with id ${args.matchId}.` : !batch2.complete ? `Market data unavailable or incomplete for ${marketHeader(match, args)} \u2014 this match could not be checked.` : shown2 ? marketText(match, shown2, args) : noSignalText(match, args, now2);
|
|
8786
8793
|
return {
|
|
8787
8794
|
// The fixture read was not whole: said first, apart from `complete`
|
|
8788
8795
|
// (the market requests' own completeness).
|
|
@@ -8798,13 +8805,15 @@ async function marketAnswer(args) {
|
|
|
8798
8805
|
}
|
|
8799
8806
|
if (args.team) {
|
|
8800
8807
|
const code = args.team.toUpperCase();
|
|
8801
|
-
const
|
|
8808
|
+
const adapter2 = resolveAdapter(args);
|
|
8809
|
+
const now2 = requestClock(adapter2, args.now);
|
|
8810
|
+
const picked = await marketFixtureForTeam(adapter2, code, now2);
|
|
8802
8811
|
const { match: fixture, degraded } = picked;
|
|
8803
|
-
const relevant = fixture ? marketRelevant(fixture,
|
|
8812
|
+
const relevant = fixture ? marketRelevant(fixture, now2) : false;
|
|
8804
8813
|
const batch2 = fixture && relevant ? await getMarketSignals(provider, [fixture], MARKETS_TOOL_OPTS) : { results: /* @__PURE__ */ new Map(), complete: true };
|
|
8805
8814
|
const sig = fixture ? resolvedValues(batch2).get(fixture.id) : void 0;
|
|
8806
8815
|
const shown2 = batch2.complete && fixture && sig && marketDisplayable(fixture, sig) ? sig : void 0;
|
|
8807
|
-
const text2 = !fixture ? verdictNotice(picked, args.lang) ?? (degraded ? `Live feed unavailable \u2014 can't resolve ${code}'s next fixture right now.` : `No upcoming fixture found for ${code}.`) : !batch2.complete ? `Market data unavailable or incomplete for ${marketHeader(fixture, args)} \u2014 this match could not be checked.` : shown2 ? marketText(fixture, shown2, args) : noSignalText(fixture, args,
|
|
8816
|
+
const text2 = !fixture ? verdictNotice(picked, args.lang) ?? (degraded ? `Live feed unavailable \u2014 can't resolve ${code}'s next fixture right now.` : `No upcoming fixture found for ${code}.`) : !batch2.complete ? `Market data unavailable or incomplete for ${marketHeader(fixture, args)} \u2014 this match could not be checked.` : shown2 ? marketText(fixture, shown2, args) : noSignalText(fixture, args, now2);
|
|
8808
8817
|
return {
|
|
8809
8818
|
// Either read the pick was made from was not whole: said first, apart
|
|
8810
8819
|
// from `complete` (the market requests' own completeness).
|
|
@@ -8820,8 +8829,10 @@ async function marketAnswer(args) {
|
|
|
8820
8829
|
}
|
|
8821
8830
|
};
|
|
8822
8831
|
}
|
|
8832
|
+
const adapter = resolveAdapter(args);
|
|
8833
|
+
const now = requestClock(adapter, args.now);
|
|
8823
8834
|
const date = args.date ?? localDate(now.toISOString(), args.tz);
|
|
8824
|
-
const day = await getMatchesForDate(
|
|
8835
|
+
const day = await getMatchesForDate(adapter, date, resolveTz(args.tz));
|
|
8825
8836
|
const fixtureRead = marketsCoverCompetition(competitionOf(args)) ? day : {};
|
|
8826
8837
|
const todays = fixturesByDate(date, day.matches, args.tz).filter((m) => marketRelevant(m, now));
|
|
8827
8838
|
const batch = await getMarketSignals(provider, todays, MARKETS_TOOL_OPTS);
|
|
@@ -8863,9 +8874,8 @@ ${shown.items.map(({ match, signal }) => marketText(match, signal, args)).join("
|
|
|
8863
8874
|
}
|
|
8864
8875
|
};
|
|
8865
8876
|
}
|
|
8866
|
-
async function reliableSignalMap(args, matches) {
|
|
8877
|
+
async function reliableSignalMap(args, matches, now) {
|
|
8867
8878
|
if (!marketsEnabled()) return { signals: /* @__PURE__ */ new Map(), complete: true };
|
|
8868
|
-
const now = args.now ?? /* @__PURE__ */ new Date();
|
|
8869
8879
|
const relevant = matches.filter((m) => marketRelevant(m, now));
|
|
8870
8880
|
if (relevant.length === 0) return { signals: /* @__PURE__ */ new Map(), complete: true };
|
|
8871
8881
|
const result = await cachedMarketSignals(args, relevant);
|
|
@@ -8938,11 +8948,12 @@ function shareKindAsked(args) {
|
|
|
8938
8948
|
}
|
|
8939
8949
|
async function shareAnswer(args) {
|
|
8940
8950
|
const options = shareOptions(args);
|
|
8941
|
-
const signalsFor = (ms) => args.includeMarkets === false ? Promise.resolve({ signals: /* @__PURE__ */ new Map(), complete: true }) : reliableSignalMap(args, ms);
|
|
8951
|
+
const signalsFor = (ms, now2) => args.includeMarkets === false ? Promise.resolve({ signals: /* @__PURE__ */ new Map(), complete: true }) : reliableSignalMap(args, ms, now2);
|
|
8942
8952
|
const competition = selectedOf(args).slug;
|
|
8943
8953
|
const where = { tz: args.tz, locale: args.lang, competition };
|
|
8944
8954
|
if (args.live) {
|
|
8945
|
-
const
|
|
8955
|
+
const adapter2 = resolveAdapter(args);
|
|
8956
|
+
const live = await getLiveMatches(adapter2, requestClock(adapter2, args.now));
|
|
8946
8957
|
const shownLive = boundedRecords(live.matches);
|
|
8947
8958
|
return shareResult(
|
|
8948
8959
|
liveShareCard(live, where, {
|
|
@@ -9012,24 +9023,29 @@ async function shareAnswer(args) {
|
|
|
9012
9023
|
};
|
|
9013
9024
|
}
|
|
9014
9025
|
if (args.matchId) {
|
|
9015
|
-
const
|
|
9016
|
-
const
|
|
9026
|
+
const adapter2 = resolveAdapter(args);
|
|
9027
|
+
const now2 = requestClock(adapter2, args.now);
|
|
9028
|
+
const found = await getMatchById(adapter2, args.matchId, now2);
|
|
9029
|
+
const market2 = await signalsFor(found.match ? [found.match] : [], now2);
|
|
9017
9030
|
return shareResult(matchShareCard(found, args.matchId, market2, where), options);
|
|
9018
9031
|
}
|
|
9019
9032
|
if (args.team) {
|
|
9020
|
-
const
|
|
9033
|
+
const adapter2 = resolveAdapter(args);
|
|
9021
9034
|
const query = humanLabel(args.team, 40);
|
|
9022
|
-
const asked = bundleApplies(
|
|
9035
|
+
const asked = bundleApplies(adapter2.competition) ? nationArg(query) : { code: query };
|
|
9023
9036
|
const code = "code" in asked ? asked.code : query;
|
|
9024
|
-
const
|
|
9025
|
-
const
|
|
9037
|
+
const now2 = requestClock(adapter2, args.now);
|
|
9038
|
+
const next = "code" in asked ? await getNextFixtureForTeam(adapter2, code, now2) : asked.answer;
|
|
9039
|
+
const market2 = await signalsFor(next.fixture ? [next.fixture] : [], now2);
|
|
9026
9040
|
return shareResult(nextShareCard(next, code, market2, where), options);
|
|
9027
9041
|
}
|
|
9028
|
-
const
|
|
9029
|
-
const
|
|
9042
|
+
const adapter = resolveAdapter(args);
|
|
9043
|
+
const now = requestClock(adapter, args.now);
|
|
9044
|
+
const date = args.date ?? localDate(now.toISOString(), args.tz);
|
|
9045
|
+
const day = await getMatchesForDate(adapter, date, resolveTz(args.tz));
|
|
9030
9046
|
const todays = fixturesByDate(date, day.matches, args.tz);
|
|
9031
9047
|
const shownToday = boundedRecords(todays);
|
|
9032
|
-
const market = await signalsFor(shownToday.items);
|
|
9048
|
+
const market = await signalsFor(shownToday.items, now);
|
|
9033
9049
|
return shareResult(
|
|
9034
9050
|
dateShareCard(
|
|
9035
9051
|
{
|
|
@@ -9055,7 +9071,7 @@ async function shareAnswer(args) {
|
|
|
9055
9071
|
|
|
9056
9072
|
// src/server.ts
|
|
9057
9073
|
var SERVER_NAME = "claudinho";
|
|
9058
|
-
var SERVER_VERSION = "0.11.
|
|
9074
|
+
var SERVER_VERSION = "0.11.2";
|
|
9059
9075
|
var VOICE = asFlavorLevel(process.env.CLAUDINHO_FLAVOR) === "off" ? "" : `
|
|
9060
9076
|
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!"): use it as a tone cue. Keep every fact exact; never invent details and never impersonate or name a real commentator.`;
|
|
9061
9077
|
var INSTRUCTIONS = `Claudinho serves live scores, fixtures, and standings for one football competition per request, chosen by the tool call's competition argument (an alias such as premier-league, or an ESPN slug such as eng.1), else the server's CLAUDINHO_COMPETITION, else the user's saved choice (set with claudinho follow <alias>). With none of the three, every competition-answering tool answers noCompetition with a sentence saying what to do: pass competition, or ask the user to run claudinho follow <alias>. list_competitions lists the supported competitions, their aliases and what each offers, offline. Every tool's text but get_team's, get_share_snippet's and list_competitions' starts with the competition it is for, and its structured data carries it as competition (get_share_snippet's card names it in its title; list_competitions says it last, as Current, and in data.current; get_team is the World Cup's roster). An unknown competition is a tool error that lists the aliases.
|
|
@@ -9674,8 +9690,9 @@ function buildServer() {
|
|
|
9674
9690
|
},
|
|
9675
9691
|
async (uri, variables) => {
|
|
9676
9692
|
const date = String(variables.date ?? "");
|
|
9693
|
+
const now = /* @__PURE__ */ new Date();
|
|
9677
9694
|
const text = `${competitionLabel(BUNDLE_COMPETITION)}
|
|
9678
|
-
${matchList(fixturesByDate(date, void 0, "UTC"), `No matches on ${date}
|
|
9695
|
+
${matchList(fixturesByDate(date, void 0, "UTC"), `No matches on ${date}.`, { now })}`;
|
|
9679
9696
|
return { contents: [{ uri: uri.href, mimeType: "text/plain", text }] };
|
|
9680
9697
|
}
|
|
9681
9698
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claudinho/mcp",
|
|
3
|
-
"version": "0.11.
|
|
3
|
+
"version": "0.11.2",
|
|
4
4
|
"mcpName": "io.github.arturogarrido/claudinho",
|
|
5
5
|
"description": "An MCP server with live football scores, fixtures, standings and paste-ready match cards for the competition you follow: the World Cup, the Premier League, LALIGA, the Champions League and 12 more. Works with Claude Code, Cursor, Codex, Claude Desktop, Windsurf, Zed and any MCP client. No API key. Independent fan project. Not affiliated with FIFA, any confederation, league or club, or Anthropic.",
|
|
6
6
|
"type": "module",
|
|
@@ -73,7 +73,7 @@
|
|
|
73
73
|
"tsup": "^8.0.0",
|
|
74
74
|
"typescript": "^5.7.0",
|
|
75
75
|
"vitest": "^5.0.3",
|
|
76
|
-
"@claudinho/core": "0.11.
|
|
76
|
+
"@claudinho/core": "0.11.2"
|
|
77
77
|
},
|
|
78
78
|
"scripts": {
|
|
79
79
|
"build": "tsup",
|