How to Version Your OpenAI Plugin and Handle Updates

OpenAI plugins use a version field in the .app.json manifest file that follows semantic versioning (MAJOR.MINOR.PATCH), allowing you to manage breaking changes, maintain compatibility, and publish updates via the opencode CLI while tracking execution versions through run_manifest.json.

Managing versions is essential for maintaining stable integrations. In the openai/plugins repository, every plugin defines its contract through a manifest file located at .app.json in the plugin directory. This guide explains how to version your plugin and handle updates using semantic versioning principles and the OpenAI publishing toolchain.

Understanding the Plugin Manifest Structure

The version Field in .app.json

Every plugin contains a .app.json manifest file that serves as the authoritative source of truth for versioning. For example, in plugins/zoom/.app.json, the version field declares the current release:

{
  "name": "Zoom SDK",
  "description": "Interact with Zoom meetings via the Zoom App SDK",
  "version": "0.16.0",
  "manifest_version": "v1",
  "api": {
    "openapi": "openapi.yaml"
  },
  "auth": {
    "type": "oauth",
    "authorization_url": "https://zoom.us/oauth/authorize"
  }
}

The version field must follow semantic versioning format. When you publish, the opencode CLI reads this field to identify the release.

Semantic Versioning Rules

OpenAI plugins follow strict semantic versioning to communicate compatibility guarantees:

  • MAJOR: Increment when introducing breaking API or schema changes, such as removing endpoints or changing required authentication flows.
  • MINOR: Increment when adding backwards-compatible features, such as new optional fields or additional routes.
  • PATCH: Increment for bug fixes, documentation updates, or internal changes that do not affect the external contract.

How to Version Your Plugin

Updating the Manifest Version

When releasing changes, modify the version field in your plugin's .app.json file according to the nature of your changes. For example, bumping from 0.16.0 to 0.17.0 indicates new features, while 0.16.0 to 0.16.1 indicates a patch.

Always synchronize this update with changes to your openapi.yaml file referenced in the api.openapi field. The OpenAPI specification must accurately reflect the capabilities and schema of the version declared in the manifest.

Syncing with the OpenAPI Specification

The api field in .app.json points to your OpenAPI specification (typically openapi.yaml). Keep these files in lockstep:

  1. Update the OpenAPI spec to reflect new endpoints or schema changes.
  2. Bump the version in .app.json using semantic versioning rules.
  3. Ensure breaking changes in the OpenAPI spec correspond to a MAJOR version bump.

Handling Plugin Updates

The Update Workflow

Follow this systematic approach when releasing updates to your plugin:

  1. Bump the version in plugins/<your-plugin>/.app.json.
  2. Update the OpenAPI spec (openapi.yaml) to reflect any new or changed endpoints.
  3. Add migration notes in README.md or a dedicated MIGRATION.md describing what changed and how callers should adapt.
  4. Run the plugin test suite against the new version to catch breaking changes early.
  5. Publish the new version using the opencode CLI.
  6. Monitor usage metrics and error logs; release a hot-fix (PATCH) quickly if needed.

Managing Breaking Changes

When you must introduce breaking changes, implement these strategies to minimize disruption:

  • Maintain legacy versions: Keep the old version alive for at least one release cycle to prevent immediate failures for existing users.
  • Provide deprecation windows: Announce deprecation at least 30 days before removing functionality, giving consumers time to migrate.
  • Use feature flags: Implement runtime flags or fallback routes that allow existing clients to continue operating while they update their integrations.

Version-Drift Detection

The repository includes support for run_manifest.json, which records the exact plugin version used for each execution. This enables you to audit which version produced a particular result and trigger re-runs if you upgrade. As documented in the NGS-Analysis plugin's README at line 292, the manifest captures the plugin version used during execution, allowing you to track version drift across your deployments.

Publishing New Versions

Using the opencode CLI

The root-level opencode.json configures the publishing toolchain. Deploy new versions using the CLI from your plugin root directory:

opencode publish --manifest plugins/zoom/.app.json

The CLI reads the version field from the specified manifest and pushes the new bundle to the OpenAI Plugin Registry. Ensure your opencode.json is properly configured at the repository root to authenticate with the registry.

Implementing Version-Aware Routing

For plugins supporting multiple versions simultaneously, implement version checking in your middleware. This Node.js example routes requests based on the x-plugin-version header:

// version check middleware (Express)
app.use((req, res, next) => {
  const requested = req.headers['x-plugin-version'] || '0.0.0';
  if (semver.lt(requested, '0.16.0')) {
    // Old version – route to legacy handler
    return legacyRouter(req, res, next);
  }
  next(); // New version – normal handler
});

Documenting Migrations

Create clear migration guides in your plugin's documentation. Use this structure in your README.md or MIGRATION.md:


# Migration Guide – 0.16.0 → 0.17.0

## What's new

- Added `participants.list` endpoint (minor bump).
- Removed `clientVersion` field from `config` (major bump).

## Migration steps

1. Update your client to request version `0.17.0` or later.
2. If you still need the old `clientVersion`, keep calling the previous major version (`0.16.x`).

*See the full spec diff in `openapi.yaml`*.

Summary

  • Version location: The .app.json manifest file (e.g., plugins/zoom/.app.json) contains the authoritative version field using semantic versioning (MAJOR.MINOR.PATCH).
  • Synchronization: Always keep the OpenAPI spec (openapi.yaml) synchronized with the manifest version, ensuring breaking changes trigger major version bumps.
  • Publishing: Use opencode publish --manifest <path> to deploy updates, with configuration defined in the root opencode.json.
  • Execution tracking: run_manifest.json captures the exact version used during each execution, enabling audit trails and version-drift detection as shown in the NGS-Analysis plugin documentation.
  • Breaking changes: Maintain legacy versions during deprecation windows and implement version-aware routing to support gradual client migrations.

Frequently Asked Questions

What happens if I don't update the version field in .app.json?

The opencode CLI may reject your publish request or overwrite the existing version in the registry, causing inconsistent behavior for users who depend on specific versions. Always increment the version when modifying plugin functionality, even for documentation-only changes (PATCH level).

How do I handle breaking API changes without disrupting existing users?

Increment the MAJOR version in your .app.json and maintain the previous version's endpoints for a deprecation period (typically 30 days). Document the breaking changes in your README.md and provide migration instructions. Consider implementing version-aware middleware to route requests to the appropriate handler based on the x-plugin-version header.

Can users request specific versions of my plugin?

Yes, consumers can specify which version to use during initialization. The system uses the version field from your .app.json to match requested versions. Ensure your implementation handles the x-plugin-version header to serve the correct API contract, or maintain separate deployments for different major versions.

Where is the version recorded during plugin execution?

The system generates a run_manifest.json file that captures the exact plugin version used for each execution, as demonstrated in the NGS-Analysis plugin's README at line 292. This allows you to audit which version produced specific results and to trigger re-runs if you need to upgrade or rollback to a different version.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →