# How to Describe the Capabilities of an OpenAI Plugin

> Describe OpenAI plugin capabilities by declaring them in the manifest file. Clearly define actions like Read, Write, or Interactive for LLM authorization.

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

---

**You describe the capabilities of an OpenAI plugin by declaring them in the `capabilities` array inside the `interface` object of the manifest file located at `plugins/<plugin>/.codex-plugin/plugin.json`, which explicitly tells the LLM what actions—such as `Read`, `Write`, or `Interactive`—the plugin is authorized to perform.**

The `openai/plugins` repository uses a manifest-driven architecture to ensure secure, discoverable integrations. By enumerating capabilities in a standardized JSON schema, developers provide the LLM with a strict permissions boundary that prevents unauthorized operations while enabling precise skill routing.

## Where Capability Definitions Live

### The Plugin Manifest File

The canonical source of truth for plugin capabilities is the **manifest file** at `plugins/<plugin>/.codex-plugin/plugin.json`. This file contains an `interface` object that exposes human-readable metadata and the critical `capabilities` array. For example, the Figma plugin declares three capabilities in [`plugins/figma/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/figma/.codex-plugin/plugin.json):

```json
"capabilities": [
  "Interactive",
  "Read",
  "Write"
],

```

### Runtime Configuration

The **[`.app.json`](https://github.com/openai/plugins/blob/main/.app.json)** file (e.g., [`plugins/google-drive/.app.json`](https://github.com/openai/plugins/blob/main/plugins/google-drive/.app.json)) stores runtime configuration such as authentication scopes and entry points, but it does **not** define capabilities. While essential for execution, it plays no role in the LLM's permission discovery phase.

### Skill Implementations

Individual capabilities map to **skills** stored under `plugins/<plugin>/skills/<skill-name>/`. Each skill contains a [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) file describing the implementation logic and may include an [`agents/openai.yaml`](https://github.com/openai/plugins/blob/main/agents/openai.yaml) file that binds the capability to LLM triggers. For instance, the Google Drive plugin implements its `Write` capability through the skill documented at [`plugins/google-drive/skills/google-drive/SKILL.md`](https://github.com/openai/plugins/blob/main/plugins/google-drive/skills/google-drive/SKILL.md).

## Declaring Capabilities in the Manifest

The `capabilities` array accepts standard permission strings that control LLM interaction models. Valid values include:

- **Interactive** – Authorizes multi-turn conversations where the plugin can ask clarifying questions or request additional input.
- **Read** – Permits data retrieval without modification (e.g., fetching documents or metadata).
- **Write** – Allows creation or modification of resources (e.g., updating spreadsheets or creating files).

The Google Drive plugin demonstrates a restricted permission set in [`plugins/google-drive/.codex-plugin/plugin.json`](https://github.com/openai/plugins/blob/main/plugins/google-drive/.codex-plugin/plugin.json):

```json
"capabilities": [
  "Interactive",
  "Write"
],

```

If a user requests a `Read` operation from this plugin, the LLM will refuse or route the request to a different plugin with explicit `Read` authorization.

## How the System Enforces Capabilities

The OpenAI plugin framework validates capabilities through a four-stage pipeline defined in the core loader logic (referenced in [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json)):

1. **Manifest parsing** – The loader reads `plugins/<plugin>/.codex-plugin/plugin.json` and extracts `interface.capabilities`.
2. **Capability enforcement** – The runtime validates incoming LLM calls against this whitelist before processing.
3. **Skill dispatch** – Valid requests route to the appropriate skill folder under `plugins/<plugin>/skills/`.
4. **Execution** – The skill executes external API calls (e.g., Google Drive API) and returns structured data to the LLM.

If an operation lacks a corresponding capability declaration, the system blocks execution at the enforcement stage, ensuring security by default.

## Extending Plugin Capabilities

To add a new capability, you must update both the manifest and implement the supporting skill logic:

1. Edit `plugins/<plugin>/.codex-plugin/plugin.json` to append the new capability to the `capabilities` array:

```json
"capabilities": [
  "Interactive",
  "Write",
  "Delete"
]

```

2. Create a new skill directory at `plugins/<plugin>/skills/<new-skill>/` containing a [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) that documents the API calls and parameters required to execute the new action.

The LLM will only recognize the new capability after the manifest is reloaded and the skill is properly registered in the marketplace configuration at [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json).

## Programmatically Reading Capabilities

You can extract capability declarations using standard JSON parsing. The following Python function loads the capability list for any plugin:

```python
import json
import pathlib

def load_capabilities(plugin_name: str) -> list[str]:
    """Load the declared capabilities of a plugin."""
    manifest_path = pathlib.Path(
        f"plugins/{plugin_name}/.codex-plugin/plugin.json"
    )
    with manifest_path.open() as f:
        data = json.load(f)
    return data["interface"]["capabilities"]

# Example: list capabilities for the figma plugin

print(load_capabilities("figma"))

# Output: ['Interactive', 'Read', 'Write']

```

To modify capabilities programmatically, apply a JSON Patch operation:

```json
{
  "op": "add",
  "path": "/interface/capabilities/-",
  "value": "Delete"
}

```

When the LLM invokes a plugin action, the backend performs a runtime check against the manifest before routing:

```http
POST /v1/plugins/google-drive/actions/run
Content-Type: application/json
Authorization: Bearer <token>

{
  "action": "deleteFile",
  "parameters": {
    "fileId": "1A2B3C4D5E"
  }
}

```

The request succeeds only if `"Delete"` appears in the plugin's `capabilities` array.

## Summary

- **Describe capabilities** by editing the `capabilities` array in `plugins/<plugin>/.codex-plugin/plugin.json`.
- **Standard values** include `Interactive`, `Read`, and `Write`, which define the LLM's permission boundaries.
- **Enforcement** occurs at runtime when the plugin loader validates requests against the manifest before dispatching to skills in the `plugins/<plugin>/skills/` directory.
- **Extend capabilities** by updating the manifest and creating corresponding skill documentation in [`SKILL.md`](https://github.com/openai/plugins/blob/main/SKILL.md) files.

## Frequently Asked Questions

### What file describes the capabilities of an OpenAI plugin?

The capabilities are described in the **manifest file** at `plugins/<plugin>/.codex-plugin/plugin.json`. Specifically, the `interface.capabilities` array contains the list of authorized actions that the LLM can invoke.

### What are the standard capability values for OpenAI plugins?

The standard values are **`Interactive`** (multi-turn conversation), **`Read`** (data retrieval), and **`Write`** (resource modification). These strings appear in the `capabilities` array and determine which requests the LLM will route to the plugin.

### How does the LLM know what a plugin is allowed to do?

The LLM discovers permissions by reading the **`interface`** object in the plugin manifest during the discovery phase managed by [`.agents/plugins/marketplace.json`](https://github.com/openai/plugins/blob/main/.agents/plugins/marketplace.json). Before executing any action, the system checks the request against the `capabilities` array to ensure the operation is explicitly authorized.

### Can I add custom capabilities beyond Read, Write, and Interactive?

Yes, you can declare custom capability strings in the manifest (e.g., `"Delete"` or `"Admin"`), but you must also implement the corresponding skill logic under `plugins/<plugin>/skills/` and ensure the plugin framework's enforcement layer recognizes the new capability type. The LLM will only invoke actions that match declared capabilities.