jellyfin について
jellyfin は、稼働中の Jellyfin メディアサーバーを読み取り専用で調べるコマンドラインスキルです。メディアの検索やライブラリ確認に使え、JSON 出力、ページング、パスワードを表示しないログインに対応します。
主な機能
- 01メディアの検索と詳細確認
- 02ページング対応のライブラリ閲覧
- 03新着と次に見る項目の確認
- 04シリーズ、シーズン、エピソードの詳細表示
- 05JSON 出力とリクエストのプレビュー
- 06ユーザーセッションでのログイン
活用シーン
- 01作品を検索してメタデータを確認
- 02次に視聴する未視聴エピソードの特定
- 03ライブラリの一覧化やページ単位の取得
- 04実行前の API リクエスト確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ magnus919/ agent-skills --skill jellyfinインストール後、Claude Code で/jellyfinを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
README.mdevals/evals.jsonreferences/auth-and-sessions.mdendpoint-catalog.mdgotchas-field-guide.mdquick-connect.mduser-scoping-and-errors.mdworked-recipes.mdscripts/jellyfintest_jellyfin_cli.py詳細
jellyfin — ターミナルから Jellyfin Media Server を操作
最近追加された映画やテレビのエピソードを取得し、メディアを検索・確認し、シリーズ →
シーズン → エピソードの順にたどり、ライブラリを閲覧し、次に視聴するエピソードを確認し、ユーザーとしてログインし、
サーバーの統計情報を確認できます。すべて Jellyfin サーバーの REST API を使って実行します。login を除き、すべてのコマンドは読み取り専用です。
セットアップ
- Jellyfin サーバーが実行中で、アクセス可能であることを確認します(デフォルトは
http://localhost:8096)。 - 認証方法を選びます。
- API キー — ダッシュボード → API キー →
+。管理者レベルで、ユーザー ID は紐づきません。 そのため、ユーザー単位のコマンドでは毎回、明示的なユーザー ID が必要です。 - ユーザートークン —
scripts/jellyfin login --username NAME --promptを一度実行します。 エクスポートする値が表示されます。
- API キー — ダッシュボード → API キー →
- 次の環境変数を設定します。
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
同梱の CLI は scripts/jellyfin として実行します。--help と --dry-run は認証情報なしで動作します。
認証の仕組み
Jellyfin では、すべての呼び出しに MediaBrowser スキームの Authorization ヘッダーが必要です。ログイン
エンドポイントでは、トークンを取得する前に Client=..., Device=..., DeviceId=..., Version=... の4つの値が必要です。
それ以外の場合、サーバーは POST /Users/AuthenticateByName を
400 Error processing request. で拒否します。その後、アクセストークン(または API キー)は、同じヘッダー内で
Token="..." として送信されます。従来の X-Emby-Token ヘッダーも同じ意味ですが、
Jellyfin 12.0 での削除が予定されています。同梱の CLI は新しい形式を使い、リクエストごとにトークンをこの1つの経路でのみ送信します(X-Emby-Token を同時に送信することはありません)。
references/auth-and-sessions.md を参照してください。
基本コマンド
認証 — セッションを取得
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 は、調査済みの一連の手順を実行します。トークン取得前の完全な MediaBrowser ヘッダー
→ POST /Users/AuthenticateByName → User.Id と AccessToken を取得 → 再利用できるトークン取得後のヘッダーを表示します。
パスワードが表示されることはありません。
info — サーバー情報
scripts/jellyfin info # server name, version, OS, user count
scripts/jellyfin info --json
recent — 最近追加されたメディア
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
userId を指定して /Items/Latest にリクエストします。レスポンスは JSON 配列そのもの(Items
ラッパーなし)で、groupItems はエピソードをシリーズごとにまとめるため、「新着コンテンツ」として扱ってください。
search — メディアライブラリを検索
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/Hints にリクエストします。結果には id が含まれます(古いサーバーでは非推奨の ItemId も含まれますが、
CLI はすでに新しいフィールドを優先します)。
ナビゲーション — アイテムを確認してシリーズをたどる
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、next-up はユーザー単位のコマンドです。JELLYFIN_USER_ID または --user-id が必要で、
どちらも指定されていない場合は、ネットワーク呼び出しの前にエラーになります。
libraries — コレクションを閲覧
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 は /Library/MediaFolders を読み取ります。このエンドポイントは 管理者専用 のため、管理者以外のトークンでは
403 が返されます。その場合は /UserViews を使用してください(リファレンスを参照)。browse は /Items を
startIndex/limit でページングし、userId が指定されている場合はそれも渡します。API キー以外の
認証を使うサーバーでは、ユーザーを指定しないクエリが 400 userId is required で拒否されるためです。
stats — ライブラリの統計情報
scripts/jellyfin stats # movie, series, episode, song counts (/Items/Counts)
パイプラインの例
シリーズを検索し、次に視聴する未視聴のエピソードを確認
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'
ライブラリ全体をページングして取得
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
ログインしてセッションを保存
scripts/jellyfin login --username alice --prompt --json | jq -r '"\(.user_id) \(.access_token)"'
JSON と jq
--json はサブコマンドの前後どちらにも指定できます。出力キーは安定した snake_case 形式です。items
(id、name、type、year、series、season_number、episode_number を含む)、
results、libraries、total_record_count、start_index が出力されます。--dry-run は、
実際に送信される内容に対応する dry_run、path、params を含むプランを出力します(login は authorization_header を追加し、info
は requests リストを構成します)。これにより、ライブ実行の前に jq で一連の処理を検証できます。終了コードは、0
が成功(dry-run を含む)、1 が CLI/API エラー、2 が引数エラーです。表形式で受け渡すには、jq -r '.items[] | [.name, .year] | @tsv' を使います。
既知の注意点
- JELLYFIN_URL にはプロトコルとポートを含める必要があります — 例:
http://192.168.1.100:8096。 - ユーザー単位のコマンドにはユーザーの明示指定が必要です —
recent、next-up、item、seasons、episodesは、JELLYFIN_USER_ID/--user-idがないと実行できません。CLI が管理者を自動で選ぶことはありません。ユーザートークンを使ったリクエストで userId が指定されていない場合、 サーバーは400 userId is requiredを返します。 - API キーにはユーザーが紐付いていません —
/Users/Meに API キーでアクセスすると、仕様上400 Token is not owned by a user.が返されます。ユーザー単位のクエリにはユーザー ID の明示指定が必要です( references/user-scoping-and-errors.md を参照)。 - ログイン時の 400 と 401 の落とし穴 — MediaBrowser ヘッダーがない、または不完全な場合は、プレーンテキストの
Error processing request.を伴う400が返されます。認証情報が誤っている場合は401が返されます。同じエンドポイントでも、失敗の種類は異なります。 - エンドポイントごとにレスポンスの形式が異なります —
/Itemsと/Shows/*は結果を{Items, TotalRecordCount, StartIndex}に格納して返します。/Items/Latestは配列をそのまま返し、検索結果はSearchHintsキーを使用します。汎用クライアントでは場合分けが必要です(CLI では対応済みです)。 - 最近のアイテムの種類による絞り込みはサーバー側で行われます —
--movies/--episodesはlimitの前にincludeItemTypesに変換され、ローカルでは絞り込みません。 - NextUp ではすべてのサーバーバージョンで userId が必要です — 省略すると、10.8 以下のサーバーではクラッシュし、10.9 以上では セッションのユーザーに暗黙的に対象が限定されます。CLI は常に userId を送信します。
librariesは管理者専用です —/Library/MediaFoldersには管理者トークンが必要です。 管理者以外のトークンでは 403 が返されます。- レガシー認証は廃止予定です —
X-Emby-Token、X-MediaBrowser-Token、およびapi_keyクエリパラメーターは非推奨です。管理者はすでに無効化できます(10.11 以降)。削除は 12.0 を予定しています。 CLI が送信する最新の Authorization ヘッダーを使用してください。 - 遅延認証 —
--helpと--dry-runは認証情報なしで使用でき、dry-run ではネットワークに一切アクセスしません。
使用する場面
稼働中の Jellyfin サーバーを読み取り専用で操作する場合に、このスキルを使用します。新着コンテンツの確認、アイテムの検索と詳細の確認、シリーズやシーズンの閲覧、次に視聴する作品の計画、ライブラリの一覧取得、および login または Quick Connect によるユーザーセッションの取得に対応します。
使用しない場面
サーバーのインストールや管理(Jellyfin または Emby のインストール、ライブラリの編集、ユーザー管理)には、このスキルを使用しないでください。login を除き、同梱されているすべてのコマンドは読み取り専用です。Plex や Kodi には対応していません(API が異なるため、それぞれ専用のツールを使用してください)。また、再生を操作するリモコンでもありません。ストリーミングやリモート操作の自動化には、Jellyfin の公式クライアントを使用してください。
リファレンスファイル
| ファイル | 用途 |
|---|---|
| references/auth-and-sessions.md | MediaBrowser ヘッダー方式、ログインフロー、トークンの受け渡し方法、レガシー方式の非推奨化、エラーの特徴 |
| references/endpoint-catalog.md | 各読み取りエンドポイントのパラメーター、レスポンス形式、画像 URL、ページネーションのループ |
| references/user-scoping-and-errors.md | userId の要件一覧、API キーの識別に関する仕様、400 と 404 の診断 |
| references/gotchas-field-guide.md | 通信レベルの失敗の特徴、バージョン差異の記録、モックの形式 |
| references/worked-recipes.md | 複数ステップの curl/jq および CLI の例:ログイン → 最新、ライブラリ → 閲覧、検索 → シーズン → エピソード |
| references/quick-connect.md | パスワード不要の Quick Connect ログインフロー |
利用可能なスクリプトと前提条件
scripts/jellyfin— 同梱の Python CLI(--json、--dry-run、遅延認証)。 標準ライブラリとrequestsのみをインポートします。scripts/test_jellyfin_cli.py— オフラインのテストスイート(pytest と unittest に対応)。 HTTP の動作はすべてモックされ、ネットワークへの送信は一切ありません。- Python 3.8 以降と
requestsが必要です。Jellyfin サーバーが稼働している必要があります(10.8 以降を想定。動作確認は 12.0 時代の OpenAPI 仕様に基づいています)。このスキルによってサービスが起動されることはありません。