How Local Plugins Are Defined in the Marketplace JSON
Local plugins in the OpenAI Codex platform are defined within the marketplace.json file by setting "type": "local" and specifying the plugin_id (folder name) and manifest path to the plugin's configuration file.
The marketplace.json file serves as the central catalogue for the Codex platform, determining which plugins are available and how to load them. For plugins bundled directly inside the openai/plugins repository—referred to as local plugins—the JSON entries follow a strict schema that links the abstract plugin ID to its concrete implementation on disk.
Marketplace JSON Schema for Local Plugins
Each local plugin entry resides in the top-level "plugins" array inside marketplace.json. The Codex runtime iterates this array to discover and register available plugins.
Required Properties
Every local plugin definition must include these core fields:
id— The marketplace-wide unique identifier for the plugin (e.g.,"public-equity-investing").plugin_id— The exact folder name underplugins/containing the source code (e.g.,"public-equity-investing").type— Must be set to"local"to indicate the plugin is bundled with the repository rather than fetched remotely.manifest— Relative path from the repository root to the plugin's manifest file, typically"plugins/<name>/.app.json"or"plugins/<name>/.mcp.json".description— Human-readable summary displayed in the marketplace UI.
Optional Configuration Fields
Two additional fields provide runtime flexibility:
enabled— Boolean flag to toggle plugin visibility without removing the entry (defaults totrue).config— Static configuration object passed to the plugin at load time (e.g.,{ "defaultRegion": "US" }).
Example: Configuring Local Plugins in marketplace.json
Below is a complete marketplace.json snippet defining two local plugins: one for public equity investing and another for Zoom integration.
{
"plugins": [
{
"id": "public-equity-investing",
"plugin_id": "public-equity-investing",
"type": "local",
"manifest": "plugins/public-equity-investing/.app.json",
"description": "Public‑Equity Investing source‑category catalog",
"enabled": true
},
{
"id": "zoom",
"plugin_id": "zoom",
"type": "local",
"manifest": "plugins/zoom/.app.json",
"description": "Zoom meeting integration",
"enabled": true
}
]
}
How the Codex Runtime Loads Local Plugins
When the Codex platform initializes, it processes the marketplace.json file to register plugins. For local entries, the loader resolves the manifest path relative to the repository root and imports the plugin metadata.
// Simplified loading logic from the marketplace loader
for (const entry of marketplace.plugins) {
if (entry.type === 'local') {
const manifestPath = path.resolve(repoRoot, entry.manifest);
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));
registerPlugin(entry.id, manifest);
}
}
This process bypasses remote fetching because "type": "local" signals that all resources exist within the plugins/ directory structure.
Critical Files in the Local Plugin Lifecycle
Understanding the relationship between these files ensures correct plugin registration:
| File | Role |
|---|---|
marketplace.json |
Root catalogue containing the "plugins" array that declares every local plugin via the schema described above. |
plugins/<plugin_id>/.app.json |
Concrete manifest defining API endpoints, skills, and UI hooks. Example: plugins/zoom/.app.json. |
plugins/<plugin_id>/.mcp.json |
Alternative manifest format used by some plugins. Example: plugins/vercel/.codex-plugin/plugin.json. |
plugins/public-equity-investing/skills/user-context/plugin-author-config/source-category-config.json |
Plugin-specific state files that reference the marketplace_id placeholder and are stored at $CODEX_HOME/state/plugins/{marketplace_id}/{plugin_id}/. |
The plugin_id field in marketplace.json must match the folder name exactly, as this determines the physical path resolution for both the manifest and runtime state directories.
Summary
- Local plugins are declared in
marketplace.jsonwith"type": "local"to indicate bundled repository code. - The
plugin_idmust match the folder name underplugins/, while themanifestpoints to either.app.jsonor.mcp.json. - Optional
enabledandconfigfields control visibility and initialization parameters. - The Codex runtime iterates the
"plugins"array, resolves manifest paths locally, and registers plugins without remote network calls.
Frequently Asked Questions
What is the difference between id and plugin_id in the marketplace JSON?
The id field serves as the global marketplace identifier used throughout the Codex platform and in state file paths ($CODEX_HOME/state/plugins/{id}/), while plugin_id specifically maps to the physical folder name under the plugins/ directory. These often match but serve different purposes: id for logical reference, plugin_id for filesystem location.
Can a local plugin use a .mcp.json manifest instead of .app.json?
Yes. While many plugins in the openai/plugins repository use .app.json manifests (such as plugins/zoom/.app.json), the marketplace JSON supports alternative formats like .mcp.json for Model Context Protocol configurations. The plugins/vercel/.codex-plugin/plugin.json file demonstrates this alternative structure.
How do I temporarily disable a local plugin without deleting its configuration?
Set the "enabled" field to false in the plugin's marketplace JSON entry. This Boolean flag hides the plugin from the marketplace UI and prevents registration during runtime startup, while preserving the entire configuration block for future reactivation.
Where does the Codex platform store local plugin state data?
Runtime state files are stored at $CODEX_HOME/state/plugins/{marketplace_id}/{plugin_id}/, where marketplace_id corresponds to the id field defined in marketplace.json. This path structure appears in plugin-specific configuration files such as plugins/public-equity-investing/skills/user-context/plugin-author-config/source-category-config.json.
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 →