On 24 July 2026, the agentic tooling ecosystem reached what looked like a decisive milestone: the publication of the Agent Plugins v1.0.0 specification by the Agent Plugins Working Group. Across coding agents such as GitHub Copilot, Claude Code, OpenAI Codex, and Cursor, the unit of extension had already converged on a recognizable shape: a directory containing a manifest alongside some combination of skills (markdown instruction files loaded when a task matches), sub-agents, slash commands, lifecycle hooks, and Model Context Protocol (MCP) servers exposing tools. Until July 2026, however, each vendor defined its own client-specific directory layout, forcing authors to restructure or duplicate their bundles for every target host.
The promise of Agent Plugins v1.0.0 was simple: place a single plugin.json manifest at the bundle root, follow fixed path conventions for components, and let any conforming coding agent load the package without out-of-band instructions.
Two months later, the empirical reality of the open-source plugin ecosystem tells a far more sobering story. In a comprehensive census of 68,072 plugin bundles across 30,655 public GitHub repositories (AgentPluginZoo, Tezan Sahu, arXiv:2609.23809, September 2026), alongside 157,062 standalone skills and 1,379 standalone MCP configurations, two structural truths emerge. First, strict conformance in the wild is rare (6.2%), though the barrier is shallow (96.6% of parseable manifests load once a single missing $schema boilerplate declaration is added). Second, and far more consequentially, even 100% schema conformance would not make plugins work reliably together: 40.2% of loadable manifests have author-written fields silently discarded by conforming clients, 95.6% of multi-vendor manifest copies drift out of semantic sync, and 81% of capability-exporting bundles collide on a capability name claimed by another plugin.
Standardizing a single-package layout without a formal model for multi-plugin composition and execution isolation merely turns fragmentation into packaged chaos.
The Anatomy of an Agent Plugins v1.0.0 Bundle
To understand why conforming plugins still fail in practice, we have to examine what Agent Plugins v1.0.0 actually standardizes and what it deliberately omits. The specification standardizes a package layout, not a runtime API or a composition model. Its portability claim rests on two design decisions:
- A single closed root manifest (
plugin.json): Exactly oneplugin.jsonsits at the package root, carrying identity and provenance metadata ($schema,name,version,description,author,license,repository). - Convention-based component discovery: A conforming client does not read
plugin.jsonto learn what capabilities a plugin ships. Instead, it walks fixed paths on disk, specificallyskills/*/SKILL.mdfor skills andmcp.json(or.mcp.json) for MCP tool servers.
my-plugin/
βββ plugin.json # Closed identity manifest ($schema, name, version, ...)
βββ skills/ # Convention-discovered skills
β βββ code-review/
β βββ SKILL.md
βββ mcp.json # Convention-discovered MCP server definitions
βββ com.example.client/ # Reverse-domain directory for vendor-specific files
A strictly conforming v1.0.0 plugin.json manifest looks like this:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "my-plugin",
"version": "1.0.0",
"description": "Automated architectural conformance and security review plugin.",
"author": {
"name": "Example Maintainer"
},
"license": "MIT",
"extensions": {
"com.example.client": {
"customSetting": true
}
}
}
Version 1.0.0 standardizes only two component types: skills and MCP servers. Slash commands, lifecycle hooks, sub-agents, rules, and language servers were deferred as too client-specific to standardize in v1.0.0. To accommodate vendor-specific features, the specification sanctions a top-level reverse-domain directory (com.example.client/) and a matching extensions object inside plugin.json, but explicitly assigns no portable discovery, validation, loading, or failure semantics to either.
Crucially, the JSON Schema (Draft 2020-12) governing plugin.json enforces three asymmetric validation rules that drive the failure modes observed in the wild:
- The schema is closed (
additionalProperties: false): Any top-level field not explicitly named in the v1.0.0 schema is a schema violation. $schemais mandatory alongsidename: Omitting$schemais a fatal violation; a conforming client must reject the plugin and refuse to discover or execute any of its components.- Unknown top-level fields are non-fatal but silently discarded: If a manifest includes an unrecognized top-level field (such as
skills,commands,hooks, oragents), a conforming client must report and ignore the unknown field and continue loading the plugin.
What 68,072 Plugins Reveal: Five Empirical Failure Modes
By scoring all 68,072 bundles in AgentPluginZoo (assembled across 30,655 repositories from 22,901 distinct owners) against the normative v1.0.0 schema and loading rules, Sahu (2026) decomposed ecosystem failures into five distinct phenomena:
AgentPluginZoo Conformance & Composition Breakdown (68,072 Bundles)
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Strictly validate against v1.0.0 JSON Schema 4,237 (6.2%) β
β Loadable as-is by a conforming v1.0.0 client 4,357 (6.4%) β
β Place plugin.json at the portable bundle root 13,417 (19.7%) β
β Loadable after adding missing $schema boilerplate 65,729 (96.6%) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Silent field loss (host discards top-level fields) 27,291 (40.2%*) β
β Multi-manifest bundles with semantic drift 3,822 (95.6%**) β
β Capability-exporting bundles with name collisions 25,840 (81.0%***) β
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
* Among manifests that load after adding $schema.
** Among a random sample of 3,998 multi-manifest bundles (out of 9,857 total).
*** Among the 31,901 bundles that export at least one named capability.
1. The $schema Cliff vs. Silent Field Loss
At first glance, strict schema validation paints a bleak picture: only 4,237 bundles (6.2%) validate end-to-end, and a conforming client would load only 6.4% as-is while rejecting 93.6% outright. Yet when every parseable manifest is granted a single missing $schema declaration without changing anything else, 96.6% load. Only 2,343 bundles (3.4%) fail for deeper structural reasons, two-thirds of which are naming-constraint violations (such as uppercase characters in the 1-to-64 lowercase character name field).
The deeper hazard lies in what happens after those 96.6% load. Among manifests that load once $schema is present, 40.2% (27,291 bundles) contain at least one top-level field that the closed specification obliges the client to discard. Even more revealingly, 32% of bundles explicitly write top-level fields such as skills, mcpServers, commands, hooks, or agents into plugin.json so that a human or registry reading the manifest can see what the plugin ships. Others add dependencies (declaring that one plugin requires another) or userConfig (declaring required runtime settings).
Although the specification provides the extensions object for non-standard fields, only 1.9% of manifests across 129 reverse-domain namespaces actually use it, compared with 43% that write forbidden fields at the top level. Because unknown top-level fields are non-fatal, the plugin appears to load cleanly while the host silently throws away the author's capability declarations, dependencies, and configuration requirements.
2. The Portability Tax and Multi-Manifest Drift
If a vendor-neutral format exists, the portable choice is to place one plugin.json at the bundle root. In practice, only 19.7% (13,417 bundles) do so; the remaining 80.3% keep their manifests inside vendor-specific directories (such as .claude-plugin/ or .cursor/). Recomputing this metric over the 36,157-bundle sub-corpus discovered without vendor-path queries confirms that the pattern is genuine rather than a search artifact.
Vendor lock-in strongly suppresses standards adoption:
- Bundles using no vendor directory conform at 23.2% ($n = 10,511$).
- Bundles locked into exactly one vendor directory conform at just 2.0% ($n = 49,309$).
- Bundles spanning two or more vendor directories recover to 9.7% ($n = 8,252$).
To support $k$ coding agents today, maintainers frequently pay a portability tax by maintaining $k$ copies of the manifest across client-specific folders. Within AgentPluginZoo, 9,857 bundles (14.5%) ship two or more manifest files. Across a random sample of 3,998 such multi-manifest bundles, 95.6% had copies that were no longer semantically identical, and 7.3% disagreed on the plugin's own name. Depending on which coding agent opens the repository, the exact same bundle announces itself under different identities or capability sets.
3. Adoption Trajectory: Growing, Yet Blind to Composition
By tracing the specification repository's commit history to the signed commit "Publish Agent Plugins Specification 1.0.0" on 24 July 2026, Sahu (2026) measured whether the ecosystem is converging over time. Splitting the corpus by repository creation date shows conformance rising more than sixfold, from 3.2% before 24 July 2026 ($n = 55,881$) to 19.9% after ($n = 12,191$). Among the 45,796 bundles in repositories pushed to after publication, conformance stands at 9.3%, reaching 10.4% (with 15.5% declaring $schema) among the 38,331 bundles touched in the final 30 days of the census window.
While adoption of the packaging envelope is accelerating, roughly nine out of ten actively maintained bundles still fail strict validation, and the specification's progress is confined entirely to single-bundle formatting.
4. The Capability Name Collision Crisis
Users rarely install a single plugin in isolation, and host runtimes already strain under multi-plugin loads. Visual Studio Code caps agent mode requests at 128 tools (a ceiling easily hit by enabling a few MCP servers), OpenAI Codex budgets the skill list to 2% of the context window before silently omitting skills, and controlled evaluations by Repantis et al. (2026, arXiv:2605.24660) show that LLM tool-selection accuracy drops from 93.1% to 87.1% as the offered tool list grows.
Extracting every capability exported across AgentPluginZoo (skills, sub-agents, commands, and hooks) yielded 409,935 capability records spanning 94,837 distinct skill names:
Capability Collision Metrics Across AgentPluginZoo (409,935 Records)
β’ Distinct skill names claimed by >1 plugin: 28.0% (of 94,837 names)
β’ Individual skill instances carrying a contested name: 78.0%
β’ Capability-exporting bundles with β₯1 name collision: 81.0% (of 31,901 bundles)
β’ Cross-owner collision rate (excluding same-org forks): 74.0%
Most Contested Capability Names by Distinct Repository Owners:
1. code-reviewer (claimed by 300 distinct repository owners)
2. systematic-debugging (claimed by 221 distinct repository owners)
Because popular task names attract independent authors, 78% of all individual skills carry a name that another plugin also claims, and 81% of the 31,901 capability-exporting bundles (74% when requiring the conflicting claim to come from a different repository owner) collide on at least one capability name.
When a developer installs two plugins that both export code-reviewer or systematic-debugging, Agent Plugins v1.0.0 defines no namespace and no precedence rule. Resolution is left entirely to client quirks: Claude Code forcibly prefixes plugin skills by vendor convention, GitLab Duo resolves collisions by selecting "the first one it encounters" in directory traversal order, and other hosts silently overwrite earlier registrations.
5. Unbounded Execution and Security Drift
Beyond naming and manifest loss, empirical security studies on the underlying components show why packaging without runtime isolation is hazardous:
- Skill vulnerabilities at scale: Mining 42,447 agent skills in the wild, Liu et al. (2026, arXiv:2601.10338) documented widespread prompt-injection surfaces, unchecked shell execution patterns, and credential exposure in community skill files.
- MCP server drift and maintainability flaws: Hasan et al. (2025, arXiv:2506.13538) identified pervasive security and maintainability defects across public MCP servers, while Kraishan (2026, arXiv:2609.14119) demonstrated "same name, different server" silent drift across MCP server versions and registries.
Architectural Patterns for Real Interoperability
As Sahu (2026) argues, the community standardized a packaging format (checkable on a single directory sitting on disk) when multi-plugin installations require a composition model (rules governing plugins in relation to one another and to the host runtime). Reconciling portability with safety requires four architectural upgrades, three of which fit cleanly into an additive v1.1 profile of the specification alongside host-level sandboxing:
Unbounded v1.0.0 Loading (Flat Namespace & Silent Field Loss):
βββββββββββββββββββββββ Agent Host ββββββββββββββββββββββββ
β Plugin A (code-reviewer) βββ β
β βββ> Traversal-Order Clash β
β Plugin B (code-reviewer) βββ (Host-dependent winner)β
β plugin.json ("dependencies", "hooks") ββ> Silently β
β Discarded β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
v1.1 Composition Model + Sandboxed Host Runtime:
βββββββββββββββββββββββ Agent Host ββββββββββββββββββββββββ
β 1. Declared Surface & Dependency Check (Pre-Install) β
β 2. Qualified Identity Router: β
β plugin_a:code-reviewer vs plugin_b:code-reviewerβ
β 3. Deterministic Precedence / Disambiguation Policy β
β 4. Container / Wasm Sandbox for MCP & Hook Execution β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
Pattern 1: Qualified Capability Identity (plugin:capability)
A capability must never exist solely in a flat global namespace. Every skill, command, sub-agent, and tool should carry a qualified canonical identity of the form plugin_name:capability_name, treating the bare name (code-review) only as a convenience alias when unambiguous:
from typing import Any, Callable
class QualifiedPluginRegistry:
"""Enforces qualified plugin:capability identity and explicit conflict policy."""
def __init__(self) -> None:
self._capabilities: dict[str, Callable[..., Any]] = {}
self._aliases: dict[str, list[str]] = {}
def register(
self,
plugin_name: str,
capability_name: str,
handler: Callable[..., Any],
) -> str:
qualified_id = f"{plugin_name}:{capability_name}"
if qualified_id in self._capabilities:
raise ValueError(f"Duplicate capability within plugin: {qualified_id}")
self._capabilities[qualified_id] = handler
self._aliases.setdefault(capability_name, []).append(qualified_id)
return qualified_id
def resolve(self, identifier: str) -> Callable[..., Any]:
# 1. Exact qualified lookup ("sentinel:code-reviewer")
if identifier in self._capabilities:
return self._capabilities[identifier]
# 2. Bare alias lookup ("code-reviewer") with deterministic ambiguity error
matches = self._aliases.get(identifier, [])
if len(matches) == 1:
return self._capabilities[matches[0]]
if len(matches) > 1:
raise RuntimeError(
f"Ambiguous capability '{identifier}' claimed by multiple plugins: "
f"{matches}. Use a qualified 'plugin:capability' identifier."
)
raise KeyError(f"Unknown capability: '{identifier}'")
Pattern 2: Declared Capability Surface and Composition Relations in plugin.json
Instead of forcing 32% of authors to write illegal top-level fields that conforming clients silently discard, the manifest schema should allow an optional declared capability surface alongside inter-plugin relations (dependencies, conflicts, and required userConfig). Declaring exported capabilities in plugin.json enables registries, CI pipelines, and host installers to detect name collisions and resolve dependency graphs (an NP-complete problem in non-trivial component models; Abate et al., 2020) before downloading and walking the bundle tree.
Until the v1.1.0 specification incorporates these fields at the top level, authors targeting v1.0.0 hosts should place client-specific and composition metadata inside the sanctioned extensions reverse-domain object and generate any required vendor-specific manifest copies from a single source of truth in CI so the 95.6% multi-manifest drift rate cannot occur.
Pattern 3: Sandboxed MCP and Hook Execution
Finally, even a conflict-free composition model must bound what a plugin can execute on the host. Rather than spawning MCP servers or hook scripts as unisolated host processes inheriting ambient credentials and filesystem access, agent runtimes should execute tool servers inside declarative container or WebAssembly sandboxes with explicit environment allowlists and fail-closed lifecycle hook timeouts:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "isolated-code-reviewer",
"version": "1.0.0",
"description": "Sandboxed static analysis plugin with explicit capability scoping.",
"author": { "name": "Arne Burk" },
"license": "Apache-2.0",
"extensions": {
"io.agentruntime.sandbox": {
"engine": "oci-container",
"image": "ghcr.io/org/agent-linter:1.0.0",
"read_only_rootfs": true,
"required_env": ["LINTER_TOKEN"],
"hook_policy": "fail_closed"
}
}
}
Conclusion: From Package Format to Composition Model
The Agent Plugins v1.0.0 specification solved a real problem: it gave a single plugin bundle an agreed layout on disk. Yet the empirical evidence from 68,072 bundles in AgentPluginZoo proves that standardizing how one extension is shipped does not standardize what happens when several run together.
Turning portable packaging into reliable operational interoperability requires closing both halves of the gap:
- For plugin authors today: Always place
plugin.jsonat the bundle root with an explicit$schemadeclaration (eliminating the cause of 93.6% of load rejections), prefix capability names rather than shipping generic names likecode-reviewer, put non-standard metadata insideextensionsso hosts do not silently drop 40.2% of manifests' fields, and generate any legacy vendor manifests automatically in CI. - For the specification and host runtimes: Evolve v1.1 from a single-package format into a true composition model with qualified
plugin:capabilityidentities, a declared capability surface inplugin.json, deterministic collision and precedence rules, and sandboxed runtime execution boundaries.

Comments (0)
Please sign in to leave a comment