Skip to main content
A plugin is a folder that bundles things o4 can use: slash commands, skills, subagent definitions, workflows, and, in some formats, MCP servers. Install a plugin to share a team’s commands and skills, or to use a set someone else has published. A marketplace is a catalog of plugins that you can install by name.

Install a plugin

Install from a local folder, a GitHub repository, or any git URL:
owner/repo is short for https://github.com/owner/repo.git. o4 clones the repository or copies the folder into its plugins folder:
The plugin’s commands show up as slash commands, and its skills and agents become available to the model. A plugin you install with o4 plugin install loads in your next session. A plugin you install from /plugins in a session is available in that session right away. o4 then restarts your MCP servers, so the plugin’s MCP servers start too.
A plugin can give the model new instructions and can start programs on your machine. Install plugins only from sources you trust.

Global and project plugins

By default a plugin is installed globally, in ~/.o4/plugins, and is available in every workspace. Use --project to install it into the current project’s .o4/plugins instead:
Project plugins only load in a trusted workspace, and --project refuses to install into an untrusted one. Run o4 trust in the project first. See Workspace trust. You can have the same plugin in both places. They’re listed separately.

List and remove plugins

o4 plugin list also warns when the current project has plugins that aren’t loaded because the workspace isn’t trusted.
o4 plugin remove removes the project copy if there is one, and otherwise the global one. It also removes any permissions you granted the plugin.

Marketplaces

A marketplace is a git repository or folder with a marketplace.json catalog. Register one, and you can install its plugins by name:
If two marketplaces list a plugin with the same name, pick one with name@marketplace:
o4 keeps marketplace data in ~/.o4/marketplaces. On the first interactive launch, if you haven’t registered any marketplaces, o4 tries once to register an official marketplace. If that fails, for example because you’re offline, o4 doesn’t try again, and you can add marketplaces yourself.

Create a marketplace

Put a marketplace.json at the root of a repository or folder, or in .o4-plugin/marketplace.json:
Each plugin’s source is one of:
  • A path inside the marketplace that starts with ./, for a plugin kept in the same repository. The path can’t lead outside the marketplace.
  • owner/repo, for a plugin in its own GitHub repository.
  • A full git URL.
  • A path to a folder elsewhere on your machine, only in a marketplace you added from a local folder.
The marketplace needs a name, and each plugin entry needs a name and a source. The Discover tab of /plugins shows each plugin’s description and category, and its filter searches them along with the plugin and marketplace names. owner, if present, needs a name and can have a url, but o4 doesn’t show it. A plugin entry’s version and tags are accepted but not used.

Manage plugins in a session

/plugins opens the plugin browser. It has four tabs:
  • Discover: plugins from your marketplaces. Select one to install it.
  • Installed: your plugins. Select one to update it (pull the latest changes from its source), validate its files, remove it, or revoke a saved capability grant (the granted: rows). Parts of the plugin that were skipped are listed as disabled component rows. The first row, Install plugin, installs from a git URL, owner/repo, or path, globally or for the project.
  • Marketplaces: your marketplaces. Add, refresh, or remove them here.
  • Errors: plugins or plugin files that failed to load, with the reason.
You can also go straight to an action with a subcommand: A plugin copied from a local folder can’t be updated. Install it again to pick up changes. While the model is working, you can still open the browser, validate plugins and revoke grants, but installing, updating or removing a plugin and refreshing or removing a marketplace are refused: o4 closes the browser and shows Wait for the current turn to finish before making this change. Typed commands that change plugins, such as /plugins install <source> and /plugins remove <name>, wait for the turn to finish instead. The Plugins tab in /config (run /config plugins to go straight to it) has one row, Open plugin browser. It opens the same plugin browser as /plugins. The browser starts on Discover, or on Installed when you have plugins, and returns to the tab you last used in the session.

What a plugin can contain

A plugin’s skills can include hooks in their front matter; those run while the skill is active (see Hooks in skills). Plugins in the portable, Codex, Claude Code, and Cursor formats can also declare MCP servers. See Plugin formats. o4 reads at most 256 files from each component folder, and 256 plugins from each plugins folder. A file that fails to load is listed on the Errors tab of /plugins; the rest of the plugin still loads. Print mode (o4 -p) doesn’t load plugin commands, skills, subagents or tools. It does start the MCP servers that plugins declare.

Commands

A command is a Markdown file in commands/. The file name is the command name, unless the front matter sets name:
When you run /changelog 2.4.0, o4 sends the body to the model, with these replaced: Built-in slash commands and your own skills take precedence over a plugin’s commands with the same name.

Workflows

