Optional Companion Surfaces for OpenAI Codex Plugins: The Complete Guide

OpenAI Codex plugins support seven optional companion surfaces—skills/, .app.json, .mcp.json, agents/, commands/, 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

The .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.

{
  "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)

The .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.

{
  "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.

#!/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

The hooks.json file registers lifecycle event handlers that execute during critical plugin state transitions. This surface supports automation for setup, maintenance, and cleanup operations.

{
  "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 or provide visual elements for multi-channel presentations configured in .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 with name, version, and author metadata
  • Skill implementations: skills/ directory containing design-to-code logic
  • Web interface: .app.json pointing to dist/index.html
  • Multi-format output: .mcp.json configuring markdown and HTML templates
  • Lifecycle automation: 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, .mcp.json, agents/, commands/, hooks.json, and assets/
  • Required foundation: Every plugin must include .codex-plugin/plugin.json at the root
  • Modular architecture: Surfaces function independently; developers implement only necessary capabilities
  • Cross-channel support: .mcp.json enables simultaneous markdown, HTML, and chat rendering
  • Lifecycle integration: 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. Developers should add surfaces selectively based on whether they need UI components (assets/, .app.json), custom commands (commands/), background processing (agents/), or multi-format output (.mcp.json).

How does the .mcp.json file handle different output formats?

The .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 execute scripts written in languages other than Bash?

Yes. The 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.

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 →