Quick answer
Create a directory with root plugin.json, then place each Agent Skill in an immediate child directory of skills/ and declare MCP servers in root mcp.json. Pin both JSON files to Agent Plugins 1.0.0 canonical schemas, keep package paths contained, and validate components independently.
That produces a conforming package. It does not produce a trusted distribution, permission model, sandbox, credential store, or universal install command.
1. Decide whether you need a plugin
Use a plugin when related skills and MCP servers need one versioned package or must move across compatible clients. A single skill can remain a skill, and a single MCP server can use a client’s native configuration.
Write the package purpose in one sentence. If components have unrelated permissions, users, data, release cycles, or owners, split them into separate plugins.
2. Create the fixed directory layout
reports-plugin/
├── plugin.json
├── skills/
│ ├── weekly-summary/
│ │ ├── SKILL.md
│ │ └── references/
│ └── anomaly-review/
│ └── SKILL.md
├── mcp.json
├── bin/
│ └── reporting-server
└── com.example.client/
└── hooks/
The client discovers only immediate children of skills/ that contain a regular file named exactly SKILL.md. It does not recursively find additional skills nested deeper.
3. Write the manifest
Start with the smallest closed-schema manifest:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "reports-plugin",
"version": "1.0.0",
"description": "Review reporting data and prepare bounded weekly summaries",
"license": "Apache-2.0",
"repository": "https://github.com/example/reports-plugin"
}
Use only permitted top-level fields. Put client-specific manifest data under a reverse-domain namespace in extensions. Do not add component paths: fixed locations are part of the portable contract.
Validate names, versions, URLs, keywords, and author fields against the live schema rather than copying remembered constraints.
4. Add skills
Each skill follows the Agent Skills specification:
skills/weekly-summary/
├── SKILL.md
├── scripts/
├── references/
└── assets/
Keep its description specific enough for client selection. Put essential safety, evidence, permission, and output rules in the skill itself. Reference files should deepen the workflow, not hide critical authorization conditions from reviewers.
Validate every SKILL.md independently. One invalid skill should be skipped without breaking valid siblings or MCP servers.
5. Add MCP servers
Root mcp.json has its own schema and explicit server types:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
"mcpServers": {
"local-reporting": {
"type": "stdio",
"command": "./bin/reporting-server",
"args": ["--data", "${PLUGIN_DATA}/reports"],
"cwd": "${PLUGIN_ROOT}"
},
"remote-catalog": {
"type": "streamable-http",
"url": "https://catalog.example.com/mcp",
"headers": {
"X-Client": "reports-plugin"
}
}
}
}
For stdio, command is one executable token, not a shell command string. Put arguments in args. A bundled executable uses a plugin-relative path beginning ./. Review ${PLUGIN_ROOT} and ${PLUGIN_DATA} expansion and working-directory containment.
For remote servers, use an absolute HTTPS URL outside loopback. Do not embed credentials in headers. A client can add its own authorization headers; v1 does not standardize OAuth or portable credential references.
Do not add automatic fallback between transports. The client uses the declared type for the initial connection.
6. Add client extensions only when needed
Client-specific commands, hooks, agents, or metadata can use an extension namespace:
{
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
"name": "reports-plugin",
"extensions": {
"com.example.client": {
"reviewMode": true
}
}
}
Related files go in a top-level directory named exactly com.example.client/. The namespace owner defines the content. Other clients ignore it, so do not make a portable skill or MCP server depend silently on an extension.
7. Validate in layers
Package validation
- Resolve the plugin root and every package file through symlinks and platform equivalents.
- Confirm
plugin.jsonstays inside the root. - Validate the pinned manifest schema and allowed fields.
- Confirm fixed component locations use the expected filesystem types.
Component validation
- Validate each skill against Agent Skills.
- Validate the
mcp.jsontop level and matching spec version. - Validate each MCP entry against exactly one closed transport variant.
- Start or connect to entries individually and preserve failure isolation.
Target-client validation
- Record whether the client supports skills, MCP, or both.
- Test required MCP transports and placeholder behavior.
- Test install, enable, update, disable, and removal flows.
- Confirm client extensions are optional or explicitly required.
Security validation
- Review every instruction, executable, remote origin, argument, environment value, working directory, and data destination.
- Keep credentials outside the package.
- Apply least-privilege service permissions and client tool approvals.
- Define subprocess, filesystem, and network isolation separately.
- Verify package source, integrity, provenance, update policy, and rollback through client or organizational controls.
8. Test failure boundaries
Deliberately test an invalid skill, invalid MCP entry, unsupported transport, failed authentication, mismatched schema version, escaping path, and unavailable executable. The client should apply the narrowest specified failure boundary and continue loading unrelated valid components where the specification requires it.
Do not market partial loading as proof of overall health. Report exactly which components were accepted, skipped, or failed.
Publication checklist
- One coherent purpose and least-privilege permission profile.
- Canonical schemas pinned to the same supported version.
- No unknown portable fields or inline component configuration.
- No credentials or sensitive endpoints in package data.
- License and repository metadata match the distributed contents.
- Compatibility matrix tested on named client versions.
- Client-specific features labeled non-portable.
- Install, trust, permission, sandbox, update, and removal instructions documented outside the v1 package claim.
Read the Agent Plugins 1.0 specification guide for requirement details and compare Plugins, Skills, and MCP before adding a wrapper. For Google examples, see Agents CLI and Data Agent Kit.
Frequently asked questions
What is the minimum valid Agent Plugin?
A directory with root plugin.json containing supported $schema and valid name fields.
Can plugin.json list skill or MCP paths?
No. V1 uses fixed locations and does not allow inline component configuration.
Can I put an API token in mcp.json headers?
No. Configured headers are visible package data, and v1 defines no portable credential mechanism.
How should I validate a plugin before publishing?
Validate both JSON schemas, every skill and MCP entry, package containment, target clients, and the separate security and distribution layers.
Official sources
- Agent Plugins author guide
- Manifest reference
- Skills packaging reference
- MCP server packaging reference
- Client extensions reference
Source check: August 9, 2026. Validate examples against the current Working Draft, canonical schemas, Agent Skills specification, MCP specification, and target clients before publishing.