How to Add Custom Commands and Hooks to a Plugin

You add custom commands by creating Markdown files in the commands/ directory and define hooks by configuring hooks.json to trigger actions after specific tool events, with the Codex runtime automatically discovering both assets.

The OpenAI Codex plugin system enables you to extend agent capabilities through declarative configuration files. When you need to add custom commands and hooks to a plugin, you work with three specific file types located in the openai/plugins repository: a JSON manifest, Markdown command definitions, and a hooks configuration file. This guide explains the exact structure, file paths, and schemas required to implement both features.

Understanding the Plugin Manifest Structure

Every Codex plugin requires a manifest file at plugins/<name>/.codex-plugin/plugin.json. This file serves as the anchor point that tells the runtime where to find commands, skills, and other assets.

According to the openai/plugins source code, the manifest uses a standard JSON structure:

{
  "name": "zoom",
  "version": "1.0.2",
  "apps": "./.app.json",
  "skills": "./skills/"
}

The fields apps and skills are optional; the runtime automatically scans the sibling commands/ folder and the hooks.json file if they exist at the plugin root.

How to Add Custom Commands to a Plugin

Commands are reusable workflows defined as Markdown documents. The Codex runtime discovers them automatically in the plugins/<name>/commands/ directory without requiring explicit registration in the manifest.

Creating Command Markdown Files

Create a new file with a concise, hyphen-separated filename like my-custom-action.md. Each command requires YAML front matter with a description field, followed by instructional content the model should execute.

As implemented in plugins/zoom/commands/plan-zoom-product.md, the structure follows this pattern:

---
description: Choose the right Zoom product surface for a use case and explain the tradeoffs clearly.
---

# Plan Zoom Product

## Preflight

1. Analyze user requirements
2. Compare available product surfaces

## Plan

...

Command Front Matter Requirements

The only required front matter field is description, which appears in the plugin catalog and helps the model select the appropriate command. The body can contain any Markdown structure including headings, bullet points, and inline code.

Save your file as plugins/<your-plugin>/commands/<name>.md and commit it. No additional registration steps are required.

How to Add Custom Hooks to a Plugin

Hooks let you run commands automatically after specific tool events (such as write operations). You declare hooks in a hooks.json file at the root of the plugin directory.

Understanding Hook Triggers and Matchers

The hook JSON structure maps event types like PostToolUse to arrays of matcher definitions. Each matcher uses a regular expression pattern to select which tool usage events should trigger the hook.

As shown in plugins/figma/hooks.json, the schema follows this structure:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "./scripts/post_write_figma_parity_check.sh"
          }
        ]
      }
    ]
  }
}

Linking Hooks to Commands or Scripts

Under the hooks array, define one or more actions using the type field set to "command". The command value can reference:

  1. Shell scripts: "./scripts/post_write_figma_parity_check.sh"
  2. Markdown command files: "./commands/my-custom-action.md"

The runtime will execute the referenced asset when the matcher pattern matches the tool event.

Complete Walkthrough: Adding a Command and Hook Together

To implement a post-write review hook that triggers a custom command, follow these steps:

  1. Create the command file:
mkdir -p plugins/my-plugin/commands
cat > plugins/my-plugin/commands/auto-review.md <<'EOF'
---
description: Run an automated code review of the repo.
---

# Auto Review

1. Run `git diff`.
2. Summarize any risky changes.
3. Suggest tests for new code paths.
EOF
  1. Create the hook configuration:
cat > plugins/my-plugin/hooks.json <<'EOF'
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "./commands/auto-review.md"
          }
        ]
      }
    ]
  }
}
EOF
  1. Commit the files:
git add plugins/my-plugin/commands/auto-review.md plugins/my-plugin/hooks.json
git commit -m "Add auto-review command and post-write hook"

The Codex engine will now surface /auto-review as a callable command and automatically invoke it after any write operation matching the Write|Edit pattern.

Key Files and Locations

When adding custom commands and hooks to a plugin, remember these critical paths in the openai/plugins repository:

Best Practices for Plugin Development

  • Keep commands atomic: Define one logical task per Markdown file to improve reusability.
  • Use clear front matter: The description field appears in the plugin catalog and helps the model choose the correct command.
  • Match wisely: Keep hook matcher patterns as specific as necessary to avoid unintended invocations.
  • Version bump: Increment the version field in plugin.json when you add public-facing commands or hooks so downstream users know the plugin changed.

Summary

  • Commands are Markdown files stored in plugins/<name>/commands/ with YAML front matter containing a description field.
  • Hooks are defined in plugins/<name>/hooks.json using event types like PostToolUse, regex matcher patterns, and action definitions.
  • Both assets are auto-discovered by the Codex runtime without requiring explicit registration in the manifest.
  • Hooks can trigger shell scripts or directly reference Markdown command files using relative paths.
  • File naming should use hyphen-separated lowercase for commands and proper JSON structure for hooks.

Frequently Asked Questions

Do I need to register new commands in the plugin manifest?

No. The Codex runtime automatically discovers command files placed in the commands/ directory. You do not need to add explicit references to plugin.json for the runtime to recognize new commands.

Can hooks trigger Markdown command files instead of shell scripts?

Yes. In hooks.json, set the type to "command" and use the relative path to the Markdown file, such as "./commands/auto-review.md". The runtime will execute the steps described in that command file.

What tool events can trigger hooks?

The openai/plugins source code supports event types like PostToolUse and PreToolUse. You use these as top-level keys in your hooks.json object, then specify matcher patterns (like Write|Edit or Search) to filter which specific tool invocations should trigger your hook.

Do I need to restart Codex after adding command or hook files?

No restart is required, but the runtime will load the new assets on the next plugin reload. Ensure you commit your changes so the updated commands/ contents and hooks.json definitions are available to the system.

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:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →