Skill: jeremydouglaslaw-ui/mlb-daily-scores (version 1.0.13)

--- name: mlb-daily-scores description: Daily MLB baseball scores, box scores, starting pitchers, and injury reports for your favourite team. Covers spring training, regular season, and playoffs. Runs on a schedule or on demand. user-invocable: true metadata: { "openclaw": { "emoji": "⚾", "requires": { "bins": ["python3"] }, "os": ["darwin", "linux", "win32"], "hooks": { "postInstall": "cd {baseDir} && sed -i 's/\\r$//' *.py *.sh && chmod +x fetch_mlb.py setup.sh && python3 {baseDir}/setup.py", }, "entrypoint": "{baseDir}/.venv/bin/python3 {baseDir}/fetch_mlb.py --config", "homepage": "https://clawhub.ai/skills?focus=search&q=mlb-daily-scores", }, } --- # MLB Daily Scores Fetches yesterday's game recap and today's upcoming game preview for the user's configured favourite MLB team. Includes spring training, regular season, postseason (Wild Card, Division Series, Championship Series, World Series), and exhibition games. ## Data Source Uses the free **MLB Stats API** (statsapi.mlb.com). No API key required. ## Setup (one-time) ### 1. Install dependencies Run the setup script to install the Python packages: ```bash # macOS/Linux bash {baseDir}/setup.sh # Any platform (including Windows) python {baseDir}/setup.py ``` Or install manually: ```bash pip install --user MLB-StatsAPI requests ``` ### 2. Configure your team Add this to `~/.openclaw/openclaw.json` under `skills.entries`: ```json5 { skills: { entries: { "mlb-daily-scores": { enabled: true, config: { team: "Toronto Blue Jays", // Your favourite team (full name) timezone: "America/Toronto", // Your local timezone (IANA format) }, }, }, }, } ``` **Valid team names** — use the full official name: Arizona Diamondbacks, Atlanta Braves, Baltimore Orioles, Boston Red Sox, Chicago Cubs, Chicago White Sox, Cincinnati Reds, Cleveland Guardians, Colorado Rockies, Detroit Tigers, Houston Astros, Kansas City Royals, Los Angeles Angels, Los Angeles Dodgers, Miami Marlins, Milwaukee Brewers, Minnesota Twins, New York Mets, New York Yankees, Oakland Athletics, Philadelphia Phillies, Pittsburgh Pirates, San Diego Padres, San Francisco Giants, Seattle Mariners, St. Louis Cardinals, Tampa Bay Rays, Texas Rangers, Toronto Blue Jays, Washington Nationals. ### 3. Set up the daily cron job Ask me to set it up, or run manually: ```bash openclaw cron add \ --name "MLB Daily Scores" \ --cron "0 6 * * *" \ --tz "America/Toronto" \ --session isolated \ --message "Run the mlb-daily-scores skill for my configured team. Use the fetch_mlb.py script, format the results nicely, and include yesterday's recap, today's preview, and any injuries." \ --announce \ --channel discord \ --to "channel:YOUR_CHANNEL_ID" ``` Adjust the parameters: - `--cron "0 6 * * *"` — time to run (6:00 AM); change to your preferred time - `--tz` — your timezone - `--channel` — your preferred channel (discord, telegram, whatsapp, slack, etc.) - `--to` — channel-specific target (channel ID, phone number, chat ID, etc.) ## How to use ### Automatic (cron) Once the cron job is set up, the skill runs daily at your configured time and delivers the report to your channel. ### On demand (slash command) Send `/mlb-daily-scores` in any chat to get an immediate update. ### Manual invocation Ask me: _"What happened in the Blue Jays game yesterday?"_ or _"Give me today's MLB update"_ ## Instructions for the agent `{baseDir}` in these instructions refers to the directory containing this SKILL.md file. Determine this path from the location of this file (e.g., if this file is at `/home/openclaw/.openclaw/workspace/skills/mlb-daily-scores/skills/mlb-daily-scores/SKILL.md`, then `{baseDir}` is `/home/openclaw/.openclaw/workspace/skills/mlb-daily-scores/skills/mlb-daily-scores`). When this skill is invoked (via cron, slash command, or user request): 1. **Determine the base directory** — find the directory where this SKILL.md and `fetch_mlb.py` are located. Call this `BASEDIR`. 2. **Read the user's config** from `skills.entries.mlb-daily-scores.config`: - `team`: the MLB team name (required) - `timezone`: IANA timezone string (optional, defaults to system timezone) 3. **Run the fetch script** using this EXACT command pattern (replacing BASEDIR with the actual path): ```bash BASEDIR/.venv/bin/python3 BASEDIR/fetch_mlb.py --config ``` **IMPORTANT:** You MUST use the venv Python at `BASEDIR/.venv/bin/python3`. Do NOT use `python`, `python3`, or any other Python interpreter — the required packages are only installed inside the `.venv` virtual environment. Using any other Python will fail with import errors. The `--config` flag tells the script to read team/timezone directly from `~/.openclaw/openclaw.json`. No user values should be interpolated into the command string. This outputs JSON to stdout. 4. **Parse the JSON output** and check `has_data`: - If `has_data` is `false` and there's no error: it's off-season or a day off. Reply with `HEARTBEAT_OK` (this suppresses the message in cron/heartbeat mode). - If `has_data` is `false` and there's an `error` field: report the error to the user. - If `has_data` is `true`: format the report as described below. 5. **Format the report** using this structure (include `game_type` from the JSON when it is not Regular Season): ``` ⚾ MLB Daily Report — [Team Name] 📅 [Today's Date] ━━━━━━━━━━━━━━━━━━━━━━━ 📊 YESTERDAY'S RECAP [game_type, e.g. "(Spring Training)" — omit if Regular Season] ━━━━━━━━━━━━━━━━━━━━━━━ [Score Line, e.g.: Blue Jays 5, Yankees 3] W: [Winning Pitcher] L: [Losing Pitcher] S: [Save Pitcher, if any] LINE SCORE: [Linescore text from the API] ━━━━━━━━━━━━━━━━━━━━━━━ 🔮 TODAY'S PREVIEW [game_type, e.g. "(Spring Training)" — omit if Regular Season] ━━━━━━━━━━━━━━━━━━━━━━━ [Opponent] @ [Home Team] 🕐 [Game Time in local timezone] 🏟️ [Venue] Starting Pitchers: [Away Team]: [Pitcher Name] ([W-L], [ERA] ERA) [Home Team]: [Pitcher Name] ([W-L], [ERA] ERA) ━━━━━━━━━━━━━━━━━━━━━━━ 🏥 INJURY REPORT ━━━━━━━━━━━━━━━━━━━━━━━ [For each injury]: • [Player Name] ([Position]) — [Injury Description] [Status] [If no injuries]: ✅ No players currently on the injury list. ``` 6. **Omit sections** that have no data: - No yesterday game → skip the recap section, note "No game yesterday" - No today game → skip the preview section, note "No game scheduled today" - No injuries → show the clean bill of health line 7. **Keep the box score concise** — include the linescore (innings R/H/E) but NOT the full box score text (it's too long for chat). Only include the full boxscore if the user explicitly asks for more detail. 8. **Off-season handling** — If neither yesterday nor today has a game **and** there are no injuries to report, respond with just `HEARTBEAT_OK` so no message is delivered. The script covers all game types (spring training, regular season, postseason, exhibition), so true off-season gaps are only mid-November through late February.

