Skip to main content
How a plugin gets into the marketplace: what the registry reads, what a release has to look like, and what happens between pushing a tag and the listing going live.
The registry is curated. There is no publisher account, no submission form, and no self-serve claim: a namespace exists because an operator seeded a listing under it, and every listing today sits under the tai42 namespace at the official trust tier. Adding a repository to the registry is an administrative action on the registry itself.

The descriptor

Every plugin describes itself in a tai-plugin.yml file at the repository root, shipped inside the built wheel as well. It is the single artifact the registry reads — the registry never downloads or unpacks the package to learn what it contains.
tai-plugin.yml
Each entry in provides carries a kind (tool, agent, extension, connector, channel, backend, storage, monitoring, webhook-verifier, config, identity, studio-plugin, router, or middleware), a name, the module that registers it, and a one-line description. The kind is what tells an installer which manifest field the item wires into — see the plugin descriptor.
The parser is strict on purpose: unknown keys, YAML anchors, duplicate keys, a file over 256 KiB, or a non-UTF-8 file are all rejected rather than interpreted. permissions is declarative metadata shown to installers — it is not a sandbox.

Cut a release

The registry resolves a version’s artifact from PyPI when the distribution is there, so the release order is: publish the distribution, then push the tag the registry watches.
  1. Bump version in both pyproject.toml and tai-plugin.yml to the same value.
  2. Push tag v<version>. The shipped release workflow asserts the tag matches the project version, builds with uv build, and uploads to PyPI.
  3. The registry normalises the tag by stripping one leading v, so v0.2.0 must match version: 0.2.0 in the descriptor.

What the registry does with it

A registered repository’s tag push reaches the registry as a GitHub webhook, and the whole publish happens inside that one request — there is no queue, no worker, and no scheduled crawl.
1

Verify the delivery

The HMAC signature is checked against the registry’s webhook secret before anything else is read. A push that is not a tag is acknowledged and ignored.
2

Resolve the listing

The repository URL is matched to a registered listing. An unknown repository is rejected — this is where “curated” is enforced.
3

Read the descriptor at the tag

tai-plugin.yml is fetched at the pushed tag and validated. The registry then cross-checks that its namespace, name, and package still match the listing, so a registered repository cannot publish into someone else’s namespace.
4

Resolve the artifact

The distribution is looked up on PyPI. When it is there, the version’s artifact reference and its SHA-256 are recorded and the listing’s source is pypi; when it is not, the source is github and the version carries no artifact pointer.
5

Render and store

The README is rendered to sanitised HTML, the version row is written with its items and its full descriptor, and the listing’s displayed metadata follows if this version is now the latest.
Ingest refuses, loudly, when the descriptor fails validation, when a category is outside the registry’s vocabulary, when contract is not a parseable specifier set, when the tag does not normalise to the descriptor’s version, or when that version has been killed. A killed version is terminal: re-pushing the tag does not resurrect it. A distribution absent from PyPI is not a refusal — the version is simply recorded as a github source.

Advisories

An advisory marks a version range of a listing as unsafe. Filing one is a registry-administrator action, and there is no reporting route for publishers or users — report a problem to the registry’s maintainers. An advisory carries the listing ref, an affected_versions specifier set, a severity of low, medium, high, or critical, and a one-line summary. Withdrawing one keeps the row and stamps it withdrawn, so consumers that already saw it also see the withdrawal. Servers poll the public advisories feed and surface matches against what they have installed — Advisories covers the client side and its poll setting. A kill switch is the sharper tool: it marks a version unpublishable rather than merely warning about it.

See also