A workflow runs a plugin’s commands one after another as stages. Define it in workflows/<name>.yaml:
commands maps each stage to one of the plugin’s commands. entry is the command for the first stage if commands doesn’t list one. agents can map a stage to one of the plugin’s agents, whose instructions are used for that stage. When state.path is set, o4 saves the workflow’s progress there, so a later run continues from the next stage. The path must be inside .o4/state/plugins/<plugin-name>/. Run workflows with /workflow:
--stage starts from a given stage. Text after the workflow name (and the stage) is passed to each stage’s command as $ARGUMENTS.

Tools

A plugin tool is a Markdown file in tools/ whose YAML front matter defines a tool the model can call. The body of the file isn’t used.
A binding has one of two types:
  • command runs a program. argv-template is the program and its arguments; each {parameter} in them is replaced with the value the model passed. o4 runs the program directly, not through a shell, in o4’s sandbox, from the plugin’s folder, with a minimal environment. The program must be inside the plugin’s folder or in /usr/bin, /bin, /usr/sbin or /sbin. timeout-ms defaults to 30000. The tool returns the program’s standard output, or its standard error if it fails.
  • template returns text, with each {parameter} replaced, without running anything.
A tool with the same name as a built-in tool, or as a tool from another plugin, isn’t loaded.

Approving plugin tools

o4 asks for your approval each time the model calls a plugin tool. A tool also needs each capability it uses; a command tool always needs exec. The first time, o4 asks you to grant the capability to the plugin: allow it once (y), allow it always (a), or deny it (n). An “always” grant is saved in ~/.o4/settings.json and tied to the plugin’s current files, so o4 asks again after the plugin is updated or changed. To revoke a grant, open the plugin in /plugins; each saved grant is listed as a granted: row that you can select to revoke. See Permissions. The sandbox blocks the program’s network access unless the tool has the network grant, and exec alone doesn’t let it write files. In o4 0.2.74, a tool that requires a path: grant always fails with “plugin path capabilities are disabled”.

Create a plugin

/plugins new team-tools creates a starter plugin in .o4/plugins/team-tools with a manifest, a /main command, a main workflow, and a README. o4 lowercases the name and turns other characters into -. The plugin loads right away. Edit the files, then start a new session to load your changes. The workspace must be trusted, because project plugins only load there. To build one by hand, make a folder with a manifest and any of the component folders:
The manifest, .o4-plugin/plugin.json:
name and version are required. The name can use letters, digits, ., _, and -, up to 128 characters. author can be a string or an object with a name. The manifest can also have capabilities and permissions:
  • capabilities lists what the plugin provides, as true or false for commands, agents, skills, workflows, state, ui and hooks. It’s descriptive only: it doesn’t turn anything on or off.
  • permissions limits what the plugin’s parts may use. A command whose allowed-tools, a subagent whose tools, or a skill whose allowed-tools names a tool outside permissions.tools isn’t loaded. A plugin tool whose required-grants asks for a tool outside permissions.tools, a path outside permissions.paths, or the network when network is false, isn’t loaded either. Each skipped part is listed on the Errors tab and as a disabled component row in the plugin’s details in /plugins, and o4 plugin list prints a warning for it. Tool names match without regard to case or punctuation.
Without permissions, none of these checks apply. o4 reads capabilities and permissions only from .o4-plugin/plugin.json. Install it from its folder to test it:
To share it, push the folder to a git repository and install it with o4 plugin install owner/repo, or list it in a marketplace.

Plugin formats

o4 looks for a manifest in this order and uses the first one it finds: So you can often install a plugin written for another agent as is. The portable format is stricter than o4’s own:
  • $schema must be https://agent-plugins.org/schemas/1.0.0/plugin.schema.json. o4 refuses other schema versions with unsupported Agent Plugins schema.
  • name can use lowercase letters, digits, . and -, up to 64 characters. It must start and end with a letter or digit, and can’t contain -- or ...
  • version is optional. o4 lists a plugin without one as unversioned.
  • author must be an object with only name, email and url.
  • version, description, author and homepage can’t be null.
The Codex, Claude Code, and Cursor manifests can point to skill folders with skills and to an MCP configuration with mcpServers. These paths must start with ./ and stay inside the plugin folder, or o4 refuses the plugin. mcpServers can also list the servers inline. MCP servers from plugins come from the portable format, which reads them from mcp.json in the plugin folder, and from the other agents’ formats, which read the manifest’s mcpServers, or .mcp.json in the plugin folder when the manifest has none. A plugin’s MCP servers start with your own servers. If a server in your .mcp.json has the same name, yours is used. See MCP servers.