# How Does the Codex Client Discover and Load Plugins: A Deep Dive into the OpenAI Plugins Architecture

> Learn how the Codex client discovers and loads plugins via a three stage pipeline. Understand the marketplace scanning, manifest parsing, and skill registration process.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: deep-dive
- Published: 2026-09-12

---

**The Codex client discovers and loads plugins through a three-stage pipeline that scans marketplace.json files, parses manifest metadata from .codex-plugin/plugin.json, and registers skills defined in SKILL.md front-matter.**

The openai/plugins repository implements a declarative plugin system that requires zero runtime hooks. Instead of dynamic code execution during discovery, the Codex client relies on static metadata files to map plugin capabilities to user intents.

## The Three-Stage Discovery Pipeline

According to the source code in the openai/plugins repository, the client executes a predictable pipeline when initializing the plugin ecosystem:

| Stage | Action | Key File |
|-------|--------|----------|
| **Marketplace Scan** | Reads default and workspace-specific marketplace.json files to map plugin names to directory paths | [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json) |
| **Manifest Load** | Parses plugin metadata including version, description, and interface entry points | [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) |
| **Skill Registration** | Discovers SKILL.md files and extracts retrieval metadata (aliases, intents, patterns) to populate the runtime registry | `<plugin>/skills/**/SKILL.md` |

## Stage 1: Marketplace Scanning

The discovery process begins with **marketplace resolution**. The client locates the marketplace file at `~/.agents/plugins/marketplace.json` (or a workspace-specific variant at `<workspace>/.agents/plugins/marketplace.json`) and parses the JSON structure to determine which plugins are available.

### Resolving Plugin Directories

Each entry in the marketplace contains a `name` and a `path` property. The client resolves the `path` relative to the marketplace file location to determine the absolute plugin directory:

```json
{
  "plugins": [
    {
      "name": "vercel",
      "path": "./plugins/vercel"
    },
    {
      "name": "gmail",
      "path": "./plugins/gmail"
    }
  ]
}

```

The following Node.js implementation illustrates how the client loads the marketplace and resolves plugin directories:

```javascript
const fs = require('fs');
const path = require('path');

function loadMarketplace(marketplacePath) {
  const raw = fs.readFileSync(marketplacePath, 'utf8');
  const data = JSON.parse(raw);
  return data.plugins.map(p => ({
    name: p.name,
    dir: path.resolve(path.dirname(marketplacePath), p.path),
  }));
}

// Example usage
const marketplace = loadMarketplace(
  path.join(process.env.HOME, '.agents', 'plugins', 'marketplace.json')
);
console.log('Discovered plugins:', marketplace);

```

## Stage 2: Manifest Loading

Once the client identifies a plugin directory, it loads the **plugin manifest** located at `<plugin-dir>/.codex-plugin/plugin.json`. This manifest defines the plugin's identity, versioning, and interface specifications required for UI rendering.

### The .codex-plugin/plugin.json Structure

The manifest contains fields such as `name`, `version`, `description`, and an `interface` block that details the plugin's entry points. For example, the Vercel plugin manifest defines how the client should surface the plugin's capabilities to users.

To load a manifest programmatically:

```javascript
function loadPluginManifest(pluginDir) {
  const manifestPath = path.join(pluginDir, '.codex-plugin', 'plugin.json');
  const raw = fs.readFileSync(manifestPath, 'utf8');
  return JSON.parse(raw);
}

// For each discovered plugin
marketplace.forEach(p => {
  const manifest = loadPluginManifest(p.dir);
  console.log(`${p.name} v${manifest.version}: ${manifest.description}`);
});

```

## Stage 3: Skill and Agent Registration

The final stage involves **recursive skill discovery**. The client walks the plugin directory tree, identifying every [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) file and parsing its YAML front-matter to extract **retrieval metadata**.

### Parsing SKILL.md Front-Matter

Each [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) file contains metadata that drives Codex-native discovery without additional registration code. The front-matter specifies `retrieval.aliases`, `intents`, `entities`, `pathPatterns`, and `bashPatterns` that match user utterances to specific capabilities:

