Side project · Spring 2026 season · May 2026

An AI scouting department for a Little League team

Scout turns a season of league-wide GameChanger data into coaching intelligence — built in about two weeks of nights with Claude Chat and Claude Code, shipped mid-season, and used by our coaching staff to prep for games through a playoff run.

80+
games captured
4,626
plate appearances
10
teams scouted
$0.29 $0.05
per question
~20
PRs from my phone

I'm an assistant coach on my son's AAA Little League team, the Alameda Aces. Every team in our league scores its games in GameChanger, which means every game produces a beautiful pile of data — box scores, play-by-play, pitch counts — that mostly goes unused. Coaches check their own team's batting averages, and that's about it.

Meanwhile, the questions we actually argue about in the dugout are scouting questions: What's this pitcher's walk rate late in games? Does that team steal on the catcher? Who should bat cleanup on Tuesday? The data to answer them exists. Nobody has time to dig it out at 5pm on a school night.

So I built Scout: a mobile-first app with a stats explorer, pushed scouting insights about your next opponent, a drag-and-drop lineup builder, and an AI agent (also named Scout) you can ask anything — backed by real play-by-play from every game in the league.

Scout home screen with record, next game, and color-coded scouting insights
Home — pushed insights about the next opponent, color-coded: attack, caution, avoid
Scout chat with suggested questions about the next opponent
Scout — the agent, with suggested questions seeded from the upcoming matchup

Product thinking: built for the night before the game

A few decisions came before any code:

The data problem: there is no API

Here's what almost killed the project on day one: as a coach I can export my own team's stats. The other nine teams' coaches don't share theirs, and GameChanger has no public API.

But box score and play-by-play pages are viewable. So the pipeline became: screenshot every box score in the league (160+ screenshots) → Claude Chat extracts each one into structured markdown, validated against team totals → Claude Code parses the markdown into JSON at build time — every plate appearance with inning, runners, result, and pitcher. Later I turned the capture step into a reusable Claude Code skill: after each new game, Claude drives a browser to the GameChanger page, extracts everything, cross-checks the totals, and files a clean record. New game to updated app in minutes.

The unglamorous truth is that data quality was the hardest ongoing work. Claude Chat caught transcription errors by diffing against my official export. A validation script caught a parser bug that had silently dropped eight Iron Birds games (a case-sensitive header, naturally). A coach who catches one wrong batting average stops trusting every number in the app — they were at the game. "Off by one or two" was never acceptable.

Screenshots are an API if you're stubborn enough.

The build: Claude Chat as PM, Claude Code as the engineering team

The division of labor across surfaces was one of my favorite parts of this project. Claude Chat was the product and analyst side: it held the league knowledge base, extracted the box scores, wrote the analytics methodology (ERA scaled to six innings, contact-quality definitions, lineup tiers), brainstormed the insight catalog, and finally wrote a complete build brief — design spec, data architecture, API design, roster notes — as a handoff document.

Claude Code took that brief and built the app: Next.js, TypeScript, Tailwind, static JSON processed at build time, no database, Vercel free tier. The first session went from an empty folder to a deployed app with a working stats page in one evening. Later iterations happened from wherever I was — including Claude Code sessions started on my phone that landed as pull requests. About 20 PRs shipped that way during the season: the Lineups tab, mobile layout fixes, playoff data updates.

The timeline still makes me laugh: the scaffold deployed on May 11. Coaches were using it to prep for a real game on May 13.

Design iterations: from wireframe to something you'd show people

The first working version was pure wireframe — black and white, default everything, the stats table cheerfully scrolling underneath the tab bar. One long feedback pass ("this should feel like Airbnb or Apple Health, not a wireframe") brought in the field-green brand, tab icons, merged cards, and the zebra-striped table.

Early wireframe version of the stats page in black and white
Day 1 — the wireframe era: functional stats, zero polish, table colliding with the nav
Final stats page with green brand, zebra rows, and team totals
Day 14 — pinned names, zebra rows, team totals row, sortable columns

Then came the mobile-web battles nobody warns you about. iOS Safari zoomed the whole page every time you tapped the chat input. The keyboard broke scroll positioning. The modal needed a real slide-up animation. And Scout's carefully formatted analysis arrived as raw asterisks and pipe characters, because markdown rendering wasn't wired up yet:

Scout returning a per-game stats table as raw unrendered markdown
Before — a beautiful per-game table, delivered as raw pipes and asterisks
Polished home screen with color-coded scouting insights and league ranks
After — the polished home screen: insights with league-rank context and tone colors

