| name | plugin-author-helper |
| description | Design, validate, and ship a marketplace Plugin (or Skill bundle) with proper manifest format, multi-ecosystem compatibility, version pinning, manifest fallback, install idempotency, and three-layer startup sync.
USE WHEN: writing a new Plugin manifest, picking manifest format (Legacy vs AgentPlugin), adding `skills` / `mcp_servers` / `apps` / `hooks` / `interface` fields, validating a plugin before publish, designing marketplace install/remove/upgrade flows, or any task involving "make my plugin actually work in Codex".
TRIGGER PHRASES: "plugin manifest", "PluginManifest", "marketplace", "agent plugin", ".agents/plugins/marketplace.json", "manifest fallback", "idempotency key", "plugin author", "plugin publish", "plugin version", "startup sync", "lock file".
SKIP WHEN: writing a single skill (use `skill-auto-select`), pure MCP server (use `mcp-server` directly), one-off tool without packaging.
|
| license | Apache-2.0 |
| compatibility | Requires MiniMax Code with Agent Plugins 1.0 support. |
| metadata | {"author":"antianqi","version":"0.1.0","inspired-by":"https://github.com/openai/codex/tree/main/codex-rs/core-plugins/ (P-93/94/95/99)","changes-from-v0.0.0":"Initial design distilled from P-93/94/95/99 deep-dive (Phase 1 Week 4)."} |
Plugin Author Helper
Design, validate, and ship a Plugin that fits into the Codex (or compatible) Plugin
ecosystem. Mirrors the design of codex-rs/core-plugins/.
When to use
Activate when:
- Writing a new
plugin.json / marketplace.json manifest.
- Choosing between manifest formats (Legacy vs AgentPlugin).
- Validating a plugin before publish.
- Designing install / remove / upgrade / sync flows.
- Picking a plugin scope (User / System / Admin / Plugin) and pinning a version.
When NOT to use
- Single skill authoring → use
skill-auto-select.
- Pure MCP server (no Skill bundle) → use the
mcp-server crate's own conventions.
- One-off tool scripts → don't package.
Host runtime requirements
This Skill describes how to design a Plugin (manifest, idempotency, scope).
It does not cause the agent to install, modify, or publish anything on its own.
Specifically, the agent MUST NOT, on the strength of this Skill alone:
- Run
npm install / npm link / any package manager command for the user.
- Write or overwrite files in
~/.minimax/.../plugins/, ~/.codex/.../,
~/.config/, or any other user-level config directory.
- Hit a marketplace endpoint (download, install, upgrade) on the user's behalf.
- Trigger a plugin sync that reaches the network (3-layer fallback in Codex is a
Codex-runtime concept; MiniMax Code may or may not have an equivalent).
All of the above require explicit user confirmation in the host's normal
permission flow (approval_policy, ask mode, or whatever the host uses).
This Skill is for designing the manifest / sync flow, not for executing it.
The agent that runs the install / sync must follow the host's user-confirmation
policy, not the patterns in this Skill.
Process
1. Pick the manifest format
Codex supports two manifest formats:
| Format | Path | Notes |
|---|
Legacy | .claude-plugin/marketplace.json / .cursor-plugin/marketplace.json | Older ecosystems. |
AgentPlugin | .agents/plugins/marketplace.json / .agents/plugins/api_marketplace.json | Current Codex format. |
If the plugin should be cross-ecosystem (OpenAI + Claude + Cursor), ship both manifests and let the loader pick whichever it finds first.
2. Write the 8-field PluginManifest
struct RawPluginManifest {
name: String,
version: Option<String>,
description: Option<String>,
keywords: Vec<String>,
skills: Option<RawPluginManifestPaths>,
mcp_servers: Option<RawPluginManifestMcpServers>,
apps: Option<String>,
hooks: Option<RawPluginManifestHooks>,
interface: Option<RawPluginManifestInterface>,
}
Hard limits:
MAX_DEFAULT_PROMPT_COUNT: 3 — at most 3 default prompts in interface.
MAX_DEFAULT_PROMPT_LEN: 128 — each prompt ≤ 128 chars.
- All paths in
skills MUST use the ./... syntax (./skills/<id>/SKILL.md) and resolve under the plugin root.
3. Provide a manifest fallback
If the main manifest is missing or malformed, fall back to a known-good shape. The
fallback typically contains just name + version + a minimal skills list.
4. Use a 3-letter marketplace name taxonomy
Pick a short, descriptive name with one of these prefixes:
| Prefix | Meaning |
|---|
openai-curated | OpenAI-curated official |
openai-api-curated | OpenAI API curated |
openai-bundled | Bundled with Codex |
openai-bundled-alpha | Bundled alpha |
openai-primary-runtime | Primary runtime |
For your own marketplace, use <author>-<purpose> (e.g. acme-data-pipelines).
5. Use idempotency keys for create operations
pub struct CreateProjectParams {
pub name: String,
pub idempotency_key: String,
}
pub struct CreatedProject {
pub project: StoredProject,
pub created: bool,
}
Always require idempotency_key on create / install endpoints. The same key + same payload returns the existing object with created: false. Different key + same name creates a new object (no conflict).
6. Three-state updates: Option<Option<T>>
For partial-update APIs:
None — "do not touch this field".
Some(None) — "set this field to null/empty".
Some(Some(value)) — "set this field to value".
This is the only correct encoding for "no change vs explicit clear" in JSON.
7. Report moved vs unchanged
pub enum ProjectMoveOutcome { Moved, Unchanged }
Reorder APIs should return whether the operation actually moved anything. UI uses this to skip re-renders on no-ops.
8. Use a BTreeMap for metadata
Stable iteration order = stable output. Don't use HashMap for user-visible metadata.
9. Three-layer startup sync
When the marketplace needs to refresh plugins at every Codex startup, use this 3-layer fallback:
1) GitHub API → GET /repos/openai/plugins/git/refs/codex/curated-sync
compare SHA against .tmp/plugins.sha
if changed, download + extract
2) Backend archive fallback → GET /backend-api/plugins/export/curated
3) Git clone → git clone https://github.com/openai/plugins.git --branch refs/codex/curated-sync
Each layer has a 30s timeout. Use a lock file (.tmp/plugins.sync.lock) to prevent
concurrent syncs from multiple Codex processes. Use a SHA cache (.tmp/plugins.sha)
to skip work when nothing changed. Stale temp dirs (older than 10 min) are auto-cleaned.
10. Decide a scope per skill within the plugin
Each skill in your plugin should be User (user-installed) / System (bundled) / Plugin (this plugin) scoped. Document the scope in the frontmatter metadata.scope field.
Output contract
A plugin that follows this design:
- Has both
plugin.json (AgentPlugin) AND a fallback manifest.
- Has
name / version / description / keywords / skills / mcp_servers / apps / hooks / interface set.
- Default prompts ≤ 3 entries, each ≤ 128 chars.
- All skill paths use the
./... syntax.
- Has a marketplace name following the prefix taxonomy.
- All create / install endpoints require an
idempotency_key.
- Uses
BTreeMap for any user-visible metadata.
- If a startup sync is needed, it uses a 3-layer fallback with a lock file and SHA cache.
Common pitfalls
- No idempotency key → user retries after a network blip create duplicates. Always require it.
HashMap for metadata → JSON output flickers on every render. Use BTreeMap.
- Two syncs in parallel → file corruption. Lock file mandatory.
- Forgetting fallback layer → GitHub outage takes down all installs. Always have the archive + clone as backups.
- Default prompts > 3 or > 128 chars → silently truncated. Stay under the limit.
- Skill paths not starting with
./ → resolution fails. Always use ./skills/.../SKILL.md.
Option<T> instead of Option<Option<T>> → cannot distinguish "no change" from "set to null".
Example — minimal plugin manifest
{
"$schema": "https://agent-plugins.org/schemas/1.0/plugin.schema.json",
"name": "acme-data-pipelines",
"version": "0.1.0",
"description": "Data pipeline skills for ETL, schema validation, and warehouse sync.",
"keywords": ["data", "etl", "pipeline"],
"skills": "./skills/*/SKILL.md",
"mcp_servers": {
"warehouse": {
"transport": "stdio",
"command": "./bin/warehouse-mcp"
}
},
"interface": {
"display_name": "ACME Data Pipelines",
"brand_color": "#0066cc"
}
}
Verification checklist