Legacy Metadata Agent (V0)

Legacy metadata agents (version = 0, the default) use the traditional agent API with MediaContainer for search results and MetadataSearchResult objects.

Agent Base Classes

All agents inherit from one of the following base classes. The base class determines what media type the agent handles.

Agent.Movies

Base class for movie metadata agents.

Agent.TV_Shows

Base class for TV show metadata agents.

Agent.Artist

Base class for music artist metadata agents.

Agent.Album

Base class for music album metadata agents.

Agent.Photos

Base class for photo metadata agents.

Agent Class Attributes

All agent base classes share the following class attributes:

Attribute

Type

Default

Description

name

str

‘Unnamed Agent’

Display name of the agent.

languages

list[str]

[]

List of supported language codes (e.g. [Locale.Language.English]).

primary_provider

bool

True

Whether this agent is a primary metadata provider.

contributes_to

list[str] or None

None

List of agent identifiers this agent contributes to.

accepts_from

list[str] or None

None

List of agent identifiers this agent accepts contributions from.

fallback_agent

str or None

None

Identifier of the agent to fall back to.

persist_stored_files

bool

True

Whether to persist stored media files on disk.

version

int

0

Agent version. 0 = legacy (this chapter), 2 = modern Artist. See modern search API for using modern search objects with V0 agents via the tree parameter.

Note

Agent version vs. PlexFrameworkVersion

The version attribute on an agent class controls the agent API style:

This is not the same as PlexFrameworkVersion in Info.plist, which selects the framework bootstrap version (always "2" for modern plug-ins). See Info.plist keys for details.

search(self, results, media, lang, manual=False, tree=None)

Called when the server needs search results for a media item.

Parameter

Type

Description

results

MediaContainer

Container to append results to. Use results.Append(MetadataSearchResult(...)).

media

Media.Movie, Media.TV_Show, Media.Artist, Media.Album, etc.

Media hints object with information from the scanner (name, year, etc.). The concrete type depends on the agent base class.

lang

str

Language code for the search.

manual

bool

True if the user initiated the search manually.

tree

MediaTree or None

Keyword argument. When present in the method signature, the framework switches to modern search objects — see Using the tree Parameter below.

Optional parameters (passed if the function signature accepts them):

Parameter

Type

Description

primary

bool

True if this is the primary agent for the library, False if contributing.

Contributing agent attributes — When an agent contributes_to another agent, the media object in search() also has:

Attribute

Type

Description

primary_metadata

model instance or None

The primary agent’s existing metadata object (e.g. Movie, TV_Show, etc.). None if this is the primary agent.

primary_agent

str or None

Identifier string of the primary agent. None if this is the primary agent.

Example:

results.Append(MetadataSearchResult(id='123', name='Movie Title', year=2020, score=95, lang=lang))

Results are automatically sorted by year and then by score (descending).

Using the tree Parameter

The framework inspects your search() function signature at startup. If the method declares a tree keyword argument, the framework automatically switches to the modern search API for that agent:

  • results is passed as an ObjectContainer instead of a MediaContainer.

  • tree receives a MediaTree built from the database, providing the full file and stream hierarchy for the item.

  • Use results.add(SearchResult(...)) instead of results.Append(MetadataSearchResult(...)). SearchResult accepts id, name, year, score, type, and parentName.

This works for all agent types — Movies, TV Shows, Albums, and Photos — without changing version. The update() method signature and behaviour are unaffected.

Example — Movie agent with tree:

class MyMovieAgent(Agent.Movies):
    name = 'My Movie Agent'
    languages = [Locale.Language.English]
    primary_provider = True

    def search(self, results, media, lang, manual=False, tree=None):
        results.add(SearchResult(
            id='12345',
            name=media.name,
            year=int(media.year),
            score=100,
        ))

    def update(self, metadata, media, lang, force=False):
        metadata.title = 'Movie Title'
        metadata.year = 2020

update(self, metadata, media, lang, force=False)

Called when the server needs metadata for a matched item.

Parameter

Type

Description

metadata

Movie, TV_Show, Artist, Album, etc.

The metadata model instance to populate. The concrete type depends on the agent base class.

media

Media.Movie, Media.TV_Show, Media.Artist, Media.Album, etc.

The media information. In update(), this is a MediaTree with file info, parts, and streams.

lang

str

Preferred language code.

force

bool

True if the user forced a metadata refresh.

Optional parameters (passed if the function signature accepts them):

Parameter

Type

Description

periodic

bool

True if this update was triggered by a periodic refresh.

prefs

dict

Library section preferences (music agents). Keys include: artistBio, albumReviews, popularTracks, concerts, genres, albumPosters; values are integers (0 or 1).

