- Python 100%
|
Some checks are pending
CI / validate (push) Waiting to run
Match published release used by the host MVP binary after offline Dispatch/ImportPath cut. Co-authored-by: Cursor <cursoragent@cursor.com> |
||
|---|---|---|
| .github/workflows | ||
| scripts | ||
| tags | ||
| .gitignore | ||
| catalog.json | ||
| LICENSE | ||
| README.md | ||
| SECURITY.md | ||
MuxCore Official Spool
This is the official module spool for MuxCore. Add this repository URL to your MuxCore instance to discover official modules and tags.
URL
https://github.com/Muxcore-Media/spool
Tags
Tags are curated module presets — a named set of modules that work together. Pull a tag to load its modules:
# Start MuxCore with the default tag from the official spool
muxcored --tag default
# Use a minimal preset
muxcored --tag minimal
# Media libraries + scanner / roots (fixture-friendly)
muxcored --tag media
# Fixture-first library ingest (no live indexer)
muxcored --tag acquisition
# Optional music/books (+ comics/audiobooks) libraries — not in default/media
muxcored --tag library-plus
Available Tags
| Tag | Description |
|---|---|
default |
Admin UI, REST API, local auth, SQLite, cache-local, call/publish policy defaults, encryption, secrets, health monitoring, rate limiting, cron scheduler, tapestry workflow |
minimal |
Bare essentials: admin UI, REST API, local auth, SQLite, encryption, secrets, health monitoring |
media |
TMDB metadata, movie/TV libraries, automation, call/publish policies, scanner, roots, Jellyfin |
acquisition |
Fixture-first ingest: scanner, root folders, optional list sync — no Pirate Bay / Torznab pin |
library-plus |
Optional: media-music + media-books (required), media-comics + media-audiobooks (optional) — not part of default/media |
workflow |
Optional: workflow-tapestry DAG engine — also listed optional on default; opt in with --tag workflow |
cache-redis |
Optional: swap to cache-redis (shared Redis) — not default; do not combine with cache-local |
secrets-vault |
Optional: swap to secrets-vault (Vault/OpenBao / cloud mocks for CI) — not default; do not combine with secrets-file |
Every module entry in a tag pins an explicit published semver (vX.Y.Z) that must match catalog.json. Floating latest is rejected by validation.
worker-pool-memory remains in catalog.json but is deprecated (prefer core’s built-in worker pool).
Fixture-first acquisition
Laptop demos and product gates use fixture / offline acquisition — not live pirate indexers or BitTorrent swarms.
acquisitionpins only library ingest helpers (media-scanner,media-root-folders, optionalmedia-list-sync). It does not requireindexer-piratebay, Torznab, or a live downloader.mediaadds libraries, automation, and metadata. It also omits live indexer defaults.- Pair either tag with the installer /
_mvpdefaultDOWNLOADER_ENGINE=fixturewhen you need a completed download without a swarm. - Leave
PIRATEBAY_API_BASE/ Torznab URLs unset. Operators who want live indexers must opt in outside these presets (and keep that path out of CI/smoke gates).
export DOWNLOADER_ENGINE=fixture # installer / _mvp default
muxcored --tag acquisition # ingest helpers only
# or:
muxcored --tag media # libraries + automation, still no live indexer pin
Optional library-plus
Music, books, comics, and audiobook managers stay out of default / media so laptop movie/TV demos stay lean. Pull them explicitly:
muxcored --tag library-plus
| Module | Pin | Role in tag |
|---|---|---|
media-music |
v0.1.0 (catalog) |
required |
media-books |
v0.1.0 (catalog) |
required |
media-comics |
v0.1.0 (catalog) |
optional (required: false) |
media-audiobooks |
v0.1.0 (catalog) |
optional (required: false) |
Pins are the published catalog semver tags. For MuxCore monorepo / workspace demos, you may load the sibling checkouts under media-music/, media-books/, media-comics/, and media-audiobooks/ at those same versions instead of fetching GitHub release artifacts — keep pin strings aligned with catalog.json so scripts/validate.py stays green.
Optional workflow
muxcored --tag workflow
Loads workflow-tapestry (v0.1.6). Also present as required: false on the default tag.
Optional cache-redis
Default keeps cache-local. For multi-host / durable shared cache:
muxcored --tag cache-redis
Do not combine with cache-local in the same mesh. CI in the cache-redis repo uses miniredis for unit tests and optional redis:7-alpine for a live round-trip.
Optional secrets-vault
Default / minimal keep secrets-file. Swap to Vault/OpenBao (or other backends) with:
muxcored --tag secrets-vault
Do not combine with secrets-file in the same mesh. Local OpenBao Docker smoke lives in the secrets-vault repo (deploy/run-openbao-smoke.sh).
Schema validation
scripts/validate.py checks catalog.json and tags/*.json (required fields, unique repos, semver pins matching the catalog, and no live indexer peers in curated tags). CI runs it on self-hosted runners:
SKIP_REMOTE=1 python3 scripts/validate.py
Omit SKIP_REMOTE (or leave it unset) to also warn when catalog pins are missing as GitHub release tags.
Secrets backends
Preset tags (default, minimal) pin secrets-file for local encrypted-file secrets. Optional tag secrets-vault pins secrets-vault (v0.1.1) for Vault/OpenBao (local Docker smoke), Infisical, AWS Secrets Manager, GCP Secret Manager, or Azure Key Vault. Not part of default/minimal — opt in with --tag secrets-vault. Never run both secrets modules (one secrets capability per mesh). secrets-vault does not embed a secrets server; point env at OpenBao/Vault or your provider (cloud backends are mock-only in unit tests).
Cache backends
Preset tags default (and laptop demos) pin cache-local (v0.1.1) for a process-local in-memory CacheLayer (cache.local, plus legacy cache.memory alias). Optional tag cache-redis pins cache-redis (v0.1.5) when you need a shared Redis. Not part of default/minimal — opt in with --tag cache-redis. Never run both cache modules (one cache capability per mesh).
muxcored --tag cache-redis
Tag Definition Format
Tags live in tags/<name>.json:
{
"name": "default",
"description": "The official MuxCore starter setup",
"version": "2.1.0",
"modules": [
{
"repo": "https://github.com/Muxcore-Media/admin-ui",
"version": "v0.1.0",
"required": true
}
]
}
required: true— core refuses to start without this modulerequired: false— core starts without it but logs a warning
For Third-Party Spools
Anyone can create a spool. Create a repo with a catalog.json and tags/ directory. Users add your repo URL to their MuxCore instance with --spool <url>.
Security Warning
Third-party spools are untrusted. Modules run with the same privileges as the core process. See SECURITY.md for the full security disclaimer.
Module Repo Requirements
Each module repo must have a muxcore.json at its root with:
{
"name": "Module Name",
"description": "What it does",
"version": "1.0.0",
"icon": "https://...",
"author": "Author Name",
"kind": "example",
"capabilities": ["example.capability"],
"dependencies": [],
"homepage": "https://github.com/org/repo"
}
Contract Declarations (Required for Third-Party Modules)
If your module uses contract repos that are not from the Muxcore-Media GitHub organization, declare them in muxcore.json under contracts:
{
"name": "My Custom Module",
"kind": "example",
"capabilities": ["example.custom"],
"contracts": [
{
"repo": "github.com/my-org/contracts-example",
"version": "v2.0.0",
"interface": "Example"
}
]
}
How Contract Reconciliation Works
MuxCore uses Go's nominal type system for compile-time safety. Two interfaces with identical method sets but different package paths (e.g., github.com/my-org/contracts-example.Downloader vs github.com/Muxcore-Media/contracts-example.Example) are different types in Go.
When MuxCore tooling reconciles a module with non-canonical contracts:
- The reconciler (
contracts-reconciler) fetches both the third-party contract repo and the canonical Muxcore-Media equivalent - It parses both Go source files and extracts interface method signatures via AST
- If the method sets are structurally identical, it generates a
go.mod replacedirective that normalizes the import to the canonical path - If they differ, the import is rejected with a detailed mismatch report
This preserves compile-time type safety while keeping the MuxCore philosophy: contracts are patterns, not org-bound dependencies.
Requirements for Contract Repos
Third-party contract repos must define interfaces with structurally identical method signatures to the canonical equivalents. Only method names, parameter types, and return types are compared — package paths, comments, and embedded interfaces are ignored.
Recommended: Use Go type aliases to avoid reconciliation entirely:
package example
import "github.com/Muxcore-Media/contracts-example"
// This IS the same type — no reconciliation needed
type Example = contracts_example.Example
Modules that use type aliases don't need contract declarations — the Go compiler already sees them as the canonical types.