@semanticintent/semantic-chirp-intelligence-mcp 4.0.2 → 4.0.4

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.
@@ -20,5 +20,5 @@
20
20
  "position": "D"
21
21
  }
22
22
  ],
23
- "updated_at": "2026-09-01T20:56:50.722Z"
23
+ "updated_at": "2026-09-01T23:04:34.827Z"
24
24
  }
@@ -30,5 +30,5 @@
30
30
  "slot": "LW"
31
31
  }
32
32
  ],
33
- "updated_at": "2026-09-01T20:56:50.579Z"
33
+ "updated_at": "2026-09-01T23:04:34.685Z"
34
34
  }
@@ -13,5 +13,5 @@
13
13
  "points": 138
14
14
  }
15
15
  ],
16
- "updated_at": "2026-09-01T20:56:50.874Z"
16
+ "updated_at": "2026-09-01T23:04:34.980Z"
17
17
  }
@@ -22,6 +22,7 @@ import { NHL_SCHEDULE, NhlScheduleService } from '../services/NhlScheduleService
22
22
  import { toNhlTricode } from '../domain/nhl-teams.js';
23
23
  import { LEAGUE_DATA, LeagueDataService } from '../services/LeagueDataService.js';
24
24
  import { NHL_STATS } from '../services/NhlStatsService.js';
25
+ import { ROSTER_STORE } from '../services/RosterStore.js';
25
26
  /** Skater and goalie slots this analysis reasons about. */
26
27
  const TRACKED_POSITIONS = ['C', 'LW', 'RW', 'D', 'G'];
27
28
  export class DraftPickAnalysis extends AnalysisTemplate {
@@ -49,7 +50,21 @@ export class DraftPickAnalysis extends AnalysisTemplate {
49
50
  // Board state comes entirely from what the user tells us — there is no
50
51
  // platform to ask. `already_drafted` is therefore the source, not a
51
52
  // fallback, and the pick number follows from it unless stated.
52
- const draftedNames = new Set((args.already_drafted ?? []).map(n => this.normalizeName(n)));
53
+ // `already_drafted` is pasted from a draft board, so each entry may carry a
54
+ // pick number, club and position around the name — "1. (1) Connor McDavid
55
+ // EDM - C". Matching those raw against a player name never succeeds, so
56
+ // they run through the same forgiving parser set_roster uses, which
57
+ // resolves each line to an actual NHL player id.
58
+ const draftedText = (args.already_drafted ?? []).join('\n');
59
+ const draftedReport = draftedText.trim()
60
+ ? ROSTER_STORE.parseRoster(draftedText)
61
+ : { resolved: [], unresolved: [], ambiguous: [], lines_read: 0 };
62
+ const draftedIds = new Set(draftedReport.resolved.map(p => p.player_id));
63
+ // Anything the parser could not pin to one player is still excluded by name,
64
+ // so a near-miss removes the right player more often than not — and the
65
+ // unmatched lines are reported rather than silently dropped.
66
+ const draftedNames = new Set([...draftedReport.unresolved, ...draftedReport.ambiguous]
67
+ .map((entry) => this.normalizeName(entry.line)));
53
68
  const rosterPositions = {};
54
69
  for (const p of rawData.roster?.players ?? []) {
55
70
  for (const pos of String(p.position ?? '').split(',')) {
@@ -75,11 +90,12 @@ export class DraftPickAnalysis extends AnalysisTemplate {
75
90
  }));
76
91
  return {
77
92
  draftPool: pool,
78
- draftedIds: new Set(),
93
+ draftedIds,
79
94
  draftedNames,
80
- draftedCount: draftedNames.size,
81
- draftResultsAvailable: false,
82
- manualDraftedCount: draftedNames.size,
95
+ draftedCount: draftedIds.size,
96
+ draftResultsAvailable: draftedIds.size > 0,
97
+ manualDraftedCount: draftedIds.size,
98
+ draftedUnmatched: [...draftedReport.unresolved, ...draftedReport.ambiguous],
83
99
  rosterPositions,
84
100
  playoffWindow: this.resolvePlayoffWindow(args),
85
101
  poolCaveat: rawData.pool_caveat
@@ -92,7 +108,7 @@ export class DraftPickAnalysis extends AnalysisTemplate {
92
108
  const d = data;
93
109
  const maxResults = args.max_results ?? 8;
94
110
  // Pick on the clock: explicit, else inferred from picks already made.
95
- const pickNumber = args.pick_number ?? (Math.max(d.draftedCount, d.draftedNames.size) + 1);
111
+ const pickNumber = args.pick_number ?? (d.draftedCount + 1);
96
112
  const needs = args.roster_needs?.length
97
113
  ? args.roster_needs.map(p => p.toUpperCase())
98
114
  : this.inferNeeds(d.rosterPositions);
@@ -111,7 +127,8 @@ export class DraftPickAnalysis extends AnalysisTemplate {
111
127
  roster_needs: needs,
112
128
  pool_size: d.draftPool.length,
113
129
  available_count: available.length,
114
- players_off_board: d.draftedIds.size + d.draftedNames.size,
130
+ players_off_board: d.draftedIds.size,
131
+ drafted_unmatched: d.draftedUnmatched ?? [],
115
132
  draft_results_available: d.draftResultsAvailable,
116
133
  manual_drafted_count: d.manualDraftedCount,
117
134
  playoff_window: d.playoffWindow,
@@ -188,9 +205,14 @@ export class DraftPickAnalysis extends AnalysisTemplate {
188
205
  pick_number_source: chirpEnhanced.pick_number_source,
189
206
  roster_needs: chirpEnhanced.roster_needs,
190
207
  players_off_board: chirpEnhanced.players_off_board,
191
- board_state: `${chirpEnhanced.players_off_board} player(s) marked as already drafted. ` +
192
- 'Board state comes from `already_drafted` there is no platform to read it from, ' +
193
- 'so tell me who has gone and the board updates.',
208
+ board_state: `${chirpEnhanced.players_off_board} player(s) removed from the board. ` +
209
+ 'Paste picks into `already_drafted` in whatever shape your draft room shows ' +
210
+ 'them pick numbers, clubs and positions around the name are fine.',
211
+ // Never silently swallow a line that did not resolve; on draft day an
212
+ // unmatched pick means a drafted player is still being recommended.
213
+ drafted_not_matched: chirpEnhanced.drafted_unmatched?.length
214
+ ? chirpEnhanced.drafted_unmatched
215
+ : undefined,
194
216
  board_note: chirpEnhanced.pool_caveat,
195
217
  schedule_source: chirpEnhanced.schedule_available
196
218
  ? `NHL public API (season ${NHL_SCHEDULE.getSeason()})`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@semanticintent/semantic-chirp-intelligence-mcp",
3
- "version": "4.0.2",
3
+ "version": "4.0.4",
4
4
  "description": "Universal fantasy hockey intelligence \u2014 a Model Context Protocol server that reads NHL schedule and player data and analyses any roster you paste. No account, no API key, no platform lock-in.",
5
5
  "type": "module",
6
6
  "main": "build/index.js",
@@ -43,6 +43,6 @@
43
43
  "vitest": "^4.1.10"
44
44
  },
45
45
  "dependencies": {
46
- "@modelcontextprotocol/sdk": "^1.19.1"
46
+ "@modelcontextprotocol/sdk": "^1.30.0"
47
47
  }
48
48
  }