Sports Betting Stats MCP
Provides live MLB scores, schedules, and results from ESPN.
Provides live NBA scores, schedules, and results from ESPN, plus NBA player prop lines and odds comparisons.
Provides live NHL scores, schedules, and results from ESPN.
Provides Premier League odds, opening and closing lines, results, and xG/shot data for match analysis and backtesting.
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., "@Sports Betting Stats MCPCompare tonight's NBA moneylines and show the best price per side."
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.
Sports Betting Stats MCP: odds, player props, scores, xG, horse racing, prediction markets
Everything a betting model or sports assistant needs, as MCP tools: live odds from US and European sportsbooks, player props, scores and schedules, football xG and shot data, historical closing lines, US horse racing entries and results, and prediction-market prices. One hosted endpoint, one Actor per job.
Hosted remote MCP server (Streamable HTTP) on Apify's MCP gateway. Client config plus a small open-source stdio proxy server. No Actor source.
Disclosure: entries marked "(maintained by us)" are Actors I maintain on Apify Store (publisher publicrecords). Every other Actor is independent, made by its own publisher and picked on merit (Store usage, ratings and recent maintenance). This repo is not affiliated with those publishers or with the sites the Actors read.
MCP endpoint
https://mcp.apify.com/?tools=publicrecords/sports-odds-api,scrapemint/sports-odds-scraper,zen-studio/prizepicks-player-props,sports-odds-lab/football-odds-results,hgservices/apify-actor-espn,constructive_calm/understat-football-analytics,jungle_synthesizer/equibase-us-horse-racing-scraper,congism/polymarket-kalshi-arb-finderAuth: sign in with Apify (OAuth) when your client prompts, or send an Apify API token as a Bearer token. Runs are billed on your own Apify account under each Actor's own Store pricing; see each Store page.
Related MCP server: mcp-odds-api
Tools
Actor | Store page | MCP tool | What it returns |
Sports Odds API (Kambi books) (maintained by us) |
| Live odds from Kambi-powered sportsbooks (BetRivers, Unibet, Paf, Svenska Spel, ATG): one row per game with every book's price and the best price per outcome. | |
Sports Odds Scraper |
| DraftKings, Pinnacle and Bovada moneyline, spread and totals on one line per game, with best price and arbitrage. | |
PrizePicks Player Props |
| Real-time PrizePicks player prop lines across many leagues: over/under lines, odds tiers, matchups. | |
Football Odds & Results |
| Soccer odds with opening and closing lines from many bookmakers, plus results, for 1,000+ leagues. | |
ESPN Scores & Schedules |
| Live scores, schedules and results from ESPN: NBA, NFL, MLB, NHL, MLS, EPL, NCAA and more. | |
Understat xG & Shot Data |
| Understat player and team xG, per-match win probabilities and shot-level data for the top European leagues. | |
Equibase Horse Racing |
| US Thoroughbred race entries (horses, jockeys, trainers, odds) and results (finish order, times, payouts). | |
Polymarket + Kalshi Arbitrage Finder |
| Matches binary markets on Polymarket and Kalshi and ranks price gaps between them. |
The Apify gateway also exposes helper tools to read run results (get-actor-run, get-dataset-items). Want fewer tools? Drop any Actor from the tools= list.
Who it's for
Bettors and tipsters: who has the best price on this game right now?
Modelers: closing lines, results and xG for backtests.
DFS and props players: today's PrizePicks lines next to the scores.
Racing fans: today's Equibase entries and yesterday's payouts.
Example prompts
Compare tonight's NBA moneylines across BetRivers, Unibet, DraftKings and Pinnacle and show the best price per side.
Which PrizePicks NBA props are posted for
<player>today?Give me the opening and closing odds and the result for
<team>'s last 10 Premier League matches.Show
<team>'s xG for and against over its last five matches.
Cursor / Claude Code / any remote-MCP client
{
"mcpServers": {
"sports-betting-stats": {
"url": "https://mcp.apify.com/?tools=publicrecords/sports-odds-api,scrapemint/sports-odds-scraper,zen-studio/prizepicks-player-props,sports-odds-lab/football-odds-results,hgservices/apify-actor-espn,constructive_calm/understat-football-analytics,jungle_synthesizer/equibase-us-horse-racing-scraper,congism/polymarket-kalshi-arb-finder"
}
}
}Claude Code:
claude mcp add --transport http sports-betting-stats "https://mcp.apify.com/?tools=publicrecords/sports-odds-api,scrapemint/sports-odds-scraper,zen-studio/prizepicks-player-props,sports-odds-lab/football-odds-results,hgservices/apify-actor-espn,constructive_calm/understat-football-analytics,jungle_synthesizer/equibase-us-horse-racing-scraper,congism/polymarket-kalshi-arb-finder"Claude Desktop (local bridge)
{
"mcpServers": {
"sports-betting-stats": {
"command": "npx",
"args": ["-y", "@apify/actors-mcp-server", "--actors", "publicrecords/sports-odds-api,scrapemint/sports-odds-scraper,zen-studio/prizepicks-player-props,sports-odds-lab/football-odds-results,hgservices/apify-actor-espn,constructive_calm/understat-football-analytics,jungle_synthesizer/equibase-us-horse-racing-scraper,congism/polymarket-kalshi-arb-finder"],
"env": { "APIFY_TOKEN": "YOUR_APIFY_TOKEN" }
}
}
}Local stdio server (open source)
This repo also ships a small MCP server in src/ for clients that only run local stdio servers. It answers initialize and tools/list locally from tools.json, which is generated from each Actor's public input schema and checked for drift in CI and weekly, so any client or directory can inspect the tools with no token. tools/call is forwarded to the hosted Apify MCP endpoint above with your own APIFY_TOKEN; without a token a call returns a clear error instead of running anything. The token is only sent in the Authorization header and is never logged.
{
"mcpServers": {
"sports-betting-stats": {
"command": "npx",
"args": ["-y", "github:GeminiGeorge22/sports-betting-stats-mcp"],
"env": { "APIFY_TOKEN": "YOUR_APIFY_TOKEN" }
}
}
}Or from a clone:
git clone https://github.com/GeminiGeorge22/sports-betting-stats-mcp.git
cd sports-betting-stats-mcp && npm install
APIFY_TOKEN=YOUR_APIFY_TOKEN node src/server.jsOptional env: APIFY_ACTORS (comma-separated subset of the Actors above) and APIFY_MCP_URL (full endpoint override).
Tests run against an in-memory mock server, with no network and no token: npm test. Requires Node.js 18+.
See also
ecommerce-search-rankings-mcp: E-commerce search results and rankings
ecommerce-sales-mcp: E-commerce sales signals
forecast-accuracy-mcp: Forecast accuracy and track records
sports-odds-mcp: Kambi sportsbook odds
etsy-sales-mcp: Etsy search and shop sales
ats-jobs-mcp: ATS job postings (Greenhouse, Lever, Ashby, SmartRecruiters)
gov-tenders-mcp: Government tenders and grants
Registry
Official MCP Registry name: io.github.GeminiGeorge22/sports-betting-stats-mcp
License
MIT, for this documentation, config and the proxy server code in src/. Each Actor belongs to its publisher.
Available Tools
8 toolscongism--polymarket-kalshi-arb-finderPolymarket + Kalshi Arbitrage FinderARead-onlyInspect
Polymarket + Kalshi Arbitrage Finder. Scans both Polymarket and Kalshi for matching binary prediction markets and identifies price discrepancies where buying YES on one platform and NO on the other guarantees a risk-free profit. Returns ranked opportunities with trade details and return %. Now covers PredictIt too - see our Arb Scanner.
When to use: Use when looking for price gaps between matching Polymarket and Kalshi binary markets.
Returns: the run's dataset rows as structured JSON (one row per result), plus the run and dataset IDs for paging the full dataset.
Behavior: starts one run of the Apify Actor "congism/polymarket-kalshi-arb-finder" through Apify's hosted MCP gateway (mcp.apify.com) with your own APIFY_TOKEN; the run uses your Apify account. Read-only: it only reads public web data and changes nothing on the source site. Docs: https://apify.com/congism/polymarket-kalshi-arb-finder
| Name | Required | Description | Default |
|---|---|---|---|
| minSpread | No | Minimum YES price difference between platforms to flag as an arb opportunity (0–1 scale). Example: 0.05 means at least 5 cents difference. Default: 0.02. | |
| maxResults | No | Maximum number of arb opportunities to return, sorted by return % descending. Default: 500. | |
| kalshiEmail | No | Your Kalshi account email. Required to fetch Kalshi market prices. Without this, only Polymarket data is scanned. | |
| minLiquidity | No | Only include markets with at least this much liquidity. Filters out thin markets where you can't fill a meaningful position. Default: 0. | |
| minReturnPct | No | Minimum estimated profit % per dollar risked. Example: 1.0 = only show opportunities worth at least 1% return. Default: 0.5. | |
| minVolume24h | No | Only include markets with at least this much 24-hour trading volume. Default: 0. | |
| minSimilarity | No | Keyword similarity threshold (0–1) for matching markets across platforms. Higher = stricter matching, fewer but more accurate pairs. Default: 0.25. | |
| kalshiPassword | No | Your Kalshi account password. Stored securely and only used to authenticate with the Kalshi API. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
The description adds context that annotations alone do not provide: the tool starts one run of the Apify Actor 'congism/polymarket-kalshi-arb-finder' through the hosted gateway with your own APIFY_TOKEN, the run consumes your Apify account, and the dataset, plus run and dataset IDs for paging, is returned. Read-only and open-world behavior is already declared in annotations and is not contradicted. It omits run duration, cost, and the consequence of omitting Kalshi credentials, which limits the score.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
It is well structured, with When to use, Returns, and Behavior sections that are easy to scan. The opening line just repeats the title, and the PredictIt and Arb Scanner sentence is promotional rather than operational, so both could be trimmed. It is otherwise dense and front-loaded.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an eight-parameter tool with no output schema, the description covers what is returned, how paging works, and the auth requirement for APIFY_TOKEN. It does not explain optional Kalshi authentication, runtime, or cost implications, leaving gaps for an agent deciding when and how to invoke the tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema description coverage is 100%, so every one of the eight parameters is already documented with defaults and examples. The description adds no guidance on setting minSpread, minSimilarity, or the Kalshi credentials, and therefore it does not go beyond the schema, consistent with the baseline.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description names a concrete verb and resource: it scans Polymarket and Kalshi for matching binary markets and identifies YES/NO price discrepancies that guarantee risk-free profit. That is far more specific than the title alone, and among its sports-odds siblings it offers a clear purpose. A minor deduction for the sentence 'Now covers PredictIt too - see our Arb Scanner', which suggests this tool may cover PredictIt even though it does not, muddying scope.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It includes an explicit 'When to use' line that limits the tool to price gaps between matching Polymarket and Kalshi binary markets, and it points to the Arb Scanner as an alternative for PredictIt. It does not state when not to use the tool, or the conditions that favor the sibling scanners, so the coverage is incomplete.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
constructive_calm--understat-football-analyticsUnderstat xG & Shot Data - Football AnalyticsARead-onlyInspect
Understat xG & Shot Data - Football Analytics. Scrapes Understat: player/team season aggregates, per-match xG/PPDA/win-probabilities, shot-level data with x/y coords + xG, situation/formation/game-state breakdowns, player career histories, and fixtures across the Big 5 + RFPL (2014–2025). Multi-season + multi-league in a single run.
When to use: Use for expected goals (xG), shot maps, PPDA and player or team season stats in the Big 5 European leagues and RFPL.
Returns: the run's dataset rows as structured JSON (one row per result), plus the run and dataset IDs for paging the full dataset.
Behavior: starts one run of the Apify Actor "constructive_calm/understat-football-analytics" through Apify's hosted MCP gateway (mcp.apify.com) with your own APIFY_TOKEN; the run uses your Apify account. Read-only: it only reads public web data and changes nothing on the source site. Docs: https://apify.com/constructive_calm/understat-football-analytics
| Name | Required | Description | Default |
|---|---|---|---|
| mode | Yes | What to scrape. 'league_players' returns per-player season aggregates (xG, xA, xGChain, xGBuildup, etc). 'league_teams' returns team season aggregates (W/D/L, xG, xGA, PPDA, points, xPoints). 'league_matches' returns played-match metadata (xG, win-prob, deep, ppda). 'match_shots' returns every shot with x/y coords, xG, situation, body part, result. 'team_situations' returns long-format breakdowns by situation/formation/game-state/timing/zones. 'player_career' returns one player's full multi-sea… | league_players |
| teams | No | Filter output to specific teams. Applies to league_players, league_teams, league_matches, fixtures, match_shots (league discovery) and team_situations. Names must match Understat's display names — e.g. 'Arsenal', 'Manchester United', 'Real Madrid' (matching is case-insensitive). A name that matches nothing produces a 'team_not_matched' status row with closest-name suggestions instead of failing silently. | |
| dateEnd | No | Restrict league_players stats to matches on or before this date. Leave empty for none. | |
| leagues | No | One or more of the six leagues Understat covers. Required for league_*, match_shots (when matchIds is empty), team_situations (when teams is empty), and fixtures. | |
| seasons | No | List of season start years as integers — 2025 = the 2025/26 season. Understat history goes back to 2014. The current season becomes valid automatically once it kicks off in August. Invalid entries are reported in a status row instead of being dropped silently. | |
| matchIds | No | Specific match IDs to scrape directly (used by match_shots). When set, leagues/seasons are ignored. Find IDs in Understat URLs: /match/{ID}. | |
| dateStart | No | Restrict league_players stats to matches on or after this date. Leave empty for none. | |
| playerIds | No | Player IDs for player_career mode. Find IDs in Understat URLs: /player/{ID}. Examples: 553 (Messi), 619 (Agüero), 1250 (Salah), 8260 (Haaland). | |
| positions | No | Filter players by position. Only applies to league_players mode (uses Understat's filtered POST endpoint). | |
| maxCostUsd | No | Hard cap on the run's total billed amount. The actor estimates cost up-front and stops gracefully if the cap is hit mid-run. | |
| maxResults | No | Stop emitting after this many dataset rows. 0 = unlimited (subject to maxCostUsd). | |
| nLastMatches | No | Filter player stats to the last N matches. 0 = full season. Only applies to league_players mode. | |
| includeRawJson | No | When true, attach the original Understat record under `_raw` on every output row. Useful for power users / debugging. Default off — keeps the dataset light. | |
| minAppearances | No | Drop player rows where games played is below this threshold (client-side filter). 0 = no filter. | |
| proxyConfiguration | No | Apify proxy. Understat does not block scrapers, but residential proxies help users behind corporate networks. Default = Apify residential. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Beyond the read-only and open-world annotations, the description explains that a run is started on the Apify Actor via the hosted MCP gateway using the caller's own APIFY_TOKEN and account. It also states that the operation only reads public web data and returns dataset rows plus run and dataset IDs for paging, which is useful operational context. It does not discuss rate limits or billing beyond the schema's maxCostUsd, so it falls short of the richest behavioral disclosure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is organized into clear 'When to use', 'Returns', and 'Behavior' sections, with the core purpose front-loaded. The opening line repeats the tool title and name, which is slightly redundant, but the remaining content is efficient and easy to scan.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given a 15-parameter scraper with a very rich input schema and no output schema, the description covers the essential context: what data is returned, how runs are authenticated, and that dataset IDs support paging. It does not document the row-level output shape, but the schema already carries nearly all parameter semantics, so the remaining gap is minor.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 15 parameters are already documented in detail, including mode-specific behavior and required combinations. The description only loosely restates that multi-season and multi-league runs are possible and does not add syntax or format meaning beyond the schema, making the baseline score appropriate.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific verb and resource: scraping Understat xG, shot, PPDA, and season aggregate data across the Big 5 and RFPL. It enumerates the data families (player/team aggregates, match xG, shot-level coordinates, career histories, fixtures), which clearly separates it from the sibling odds and player-prop tools.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
It gives a clear 'When to use' trigger: xG, shot maps, PPDA, and player or team season stats in the covered leagues. It does not name explicit alternatives or when-not-to-use conditions, so the agent must infer that odds-related siblings cover betting lines instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
hgservices--apify-actor-espnESPN Sports Scores & Schedules - NBA, NFL, MLB, NHL, MLS, EPL..ARead-onlyInspect
ESPN Sports Scores & Schedules - NBA, NFL, MLB, NHL, MLS, EPL... Get live scores, schedules, and game results from ESPN — covering NBA, NFL, MLB, NHL, MLS, EPL, NCAA, and more. Find the next game of any team. No API key needed. Filter by team, date, or status. Empty results explain why.
When to use: Use when you need scores, schedules or final results for NBA, NFL, MLB, NHL, MLS, EPL, NCAA and other leagues, or a team's next game.
Returns: the run's dataset rows as structured JSON (one row per result), plus the run and dataset IDs for paging the full dataset.
Behavior: starts one run of the Apify Actor "hgservices/apify-actor-espn" through Apify's hosted MCP gateway (mcp.apify.com) with your own APIFY_TOKEN; the run uses your Apify account. Read-only: it only reads public web data and changes nothing on the source site. Docs: https://apify.com/hgservices/apify-actor-espn
| Name | Required | Description | Default |
|---|---|---|---|
| date | No | Date for 'single' date mode, as YYYYMMDD (or YYYY-MM-DD). | |
| teams | No | Only return games of these teams. Use an ESPN code (LAL, GS, NY, WSH), a common code (GSW, NYK, WAS, LAK) or a team name (Lakers, Golden State Warriors). An entry applies to every selected league. To limit it to one league, add a league prefix, for example nba:LAC. Entries that match no team are reported in a notice item. Leave empty for all teams. | |
| endDate | No | Last day for 'range' date mode, as YYYYMMDD (or YYYY-MM-DD). A range can be up to 366 days. A longer range is cut to 366 days, and the run reports this in a notice item. | |
| leagues | Yes | League codes: nba, wnba, ncaam (NCAA men's basketball), ncaaw (NCAA women's basketball), nfl, ncaaf (NCAA football), mlb, nhl, mls, epl (English Premier League), laliga, ucl (UEFA Champions League). Ask only for the leagues you need: each league costs one request per day. | |
| dateMode | Yes | nextGames: the next games that are not over, from today - per league the next game day, or with 'teams' the next game of each team. Use it for 'when do they play next'. Many leagues skip days (NFL: mostly Thu, Sun, Mon), so 'today' is often empty. today, tomorrow, yesterday: one day. thisWeek: Mon-Sun. thisWeekend: Sat-Sun. next7Days, last7Days: 7 days from or to today. single: 'date'. range: 'startDate' to 'endDate', up to 366 days. Days are in 'timezone'. Options: today = Today; tomorrow = To… | today |
| liveOnly | No | Only games in progress at the moment of the run. Often empty: most games are in the evening (US time). For a schedule or scores, leave it false and read status.state of each game. | |
| timezone | No | IANA timezone (for example America/New_York, America/Los_Angeles, Europe/London). It sets what today, tomorrow and the other relative modes mean, and the time in dateLocal. Use the user's timezone. | America/New_York |
| startDate | No | First day for 'range' date mode, as YYYYMMDD (or YYYY-MM-DD). | |
| gameStatus | No | pre = scheduled (not started), in = in progress, post = final (also postponed or canceled). Keep all three unless you need only one kind, for example ["post"] for results only. | |
| networkFilter | No | Only games on these networks, as ESPN names them (for example ESPN, TNT, ABC, Prime Video). Not case-sensitive. | |
| homeAwayFilter | No | Only with teams: all games of those teams, only their home games, or only their away games. With dateMode nextGames, it finds the next home (or away) game. Options: all = All Games; home = Home Games Only; away = Away Games Only. | all |
| includeNotices | No | When a run returns no games, or the Actor ignored or changed part of the input, write one item with type 'notice' at the start of the dataset. It says why (for example: no NFL games today, the next ones are on Thursday) and what to change. Game items have type 'game'. Turn this off if your pipeline must get game items only. The explanation is also in the run's status message and in the SUMMARY record. | |
| nationalTvOnly | No | Only games on a US national TV or streaming network (ESPN, ABC, TNT, FOX, NBC, CBS, Prime Video and others). | |
| startingWithinHours | No | Only scheduled games that start in the next N hours (1-72). Games in progress and final games are kept. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Goes well beyond the annotations by disclosing that each call starts a run of the hosted Apify Actor through mcp.apify.com using the caller's own APIFY_TOKEN and Apify account, which implies billing and quota implications. It also describes the notice items for empty or altered results and notes the run can be paged via the returned run and dataset IDs.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well structured with labeled sections (When to use / Returns / Behavior / Docs) and the key capability is front-loaded. The opening restates the title and league list at some length, which is mild redundancy against an otherwise tight body.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 14-parameter tool with no output schema, the description still explains the return shape (one dataset row per result plus run and dataset IDs for paging), authentication requirements, and the optional notice rows. Nothing an agent needs to invoke it correctly is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all 14 parameters — including the tricky dateMode semantics, team code formats, and the 366-day range cap — are already documented in the schema. The description adds only a high-level summary ('Filter by team, date, or status') and the notice behavior, so the baseline of 3 applies.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb and resource ('Get live scores, schedules, and game results from ESPN') and enumerates the covered leagues, including the specialized 'find the next game of any team' capability. An agent can tell this is a scores/schedules tool rather than the odds, props, or analytics tools in the sibling set.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
A dedicated 'When to use' block names the conditions (scores, schedules, final results, next game) and the leagues that trigger it. It stops short of naming the sibling odds/analytics tools or stating when NOT to use it, so the routing decision is clear but not fully disambiguated.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
jungle_synthesizer--equibase-us-horse-racing-scraperEquibase Horse Racing Scraper - US Race Entries & ResultsARead-onlyInspect
Equibase Horse Racing Scraper - US Race Entries & Results. Scrape US Thoroughbred horse racing data from Equibase.com — the official source for North American racing. Extract race entries (horses, jockeys, trainers, odds) and results (finish order, times, payouts) for any date and track. Ideal for handicappers and sports analytics.
When to use: Use for US Thoroughbred race entries and results (horses, jockeys, trainers, morning-line odds, finish order, payouts) for a date and track.
Returns: the run's dataset rows as structured JSON (one row per result), plus the run and dataset IDs for paging the full dataset.
Behavior: starts one run of the Apify Actor "jungle_synthesizer/equibase-us-horse-racing-scraper" through Apify's hosted MCP gateway (mcp.apify.com) with your own APIFY_TOKEN; the run uses your Apify account. Read-only: it only reads public web data and changes nothing on the source site. Docs: https://apify.com/jungle_synthesizer/equibase-us-horse-racing-scraper
| Name | Required | Description | Default |
|---|---|---|---|
| dataMode | No | entries = race cards (horses, jockeys, trainers, odds); results = finish order + payouts; both = entries and results together (results only available for past races); late_changes = today's race-day changes instead of race cards, one record per change (scratches, course/surface switches, jockey and weight changes, track conditions; Equibase publishes the current race day only, so leave Race Date empty or set it to today). Options: entries = Entries only; results = Results only; both = Entries +… | both |
| maxItems | No | Maximum number of records to return (each race = one record; in late_changes mode each change = one record). Default 50 samples several meetings; raise it (e.g. 500+) to collect EVERY track racing on the date — the actor enumerates the full daily slate and fills up to this cap. | |
| raceDate | No | Date to scrape in MM/DD/YYYY format. Defaults to today. Use a recent past date to get completed results. Example: "" | |
| raceTypes | No | Optional race-type filter, matched as case-insensitive text against each race's type. Example: claiming keeps Claiming, Maiden Claiming, Optional Claiming and Starter Optional Claiming races; maiden keeps every Maiden race. Leave empty for all race types. Not used in late_changes mode. Example: [] | |
| sp_contact | No | We'll personally help with your use case. No spam. Example: "Share your email here..." | |
| trackCodes | No | Optional list of track codes to filter (e.g. AQU, CD, SA, GP). Leave empty to scrape all tracks running on the selected date. Example: [] | |
| filliesMaresOnly | No | Keep only races where every runner is a filly or mare. Off by default. Not used in late_changes mode. | |
| maxHorseProfiles | No | Upper bound on horse-history records per run (only used when Include horse history is on). Horses are taken in card order. | |
| sp_intended_usage | No | What will this data feed? E.g. lead lists, KYB checks, price tracking. | |
| includeHorseHistory | No | Adds one extra record per distinct horse in the saved races: every career start (track, date, race, finish, speed figure, race_id that joins to this actor's own race records) and the last 60 days of workouts, read from Equibase's public horse profile. Each profile is fetched once per run and billed as a premium record (see pricing). Not used in late_changes mode. Off by default. | |
| sp_improvement_suggestions | No | Provide any feedback or suggestions for improvements. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Well beyond the annotations, it discloses that the call starts a run of the named Apify Actor through mcp.apify.com using the caller's own APIFY_TOKEN and Apify account, and that premium billing applies to horse-history records. The read-only statement largely restates readOnlyHint/destructiveHint, but the auth and cost context is genuinely additive.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with a clear purpose sentence followed by labeled When-to-use / Returns / Behavior blocks, which is easy to scan. Some filler ("the official source for North American racing," "Ideal for handicappers and sports analytics") does not earn its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With 11 optional parameters and no output schema, the definition covers the missing return contract by describing dataset rows plus run/dataset IDs for paging. It is adequate for correct invocation, with only the optional contact/feedback fields left unexplained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already carries all parameter meaning; the description only reinforces the date/track scoping and the "one row per result" grain. It says nothing about the three sp_* feedback parameters, which a reader must infer from the schema alone.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description uses a specific verb and resource — "Scrape US Thoroughbred horse racing data from Equibase.com" — and enumerates the extracted entities (horses, jockeys, trainers, odds, finish order, times, payouts). It is clearly distinguishable from sibling sports-odds tools by domain, though it never names a sibling to route against.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
An explicit "When to use" section scopes it to US Thoroughbred entries and results for a date and track, and the parenthetical dataMode note (results only for past races, late_changes for today) gives real selection context. It stops short of stating when not to use it or which alternative sibling tool to pick instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
publicrecords--sports-odds-apiSports Odds API: BetRivers, Unibet, Paf, Svenska Spel, ATGARead-onlyInspect
Sports Odds API: BetRivers, Unibet, Paf, Svenska Spel, ATG. Live odds from 24 Kambi-powered sportsbooks in one call: BetRivers (12 US states + Ontario), Unibet (7 countries), Paf, Svenska Spel and ATG. One row per game with every book's price and the best price per outcome.
When to use: Use when you need current pre-match or live prices for a game or league from Kambi-powered books (BetRivers, Unibet, Paf, Svenska Spel, ATG) and want to compare books or find the best price per outcome. Not for DraftKings/FanDuel or historical odds.
Returns: the run's dataset rows as structured JSON (one row per result), plus the run and dataset IDs for paging the full dataset.
Behavior: starts one run of the Apify Actor "publicrecords/sports-odds-api" through Apify's hosted MCP gateway (mcp.apify.com) with your own APIFY_TOKEN; the run uses your Apify account. Read-only: it only reads public web data and changes nothing on the source site. Docs: https://apify.com/publicrecords/sports-odds-api
| Name | Required | Description | Default |
|---|---|---|---|
| leagues | No | Kambi paths, sport or league level: "basketball/nba", "american_football/nfl", "ice_hockey/nhl", "baseball/mlb", "football/england/premier_league", or a whole sport such as "tennis". Unknown paths are answered with suggestions and are never charged. | |
| markets | No | "main" returns the headline markets per game. "all" returns each game's full board (often 300–500 markets) and is priced higher. Options: main = Main lines (moneyline, spread, total); all = Every market incl. player props and alternates. | main |
| maxEvents | No | Soonest games first. | |
| operators | No | Kambi-powered books to price. Each book is a separate brand/jurisdiction feed; prices can differ between them. The list contains only books verified open on the date in the README. | |
| includeLive | No | Include games already started (live prices at the moment of the run). | |
| startsWithinHours | No | 0 = no limit. Live games are kept when "Include in-play games" is on. | |
| proxyConfiguration | No | On by default. Kambi limits how often one IP may ask; your run moves to a fresh Apify Proxy IP whenever it is slowed down. Turn off only to test without a proxy. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only, non-destructive and open-world, so the safety bar is low; the description still adds substantial operational context: it spins up an Apify Actor run under the caller's APIFY_TOKEN and account, returns run/dataset IDs for paging, and notes that unknown league paths are answered with suggestions and never charged. The proxy/IP-rotation behavior is also surfaced in the schema, reinforcing cost/rate-limit awareness beyond the annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well front-loaded: purpose, then When to use, Returns, and Behavior sections make it skimmable. It is somewhat repetitive, restating the five brand names in both the title line and the body, but no sentence is filler.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
There is no output schema, and the description compensates by describing the return payload (one row per game, all book prices, best price per outcome) and the run/dataset IDs for paging. For a 7-param, zero-required, nested-object tool, an agent has everything needed to call it and interpret results.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 100%, so the baseline is 3; the description goes further by explaining that the operator enum maps to distinct brands/jurisdictions whose prices can differ, and that 'all' markets is priced higher and can return 300–500 markets per game. That adds decision-relevant meaning (cost and output shape) beyond the field descriptions, though it repeats the brand list already implied by the enum.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a concrete verb+resource (fetch live odds for games) plus scope: 24 Kambi-powered books, one row per game with best price per outcome. It explicitly differentiates from what it is not (DraftKings/FanDuel, historical odds), so an agent can separate it from siblings like sports-odds-scraper without opening a schema.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Has an explicit 'When to use' block naming the condition (current pre-match/live prices from Kambi books, book comparison, best-price search) and an explicit exclusion ('Not for DraftKings/FanDuel or historical odds'). It never names a sibling tool directly, but the inclusion/exclusion conditions are unambiguous.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
scrapemint--sports-odds-scraperSports Odds Scraper: DraftKings, Pinnacle & BovadaARead-onlyInspect
Sports Odds Scraper: DraftKings, Pinnacle & Bovada. Sports betting odds from DraftKings, Pinnacle and Bovada on one line per game, with the best price per outcome and arbitrage. Moneyline, spread and totals for NFL, NBA, WNBA, MLB, NHL, UFC, college and soccer. American or decimal. Keyless, no login, no browser.
When to use: Use when you need DraftKings, Pinnacle or Bovada moneyline, spread and total lines for US leagues, UFC or soccer, side by side with the best price per outcome.
Returns: the run's dataset rows as structured JSON (one row per result), plus the run and dataset IDs for paging the full dataset.
Behavior: starts one run of the Apify Actor "scrapemint/sports-odds-scraper" through Apify's hosted MCP gateway (mcp.apify.com) with your own APIFY_TOKEN; the run uses your Apify account. Read-only: it only reads public web data and changes nothing on the source site. Docs: https://apify.com/scrapemint/sports-odds-scraper
| Name | Required | Description | Default |
|---|---|---|---|
| books | No | No longer used, kept so older saved inputs keep working. Every run reads both available feeds: one bookmaker via ESPN's public scoreboard, typically DraftKings, plus Bovada's own prices. Setting this has no effect on what is returned. | |
| dedupe | No | Skip event IDs already pushed in previous runs (keyed by sport + home + away + commenceTime). Turn off to refresh stale rows. | |
| sports | No | Sports/leagues to sweep: nfl, ncaaf, nba, wnba, ncaab, mlb, nhl, ufc, soccer_epl, soccer_laliga, soccer_bundesliga, soccer_seriea, soccer_ligue1, soccer_mls, soccer_uefa_cl, soccer_uefa_el (or short forms like epl, mls, ucl). Any ESPN sport/league path like soccer/bra.1 also works. | |
| markets | No | Which betting markets to pull per event. | |
| eventUrls | No | No longer supported (the sportsbook pages these pointed at block automated access). Use sports[] instead; URL entries return a free explanatory row. | |
| minArbPct | No | Drop arbitrage opportunities below this edge. 0.5 means at least 0.5% guaranteed return. | |
| oddsFormat | No | How to express prices in the row. Options: american = American (-110 / +200); decimal = Decimal (1.91 / 3.00); fractional = Fractional (10/11 / 2/1); implied_probability = Implied probability (0.524 / 0.333). | american |
| concurrency | No | No longer used (one request per sport now). Kept for compatibility. | |
| lookAheadHours | No | Only return events starting within this many hours from now. 0 means no time limit. | |
| minBestEdgePct | No | Filter best price flags to only those that beat the average price across books by this percent. | |
| totalMaxEvents | No | Hard cap on event rows pushed per run. 0 means unlimited. | |
| computeArbitrage | No | Flag two way and three way markets where the best prices across books guarantee a profit. Adds an arbitrage object per market when found. | |
| computeBestPrice | No | Attach a bestPrice field per outcome with the highest odds and which book offers it, compared across the books that priced that outcome. Events carried by only one book are left alone. | |
| maxEventsPerSport | No | Per league cap. Useful when scraping multiple leagues in one run. | |
| proxyConfiguration | No | Not used: the odds source works from datacenter IPs without any proxy. Kept for compatibility with older saved inputs. | |
| includeStartedEvents | No | Include events already in progress. Off keeps the feed to upcoming events only. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnlyHint/openWorldHint/destructiveHint, but the description adds real context beyond them: it runs an Apify Actor through the hosted MCP gateway, consumes the caller's own APIFY_TOKEN and account, and returns dataset rows plus run/dataset IDs for paging. It also documents dedupe-driven idempotency behavior, consistent with idempotentHint=false. It stops short of mentioning cost/credit consumption or runtime, which is the remaining material gap for a run-launching tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The definition is well front-loaded: one-line summary, then explicit When to use / Returns / Behavior / Docs blocks. Sentences are dense but each carries information. The only mild redundancy is restating the title's book list at the start of the summary.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 16-parameter, no-output-schema tool, the description covers the essentials an agent needs before calling: auth token, account ownership, read-only nature, and the shape of the return plus paging IDs. Minor tension remains between "Keyless, no login" and the stated APIFY_TOKEN requirement, and there is no guidance on cost or the deprecated parameters.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the schema already documents all 16 parameters in detail, including the four deprecated no-op ones. The description adds only marginal mapping ("Moneyline, spread and totals", "American or decimal") and mentions just two of the four supported odds formats. It never warns that books, eventUrls, concurrency and proxyConfiguration are inert, leaving that entirely to the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states a specific resource and scope: sports betting odds from DraftKings, Pinnacle and Bovada, one row per game, with moneyline/spread/totals and best-price/arbitrage. An agent can tell what it gets. However, with seven sports-odds siblings (e.g. publicrecords--sports-odds-api, congism--polymarket-kalshi-arb-finder) the description never explains how this differs from them.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is an explicit "When to use" clause naming the books, markets and league types that select this tool, which is more than most definitions offer. It gives no when-not-to-use conditions and does not route to any alternative tool, so the agent must infer exclusions itself.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
sports-odds-lab--football-odds-resultsSoccer & Football Betting Odds: Historical & Closing LinesARead-onlyInspect
Soccer & Football Betting Odds: Historical & Closing Lines. Soccer odds, football betting odds and football data API: Premier League, LaLiga, Serie A, Bundesliga, Champions League + 1,000 leagues. Up to 120 bookmakers: 1X2, over/under, BTTS, Asian handicap, opening & closing. Results, xG, shots, corners, scorers. History back to 2005.
When to use: Use for soccer odds history, opening and closing lines, results and match stats (xG, shots, corners) going back to 2005, e.g. backtesting or closing-line value.
Returns: the run's dataset rows as structured JSON (one row per result), plus the run and dataset IDs for paging the full dataset.
Behavior: starts one run of the Apify Actor "sports-odds-lab/football-odds-results" through Apify's hosted MCP gateway (mcp.apify.com) with your own APIFY_TOKEN; the run uses your Apify account. Read-only: it only reads public web data and changes nothing on the source site. Docs: https://apify.com/sports-odds-lab/football-odds-results
| Name | Required | Description | Default |
|---|---|---|---|
| mode | No | Recent matches: every competition from up to 7 days back to 7 days ahead (upcoming matches with current odds). Full seasons: complete seasons of the leagues you list below, history back to 2005 — add the leagues in the 'Full seasons' section. Options: recent = Recent matches (7 days back to 7 days ahead); seasons = Full seasons (history back to 2005). | recent |
| leagues | No | 'Country: League' as shown on Flashscore — e.g. 'England: Premier League', 'Spain: LaLiga', 'Germany: Bundesliga', 'Brazil: Serie A', 'Europe: Champions League' — or the league's Flashscore URL. Every stage of a season is included (play-offs, championship and relegation groups). Example: ["England: Premier League"] | |
| markets | No | Full-time markets to collect. 1X2 is always included — it shows which bookmakers priced the match. | |
| seasons | No | Optional. Seasons as the league names them: 2024-2025 for autumn–spring leagues, 2024 for calendar-year leagues (MLS, Brazil, Scandinavia). Leave empty to use 'Last seasons'. Example: ["2024-2025"] | |
| daysBack | No | How many past days to include (0 = today only). Up to 7. Values above 7 are clamped to 7. | |
| statuses | No | Finished includes matches decided after extra time or penalties and awarded results. In 'Full seasons' mode only finished (and postponed/cancelled) matches exist. | |
| countries | No | Optional. Country or region names as shown on Flashscore, e.g. England, Spain, Brazil, Europe (UEFA club and national-team competitions), World (friendlies, FIFA). Leave empty for every country. | |
| daysAhead | No | How many upcoming days to include. Up to 7. Upcoming matches carry the current prices instead of closing lines. Values above 7 are clamped to 7. | |
| bookmakers | No | Optional. Names or parts of names, e.g. bet365, Betano, SNAI, Winamax. Leave empty for every bookmaker in scope (about 30 listings, or up to about 120 with 'All bookmakers'). | |
| maxMatches | No | Stop after saving this many matches (0 = no limit). A busy weekend day has 1,500+ matches; a full season of a top league 300–400. | |
| concurrency | No | Advanced. Requests in parallel (1–192). The default 128 is about six times faster than 16, with the same odds coverage. | |
| includeOdds | No | Opening and latest (closing) odds per bookmaker plus the no-vig consensus. | |
| incremental | No | For runs every few minutes: skip finished, live and cancelled matches whose score and status have not changed since an earlier run with the same settings, and upcoming matches whose prices, lines and kick-off have not moved — faster, and you pay only for new data. The memory lives in a key-value store 'football-odds-incremental' in your account. | |
| lastSeasons | No | Used when Seasons is empty: the current season (matches played so far) plus this many minus one previous seasons. 5 = the current season and the four before it; 22 = the whole history since 2005/06 in one run. | |
| competitions | No | Optional. 'Country: Competition' as shown on Flashscore, e.g. 'England: Premier League', 'Spain: LaLiga', 'Europe: Champions League'. Stages are included automatically ('Argentina: Liga Profesional' also matches its Apertura and Clausura). A name without a country (e.g. 'Premier League') matches that name in every country. Example: ["England: Premier League","Spain: LaLiga","Italy: Serie A","Germany: Bundesliga","France: Ligue 1","Europe: Champions League"] | |
| includeStats | No | xG, xGOT, xA, possession, shots, big chances, corners, passes, fouls, cards and more for finished and live matches (full detail for major competitions). | |
| includeWomen | No | Women's leagues, cups and national-team matches. | |
| includeYouth | No | U17–U23, reserve, B-team and academy competitions. | |
| onlyWithOdds | No | Do not save (and do not pay for) matches that no bookmaker priced. About 1 in 5 matches, mostly amateur and youth football. | |
| allBookmakers | No | Read the odds menus of ~55 countries instead of 10: up to about 120 bookmaker listings for a top-league match (default about 30) — Italian (SNAI, Sisal, Eurobet), French (Winamax, PMU, Unibet), Romanian, Czech, Greek, Latin American, African and Asian books. History gains too (Premier League 2024/25: 69 instead of 20 per match). Same price per match; runs take about 2–3× longer. | |
| includeEvents | No | Every goal with minute, scorer, assist and score after the goal; penalties (scored and missed), own goals, yellow and red cards. | |
| overUnderLines | No | Goal lines to return, e.g. 1.5, 2.5, 3.5. Enter 'all' for every line each bookmaker offers (0.5 to 6.5, quarter lines included). | |
| incrementalName | No | Optional name for the incremental memory, to keep several schedules apart or start fresh (a new name = a new memory). Empty = one memory per combination of settings. | |
| asianHandicapLines | No | The main line is the one whose consensus is closest to 50/50 (reported as ahLine; the opening main line as ahLineOpening). Options: main = Main line only; all = All lines. | main |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare read-only/open-world, but the description adds what they cannot: the run executes the Apify Actor through mcp.apify.com using the caller's own APIFY_TOKEN and Apify account, the output is dataset rows plus run/dataset IDs for paging, and cost-sensitive options (onlyWithOdds skipping paid matches, the incremental key-value memory store) are explained. That is substantial context beyond structured fields.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Three labeled blocks (statement, When to use, Returns, Behavior) with the key facts front-loaded. The league/market enumeration in the first sentence is mildly promotional fluff, but the rest earns its space.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For a 24-parameter tool with no output schema, the description covers what is returned (structured JSON, one row per result, plus run/dataset IDs), auth requirements, and cost/memory behavior. Only the sibling-routing decision is unaddressed, which is a small gap at this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so the 24 parameters are already fully documented with defaults, enums, and clamping behavior; the description adds no parameter-level meaning beyond what the schema says. Baseline 3 applies because the schema carries the burden.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
States a specific verb-and-resource combination ('soccer odds, football betting odds', markets, bookmakers, history back to 2005) and the Actor it invokes. It is specific enough to separate from generic sports-odds siblings, but it never names an alternative tool the way a top-tier definition would.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The 'When to use' line gives concrete scenarios — odds history, opening/closing lines, results and match stats for backtesting or closing-line value. It stops short of exclusions (e.g. when to use the ESPN or Understat siblings instead), leaving sibling choice to the agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
zen-studio--prizepicks-player-propsPrizePicks Player Props Scraper - Real-Time LinesARead-onlyInspect
PrizePicks Player Props Scraper - Real-Time Lines. Extract real-time player prop lines from PrizePicks across 29 leagues. Get over/under lines, odds tiers, player stats, team matchups, and game schedules. NBA, MLB, NHL, Soccer, Tennis, and esports. Filter by league or player name. 51 fields per prop. JSON, CSV, Excel export.
When to use: Use when the question is about player prop lines (over/under) on PrizePicks for a league, team or player.
Returns: the run's dataset rows as structured JSON (one row per result), plus the run and dataset IDs for paging the full dataset.
Behavior: starts one run of the Apify Actor "zen-studio/prizepicks-player-props" through Apify's hosted MCP gateway (mcp.apify.com) with your own APIFY_TOKEN; the run uses your Apify account. Read-only: it only reads public web data and changes nothing on the source site. Docs: https://apify.com/zen-studio/prizepicks-player-props
| Name | Required | Description | Default |
|---|---|---|---|
| teams | No | Comma-separated team names or abbreviations, case-insensitive. Matches player's team or either side of the matchup. Example: Lakers, LAL, Celtics, BOS . Leave empty to get all teams. | |
| leagues | No | Select one or more leagues to fetch player props for. Choose All to get every available projection across all leagues. Don't see a league (e.g. a seasonal event)? Add it under Other leagues below, or enable List available leagues to see everything live right now. Example: ["MLB","World Cup"] | |
| feedback | No | For AI agents. Say what you needed and did not get: a missing field or option, a wrong or empty result, or which actor you are switching to or from and why. Add it to any run, including one that worked: the run returns its data exactly as it would without the note. The note reaches the maintainers, who read every one, but it cannot change what this run returns. | |
| oddsTiers | No | Filter by line difficulty. Standard is the normal line, Demon is harder with higher payout, Goblin is easier with lower payout. Select one or more. Leave empty to get all tiers. | |
| statTypes | No | Comma-separated stat types, case-insensitive. Accepts full names or abbreviations. Example: Points, PRA, Rebounds, Goals, SOT . Stat types are league-specific — see README for the full list grouped by sport. Leave empty to get all stats. | |
| listLeagues | No | Turn this on to output the leagues currently offering props and how many, then stop. Use it to see exactly what you can request. Ignores all other inputs. | |
| playerNames | No | Comma-separated player names, case-insensitive. Matches partial names and handles accents (Jokic matches Jokić). Example: Jokic, Haaland, Ohtani . Leave empty to get all players. | |
| extraLeagues | No | Type any league name exactly as it appears on PrizePicks (e.g. World Cup ), comma-separated. Use this for seasonal events not in the list above. Combined with your selection above. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Annotations already declare readOnly, openWorld, non-destructive, and non-idempotent, so the bar is lower, and the description still adds real value: it discloses the Apify Actor behind it, that execution runs through mcp.apify.com with the caller's own APIFY_TOKEN and Apify account (a cost/quota consideration), and that each call starts a fresh run. It also explains that only public web data is read. Minor gap: no mention of runtime or run-failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The prose is sectioned into When to use / Returns / Behavior / Docs, which front-loads the decision-relevant content. The opening sentence redundantly restates the tool title verbatim before adding new information, which is the only real waste; the rest is dense with specifics.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
For an eight-parameter, all-optional scraper with no output schema, the description covers what an agent needs: what data comes back (dataset rows as JSON plus run and dataset IDs for paging the full dataset), how to discover valid league values, how to supply out-of-list leagues, auth requirements, and safety profile. Nothing material is missing.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 100%, so all eight parameters are already self-documenting, and the enumeration in the description ('filter by league or player name') maps directly onto leagues/playerNames. The description adds no syntax or format detail beyond the schema, so it lands at the baseline plus a small credit for reinforcing the primary filtering axes.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description gives a specific verb and resource ('Extract real-time player prop lines from PrizePicks') and enumerates scope: 29 leagues, over/under lines, odds tiers, stat types, 51 fields per prop. It implicitly separates itself from the sibling odds/analytics tools by naming a distinct source (PrizePicks) and a distinct payload (player props), though it never names an alternative directly.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
There is an explicit 'When to use' clause tied to a clear condition: questions about player prop over/under lines on PrizePicks for a league, team, or player. The schema also steers the discovery path (listLeagues to enumerate live leagues, extraLeagues for seasonal events). It stops short of naming when NOT to use it or which sibling to pick instead.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
8 tool updates
v0.2.0- First observed
congism--polymarket-kalshi-arb-finder - First observed
constructive_calm--understat-football-analytics - First observed
hgservices--apify-actor-espn - First observed
jungle_synthesizer--equibase-us-horse-racing-scraper - First observed
publicrecords--sports-odds-api - First observed
scrapemint--sports-odds-scraper - First observed
sports-odds-lab--football-odds-results - First observed
zen-studio--prizepicks-player-props
TDQS
Scored across 8 tools
Each tool is scoped to a distinct data source or market segment (Kambi books vs DraftKings/Pinnacle/Bovada vs PrizePicks props vs soccer odds history vs Understat xG vs ESPN scores vs horse racing vs prediction-market arb), and descriptions explicitly state 'when to use'. The main residual ambiguity is between the two soccer-oriented tools (football-odds-results and understat-football-analytics), and between the two odds-comparison scrapers for an agent that doesn't know which books it needs.
Every tool follows the same Apify actor convention `<vendor>--<actor-slug>` in kebab-case, so the pattern is predictable and machine-parseable. It is not a verb_noun convention and vendor names mix hyphen and underscore styles (zen-studio vs constructive_calm), but the tool-name portion is uniform.
Eight tools is a well-scoped set for a multi-source sports betting stats aggregator; each tool contributes a genuinely different data source rather than redundant variants. Nothing feels padded or thin.
Coverage is broad across sources (US books, sharp books, props, soccer history/xG, scores, horse racing, prediction markets), but it is a collection of independent scrapers with no unifying query layer. Notably, every description advertises run/dataset IDs 'for paging the full dataset' yet no tool exists to page or fetch a full dataset, and there are gaps for non-soccer historical odds, lineups/injuries, and live in-play data.
Maintenance
Related MCP Connectors
Live odds, cross-book +EV and graded player-prop results across 37 books. Hosted endpoint included.
Live sports data: scores, play-by-play, box scores, odds and props. No key needed to start.
NFL/NBA/MLB/NHL/PGA + DFS and prediction-market data. Browse free; query with a free API key.
Sportsbook-derived no-vig fair value with confidence, provenance, and history over REST/MCP.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceCLI and MCP server for EdgeFinder sports analysis. Get AI-powered NFL, NBA, and MLB betting recommendations, player stats, odds, schedules, and Polymarket portfolio tracking from your terminal or AI agent.7 npm2MIT
- AlicenseNot gradedqualityBmaintenanceEnables fetching sportsbook odds, live scores, and event information across 70+ books and 30+ leagues, with tools to list sports, get scores, and discover events.343 npm1MIT
- AlicenseAqualityAmaintenanceLive sports betting player props MCP server covering NBA, MLB, NFL, NHL, NCAA, and soccer. Unified from real sportsbooks into one REST API and a real MCP server (Streamable HTTP). Free tier, no card required.5MIT
- AlicenseNot gradedqualityCmaintenanceProps-first sports odds API with a hosted MCP server. Live odds and player props (moneyline, spreads, totals) across US sportsbooks, normalized to JSON. Tools: get_odds, get_props, get_events, get_books. API-key auth, free tier.MIT No Attribution