OpenCastle

Docs / Agent Plugins

Agent Plugins and the open standards

The formats AI coding assistants read are converging on open standards. OpenCastle writes them wherever an assistant reads them, uses any Agent Plugin in every assistant — including the ones that do not read Agent Plugins yet — and publishes your team's standard as one.

The Standards

Four open standards now cover most of what an assistant is given. Three are stewarded by the Linux Foundation's Agentic AI Foundation; Agent Skills started at Anthropic and is read by dozens of tools.

StandardCoversWhat OpenCastle does with it
AGENTS.mdProject instructionsWrites it for Codex CLI and OpenCode, and Antigravity reads it beside GEMINI.md; Claude Code gets the same content in CLAUDE.md, Copilot and Windsurf in their own instruction and rule files, and Cursor in its rule files unless it already reads them from CLAUDE.md or AGENTS.md
Agent Skills (SKILL.md)Procedures an agent loads when a task matchesEvery skill — OpenCastle's, your baseline's, your project's — is compiled as a SKILL.md folder named as the skill, where each assistant reads skills
MCPTools and data an agent can callWrites every server in each assistant's own config, in its own variable syntax — JSON for six, .codex/config.toml for Codex
Agent Plugins 1.0A package of skills and MCP serversUses any Agent Plugin as a baseline, publishes yours as one, and ships each of its 33 integrations as one

What none of them covers yet — custom agents, commands, hooks, scoped rules, a policy for which servers may run — OpenCastle still compiles assistant by assistant. Agent Plugins gives that a place to live inside a standard package: a client's own namespace.

What an Agent Plugin Is

Agent Plugins 1.0 was published in August 2026 by maintainers from Amazon, Cursor, Microsoft, OpenAI and Vercel. A plugin is a directory:

my-plugin/
├── plugin.json          the manifest — $schema and name are required
├── skills/
│   └── summarize/
│       ├── SKILL.md     an Agent Skill, named as its directory
│       └── references/
├── mcp.json             MCP servers: stdio, streamable-http or sse
└── com.example.client/  anything one assistant adds, under its own namespace

The manifest is closed: ten fields, two required. Skills follow the Agent Skills spec, and a skill whose name does not match its directory is skipped. MCP servers are a closed union of three transports. Anything a single assistant adds goes under a reverse-domain namespace — OpenCastle's is dev.opencastle.

AssistantReads Agent PluginsMarketplace file
GitHub Copilot (VS Code, CLI)Yes, plugin.json at the root.github/plugin/marketplace.json or .claude-plugin/marketplace.json
CursorYes.cursor-plugin/marketplace.json
Codex CLIYes.agents/plugins/marketplace.json
KiroYes—
Claude CodeIts own manifest, .claude-plugin/plugin.json, and .mcp.json — opencastle plugin build writes both.claude-plugin/marketplace.json
Windsurf (Devin Desktop), OpenCode, AntigravityNot as plugins — OpenCastle compiles a plugin's skills and servers into their own files—

Use One Everywhere

Any Agent Plugin can be a baseline. Install it as a devDependency — or keep it in the repository — and extend it:

// .opencastle/config.json
{
  "extends": ["@acme/ai-standard"]   // an installed package, or a path from this file: "../plugins/ai-standard"
}

opencastle sync then compiles its skills and its servers into every assistant the project compiles for, held to your policy and recorded in the lock, like any baseline's. No OpenCastle declaration is needed in its package.json: a plugin.json at its root is enough.

  • Skills are compiled as they are. One the Agent Skills spec would have an assistant skip — a name that does not match its directory — is reported.
  • Servers in mcp.json become the project's: ./ and ${PLUGIN_ROOT} become the plugin's path from the project root, where assistants start a project's servers.
  • A server that uses ${PLUGIN_DATA}, a working directory of its own, or the legacy SSE transport is left out with the reason: those need an assistant that installs the plugin itself.
  • A manifest a conformant client would reject — a missing name, a field of the wrong type — is an error, and nothing is written.

Publish Your Standard

opencastle baseline init creates a baseline that is also an Agent Plugin. Assistants that read Agent Plugins can install its skills and servers as they are; OpenCastle compiles all of it — including what the standard does not cover — into every assistant, in every repository that extends it.

ai-standard/
├── package.json             "opencastle": { "baseline": "." }
├── README.md
├── plugin.json              the Agent Plugins manifest
├── mcp.json                 servers every assistant can start as they are
├── skills/
│   └── code-review/
│       └── SKILL.md
├── dev.opencastle/          OpenCastle's namespace: what the standard does not cover yet
│   ├── config.json          the policy, and servers that need ${NAME} variables
│   └── instructions/
│       └── engineering-standards.md
├── .github/workflows/
│   └── check.yml            runs opencastle baseline check on every push and pull request
├── .claude-plugin/
│   └── plugin.json          Claude Code's copy — opencastle plugin build writes it
└── .mcp.json                Claude Code's copy of mcp.json, once mcp.json has a server
{
  "$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
  "name": "acme.ai-standard",
  "version": "0.1.0",
  "description": "Our AI assistant standard: compiled by OpenCastle into every assistant …",
  "license": "UNLICENSED"
}

