back
loading skill details...
Read MaxPreps.com high school sports data — find a school, then get team schedules, scores, records, rosters, stat leaders, rankings, and athlete careers for any US high school.
--- name: maxpreps description: "Read MaxPreps.com high school sports data — find a school, then get team schedules, scores, records, rosters, stat leaders, rankings, and athlete careers for any US high school." --- # MaxPreps National high-school sports database (CBS Sports). **No auth, no API key, no browser bridge** — plain `curl` from anywhere, no signed-in tab. Pages are Next.js SSR: every public page has a companion JSON route at `/_next/data/<buildId>/<path>.json`. `scripts/mpx.mjs` resolves the `buildId`, fetches, and decodes. ```bash # scripts/mpx.mjs sits next to this SKILL.md — point M at it. # Standalone install: M=~/.claude/skills/maxpreps/scripts/mpx.mjs # Shipped with maxpreps-mcp: M=<plugin-root>/skills/maxpreps/scripts/mpx.mjs M=~/.claude/skills/maxpreps/scripts/mpx.mjs node "$M" search "myers park" node "$M" schedule nc/charlotte/myers-park-mustangs/football/25-26/schedule ``` `mpx.mjs <kind> [path]` — `path` is the site path without leading/trailing slashes. With no path it decodes a payload on stdin. Kinds: - `search "<query>"` — schools + athletes (**start here**) - `teams <school-or-team-path>` — every team path the school publishes - `schedule` — games with scores, result, home/away (decodes the positional array) - `roster` — players with jersey, position, height, class (decodes the positional array) - `stats` — team stat leaders · `team` — season info, record, standings, rankings - `rankings` — ranked leaderboard for a sport (see path note below) - `teamrankings` / `standings` — one team's ranks; its conference table - `statcats` / `statleaders` — stat leaderboard index; one board's ranked athletes - `school` — school profile + nearby schools · `athlete` — one athlete's career - `raw` — undecoded `pageProps`, for anything without a dedicated kind - `buildid` — print the cached build id Flags: `--all` keep `isDeleted` rows · `--raw` emit undecoded `pageProps` · `--fresh` (buildid) bypass cache. ## Resolve before you fetch Don't guess paths — two lookups, both cheap: ```bash # 1. school -> canonicalUrl node "$M" search "mater dei" | jq -r '.schools[] | "\(.name) (\(.city), \(.state)) \(.canonicalUrl)"' # 2. school path -> real team paths node "$M" teams ca/santa-ana/mater-dei-monarchs | jq -r '.[] | "\(.path) [\(.gender) \(.sport) \(.level)]"' ``` Team path grammar is `<sport>[/girls][/jv|/freshman][/<yy-yy>]/<tab>`, but the segments are **not predictable** — the default gender varies by sport (`golf/girls` + `golf/spring`, `field-hockey` is Girls with no gender segment). Always take paths from `teams`. Tabs: `schedule`, `roster`, `stats`, `rankings`, `standings`. Omit the tab for the team home page. Leaderboards live on their own path: `[<st>/]<sport>[/<season>]/rankings/<page>` — the trailing page number is **required** (omitting it 404s) and each page holds 25 teams. ## Seasons Current season = no year segment. Prior seasons insert `<yy-yy>` **before** the tab: `.../football/25-26/schedule`. Roughly 20 years of history; `mpx teams <team-path>` lists every season with its `year`, or read `.seasons` from `mpx team <team-path>`. ## Gotchas - **`buildId` rotates on every deploy.** `mpx` caches it for 6h and silently re-resolves on a 404, so this is handled — but a hand-rolled `curl` against a stale id 404s. Use the script, or `node "$M" buildid` first. - **An out-of-season team looks broken.** Before opening day the current season has an empty roster and no results. That is correct data, not a failure — check the prior season (`25-26`) before reporting nothing. - **`isDeleted` rows are real and numerous.** The 25-26 Myers Park football roster carries 87 entries, 63 of which the site renders; the rest are soft-deleted duplicates. `mpx` filters them by default (matching the site) — `--all` keeps them. Same for contests. - **`resultString` is winner-first, not team-first.** A loss reads `"L 20-13"` even though the team scored 13. For team-vs-opponent use the decoded `teamScore` / `opponentScore` fields, which `mpx` orients correctly. - **`homeAwayType`: `0` = home, `1` = away** (decoded to `homeAway`). - **`classYear` is a number**: 9–12, decoded to `classYearLabel` (`Fr.`/`So.`/`Jr.`/`Sr.`). - **Statewide scoreboards are not in the JSON.** `/<st>/<sport>/scores/` returns only page chrome — the game list is hydrated by a route that never fires server-side. Get scores per-team from `schedule` instead; don't claim a state had no games. - Search is strict — `"myers park high"` returns zero, `"myers park"` returns the school. Drop qualifiers and retry before concluding a school is absent. Read-only and low-volume by design; there is no write path. See `references/recipes.md` for field shapes, the positional key maps, and ready-to-run jq. For the same data as typed MCP tools — usable from claude.ai or any client without this CLI — see [maxpreps-mcp](https://github.com/chrischall/maxpreps-mcp), which ships this skill.
don't have the plugin yet? install it then click "run inline in claude" again.