How to Add Custom Commands to a Codex Plugin: A Complete Guide
To add custom commands to a Codex plugin, create a commands/ directory in your plugin root and add markdown files following the _conventions.md template, which Codex automatically discovers and invokes.
The openai/plugins repository demonstrates how to add custom commands to a Codex plugin using deterministic, markdown-based workflows. Each command is defined as a structured document that Codex interprets and executes when invoked from a prompt, such as /setup-zoom-oauth. By following the conventions established in the Zoom plugin and other examples, you can extend any plugin with new deterministic capabilities.
Understanding the Codex Plugin Structure
A Codex plugin organizes its functionality around a central manifest file and optional companion directories. The core configuration lives in .codex-plugin/plugin.json, while deterministic workflows reside in the commands/ directory. Unlike skills that may require complex logic, commands are declarative markdown files that specify inputs, processing steps, and expected outputs.
Creating the Commands Directory
Begin by establishing a commands/ folder at your plugin root if it does not already exist. Codex automatically indexes any .md file placed in this directory, provided the filename does not start with an underscore. This auto-discovery mechanism means you typically do not need to modify the plugin manifest to register new commands.
Writing Markdown Files for Custom Commands
Each command requires a dedicated markdown file named <command-name>.md that adheres to the conventions defined in your plugin's _conventions.md file. For example, the Zoom plugin documents its requirements at plugins/zoom/commands/_conventions.md.
Required Template Sections
Every command markdown file must include these specific sections:
- Title – A short, human-readable name for the command.
- Description – A clear explanation of what the command accomplishes.
- Inputs – Parameters the command accepts, including type and description.
- Steps – A numbered list of actions Codex should perform.
- Outputs – The expected result format, typically shown as JSON.
Here is a minimal example:
# 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!"
}
### Parameterized Command Example
Commands can accept dynamic inputs using template variables. The following example demonstrates a command that searches the repository:
```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"]
}
## Optional Manifest Configuration
Most plugins rely on automatic command discovery, but you can explicitly declare the commands directory in [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) if preferred. The Zoom manifest at [`plugins/zoom/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/zoom/.codex-plugin/plugin.json) omits this field entirely, yet its commands remain fully functional.
To declare the path explicitly:
```json
{
"name": "my-plugin",
"version": "1.0.0",
"commands": "./commands"
}
Testing Your Custom Commands in a Codex Plugin
After creating your markdown files, validate them using the plugin evaluation suite located at plugins/plugin-eval/. Alternatively, invoke the built-in skill /evaluate-plugin to ensure your command parses correctly and follows the established conventions. This verification step confirms that Codex can interpret your inputs, steps, and outputs as intended.
Summary
- Create a
commands/directory at your plugin root to store command definitions. - Name each command file
<command-name>.mdwithout leading underscores. - Follow the
_conventions.mdtemplate from your plugin, including Title, Description, Inputs, Steps, and Outputs sections. - Rely on automatic discovery through the
commands/folder, or optionally specify"commands": "./commands"in.codex-plugin/plugin.json. - Test implementations using
plugins/plugin-eval/or the/evaluate-pluginskill before deployment.
Frequently Asked Questions
Do I need to update the plugin.json manifest to add new commands?
No, explicit manifest updates are usually unnecessary. Codex automatically discovers any .md file in the commands/ directory. You only need to add a "commands" field to .codex-plugin/plugin.json if your plugin uses a non-standard directory structure or if you prefer explicit declaration for documentation purposes.
What is the difference between commands and skills in a Codex plugin?
Commands are deterministic, markdown-based workflows defined in the commands/ directory that follow a strict template with inputs, steps, and outputs. Skills typically involve executable code or scripts placed in the skills/ directory that handle complex runtime logic. Commands are ideal for structured, repeatable workflows, while skills handle dynamic computations.
Can I use variables or templates in my command definitions?
Yes, command files support template variables using the {{variable}} syntax. Define these in the Inputs section, then reference them in the Steps section. Codex substitutes actual values when users invoke the command with parameters.
How do I ensure my command follows the correct format?
Consult your plugin's _conventions.md file, typically located at commands/_conventions.md. This document specifies the required sections and formatting rules. Run the evaluation suite in plugins/plugin-eval/ to programmatically verify that your markdown structure meets all requirements.
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 →