propline-mcp 0.38.0 → 0.40.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/README.md +2 -2
- package/dist/http.js +43 -11
- package/dist/http.js.map +1 -1
- package/dist/index.js +43 -11
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -27,7 +27,7 @@ The model uses these tools transparently:
|
|
|
27
27
|
| `propline_list_sports` | Discover what sports PropLine polls (54 today) |
|
|
28
28
|
| `propline_list_events` | Upcoming events for a sport, with ids |
|
|
29
29
|
| `propline_list_event_markets` | Available market types for an event |
|
|
30
|
-
| `propline_get_odds` | Live odds — bulk by sport or full props per event. Accepts `period` (q1/h1/p1/f5/…) to scope to game-period markets. |
|
|
30
|
+
| `propline_get_odds` | Live odds — bulk by sport or full props per event. Accepts `period` (q1/h1/p1/f5/…) to scope to game-period markets; `include_depth` adds order-book depth per outcome. |
|
|
31
31
|
| `propline_get_odds_history` | Hobby+: snapshot history per outcome; supports `period` (q1/h1/…) plus time-window filters (from/to, relative_from/relative_to, interval, changes_only) |
|
|
32
32
|
| `propline_get_odds_closing` | Hobby+: opening **and** closing line per (book, market, outcome) — CLV helper. Accepts `period` to scope to a specific game period. |
|
|
33
33
|
| `propline_grade_clv` | Hobby+: grade **placed** bets against their closing lines. Returns closing price, de-vigged closing fair (`fair_source` = sharpest book at close, not yours), `clv_pct` (price-vs-price, vig-blind) **and** `ev_vs_close_pct` (the honest number), plus the graded result once the game settles. Fail-closed matching; unstarted events come back `closing_is_final: false` and are excluded from the averages. `devig`: multiplicative or shin. |
|
|
@@ -41,7 +41,7 @@ The model uses these tools transparently:
|
|
|
41
41
|
| `propline_get_resolution_summary` | Graded-prop volume + per-sport/market breakdown (free) |
|
|
42
42
|
| `propline_get_event_stats` | Raw box-score stats (free, book-agnostic) |
|
|
43
43
|
| `propline_get_event_context` | Game conditions a prop settles under — probable pitchers, lineup flag, home-plate umpire, first-pitch weather (free) |
|
|
44
|
-
| `propline_get_event_movement` | Line movement + steam detection (sharp-money signal across all books) from the tick history (Hobby+) |
|
|
44
|
+
| `propline_get_event_movement` | Line movement + steam detection (sharp-money signal across all books) from the tick history (Hobby+). `since` (e.g. `-6h`) measures from a moment; `include_book_ids` adds book ids. |
|
|
45
45
|
| `propline_get_event_results` | Pro: graded won/lost/push per prop |
|
|
46
46
|
| `propline_get_player_history` | Player prop history with resolution |
|
|
47
47
|
| `propline_get_player_games` | Player game log — recent games with every raw box-score stat per game, one call instead of one per event; `opponent` gives head-to-head (last N *meetings*). Raw-stat archive, so it includes games no book priced |
|
package/dist/http.js
CHANGED
|
@@ -123,7 +123,8 @@ var PropLineClient = class {
|
|
|
123
123
|
bookmakers: opts.bookmakers,
|
|
124
124
|
period: opts.period,
|
|
125
125
|
includeLinks: opts.includeLinks ? "true" : void 0,
|
|
126
|
-
includeBookIds: opts.includeBookIds ? "true" : void 0
|
|
126
|
+
includeBookIds: opts.includeBookIds ? "true" : void 0,
|
|
127
|
+
includeDepth: opts.includeDepth ? "true" : void 0
|
|
127
128
|
};
|
|
128
129
|
if (opts.eventId) {
|
|
129
130
|
return this.request(
|
|
@@ -152,7 +153,12 @@ var PropLineClient = class {
|
|
|
152
153
|
getOddsClosing(sportKey, eventId, opts = {}) {
|
|
153
154
|
return this.request(
|
|
154
155
|
`/v1/sports/${sportKey}/events/${eventId}/odds/closing`,
|
|
155
|
-
{
|
|
156
|
+
{
|
|
157
|
+
markets: opts.markets,
|
|
158
|
+
bookmakers: opts.bookmakers,
|
|
159
|
+
period: opts.period,
|
|
160
|
+
opening_window: opts.openingWindow
|
|
161
|
+
}
|
|
156
162
|
);
|
|
157
163
|
}
|
|
158
164
|
/**
|
|
@@ -247,7 +253,13 @@ var PropLineClient = class {
|
|
|
247
253
|
getEventMovement(sportKey, eventId, opts = {}) {
|
|
248
254
|
return this.request(
|
|
249
255
|
`/v1/sports/${sportKey}/events/${eventId}/movement`,
|
|
250
|
-
{
|
|
256
|
+
{
|
|
257
|
+
markets: opts.markets,
|
|
258
|
+
bookmakers: opts.bookmakers,
|
|
259
|
+
period: opts.period,
|
|
260
|
+
since: opts.since,
|
|
261
|
+
includeBookIds: opts.includeBookIds ? "true" : void 0
|
|
262
|
+
}
|
|
251
263
|
);
|
|
252
264
|
}
|
|
253
265
|
// ----- Player history -----
|
|
@@ -316,7 +328,7 @@ var PropLineClient = class {
|
|
|
316
328
|
};
|
|
317
329
|
|
|
318
330
|
// src/server.ts
|
|
319
|
-
var VERSION = "0.
|
|
331
|
+
var VERSION = "0.40.0";
|
|
320
332
|
var DEMO_KEY = "be2b8487fcfacb1fbc292a8aa925a84c";
|
|
321
333
|
var apiKey = process.env.PROPLINE_API_KEY;
|
|
322
334
|
var baseUrl = process.env.PROPLINE_BASE_URL;
|
|
@@ -420,7 +432,7 @@ var tools = [
|
|
|
420
432
|
{
|
|
421
433
|
name: "propline_get_odds",
|
|
422
434
|
title: "Get odds",
|
|
423
|
-
description: "Get live odds. If event_id is supplied, returns full per-event props for that event; otherwise returns bulk game-line odds for the whole sport. Pass markets as a comma-separated list (e.g. 'h2h,spreads,totals' or 'player_points,player_rebounds'). Response includes a bookmakers[] array across every book that carries the requested markets (currently up to 27: Bovada, DraftKings, FanDuel, Pinnacle, BetMGM, BetRivers, Unibet, BetUS, BetOnline.ag, LowVig.ag, MyBookie.ag, Fanatics, Marathon Bet, 1xBet, TAB, Underdog Fantasy, PrizePicks, Sleeper, Dabble, Betr Picks, ReBet, Kalshi, Polymarket, Matchbook, Smarkets, Novig, ProphetX \u2014 coverage varies by sport). Underdog Fantasy outcomes carry a payout_multiplier on EVERY outcome (1.0 = standard pick, e.g. 1.5 = boost, 0.75 = discount; null means the book is not Underdog) \u2014 keep only payout_multiplier == 1.0 when comparing DFS lines to sportsbook consensus, since filtering on non-null would drop every Underdog line. Each market carries suspended_at: null while on the board, set when that book pulled the market pregame (late scratch, dropped market type) \u2014 its outcomes are then the last quoted legs, not a live price. Treat a suspended market as unbettable and, if several books show it for one player, as a probable scratch. Each BOOKMAKER carries pregame_only: true when the event is live and that book does not price it in play, so its prices are the last pregame quote and will never move again this game. suspended_at cannot show this \u2014 a book with no in-play feed is never polled once the game starts, so nothing goes missing to flag. Exclude pregame_only books when reasoning about a live game; they are still returned because on DFS books that frozen line is what the bet settles against. Each market also carries team: the canonical event team name when the market is scoped to ONE team (a TEAM total), and null for the game total. Both ride the totals key, so NEVER compare totals on (market key, point) alone \u2014 a team total at 0.5 is not a game total at 0.5. Filter team == null for the game total; team matches home_team/away_team exactly. Always null outside totals.",
|
|
435
|
+
description: "Get live odds. If event_id is supplied, returns full per-event props for that event; otherwise returns bulk game-line odds for the whole sport. Pass markets as a comma-separated list (e.g. 'h2h,spreads,totals' or 'player_points,player_rebounds'). Response includes a bookmakers[] array across every book that carries the requested markets (currently up to 27: Bovada, DraftKings, FanDuel, Pinnacle, BetMGM, BetRivers, Unibet, BetUS, BetOnline.ag, LowVig.ag, MyBookie.ag, Fanatics, Marathon Bet, 1xBet, TAB, Underdog Fantasy, PrizePicks, Sleeper, Dabble, Betr Picks, ReBet, Kalshi, Polymarket, Matchbook, Smarkets, Novig, ProphetX \u2014 coverage varies by sport). Underdog Fantasy outcomes carry a payout_multiplier on EVERY outcome (1.0 = standard pick, e.g. 1.5 = boost, 0.75 = discount; null means the book is not Underdog) \u2014 keep only payout_multiplier == 1.0 when comparing DFS lines to sportsbook consensus, since filtering on non-null would drop every Underdog line. Each market carries suspended_at: null while on the board, set when that book pulled the market pregame (late scratch, dropped market type) \u2014 its outcomes are then the last quoted legs, not a live price. Treat a suspended market as unbettable and, if several books show it for one player, as a probable scratch. Each BOOKMAKER carries pregame_only: true when the event is live and that book does not price it in play, so its prices are the last pregame quote and will never move again this game. suspended_at cannot show this \u2014 a book with no in-play feed is never polled once the game starts, so nothing goes missing to flag. Exclude pregame_only books when reasoning about a live game; they are still returned because on DFS books that frozen line is what the bet settles against. Each market also carries team: the canonical event team name when the market is scoped to ONE team (a TEAM total), and null for the game total. Both ride the totals key, so NEVER compare totals on (market key, point) alone \u2014 a team total at 0.5 is not a game total at 0.5. Filter team == null for the game total; team matches home_team/away_team exactly. Always null outside totals. Each outcome carries side ('home'/'away'/'draw', null for Over/Under/Yes/No/player legs) so you can pair legs without matching team spellings. Each event carries is_outright (true for a tournament listing with no away side) and, on tennis, tournament + tour (ATP/WTA/Challenger/ITF/\u2026).",
|
|
424
436
|
inputSchema: {
|
|
425
437
|
type: "object",
|
|
426
438
|
properties: {
|
|
@@ -448,6 +460,10 @@ var tools = [
|
|
|
448
460
|
include_book_ids: {
|
|
449
461
|
type: "boolean",
|
|
450
462
|
description: "When true, each bookmaker block carries book_event_id and each outcome carries book_outcome_id \u2014 that book's OWN ids for the event and the priced selection, for joining onto a book's native feed by id instead of matching team/player names and lines. Kalshi ships both (event ticker + per-contract market ticker, e.g. KXMLBGAME-26AUG08NYYBOS-NYY); most other books ship an event id; books without a stable id return null. NB a two-sided market can share ONE book_outcome_id across both legs \u2014 a Kalshi contract is binary, so Over/Under are its YES/NO sides; the outcome's name says which side."
|
|
463
|
+
},
|
|
464
|
+
include_depth: {
|
|
465
|
+
type: "boolean",
|
|
466
|
+
description: "When true, every outcome carries depth: up to three order-book levels beyond the served price, each {price (American), size (dollars)}. [] for books whose depth PropLine does not read (sportsbooks)."
|
|
451
467
|
}
|
|
452
468
|
},
|
|
453
469
|
required: ["sport_key"],
|
|
@@ -459,7 +475,8 @@ var tools = [
|
|
|
459
475
|
bookmakers: args.bookmakers,
|
|
460
476
|
period: args.period,
|
|
461
477
|
includeLinks: args.include_links,
|
|
462
|
-
includeBookIds: args.include_book_ids
|
|
478
|
+
includeBookIds: args.include_book_ids,
|
|
479
|
+
includeDepth: args.include_depth
|
|
463
480
|
})
|
|
464
481
|
},
|
|
465
482
|
{
|
|
@@ -528,7 +545,7 @@ var tools = [
|
|
|
528
545
|
{
|
|
529
546
|
name: "propline_get_odds_closing",
|
|
530
547
|
title: "Get opening & closing lines",
|
|
531
|
-
description: "Hobby+ endpoint. Returns the OPENING and CLOSING line per (book, market, outcome) for an event. Closing = the last snapshot at or before commence_time (price/point/closing_at); opening = the first snapshot
|
|
548
|
+
description: "Hobby+ endpoint. Returns the OPENING and CLOSING line per (book, market, outcome) for an event. Closing = the last snapshot at or before commence_time (price/point/closing_at); opening = the first snapshot PropLine holds for the outcome, however far before kickoff the book posted it (opening_price/opening_point/opening_at); pass opening_window to limit that lookback. Canonical CLV-tracking helper; one call returns both data points your bet should be measured against, instead of fetching full history and post-processing. Compare the POINTS as well as the prices \u2014 on spreads and totals the number moves as much as the price, so a price-only comparison mis-measures those markets. opening_age_seconds says how long before kickoff the opener was recorded: the archive starts 2026-04, so a small value means PropLine started polling late and this is not the book's true open. Free tier returns redacted structure with upgrade pointer.",
|
|
532
549
|
inputSchema: {
|
|
533
550
|
type: "object",
|
|
534
551
|
properties: {
|
|
@@ -542,6 +559,10 @@ var tools = [
|
|
|
542
559
|
period: {
|
|
543
560
|
type: "string",
|
|
544
561
|
description: "Game-period filter. Omitted = full-game markets only. Canonical codes (q1..q4, h1/h2, p1..p3, i1..i9, f3/f5/f7), comma-separated, or 'all'."
|
|
562
|
+
},
|
|
563
|
+
opening_window: {
|
|
564
|
+
type: ["string", "number"],
|
|
565
|
+
description: "Limit the opening lookback to this many days before kickoff (1-3650), or 'all' (default: the first snapshot held). 14 matches the resolved-props export's opening columns."
|
|
545
566
|
}
|
|
546
567
|
},
|
|
547
568
|
required: ["sport_key", "event_id"],
|
|
@@ -553,7 +574,8 @@ var tools = [
|
|
|
553
574
|
{
|
|
554
575
|
markets: args.markets,
|
|
555
576
|
bookmakers: args.bookmakers,
|
|
556
|
-
period: args.period
|
|
577
|
+
period: args.period,
|
|
578
|
+
openingWindow: args.opening_window === void 0 ? void 0 : String(args.opening_window)
|
|
557
579
|
}
|
|
558
580
|
)
|
|
559
581
|
},
|
|
@@ -783,7 +805,7 @@ var tools = [
|
|
|
783
805
|
{
|
|
784
806
|
name: "propline_get_nhl_daily_goals_total",
|
|
785
807
|
title: "Get NHL daily goals total",
|
|
786
|
-
description: "Free-tier endpoint. Returns the synthetic daily NHL goals total (hockey's equivalent of the MLB Grand Salami) for a given
|
|
808
|
+
description: "Free-tier endpoint. Returns the synthetic daily NHL goals total (hockey's equivalent of the MLB Grand Salami) for a given US Eastern date \u2014 total goals scored across every NHL game on the slate (including OT/SO) plus each book's implied Daily Goals Total line (median of per-game primary totals across our NHL books). No retail sportsbook quotes this as a single market. Useful for: 'what's the total goal line for tonight's full NHL slate', 'did the Daily Goals Total go over yesterday', 'historical NHL daily-goals results for backtesting'.",
|
|
787
809
|
inputSchema: {
|
|
788
810
|
type: "object",
|
|
789
811
|
properties: {
|
|
@@ -873,7 +895,7 @@ var tools = [
|
|
|
873
895
|
{
|
|
874
896
|
name: "propline_get_event_movement",
|
|
875
897
|
title: "Get line movement & steam",
|
|
876
|
-
description: "Line movement + steam detection from the snapshot tick history. Per (book, market, outcome): opening line, latest line, signed implied-probability shift, point shift, direction. The steam[] array flags outcomes that multiple books moved the same direction \u2014 the classic sharp-money signal, computed across all 27 books PropLine polls. When a book moves the line itself, that outcome's prob_shift is null and direction is 'line_moved' (excluded from the steam signal). No pull-only odds API can produce this. Hobby+ full; free tier redacted.",
|
|
898
|
+
description: "Line movement + steam detection from the snapshot tick history. Per (book, market, outcome): opening line, latest line, signed implied-probability shift, point shift, direction. The steam[] array flags outcomes that multiple books moved the same direction \u2014 the classic sharp-money signal, computed across all 27 books PropLine polls. When a book moves the line itself, that outcome's prob_shift is null and direction is 'line_moved' (excluded from the steam signal). No pull-only odds API can produce this. Each outcome carries outcome_id (the id /odds and webhooks use); steam rows carry team (team totals) plus open_point/latest_point. Hobby+ full; free tier redacted.",
|
|
877
899
|
inputSchema: {
|
|
878
900
|
type: "object",
|
|
879
901
|
properties: {
|
|
@@ -890,6 +912,14 @@ var tools = [
|
|
|
890
912
|
period: {
|
|
891
913
|
type: "string",
|
|
892
914
|
description: "Game-period filter (q1..q4, h1/h2, p1..p3, i1..i9, f3/f5/f7; comma-separated, or 'all'). Omit for full-game."
|
|
915
|
+
},
|
|
916
|
+
since: {
|
|
917
|
+
type: "string",
|
|
918
|
+
description: "Measure movement from this moment instead of each line's first quote: ISO-8601 timestamp or a negative offset from now ('-6h', '-30m', '-2d'). Steam then covers only moves inside the window."
|
|
919
|
+
},
|
|
920
|
+
include_book_ids: {
|
|
921
|
+
type: "boolean",
|
|
922
|
+
description: "When true, each outcome also carries book_outcome_id \u2014 the book's own selection id."
|
|
893
923
|
}
|
|
894
924
|
},
|
|
895
925
|
required: ["sport_key", "event_id"],
|
|
@@ -901,7 +931,9 @@ var tools = [
|
|
|
901
931
|
{
|
|
902
932
|
markets: args.markets,
|
|
903
933
|
bookmakers: args.bookmakers,
|
|
904
|
-
period: args.period
|
|
934
|
+
period: args.period,
|
|
935
|
+
since: args.since,
|
|
936
|
+
includeBookIds: args.include_book_ids
|
|
905
937
|
}
|
|
906
938
|
)
|
|
907
939
|
},
|