path: .gitattributes
content: # Force LF line endings for all text files so scripts work on Linux
* text=auto eol=lf


path: README.md
content: # ⚾ MLB Daily Scores — OpenClaw Skill

Get daily baseball updates for your favourite MLB team, delivered to any chat channel on a schedule.

**What you get every morning:**

- Yesterday's game recap (score, winning/losing/save pitchers, linescore)
- Today's game preview (opponent, time, venue, probable starters with stats)
- Current injury report for your team

## Quick Start

### 1. Install from ClawHub

```bash
clawhub install mlb-daily-scores
```

### 2. Configure your team

> **Note:** Python dependencies (`MLB-StatsAPI`, `requests`) are installed automatically when you run `clawhub install`. If you need to reinstall them manually, run:
>
> ```bash
> python ~/.openclaw/skills/mlb-daily-scores/setup.py
> ```

Edit `~/.openclaw/openclaw.json`:

```json5
{
  skills: {
    entries: {
      "mlb-daily-scores": {
        enabled: true,
        config: {
          team: "Toronto Blue Jays",
          timezone: "America/Toronto",
        },
      },
    },
  },
}
```

### 3. Set up the daily schedule

```bash
openclaw cron add \
  --name "MLB Daily Scores" \
  --cron "0 9 * * *" \
  --tz "America/Toronto" \
  --session isolated \
  --message "Run the mlb-daily-scores skill" \
  --announce \
  --channel discord \
  --to "channel:YOUR_CHANNEL_ID"
```

