Files
Magnus Hedemarkandfactory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com> 2a9a81e29b fix(jellyfin): harden dispatch against subcommand-named flag values
main() sliced argv at the first occurrence of a known subcommand name,
so a value-flag pair whose value names a subcommand (e.g. login's
--server given `search`) made argparse dispatch the wrong subparser:
`jellyfin --server search browse ...` errored inside the `search`
sub-parser instead of running browse.

Dispatch now splits such misplaced pairs out of the top-level argv
(find_subcommand_token + split_misplaced_value_pairs) and re-attaches
them to the command tail, where each handler's parse_known_args already
tolerates unknown flags. A properly placed occurrence of the same flag
later in the tail still wins. Any other pre-command token (unknown
flags, stray positionals, `--`, dangling value flags) is untouched, so
argparse errors stay byte-identical to the pre-hardening CLI.

Also dedupe the twice-repeated "Bundled CLI --dry-run and exit-code
contract" section in references/worked-recipes.md (user-testing round 1
finding); content merged into one section.

Adds DispatchHardeningTests: the mis-slice scenario for every
subcommand shape, clean-argv dispatch for all 11 subcommands, flag
priority, argparse-owned error paths, and unit pinning of both helper
return-value tables.

Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
2026-08-30 00:45:16 -04:00
..

Jellyfin Media Server from the Terminal

Query your Jellyfin media library — recently added movies and episodes, search and inspect items, walk series, seasons, and episodes, browse library contents, see next-up episodes, log in as a user, and check server stats.

Why Install This Skill

When your agent loads this skill, it can navigate your home media server without opening a browser. That means:

  • See what's new — recently added movies and TV episodes, filtered server-side
  • Search your library — find any movie, show, or episode by keyword
  • Navigate series — walk a show's seasons and episodes, and see what's next unwatched
  • Browse collections — list your libraries and page through everything in them
  • Authenticate properly — log in as a user (or use Quick Connect) without fumbling Jellyfin's unusual MediaBrowser authorization header, which trips up most scripts
  • Check server details — server name, version, operating system, user count, counts

Every command is read-only (plus a login helper), and --dry-run previews any request without touching the network.

What You Get

Path Purpose
SKILL.md Complete command reference with setup, gotchas, and recipes
scripts/jellyfin CLI for Jellyfin API operations (--json, --dry-run)
scripts/test_jellyfin_cli.py Offline test suite (all HTTP mocked)
references/auth-and-sessions.md The MediaBrowser header scheme, login flow, token channels, deprecation timeline
references/endpoint-catalog.md Endpoint-by-endpoint parameter and response-shape catalog
references/user-scoping-and-errors.md Which calls need a user id, and why queries 400/404 without one
references/gotchas-field-guide.md Wire-level failure signatures and version differences
references/worked-recipes.md Multi-step curl/jq and CLI workflows
references/quick-connect.md Passwordless Quick Connect login
evals/evals.json Behavioral eval cases including negative triggers

Quick Start

scripts/jellyfin --help
export JELLYFIN_URL="http://your-server:8096"
export JELLYFIN_API_KEY="your-api-key"           # Dashboard → API Keys
export JELLYFIN_USER_ID="your-jellyfin-user-id"  # required by user-scoped commands
scripts/jellyfin search --query "dune" --type Movie --json
scripts/jellyfin recent --movies --limit 5

No API key yet? Log in as a user instead — the script sends the pre-token Authorization: MediaBrowser Client=..., Device=..., DeviceId=..., Version=... header that POST /Users/AuthenticateByName requires and prints the values to export:

scripts/jellyfin login --username alice --prompt

Triggers

Load this when asking about Jellyfin, media server content, recently added movies or TV, next-up episodes, browsing your home media library, or Jellyfin API authentication.

Requirements

Python 3.8+ with requests. A running Jellyfin server (10.8+ behaviors assumed). Authentication: an API key (Dashboard → API Keys), a user access token via login, or Quick Connect. User-scoped commands also need a Jellyfin user id.