Public Go SDK for building Silo plugins. Not a runtime plugin — this is a library that plugin authors depend on via go.mod.
silo-plugin-sdk is the source of truth for the plugin authoring contract. First-party consumers (Silo host, silo-plugin-tmdb, silo-plugin-metadb, every other plugin in this repo) pin tagged semver releases. Local multi-repo workspaces may use go.work or a temporary replace, but CI and release builds resolve the SDK from a published module tag.
github.com/Silo-Server/silo-plugin-sdk/pkg/pluginproto/silo/plugin/v1— generated protobuf code.github.com/Silo-Server/silo-plugin-sdk/pkg/pluginsdk/capability— stable capability type constants for manifests and peer discovery.github.com/Silo-Server/silo-plugin-sdk/pkg/pluginsdk/config— config-schema helpers.github.com/Silo-Server/silo-plugin-sdk/pkg/pluginsdk/convert— type conversions.github.com/Silo-Server/silo-plugin-sdk/pkg/pluginsdk/manifest— manifest loading/rendering.github.com/Silo-Server/silo-plugin-sdk/pkg/pluginsdk/runtime—manifestsubcommand +Runtimeserver scaffolding.github.com/Silo-Server/silo-plugin-sdk/pkg/pluginsdk/runtimedefault— defaultRuntimeimplementation withBindHostBrokeralready wired; embed it to skip boilerplate.github.com/Silo-Server/silo-plugin-sdk/pkg/pluginsdk/runtimehost— typed client for the host'sRuntimeHostservice, including event publishing, host info, catalog browsing, installed-plugin discovery, scoped streams, plugin-to-plugin HTTP calls, and plugin-owned config writes.
The SDK ships protobuf contracts for every capability the host understands:
metadata_provider.v1media_analyzer.v1scheduled_task.v1event_consumer.v1auth_provider.v1http_routes.v1request_router.v1audiobook_backend.v1ebook_backend.v1
Plugins implement one or more, advertise them in manifest.json, and serve them over gRPC.
A typical plugin:
- Defines a
manifest.jsonusing the protobuf-derived schema. - Exposes a
RuntimegRPC server plus one or more capability servers. - Supports the
manifestsubcommand viapkg/pluginsdk/runtimeso the host can introspect manifests without launching the plugin. - Is installed either from a catalog or by uploading a trusted binary to a Silo server.
For a minimal self-describing plugin, see examples/hello-scheduled-task. For a plugin that calls back into the host via RuntimeHost (publishing events, listing libraries), see examples/hello-runtime-host.
Plugins talk to the host through the RuntimeHost service, accessed via pkg/pluginsdk/runtimehost.Client. The host invokes Runtime.BindHostBroker on startup so plugins can dial back over the shared broker; runtimedefault handles that step for you. Available RPCs:
PublishEvent/PublishEventTo/PublishEventToInstallation— fire events into the host's bus, broadcast, addressed to a stableplugin_id, or addressed to one specific installation.GetHostInfo— read host URL metadata for callback URLs and external-facing plugin links.ListLibraries— enumerate libraries the operator has configured.CheckMediaPresence— ask whether a given external id is already in the catalog.ListInstalledPlugins— discover sibling plugins (e.g. routers a request plugin can target).ListLibraryMedia/GetCatalogStats— read public-safe catalog rows and aggregate counts.ResolveCatalogImageURLs— resolve stored poster/backdrop image paths into host-generated browser URLs.MintScopedStream— create short-lived, narrowly scoped stream grants for guest/public workflows.CallPluginHTTP— invoke another installed plugin'shttp_routes.v1handler through the host control plane.SetGlobalConfigEntry— persist plugin-owned config that admins didn't set via the manifest form.
For plugin-to-plugin JSON calls, prefer the helper layer:
plugins, err := host.ListInstalledPluginsByCapability(ctx, capability.RequestRouter)
if err != nil || len(plugins) == 0 {
return err
}
var out struct {
Accepted bool `json:"accepted"`
}
err = host.CallPluginJSON(ctx, runtimehost.CallPluginJSONRequest{
InstallationID: int(plugins[0].GetInstallationId()),
Path: "/api/request",
Request: map[string]any{"title": "The Matrix"},
Response: &out,
})The auth_provider.v1 capability also exposes OAuth-flow RPCs (InitAuthorize, ExchangeCode, RefreshSession) for plugins that wrap external identity providers.
Direct binary upload works best when the plugin embeds a manifest template and computes its own executable checksum at runtime before returning Runtime.GetManifest. That keeps the plugin installable without requiring a checked-out Silo repository or a sibling manifest.json file at upload time. The example plugin shows the pattern.
Compatibility and versioning expectations are documented in docs/compatibility.md.
SDK releases are cut from semver tags such as v0.1.0 and published through GitHub Actions.
- Additive public API changes belong in a new minor release.
- Compatible fixes and documentation updates belong in a patch release.
- Breaking public API, protobuf, or manifest contract changes require a new major version.
Before downstream repos stop using local workspace overrides, the required SDK commit must be pushed and tagged here first.
make proto # regenerate protobuf code (uses locally vendored buf under ./bin/)
go test ./...Apache-2.0. See LICENSE.