Skip to content
Skillv1.0.0

jellyfin

Query your Jellyfin media server from the terminal — recently added media, search, item details, series navigation, next-up episodes, library browsing, server info, and user login. Use when the user a

by magnus919(0) 0 installs
Free
Sign in to install

Free account. Installing gives you the manifest plus copy-paste snippets.

See reviews

About

Imported from magnus919/agent-skills (jellyfin/SKILL.md). Install upstream with npx skills add magnus919/agent-skills --skill jellyfin. Copyright stays with the author (MIT).

jellyfin — Jellyfin Media Server from the Terminal

Query recently added movies and TV episodes, search and inspect media, walk series → seasons → episodes, browse libraries, see next-up episodes, log in as a user, and check server stats — all from your Jellyfin server's REST API. Every command is read-only except login.

Setup

  1. Make sure your Jellyfin server is running and accessible (default http://localhost:8096).
  2. Pick an authentication route:
    • API key — Dashboard → API Keys+. Administrator-level, no user identity: every user-scoped command then needs an explicit user id.
    • User token — run scripts/jellyfin login --username NAME --prompt once; it prints the values to export.
  3. Set these environment variables:
export JELLYFIN_URL="http://your-server:8096"   # include protocol and port
export JELLYFIN_API_KEY="your-api-key-here"     # or JELLYFIN_TOKEN after `login`
export JELLYFIN_USER_ID="your-jellyfin-user-id" # required by recent, next-up, item, seasons, episodes

Run the bundled CLI as scripts/jellyfin. --help and --dry-run work without credentials.

How authentication works

Jellyfin wants a MediaBrowser-scheme Authorization header on every call. The login endpoint requires its Client=..., Device=..., DeviceId=..., Version=... quartet before any token exists — the server rejects POST /Users/AuthenticateByName with 400 Error processing request. otherwise. Afterwards the access token (or API key) rides the same header as Token="..."; the legacy X-Emby-Token header means the same thing and is scheduled for removal from Jellyfin 12.0. The bundled CLI sends the modern form and puts the token in exactly that one channel per request (never co-sends X-Emby-Token). See references/auth-and-sessions.md.

Essential Commands

Authentication — get a session

scripts/jellyfin login --username alice --prompt          # prints JELLYFIN_* exports
echo "pw" | scripts/jellyfin login --username alice --password-stdin
scripts/jellyfin login --username alice --dry-run --json  # preview the pre-token header

login demonstrates the full researched sequence: complete pre-token MediaBrowser header → POST /Users/AuthenticateByName → capture User.Id + AccessToken → print the post-token header for reuse. It never echoes the password.

info — Server information

scripts/jellyfin info              # server name, version, OS, user count
scripts/jellyfin info --json

recent — Recently added media

scripts/jellyfin recent                     # last 10 items added for JELLYFIN_USER_ID
scripts/jellyfin recent --movies --limit 5  # server-side includeItemTypes filter
scripts/jellyfin recent --episodes --limit 20 --json
scripts/jellyfin recent --user-id USER_ID   # override the env var

Hits /Items/Latest with userId; the response is a bare JSON array (no Items wrapper), and groupItems merges episodes by series, so treat it as "what's new".

search — Search your media library

scripts/jellyfin search --query "dune"                  # everything
scripts/jellyfin search --query "dune" --type Movie     # comma-separated types
scripts/jellyfin search --query "star trek" --type Series,Episode --limit 5 --json

Search hits /Search/Hints; results carry id (with a deprecated ItemId twin on old servers — the CLI already prefers the modern field).

Navigation — inspect items and walk series

scripts/jellyfin search --query "dune" --type Movie --json   # find an item ID
scripts/jellyfin item --id ITEM_ID                           # full metadata (needs user)
scripts/jellyfin seasons --series-id SERIES_ID               # list seasons
scripts/jellyfin episodes --series-id SERIES_ID --season-id SEASON_ID
scripts/jellyfin next-up --limit 10                          # next unwatched episodes
scripts/jellyfin next-up --series-id SERIES_ID --user-id USER_ID

item, seasons, episodes, and next-up are user-scoped: they require JELLYFIN_USER_ID or --user-id and fail before any network call without one.

libraries — browse a collection

scripts/jellyfin libraries                                   # library IDs and types
scripts/jellyfin browse --library-id LIBRARY_ID --type Movie --limit 50
scripts/jellyfin browse --library-id LIBRARY_ID --start-index 50   # paginate
scripts/jellyfin browse --library-id LIBRARY_ID --user-id USER_ID  # userId sent explicitly

libraries reads /Library/MediaFolders, which is admin-only — non-admin tokens get 403 and should use /UserViews (see references). browse pages /Items with startIndex/limit and passes userId when provided, since servers using non-API-key auth reject unscoped queries with 400 userId is required.

stats — Library statistics

scripts/jellyfin stats    # movie, series, episode, song counts (/Items/Counts)

Pipeline recipes

Find a series, then its next unwatched episode

scripts/jellyfin search --query "breaking bad" --type Series --json | jq -r '.results[0].id'
scripts/jellyfin next-up --series-id "$SERIES_ID" --user-id "$JELLYFIN_USER_ID" --json | jq -r '.items[0].name'

Page through a whole library

scripts/jellyfin browse --library-id "$LIB_ID" --limit 100 --start-index 0 --json | jq -c '.items'
# loop: advance --start-index by the returned count until .total_record_count is reached

Log in and persist a session

scripts/jellyfin login --username alice --prompt --json | jq -r '"\(.user_id) \(.access_token)"'

JSON and jq

Put --json before or after the subcommand. Output keys are stable snake_case: items (with id, name, type, year, series, season_number, episode_number), results, libraries, total_record_count, start_index. --dry-run emits a plan carrying dry_run, path, and params (login adds authorization_header; info composes a requests list), matching what would be sent, so jq can verify a chain before running it live. Exit codes: 0 success (including dry-run), 1 CLI/API errors, 2 argument errors. Use jq -r '.items[] | [.name, .year] | @tsv' for tabular handoff.

Known Gotchas

  • JELLYFIN_URL must include protocol and port — e.g. http://192.168.1.100:8096.
  • User-scoped commands require an explicit userrecent, next-up, item, seasons, episodes refuse to run without JELLYFIN_USER_ID/--user-id. The CLI never picks an administrator for you. A missing userId on user-token requests makes the server answer 400 userId is required.
  • API keys have no user/Users/Me answers 400 Token is not owned by a user. to API keys by design; per-user queries need an explicit user id (see references/user-scoping-and-errors.md).
  • The login 400 vs 401 trap — missing/partial MediaBrowser header → 400 with plain text Error processing request.; wrong credentials → 401. Same endpoint, different failures.
  • Response shapes differ per endpoint/Items and /Shows/* wrap results in {Items, TotalRecordCount, StartIndex}; /Items/Latest returns a bare array; search uses a SearchHints key. Generic clients must branch (the CLI already does).
  • Recent type filtering is server-side--movies/--episodes become includeItemTypes before limit; no local filtering.
  • NextUp needs userId on every server version — omitting it crashed servers ≤10.8 and silently scopes to the session user on ≥10.9. The CLI always sends it.
  • libraries is admin-only/Library/MediaFolders requires an administrator token; non-admin tokens get 403.
  • Legacy auth is going awayX-Emby-Token, X-MediaBrowser-Token, and the api_key query parameter are deprecated; admins can already disable them (10.11+), and removal targets 12.0. Prefer the modern Authorization header the CLI sends.
  • Lazy auth--help and --dry-run work without credentials; dry-run never touches the network.

When to use

Use this skill for read-only interaction with a running Jellyfin server: discovery of what's new, searching and inspecting items, walking series and seasons, next-up planning, library inventories, and obtaining a user session via login or Quick Connect.

When not to use

Do not use this skill for server installation or administration (installing Jellyfin or Emby, editing libraries, managing users) — every bundled command is read-only except login. It does not target Plex or Kodi (different APIs — use their own tools), and it is not a playback remote: route streaming or remote-control automation to Jellyfin's official clients.

Reference Files

File Use it for
references/auth-and-sessions.md MediaBrowser header scheme, login flow, token channels, legacy deprecation, error signatures
references/endpoint-catalog.md Every read endpoint's parameters, response shapes, image URLs, pagination loop
references/user-scoping-and-errors.md The userId requirement matrix, API-key identity quirks, 400-vs-404 diagnosis
references/gotchas-field-guide.md Wire-level failure signatures, version-drift ledger, mock shapes
references/worked-recipes.md Multi-step curl/jq and CLI recipes: login → latest, libraries → browse, search → seasons → episodes
references/quick-connect.md Passwordless Quick Connect login flow

Available Scripts and Prerequisites

  • scripts/jellyfin — the bundled Python CLI (--json, --dry-run, lazy auth). Imports only the standard library and requests.
  • scripts/test_jellyfin_cli.py — offline test suite (pytest + unittest compatible); all HTTP behavior is mocked, zero network egress.
  • Requires Python 3.8+ and requests. A running Jellyfin server (10.8+ assumed; tested behaviors anchored to the 12.0-era OpenAPI spec). No service is started by this skill.

Use it

Copy one of these into your project. Installing also returns the manifest and these snippets.

yaml
targets:
  - https://api.opensmartroute.ai/api/v1/registry/magnus919-agent-skills-jellyfin/manifest   # or paste the manifest below

Manifest

An Open Capability Manifest: the router reads it to know what this does, what it costs and when to pick it.

magnus919-agent-skills-jellyfin.ocm.jsonjson
{
  "ocm": "1",
  "id": "magnus919-agent-skills-jellyfin",
  "kind": "skill",
  "name": "jellyfin",
  "description": "Query your Jellyfin media server from the terminal — recently added media, search, item details, series navigation, next-up episodes, library browsing, server info, and user login. Use when the user asks about Jellyfin, media servers, movies, TV shows, next episodes, or their media library. Do not use this skill for server installation, library management, playback control, or Emby/Plex servers.",
  "publisher": "magnus919",
  "version": "1.0.0",
  "capabilities": {
    "domains": [
      "data_analysis"
    ],
    "tags": [
      "skill-md",
      "jellyfin",
      "media-server",
      "movies",
      "tv",
      "episodes",
      "recently-added",
      "library",
      "home-media",
      "api-client"
    ],
    "languages": [
      "en"
    ]
  },
  "quality_prior": 0.6,
  "examples": [
    "Query your Jellyfin media server from the terminal — recently added media, search, item details, series navigation, next-up episodes, library browsing, server info, and user login. Use when the user asks about Jellyfin, media servers, movies, TV shows, next episodes, or their media library. Do not use this skill for server installation, library management, playback control, or Emby/Plex servers."
  ],
  "primary": false,
  "metadata": {
    "source": {
      "provider": "github",
      "repository": "https://github.com/magnus919/agent-skills",
      "path": "jellyfin/SKILL.md",
      "ref": "1ac5b58139a19ff3a911c0447ef0673bb94ccfca",
      "url": "https://github.com/magnus919/agent-skills/blob/1ac5b58139a19ff3a911c0447ef0673bb94ccfca/jellyfin/SKILL.md",
      "key": "magnus919/agent-skills/jellyfin/SKILL.md"
    },
    "compatibility": "Requires Python 3.8+ and `requests`. Authenticate with JELLYFIN_API_KEY (Dashboard → API Keys), a user access token from `login`, or Quick Connect; user-scoped commands (`recent`, `next-up`, `item`, `",
    "license": "MIT"
  },
  "instructions": "# jellyfin — Jellyfin Media Server from the Terminal\n\nQuery recently added movies and TV episodes, search and inspect media, walk series →\nseasons → episodes, browse libraries, see next-up episodes, log in as a user, and check\nserver stats — all from your Jellyfin server's REST API. Every command is read-only\nexcept `login`.\n\n## Setup\n\n1. Make sure your Jellyfin server is running and accessible (default `http://localhost:8096`).\n2. Pick an authentication route:\n   - **API key** — Dashboard → **API Keys** → `+`. Administrator-level, no user identity:\n     every user-scoped command then needs an",
  "cost": {
    "context_tokens": 2561
  }
}

Fetch it by URL: GET /api/v1/registry/magnus919-agent-skills-jellyfin/manifest?version=1.0.0

Reviews

Star ratings from people who tried it. One review per account; edit yours any time.

No reviews yet. Install it, try it, and be the first to rate it.