That's it! You'll get a daily baseball briefing at 9 AM.

## Configuration Reference

| Key        | Required | Default   | Description                                      |
| ---------- | -------- | --------- | ------------------------------------------------ |
| `team`     | Yes      | —         | Full MLB team name (e.g., `"Toronto Blue Jays"`) |
| `timezone` | No       | System TZ | IANA timezone (e.g., `"America/New_York"`)       |

### Supported Teams

Arizona Diamondbacks, Atlanta Braves, Baltimore Orioles, Boston Red Sox, Chicago Cubs, Chicago White Sox, Cincinnati Reds, Cleveland Guardians, Colorado Rockies, Detroit Tigers, Houston Astros, Kansas City Royals, Los Angeles Angels, Los Angeles Dodgers, Miami Marlins, Milwaukee Brewers, Minnesota Twins, New York Mets, New York Yankees, Oakland Athletics, Philadelphia Phillies, Pittsburgh Pirates, San Diego Padres, San Francisco Giants, Seattle Mariners, St. Louis Cardinals, Tampa Bay Rays, Texas Rangers, Toronto Blue Jays, Washington Nationals.

## Cron Schedule Examples

| Schedule           | Cron Expression | Description                      |
| ------------------ | --------------- | -------------------------------- |
| Morning briefing   | `0 9 * * *`     | Every day at 9:00 AM             |
| Lunchtime update   | `0 12 * * *`    | Every day at noon                |
| After games finish | `0 1 * * *`     | 1:00 AM (after west-coast games) |
| Weekdays only      | `0 9 * * 1-5`   | Mon–Fri at 9:00 AM               |

## On-Demand Usage

You can also get updates anytime by:

- Typing `/mlb-daily-scores` in any chat connected to OpenClaw
- Asking your assistant: _"What happened in the Yankees game yesterday?"_

## How It Works

1. The skill runs `fetch_mlb.py` which calls the free **MLB Stats API** (no API key needed)
2. It fetches yesterday's results, today's schedule, and current injuries
3. The OpenClaw agent formats the data into a clean, readable report
4. The report is delivered to your configured channel

## Requirements

- **Python 3.9+** (for `zoneinfo` module)
- **OpenClaw Gateway** with cron support
- **pip packages**: `MLB-StatsAPI`, `requests`

## Off-Season Behaviour

During the off-season (November–February) or on off-days, the skill silently skips — no messages are sent. It will automatically resume when games are scheduled.

## Troubleshooting

**"Team not found" error**
→ Use the full official team name (e.g., "New York Yankees" not "Yankees" or "NYY")

**No message delivered**
→ Check that the cron job is running: `openclaw cron list`
→ Verify the team has a game: the skill skips days with no games

**Dependency errors**
→ Ensure Python 3.9+ is installed: `python3 --version`
→ Reinstall packages: `pip3 install --user --force-reinstall MLB-StatsAPI requests`