Details I'm fond of: every stat in an insight carries a league rank ("1st of 10") because a coach can't tell whether 12 extra-base hits is a lot; chat answers got promoted out of bubbles to full-width text because they're analysis, not texting; and the drag-and-drop Lineups tab exists because Scout kept recommending batting orders in prose, and the obvious next step was letting a coach grab a row and move a kid up the order.

Lineups tab with drag-and-drop batting order and live stats
Lineups — drag-and-drop order with live stats and a recommended arrangement

The agent: four architectures in ten days

The AI side of Scout went through four distinct versions, each forced by a real failure — I couldn't have designed the final one on a whiteboard, because every architecture was correct until a real coach question made it wrong.

v1Stuff everything in the promptcost/question $0.29

All the stats, methodology, and league rules went into the system prompt on the biggest model. It worked beautifully and cost 29 cents a question. Three questions in, I did the math on a coaching staff poking at it all season and nearly abandoned the idea.

v2Context engineeringcost/question ~$0.06

Reformatting stats as compact tuples shrank the prompt from ~118K tokens to ~31K. Dropping to a smaller model with low reasoning effort, and stretching the prompt-cache TTL from 5 minutes to an hour — coaches don't ask questions in tidy 5-minute windows, they poke at it over an evening — brought a question down to a few cents.

v3Toolscost/question $0.03–0.13

Then a coach question broke everything: "How has Wyatt been pitching over the last 8 games?" Season aggregates can't answer that, and adding per-game data to the prompt re-exploded the cost. So per-game stats and the play-by-play index moved behind tools the model calls on demand — the agent decides when it needs to dig into pitch-level data.

v4Precomputationleague-wide questions: 0 tool calls

League-wide questions were the last boss. "Make an All-Star team of the top 13 players in AAA" means comparing every player on ten teams — the agent chained tool calls until the serverless function timed out. The fix wasn't a bigger timeout: ranking questions have a shape. Precomputed team rollups and league leaderboards went into the cached prompt so ranking questions need zero tool calls, tools stayed for drill-downs, and answers were restructured conclusion-first so even a slow generation streams its verdict immediately.

Scout chat showing a timeout error on an All-Star team question
The last boss — the All-Star question that kept outrunning the server
Scout analyzing a pitcher as a three-inning closer with a bottom-line verdict
The payoff — Scout as a closer analyst: walk rate, unearned-run caveat, bottom line

The human layer

My favorite bug report wasn't technical. Scout analyzed one of our pitchers — a kid, and a fellow coach's son — and bluntly advised against pitching him. Statistically defensible; humanly unacceptable. That produced a system-prompt pass on tone: Scout now leads with what a kid is doing well, checks recent form before judging a season line (kids develop fast — the season average is often stale), and frames concerns as things to work on at practice. "Gentle but honest" turned out to be a real product requirement, not a nice-to-have.

Same energy: the insight engine once told our outfielders to "play deeper" against the team with the worst extra-base power in the league. Fellow coaches make excellent QA.

Did it work?

The coaching staff used Scout through the end of the regular season and the playoffs — not in the dugout, but the night before: opponent insights, the lineup builder, and pitching plans. One coach used it to set our batting order and figure out how to align our middle-relief pitching for a Sunday game. The texts started arriving:

I was playing with Scout to figure out how we should align our middle relief pitching for Sunday. Good stuff!
Scout is amazing. Let's take the Aces to the TOC, Majors, and beyond!
actual texts from the Aces coaching staff

The receipts: Scout's agent went live on the evening of May 12, with the Aces sitting at 8–6–2. The first game we prepped with it — May 13, at the Mighty Mussels — we won 22–4. Then came a 9–8 playoff thriller over the Flying Squirrels to reach the semifinal against the top-seeded Rail Riders — and that week Scout got its most serious upgrade: pre-loaded, pitch-level splits on just that one opponent, because that's exactly what a real scouting department does before the biggest game of the year. The run ended there, against the league's best. After Scout shipped, the Aces went 2–1; I won't claim causation, but I'm not not claiming it.

A second team asked to onboard, which is how you know a side project built for four users has legs. Next season I'm tempted to open it to the whole league for league-wide feedback — though youth-baseball coaches are famously secretive about what they're willing to share, so we'll see.

What this project is really about

Stack: Next.js (App Router, TypeScript) · Tailwind · Anthropic API (streaming, prompt caching, tool use) · static JSON data pipeline · Vercel
Built with: Claude Chat (spec, data extraction, methodology) · Claude Code (build, ~20 PRs, browser-automation skill) · one Little League season of data · one very patient coaching staff