Omahub
← All plugins
J

MLB Booth

by Jeremy Longshore

MLB Booth makes your chosen club legible at a glance: first-pitch countdowns before games, then score and inning, count, outs, bases, and last play while live. Panel: local schedule, division race, and line score. It reads the keyless MLB Stats API: schedule and standings every 15 minutes, Gameday every 20 seconds only during a game. MLB requests use the selected club and public game data, not an account or identifying data. Optional bring-your-own-key recaps are off by default and post nothing.

Security review

Potentially dangerous behavior detected · 10 findings

Deterministic scan — not a security guarantee

High
Risk level
High
Analyzed commit
79a47e3
Scanned
1 week ago
  • high destructive_filesystem scripts/rig-verify.sh:76

    Destructive operation on the root filesystem or a block device.

    rm -rf /tmp/$NAME && mkdir -p /tmp/$NAME && tar xzf /tmp/$NAME.tgz -C /tmp/$NAME' || exit 3
  • high destructive_filesystem scripts/rig-verify.sh:97

    Destructive operation on the root filesystem or a block device.

    rm -rf /tmp/$NAME /tmp/$NAME.tgz >/dev/null 2>&1
  • medium external_hosts Panel.qml:188

    Downloads or connects to an external HTTP(S) host.

    curl("https://statsapi.mlb.com/api/v1/schedule?sportId=1&teamId="
  • medium external_hosts Panel.qml:198

    Downloads or connects to an external HTTP(S) host.

    curl("https://statsapi.mlb.com/api/v1/standings?leagueId=103,104&season=" + season)
  • medium external_hosts Panel.qml:215

    Downloads or connects to an external HTTP(S) host.

    curl("https://statsapi.mlb.com/api/v1.1/game/"
  • low obfuscation tests/model.test.js:30

    Augments a command with octal/hex escape sequences.

    \x7fd"), "abcd")
  • Augments a command with octal/hex escape sequences.

    \x89PNG\r\n\x1a\n" or raw[12:16] != b"IHDR":
  • Docs external_hosts VERIFICATION.md:26

    Downloads or connects to an external HTTP(S) host.

    curl -s "https://statsapi.mlb.com/api/v1/schedule?sportId=1&teamId=144&hydrate=team,linescore&startDate=2026-08-19&endDate=2026-08-27" -o tests/fixtures/statsapi-schedule.json
  • Docs external_hosts VERIFICATION.md:27

    Downloads or connects to an external HTTP(S) host.

    curl -s "https://statsapi.mlb.com/api/v1/standings?leagueId=103,104&season=2026" -o tests/fixtures/statsapi-standings.json
  • Docs external_hosts VERIFICATION.md:28

    Downloads or connects to an external HTTP(S) host.

    curl -s "https://statsapi.mlb.com/api/v1.1/game/824589/feed/live" | jq '{gameData: {status: .gameData.status, teams: {away: {abbreviation: .gameData.teams.away.abbreviation, name: .gameData.teams.away

Automated analysis only — not a security guarantee.

AI advisory review

No obvious issues detected

Language-model assessment · ~deepseek/deepseek-v4-flash-latest — advisory only

Low
AI risk level
Low
Recommendation
install
Model
~deepseek/deepseek-v4-flash-latest
Analyzed commit
79a47e3
Reviewed
1 week ago

This is a benign MLB score widget that fetches public data from the MLB Stats API. The deterministic scan's high-risk findings are in developer-only scripts (rig-verify.sh) that are never executed on a user's machine, and the external hosts are legitimate API endpoints. The optional AI recap feature is off by default and requires a user-provided key, with no evidence of exfiltration.

  • The optional AI recap stores the user's API key in plaintext in shell.json, but this is user-controlled and off by default.
  • The deterministic scan flagged destructive filesystem operations in scripts/rig-verify.sh, but these are development/CI scripts not part of the runtime plugin.
How this check works

This review combines the deterministic scan (the rule-based results above) with an independent look at the plugin's code by a language model. The model reads a trimmed sample of the repository's files, the manifest, and the README, then gives a plain-language risk level and a recommendation: install (no notable danger), review (look closer first), or avoid (clearly dangerous).

It runs on the same analyzed commit as the deterministic scan and is strictly advisory — it is not a security guarantee and never blocks a plugin by itself. A human moderator still reviews plugins before they are listed.

AI advisory only — automated analysis, not a security guarantee.

Install
$ omarchy plugin add https://github.com/jeremylongshore/omarchy-mlb-booth-entry --enable
Widgets #bar #quickshell #media
<p align="center"><img src="assets/banner.svg" alt="MLB Booth" width="720"></p>

MLB Booth

Deep live MLB for the Omarchy bar. Pick any of the 30 clubs. Between games the pill counts down to first pitch; during one it reads like the booth's scorecard: score, half inning, count, and outs, refreshed every 20 seconds from the same GUMBO feed MLB's own Gameday runs on.

ATL @ CWS 1h 05m              before the game
ATL 1-0 · T4 · 2-2, 0 out     during it
ATL W 4-2                     after it

ko-fi

Install

omarchy plugin add https://github.com/jeremylongshore/omarchy-mlb-booth-entry --enable

Then add MLB Booth to your bar layout (Omarchy menu, Bar, or ~/.config/omarchy/shell.json). Open the pill and click the gear, or right-click the pill, to pick your club and 12-hour or 24-hour first-pitch times.

Remove

omarchy plugin remove io.github.jeremylongshore.mlb-booth

The panel

Click the pill:

  • Line score by inning with R H E, plus bases, count, the live matchup, and the last play as the scorer described it. Extra-inning games show their trailing nine.
  • Schedule for the coming week in your local time.
  • The division race, your club bolded.
  • The Booth (optional): two or three sentences of storyline between games, written by any OpenAI-compatible model you point it at. Off by default; the widget is complete without it.

Data

Everything live comes free and keyless from the MLB Stats API (statsapi.mlb.com): the schedule endpoint with team and line-score hydration, the GUMBO live feed per game, and the standings endpoint. No account, no token, no scraping.

Feed Cadence
Schedule + standings every 15 minutes
GUMBO live feed every 20 seconds, only while a game runs
The Booth recap once per game-state change, never during live play

Rain delays, postponements, suspended games, and doubleheaders are handled: a delayed start holds the pill instead of collapsing it, a postponed game never masquerades as a 0-0 final, and game two of a doubleheader never renders game one's innings. How network input is contained is in SECURITY.md.

Settings

Click the gear in the popup, right-click the pill, or press s with the panel open, for the two choices a user owns:

  • Team: any of the 30 club abbreviations
  • First pitch: 12-hour or 24-hour wall clocks on the schedule and tooltip

While settings are open the usual panel keys apply: h j k l or arrows move, Enter or Space selects, Escape goes back to the game panel. Save and Cancel are on the same cursor. The owner-runnable IPC is omarchy-shell io.github.jeremylongshore.mlb-booth settings.

The live pill still counts down as a duration (1h 05m); the clock format only changes printed first-pitch times. Default is 24-hour, so existing installs do not change until you pick 12-hour.

Save writes the same widget entry in ~/.config/omarchy/shell.json. Do not add a second layout object with the same id; that puts two pills on the bar.

{ "id": "io.github.jeremylongshore.mlb-booth", "team": "PIT", "timeFormat": "12h" }

The Booth recap takes three more values, and three is the floor for bring-your-own-key: which server, which model, which key. They are not in the settings form; set them on the same widget entry:

{ "id": "io.github.jeremylongshore.mlb-booth", "team": "ATL", "timeFormat": "24h",
  "aiBaseUrl": "https://api.openai.com/v1", "aiModel": "gpt-4o-mini",
  "aiApiKey": "sk-..." }

The base URL must be https. Leave the three empty and the widget stays fully keyless.

Why not the existing scores plugin

The multi-sport scores widget is wide: every league, one line per game. MLB Booth is narrow and deep: one club, the full in-game state (count, outs, bases, last play), the division race, and an optional voice in the booth. Follow one team all season and you want the scorecard, not the ticker.

Development

npm test

The data layer (Model.js) is pure functions and loads in both Quickshell and node; fixtures under tests/fixtures/ are real API bodies captured during a live game. Built from omarchy-widget-template.

Maintainers wanted

These plugins are growing, and we are looking for dependable Omarchy users who want to review issues, test releases, and keep a plugin healthy over time. Start with a small pull request or open a maintainer interest issue titled Maintainer interest. Tell us which plugin you use and how you want to help. Consistent contributors can earn maintainer responsibility.

License

MIT.