Skip to content

Introduction

universal-plugin is a build tool for universal AI agent plugins. You write one canonical definition in root plugin.json, and universal-plugin build generates a spec-conformant vendor manifest for each runtime you target.

Every major AI coding agent runtime — Claude Code, Cursor, Codex, GitHub Copilot CLI — uses its own plugin.json format at a vendor-specific path. Targeting multiple runtimes means maintaining multiple manifest files that share ~60% of their content, hand-writing vendor-specific transformations (hook event casing, env var names, component fields), and re-syncing on every change.

A single source of truth in root plugin.json, following the closed Agent Plugins Specification v1.0.0 field set ($schema, name, version, description, author, homepage, repository, license, keywords, extensions). All universal-plugin build config — component paths, the vendor target list, and per-harness overrides — nests under extensions["org.cyberuni.universal-plugin"]. Running universal-plugin build produces each vendor’s manifest as a build artifact.

{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "my-plugin",
"extensions": {
"org.cyberuni.universal-plugin": {
"vendors": ["claude-code", "cursor", "codex", "copilot-cli"],
"skills": "./skills/",
"mcpServers": "./mcp.json",
"hooks": "./hooks/hooks.json",
"harnesses": {
"claude-code": { "monitors": "./monitors/monitors.json" },
"cursor": { "publisher": "my-org", "logo": "./assets/logo.png" },
"codex": { "version": "1.0.0", "description": "My plugin." },
"copilot-cli": {}
}
}
}
}

Running universal-plugin build from the plugin root generates:

VendorOutput
claude-code.claude-plugin/plugin.json
cursor.cursor-plugin/plugin.json
codex.codex-plugin/plugin.json
copilot-cliplugin.json
  • Hook event names — canonical PascalCase (SessionStart) is translated to each vendor’s casing (camelCase for Cursor, PascalCase for Claude Code and Codex).
  • Env vars — canonical ${PLUGIN_ROOT} is translated to vendor-native names in hook commands and MCP configs.
  • Vendor-specific fields — fields in extensions["org.cyberuni.universal-plugin"].harnesses.<vendor> are merged into the generated manifest; fields the vendor doesn’t support are dropped with a warning.
  • Required field enforcement — Codex requires version and description; build fails with a clear error if they’re missing.

The generated vendor manifests should be treated like compiled output — either gitignored (build on install) or committed (pre-built for distribution). The choice is yours; universal-plugin enforces neither.