Skip to main content
A connector is data, not code: its whole definition is a ProviderDescriptor — the provider’s OAuth endpoints, its sub-services and scopes, and the env var names that hold the operator’s client credentials. So a connector ships as a descriptor-only plugin: a tai-plugin.yml with no package, delivered by spec. There is nothing to build and nothing to pip-install — publishing the descriptor publishes the whole integration. This page walks the path end to end. For the file-format rules your docs follow, see Author plugin docs; for the model behind the descriptor, see the ProviderDescriptor reference.

Scaffold the plugin

tai plugins init writes a valid, ready-to-edit descriptor tree. A connector needs --authoauth for an OAuth provider, none for a no-auth one:
The written tree parses as a plugin spec and its docs validate as-is, so you edit placeholders rather than start from a blank file. Print the full schema of a tai-plugin.yml anytime with:

Fill the descriptor

Open tai-plugin.yml and replace every placeholder — the acme identifiers, the example.invalid endpoints, and the icon — with your provider’s real values:
tai-plugin.yml
A few rules the model enforces, loud on validation:
  • No package. Omitting it is what makes the plugin descriptor-only. Its delivery derives to descriptor, and installing it touches no environment beyond the config it declares.
  • icon and icon_url are https:// URLs. The catalog serves the brand mark verbatim; there is no bundled asset to host, and a non-https URL is refused.
  • origin matches the namespace. A tai42 listing may claim system; every community listing is community.
  • The connector item name equals provider.id. That id is the manifest key the install patches into the server’s connectors list.
Then write the operator notes in docs/index.mdx — what OAuth client the operator registers with the provider, which scopes it needs, and the redirect URI to configure. Keep it a thin provider page; link platform features to their central docs rather than re-documenting them.

Publish

1

Open a pull request

Commit the filled tree to the plugin’s repository and open a PR. The same docs contract the marketplace enforces runs in CI, so a page that would fail ingest fails the PR first.
2

Tag the release

Tag the version to match tai-plugin.yml (and version.txt, which exists only so release tooling has a version file to read). The marketplace resolves a descriptor listing by its <namespace>-<name> tag component.
3

Seed the listing

The marketplace ingests the tag: for a descriptor it fetches the raw tai-plugin.yml at that tag, records its digest, and lists it with source: spec — no wheel, no PyPI lookup. The listing and its docs/ render under Plugins automatically; you never open a PR against the docs site.
Once listed, an operator installs it like any plugin — supplying their own client credentials — and the server registers the descriptor with no code on the box:
--env KEY=VALUE supplies every value; --secret KEY is a bare mark that hides one (the server also auto-marks the connector’s client_secret_env). See Installing a descriptor-only plugin for what the server does with it.

Checklist

tai plugins init scaffolds every file below; confirm each is filled before you tag:
  • tai-plugin.yml — no package; real namespace/name/version, provider endpoints, scopes, and client_*_env names.
  • README.md — the repository’s own front page.
  • docs/index.mdx — the operator setup notes rendered under Plugins; front matter is exactly title and description.
  • icon.png — the brand-mark image committed in the repo AND published at a raw https:// URL; icon and icon_url both point at that https URL (http, relative, or empty is rejected).
  • version.txt — equals the version in tai-plugin.yml.
  • CHANGELOG.md — Keep-a-Changelog format.
  • LICENSE — the plugin’s license.
  • NOTICE — attributions, including the source of the icon brand mark.

See also