---
title: Compatible Clients
description: Explore clients that support the portable Agent Plugins format and the components each client can load.
type: overview
---

# Compatible Clients



Agent Plugins clients can adopt portable component types incrementally. The
clients below document the components and MCP transports they support.

<CompatibleClients />


---
title: Agent Plugins
description: A portable package format for reusable components that extend AI agents.
---

# Agent Plugins



Agent Plugins is an open, vendor-neutral standard for packaging reusable components into portable plugins. Its version 1.0.0 specification defines a shared format for [Agent Skills](https://agentskills.io/specification) and [MCP servers](https://modelcontextprotocol.io/specification) that compatible clients can discover and load consistently.

## Why Agent Plugins? [#why-agent-plugins]

AI agent clients have developed their own plugin formats, even when plugins contain the same underlying components. Authors must rearrange or duplicate those components for each client, so a plugin packaged for one client may need adaptation before another can use it.

Agent Plugins defines a small interoperability floor for the parts that can be portable across clients. Shared components can use one predictable structure, while distribution, installation, permissions, user experience, and client-specific capabilities remain under each client's control.

## The portable package [#the-portable-package]

An Agent Plugin is a directory with a required manifest and optional components in fixed locations:

```text
my-plugin/
├── plugin.json
├── skills/
│   └── summarize/
│       ├── SKILL.md
│       ├── scripts/
│       └── references/
├── mcp.json
└── com.example.client/
    └── hooks/
```

* `plugin.json` identifies the plugin and the Agent Plugins version it targets.
* `skills/` contains Agent Skills in the format defined by the Agent Skills specification.
* `mcp.json` describes stdio, Streamable HTTP, or legacy HTTP+SSE MCP servers.
* Reverse-domain extension namespaces let individual clients add behavior without changing the portable core.

## Open development [#open-development]

Agent Plugins is openly licensed and developed in public. Its initial Technical Steering Committee includes Core Maintainers from Amazon, Cursor, Microsoft, OpenAI, and Vercel.

Proposals and technical decisions are public, and participation is open to the broader ecosystem. Ideas for new features and material changes begin in [GitHub Discussions](https://github.com/agentplugins/agent-plugins-spec/discussions), where proposals can establish a concrete portability need and implementer support.

Explore the specification, schemas, governance, and contribution process in the [Agent Plugins specification repository](https://github.com/agentplugins/agent-plugins-spec).

## Choose your path [#choose-your-path]

<Cards>
  <Card title="Build a plugin" href="/plugin-authors" description="Create a portable package with skills and MCP servers." />

  <Card title="Implement a client" href="/client-implementers" description="Load, validate, and run Agent Plugins safely." />

  <Card title="Read the specification" href="/specification" description="Consult the complete normative specification." />

  <Card title="Browse the schemas" href="/schemas" description="Use the canonical plugin and MCP JSON Schemas." />
</Cards>


---
title: JSON Schemas
description: Canonical machine-readable schemas for Agent Plugins manifests and MCP configuration.
type: reference
---

# JSON Schemas



Agent Plugins publishes separate JSON Schemas for the plugin manifest and MCP server configuration. Clients use each canonical `$schema` identifier to select locally supported validation and interpretation rules; they do not retrieve schemas while loading a plugin.

<Cards>
  <Card title="Plugin manifest schema" href="/schemas/1.0.0/plugin.schema.json" description="Validate the root plugin.json manifest." />

  <Card title="MCP configuration schema" href="/schemas/1.0.0/mcp.schema.json" description="Validate the root mcp.json document and individual server entries." />
</Cards>

The [specification](/specification) is authoritative if its requirements conflict with a machine-readable schema.


---
title: Agent Plugins Specification
description: The complete normative contract for portable Agent Plugin packages and conformant clients.
type: reference
---

# Agent Plugins Specification



**Spec Version: 1.0.0**

**Status: Working Draft**

This document defines the canonical Agent Plugins Specification v1.0.0 for packaging reusable components that extend AI agents into distributable plugins.

## Table of contents [#table-of-contents]

1. [Status and version](#1-status-and-version)
2. [Conformance language](#2-conformance-language)
3. [Terminology](#3-terminology)
4. [Plugin package model](#4-plugin-package-model)
5. [Manifest](#5-manifest)
6. [Component discovery](#6-component-discovery)
7. [Component types](#7-component-types)
8. [Client extensions](#8-client-extensions)
9. [Environment variables and placeholder expansion](#9-environment-variables-and-placeholder-expansion)
10. [Versioning](#10-versioning)
11. [Client conformance](#11-client-conformance)

**Non-normative material**

* [Appendix A: Conformance Checklist](#appendix-a-conformance-checklist)
* [Design Decisions](#design-decisions)

## 1. Status and version [#1-status-and-version]

This specification defines version `1.0.0` of the Agent Plugins format.

Clients and plugin packages claiming conformance to Agent Plugins v1 MUST implement or follow the requirements in this document.

### 1.1 Governance model [#11-governance-model]

Governance for the Agent Plugins project is defined separately from the portable package format in the [Technical Charter](https://github.com/agentplugins/agent-plugins-spec/blob/main/GOVERNANCE.md).

## 2. Conformance language [#2-conformance-language]

In the normative sections of this document, the key words MUST, MUST NOT, REQUIRED, SHOULD, SHOULD NOT, RECOMMENDED, MAY, and OPTIONAL are to be interpreted as described in RFC 2119 and RFC 8174 when, and only when, they appear in all capitals.

Appendix A and Design Decisions are non-normative. All other sections are normative.

## 3. Terminology [#3-terminology]

| Term                | Meaning                 | Description                                                                                                                          |
| ------------------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| Plugin              | Package unit            | A self-contained directory with a manifest and optional components.                                                                  |
| Plugin root         | Filesystem root         | The top-level directory of a plugin package.                                                                                         |
| Manifest            | Metadata document       | A `plugin.json` file at the plugin root.                                                                                             |
| Component           | Plugin-provided unit    | A skill or MCP server entry supplied through a component type standardized by this specification.                                    |
| Client              | Plugin runtime          | A tool that discovers, installs, loads, and executes plugin components.                                                              |
| Extension namespace | Client-owned identifier | A reverse-domain identifier used for client-specific manifest data, a client-specific top-level directory, or both.                  |
| Extension directory | Client-owned file root  | A top-level directory whose name is exactly an extension namespace and whose contents are defined by that namespace's owning client. |

## 4. Plugin package model [#4-plugin-package-model]

### 4.1 General requirements [#41-general-requirements]

1. A plugin is a directory rooted at a single filesystem location.
2. A plugin MUST include a manifest at `plugin.json` in the plugin root.
3. When a client discovers, reads, or executes a file or directory supplied by the plugin package, the filesystem-resolved path MUST remain within the filesystem-resolved plugin root. Symlinks, junctions, reparse points, and equivalent filesystem mechanisms MAY resolve to targets within the plugin root, but clients MUST reject package paths that resolve outside it.
4. A configuration field defined by this specification as a plugin-relative path MUST begin with `./`, be resolved against the plugin root, and remain within the filesystem-resolved plugin root after resolution.
5. Configuration values not defined as paths, including command arguments and environment variable values, are opaque strings. Clients MUST NOT interpret them as package paths for the purpose of enforcing this section.

Example: valid and invalid relative paths

```json
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "server": {
      "type": "stdio",
      "command": "./bin/server",
      "cwd": "./data"
    }
  }
}
```

```json
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "server": {
      "type": "stdio",
      "command": "../bin/server",
      "cwd": "data"
    }
  }
}
```

The first example is valid — both paths start with `./` and stay within the plugin root. The second is invalid — `../bin/server` escapes the plugin root and `data` is not a plugin-relative path.

These containment rules govern access to files supplied by the plugin package. They do not sandbox a plugin subprocess or restrict paths supplied at runtime. §7.2.1 separately defines containment for a configured working directory rooted in the client-managed `PLUGIN_DATA` directory.

When a path fails a containment requirement, the client MUST apply the narrowest applicable failure boundary:

1. If `plugin.json` does not resolve within the plugin root, the client MUST reject the plugin.
2. If a fixed component location does not resolve within the plugin root, the client MUST treat that component type as invalid under §6.2.
3. If a discovered `SKILL.md` does not resolve within the plugin root, the client MUST skip that skill under §7.1.
4. If an MCP server `command` or `cwd` fails containment, the client MUST treat that server entry as invalid under §7.2.2.
5. For any other package path that resolves outside the plugin root, the client MUST deny access to that path.

### 4.2 Standard layout [#42-standard-layout]

A plugin that has skills, MCP servers, and a client extension can have the following layout:

```text
my-plugin/
├── plugin.json
├── skills/
│   └── summarize/
│       ├── SKILL.md
│       ├── scripts/
│       │   └── analyze.sh
│       └── references/
│           └── checklist.md
├── mcp.json
├── com.example.client/
│   └── hooks/
├── LICENSE
└── CHANGELOG.md
```

> **See also:** [§5 Manifest](#5-manifest) for manifest rules, [§6 Component discovery](#6-component-discovery) for fixed component locations and missing-location behavior, and [§8 Client extensions](#8-client-extensions) for client extension conventions.

## 5. Manifest [#5-manifest]

### 5.1 Location and loading [#51-location-and-loading]

Clients MUST check for a manifest at `plugin.json` in the plugin root.

The Agent Plugins core specification defines exactly one portable manifest per plugin. No other file can replace, supplement, or override the core fields in root `plugin.json`.

A client loads and validates root `plugin.json` before discovering components or applying client-specific behavior.

> **See also:** [§11 Client conformance](#11-client-conformance) for requirements around supporting `plugin.json`.

### 5.2 Manifest object [#52-manifest-object]

The manifest MUST be JSON and MUST contain a top-level object. Its schema is closed: the only permitted top-level fields are `$schema`, `name`, `version`, `description`, `author`, `homepage`, `repository`, `license`, `keywords`, and `extensions`.

If `plugin.json` contains any other top-level field, it does not conform to the schema. Clients MUST report and ignore each unknown field and MUST continue loading the plugin if the manifest otherwise satisfies this section. Clients MUST NOT assign semantics to unknown fields. Client-specific manifest data belongs under `extensions` as defined in §8.

A non-object `extensions` field is handled as defined in §8.1. Every permitted field otherwise MUST match the type and constraints defined below. Any schema violation other than an unknown top-level field or a non-object `extensions` field is fatal: the client MUST reject the plugin and MUST NOT discover or execute any of its components.

The official machine-readable schema is [`schemas/1.0.0/plugin.schema.json`](../schemas/1.0.0/plugin.schema.json). The specification text is authoritative if it conflicts with the schema.

The required `$schema` field identifies the Agent Plugins specification version targeted by the plugin and its corresponding manifest schema. For Agent Plugins 1.0.0, its value MUST be the canonical identifier `https://agent-plugins.org/schemas/1.0.0/plugin.schema.json`.

Clients MUST use a recognized `$schema` value to select locally supported manifest validation and interpretation rules. A client MAY map multiple canonical identifiers to the same implementation only when it explicitly recognizes those Agent Plugins versions as compatible. Clients MUST NOT retrieve a schema while loading a plugin. If a client does not support the declared Agent Plugins version or an explicitly recognized compatible version, it MUST reject the plugin and SHOULD report the unsupported version.

Example: minimal manifest

```json
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "minimal-plugin"
}
```

Example: full manifest

```json
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "plugin-name",
  "version": "1.2.0",
  "description": "Brief plugin description",
  "author": {
    "name": "Author Name",
    "email": "author@example.com",
    "url": "https://example.com"
  },
  "homepage": "https://docs.example.com/plugin",
  "repository": "https://github.com/example/plugin",
  "license": "MIT",
  "keywords": ["keyword1", "keyword2"],
  "extensions": {
    "com.example.client": {
      "setting": true
    }
  }
}
```

### 5.3 Required fields [#53-required-fields]

| Field     | Type   | Description                                                  |
| --------- | ------ | ------------------------------------------------------------ |
| `$schema` | string | Canonical plugin manifest schema identifier defined in §5.2. |
| `name`    | string | Human-readable plugin name.                                  |

If a required field is missing, has the wrong type, is empty, or otherwise violates its requirements, the manifest is invalid. Clients MUST reject the plugin and MUST NOT discover or execute any of its components. Clients SHOULD report which required field is invalid.

### 5.4 Metadata fields [#54-metadata-fields]

| Field         | Type      | Description                                                                                   |
| ------------- | --------- | --------------------------------------------------------------------------------------------- |
| `version`     | string    | Version string (Semantic Versioning RECOMMENDED). Used for update checks and cache freshness. |
| `description` | string    | Short description of plugin purpose.                                                          |
| `author`      | object    | Author object with optional `name`, `email`, and `url` string fields.                         |
| `homepage`    | string    | Documentation or homepage URL.                                                                |
| `repository`  | string    | Source repository URL.                                                                        |
| `license`     | string    | License identifier (SPDX identifier RECOMMENDED).                                             |
| `keywords`    | string\[] | Search and discovery tags.                                                                    |

The `author` object MAY contain only the `name`, `email`, and `url` fields, each with a string value. Any other field or value type makes the manifest invalid.

Except where this specification states an explicit constraint, metadata fields are validated only by their JSON types. Clients MUST NOT reject a manifest solely because `version` is not valid Semantic Versioning; `homepage`, `repository`, or `author.url` is not a recognized URL; `author.email` is not a recognized email address; or `license` is not an SPDX identifier.

### 5.5 Plugin name constraints [#55-plugin-name-constraints]

The manifest `name` value MUST satisfy all of the following:

| Constraint    | Requirement            | Description                                                   |
| ------------- | ---------------------- | ------------------------------------------------------------- |
| Length        | 1-64 characters        | The name MUST be between 1 and 64 characters inclusive.       |
| Character set | `a-z`, `0-9`, `-`, `.` | Lowercase alphanumeric characters, hyphens, and periods only. |
| Start and end | Alphanumeric           | The first and last characters MUST be alphanumeric.           |
| Repetition    | No `--` or `..`        | Consecutive hyphens and consecutive periods are not allowed.  |

Periods are allowed in plugin names.

Valid names: `my-plugin`, `acme.tools`, `lint3r`, `a`

Invalid names: `My-Plugin` (uppercase), `-start` (leading hyphen), `has--double` (consecutive hyphens), `too.many..dots` (consecutive periods), \`\` (empty)

### 5.6 Extensions field [#56-extensions-field]

The optional `extensions` field contains client-specific manifest data keyed by extension namespace. See §8 for processing rules.

## 6. Component discovery [#6-component-discovery]

> **See also:** [§4 Plugin package model](#4-plugin-package-model) for directory layout conventions.

### 6.1 Fixed locations [#61-fixed-locations]

Clients MUST discover each supported component type from its fixed location. `plugin.json` cannot override these locations or contain inline component configuration.

Component locations:

| Component type | Fixed location | Pattern                              |
| -------------- | -------------- | ------------------------------------ |
| Skills         | `skills/`      | Subdirectories containing `SKILL.md` |
| MCP servers    | `mcp.json`     | JSON configuration                   |

Example: given a plugin `reports-plugin` with this layout:

```text
reports-plugin/
├── plugin.json
├── skills/summarize/SKILL.md
└── mcp.json
```

The client discovers skill `summarize` from `skills/` and MCP servers from `mcp.json`.

### 6.2 Missing locations [#62-missing-locations]

If a fixed component location is absent, the client MUST NOT treat that as an error.

If a fixed component location is present but does not resolve to the expected filesystem kind — for example, `skills` does not resolve to a directory or `mcp.json` does not resolve to a regular file — the client MUST treat that component type as invalid and continue loading other supported component types.

## 7. Component types [#7-component-types]

> **See also:** [§6 Component discovery](#6-component-discovery) for how component files are located.

Agent Plugins v1 defines exactly two component types: **skills** and **MCP servers**. Other component types are outside the v1 format and do not affect conformance.

Clients MUST ignore component types they do not support.

### 7.1 Skills [#71-skills]

Agent Skills MUST conform to the [Agent Skills specification](https://agentskills.io/specification). That specification is the source of truth for the `SKILL.md` format, frontmatter fields, and directory layout (`scripts/`, `references/`, `assets/`).

This specification defines how Agent Skills are *discovered* within a plugin, not the skill format itself or how clients expose skills to users or models.

The fixed discovery location is `skills/`. Each immediate child directory containing a path named exactly `SKILL.md` that resolves to a regular file is treated as one skill. Clients MUST NOT recursively search deeper descendants for additional skills.

If a discovered skill does not conform to the Agent Skills specification, the client MUST skip that skill and continue loading other skills and component types. The client SHOULD report the invalid skill.

Example: a skill directory named `deploy` inside `skills/`:

```text
skills/
└── deploy/
    ├── SKILL.md          # name: deploy
    ├── scripts/
    │   └── rollback.sh
    └── references/
        └── runbook.md
```

### 7.2 MCP servers [#72-mcp-servers]

The [Model Context Protocol specification](https://modelcontextprotocol.io/specification) defines MCP wire behavior and lifecycle semantics. Agent Plugins defines the `mcp.json` configuration format used to locate and connect to MCP servers in a plugin. Clients map this portable format to their native configuration; its field names and values need not match a client-native format.

#### 7.2.1 Discovery and configuration [#721-discovery-and-configuration]

The MCP configuration path is `mcp.json` at the plugin root. MCP configuration MUST NOT be declared inline in `plugin.json` or loaded from any alternative core path.

`mcp.json` MUST be a JSON object containing the required `$schema` and `mcpServers` fields, with no other top-level fields. `mcpServers` MUST be an object whose member names identify servers and whose member values are server configuration objects. An empty `mcpServers` object is valid.

The official machine-readable schema is [`schemas/1.0.0/mcp.schema.json`](../schemas/1.0.0/mcp.schema.json). The specification text is authoritative if it conflicts with the schema. The schema exposes `#/$defs/server` so that clients can validate each server independently and preserve the failure boundaries in §7.2.2.

The required `$schema` field identifies the Agent Plugins specification version targeted by the MCP configuration and its corresponding MCP schema. For Agent Plugins 1.0.0, its value MUST be the canonical identifier `https://agent-plugins.org/schemas/1.0.0/mcp.schema.json`.

Clients MUST use a recognized `$schema` value to select locally supported MCP configuration validation and interpretation rules. A client MAY map multiple canonical identifiers to the same implementation only when it explicitly recognizes those Agent Plugins versions as compatible. Clients MUST NOT retrieve a schema while loading a plugin.

Each server configuration MUST contain a `type` field and match exactly one of the closed variants below. An unknown field, an unknown `type` value, or a field belonging to another variant makes that server entry invalid.

##### stdio [#stdio]

| Field     | Type              | Required | Description                                    |
| --------- | ----------------- | -------- | ---------------------------------------------- |
| `type`    | `"stdio"`         | Yes      | Selects the MCP stdio transport.               |
| `command` | string            | Yes      | Executable token to launch.                    |
| `args`    | string\[]         | No       | Arguments passed to the executable.            |
| `env`     | object of strings | No       | Environment variables supplied to the process. |
| `cwd`     | string            | No       | Working directory for the process.             |

The `command` field MUST contain a single executable token, not a shell command string. It MUST be either a bare executable name or a plugin-relative path beginning with `./`. Clients MUST resolve bare names using the platform's executable search rules and MUST resolve plugin-relative paths against the plugin root. Clients MUST NOT perform placeholder expansion in `command`.

Whether a configured `PATH` environment value participates in resolving a bare `command` is client-defined. Plugins claiming conformance MUST NOT depend on that behavior. A plugin that bundles an executable in the package MUST use a plugin-relative `command`.

Clients MAY use a platform-specific command interpreter when required to launch the resolved executable, such as a `.bat` or `.cmd` script on Windows, but MUST preserve `command` as one token and pass `args` separately.

When `cwd` is omitted, clients MUST use the plugin root as the subprocess working directory. When present, `cwd` MUST have one of these forms:

1. A plugin-relative path beginning with `./`.
2. Exactly `${PLUGIN_ROOT}` or a path beginning with `${PLUGIN_ROOT}/`.
3. Exactly `${PLUGIN_DATA}` or a path beginning with `${PLUGIN_DATA}/`.

Clients MUST expand placeholders before resolving `cwd`. A plugin-relative or `${PLUGIN_ROOT}`-rooted value MUST remain within the filesystem-resolved plugin root. A `${PLUGIN_DATA}`-rooted value MUST remain within the filesystem-resolved plugin data directory. Any other form or any post-resolution escape makes that server entry invalid under §7.2.2.

The `args`, `env`, and `cwd` fields in a stdio server configuration MUST support `${PLUGIN_ROOT}` and `${PLUGIN_DATA}` expansion.

##### Streamable HTTP and legacy HTTP+SSE [#streamable-http-and-legacy-httpsse]

| Field     | Type                           | Required | Description                                                       |
| --------- | ------------------------------ | -------- | ----------------------------------------------------------------- |
| `type`    | `"streamable-http"` or `"sse"` | Yes      | Selects the remote MCP transport.                                 |
| `url`     | string                         | Yes      | MCP endpoint URL.                                                 |
| `headers` | object of strings              | No       | Fixed HTTP headers sent when connecting to the configured origin. |

`streamable-http` selects the current MCP Streamable HTTP transport. `sse` selects the deprecated HTTP+SSE transport defined by the [MCP 2024-11-05 specification](https://modelcontextprotocol.io/specification/2024-11-05/basic/transports); it does not refer to SSE responses or streams used within Streamable HTTP.

The `url` value MUST be an absolute HTTP or HTTPS URL and MUST NOT contain user information or a fragment. Non-loopback endpoints MUST use HTTPS. HTTP MAY be used when the URL host is exactly `localhost` or an IP literal in a loopback range.

Header names and values MUST be valid HTTP header fields. Header names are case-insensitive; an entry containing the same header name more than once under different casing is invalid. Clients MUST NOT perform placeholder or environment-variable expansion in `url`, header names, or header values.

Header values are visible package data, not a portable secret mechanism. Plugins MUST NOT embed credentials or other secrets in `headers`. Headers generated by the client to implement HTTP, MCP, or authorization take precedence over configured headers with the same case-insensitive name. A client MUST NOT forward configured headers to a different origin through a redirect or legacy SSE endpoint event without explicit user authorization.

Agent Plugins v1 defines no OAuth configuration or portable credential-reference fields. Authorization discovery, user interaction, and credential storage are client-managed. An authorization failure is a connection failure for that server, not invalid plugin configuration.

##### Transport support [#transport-support]

A client that supports Agent Plugins MCP servers MUST support at least one of `stdio` or `streamable-http` and SHOULD support both. Support for `sse` is OPTIONAL. A client MUST use the transport declared by `type` for its initial connection attempt. Agent Plugins does not define fallback behavior if that attempt fails.

Example: `mcp.json`

```json
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "local-validator": {
      "type": "stdio",
      "command": "./bin/validator",
      "args": ["--data", "${PLUGIN_DATA}/validator"],
      "env": {
        "CONFIG": "${PLUGIN_ROOT}/config.json"
      },
      "cwd": "${PLUGIN_ROOT}"
    },
    "deployment-api": {
      "type": "streamable-http",
      "url": "https://deploy.example.com/mcp",
      "headers": {
        "X-Tenant": "public-tenant"
      }
    },
    "legacy-events": {
      "type": "sse",
      "url": "https://legacy.example.com/sse"
    }
  }
}
```

#### 7.2.2 Loading rules [#722-loading-rules]

1. Clients that support MCP servers MUST load configuration only from `mcp.json` at the plugin root.
2. If `mcp.json` is not valid JSON, targets an Agent Plugins version for which the client has no supported or explicitly recognized compatible version, targets a different Agent Plugins version than `plugin.json`, or does not satisfy the other top-level requirements in §7.2.1, the client MUST disable MCP for that plugin and continue loading other component types. The client SHOULD report the invalid, unsupported, or mismatched configuration.
3. If an individual server entry does not satisfy the requirements in §7.2.1, the client MUST skip that server and continue loading other servers and component types. The client SHOULD report the invalid entry.
4. If the client does not support the transport declared by an otherwise valid server entry, it MUST skip that server and continue loading other servers and component types. The client SHOULD report the unsupported transport.
5. If a server fails to start, connect, authenticate, or complete the MCP handshake, the client MUST continue loading other servers and component types. The client SHOULD report the connection failure.

## 8. Client extensions [#8-client-extensions]

Client-specific manifest data MUST be represented under a reverse-domain namespace in `extensions`. Client-specific files MUST be represented under a top-level directory named for that namespace. A client MAY use either representation or both.

A client SHOULD base its namespace on a domain name it controls and SHOULD keep the namespace stable. For example, a client that controls `example.com` could use `com.example.client`.

Agent Plugins assigns no portable discovery, validation, loading, or failure semantics to client extension data or files. Each client defines the contents and behavior of its own namespace, including how its manifest data and directory contents relate.

### 8.1 Manifest extension data [#81-manifest-extension-data]

The optional `extensions` field in `plugin.json` MUST be an object whose member names are client extension namespaces and whose member values are objects.

Example:

```json
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "example-plugin",
  "extensions": {
    "com.example.client": {
      "setting": true
    }
  }
}
```

If `extensions` is not an object, the client MUST report and ignore the field and continue loading components. A client MUST ignore manifest entries for namespaces it does not implement without validating the contents of their values. Validation and failure handling within an implemented namespace are defined by that client.

### 8.2 Extension directories [#82-extension-directories]

The extension directory for a namespace is the top-level directory named after it. For example, files for `com.example.client` belong in `com.example.client/`.

Example: a file-only client extension

```text
my-plugin/
├── plugin.json
├── skills/
│   └── summarize/
│       └── SKILL.md
└── com.example.client/
    └── hooks/
        └── hooks.json
```

A client that implements file-based behavior for a namespace MUST look for it in the corresponding top-level directory.

## 9. Environment variables and placeholder expansion [#9-environment-variables-and-placeholder-expansion]

> **See also:** [§7.2 MCP servers](#72-mcp-servers) for the fields where plugin variable expansion applies, and [§4.1 General requirements](#41-general-requirements) for path safety rules.

### 9.1 Subprocess environment [#91-subprocess-environment]

Clients that launch plugin subprocesses (i.e., stdio MCP servers) MUST provide `PLUGIN_ROOT` and `PLUGIN_DATA` in each subprocess environment. `PLUGIN_ROOT` is the absolute path to the filesystem-resolved plugin root. `PLUGIN_DATA` is the absolute path to a client-managed persistent data directory dedicated to that installed plugin instance.

The client chooses the `PLUGIN_DATA` location. It MUST create the directory before launching a plugin subprocess, MUST make it writable to that subprocess, and MUST preserve its contents across plugin updates. The client MAY delete the directory when the plugin is uninstalled.

Use `PLUGIN_DATA` for: installed dependencies (node\_modules, virtual environments), generated code, caches, and other plugin state that should persist across updates. Use `PLUGIN_ROOT` for referencing bundled scripts, binaries, and config files that ship with the plugin.

The client chooses the base subprocess environment and MAY inherit, omit, or sanitize ambient variables. After placeholder expansion, entries in a stdio server's `env` object MUST overlay the base environment and replace same-name entries according to platform environment-name semantics. The client MUST then set `PLUGIN_ROOT` and `PLUGIN_DATA` to the values defined above, replacing any entries with equivalent names according to platform environment-name semantics.

Except for the platform executable search used to resolve a bare `command`, plugins claiming conformance MUST NOT depend on a base-environment variable unless this specification requires that variable or the server configuration supplies it explicitly.

Example: a client loading the plugin `devtools` from `/home/alex/.agents/plugins/devtools` sets:

```text
PLUGIN_ROOT=/home/alex/.agents/plugins/devtools
PLUGIN_DATA=/home/alex/.agents/plugins/data/devtools
```

### 9.2 Placeholder expansion [#92-placeholder-expansion]

Clients that launch plugin subprocesses MUST expand `${PLUGIN_ROOT}` and `${PLUGIN_DATA}` in supported configuration fields. Expansion is a single, non-recursive textual replacement of every exact occurrence of either placeholder. Text introduced by a replacement MUST NOT be scanned for further placeholders.

Expansion applies to every string element of `args`, every string value in `env`, and the `cwd` string. It does not apply to `env` keys, `command`, or fixed component locations.

Unrecognized placeholder-like text MUST remain literal. Clients MUST NOT perform any other placeholder or environment-variable expansion.

Configured `env` values are visible package data, not a portable secret mechanism. Plugins MUST NOT embed credentials or other secrets in `env`.

An MCP server's `env` object MUST NOT contain entries named `PLUGIN_ROOT` or `PLUGIN_DATA`. Such an entry makes that server configuration invalid under §7.2.2. Clients MUST supply the reserved environment variables themselves.

Example: plugin variable expansion in MCP

```json
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "database": {
      "type": "stdio",
      "command": "npx",
      "args": ["--config", "${PLUGIN_ROOT}/config/db.json"],
      "cwd": "${PLUGIN_ROOT}",
      "env": {
        "DATA_DIR": "${PLUGIN_DATA}/database"
      }
    }
  }
}
```

## 10. Versioning [#10-versioning]

### 10.1 Specification and schema versions [#101-specification-and-schema-versions]

The version in §1 identifies the complete Agent Plugins specification release, including its normative text, plugin manifest schema, and MCP configuration schema. Every specification release MUST publish both schemas with the same version as the specification, even when a schema's validation rules are unchanged from the previous release.

A plugin's required `plugin.json` `$schema` value declares the Agent Plugins version that the package targets. When `mcp.json` is present, the version in its `$schema` value MUST match the version declared by `plugin.json`. A mismatch makes the MCP configuration invalid under §7.2.2 but does not invalidate other component types.

A change to either schema requires a new specification release. Published canonical schema identifiers MUST NOT be reassigned to different schema contents. Existing plugins MAY continue targeting an older Agent Plugins version; clients determine support using the declared canonical identifiers and any explicit compatibility mappings.

### 10.2 Plugin versions [#102-plugin-versions]

Plugins SHOULD use Semantic Versioning for `version`.

| Segment | Meaning                     | Description                                              |
| ------- | --------------------------- | -------------------------------------------------------- |
| Major   | Breaking change             | Incompatible behavior or schema change.                  |
| Minor   | Backward-compatible feature | New behavior without breaking existing clients or users. |
| Patch   | Backward-compatible fix     | Corrective change without intended behavioral break.     |

Clients MAY use `version` to determine whether updates are available and whether caches are stale.

## 11. Client conformance [#11-client-conformance]

### 11.1 Minimum client requirements [#111-minimum-client-requirements]

A conformant client MUST satisfy all applicable requirements in sections 1–10. At minimum, it:

1. Can load a plugin from a directory path.
2. Selects a locally supported plugin manifest schema from `$schema`, then parses and validates the closed `plugin.json` schema using the non-fatal exceptions in §5.2 and §8.1.
3. Ignores unimplemented members of `extensions` without validating the contents of their values.
4. For each component type it supports, discovers components in its fixed location.
5. If it supports MCP servers, selects a locally supported MCP configuration schema from `$schema` and supports at least one of the `stdio` or `streamable-http` variants in `mcp.json`.
6. If the client launches plugin subprocesses (i.e., stdio MCP servers), provides `PLUGIN_ROOT` and `PLUGIN_DATA` and expands both variables in runtime configuration values (`args`, `env`, `cwd`).
7. For stdio MCP servers, resolves `command` as a single executable token and uses the plugin root as the default subprocess working directory.
8. Supports at least one component type (skills or MCP servers).

### 11.2 Incremental adoption [#112-incremental-adoption]

A client is not required to support every component type. For example, a skills-only client can conform without supporting MCP servers, provided it satisfies all applicable requirements.

### 11.3 Unsupported components and failures [#113-unsupported-components-and-failures]

1. Clients MUST ignore unsupported component types.
2. An unknown top-level field or a non-object `extensions` field is non-fatal under §5.2 and §8.1. Any other `plugin.json` schema violation is fatal to the plugin: the client MUST reject the plugin and MUST NOT discover or execute any of its components.
3. A failure isolated to a component type, component entry, or component process MUST NOT prevent the client from loading independently valid components. Clients MUST apply the failure behavior defined for that component in §6 and §7.
4. Clients SHOULD report invalid configuration and component failures. Clients MAY report partially unsupported plugins, but lack of support for a component type, MCP transport, or client extension is not itself an error.

***

## Appendix A: Conformance Checklist [#appendix-a-conformance-checklist]

*This checklist is for convenience only — when it conflicts with the spec text above, the spec governs.*

### Plugin loader [#plugin-loader]

* [ ] Parse and validate `plugin.json` ([§5.1](#51-location-and-loading), [§5.2](#52-manifest-object))
* [ ] Validate required `$schema` and `name` fields ([§5.3](#53-required-fields))
* [ ] Validate plugin name against naming constraints ([§5.5](#55-plugin-name-constraints))
* [ ] Report and ignore unknown `plugin.json` fields ([§5.2](#52-manifest-object))
* [ ] Ignore unimplemented namespaces in `extensions` without validating the contents of their values ([§8.1](#81-manifest-extension-data))
* [ ] Reject package paths that resolve outside the plugin root ([§4.1](#41-general-requirements))
* [ ] Discover implemented file-based extensions from their top-level namespace directories ([§8.2](#82-extension-directories))

### Component discovery [#component-discovery]

* [ ] Scan the fixed location for each supported component type ([§6.1](#61-fixed-locations))
* [ ] Ignore missing fixed locations without error ([§6.2](#62-missing-locations))

### MCP configuration [#mcp-configuration]

* [ ] Select a supported `$schema`, then validate the closed `mcp.json` schema and each server variant ([§7.2.1](#721-discovery-and-configuration))
* [ ] If supporting MCP, implement at least one of stdio or Streamable HTTP ([§7.2.1](#transport-support))
* [ ] Use each server entry's declared transport for the initial connection attempt ([§7.2.1](#transport-support))
* [ ] Enforce remote URL and literal-header requirements ([§7.2.1](#streamable-http-and-legacy-httpsse))

### Environment and expansion [#environment-and-expansion]

* [ ] If the client launches plugin subprocesses, provide `PLUGIN_ROOT` and a dedicated writable `PLUGIN_DATA` directory ([§9.1](#91-subprocess-environment))
* [ ] Resolve MCP server `command` as a single bare or plugin-relative executable token ([§7.2.1](#721-discovery-and-configuration))
* [ ] Use the plugin root as the default MCP server working directory ([§7.2.1](#721-discovery-and-configuration))
* [ ] Validate explicit `cwd` forms and post-resolution containment ([§7.2.1](#721-discovery-and-configuration))
* [ ] Overlay configured `env` entries on a client-selected base environment ([§9.1](#91-subprocess-environment))
* [ ] Set client-provided `PLUGIN_ROOT` and `PLUGIN_DATA` after applying configured `env`, replacing equivalent names according to platform environment-name semantics ([§9.1](#91-subprocess-environment))
* [ ] Do not require configured `PATH` to affect bare-command resolution ([§7.2.1](#721-discovery-and-configuration))
* [ ] Expand only `${PLUGIN_ROOT}` and `${PLUGIN_DATA}` in MCP server `args`, `env`, and `cwd` fields ([§9.2](#92-placeholder-expansion))

### Resilience [#resilience]

* [ ] Ignore unsupported component types ([§11.3](#113-unsupported-components-and-failures))
* [ ] Skip server entries whose declared transport is unsupported without affecting other servers or components ([§7.2.2](#722-loading-rules))
* [ ] Continue loading when an independent component fails ([§11.3](#113-unsupported-components-and-failures))
* [ ] Support at least one component type ([§11.1](#111-minimum-client-requirements))

***

## Design Decisions [#design-decisions]

*This section explains why key design choices were made. It is for context only — the binding rules are in the normative sections above.*

### Why directory-based discovery? [#why-directory-based-discovery]

Plugins use filesystem directories as the package unit rather than archive formats (`.zip`, `.tar.gz`) or registry-fetched bundles. This keeps plugins inspectable with standard tools (`ls`, `cat`, `git`), editable in-place during development, and compatible with version control without special tooling. Fixed root-level locations such as `skills/` and `mcp.json` eliminate discovery indirection, alternate-source precedence, and manifest configuration that every client would otherwise need to implement.

### Why only Agent Skills and MCP in v1? [#why-only-agent-skills-and-mcp-in-v1]

Agent Plugins v1 focuses on Agent Skills and MCP because both have established specifications outside this project and meaningful cross-client adoption. Other proposed component types — such as commands, hooks, agents, rules, and LSP servers — remain too client-specific for a stable portable contract and are outside the v1 format until their formats converge.

### Why root-level `plugin.json` is the conformance floor [#why-root-level-pluginjson-is-the-conformance-floor]

Every conformant client MUST check `plugin.json` at the plugin root ([§5.1](#51-location-and-loading)). This gives plugin authors a single guaranteed manifest that works across all clients without client-specific path knowledge.

### Why a closed portable manifest? [#why-a-closed-portable-manifest]

Restricting root `plugin.json` to known fields enables strict validation, typo detection, and schema-driven key completion. Client experiments cannot claim arbitrary top-level fields; they are contained under reverse-domain keys in `extensions`. Unknown top-level fields remain schema violations, but clients report and ignore them instead of rejecting an otherwise valid plugin.

### Why reverse-domain client extensions? [#why-reverse-domain-client-extensions]

Reverse-domain identifiers provide a decentralized convention for avoiding collisions without requiring a central client-name registry. The same identifier can be used for manifest data and a client-specific directory, while either representation can exist independently. Extension directories remain top-level to keep plugin layouts flat and convention-driven.

### Why an explicit MCP configuration format? [#why-an-explicit-mcp-configuration-format]

Existing clients use incompatible MCP configuration shapes and infer transports differently. Agent Plugins therefore defines an explicit closed union whose meaning is independent of any client-native format. Distinguishing Streamable HTTP from legacy HTTP+SSE gives each entry an unambiguous initial transport while leaving fallback behavior after a failed connection outside the portable format.

### Why may clients support only one standard MCP transport? [#why-may-clients-support-only-one-standard-mcp-transport]

Stdio and Streamable HTTP serve different deployment and security models. Requiring every MCP-capable client to support both local process execution and remote HTTP connectivity would expand its implementation and trust surface without changing the portable configuration format. Because each server entry declares its transport, a client can skip unsupported entries while continuing to load independent servers and components.

### Why do schemas share the specification version? [#why-do-schemas-share-the-specification-version]

`plugin.json` and `mcp.json` schemas use the Agent Plugins specification version rather than independent version sequences. This gives plugin authors and clients one portable format version to understand, prevents mixed-version packages, and lets `$schema` select the complete validation and interpretation contract — including requirements that JSON Schema cannot express. Republishing an unchanged schema with a new specification release is a small maintenance cost compared with exposing three independent compatibility timelines.

### Why plugin variables over relative paths in configs? [#why-plugin-variables-over-relative-paths-in-configs]

MCP server arguments often need absolute paths at runtime. `${PLUGIN_ROOT}` provides an unambiguous, client-resolved anchor for bundled files, while `${PLUGIN_DATA}` identifies client-managed writable state that persists when package contents are replaced during an update. The `command` field does not use interpolation: a `./` path is resolved directly against the plugin root, and a bare name uses the platform's executable search rules. Treating `command` as one token avoids requiring clients to parse and escape user-authored shell command strings. Clients differ in inherited environment and `PATH` behavior, so Agent Plugins standardizes configured environment overrides but leaves bare-command search client-defined; plugin-relative commands provide deterministic bundled execution.

### Why component failures are non-fatal [#why-component-failures-are-non-fatal]

When an MCP server fails to start or connect, the client continues loading the plugin's remaining components ([§11.3](#113-unsupported-components-and-failures)). A plugin that provides skills and an MCP server should not become entirely unusable because one server is unavailable. The spec pairs non-fatal component failures with diagnostic requirements so that failures are visible rather than silent.


---
title: Client conformance checklist
description: Review the minimum behavior required for an Agent Plugins 1.0.0 client.
type: reference
---

# Client conformance checklist



This checklist is non-normative. The [complete specification](/specification) governs when wording differs.

## Plugin loader [#plugin-loader]

* [ ] Load a plugin from a directory and enforce the filesystem-resolved package boundary.
* [ ] Select locally supported manifest rules from `$schema`; do not retrieve a schema during loading.
* [ ] Validate the closed `plugin.json` schema and required `$schema` and `name` fields.
* [ ] Report and ignore unknown top-level fields.
* [ ] Ignore a non-object `extensions` field and unimplemented extension namespaces.
* [ ] Reject other fatal manifest violations before component discovery.

## Discovery and isolation [#discovery-and-isolation]

* [ ] Discover supported component types only from their fixed locations.
* [ ] Treat missing component locations as valid absence.
* [ ] Isolate invalid component types, skills, and MCP entries at their specified boundaries.
* [ ] Ignore unsupported component types and support at least one of skills or MCP servers.

## MCP support [#mcp-support]

* [ ] If MCP is implemented, support at least one of stdio and Streamable HTTP; support for both is recommended.
* [ ] Use each server entry's declared transport for the initial connection attempt.
* [ ] Validate the closed top-level document and each server entry independently.
* [ ] Resolve stdio commands as single executable tokens.
* [ ] Provide `PLUGIN_ROOT` and a dedicated persistent `PLUGIN_DATA` directory.
* [ ] Expand only the two defined placeholders and only in `args`, `env` values, and `cwd`.
* [ ] Enforce working-directory containment and remote URL/header requirements.
* [ ] Continue loading after an independent MCP server fails.

## Versioning [#versioning]

* [ ] Require matching Agent Plugins versions in `plugin.json` and `mcp.json`.
* [ ] Never reassign a published canonical schema identifier to different contents.
* [ ] Allow plugins to continue targeting older versions according to locally supported compatibility policy.


---
title: Implement an Agent Plugins client
description: Add the portable Agent Plugins loading contract to an agent or development tool.
---

# Implement an Agent Plugins client



A conformant client loads an Agent Plugin from a directory, validates `plugin.json`, and supports at least one component type: skills or MCP servers.

## Loading sequence [#loading-sequence]

1. Establish the filesystem-resolved plugin root.
2. Locate and validate root `plugin.json` using the locally supported schema selected by `$schema`.
3. Reject the plugin for fatal manifest violations; report and ignore the explicitly non-fatal cases.
4. Discover each supported component type from its fixed location.
5. Apply the failure boundary defined for each component type or entry.
6. Apply implemented client-extension namespaces and ignore all others.

Clients use canonical schema identifiers to select local validation and interpretation rules. They do not retrieve schemas while loading a plugin.

## Portable versus client-owned behavior [#portable-versus-client-owned-behavior]

Agent Plugins defines package structure, validation, discovery, MCP configuration, plugin variables, and failure isolation. It does not prescribe:

* installation sources, registries, or marketplaces
* enablement, update, or cache user experience
* permission prompts, trust policy, or sandboxing
* how skills are shown to users or models
* internal client-extension behavior

## Next steps [#next-steps]

* **[Loading and discovery](/client-implementers/loading-and-discovery)** — Validate the manifest, discover supported components, and apply failure boundaries.
* **[MCP runtime](/client-implementers/mcp-runtime)** — Map portable MCP configuration to stdio and HTTP connections.
* **[Conformance checklist](/client-implementers/conformance)** — Check the minimum portable client requirements.


---
title: Loading and discovery
description: Validate the manifest, discover supported components, and apply narrow failure boundaries.
---

# Loading and discovery



## Establish the package boundary [#establish-the-package-boundary]

The plugin root is a single filesystem location. Every package file a client discovers, reads, or executes must remain inside the filesystem-resolved root after resolving symlinks, junctions, reparse points, and equivalent mechanisms.

## Load the manifest first [#load-the-manifest-first]

Clients check for `plugin.json` at the plugin root and load it before discovering components or applying client behavior. The closed JSON object has two required fields: `$schema` selects the Agent Plugins version and validation contract, while `name` identifies the plugin. Other permitted fields provide optional metadata or [client-extension data](/plugin-authors/client-extensions). See the [manifest reference](/plugin-authors/manifest) for the complete field set.

Select locally supported validation and interpretation rules from `$schema`; do not retrieve a schema while loading the plugin. A missing or unsupported `$schema` rejects the plugin.

The following two manifest schema violations are non-fatal:

* Report and ignore each unknown top-level field, then continue if the manifest is otherwise valid.
* Report and ignore a non-object `extensions` field, then continue loading components.

Any other manifest schema violation rejects the complete plugin.

When `extensions` is an object, each member is owned by the client identified by its reverse-domain namespace. Ignore namespaces the client does not implement without validating their values.

## Discover supported components [#discover-supported-components]

Agent Plugins assigns each component type a fixed location:

| Component type                             | Fixed location | Discovery rule                                               |
| ------------------------------------------ | -------------- | ------------------------------------------------------------ |
| [Skills](/plugin-authors/skills)           | `skills/`      | Immediate child directories containing a regular `SKILL.md`. |
| [MCP servers](/plugin-authors/mcp-servers) | `mcp.json`     | One root JSON configuration document.                        |

A missing fixed location is not an error. If a location exists with the wrong filesystem kind, mark only that component type invalid and continue with other supported types.

If a discovered skill does not conform to the Agent Skills specification, skip that skill and continue loading its siblings. Do not recursively search nested descendants for additional skills.

A client ignores component types it does not implement. Lack of support is not itself a plugin error; a conformant client implements at least one of skills or MCP servers. How a client presents a valid skill to users or models remains client policy.

## Path failure boundaries [#path-failure-boundaries]

Apply the narrowest relevant boundary:

1. Reject the plugin if `plugin.json` resolves outside the plugin root.
2. Disable one component type when its fixed location has the wrong filesystem kind or escapes the root.
3. Skip one skill when its `SKILL.md` escapes the root.
4. Skip one MCP entry when a configured package path escapes its permitted root.
5. Deny access for other escaping package paths.


---
title: MCP runtime
description: Map portable MCP configuration into native connections and isolate server failures.
---

# MCP runtime



Agent Plugins defines how `mcp.json` selects a transport and supplies runtime configuration. MCP defines message framing, initialization, capability negotiation, authorization, and lifecycle.

An MCP-capable Agent Plugins client must support at least one of stdio and Streamable HTTP and should support both. Legacy HTTP+SSE support is optional.

## Configuration model [#configuration-model]

`mcp.json` contains an `mcpServers` object whose members are independently configured servers. Each entry declares a `type` and only the fields allowed for that transport:

```json title="mcp.json"
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "local-tools": {
      "type": "stdio",
      "command": "./bin/server",
      "args": ["--data", "${PLUGIN_DATA}"]
    },
    "remote-tools": {
      "type": "streamable-http",
      "url": "https://tools.example.com/mcp"
    }
  }
}
```

See the [MCP server reference for plugin authors](/plugin-authors/mcp-servers) for every field and constraint.

## Select the declared transport [#select-the-declared-transport]

The `type` field selects the transport for the initial connection attempt; it is not a transport-neutral URL hint. Instantiate the corresponding MCP transport after reading `type`. Agent Plugins does not define fallback behavior if that attempt fails. Clients that implement fallback can follow MCP's [backwards-compatibility guidance](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#backwards-compatibility).

SSE responses and streams used within Streamable HTTP remain part of `streamable-http`; they are distinct from the deprecated HTTP+SSE transport. Redirects remain subject to the selected transport and the header-forwarding rules below.

## Validate in two stages [#validate-in-two-stages]

First validate the top-level `mcp.json`: valid JSON, matching supported `$schema`, matching plugin specification version, required `mcpServers`, and no unknown top-level fields. A top-level failure disables MCP for that plugin.

Then validate each server entry using the requirements for its declared `type`. An unknown transport, an unknown field, or a missing or invalid transport field makes only that entry invalid. Skip it without disabling valid siblings or other component types. The canonical schema exposes `#/$defs/server` for this purpose.

## Launch stdio servers [#launch-stdio-servers]

* Treat `command` as one executable token and pass `args` separately.
* Resolve a bare command through platform executable search rules.
* Resolve a `./` command against the plugin root and enforce containment. Arguments and environment values remain opaque strings even when they resemble paths.
* Default `cwd` to the plugin root.
* Create a dedicated writable `PLUGIN_DATA` directory before launch and preserve it across plugin updates.
* Overlay configured `env` on the client-selected base environment, then set client-controlled `PLUGIN_ROOT` and `PLUGIN_DATA` last.
* Expand plugin variables only in `args`, `env` values, and `cwd`.

The client may inherit, omit, or sanitize ambient environment variables. Portable plugins cannot depend on unspecified ambient variables or on configured `PATH` affecting bare-command resolution.

After launch, follow the MCP [stdio transport](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#stdio) and [lifecycle](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle) requirements.

## Connect remote servers [#connect-remote-servers]

Validate the URL and literal headers before connecting. Never forward configured headers to a different origin through redirects or legacy SSE endpoint events without explicit user authorization.

Follow the MCP [Streamable HTTP transport](https://modelcontextprotocol.io/specification/2025-11-25/basic/transports#streamable-http), [lifecycle](https://modelcontextprotocol.io/specification/2025-11-25/basic/lifecycle), and [authorization](https://modelcontextprotocol.io/specification/2025-11-25/basic/authorization) requirements. Agent Plugins defines no portable OAuth or credential-reference fields; authorization discovery, credential storage, and user interaction are client-managed. Authentication failure is a connection failure, not invalid package configuration.

## Runtime failures [#runtime-failures]

If one server fails to start, connect, authenticate, or complete the MCP handshake, continue loading other servers and components. Report the failure when practical.


---
title: Client extensions
description: Add client-owned behavior without expanding the portable Agent Plugins core.
---

# Client extensions



Client extensions let a particular client define additional manifest data, files, and behavior. Agent Plugins reserves no central registry; namespaces use reverse-domain identifiers to avoid collisions.

## Manifest data [#manifest-data]

Put client-specific data under `extensions` in `plugin.json`:

```json title="plugin.json"
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "example-plugin",
  "extensions": {
    "com.example.client": {
      "setting": true
    }
  }
}
```

Each extension value is an object. A client ignores namespaces it does not implement without validating their contents.

## Extension directories [#extension-directories]

Client-owned files live in a top-level directory whose name exactly matches the namespace:

```text
example-plugin/
├── plugin.json
├── skills/
└── com.example.client/
    └── hooks/
        └── hooks.json
```

A client can use manifest data, an extension directory, or both. The namespace owner defines their contents, validation, relationships, and failure behavior.

Client extensions are not portable Agent Plugins components. Other clients can ignore them without affecting conformance.


---
title: Build an Agent Plugin
description: Create the smallest portable package and add components in fixed locations.
---

# Build an Agent Plugin



An Agent Plugin is a self-contained directory. Every plugin has a root `plugin.json`; skills and MCP configuration are optional.

## Create a minimal plugin [#create-a-minimal-plugin]

```text
hello-plugin/
├── plugin.json
└── skills/
    └── greet/
        └── SKILL.md
```

Create `plugin.json`:

```json title="plugin.json"
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "hello-plugin"
}
```

Create the skill:

```markdown title="skills/greet/SKILL.md"
---
name: greet
description: Greet the user and offer help.
---

Greet the user and offer help.
```

A skills-capable client loads `plugin.json`, discovers the immediate children of `skills/`, and validates 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](https://github.com/agentplugins/agent-plugins-example).

## Package boundaries [#package-boundaries]

Files supplied by the package must resolve within the plugin root. Configuration fields defined as plugin-relative paths begin with `./`; symlinks and equivalent filesystem mechanisms must not be used to escape the package.

Client-managed installation, distribution, enablement, updates, and user interface are outside the portable specification.

## Next steps [#next-steps]

* **[Manifest](/plugin-authors/manifest)** — Define the plugin identity, metadata, and target specification version.
* **[Skills](/plugin-authors/skills)** — Package Agent Skills under the fixed `skills/` directory.
* **[MCP servers](/plugin-authors/mcp-servers)** — Configure local and remote MCP connections in `mcp.json`.
* **[Client extensions](/plugin-authors/client-extensions)** — Add namespaced behavior for particular clients without changing the portable contract.


---
title: Plugin manifest
description: Define portable plugin identity and metadata in root plugin.json.
---

# Plugin manifest



Every Agent Plugin contains exactly one portable manifest at `plugin.json` in the plugin root. The document must be a JSON object and must declare the canonical schema identifier and a plugin name.

## Minimal manifest [#minimal-manifest]

```json title="plugin.json"
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "deployment.tools"
}
```

The manifest schema is closed. Portable top-level fields are limited to:

| Field         | Required | Purpose                                                                                  |
| ------------- | :------: | ---------------------------------------------------------------------------------------- |
| `$schema`     |    Yes   | Selects the complete Agent Plugins validation and interpretation 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 containing optional `name`, `email`, and `url` strings.                           |
| `homepage`    |    No    | Documentation or homepage string.                                                        |
| `repository`  |    No    | Source repository string.                                                                |
| `license`     |    No    | License string; an [SPDX license identifier](https://spdx.org/licenses/) is recommended. |
| `keywords`    |    No    | Array of search and discovery strings.                                                   |
| `extensions`  |    No    | Client-owned data keyed by reverse-domain namespace.                                     |

Metadata strings are not rejected merely because they fail URL, email, Semantic Versioning, or SPDX syntax. Their JSON types remain mandatory.

## Name constraints [#name-constraints]

Plugin names are 1–64 characters and use only lowercase ASCII letters, digits, hyphens, and periods. They begin and end with an alphanumeric character and cannot contain `--` or `..`.

**Valid:** `my-plugin`, `acme.tools`, `lint3r`

**Invalid:** `My-Plugin`, `-start`, `has--double`, `too.many..dots`

## Unknown and invalid fields [#unknown-and-invalid-fields]

An unknown top-level field is a schema violation, but it does not invalidate an otherwise valid plugin: a client reports and ignores that field. Client-specific data belongs under `extensions`.

Other manifest schema violations are fatal. A client rejects the plugin without discovering or executing its components.

## Canonical schema [#canonical-schema]

Download [`plugin.schema.json`](/schemas/1.0.0/plugin.schema.json). The normative specification text governs if it conflicts with the machine-readable schema.


---
title: MCP servers
description: Configure portable stdio, Streamable HTTP, and legacy HTTP+SSE MCP connections.
---

# MCP servers



Agent Plugins defines a closed `mcp.json` format that clients map to their native MCP configuration. The [Model Context Protocol specification](https://modelcontextprotocol.io/specification) remains authoritative for MCP wire behavior and lifecycle.

## Configuration document [#configuration-document]

`mcp.json` lives at the plugin root and contains only `$schema` and `mcpServers` as its top-level fields:

```json title="mcp.json"
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "validator": {
      "type": "stdio",
      "command": "./bin/validator",
      "args": ["--data", "${PLUGIN_DATA}/validator"],
      "env": {
        "CONFIG": "${PLUGIN_ROOT}/config.json"
      },
      "cwd": "${PLUGIN_ROOT}"
    },
    "deployment-api": {
      "type": "streamable-http",
      "url": "https://deploy.example.com/mcp",
      "headers": {
        "X-Tenant": "public-tenant"
      }
    }
  }
}
```

## Transports [#transports]

| Type              | Required fields   | Notes                                                      |
| ----------------- | ----------------- | ---------------------------------------------------------- |
| `stdio`           | `type`, `command` | Optional `args`, `env`, and `cwd`.                         |
| `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 conformant client supports at least one of `stdio` and `streamable-http` and should support both. Support for `sse` is optional. A client uses the declared transport for its initial connection attempt. Agent Plugins does not define fallback behavior if that attempt fails.

## stdio commands and paths [#stdio-commands-and-paths]

`command` is one executable token, not a shell command. It is either a bare executable name resolved by platform search rules or a plugin-relative path beginning with `./`. Placeholder expansion does not apply to `command`.

When omitted, `cwd` is the plugin root. An explicit `cwd` is plugin-relative, rooted at `${PLUGIN_ROOT}`, or rooted at `${PLUGIN_DATA}`, and must stay within the corresponding directory.

## Plugin variables [#plugin-variables]

Clients provide two environment variables to stdio subprocesses:

* `PLUGIN_ROOT`: the absolute, filesystem-resolved plugin root.
* `PLUGIN_DATA`: a dedicated writable data directory that persists across plugin updates.

Clients expand both placeholders in `args`, `env` values, and `cwd`. Expansion is textual, single-pass, and non-recursive. It does not apply to environment keys, `command`, remote URLs, or HTTP headers. A plugin cannot override the reserved environment variables.

## Remote connections [#remote-connections]

Remote URLs are absolute HTTP or HTTPS URLs without user information or fragments. Non-loopback endpoints use HTTPS. Configured headers are literal, visible package data and must not contain credentials or secrets.

Agent Plugins 1.0.0 defines no portable OAuth or credential-reference fields. Authentication remains client-managed.

## Failure isolation [#failure-isolation]

An invalid top-level `mcp.json` disables MCP for the plugin. An invalid or unavailable individual server disables only that entry. Other servers, skills, and client extensions continue loading.

Download [`mcp.schema.json`](/schemas/1.0.0/mcp.schema.json).


---
title: Skills
description: Package Agent Skills under the fixed skills directory.
---

# Skills



Agent Plugins uses the [Agent Skills specification](https://agentskills.io/specification) without redefining the skill format. Agent Plugins defines only where skills are discovered inside a plugin and how failures are isolated.

## Directory layout [#directory-layout]

Place each skill in an immediate child directory of `skills/`:

```text
skills/
└── deploy/
    ├── SKILL.md
    ├── scripts/
    │   └── rollback.sh
    ├── references/
    │   └── runbook.md
    ├── assets/
    └── examples/
```

An immediate child is a discovered skill when its path named exactly `SKILL.md` resolves to a regular file. Clients do not recursively search deeper descendants for additional skills.

## Skill format [#skill-format]

`SKILL.md` frontmatter and instructions follow the Agent Skills specification. A skill may contain any additional files and directories it needs. `scripts/`, `references/`, and `assets/` are common conventions described by Agent Skills, not an exhaustive allowlist. The Agent Skills specification is the source of truth for skill validity.

## Failure isolation [#failure-isolation]

If one discovered skill is invalid, the client skips that skill, reports it when practical, and continues loading other skills and component types.

If `skills/` is missing, the plugin is still valid. If the path exists but is not a directory, the skills component type is invalid without invalidating independent components such as MCP servers.


---

For a semantic overview of all documentation, see [/sitemap.md](/sitemap.md)

For an index of all available documentation, see [/llms.txt](/llms.txt)