Example Agent

class MyMovieAgent(Agent.Movies):
    name = 'My Movie Agent'
    languages = [Locale.Language.English]
    primary_provider = True
    contributes_to = ['com.plexapp.agents.imdb']

    def search(self, results, media, lang):
        results.Append(MetadataSearchResult(
            id='12345', name=media.name, year=media.year, score=100, lang=lang
        ))

    def update(self, metadata, media, lang):
        metadata.title = "Movie Title"
        metadata.year = 2020
        metadata.summary = "A great movie."
        metadata.genres.add("Action")
        metadata.directors.new().name = "John Director"

        role = metadata.roles.new()
        role.name = "Jane Actor"
        role.role = "Lead"
        role.photo = "https://example.com/photo.jpg"

        metadata.posters['poster_url'] = Proxy.Media(
            HTTP.Request('https://example.com/poster.jpg').content
        )

Media Types

Media types represent the information provided by the scanner for each media item. In search(), the media parameter is a MediaObject with hint attributes. In update(), the media parameter is a MediaTree with file information.

Media.Movie

Attribute

Type

Description

name

str

The detected movie name.

year

str

The detected year.

openSubtitlesHash

str

Hash for OpenSubtitles lookups.

duration

str

Duration in milliseconds.

id

str

Database ID.

items

list[MediaItem]

Media items with parts/streams.

Media.TV_Show

Attribute

Type

Description

show

str

The show name.

season

str

Season number.

episode

str

Episode number.

name

str

Episode name.

year

str

Year.

duration

str

Duration.

episodic

bool

Whether it’s episodic (default True).

seasons

dict[str, MediaTree]

Dict of season indices → season MediaTree objects.

Each season MediaTree has an episodes dict of episode indices → episode MediaTree objects. Each episode MediaTree has an items list of MediaItem.

Media.Artist

Attribute

Type

Description

artist

str

Artist name.

album

str

Album name.

track

str

Track name.

index

str

Track index.

albums

dict[str, MediaTree]

Dict of album GUIDs → album MediaTree objects.

Media.Album

Attribute

Type

Description

name

str

Album name.

artist

str

Artist name.

album

str

Album name.

track

str

Track name.

index

str

Track index.

parentGUID

str

GUID of the parent artist.

parent_metadata

Artist or None

Parent artist’s metadata (loaded from parentGUID).

tracks

dict[str, MediaTree]

Dict of track indices → track MediaTree objects.

MediaTree

A tree structure representing the hierarchical media structure for a library item. Media objects (e.g. Media.Movie, Media.TV_Show) delegate attribute access to the underlying MediaTree, so properties like items, seasons, and episodes are accessible directly on the media object.

Attribute

Type

Description

items

list[MediaItem]

Media items at this level of the tree.

settings

dict

Settings associated with this item.

children

list[MediaTree]

Child MediaTree nodes.

Additional attributes vary by level. For a TV show tree, season-level nodes have an episodes dict, and episode-level nodes have items. All XML attributes from the server are also set as properties (e.g. title, year, originally_available_at).

all_parts() → list[MediaPart]

Returns a flat list of all MediaPart objects owned by this node and all its descendants.

MediaItem

Represents a single media file grouping.

Attribute

Type

Description

parts

list[MediaPart]

List of media parts.

MediaPart

Represents a single file of a media item.

Attribute

Type

Description

file

str

Absolute path to the media file.

hash

str

SHA1 hash of the file.

size

long

File size in bytes.

streams

list[MediaStream]

List of media streams.

thumbs

dict-like

Directory for thumbnail images. Supports item in thumbs, thumbs[item] (read bytes), thumbs[item] = data (write bytes).

art

dict-like

Directory for art images. Same interface as thumbs.

subtitles

dict-like

Directory for subtitles, keyed by language code. Access: subtitles[lang_code][name] = Proxy.*.

openSubtitlesHash

str

OpenSubtitles hash (if available).

MediaStream

Represents a single audio, video, or subtitle stream within a part.

Attribute

Type

Description

type

long

Stream type: 1 = Video, 2 = Audio, 3 = Subtitle.

index

long

Stream index.

id

long

Stream ID.

codec

str

Codec name.

language

str

Language name.

languageCode

str

ISO 639 language code.

MetadataSearchResult

A search result object for legacy (V0) agent search() calls. Append these to the results MediaContainer.

MetadataSearchResult(id, name=None, year=None, score=0, lang=None, thumb=None)

Parameter

Type

Description

id

str

Unique ID for this result.

name

str

Display name.

year

int

Release year.

score

int

Match score (0–100).

lang

str

Language code.

thumb

str

Thumbnail URL.