AI agent clients each developed their own plugin formats, even when plugins contain the same underlying components. Authors rearrange or duplicate skills and MCP server configuration for every client, so a plugin packaged for one tool often needs adaptation before another can use it.
Agent Plugins solves this with an open, vendor-neutral specification for portable plugins. Version 1.0 defines a shared format for Agent Skills and MCP servers that any compatible client can discover and load consistently.
Copy link to headingOverview
In this guide, you'll learn:
- What Agent Plugins is and the problem it solves
- The structure of a plugin package and its manifest
- How skills and MCP servers work as portable components
- How client extensions add client-specific behavior without breaking portability
- How clients load plugins and isolate failures
- How to build your first plugin
Copy link to headingWhat is Agent Plugins?
Agent Plugins is a specification that defines a small interoperability floor for the parts of a plugin that can be portable across clients. An Agent Plugin is a self-contained directory with a required manifest (plugin.json) and optional components in fixed locations. Version 1.0 defines exactly two portable component types, both built on established specifications:
| Component type | Fixed location | Governed by |
|---|---|---|
| Skills | skills/ | Agent Skills specification |
| MCP servers | mcp.json | Model Context Protocol specification |
Agent Plugins doesn't redefine either format. It defines where components live inside a plugin, how clients discover and validate them, and how failures are isolated so one broken component doesn't take down the rest.
The specification is openly licensed and developed in public. Its initial Technical Steering Committee includes Core Maintainers from Amazon, Cursor, Microsoft, OpenAI, and Vercel, and proposals begin in GitHub Discussions where anyone can participate and help shape the specification.
Copy link to headingWhy a portable format matters
The specification separates portable behavior from client-owned behavior:
- Portable: package structure, manifest validation, component discovery, MCP configuration, plugin environment variables, and failure isolation.
- Client-owned: installation sources and marketplaces, enablement and update flows, permission prompts and sandboxing, and how skills are surfaced.
This split lets shared components use one predictable structure while clients keep full control of distribution, trust policy, and user experience. Clients can also adopt component types incrementally, so a skills-only client conforms without supporting MCP servers, as long as it supports at least one of the two.
Copy link to headingAnatomy of a plugin
A plugin is a directory rooted at a single filesystem location. A complete plugin with skills, an MCP server, and a client extension looks like this:
Each part has a fixed role:
plugin.jsonidentifies the plugin and the Agent Plugins version it targets. It's the only required file.skills/contains Agent Skills, one per immediate child directory.mcp.jsonconfigures stdio, Streamable HTTP, or legacy HTTP+SSE MCP servers.- Reverse-domain directories like
com.example.client/hold client-specific files that other clients can safely ignore.
One rule governs the whole package: every file a client discovers, reads, or executes must resolve within the plugin root, even after resolving symlinks and equivalent filesystem mechanisms. Plugin-relative paths in configuration begin with ./ and cannot escape the package.
Copy link to headingThe plugin manifest
Every plugin contains exactly one portable manifest at plugin.json.
The minimal manifest sits in the plugin root and needs only two fields:
The manifest schema is closed, meaning only these top-level fields are permitted:
| Field | Required | Purpose |
|---|---|---|
$schema | Yes | Selects the Agent Plugins version and validation contract. |
name | Yes | Human-readable plugin name and package identifier. |
version | No | Plugin version; Semantic Versioning is recommended. |
description | No | Short description of the plugin. |
author | No | Object with optional name, email, and url strings. |
homepage | No | Documentation or homepage URL. |
repository | No | Source repository URL. |
license | No | License string; an SPDX identifier is recommended. |
keywords | No | Array of search and discovery strings. |
extensions | No | Client-owned data keyed by reverse-domain namespace. |
Copy link to headingName constraints
Plugin names are 1 to 64 characters and follow strict rules so they work as identifiers across different clients:
| Constraint | Requirement |
|---|---|
| Character set | Lowercase ASCII letters, digits, hyphens, and periods only |
| Start and end | First and last characters must be alphanumeric |
| Repetition | No consecutive hyphens (--) or periods (..) |
For example, my-plugin, acme.tools, and lint3r are valid, while My-Plugin, -start, and has--double are not.
Copy link to headingHow clients handle manifest errors
Only two schema violations are non-fatal: an unknown top-level field and a non-object extensions field. In both cases, the client reports and ignores the problem and continues loading. Any other violation, such as a missing name or an unsupported $schema, is fatal: the client rejects the plugin without discovering or executing any of its components. This closed design enables strict validation and typo detection while keeping client experiments contained under extensions.
Copy link to headingSkills
Agent Plugins uses the Agent Skills specification without redefining it. The plugin format defines only where skills are discovered and how failures are isolated.
Each skill lives in an immediate child directory of skills/:
Discovery follows three rules:
- An immediate child of
skills/is a discovered skill when it has aSKILL.md - Clients do not recursively search deeper descendants for additional skills.
- If one discovered skill is invalid, the client skips it, reports it when practical, and continues loading other skills and component types.
Skills can contain any additional files they need. Directories like scripts/, references/, and assets/ are common conventions from the Agent Skills specification, not an exhaustive allowlist.
The plugin is still considered valid if the skills/ directory is missing.
Copy link to headingMCP servers
The mcp.json file at the plugin root configures MCP connections in a closed format that clients map to their native configuration.
It contains only $schema and mcpServers at the top level:
Copy link to headingTransports
Each server entry declares its transport with a type field and only the fields allowed for that transport:
| Type | Required fields | Notes |
|---|---|---|
stdio | type, command | Optional args, env, and cwd. Launches a local subprocess. |
streamable-http | type, url | Current remote MCP transport; optional literal headers. |
sse | type, url | Deprecated HTTP+SSE transport; client support is optional. |
An MCP-capable client supports at least one of stdio and streamable-http and should support both. The declared transport is used for the initial connection attempt; Agent Plugins defines no fallback behavior if that attempt fails.
Copy link to headingstdio commands
The command field is one executable token, not a shell command string. It's either a bare executable name resolved by platform search rules or a plugin-relative path beginning with ./. A plugin that bundles its own executable must use a plugin-relative command, since configured PATH behavior is client-defined. When cwd is omitted, the plugin root is the working directory.
Copy link to headingPlugin variables
Clients provide two environment variables to every stdio subprocess:
PLUGIN_ROOT: the absolute, filesystem-resolved plugin root. Use it to reference bundled scripts, binaries, and config files.PLUGIN_DATA: a dedicated writable data directory that persists across plugin updates. Use it for installed dependencies, caches, and generated state.
Clients expand ${PLUGIN_ROOT} and ${PLUGIN_DATA} in args, env values, and cwd. Expansion is textual, single-pass, and non-recursive, and it never applies to env keys, command, remote URLs, or headers. A plugin cannot override the two reserved variables; an env entry named PLUGIN_ROOT or PLUGIN_DATA invalidates that server entry.
Copy link to headingRemote connections and security
Remote configuration follows strict safety rules:
- URLs are absolute HTTP or HTTPS, without user information or fragments. Non-loopback endpoints use HTTPS.
- Configured headers are literal, visible package data. Plugins must not embed credentials or secrets in
headersorenv. - Clients never forward configured headers to a different origin through redirects without explicit user authorization.
- Agent Plugins 1.0.0 defines no portable OAuth or credential-reference fields. Authentication remains client-managed, and an authorization failure is a connection failure, not invalid package configuration.
Copy link to headingClient extensions
Client extensions let a client add behavior without expanding the portable core. Reverse-domain identifiers avoid collisions without a central registry. For example, the client that controls example.com could use com.example.client as its namespace in two places:
- Manifest data: namespace-keyed object under
extensionsinplugin.json. - Extension directory: top-level directory named exactly after the namespace.
Clients can use either representation or both, and the namespace owner defines their contents, validation, and failure behavior. Other clients ignore namespaces they don't implement without validating their contents, so extensions never affect portability or conformance.
Copy link to headingHow clients load plugins
Conformant clients follow a fixed loading sequence:
- Establish the filesystem-resolved plugin root.
- Locate and validate root
plugin.jsonusing the locally supported rules selected by$schema. Clients never retrieve schemas while loading a plugin. - Reject the plugin for fatal manifest violations and report the non-fatal cases.
- Discover each supported component type from its fixed location.
- Apply the failure boundary defined for each component type or entry.
- Apply implemented client-extension namespaces and ignore all others.
Copy link to headingFailure isolation
Failures are scoped to the narrowest relevant boundary, so one broken piece never takes down independently valid components:
| Failure | Scope of impact |
|---|---|
Fatal plugin.json violation | Entire plugin rejected |
Invalid top-level mcp.json | MCP disabled for the plugin; skills still load |
| Invalid individual MCP server entry | Only that server skipped |
| Server fails to start, connect, or authenticate | Only that server affected; loading continues |
| Invalid individual skill | Only that skill skipped; siblings still load |
| Fixed location has wrong filesystem kind | Only that component type invalid |
| Missing fixed location | Not an error; valid absence |
Copy link to headingVersioning
One version number identifies the complete specification release, including its normative text and both schemas. This keeps compatibility simple:
- The
$schemavalue inplugin.jsondeclares the Agent Plugins version the package targets. For 1.0.0, it'shttps://agent-plugins.org/schemas/1.0.0/plugin.schema.json. - When
mcp.jsonis present, its$schemaversion must match the version declared byplugin.json. A mismatch invalidates only the MCP configuration, not other component types. - Published canonical schema identifiers are never reassigned to different contents, and plugins may keep targeting older versions according to each client's compatibility policy.
For the plugin's own version field, Semantic Versioning is recommended: major for breaking changes, minor for backward-compatible features, and patch for fixes. Clients may use it for update checks and cache freshness.
Copy link to headingBuild your first plugin
Only two files are needed for a minimal working plugin.
Copy link to heading1. Create the directory structure
Copy link to heading2. Create the manifest
Copy link to heading3. Create the skill
Skills-capable clients load the plugin.json, discover the immediate children of skills/, and validate each SKILL.md against the Agent Skills specification.
To add MCP servers, place mcp.json at the plugin root using the same Agent Plugins schema version. For a copyable package with a complete manifest and a real skill, see the Agent Plugins example repository.
You can validate your files against the canonical JSON Schemas:
plugin.schema.jsonfor the plugin manifestmcp.schema.jsonfor MCP server configuration
The specification text is authoritative if it conflicts with a machine-readable schema.
Copy link to headingNext steps
- Read the complete Agent Plugins specification for the full normative contract.
- Learn the underlying Agent Skills specification to write effective skills.
- Explore the Model Context Protocol documentation for MCP server development.
- Browse the Agent Plugins repository to follow proposals or contribute.
- Implementing a client? Start with the client conformance checklist.