Base configuration for authoring Agent Plugins — the vendor-neutral format for packaging Agent Skills and MCP servers so any compatible client can discover and load them.
Targets specification v1.0.0.
plugins/
├── template/ # copy this to start a plugin
│ ├── plugin.json # required manifest
│ ├── mcp.json # optional MCP server declarations
│ └── skills/
│ └── example-skill/
│ ├── SKILL.md # required per skill
│ ├── scripts/
│ └── references/
└── scripts/
├── new-plugin.sh # scaffold a plugin from template/
├── validate.sh # lint a plugin
└── validate.py
plugins/scripts/new-plugin.sh my-plugin "What this plugin does"
plugins/scripts/validate.sh my-pluginnew-plugin.sh copies template/ and fills in name and description. Then:
- Rename
skills/example-skill/and set thename:in itsSKILL.mdto match — the spec requires them to be identical. - Fill in
mcp.json, or delete it if the plugin ships skills only. - Re-run
validate.sh.
The only permitted top-level fields are $schema, name, version,
description, author, homepage, repository, license, keywords and
extensions. $schema and name are required; clients report but ignore
anything else and keep loading.
name: 1–64 chars, lowercase alphanumeric plus hyphens and periods, no leading
or trailing separator, no -- or ...
Servers are keyed by name under mcpServers; an empty object is valid.
stdio — type, command (required); args, env, cwd optional.
command must be a single executable token (a bare name on PATH or a
plugin-relative ./path), never a shell string.
streamable-http / sse — type, url (required); headers optional.
sse is the legacy transport. Remote URLs must be HTTPS; plain HTTP is only
allowed for localhost and loopback addresses.
Clients set PLUGIN_ROOT (the plugin directory) and PLUGIN_DATA (a
client-managed persistent data directory) in the subprocess environment.
${PLUGIN_ROOT} and ${PLUGIN_DATA} expand in args, env values and
cwd only — not in command, not in env keys, and not in HTTP headers.
Expansion is a single non-recursive text replacement; unrecognized placeholders
stay literal.
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"jira": {
"type": "stdio",
"command": "./venv/bin/python",
"args": ["-m", "jira_mcp.server"],
"env": { "JIRA_CONFIG": "${PLUGIN_ROOT}/config.json" },
"cwd": "${PLUGIN_ROOT}"
},
"deploy": {
"type": "streamable-http",
"url": "https://deploy.example.com/mcp"
}
}
}Discovery is fixed at skills/. Every immediate child directory containing a
file named exactly SKILL.md is one skill — there is no recursive scan, so
nested directories are not discovered.
SKILL.md follows the Agent Skills spec.
Frontmatter: name and description required; license, compatibility,
metadata and allowed-tools optional. name must match its directory name.
Write description to cover what it does and when to use it, with the
keywords an agent would see in a user's request — it is the only part loaded at
startup, so it decides whether the skill ever fires.
Keep SKILL.md under ~500 lines and push detail into references/; agents load
those files only when the task needs them.
Client-specific settings go under extensions, keyed by reverse-domain
namespace. Client-specific files go in a top-level directory with that same
namespace name:
my-plugin/
├── plugin.json
├── skills/
└── com.example.client/
└── hooks/hooks.json
Clients ignore namespaces they don't implement, without validating the contents.
validate.sh is an offline lint covering the structural rules above. For full
schema validation, check against the published schemas
(https://agent-plugins.org/schemas/1.0.0/…); for skills specifically, the
skills-ref
library has skills-ref validate ./my-skill.