## Publishing

To publish updates to ClawHub:

```bash
clawhub publish ./mlb-daily-scores \
  --slug mlb-daily-scores \
  --name "MLB Daily Scores" \
  --version 1.0.0 \
  --tags latest
```

## License

MIT


path: setup.py
content: #!/usr/bin/env python3
"""setup.py — Install dependencies for the mlb-daily-scores skill.

Cross-platform (macOS, Linux, Windows). Run once after installing the skill.
Creates a virtual environment in .venv/ inside the skill directory and installs
packages there, avoiding PEP 668 "externally managed environment" issues.

Usage:
    python3 setup.py        (macOS/Linux)
    python setup.py         (Windows)
"""

import subprocess
import shutil
import sys
import os
from pathlib import Path

PACKAGES = ["MLB-StatsAPI", "requests"]


def main():
    print("=== mlb-daily-scores: Installing dependencies ===")

    base_dir = Path(__file__).resolve().parent
    venv_dir = base_dir / ".venv"

    # Create virtual environment if it doesn't exist
    if not venv_dir.exists():
        print(f"Creating virtual environment in {venv_dir} ...")
        subprocess.check_call([sys.executable, "-m", "venv", str(venv_dir)])

    # Determine the venv's Python and pip paths
    if sys.platform == "win32":
        venv_python = venv_dir / "Scripts" / "python.exe"
    else:
        venv_python = venv_dir / "bin" / "python3"
        if not venv_python.exists():
            venv_python = venv_dir / "bin" / "python"

    if not venv_python.exists():
        print(f"ERROR: Could not find Python in venv at {venv_python}")
        sys.exit(1)

    # Install packages into the venv
    uv = shutil.which("uv")
    if uv:
        print("Using uv...")
        subprocess.check_call(
            [uv, "pip", "install", "--python", str(venv_python)] + PACKAGES
        )
    else:
        print(f"Using pip ({venv_python})...")
        subprocess.check_call(
            [str(venv_python), "-m", "pip", "install"] + PACKAGES
        )

    print()
    print("=== mlb-daily-scores: Dependencies installed successfully ===")
    print(f"    Virtual environment: {venv_dir}")
    print()
    print("Next steps:")
    print('  1. Add config to ~/.openclaw/openclaw.json (see SKILL.md)')
    print("  2. Set up the daily cron job (see SKILL.md)")


if __name__ == "__main__":
    main()


path: setup.sh
content: #!/usr/bin/env bash
# setup.sh — Install dependencies for the mlb-daily-scores skill.
# Creates a virtual environment in .venv/ and installs packages there.
# Run once after installing the skill.

set -e

SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
VENV_DIR="$SCRIPT_DIR/.venv"

echo "=== mlb-daily-scores: Installing dependencies ==="

# Create virtual environment if it doesn't exist
if [ ! -d "$VENV_DIR" ]; then
    echo "Creating virtual environment in $VENV_DIR ..."
    python3 -m venv "$VENV_DIR"
fi

VENV_PYTHON="$VENV_DIR/bin/python3"
if [ ! -f "$VENV_PYTHON" ]; then
    VENV_PYTHON="$VENV_DIR/bin/python"
fi

# Install packages into the venv
if command -v uv &>/dev/null; then
    echo "Using uv..."
    uv pip install --python "$VENV_PYTHON" MLB-StatsAPI requests
else
    echo "Using pip..."
    "$VENV_PYTHON" -m pip install MLB-StatsAPI requests
fi

echo "=== mlb-daily-scores: Dependencies installed successfully ==="
echo "    Virtual environment: $VENV_DIR"
echo ""
echo "Next steps:"
echo "  1. Add config to ~/.openclaw/openclaw.json (see SKILL.md)"
echo "  2. Set up the daily cron job (see SKILL.md)"
echo ""


Security scan verdicts — ClawScan: clean | static analysis: clean | VirusTotal: clean | SkillSpector: suspicious (MEDIUM)