Skip to main content

Manifest Reference

Every plugin artifact ships a manifest.json at its root. Prismedia reads it to decide whether the plugin can load, which runtime executes it, and which entity kinds and identify actions it serves.

  • Filename: manifest.json
  • Format: JSON
  • Contract: apps/backend/src/Prismedia.Contracts/Plugins/PluginManifest.cs

Example

{
"manifestVersion": 2,
"apiTags": ["prismedia"],
"id": "openlibrary",
"name": "Open Library",
"version": "0.3.0",
"runtime": "dotnet-process",
"entry": "dist/Prismedia.Plugin.OpenLibrary.dll",
"compat": {
"pluginApiMin": "2.0.0",
"pluginApiMax": null,
"prismediaMin": "1.0.0",
"prismediaMax": null
},
"auth": [],
"isNsfw": false,
"supports": [
{
"entityKind": "book",
"actions": ["lookup-id", "lookup-url", "search"],
"identityNamespaces": ["openlibrary", "openlibrarywork", "isbn"],
"search": {
"fields": [
{ "key": "title", "label": "Title", "type": "text", "required": true },
{ "key": "author", "label": "Author", "type": "text", "required": false },
{ "key": "year", "label": "First published", "type": "year", "required": false }
]
}
},
{
"entityKind": "person",
"actions": ["lookup-id", "lookup-url", "search"],
"identityNamespaces": ["openlibraryauthor"],
"search": {
"fields": [
{ "key": "title", "label": "Author", "type": "text", "required": true }
]
}
}
]
}

Fields

FieldTypeNotes
manifestVersionnumberManifest schema version. New plugins use 2; version 1 is read only for compatibility.
apiTagsstring[]Generation tags; Prismedia ignores artifacts without the prismedia tag so older plugin systems can coexist in one index.
idstringStable provider/plugin code, e.g. tmdb. Unique across the registry.
namestringHuman-readable plugin name.
versionstringArtifact SemVer.
runtimestringRuntime code — see Runtimes.
entrystringEntry artifact path, relative to the manifest directory when not rooted.
compat.pluginApiMin / compat.pluginApiMaxstring / string?Plugin-protocol version bounds. null max means "no upper bound".
compat.prismediaMin / compat.prismediaMaxstring / string?Prismedia application version bounds.
authobject[]Credential fields the plugin requests — see Auth fields.
isNsfwbooleanWhether imported metadata should be marked NSFW by default.
supportsobject[]Entity kinds and identify actions the plugin serves — see Entity support.

Runtimes

Runtimeentry meaningHow it runs
dotnet-processCompiled plugin assembly, e.g. dist/MyPlugin.dll.Executed by the .NET plugin process runner.
stash-compatA standard Stash YAML scraper definition.Executed natively by Prismedia's Stash-compat engine. You normally never write this manifest by hand — installing a scraper from the CommunityScrapers index synthesizes it (with a stash- id prefix). See Stash Compatibility.

Auth fields

Each entry in auth declares one credential the plugin wants:

FieldTypeNotes
keystringStable credential key passed to the plugin process. Unique within the array.
labelstringLabel shown in plugin settings.
requiredbooleanWhen true, identify actions are blocked until the credential is saved.
urlstring?Optional upstream page where users create or manage the credential.

Users fill these in under Plugins → Installed → credentials; values are stored server-side and injected at execution time.

Entity support

Each entry in supports is a complete routing declaration for one Prismedia entity kind. It tells the core which actions the plugin can execute, which persistent upstream identities it can resolve, and which fields its search UI requires:

FieldTypeNotes
entityKindstringStable entity kind code, e.g. book, person, video-series.
actionsstring[]Action codes: lookup-id, lookup-url, and search. Structural children are returned in the proposal when Prismedia sets includeStructuralChildren; cascade is not an action.
identityNamespacesstring[]Canonical lowercase external identity namespaces this kind can resolve, e.g. tmdb, tmdbepisode, or openlibrarywork. Required in manifest v2.
searchobject?Ordered plugin-owned search form. Required exactly when actions includes search.

The identify pipeline only routes work to a plugin for kind/action pairs it declares here, and the provider pickers in the UI filter on the same data.

Plugin id versus external identity

The manifest id identifies the installed executable. An identity namespace identifies an upstream record. They are deliberately independent: a plugin whose id is cinema-metadata may resolve { "namespace": "tmdb", "value": "83867" }.

Identity namespaces are normalized lowercase. Identity values are opaque, case-sensitive strings and may contain colons. Never lowercase, split, or reinterpret a value in the core. If a structural child does not have a native upstream id, the plugin must define a stable composite namespace/value that a context-free lookup-id can resolve back to the same child.

The order of identityNamespaces is meaningful when a proposal carries more than one accepted identity: Prismedia selects the first declared namespace present on that proposal. Put the most specific round-trippable identity first.

Search schema

search.fields is an ordered array. Prismedia renders it directly and sends the submitted values in IdentifyQuery.fields; the core does not know keys such as seriesTitle, author, or album.

FieldTypeNotes
keystringStable plugin-owned key. Unique within this kind's form.
labelstringHuman-readable input label.
typestringtext, number, or year.
requiredbooleanWhether a non-empty value is required.
placeholderstring?Optional concise example.
helpstring?Optional explanatory copy.

Plugins should read query.fields and continue accepting query.title as a compatibility fallback. A field used only during search must not imply that its value will still exist during a later identity-only review. Anything required to rehydrate a selected result belongs in its persistent identity.

Round-trip requirement

Every identity emitted by a search candidate or structural proposal must pass the same test:

  1. take the proposal's entity kind plus chosen namespace/value;
  2. issue a context-free lookup-id to the same plugin;
  3. receive the same entity kind and the exact case-sensitive identity.

This is what makes monitoring, request review, revision validation, and future background enrichment independent of the original search session.

Compatibility gating

At load time Prismedia checks manifestVersion, apiTags, and the compat bounds against its own plugin-protocol and application versions. Artifacts that fail any check are listed as incompatible instead of loading. Publishing details live in Publishing.