How to Add Custom Commands to an OpenAI Plugin: A Complete Guide
OpenAI plugins expose custom slash commands by creating declarative markdown files in the commands/ directory, which the plugin manifest auto-discovers without requiring manual registration.
The openai/plugins repository provides a declarative framework for building Codex-compatible plugins. Adding custom commands—also known as slash commands—allows users to invoke deterministic workflows directly from chat by placing structured markdown files in your plugin's commands/ directory.
Understanding the OpenAI Plugin Command Architecture
OpenAI plugins use a convention-over-configuration approach for command management. When the Codex runtime starts, it recursively scans the commands/ directory for all markdown files (excluding those prefixed with underscores), parses their YAML front-matter, and automatically registers them as invocable slash commands.
This design couples documentation with logic, making commands self-describing and version-controllable. The authoritative structure is defined in each plugin's commands/_conventions.md file, which specifies exactly how the runtime interprets your command files.
Step-by-Step Guide to Adding Custom Commands
Step 1: Create the Command File
Create a new markdown file in your plugin's commands/ directory. The filename (minus the .md extension) becomes the command name.
touch plugins/<your-plugin>/commands/my-custom-task.md
Files prefixed with an underscore (e.g., _conventions.md) are ignored by the loader, so use these for internal documentation or shared templates.
Step 2: Add Required YAML Front-Matter
Every command file must begin with YAML front-matter containing at least a description field. This description appears in the UI when users browse available commands.
---
description: Perform a custom task on the repository (e.g., lint, generate a report).
---
Step 3: Structure the Six Required Sections
The body must contain six specific sections that define the command's lifecycle. According to the commands/_conventions.md specification in the openai/plugins repository, these are:
Preflight – Pre-execution checks such as verifying environment variables, ensuring repositories are clean, or checking tool availability.
Plan – A narrative description of what the command will do, which files it will modify, and which secrets it will reference (without revealing their values).
Commands – The actual implementation steps, including shell commands, script invocations, or file edits. Use fenced code blocks with language specifiers.
Verification – Steps to confirm success, such as re-reading changed files, checking exit codes, or validating API responses.
Summary – A concise result block in a fenced code block that presents the final outcome.
Next Steps – Optional suggestions for follow-up actions or remediation.
Step 4: Verify Auto-Discovery
The plugin manifest at .codex-plugin/plugin.json automatically discovers all non-underscore markdown files in commands/. No manual registration or JSON editing is required. Simply commit your new file to the repository.
Complete Command File Example
Below is a production-ready template based on the Zoom plugin's implementation pattern found in plugins/zoom/commands/setup-zoom-oauth.md:
---
description: Perform a custom task on the repository (e.g., lint, generate a report).
---
# My Custom Task
## Preflight
1. Verify the repo is clean (`git status --porcelain`).
2. Ensure the required tool (`my-tool`) is installed (`which my-tool`).
## Plan
The command will:
- Run `my-tool lint` on the `src/` directory.
- Write the results to `reports/lint-report.txt`.
## Commands
```sh
my-tool lint src/ > reports/lint-report.txt
Verification
- Check that
reports/lint-report.txtexists. - Print the first few lines of the report (
head -n 10 reports/lint-report.txt).
Summary
## Result
- Action: lint source files
- Status: success
- Details: reports/lint-report.txt created, contains 42 warnings
Next Steps
- Review the lint report and fix the highlighted issues.
- Re-run the command after fixing problems.
## Understanding the Command Conventions
The [`commands/_conventions.md`](https://github.com/openai/plugins/blob/main/commands/_conventions.md) file in each plugin directory serves as the style guide and schema validator. It defines the exact formatting requirements for each section and the expected behavior of the runtime parser.
For reference implementations, examine the Zoom plugin's [`setup-zoom-oauth.md`](https://github.com/openai/plugins/blob/main/setup-zoom-oauth.md) command file, which demonstrates proper secret handling, API calls, and verification patterns used in production OpenAI plugins.
## Testing Your Custom Command
Test your implementation using the chat interface by invoking the command with a forward slash:
/my-custom-task
Alternatively, use the CLI interface to validate the parsing and execution:
```bash
codex run <plugin-name> my-custom-task
The runtime validates that all required sections are present and that the preflight checks pass before executing the Commands section.
Summary
- File Location: Place command files in
<plugin-root>/commands/with the.mdextension. - Auto-Discovery: The
.codex-plugin/plugin.jsonmanifest automatically includes all non-underscore markdown files without manual registration. - Required Structure: Include YAML front-matter with a
descriptionfield and six body sections (Preflight, Plan, Commands, Verification, Summary, Next Steps). - Conventions: Follow the specifications in
commands/_conventions.mdfor formatting and style consistency. - Testing: Invoke commands via
/command-namein chat orcodex run <plugin> <command>in the CLI.
Frequently Asked Questions
How does the plugin manifest discover new commands without manual registration?
The plugin loader automatically scans the commands/ directory at runtime, parsing every .md file that does not start with an underscore. It extracts the command name from the filename and registers it using the description from the YAML front-matter, as implemented in the openai/plugins runtime architecture.
What happens if I omit one of the required six sections?
The Codex runtime expects all six sections (Preflight, Plan, Commands, Verification, Summary, Next Steps) to be present in every command file. While the specific behavior depends on the runtime version, missing sections typically cause validation errors or prevent the command from appearing in the available slash commands list.
Can I use subdirectories within the commands/ folder?
The analysis indicates that the loader reads all non-underscore markdown files in commands/. While the provided examples show flat structures, you should verify support for nested directories by checking your specific plugin runtime version or the _conventions.md file in your plugin's directory.
How do I handle sensitive data like API keys in custom commands?
Reference secrets in the Plan section by name only (e.g., "will use the ZOOM_API_KEY secret"), then access them within the Commands section using environment variable syntax or your plugin's secret injection mechanism. Never hardcode credentials or print secret values in the Summary or Verification sections.
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 →