jellyfin-full

Jellyfin is a Free Software Media System that puts you in control of managing and streaming your media. It is an alternative to the proprietary Emby and Plex, to provide media from a dedicated server to end-user devices via multiple apps.

Documentation

n8n-nodes-jellyfin-full

Auto-generated n8n community node for the Jellyfin API (spec version 12.1.0), built from its OpenAPI document.

Install

In n8n: Settings → Community Nodes → Install, and enter n8n-nodes-jellyfin-full.

Or manually:

npm install n8n-nodes-jellyfin-full

What was generated

  • Node type(s) in this package: jellyfin, jellyfinFiles (file upload/download).
  • 44 resource(s), 309 operation(s) (the node above also carries usableAsTool: true, so n8n also offers it to an AI Agent -- see "Using the AI Agent tool" below).
  • 55 file upload/download operation(s), handled by the separate Files node -- see "File upload/download" below for why they're not part of the main node.
  • Credential type in this package: jellyfinApi. Each has an editable Base URL field.
    • API Key (Authorization) -- a credential field for it.
  • A Custom Headers field on the credential: add any name/value headers this API needs but the spec doesn't describe (a second Authorization scheme, a tenant ID, a gateway token). They are sent on every request by both nodes. They are defaults -- this node's own authentication header and an operation's own header field both win a name collision. The credential's Test button does not send them.
  • Field types: 838 text fields, 438 booleans (switches), 239 integers, 201 enum dropdowns, 34 nested objects and lists of objects, 18 raw JSON objects, 13 numbers -- 1781 field(s) in total. 9 request body/bodies could not be exploded into fields and stayed a single raw "Body (JSON)" field (see Limitations).
  • Default Base URL: http://localhost (override it in the credential's "Base URL" field to point at a different environment)

File upload/download

Operations whose request body is a multipart/form-data file upload, or whose response is binary (an image, PDF, or other non-JSON file), are generated as a separate node ("...Files") rather than folded into the main one. This is deliberate, not a limitation of the source spec: n8n's declarative request-routing (what the main node is built with, so it needs no hand-written request logic) is confirmed broken for binary payloads -- it JSON-serializes binary data instead of sending real bytes (n8n-io/n8n#17823). The Files node is instead a small, hand-written (programmatic) node using n8n's HTTP helpers directly, which handle binary correctly.

  • Uploads: set "Input Binary Field" to the name of the binary property on the incoming item that holds the file (n8n's convention -- usually data, e.g. from a Read/Write File or HTTP Request node upstream).
  • Downloads: set "Output Binary Field" to the name the downloaded file should be written to on the output item (also usually data, ready for a Read/Write File node or another HTTP call downstream).
  • The Files node shares the exact same credential as the main node.

Using the AI Agent tool

The nodes above are each flagged usableAsTool: true, which is what makes them selectable in an n8n AI Agent's tool list. There is deliberately no second "tool node" file in this package.

n8n does not load tool nodes from disk. When it starts up it derives one from every node that sets usableAsTool, appending Tool to that node's name and display name and switching it to an ai_tool output. So in the node picker you will see the ordinary node plus an automatically derived "... Tool" entry that runs exactly the same operations with exactly the same fields and credentials -- one implementation, two ways to use it. Shipping a hand-written tool node as well would have produced a duplicate "... Tool" action node and then a "... Tool Tool" one, because n8n appends the suffix to anything flagged usableAsTool regardless of what it is already called.

The tool's Description field is what the AI Agent reads when deciding whether to call it. n8n fills that in from the node's own description, and you can override it per tool node in its parameters. It is also a resource/operation-aware field, so an agent that has been told what the API is for can pick the right operation itself.

This needs a reasonably recent n8n, since the AI Agent's support for tool nodes is a newer addition. The one hard requirement is the one already declared in this package's package.json: n8n.n8nNodesApiVersion must be supported by your n8n build, or the whole package is skipped at load with a warning in the n8n logs.

Limitations

  • Only OpenAPI 3.x is supported.
  • Supported authentication: API Key (header or query), HTTP Bearer, HTTP Basic, and OAuth2 (authorization code or client credentials flow only -- not implicit or password grants). Anything else (OpenID Connect, HTTP Digest, mutual TLS) is refused at generation time rather than silently broken.
  • Every supported authentication scheme the spec declares becomes its own credential type and its own entry in the node's Authentication dropdown, rather than one family winning and the rest being dropped. OAuth2, HTTP Basic and API Key/Bearer are different mechanisms in n8n and genuinely cannot be merged into one credential, which is why they are separate choices rather than one combined credential. Only the method selected in the dropdown is sent; the others are not.
  • If some operations can only be authenticated with a scheme this generator does not support (the classic Swagger Petstore spec is a real example -- OAuth2 implicit flow for writes, an API key for some reads), those operations are left out of the node rather than the whole build failing -- see above for which ones, if any. Turning off an authentication method in the spec browser has the same effect for the operations that needed only that method.
  • When an authentication method is injected (added from the generator's own list, because the spec does not declare it), it is added to the spec's security requirements as an additional alternative, so operations that demanded an unsupported scheme become generatable. An operation that explicitly declares security: [] -- "this endpoint is public" -- is left public.
  • A bearer scheme's placement (header name, value prefix, header vs. query) and OAuth2's extra token header cannot be read from an OpenAPI document, because the format has nowhere to put them. They default to the standards (Authorization: Bearer <token>) and can be overridden when injecting a method, or via the credential's Custom Headers for a static value.
  • Request bodies are exploded into individual fields, including nested objects and arrays. What a body became is decided per field:
Spec n8n field you get
string text field
string with enum dropdown of the allowed values
integer / number number field (integers are pinned to 0 decimals)
boolean switch, sending a real true/false rather than the text "true"
array (any contents) a single JSON field -- one expression can supply the whole list
object with declared properties a single JSON field, sent as the nested object it describes
array of such objects a single JSON field holding the whole list
object with no declared properties a raw JSON field
string with format: date date picker
string with format: date-time date/time picker

A body stays a single raw "Body (JSON)" field only when something in it cannot be represented as a field at all: a genuine oneOf/anyOf union of different types, an array with no declared item type, an object nested more than six levels deep, a list of lists of objects, or a body with more than 80 fields. A nullable/optional primitive (anyOf: [{type: 'string'}, {type: 'null'}], as FastAPI/Pydantic emits for Optional[str]) is recognised as simple and gets its own field.

  • An enum with more than 200 possible values stays a plain text field rather than an unusable dropdown.
  • format: date-time becomes a date/time picker, which produces a local YYYY-MM-DDTHH:mm value with no timezone offset. If an endpoint needs the offset, switch that one field to an expression (={{ $now.toISOString() }} and friends).
  • An array-valued query parameter is sent repeated once per value (?id=1&id=2), which is OpenAPI's default explode: true. When the spec says explode: false the values are comma-separated instead. This is one setting per request, so a spec that uses both styles gets whichever the majority of its array parameters asked for.
  • The Files node keeps every field top-level (no "Additional Fields" grouping for optional params, unlike the main node) -- binary operations tend to have few parameters, so this keeps its hand-written execute() logic simpler.
  • Parameters declared on a path item (applying to every operation beneath it) are inherited by each of those operations, as OpenAPI specifies; an operation declaring its own parameter of the same name and location overrides the shared one, exactly as the spec requires.
  • The credential's Custom Headers are not included in its Test request. If this API rejects requests that lack one of them, the Test button fails even though requests through the node succeed.

Regenerating

This package was produced by an automated generator from the source OpenAPI spec. To pick up spec changes, re-run the generator rather than hand-editing the generated files under src/.

Discussion