Agent Plugins shipped its 1.0.0 release this month. It is an open specification for packaging agent extensions, with a technical steering committee from Amazon, Cursor, Microsoft, OpenAI and Vercel, and the goal is that one directory installs into ChatGPT, Codex, Cursor, Copilot and VS Code.
Here we will go through what a plugin is, what the specification pins down, and what it leaves alone.
A plugin is a directory
plugin.json
skills/
summarize/
SKILL.md
mcp.json
com.example.client/
LICENSE
plugin.json identifies the package. skills/ holds Agent Skills, mcp.json declares MCP servers, and a reverse-domain directory holds anything a specific client wants to carry along.
Those locations are fixed by the spec rather than declared in the manifest, so a client checks those paths and nowhere else. Missing ones are not errors: no skills/ directory means the plugin has no skills, and loading carries on.
The manifest
Ten permitted top-level fields, of which two are required.
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "my-plugin"
}
The rest are metadata: version, description, author, homepage, repository, license, keywords, extensions. The schema is closed, so a vendor cannot add a top-level key of its own, and per-client data goes under extensions keyed by reverse domain instead.
Two failure modes, split. An unknown top-level field is reported and ignored, and the plugin still loads. Any other schema violation is fatal, and the spec says the client must reject the plugin and must not execute any of its components. Validation is offline, because clients must not fetch a schema while loading.
Skills and servers
Each immediate child directory of skills/ holding a SKILL.md is one skill, and the spec forbids searching deeper for more. The migration guide adds that SKILL.md’s name must match its parent directory. So twelve skills means twelve directories at the same level, and nesting is not a way to organise them.
mcp.json carries a mcpServers object, one entry per server, each declaring stdio, Streamable HTTP or HTTP+SSE. The stdio form is a command plus args, with environment placeholders expanded at load.
Component failures stay local. A broken skill is skipped and the rest of the plugin still loads.
What is not in v1
Distribution, installation, permissions, sandboxing and user experience are all explicitly out of scope. There is no registry and no trust model.
The org’s example plugin ships a migration skill, and its mapping table is more specific about the component side. Five rows say “no portable v1 destination”: hooks, custom agents and personas, commands and prompts, LSP servers, and UI integrations. The advice for each is to keep it in a client extension namespace or a separate compatibility package. If your plugin’s main feature is a hook, that part does not travel yet.
Where it sits
Both formats being standardised are Anthropic’s, and neither Anthropic nor Google is on the steering committee. The spec is a packaging layer agreed by the clients that consume Agent Skills and MCP, rather than a change to either.
Before this, the options were per-client config files, loose SKILL.md files dropped into ~/.claude/skills/ or ~/.codex/skills/, and host marketplaces like Claude Code’s, which is how I ship ilo. Of those, none put skills and servers in one package under one identity. This does, and the conversion for an existing plugin is mostly moving files.