What it is
A plugin is one named, versioned package of MCP servers and skills. Install it into a harness and every task of that harness gets its tools and skills beside the harness's own, without copying them into each configuration.
Plugins use the open Agent Plugins format, so the same package installs into any harness that takes plugins, and a harness you have already configured can be exported as one.
What a package holds
- plugin.json
- The manifest, at the root, and required. It names the Agent Plugins schema it follows, and its name names the plugin: 1 to 64 lowercase letters, digits, hyphens and dots, starting and ending with a letter or digit.
- mcp.json
- MCP servers over stdio, streamable HTTP or SSE. A remote server is reached over https.
- skills/<name>/SKILL.md
- One folder per skill. The skill's name in its frontmatter matches the folder name, and its description is at most 1,024 characters.
- Anything else
- Scripts, templates and data the skills and servers use. Every file directly in bin/, and each .sh file directly in hooks/, is made executable.
Installing one
- In the console, open a harness's settings and choose Install from folder under Plugins. The package installs when you save, and each installed plugin can be downloaded as a zip or removed.
- From the API, send the package's files in the harness's plugins list when you create or update it. A text file goes in content and a binary one in content_b64.
- To keep an installed package as it is, send it back as {"name", "blob"} the way the harness returned it. Sending files replaces it, and leaving it out of the list uninstalls it.
POST /v1/harnesses
{
"name": "Contract Review Agent",
"base": "claude-code",
"plugins": [{
"enabled": true,
"files": [
{"path": "plugin.json", "content": "{\"$schema\": \"https://agent-plugins.org/schemas/1.0.0/plugin.schema.json\", \"name\": \"contract-review\", \"version\": \"1.0.0\"}"},
{"path": "skills/risk-checklist/SKILL.md", "content": "---\nname: risk-checklist\ndescription: ...\n---\n..."}
]
}]
}What a task gets
Each enabled plugin adds its skills and MCP servers to the harness's own. The package is unpacked into the task under .harness/plugins/, with a writable folder for it under .harness/plugin-data/, each named after the plugin with hyphens and dots written as underscores, and stdio servers find the two through PLUGIN_ROOT and PLUGIN_DATA.
A server or skill that cannot load does not fail the harness. The harness record lists it, with the reason, under skipped or notLoaded, so you can see what a task will and will not have.
A harness and its plugins share one set of MCP server and skill names, and no two plugins share a name. A plugin that breaks either rule is refused when you save, with plugin_conflict naming both sides, rather than shadowing a server or skill at run time.
Exporting and reading back
GET /v1/harnesses/{id}/plugin the harness's own tools and skills as a package, credentials left out
GET /v1/harnesses/{id}/plugins/{name}/files the files of one installed packageErrors
- 422 plugin_invalid
- The package or its manifest is not valid, for example a missing plugin.json or a path outside the package.
- 422 unsupported_plugin_schema
- The manifest names a schema this server does not read. The error lists the supported ones.
- 413 file_too_large
- The package is over the size limit.
- 409 plugin_conflict
- An MCP server or skill name clashes with the harness or another plugin, or two plugins share a name.
- 404 plugin_not_found
- No installed plugin has that name.
Limits
- One package
- Up to 16 MiB.
- Manifest
- Up to 24,000 bytes, with what is derived from it.
- System One
- Takes no skills, so a plugin's skills are left out on that base.
The plugin object, how its files are read, and the single namespace a harness shares with its plugins are defined by the protocol, so a package built for one conforming server installs on another. See UHP plugins chapter.
Ready to run this against a live workspace? Keys take under a minute.

