TKB Picks MCP
Provides tools for accessing MLB game schedules, odds, player statistics, injuries, and betting props to support sports betting picks.
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@TKB Picks MCPGet today's NBA schedule, odds, and injury report"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
TKB Picks MCP Server (v2.8.6)
MCP server wrapping SportsGameOdds (odds, schedules, props, results) and BALLDONTLIE (stats, injuries, standings) for building TKB Picks betting threads across MLB, WNBA, NFL, CFB, and ATP/WTA tennis.
Deploy
Render Web Service, Node environment:
Build:
npm install && npm run buildStart:
npm startEnv vars:
SGO_API_KEY,BDL_API_KEY,CFBD_API_KEY,CBBD_API_KEY(the two college keys are optional and SEPARATE from each other, though they share one monthly quota: without either, every other tool works and that sport's hit rates refuse rather than fall back)MCP endpoint:
https://<your-app>.onrender.com/mcpHealth check:
/health
Then verify rather than assume:
npm test # no network needed
node scripts/verify-deploy.mjs --expect 2.8.6
node scripts/verify-deploy.mjs --screen <mlbEventID> # measures entity cost/health returns version, toolCount, tools and sports. The last three are
read off a running server, so they cannot go stale independently of the code. If
the version looks old but sports contains atp, the build is new and only the
constant was forgotten.
Related MCP server: MLB V3 Scores MCP Server
Sports and what each one supports
Sport | Key | Props | Hit rates | Injuries | Weather | Splits |
MLB |
| yes | yes | yes | yes | yes |
WNBA |
| yes | yes | yes | indoors | yes |
NFL |
| yes | yes | yes | yes | yes |
CFB |
| yes | yes (CollegeFootballData) | not on plan | yes | yes |
ATP |
| no | no | no | no | no |
WTA |
| no | no | no | no | no |
Capabilities are declared in src/constants.ts and checked by each tool. A sport
that does not support something returns an explanation naming the reason, never an
empty result that reads like an answer.
Tennis is moneyline only. Competitors occupy the home/away participant slots
on an event rather than roster positions, so event.players is permanently empty
and player props cannot be addressed by playerID. This is structural, not
unfinished. Use tkb_get_odds with marketType="moneyline".
Tools (27)
Picks
Tool | Purpose |
| Games by date/range/team. CFB tiering: top25 / power4 / rivalry / postable |
| Moneyline, spread, total, player props. Pricing guardrail enforced |
| Sweeps every posted prop for one event, ranked by edge or hit rate |
| Every priced prop on one event, NO hit-rate gate. Use when a screen returns empty |
| Moneyline, spread and total across a whole slate in one call |
| Live AP Top 25. Replaces the manual rankedTeams step. Zero SGO cost |
| Full standings table, records and point differential. Zero SGO cost |
| Real counted hit rate, DNP-excluded, season- and recency-labelled. CFB: pass |
| Is this player actually on the team the odds feed claims? Zero SGO cost |
| Milestone markets (first TD, any HR, double-double) |
| Half / quarter / inning / set markets |
| Roster and playerIDs for an event |
| Injury reports, multi-shape team resolution |
| Home/road via BDL standings; head-to-head via events |
| MLB + NFL + CFB, roof-aware |
| Confirmed probable pitchers and posted lineups, from MLB directly |
Content
Tool | Purpose |
| Active streaks and standout games. Non-pick content. Zero SGO quota |
| Opening versus current line. Rides an existing fetch |
| Cover-photo subject, availability-gated |
| True X-weighted length (URLs cost 23, emoji cost 2), plus the raw "Show more" count via |
Results
Tool | Purpose |
| Resolve one posted pick to WIN/LOSS/PUSH |
| Grade a whole day at once, one fetch per event |
| Early-cashout detection, over/under asymmetry enforced |
Ops
Tool | Purpose |
| SGO quota, plus cache hit/miss/coalesce counters |
| Diagnostic: BDL tier access and real field names |
| Diagnostic: which keys an SGO event carries. Never dumps odds |
| Diagnostic: the real CFBD category/type literals. RUN ONCE before trusting a CFB rate |
Design rules this connector actually enforces
These are not aspirations. Each one exists because its absence caused a specific
published or near-published error, documented in docs/.
A price is only usable if a named sportsbook posted it. SGO's modelled
fairOddsis never returned as odds. Four categories are blocked at the pricing layer so no call site can source from them, kept in separate sets because the REASON decides what to expect: pick'em apps (Underdog, PrizePicks, Sleeper, Betr, Dabble, ParlayPlay) distort by being flat; Fliff is real but unbettable here; prediction markets (Polymarket, Kalshi, PredictIt, Manifold) price contracts that are not comparable to an over/under; and offshore books (BetOnline, Bovada, MyBookie, BetUS and peers, added v2.8.6) post real prices a US follower cannot legally bet.The book filter is one constant, imported everywhere.
DEFAULT_BOOKMAKERSinsrc/constants.ts. All six odds tools use it, so changing which books this account prices against is a one-line edit in one file.Hit rates are counted, never estimated. Sample size is the real number of appearances, DNPs excluded rather than counted as misses.
A stat that cannot be resolved returns
null, never0. A missing field reading as zero is indistinguishable from a real zero.Ordering is self-describing. Game logs carry dates on every entry, because a bare newest-first array was once read backwards and published as its inverse.
Warnings, not filters. Stale samples and playing-time risk are surfaced with reasons; the writer decides. A tool that silently drops props teaches nothing.
Decaying facts come from the connector, never from an article. Records, streaks, standings position and rankings are wrong the moment a team plays again.
tkb_get_standingsandtkb_get_rankingsexist so those numbers are always re-derived rather than quoted from a source with a publish date.A missing rate is not a missing market.
tkb_screen_propscannot rank what it cannot score, so on a sport with no rate source it returns an empty board while a full one exists.tkb_get_prop_boardprints that board. Being unable to grade a market is not a reason to hide that it is priced.An unanswerable question gets a refusal, not a plausible answer. This is why capability flags exist, and why an empty injury filter can return CANNOT VERIFY.
Repo layout
src/
constants.ts sport config + capability flags (start here)
types.ts provider response shapes
index.ts server, tool registration, /health
services/ API clients, aggregators, pricing, catalogs
tools/ one file per registered MCP tool
data/ stadiums, CFB tiers
test/ npm test, no network required
scripts/ verify-deploy.mjs
docs/ changelogs, one per release
archive/tools/ removed in v2.0.0, kept for reference onlyKnown gaps
CFB hit rates need a team NAME, not an SGO teamID. CollegeFootballData keys box scores by name, so
tkb_get_player_hit_ratetakes an optionalteamNameand falls back to deriving one from the teamID. Pass it explicitly for CFB. Until v2.8.6 the teamID went through unconverted and every CFB hit rate returned NO SAMPLE.CFB availability is never probed. SGO carries no CFB player box scores outside the playoff, so
tkb_screen_propsskips the playing-time probe for CFB rather than spending ~60 entities a game to return an empty map. Confirm CFB availability from a published depth chart, and runtkb_verify_rosterfirst to catch a stale team field.CFB injuries are unavailable through BALLDONTLIE on the current plan.
WNBA and NCAAF player stats are GOAT-gated on BDL, so their hit rates fall back to SGO. A 401 disables the BDL path for 30 minutes and heals itself, so an upgrade takes effect without a redeploy.
SGO events carry no
lineupsfield. Confirmed live 2026-08-27 viatkb_probe_event_fieldsagainst an upcoming MLB game: the event has 11 top-level keys andlineupsis not among them, despite SGO's schema browser listing it. Confirmed starting pitchers still require a live web search, per game, per date.Retractable roofs are never assumed. Roof status is a same-day team decision; those stadiums are flagged for manual verification.
CFB rankings now come from BALLDONTLIE, not a live search. SGO still does not expose a ranking field, but BDL publishes the AP poll on the NCAAF ALL-STAR tier this account already holds. Run
tkb_get_rankingsand feed itsrankedTeamsstring intotkb_get_schedule.Player props appear close to game time. An empty roster means "not priced yet", not "no players". Build threads inside the normal pre-game window.
SGO carries no CFB player box scores outside the playoff. Measured 2026-08-31: Dante Moore started all 15 of Oregon's 2025 games and had a settled passing line in 3, all playoff games; Maddux Madsen, 1 of 14. CFB hit rates therefore come from CollegeFootballData, and with no
CFBD_API_KEYset they REFUSE rather than fall back - an SGO fallback would report started games as DNPs.In the opening weeks of any season there is no current-year sample. Pass
includePriorSeason: trueto widen the lookback to its 400-day ceiling and reach last season, and take it off around Week 5.tkb_get_prop_boardandtkb_get_game_linesstill work with no rate source at all.CFBD lists a player only where he recorded a stat, so absence cannot separate "did not play" from "quiet game". CFB availability returns UNKNOWN rather than a false OK, and depth-chart confirmation stays manual.
Tennis grading is unconfirmed against live data. The code path exists and needs one finished match to validate. See
docs/CHANGES-v2_6_0.md.
This server cannot be deployed
Maintenance
Related MCP Connectors
Sports Game Odds MCP — wraps the Sports Game Odds API (sportsgameodds.com)
NBA MCP — player, team, and game data via the BallDontLie API
SportsDataIO MCP — wraps SportsDataIO's Big-Six sports data API (sportsdata.io)
The hockey data API. Stats, odds, and everything between. REST API and MCP server.
Related MCP Servers
- AlicenseAqualityCmaintenanceAn MCP Server implementation that integrates the Balldontlie API, to provide information about players, teams and games for the NBA, NFL and MLB.430 npm26MIT
- FlicenseNot gradedqualityDmaintenanceAn MCP Server that enables interaction with MLB scores and statistics via the SportsData.io MLB V3 Scores API, allowing users to access baseball data through natural language queries.-
- FlicenseNot gradedqualityDmaintenanceAn MCP Server that provides access to NHL (National Hockey League) scores and statistics via the SportsData.io NHL v3 Scores API.-
- AlicenseAqualityCmaintenanceMCP server for NBA live data and stats, providing read-only tools to query live scores, box scores, player info, standings, and more from NBA.com.158 npm1MIT