ADR-018: Agent Plugins v1.0.0 Standard Interop (parallel data-package format)
Status
Proposed — spec at ../features/agent-plugins/spec.md;
scope decisions confirmed with @evereq 2026-08-09 (both component types, all three
source kinds, strictly additive).
Date
2026-08-09
Context
Agent Plugins v1.0.0 is an
open, vendor-neutral packaging standard for agent capabilities with exactly two
component types: Skills (delegating SKILL.md format to the
Agent Skills spec) and MCP servers
(a mcp.json connection-config format over the
MCP spec). We want Ever Works
Agents to consume and produce this standard.
Ever Works already has a plugin system — but it is a different kind of thing:
native plugins are executable TypeScript packages declared via an open
everworks.plugin manifest in package.json, dynamically import()-ed by
PluginLoaderService, with capabilities/settings/lifecycle (ADR-012, ADR-016).
The Agent Plugins manifest is a closed schema (plugin.json,
additionalProperties: false) describing an inert data directory. The two
manifests are mutually incompatible by construction:
- Spec
namepermits dots and 1-char names; ourPLUGIN_ID_PATTERN(plugin-manifest-validator.service.ts) forbids both and enforces a 3-char minimum. - Our validator fatally rejects non-semver
version; spec §4.4 forbids a client from rejecting exactly that. - Our manifest requires
id/name/version/category(plugin-manifest-validator.service.ts:45-48);idandcategoryare not legal top-level keys in the spec manifest at all.
Meanwhile, the destination side of skills is already built: the
skills-provider capability seam (SkillsFacadeService fan-out, first-wins slug
dedupe), Skill rows with an open frontmatter json column, install → bind →
progressive-disclosure prompt injection + getSkillBody tool. The missing pieces
are a spec-conformant package reader, an MCP client (we only ship an MCP
server, apps/mcp), and an export serializer.
Decision
-
Parallel format, never a merge. Agent Plugins packages are a second, coexisting format. Native plugins do not gain
plugin.json; spec packages never contain platform-executable plugin code;PluginManifestValidatoris not reused and not relaxed. A new, standalone conformance library implements the closed spec schemas (plugin.json, mcp.json, Agent Skills frontmatter), discovery, path containment, and${PLUGIN_ROOT}/${PLUGIN_DATA}expansion. -
Platform bridge services connect the two worlds. A new module in
packages/agent/src/agent-plugins/exposes (a) package skills through an additive, optional second source inSkillsFacadeService— merged last, so catalog/install/bindings/injection are reused unchanged and existing entries can never be displaced — and (b) MCP server configs through aMcpServerConfigServiceconsumed by a new MCP client service inpackages/agent(official@modelcontextprotocol/sdk, per NN #22). This is deliberately NOT a native plugin: plugins are instantiated bare with no repository access, and the package registry is tenant-scoped DB state a plugin could neither query nor scope (and theskills-providerseam is scope-blind). -
Sources: local directory, git, npm — data-only acquisition. Local dirs are registered in place. Git sources are fetched ref-pinned. npm sources are tarball-extracted without
npm installand without lifecycle scripts (data packages have no dependencies to install). Source configuration and allowlisting follow the shape of ADR-016 but form a separate, parallel channel: ADR-016's registry/trust config governs code plugins; this ADR's sources govern data packages. Neither reuses the other's trust grants. -
Trust boundary: parsing is safe; only stdio executes. Reading manifests, skills, and
mcp.jsonis pure data handling and is available everywhere. Remote MCP transports (streamable-http,sse) are outbound network clients, enabled where outbound policy allows, with Ever Works-managed credentials injected as client-generated headers (never stored in packages — spec §6.2.1 forbids it).stdioMCP servers execute a subprocess: disabled by default, operator-enabled on self-hosted/desktop; on the managed SaaS, stdio stays disabled in v1 — enabling it there requires a sandboxed execution route this feature does not build (explicit follow-up decision). Skill sidecarscripts/are never executed by the platform itself — but a CLI-runner workspace IS an execution surface (the runner spawns without a sandbox), soscripts/materialization is gated by the same execution gate as stdio, while non-executablereferences//assets/materialize under standard content validation only. -
works.everis our extension namespace (reverse-domain ofever.works), for Ever Works-specific data in exported manifests (extensions["works.ever"]) and, if ever needed, aworks.ever/package directory. We ignore all other namespaces without validating them (spec §7). -
Full client conformance is the target — spec §10.1 including the optional
ssetransport, proven by a fixture suite of valid and malformed packages exercising every MUST (fatal vs non-fatal manifest errors, skip-one-skill, disable-MCP-only, per-server skip, containment escapes, expansion rules).
Consequences
- Ever Works can truthfully claim "Agent Plugins v1.0.0 compatible (client, skills + MCP)" and "exports Agent Plugins packages".
- Two manifest validators exist permanently, by design. Documentation must say plainly which format a given directory is.
- New persistent surfaces: installed-package registry table, per-package
PLUGIN_DATAdirectories (persistent storage in SaaS), MCP server bindings table, new env vars for the packages/data dirs — each wired through deploy manifests per the 2026-06-12PLATFORM_ENCRYPTION_KEYlesson. - The unwired
checkForUpdatesseam onskills-providerbecomes load-bearing (update-available indicators for git/npm sources). - Export makes our skills portable to any conformant client — the open-standard posture matches the product's "you own everything" positioning.
Alternatives considered
- Extend the native manifest to swallow the spec — rejected: the schemas conflict on closed-vs-open and validation severity; merging would either relax our validator (regression risk for 102 plugins) or violate spec MUSTs.
- Skills-only conformance (§10.2) — valid per spec, rejected by product: MCP servers are half the standard's value and the founder wants full support.
- Treat spec packages as a new native plugin category — rejected: spec
packages are data; loading them through
import()-based machinery would grant them a code-execution trust class they must not have.