A server every assistant can start as it is — a remote server with OAuth, a pinned local one — goes in mcp.json. One that needs a token or another value from the developer goes in dev.opencastle/config.json, written as ${NAME}: the standard has no way to name a secret yet, and OpenCastle spells the variable the way each assistant expects.

The scaffold's policy in dev.opencastle/config.json allows only its example servers. Add a new server's name to policy.mcp.allow, and a remote server's host to policy.mcp.remoteHosts, or opencastle baseline check fails on it.

Claude Code reads its own manifest, so opencastle plugin build writes .claude-plugin/plugin.json and .mcp.json from the portable files, and check fails when they fall behind:

$ npx opencastle plugin check ai-standard

  🏰 Agent Plugin acme.ai-standard 0.1.0 · Agent Plugins 1.0.0

  Skills: code-review
  MCP servers: internal-docs
  dev.opencastle/: OpenCastle content — check it with opencastle baseline check
  ✗ .mcp.json does not match plugin.json and mcp.json — run opencastle plugin build

  1 problem(s) to fix.

$ npx opencastle plugin build ai-standard
  ✓ Wrote .mcp.json

$ npx opencastle plugin check ai-standard
  …
  ✓ Loads in GitHub Copilot, VS Code, Cursor, Codex and Kiro as it is, and in Claude Code.

A skill someone wrote for their own assistant joins the standard with opencastle promote skill <name> --to ai-standard, checked against the Agent Skills spec and for credentials on the way in. See Team Memory.

Distribute It

For developers who install plugins in their assistant rather than through a repository, keep your plugins in one repository and let opencastle plugin index write the file each assistant reads a marketplace from:

agent-plugins/
├── package.json
├── plugins/
│   ├── ai-standard/      an Agent Plugin
│   └── payments/         another
├── .claude-plugin/marketplace.json     Claude Code, Copilot CLI
├── .cursor-plugin/marketplace.json     Cursor team marketplaces
└── .agents/plugins/marketplace.json    Codex
$ npx opencastle plugin index
  ✓ Listed 2 plugin(s) in .claude-plugin/marketplace.json, .cursor-plugin/marketplace.json, .agents/plugins/marketplace.json
  …
{
  "name": "acme.agent-plugins",
  "owner": { "name": "Acme Platform" },
  "metadata": { "description": "Acme's plugins for every assistant" },
  "plugins": [
    {
      "name": "acme.ai-standard",
      "source": "./plugins/ai-standard",
      "description": "Our AI assistant standard: …"
    },
    …
  ]
}

Claude Code, Copilot CLI and Cursor read the same shape; Codex reads its own. Each developer adds the repository once — claude plugin marketplace add acme/agent-plugins, copilot plugin marketplace add acme/agent-plugins, codex plugin marketplace add acme/agent-plugins, or in Cursor under Dashboard → Plugins → Team Marketplaces → Import. Run opencastle plugin index --check in CI so a new plugin is never missing from the list.

Integrations

Each of OpenCastle's 33 integrations is an Agent Plugin directory, checked against the spec in OpenCastle's own tests:

src/orchestrator/plugins/supabase/
├── plugin.json        compiled from config.ts; OpenCastle's own data under extensions."dev.opencastle"
├── mcp.json           the Supabase remote server, as streamable-http
├── skills/
│   └── supabase-database/
│       └── SKILL.md
└── config.ts          detection, agent tools, earlier defaults — what only OpenCastle reads

Their skills are compiled under the skill's own name — supabase-database, not supabase — so an assistant that follows the Agent Skills spec loads them. A team config that excludes skills/supabase still works, with a warning naming the new spelling.

What check Checks

opencastle plugin check loads a plugin the way the 1.0.0 spec says a conformant client must, and reports what such a client would refuse, skip or ignore. baseline check runs the same checks on a baseline that is a plugin.

  • Manifest — a $schema naming a published version; a name of lowercase letters, digits, hyphens and periods; the types of every field; author holding only name, email and url. An unknown field is reported and ignored, as a client does.
  • Skills — each immediate child of skills/ with a SKILL.md: a name matching its directory, a description of at most 1,024 characters, compatibility and metadata in their shapes.
  • MCP servers — a mcp.json on the same version as the manifest; a command that is one executable, bare or ./; no PLUGIN_ROOT in env; https unless the host is loopback; no credentials in the URL; no header given twice.
  • Containment — the manifest and every skill resolve inside the plugin, links followed.
  • Claude Code's copies — that .claude-plugin/plugin.json and .mcp.json match the portable files.

Limits

  • Agent Plugins 1.0 covers skills and MCP servers only. Instructions, agents, prompts, workflows and policy travel in dev.opencastle/, which only OpenCastle reads; an assistant that installs the plugin natively gets its skills and portable servers.
  • No secrets in the standard yet. A portable server that needs a token reads it from the environment the assistant runs in; one that needs a value spelled into its config belongs in dev.opencastle/config.json.
  • Distribution is not standardised. Each assistant indexes a marketplace in its own file, which is why plugin index writes three.
  • OpenCastle does not fetch plugins. As with any baseline, your package manager installs and pins it; extends names an installed package or a path.