# Optional Companion Surfaces for OpenAI Codex Plugins: The Complete Guide

> Discover optional companion surfaces for OpenAI Codex plugins including skills, agents, and hooks. Extend your plugin's functionality beyond the manifest.

- Repository: [OpenAI/plugins](https://github.com/openai/plugins)
- Tags: getting-started
- Published: 2026-09-11

---

**OpenAI Codex plugins support seven optional companion surfaces—`skills/`, [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json), [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json), `agents/`, `commands/`, [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json), and `assets/`—that extend core functionality beyond the required manifest file.**

Every Codex plugin requires a manifest at `plugins/<plugin-name>/.codex-plugin/plugin.json`, but developers can augment capabilities using optional companion surfaces. These surfaces enable custom UIs, multi-format outputs, background processing, and lifecycle management while keeping the core configuration minimal. According to the openai/plugins repository, these extensions reside in standardized locations within the plugin directory structure.

## Skill Definitions with `skills/`

The `skills/` directory contains one or more skill definitions that implement the plugin’s core actions. This surface allows developers to modularize capabilities into discrete, reusable components that the Codex runtime can invoke.

While the manifest declares the plugin’s existence, the `skills/` folder contains the actual implementation logic. Each skill file typically defines parameters, descriptions, and execution handlers that map to specific user intents.

## Web Application Interface via [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json)

The [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) file describes a hosted web application UI that launches directly from the plugin. This JSON configuration specifies the entry point and presentation details for graphical interactions.

```json
{
  "type": "web",
  "entry": "dist/index.html",
  "title": "Figma UI"
}

```

When present, Codex renders the specified web interface alongside conversational interactions, enabling complex visual workflows like the Figma design-to-code integration found in the repository’s examples.

## Multi-Channel Presentation Configuration ([`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json))

The [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) file defines **Multi-Channel-Presentation** (MCP) settings that control how the plugin renders output across different channels. This surface supports simultaneous generation of chat, HTML, and markdown formats from a single response.

```json
{
  "outputs": [
    { "format": "markdown", "template": "templates/summary.md" },
    { "format": "html", "template": "templates/preview.html" }
  ]
}

```

Developers specify format-specific templates, allowing the same data to appear as rich HTML in browsers and concise markdown in chat interfaces.

## Background Processing with `agents/`

The `agents/` directory contains optional agent definitions that run background processes or orchestrate complex workflows on behalf of the plugin. Unlike skills that respond to immediate requests, agents operate asynchronously to handle long-running tasks, monitor external systems, or manage stateful operations across multiple interactions.

## Custom CLI Commands in `commands/`

The `commands/` folder stores custom CLI command scripts that the Codex runtime can execute directly. These bash or executable files extend the plugin’s capabilities beyond API calls to local system operations.

```bash
#!/usr/bin/env bash

# plugins/figma/commands/export-components.sh

figma-cli export --components "$@"

```

Commands inherit environment context from the Codex runtime and accept arguments via standard input parameters, enabling integration with local development toolchains.

## Lifecycle Hooks via [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json)

The [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json) file registers lifecycle event handlers that execute during critical plugin state transitions. This surface supports automation for setup, maintenance, and cleanup operations.

```json
{
  "onInstall": "scripts/install.sh",
  "onUpdate": "scripts/update.sh"
}

```

Valid hook keys include `onInstall` for first-time setup and `onUpdate` for version migrations. Each value specifies an executable path relative to the plugin root.

## Static Resources in `assets/`

The `assets/` directory stores static resources including images, icons, fonts, and other media referenced by the plugin’s UI components. These files serve web applications defined in [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) or provide visual elements for multi-channel presentations configured in [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json).

## Real-World Implementation: The Figma Plugin

The Figma plugin in the openai/plugins repository demonstrates practical application of multiple companion surfaces. Located at `plugins/figma/`, this implementation combines:

- **Core manifest**: [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) with name, version, and author metadata
- **Skill implementations**: `skills/` directory containing design-to-code logic
- **Web interface**: [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json) pointing to [`dist/index.html`](https://github.com/openai/plugins/blob/main/dist/index.html)
- **Multi-format output**: [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) configuring markdown and HTML templates
- **Lifecycle automation**: [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json) managing installation and update scripts
- **Visual assets**: `assets/` folder containing Figma brand resources

This architecture keeps the required manifest minimal while delivering rich, multi-modal functionality through selective surface implementation.

## Summary

- **Seven optional surfaces** extend Codex plugins: `skills/`, [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json), [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json), `agents/`, `commands/`, [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json), and `assets/`
- **Required foundation**: Every plugin must include [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json) at the root
- **Modular architecture**: Surfaces function independently; developers implement only necessary capabilities
- **Cross-channel support**: [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) enables simultaneous markdown, HTML, and chat rendering
- **Lifecycle integration**: [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json) provides `onInstall` and `onUpdate` automation hooks

## Frequently Asked Questions

### What is the difference between `skills/` and `agents/` directories?

The `skills/` directory contains immediate-response action handlers that execute when users invoke specific commands, while `agents/` house background processes that run asynchronously or monitor systems over time. Skills return results directly to the conversation context, whereas agents manage stateful workflows independently of individual user messages.

### Are all companion surfaces required for every Codex plugin?

No. According to the openai/plugins source code, all seven companion surfaces are completely optional. A functional plugin requires only the manifest file at [`.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/.codex-plugin/plugin.json). Developers should add surfaces selectively based on whether they need UI components (`assets/`, [`.app.json`](https://github.com/openai/plugins/blob/main/.app.json)), custom commands (`commands/`), background processing (`agents/`), or multi-format output ([`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json)).

### How does the [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) file handle different output formats?

The [`.mcp.json`](https://github.com/openai/plugins/blob/main/.mcp.json) file contains an `outputs` array where each object specifies a `format` (e.g., "markdown", "html") and a corresponding `template` path. When generating responses, Codex iterates through this configuration to render the same underlying data through multiple presentation layers simultaneously, ensuring appropriate formatting for each target channel.

### Can [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json) execute scripts written in languages other than Bash?

Yes. The [`hooks.json`](https://github.com/openai/plugins/blob/main/hooks.json) registry references executable paths regardless of interpreter. While the Figma example uses `.sh` scripts, you can specify Python scripts, Node.js files, or compiled binaries as values for `onInstall`, `onUpdate`, or future hook events, provided the target environment contains the necessary runtime.