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:
author.namemust be a non-empty stringlicensemust be a non-empty stringkeywordsmust 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.jsonusing the schema defined in.agents/skills/plugin-creator/references/plugin-json-spec.md - Define authorship with the
authorobject containing at minimum anamestring - Declare licensing using SPDX identifiers in the
licensefield to ensure legal clarity - Enable discovery by providing relevant terms in the
keywordsarray for marketplace search indexing - Validate requirements programmatically to ensure
author.name,license, andkeywordsmeet 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →