AI Development

What Is Agent Plugins 1.0.0? plugin.json, MCP, Agent Skills, and the JSON Layout (2026)

About 15 min read

Agent Plugins 1.0.0 is an open directory contract, not another tool-calling protocol. Root plugin.json only names the package and the spec version. Skills sit in skills/. MCP servers are written only in root mcp.json. The model still only fills JSON. The host is what connects to the server.

Before you read

File What the spec requires What it does not do
plugin.json The only manifest, at the root. $schema and name are required. The field list is closed It cannot inline MCP or move a component path
skills/ Only SKILL.md in an immediate child directory. The Agent Skills spec owns the file format No recursive search. A missing directory is not an error
mcp.json Top level is only $schema and mcpServers. Every server must set type It does not run a tool. 1.0.0 has no portable credential fields
Extension directory A reverse-domain folder such as com.example.client/. extensions uses the same namespaces Other clients must be able to ignore it

Facts from the Agent Plugins 1.0.0 specification, the Vercel release note, and the Google Developers Blog, all dated 6 August 2026. Order A-1042 and orders.example.com are fictional.

It packs skills and MCP servers into one directory you can move

Agent Plugins 1.0.0 became public on 6 August 2026. The core maintainers then were from Amazon, Cursor, Microsoft, OpenAI, and Vercel. The same day, the Google Developers Blog said Google was joining that group, represented by Kevin Hou, and starting to build support into its own products. This is not a private format Google published alone. The spec defines two portable component types: Agent Skills and MCP servers. Install, distribution, policy, and UI stay with each client. A client validates root plugin.json before it discovers components. While loading a plugin, the client must not fetch the schema over the network.

  • Manifest: $schema must be https://agent-plugins.org/schemas/1.0.0/plugin.schema.json. name is required.
  • Skills: skills/<name>/SKILL.md. Immediate children only. No recursion.
  • MCP: root mcp.json. Each entry states stdio, streamable-http, or optional legacy sse.

How MCP calls travel on the wire: how a coding agent calls MCP. How an MCP tool schema differs from function calling: MCP tool schema versus function calling. This piece does not rewrite those two. It only says what the two JSON files in a plugin directory own.

The plugin.json field list is closed

The only permitted top-level fields are $schema, name, version, description, author, homepage, repository, license, keywords, and extensions. The first two are required. A name is 1 to 64 characters, lowercase letters, digits, hyphens, and periods only, must start and end with a letter or digit, and must not contain -- or ... Semantic Versioning is recommended for version, but a non-SemVer string is not by itself a reason to reject the manifest. author may contain only name, email, and url. A fictional order plugin:

{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "orders-plugin",
  "version": "1.0.0",
  "description": "Look up fictional order A-1042. No refunds.",
  "license": "Apache-2.0",
  "keywords": ["orders"]
}

An unknown top-level field must be reported and ignored, and loading continues if the rest is valid. A missing required field, a wrong type, or an illegal name rejects the whole plugin. No component is discovered or executed. Client-specific data goes in extensions, keyed by a reverse-domain namespace, and each value must be an object. No other file can override the core fields of the root manifest.

Skills and MCP cannot be written into the manifest

The spec fixes the locations. Each immediate child of skills/ that contains a regular file named exactly SKILL.md is one skill. Frontmatter and the scripts/, references/, and assets/ layout belong to the Agent Skills spec. This spec only says how a skill is discovered, not how a client shows it to a model. MCP must not be inlined in plugin.json and must not move to another path. The only top-level fields of mcp.json are $schema and mcpServers. An empty mcpServers object is valid. The two $schema versions must match. The 1.0.0 MCP identifier is https://agent-plugins.org/schemas/1.0.0/mcp.schema.json. stdio requires type and command. args, env, and cwd are optional. A path that starts with ./ is relative to the plugin root. ../ must not escape that root. The client expands PLUGIN_ROOT and PLUGIN_DATA:

{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/mcp.schema.json",
  "mcpServers": {
    "orders": {
      "type": "stdio",
      "command": "./bin/orders",
      "args": ["--data", "${PLUGIN_DATA}/orders"],
      "cwd": "${PLUGIN_ROOT}"
    }
  }
}

A remote server uses streamable-http and requires url. sse is a deprecated optional transport. The spec defines no fallback when a connection fails. A conformant client supports at least one of stdio and streamable-http, and should support both. Version 1.0.0 has no portable OAuth or credential-reference fields. Authentication stays with the client. Path rules cover files shipped in the package. They do not sandbox the subprocess. Tool arguments still need their own Schema gate: why AI needs JSON Schema.

A broken part stops at its own boundary

The spec splits failures. Do not read one bad JSON file as a dead package:

What went wrong What the client must do
plugin.json lacks a required field, or the type or name is illegal Reject the package. Discover and execute nothing.
An unknown top-level field Report it and ignore it. Keep loading if the rest is valid. Do not invent a meaning for it.
skills/ is missing, or one SKILL.md fails the Agent Skills spec A missing directory is not an error. Skip the bad skill. Other skills and MCP continue.
The mcp.json version mismatches, or one server entry is invalid A version mismatch invalidates MCP only, not skills. One bad server disables only that entry. A bad top-level mcp.json disables every MCP server in the plugin.

A client ignores component types it does not support. A reverse-domain directory such as com.example.client/ belongs to one client. Others must be able to skip it. Unknown namespaces inside extensions are ignored the same way. How a sandbox stops a tools/call that has already been sent is a different layer: OpenShell and Sentry.

Six checks before you ship a plugin

Do not start by pasting an MCP server URL into plugin.json:

  1. Write root plugin.json first. Use only keys from the closed list. A name like orders-plugin stays lowercase.
  2. Put each skill in an immediate child. skills/lookup-order/SKILL.md. A deeper directory will not be discovered.
  3. Write MCP only in mcp.json. Every entry has type. A local server uses stdio and ./bin/orders. Do not use ../.
  4. Point both $schema values at 1.0.0. On a mismatch, skills can still load. MCP cannot.
  5. Leave credentials with the client. mcp.json in 1.0.0 has no portable secret field. Do not commit a token in env or headers.
  6. Give tool arguments their own Schema. The manifest only locates the server. The host still checks A-1042 before it runs a lookup.

A plugin with no skills/ and no mcp.json can still be valid. Only plugin.json is required.

Spread both JSON files before you merge

A failed load is either a rejected package or one skipped MCP server. Split those before you edit the prompt.

  • format plugin.json and mcp.json, then Schema validate whether a top-level key is extra or $schema is missing.
  • Use JSONPath extract for $.name, $.mcpServers.orders.type, and $.mcpServers.orders.command.
  • JSON Diff the manifest against the previous revision. Check that a path does not escape the plugin root.
  • Confirm skills/lookup-order/SKILL.md is a regular file in an immediate child, not a deeper file.
  • redact tokens in the config first. Do not paste an mcp.json that holds a secret into a public formatter. JSONSort runs in the browser.

If both JSON files rebuild against the closed field list and the directories sit in the fixed places, the plugin matches 1.0.0. Whether the client runs the lookup is not decided by the manifest.

Common traps

  • Writing this as Google’s private plugin format. The 6 August 2026 texts describe a cross-vendor spec. Google joined that day as a core maintainer.
  • Putting mcpServers inside plugin.json. The spec forbids inline config and forbids moving the path. Clients read only root mcp.json.
  • Guessing the transport from the object shape. Every server needs type. There is no rule that a URL-shaped value means HTTP.
  • Putting an API key in mcp.json. Version 1.0.0 has no portable credential field. Authentication stays with the client. The sample uses a fictional order.
  • Dropping every skill because one server failed to start. One server failure disables that entry. A bad top-level mcp.json disables MCP. Skills keep loading.
  • Using this piece to rewrite MCP versus function calling. It only shows how a plugin puts an existing MCP config in a fixed file.

FAQ

Is a directory with only plugin.json a valid plugin?

Yes. plugin.json is the only required file. If skills/ or mcp.json is absent, the client loads what is there. That is not an error. A missing required field or an illegal name rejects the whole package.

What if the two $schema values disagree?

The MCP configuration is invalid. Skills and other component types stay valid. On 1.0.0 both files use the 1.0.0 identifier from the spec, and the versions must match.

Can SKILL.md live under skills/orders/extra/?

It will not be discovered. The client looks only at immediate children of skills/ and does not recurse. The file has to be a regular file such as skills/lookup-order/SKILL.md.

Do I have to declare both stdio and streamable-http?

No. One server uses one type. stdio needs command. streamable-http needs url. sse is deprecated, and a client may omit it. The spec does not switch transports when one connection fails.

Does this JSON look up the order by itself?

No. plugin.json names the plugin. mcp.json tells the client where the server is. The host still runs tools/call. An argument such as A-1042 needs its own Schema check. The manifest has no portable secret field.

Conclusion

Agent Plugins 1.0.0 packs Agent Skills and MCP servers into one root directory you can move. plugin.json locks the spec version and the name. Component locations cannot be changed in the manifest.

Check that orders-plugin is in plugin.json, ./bin/orders is in mcp.json, and SKILL.md is in an immediate child. When those three sit in the fixed places, the client does not have to guess where you hid the config.

Further reading

Changelog: First published