MLB League State Reader
Table of Contents
- [Example](#example)
- [Workflow](#workflow)
- [Degraded Mode](#degraded-mode)
- [Guardrails](#guardrails)
- [Quick Reference](#quick-reference)
Example
Scenario: Morning brief run on 2026-04-17. Coach needs current roster, matchup, FAAB, and standings before launching lineup-optimizer.
Inputs read first:
yahoo-mlb/context/league-config.md (league ID 23756, team 5, 12 teams, 5x5 cats)
yahoo-mlb/context/team-profile.md (prior known roster skeleton)
Chrome navigation sequence (authenticated):
https://baseball.fantasysports.yahoo.com/b1/23756/5 — roster with today's opponents per player
https://baseball.fantasysports.yahoo.com/b1/23756?lhst=stand — standings + category ranks
https://baseball.fantasysports.yahoo.com/b1/23756/matchup — this week's head-to-head vs Los Doyers
https://baseball.fantasysports.yahoo.com/b1/23756/transactions — FAAB spent to date → remaining
https://baseball.fantasysports.yahoo.com/b1/23756/players?status=A — top free agents (page 1)
Extracted bundle:
| Field |
Value |
| Record |
8-6-1 |
| Rank |
5 of 12 |
| FAAB spent |
$14 |
| FAAB remaining |
$86 |
| This week opp |
Los Doyers |
| Live matchup score |
4-3-3 (us leading R, HR, K; losing OBP, ERA, WHIP) |
| Roster returned |
26 of 26 slots populated |
| Free agents top-20 |
captured for waiver-analyst |
Outputs written:
context/team-profile.md — roster snapshot updated in place (slot, player, MLB team, today's opp, status)
signals/2026-04-17-league-state.md — signal file with YAML frontmatter, source_urls, confidence
Every downstream agent (lineup-optimizer, waiver-analyst, category-strategist) now reads this signal file and team-profile.md rather than re-scraping Yahoo.
Workflow
Copy this checklist and track progress:
League State Reader Progress:
- [ ] Step 1: Read context files (league-config.md + team-profile.md)
- [ ] Step 2: Pull Yahoo pages via Claude-in-Chrome (5 URLs)
- [ ] Step 3: Parse roster, standings, matchup, FAAB, free agents
- [ ] Step 4: Update team-profile.md in place
- [ ] Step 5: Emit signal file with frontmatter + source_urls
Step 1: Read context files
Load the authoritative contract and the last known state before touching Yahoo. This both verifies the league ID/URL and provides the skeleton to diff against.
Step 2: Pull Yahoo pages via Claude-in-Chrome
The user is already authenticated in the browser. Navigate in order; parse page text; if any step fails, jump to [Degraded Mode](#degraded-mode) for that specific URL only (do not abort the whole run). See [resources/methodology.md](resources/methodology.md#yahoo-navigation-sequence) for the exact tool-call sequence and page-parsing patterns.
Step 3: Parse and normalize
Extract structured data from each page. See [resources/methodology.md](resources/methodology.md#parsing-patterns) for row-level parsing logic, and [resources/methodology.md](resources/methodology.md#faab-remaining-computation) for how to reconstruct FAAB remaining from the transactions log.
Step 4: Update team-profile.md in place
See [resources/template.md](resources/template.md#team-profile-output-format) for the exact output shape. Overwrite the existing file (not append); this file is meant to always reflect "as of the latest run."
Step 5: Emit signal file
Write yahoo-mlb/signals/YYYY-MM-DD-league-state.md with YAML frontmatter per the signal framework. Every URL navigated must appear in source_urls. Degraded fetches drop confidence to 0.5; full-failure fields drop to 0.3 and are flagged. See [resources/template.md](resources/template.md#signal-file-output-format).
Degraded Mode
Chrome can fail for several reasons: tab not open, session expired, Yahoo rate-limiting, 500 error, unreadable DOM. Never abort the whole run. Fail gracefully per-URL.
Per-URL fallback decision tree:
| Failure |
Fallback |
| Navigation error / timeout |
Retry once. If still failing, ask user: "Paste the contents of {URL} and I'll parse from that." |
| Session expired (login page returned) |
Ask user: "Please log into Yahoo in your Chrome tab, then say 'retry'." Do not attempt to re-authenticate. |
| Page loads but parse fails (unknown layout) |
Dump the first ~4000 chars of getpagetext into the signal file under raw_capture: and drop confidence to 0.4 for that field. |
| Free-agents page gated / empty |
Mark free_agents: [] and flag in the signal. The waiver-analyst can still run on roster + standings. |
| Transactions page gated |
Ask user: "What's your FAAB remaining right now? Visible at the top of the transactions page." Accept user value; mark faab_confidence: 0.6. |
User-paste template (reuse for any Yahoo page):
"I couldn't reach {URL}. Please copy the visible table on that page (select all, paste into chat) and I'll extract the fields I need from your paste."
Parse the pasted text with the same regex/row patterns as the live page. See [resources/methodology.md](resources/methodology.md#paste-parsing).
Guardrails
- Never assume the roster is still what it was yesterday. Waivers clear daily and trades can fire any time. Always re-read the Yahoo team page at the start of every run, even if
team-profile.md looks fresh.
- FAAB remaining is derived, not displayed. Yahoo's UI sometimes shows "FAAB Balance" and sometimes doesn't. The authoritative computation is:
$100 minus sum of all winning bids on the transactions page this season. Do not trust a single visible number over the ledger.
- Cite every URL. The signal file's
source_urls: list must contain every Yahoo page actually visited. If a page was skipped because of degradation, note it in the signal body, not silently.
- Do not re-scrape downstream. Once this skill has emitted today's league-state signal, lineup-optimizer / waiver-analyst / category-strategist MUST read that signal rather than re-visit Yahoo. Re-scraping wastes tokens and risks drift.
- Overwrite team-profile.md; append nowhere. This file is "current state." Preserving yesterday's roster pollutes it. The append-only log lives in
tracker/decisions-log.md, not here.
- Status values are normalized enums. Map Yahoo's labels (
P, DTD, IL-10, IL-60, NA, SUSP) to the normalized enum: active | BN | IL | DTD | NA | SUSP. Downstream agents branch on the enum, not Yahoo's strings.
- Today's opponent may be blank. Off-days, postponements, and doubleheaders all produce unusual
opp_today values. Record exactly what Yahoo shows (@TEX, TEX, Off, PPD, DH1/DH2) — do not normalize away information the downstream lineup-optimizer needs.
- Don't emit a signal with zero source URLs. If every page failed, write an empty-body signal with
confidence: 0.0 and a prominent note to the coach: "Could not reach Yahoo — paste or retry required before any downstream agent runs."
Quick Reference
The five Yahoo URLs (from context/frameworks/data-sources.md):
Team: https://baseball.fantasysports.yahoo.com/b1/23756/5
Standings: https://baseball.fantasysports.yahoo.com/b1/23756?lhst=stand
Matchup: https://baseball.fantasysports.yahoo.com/b1/23756/matchup
Transactions: https://baseball.fantasysports.yahoo.com/b1/23756/transactions
Free agents: https://baseball.fantasysports.yahoo.com/b1/23756/players?status=A
Chrome tool order (load via ToolSearch first, then call):
1. mcp__claude-in-chrome__tabs_context_mcp (confirm active tab, auth state)
2. mcp__claude-in-chrome__navigate (go to URL)
3. mcp__claude-in-chrome__get_page_text (extract DOM text)
4. mcp__claude-in-chrome__read_page (structured read if text fails)
Roster slot order (for team-profile YAML; matches league-config.md):
C, 1B, 2B, 3B, SS, OF, OF, OF, UTIL, UTIL, SP, SP, SP, RP, RP, P, P, P, P, P, BN, BN, BN, IL, IL, IL
Status enum mapping:
| Yahoo |
Normalized |
| (blank) / P |
active |
| BN |
BN |
| DTD |
DTD |
| IL-10 / IL-60 / IL |
IL |
| NA |
NA |
| SUSP |
SUSP |
Signal frontmatter (minimum fields):
---
type: league-state
date: 2026-04-17
emitted_by: mlb-league-state-reader
variant_synthesis: false
confidence: 0.9
source_urls:
- https://baseball.fantasysports.yahoo.com/b1/23756/5
- https://baseball.fantasysports.yahoo.com/b1/23756?lhst=stand
- https://baseball.fantasysports.yahoo.com/b1/23756/matchup
- https://baseball.fantasysports.yahoo.com/b1/23756/transactions
- https://baseball.fantasysports.yahoo.com/b1/23756/players?status=A
---
Key resources:
- [resources/template.md](resources/template.md): team-profile.md output format, signal file output format, roster YAML schema, free-agents table schema
- [resources/methodology.md](resources/methodology.md): Yahoo navigation sequence, parsing patterns per page, FAAB reconstruction, paste parsing, degraded-mode prompts
- [resources/evaluators/rubricmlbleaguestatereader.json](resources/evaluators/rubricmlbleaguestatereader.json): 8 scoring criteria (roster completeness, FAAB accuracy, URL citation, fallback handling, etc.)
Inputs required:
- Authenticated Yahoo Fantasy session in Chrome (user's responsibility)
context/league-config.md (league ID, team ID, roster shape)
context/team-profile.md (prior state, may be stub)
Outputs produced:
- Updated
context/team-profile.md (overwrite; reflects today's state)
signals/YYYY-MM-DD-league-state.md (with frontmatter + source_urls)
- Degraded-mode prompts to user if any page fails