How to Add Commands to a Codex Plugin: Complete Implementation Guide
Create a commands/ directory in your plugin root and add markdown files following the _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 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/.
mkdir -p my-plugin/commands
2. Follow the Conventions Template
Before writing commands, examine the 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, 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)
# 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 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
{
"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:
# 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.
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 →