ContentsPackage, sign and publish
  1. API

    1. Using the API
    2. API reference
    3. Emby-compatible API
  2. Plugin SDK

    1. Plugins and built-in features
    2. Capabilities
    3. Quick start
    4. Package, sign and publish

Package, sign and publish

A plugin reaches users through a catalog: a JSON file, served over HTTPS, that lists plugins, their versions and where to download them. The server has an official catalog, and administrators can add third-party catalogs.

On this page
  1. Package
  2. The catalog
  3. Host a third-party catalog
  4. The official catalog and signing
  5. Trademarks

Package#

A package is a tar.gz with, at its root, only these files:

  • the executable, named exactly like the plugin ID (required);
  • optional LICENSE*, README* and NOTICE* files.

Subfolders, links and absolute or .. paths are rejected, and so is any other file. Build a static Linux binary for amd64 and arm64, and compute the SHA-256 of each package. Make builds reproducible where you can (fixed file times and owners in the archive).

The catalog#

{
  "generated": "2026-10-04T00:00:00Z",
  "expires": "2026-11-04T00:00:00Z",
  "plugins": [{
    "id": "my-plugin",
    "name": "My plugin",
    "description": "What it does.",
    "owner": "Your name",
    "homepage": "https://example.com/my-plugin",
    "versions": [{
      "version": "1.0.0",
      "protocol": 1,
      "sdk": "kryspal-plugin/1",
      "minServer": "0.3.0",
      "changelog": "First release.",
      "capabilities": ["metadata.movie"],
      "targets": [{ "os": "linux", "arch": "amd64", "url": "https://example.com/my-plugin-1.0.0-linux-amd64.tar.gz", "sha256": "<64 lowercase hex characters>" }]
    }]
  }]
}
  • The server rejects the whole catalog if any entry is invalid, so check it before you publish. A catalog is at most 4 MiB.
  • minServer is the oldest server version the plugin works with. A server older than that lists the version as not installable and shows the reason. The same happens for a protocol or an operating system and architecture the server does not support.
  • homepage is optional: an absolute HTTPS address (at most 512 characters) shown as a link in the console. Anything else is ignored.
  • A version's version and protocol must match what the plugin's manifest reports. Published versions never change: the same version with a different hash is refused, and versions only go up.
  • A version without the sdk marker counts as built for an older protocol and cannot be installed; it is listed with the reason.
  • capabilities on a version is optional. It lets the console show hints, such as that a feature needs a plan, before installation. After installation the manifest wins.
  • nameI18n and descriptionI18n can carry translations, keyed by language such as zh-TW.
  • Download addresses must be HTTPS.
  • Do not reuse an ID of an official plugin or a reserved ID. The server ignores such entries from third-party catalogs.

Host a third-party catalog#

Put the catalog and the packages on any public HTTPS host. The address must be a public host name: the server refuses addresses with credentials, localhost, private, loopback, link-local and similar addresses, and host names that are not public (single-label names and endings such as .local, .lan and .internal). It checks the address again when it connects and at every redirect, so a name that points at your own network is refused too.

Users add your catalog in the admin console under Plugins → Marketplace → Manage plugin catalogs. The console shows a risk warning first. Your plugins then appear marked Third-party, with the catalog's address, and installing one shows another warning. Updates come from the catalog the plugin was installed from, and only when the administrator presses update.

A third-party catalog is not signed: the server checks each package against the hash in the catalog, and, if the catalog has an expires time, that it has not expired. People who add your catalog trust you, so keep the host and the files under your control.

The official catalog and signing#

The official catalog is at plugins.kryspal.net. It is signed with an Ed25519 key. The signature is detached: a file next to the catalog, with .sig added to the address, that holds the base64 signature of the exact bytes of catalog.json. The server has the public keys built in and accepts the catalog only if one of them verifies it, and the catalog's generated time must not go back and expires must not have passed. The hashes of the packages are inside the catalog, so they are protected by the same signature. The private key is held by the project and never goes into a plugin repository.

Individual packages are not signed by their authors, and the official catalog does not accept author signatures. Packages go in only through the project's review and release process.

Listing in the official catalog is reviewed. The checklist asks for an OSI-approved open-source licence, a public source repository with a tag and a documented reproducible build, a package with only the executable and its notices, permissions that match the behaviour, no telemetry, secrets only through secret fields, a README that states the purpose, settings, outside services and privacy, and a plugin that passes the test kit. Every new version is reviewed again. There is no application form yet; for now, get in touch through the contact page.

Trademarks#

You may say "a plugin for Kryspal Media" or "built with the Kryspal Media Plugin SDK". Do not start a plugin name with "Kryspal", use the logos or claim to be official.