```yaml
retrieval:
  aliases: ["vercel", "vc"]
  intents: ["deploy", "preview"]
  pathPatterns: ["**/vercel/**"]
  bashPatterns: ["vercel *"]

```

The client parses this metadata to understand when to invoke the skill based on file paths or command patterns. Here is how the skill parsing logic extracts this metadata:

```javascript
const yaml = require('js-yaml');

function loadSkillMeta(skillPath) {
  const content = fs.readFileSync(skillPath, 'utf8');
  const [, frontMatter] = content.split('---\n').filter(Boolean);
  return yaml.load(frontMatter);
}

// Walk the plugin dir for SKILL.md files
function discoverSkills(pluginDir) {
  const walk = require('walkdir').sync;
  const skills = [];

  for (const file of walk(pluginDir)) {
    if (path.basename(file) === 'SKILL.md') {
      const meta = loadSkillMeta(file);
      skills.push({ path: file, meta });
    }
  }
  return skills;
}

// Register each skill in the client registry
marketplace.forEach(p => {
  const skills = discoverSkills(p.dir);
  skills.forEach(s => console.log(`Skill ${s.meta.name} discovered in ${s.path}`));
});

```

### Runtime Registration

After parsing, each skill definition is added to the client's internal registry. This registry is consulted whenever a user invokes a slash command or the Codex UI triggers a plugin action, enabling seamless discovery and execution without reloading the client.

## Validation and Developer Tooling

The repository includes utilities to ensure plugin integrity. The [`plugins/plugin-eval/src/evaluators/plugin.js`](https://github.com/openai/plugins/blob/main/plugins/plugin-eval/src/evaluators/plugin.js) file validates that marketplace entries and plugin manifests conform to the expected schema.

For developers creating new plugins, the [`.agents/skills/plugin-creator/scripts/create_basic_plugin.py`](https://github.com/openai/plugins/blob/main/.agents/skills/plugin-creator/scripts/create_basic_plugin.py) script scaffolds the required directory structure, generates the [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) manifest, and prepares the marketplace entry automatically.

## CLI Verification

You can verify which plugins the client has loaded using the Codex CLI:

```bash
codex plugins list

```

This command reports all plugins discovered via the marketplace scan whose manifests were successfully parsed and whose skills have been registered in the runtime.

## Summary

- **Marketplace-driven discovery**: The client reads [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json) to locate plugin directories relative to the file's location.
- **Manifest-based metadata**: Each plugin must contain a [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) file defining its identity and interface specifications.
- **Declarative skill registration**: Skills are defined in [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) files with YAML front-matter containing retrieval metadata (aliases, intents, path patterns) that enables automatic matching without runtime hooks.
- **Zero client modification**: Adding, updating, or removing plugins requires only editing the marketplace JSON and plugin files—no changes to the Codex client source code are necessary.

## Frequently Asked Questions

### What file triggers plugin discovery in Codex?

The discovery process is triggered by the **marketplace.json** file, located by default at `~/.agents/plugins/marketplace.json` or within a workspace-specific `.agents/plugins/` directory. This JSON file maps plugin names to relative directory paths, serving as the single source of truth for available plugins.

### How does Codex match user queries to specific plugin skills?

Codex matches queries using **retrieval metadata** stored in the YAML front-matter of [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) files. The metadata includes `retrieval.aliases` for command recognition, `intents` for semantic matching, `pathPatterns` for file-based triggering, and `bashPatterns` for shell command detection. The client parses this static metadata at load time to build a matching registry.

### Can plugins be loaded without modifying the Codex client source code?

Yes. The architecture supports **purely declarative plugin addition**. You can add a new plugin by creating the plugin directory, adding a [`plugin.json`](https://github.com/openai/plugins/blob/main/plugin.json) manifest, writing [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) files with proper front-matter, and updating the marketplace.json file to include the new plugin path. The client automatically discovers and loads the plugin on the next initialization cycle without requiring code changes.

### Where are plugin manifests stored in the repository structure?

Each plugin stores its manifest in a hidden directory named **`.codex-plugin`** located at the plugin root, specifically at `<plugin-directory>/.codex-plugin/plugin.json`. This file contains the plugin's `name`, `version`, `description`, and interface configuration required for client integration.