How to Structure Plugin Assets and Resource Files in OpenAI Plugins

Structure plugin assets and resource files by placing the manifest in .codex-plugin/plugin.json, runtime config in .app.json, static media in assets/, and optional capabilities in skills/ and agents/ directories under plugins/<plugin-name>/.

The openai/plugins repository defines a standardized layout for building ChatGPT-compatible plugins. Following this convention ensures your integration loads correctly and displays properly in the OpenAI ecosystem.

Core Directory Layout

Every plugin in the repository lives under the top-level plugins/ directory. Each integration occupies its own subdirectory named after the service (e.g., docusign, github, zoom).

Inside each plugin folder, you must include specific files that declare metadata and configuration:

  • .codex-plugin/plugin.json – Declares the plugin’s metadata, API endpoints, authentication scheme, and OpenAPI specification URL in the format expected by the Codex marketplace.
  • .app.json – Stores runtime settings that the OpenAI host reads when loading the plugin, including environment variables and feature flags.
  • README.md – Provides human-readable documentation, installation steps, and usage instructions.

Managing Static Assets

Static resources such as icons, logos, and other UI media belong in the dedicated assets/ directory.

The assets/ Directory

The assets/ folder holds any image format (PNG, SVG, etc.) that the plugin UI displays. Keeping all static media together ensures packaging tools can bundle them cleanly for distribution.

Referencing Assets in the Manifest

Icons are referenced in plugin.json using relative paths from the plugin root. For example, the Docusign plugin declares its icon as follows:

{
  "name": "Docusign",
  "description": "Create and manage envelopes",
  "icon": "assets/icon.png"
}

When the OpenAI runtime renders the plugin card, it resolves assets/icon.png relative to the plugins/docusign/ folder.

Optional Capability Extensions

Beyond the required files, plugins can include optional directories that expose specialized behaviors.

Skill Definitions (skills/)

The skills/ directory contains skill definitions and reference documentation that expose higher-level actions (e.g., a "create-envelope" skill for Docusign). Each skill typically includes a SKILL.md file documenting the capability and may contain a references/ folder for additional links or snippets.

Agent Configuration (agents/)

When a plugin uses an OpenAI agent for orchestrating calls, YAML files in agents/ define system prompts, temperature settings, and model parameters. For example, plugins/docusign/agents/openai.yaml supplies the system context:

system: |
  You are a helpful assistant that interacts with Docusign's API.
  Use the provided endpoints to create envelopes and retrieve status.
temperature: 0.2
max_tokens: 1024

How the Runtime Loads Your Plugin

When the OpenAI runtime initializes a plugin, it follows a specific sequence:

  1. It reads .codex-plugin/plugin.json to discover the OpenAPI definition and authentication requirements.
  2. It loads .app.json to apply runtime-specific configuration such as environment variable names.
  3. UI components pull the icon from the assets/ folder using the path declared in the manifest.
  4. If the plugin offers a skill, the runtime registers the capability based on the skills/ definition, making it callable via the chat interface.
  5. Any agent behavior defined in agents/ is instantiated when the plugin is invoked, allowing custom prompts or routing logic.

Implementation Examples

Below are practical snippets demonstrating how to interact with the repository structure programmatically.

Loading a Plugin Manifest

This Node.js example resolves and parses the Docusign plugin manifest:

import fs from 'fs';
import path from 'path';

// Resolve the plugin's manifest
const manifestPath = path.resolve(
  __dirname,
  'plugins/docusign/.codex-plugin/plugin.json'
);
const manifest = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));

console.log('Plugin name:', manifest.name);
console.log('OpenAPI spec URL:', manifest.api.url);

Invoking a Skill via API

Assume the Docusign plugin contains a skill file at skills/create-envelope/SKILL.md. A client invokes the skill through the OpenAI API:

{
  "model": "gpt-4o",
  "messages": [
    {
      "role": "user",
      "content": "Create a Docusign envelope for John Doe."
    }
  ],
  "plugins": [
    {
      "id": "docusign",
      "method": "create-envelope"
    }
  ]
}

The skill implementation reads from plugins/docusign/skills/create-envelope/ to construct the appropriate API request.

Summary

  • Place required metadata in .codex-plugin/plugin.json and runtime settings in .app.json at the plugin root.
  • Store all static media in the assets/ directory and reference them with relative paths in the manifest.
  • Implement optional capabilities by adding skills/ for high-level actions and agents/ for custom orchestration logic.
  • Follow the plugins/<plugin-name>/ pattern to ensure compatibility with the OpenAI platform and simplify maintenance.

Frequently Asked Questions

What is the purpose of .codex-plugin/plugin.json?

This file serves as the primary manifest declaring the plugin's metadata, OpenAPI specification URL, authentication type, and contact information. The OpenAI runtime reads this file first when loading your plugin to determine API capabilities and security requirements.

How do I reference icons and logos in my plugin?

Specify the relative path from the plugin root in the icon field of plugin.json. For example, "icon": "assets/icon.png" tells the runtime to look for the image at plugins/<plugin-name>/assets/icon.png.

Can a plugin work without the skills/ or agents/ directories?

Yes. Both directories are optional. A basic plugin only requires .codex-plugin/plugin.json, .app.json, and an assets/ folder with your icon. You only need skills/ if exposing specialized high-level actions, and agents/ if using custom model orchestration.

Where should I store runtime configuration settings?

Store environment-specific settings and feature flags in .app.json at the plugin root. This file is distinct from the manifest and contains platform-specific configurations that the host reads during initialization.

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 →