The public catalog of apps that run inside a Cortex
instance. Git-native and metadata-only: this repo holds listing.json files
and checksums — the app artifacts themselves live on each publisher's GitHub
releases, pinned by sha256.
Cortex instances consume the catalog through the aggregated
index.json; admins browse and install from Settings →
Apps → Browse Registry. Every install re-verifies the artifact against the
pinned checksum before anything is unpacked.
schema/app.v1.json the app manifest contract (canonical copy)
schema/listing.v1.json the listing contract
apps/{slug}/listing.json one listing per app (slug == app.json id)
index.json generated catalog (scripts/build-index.mjs)
site/ the browse site + JSON API (Next.js; renders index.json)
ECOSYSTEM.md the master plan for the whole app ecosystem
Build it first — start from cortex-app-template, or point your coding agent at cortexskills.org/builder/app.
Cut a release in your app repo (clean, pushed tree):
npm run package # → {id}-{version}.zip sha256sum {id}-{version}.zip gh release create v{version} {id}-{version}.zip --title "…" --notes "…sha256…" curl -sL <asset url>| sha256sum # verify published == built
Generate the listing (in a checkout of this repo):
node scripts/add-listing.mjs <release zip url> --tags docs,sync # downloads the artifact, extracts the manifest, pins sha256 + size,# writes apps/{id}/listing.json and rebuilds index.json
(Apps built from the template release with
git tag v{version} && git push --tags— the shipped workflow builds, validates, and attaches the zip automatically.)Or write the listing by hand —
apps/{your-id}/listing.json:Then regenerate the catalog:
node scripts/build-index.mjs.Open a PR. CI is the floor, review is the gate (REVIEWING.md). The workflow re-downloads your artifact, re-verifies the sha256 and size, checks the zip's embedded
app.jsonequals your listing's manifest, and validates both schemas. A human reviews what the app declares (key scope, endpoints, external hosts, capabilities) before merge.Update the catalog docs. CI also checks that every active listing is mentioned in the ecosystem's three catalog docs — cortex-app's handbook ch. 24 and apps docs page, and cortex-skills' apps skill — so the registry can't silently outgrow the documentation. Merge those doc PRs before (or alongside) the listing PR; the check reads each repo's
main.
New versions: new tag + new zip + a PR bumping app.version and the
artifact block. Never replace the asset under an existing tag — the pinned
digest is the trust anchor.
Yanking: a listing is never deleted; set "status": "yanked" (+
yankedReason) via PR. Instances stop offering yanked apps for install.
node scripts/validate-listings.mjs # full check incl. artifact download
node scripts/validate-listings.mjs --offline # shape/manifest checks only
node scripts/build-index.mjs --check # is index.json current?
node scripts/conformance.mjs # manifest rules vs the shared corpus
node scripts/check-docs-drift.mjs # catalog docs cover every active listing# not-yet-pushed doc edits: CORTEX_APP_DIR=… CORTEX_SKILLS_DIR=… node scripts/check-docs-drift.mjsCI runs all of this on every PR and on a weekly schedule — so a deleted or replaced release asset surfaces here, not at someone's install.
conformance/manifests.json is the shared floor of manifest rules, enforced
by three independent implementations: this repo's validator, the app
template's validate.mjs, and cortex-app's server-side validate_manifest.
Each repo's CI runs its own consumer against the corpus — a rule change that
reaches only one implementation fails the other two. Changing a manifest
rule therefore means: update all three implementations and add a corpus
case here.
- sha256-pinned artifacts — the listing commits to exact bytes; CI and every installing instance verify independently.
- Manifest transparency — the listing carries the manifest verbatim, so what an admin approves in the browser is what the zip contains (CI proves the equality).
- Least privilege is visible — key scope, endpoint allowlist, external hosts, and capabilities are all in the listing for review before install.
- Reserved for later: publisher signing (
signaturesin the manifest schema), x402cortexes/directory, monetized listings.
{ "app": { /* your app.json, VERBATIM (minus $schema) */ }, "artifact": { "url": "https://github.com/you/your-app/releases/download/v1.0.0/your-app-1.0.0.zip", "sha256": "…64 hex chars…", "size": 123456 }, "repo": "https://github.com/you/your-app", "tags": ["…"], "screenshots": [], "listedAt": "2026-07-20", "status": "active" }