# How to Add Commands to a Codex Plugin: Complete Implementation Guide

> Learn to add commands to your Codex plugin. Follow this implementation guide to create a commands directory and expose deterministic workflows like setup zoom oauth.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: how-to-guide
- Published: 2026-06-10

---

**Create a `commands/` directory in your plugin root and add markdown files following the [`_conventions.md`](https://github.com/openai/plugins/blob/main/_conventions.md) template to expose deterministic workflows that Codex invokes from prompts such as `/setup-zoom-oauth`.**

The **openai/plugins** repository provides a framework for extending Codex through deterministic, markdown-based workflows. To add commands to a Codex plugin, you organize declarative instruction files under a specific directory structure that Codex automatically discovers and executes without requiring compiled code.

## Understanding the Command Structure

Commands in the OpenAI plugins ecosystem are deterministic workflows defined entirely in markdown. Unlike skills (which contain executable scripts), commands provide structured instructions that Codex follows step-by-step when a user invokes a specific prompt pattern.

The system recognizes commands through **automatic discovery** of files placed in the `commands/` directory. Each plugin typically includes a [`_conventions.md`](https://github.com/openai/plugins/blob/main/_conventions.md) file that defines the required schema for these markdown instructions.

## Step-by-Step: Add Commands to a Codex Plugin

### 1. Create the Commands Directory

Navigate to your plugin root and create a `commands/` directory if it does not exist. For example, in the Zoom plugin referenced in the source code, this directory lives at `plugins/zoom/commands/`.

```bash
mkdir -p my-plugin/commands

```

### 2. Follow the Conventions Template

Before writing commands, examine the [`commands/_conventions.md`](https://github.com/openai/plugins/blob/main/commands/_conventions.md) file in your plugin. This template mandates specific sections for every command file:

- **Title** – A short, human-readable command name
- **Description** – Functional explanation of what the command does
- **Inputs** – Parameters the command accepts (if any)
- **Steps** – Numbered list of actions Codex should perform
- **Outputs** – Expected result format

The Zoom plugin's conventions are documented at [`plugins/zoom/commands/_conventions.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/commands/_conventions.md), which serves as the authoritative reference for command formatting in that repository.

### 3. Write the Command Markdown File

Create a file named `<command-name>.md` (no leading underscore) inside the `commands/` directory. The filename determines the command identifier that users invoke in prompts.

**Example: Minimal Command ([`hello-world.md`](https://github.com/openai/plugins/blob/main/hello-world.md))**

```markdown

# Hello World

**Description**  
A simple test command that returns a greeting.

**Inputs**  
None.

**Steps**  
1. Return the string "Hello, world!" as the command output.

**Outputs**  

```json
{
  "message": "Hello, world!"
}

```

```

**Example: Parameterized Command ([`search-repo.md`](https://github.com/openai/plugins/blob/main/search-repo.md))**

```markdown

# Search Repository

**Description**  
Searches the plugin repository for files matching a user-provided pattern.

**Inputs**  
- `pattern` (string): A glob pattern, e.g., `*.py`.

**Steps**  
1. Run a filesystem search for `{{pattern}}` inside the repository root.  
2. Collect all matching file paths.  
3. Return the list as JSON.

**Outputs**  

```json
{
  "matches": ["plugins/zoom/README.md", "plugins/zoom/commands/_conventions.md"]
}

```

```

### 4. Configure the Plugin Manifest (Optional)

Most plugins do not require explicit declaration in the manifest because Codex automatically discovers any `.md` file under `commands/`. However, if you prefer explicit configuration, add a `commands` entry in [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json):

```json
{
  "name": "my-plugin",
  "version": "1.0.0",
  "commands": "./commands"
}

```

The Zoom plugin at [`plugins/zoom/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/zoom/.codex-plugin/plugin.json) confirms that automatic discovery works without a `commands` key, yet the command files remain fully functional.

## Testing Your Commands

After committing new markdown files, validate the command structure using the evaluation suite. Run the tests in `plugins/plugin-eval/` or invoke the built-in skill `/evaluate-plugin` to ensure your command parses correctly and follows the required schema.

## Code Examples

### Manifest Configuration with Explicit Commands Path

```json
{
  "name": "my-plugin",
  "version": "0.2.0",
  "description": "Example plugin with custom commands",
  "commands": "./commands",
  "skills": "./skills/",
  "interface": {
    "displayName": "My Plugin",
    "shortDescription": "Demo plugin",
    "category": "Productivity"
  }
}

```

### Command with File Path References

When authoring commands that reference specific files, use relative paths from the plugin root:

```markdown

# Analyze Plugin Structure

**Description**  
Reads the plugin manifest and conventions file.

**Steps**  
1. Open `.codex-plugin/plugin.json` and extract the `name` field.
2. Read `commands/_conventions.md` to verify template compliance.
3. Return the plugin name and convention status.

**Outputs**  

```json
{
  "plugin_name": "string",
  "conventions_valid": true
}

```

```

## Summary

- **Create** a `commands/` directory in your plugin root to store markdown workflow definitions.
- **Follow** the [`commands/_conventions.md`](https://github.com/openai/plugins/blob/main/commands/_conventions.md) template to ensure required sections (Title, Description, Inputs, Steps, Outputs) are present.
- **Name** files `<command-name>.md` without leading underscores; these become invocable via prompts like `/command-name`.
- **Rely** on automatic discovery by default, as verified by the Zoom plugin implementation at [`plugins/zoom/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/zoom/.codex-plugin/plugin.json).
- **Test** using `plugins/plugin-eval/` or the `/evaluate-plugin` skill before deployment.

## Frequently Asked Questions

### Do I need to declare commands in the plugin.json manifest?

No. According to the source code in [`plugins/zoom/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/zoom/.codex-plugin/plugin.json), Codex automatically discovers any `.md` file placed under the `commands/` directory without explicit configuration. However, you may optionally add a `"commands": "./commands"` entry if you prefer explicit declaration or use a non-standard directory structure.

### What is the difference between commands and skills?

**Commands** are deterministic, markdown-based workflows that Codex executes step-by-step from instructions (e.g., `/setup-zoom-oauth`). **Skills** are executable scripts stored in the `skills/` directory that contain actual runtime code. Commands declare *what* Codex should do; skills contain *how* to do it programmatically.

### How do I test if my command is working correctly?

Run the evaluation suite located in `plugins/plugin-eval/` or use the built-in `/evaluate-plugin` skill. These tools validate that your markdown files conform to the [`_conventions.md`](https://github.com/openai/plugins/blob/main/_conventions.md) schema and that Codex can parse the steps, inputs, and outputs sections correctly.

### Can commands accept user inputs?

Yes. Define parameters in the **Inputs** section of your markdown file using the format `- `parameterName` (type): description`. Reference these inputs in the **Steps** section using `{{parameterName}}` syntax. The [`search-repo.md`](https://github.com/openai/plugins/blob/main/search-repo.md) example demonstrates accepting a `pattern` parameter for filesystem searches.