How to Handle Plugin Metadata (Author, License, Keywords) in OpenAI Codex

Plugin metadata is defined in the .codex-plugin/plugin.json manifest file, where the author object identifies the publisher, the license string declares legal terms, and the keywords array supplies discovery tags for the marketplace.

The openai/plugins repository powers the Codex platform's extensibility through a structured manifest system. To handle plugin metadata correctly, developers must populate specific fields in a JSON configuration file that the platform validates during discovery, indexing, and installation.

The Plugin Manifest Location

Every Codex plugin stores its canonical metadata in a hidden folder at the repository root. The file .codex-plugin/plugin.json serves as the single source of truth for the platform's marketplace and runtime systems.

According to the specification in .agents/skills/plugin-creator/references/plugin-json-spec.md, this manifest follows a strict schema that includes identity, legal, and discovery information. The platform reads this file when scanning the repository to build the searchable plugin catalog.

Required Metadata Fields

Three critical fields control how your plugin appears in the marketplace and how users discover it.

Author Information

The author field is an object containing name, optional email, and optional url. This identifies the publisher in the marketplace UI and provides attribution and contact details.

  • name: Required string displayed as the publisher identity
  • email: Optional contact address
  • url: Optional link to the author's profile or organization

The platform validates that author.name is a non-empty string during plugin loading. Missing or empty values cause the plugin to be rejected at runtime.

License Declaration

The license field is a string declaring the software license (e.g., MIT, Apache-2.0). Codex validates that a non-empty license is present and surfaces this information to users so they understand the legal terms before installation.

Use SPDX-compatible identifiers to ensure compatibility with automated license checkers. Common values include MIT, Apache-2.0, and BSD-3-Clause.

Discovery Keywords

The keywords field is an array of strings that supply discovery tags for the marketplace search engine. These tokens are indexed to help users find your plugin when searching for specific capabilities.

The array must contain at least one string, and each keyword should be concise and relevant. These tags appear directly in the UI on the plugin card, so avoid overly long phrases.

Creating and Validating Metadata

When scaffolding a new plugin, the creation script .agents/skills/plugin-creator/scripts/create_basic_plugin.py generates a plugin.json with placeholder TODO markers for metadata fields. Developers must replace these placeholders with real values before submission.

The validation pipeline enforces these rules:

  1. author.name must be a non-empty string
  2. license must be a non-empty string
  3. keywords must be a non-empty array of strings

Malformed manifests are rejected at load time, preventing broken plugins from appearing in the marketplace.

Working with Metadata Programmatically

Because the manifest is plain JSON, you can parse and modify it using standard libraries.

Loading Metadata from a Plugin

import json
import pathlib

def load_plugin_metadata(plugin_root: pathlib.Path):
    manifest_path = plugin_root / ".codex-plugin" / "plugin.json"
    with manifest_path.open() as f:
        data = json.load(f)

    author = data.get("author", {})
    license = data.get("license", "")
    keywords = data.get("keywords", [])

    return {
        "author_name": author.get("name", ""),
        "author_email": author.get("email", ""),
        "author_url": author.get("url", ""),
        "license": license,
        "keywords": keywords,
    }

# Usage

metadata = load_plugin_metadata(pathlib.Path("/path/to/plugins/zoom"))
print(metadata)

Updating License and Keywords

import json
import pathlib

def update_license_and_keywords(plugin_root: pathlib.Path, new_license: str, new_keywords: list[str]):
    manifest_path = plugin_root / ".codex-plugin" / "plugin.json"
    manifest = json.loads(manifest_path.read_text())

    manifest["license"] = new_license
    manifest["keywords"] = new_keywords

    manifest_path.write_text(json.dumps(manifest, indent=2))
    print(f"Updated {manifest_path}")

# Example call

update_license_and_keywords(
    pathlib.Path("/repo/plugins/zoom"),
    "Apache-2.0",
    ["zoom", "video", "conference", "api"]
)

Validating Metadata in Tests

import json
import pathlib
import pytest

def test_plugin_metadata():
    manifest = json.loads(
        pathlib.Path("/repo/plugins/zoom/.codex-plugin/plugin.json").read_text()
    )
    assert isinstance(manifest["author"]["name"], str) and manifest["author"]["name"]
    assert isinstance(manifest["license"], str) and manifest["license"]
    assert isinstance(manifest["keywords"], list) and all(isinstance(k, str) for k in manifest["keywords"])

Complete Manifest Example

The Zoom plugin in plugins/zoom/.codex-plugin/plugin.json demonstrates production-ready metadata:

{
  "name": "zoom",
  "version": "1.0.0",
  "description": "Interact with Zoom meetings and recordings.",
  "author": {
    "name": "OpenAI",
    "email": "[email protected]",
    "url": "https://openai.com"
  },
  "homepage": "https://zoom.us",
  "repository": "https://github.com/openai/plugins/tree/main/plugins/zoom",
  "license": "MIT",
  "keywords": ["zoom", "video", "conference", "meetings"],
  "skills": "./skills/",
  "interface": {
    "displayName": "Zoom",
    "shortDescription": "Manage Zoom meetings",
    "category": "Communication",
    "capabilities": ["Interactive", "Write"]
  }
}

Summary

  • Store metadata in .codex-plugin/plugin.json using the schema defined in .agents/skills/plugin-creator/references/plugin-json-spec.md
  • Define authorship with the author object containing at minimum a name string
  • Declare licensing using SPDX identifiers in the license field to ensure legal clarity
  • Enable discovery by providing relevant terms in the keywords array for marketplace search indexing
  • Validate requirements programmatically to ensure author.name, license, and keywords meet the platform's non-empty constraints

Frequently Asked Questions

Where is plugin metadata stored in the openai/plugins repository?

Plugin metadata lives in the .codex-plugin/plugin.json file within each plugin's directory. The platform discovers this manifest during repository scanning and uses it to populate the marketplace catalog and runtime configurations.

What license format should I use for Codex plugins?

Use SPDX-compatible license identifiers such as MIT, Apache-2.0, or BSD-3-Clause. The platform requires a non-empty string for the license field and validates its presence during plugin loading.

How does the Codex platform validate plugin metadata?

The validation pipeline checks that author.name is a non-empty string, license contains a non-empty string, and keywords is a non-empty array of strings. Plugins with placeholder values like [TODO: MIT] or missing required fields are rejected at load time and will not appear in the marketplace.

Can I update plugin metadata after the initial creation?

Yes. The .codex-plugin/plugin.json file is a standard JSON document that you can edit directly or modify programmatically. After updating metadata, ensure the plugin passes validation by checking that all required fields contain proper non-empty values according to the specification.

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 →