# How to Add Custom Commands and Hooks to a Plugin

> Learn to add custom commands and hooks to your plugin. Create Markdown files for commands and configure hooks.json to trigger actions, with automatic discovery by the Codex runtime.

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

---

**You add custom commands by creating Markdown files in the `commands/` directory and define hooks by configuring [`hooks.json`](https://github.com/openai/plugins/blob/main/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:

```json
{
  "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`](https://github.com/openai/plugins/blob/main/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`](https://github.com/openai/plugins/blob/main/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`](https://github.com/openai/plugins/blob/main/plugins/zoom/commands/plan-zoom-product.md), the structure follows this pattern:

```markdown
---
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`](https://github.com/openai/plugins/blob/main/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`](https://github.com/openai/plugins/blob/main/plugins/figma/hooks.json), the schema follows this structure:

```json
{
  "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**:

```bash
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

```

2. **Create the hook configuration**:

```bash
cat > plugins/my-plugin/hooks.json <<'EOF'
{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "./commands/auto-review.md"
          }
        ]
      }
    ]
  }
}
EOF

```

3. **Commit the files**:

```bash
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:

- **`plugins/<name>/.codex-plugin/plugin.json`**: The core manifest that points to commands, skills, and assets. Example: [`plugins/zoom/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/zoom/.codex-plugin/plugin.json)
- **`plugins/<name>/commands/<name>.md`**: Markdown-based command definitions. Example: [`plugins/zoom/commands/plan-zoom-product.md`](https://github.com/openai/plugins/blob/main/plugins/zoom/commands/plan-zoom-product.md)
- **`plugins/<name>/hooks.json`**: JSON map of hook triggers to actions. Example: [`plugins/figma/hooks.json`](https://github.com/openai/plugins/blob/main/plugins/figma/hooks.json)
- **`plugins/<name>/scripts/`**: Optional directory for helper scripts referenced by hooks

## 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`](https://github.com/openai/plugins/blob/main/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`](https://github.com/openai/plugins/blob/main/plugin.json) for the runtime to recognize new commands.

### Can hooks trigger Markdown command files instead of shell scripts?

Yes. In [`hooks.json`](https://github.com/openai/plugins/blob/main/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`](https://github.com/openai/plugins/blob/main/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`](https://github.com/openai/plugins/blob/main/hooks.json) definitions are available to the system.