Skip to content

[FEATURE]: support the Agent Plugins standard (agent-plugins.org) #40993

Closed as not planned

Description

@garysassano

Describe the enhancement you want to request

OpenCode has no support for Agent Plugins, the vendor-neutral packaging spec for bundling Agent Skills and MCP servers into a portable plugin.

Context

This is a broad, multi-vendor effort rather than any one company's format. Agent Plugins 1.0.0 was published by a TSC of Core Maintainers from Amazon, Cursor, Microsoft, OpenAI, and Vercel, and Google has since joined as a Core Maintainer.

Support already spans most major agent clients:

Vendor Products supporting Agent Plugins
OpenAI ChatGPT, Codex
Microsoft VS Code, GitHub Copilot
Amazon Kiro
Cursor Cursor
Google Agents CLI, Data Agent Kit

The first four rows are per the launch announcement; Google's two are per its Core Maintainer announcement above, with more of its products to follow.

OpenCode is a conspicuous omission, and it's the one place a user's skills currently don't follow them.

Both a client implementation and conformant plugins already exist to test against:

  • Codex implements it as of 0.147.0 (2026-08-07), via openai/codex#36544. Root plugin.json now takes precedence, with the legacy .codex-plugin/plugin.json demoted to an optional overlay.
  • AWS's agent-toolkit-for-aws shipped conformant manifests for all four of its plugins in #214 (2026-08-06).

Those AWS plugins install in Codex today. In OpenCode the same directories are only reachable if a user points skills.paths at them by hand, and their bundled MCP servers are not picked up at all.

What the format is

plugin-name/
├── plugin.json          # $schema: https://agent-plugins.org/schemas/1.0.0/plugin.schema.json
├── skills/              # Agent Skills (agentskills.io), which OpenCode already understands
├── mcp.json             # $schema: .../1.0.0/mcp.schema.json
└── com.example.client/  # reverse-domain namespace for client-specific extensions

Notably, OpenCode already discovers ~/.claude/skills/** and ~/.agents/skills/** and already speaks MCP. The gap is only the manifest layer that binds them into one installable, versioned unit.

Proposal

  1. Recognize a root plugin.json as a plugin manifest, gated on $schema matching https://agent-plugins.org/schemas/1.0.0/plugin.schema.json. Codex treats a non-matching or absent $schema as "not an Agent Plugin" and falls through, which seems like the right behaviour, since it keeps unrelated plugin.json files from being misread.
  2. Load skills/ through the existing skill discovery path.
  3. Load mcp.json into the existing MCP server config, honouring the spec's transport rules (§7.2.1).
  4. Optionally consume .agents/plugins/marketplace.json for discovery. Both Codex's own curated marketplace and AWS's toolkit already publish at that vendor-neutral path.
  5. Optionally reserve a com.opencode.* (or similar) extension namespace per §8.2 for anything OpenCode-specific.

Relationship to existing issues

  • [FEATURE]: discover skills installed by VS Code agent plugins and Claude Code plugins #40629 asks for discovery of skills sitting inside VS Code agent-plugin and Claude Code plugin directories, by reading each client's own manifests (installed.json, cache.json, installed_plugins.json). That's a per-client compatibility shim; Agent Plugins is the standard that makes such shims unnecessary for conformant packages. The two are complementary, one covering what's already installed today and the other what gets published going forward.
  • feat(opencode): add unified marketplace #40085 (closed) proposed a unified OpenCode marketplace. Supporting the spec would let such a marketplace serve portable packages rather than an OpenCode-only format.

Activity

  1. alper-sh24 commented on Aug 7, 2026

    @alper-sh24

    It seems that it did not really take long for this to appear here and become a burden on the maintainers 😄

    Image
  2. garysassano commented on Aug 7, 2026

    @garysassano
    Author

    I think the main issue is that you have to install the plugin separately for every harness, which means it ends up duplicated across multiple places in your system. That's not an approach I really like.

    What I do instead is keep a global .agents/skills directory and a .agents/AGENTS.md file, then use symlinks so every harness shares the same source of truth. Ideally, plugins would work the same way: you'd install them once at the system level, and every harness would automatically discover and use them without any additional setup.

  3. aagarwal1012 commented on Aug 8, 2026

    @aagarwal1012

    A concrete data point from shipping a conformant plugin, in case it helps size this.

    We published dodopayments/dodo-agent-plugin as an Agent Plugins 1.0.0 package — root plugin.json, seventeen skills as immediate children of skills/, two MCP servers in mcp.json. Verified loading with zero adapter code on:

    • Codex CLI 0.147.0 — 17 skills, 2 MCP servers, PLUGIN_ROOT/PLUGIN_DATA injected per spec
    • Claude Code — via its own manifest
    • Kiro — via the dev.kiro extension namespace

    OpenCode is the one target where the same package needs per-user manual configuration. Skills cannot be shipped at all by an npm-distributed plugin today (#20940, #33896, #41234), so our README has to ask every user to hand-write:

    {
        "plugin": ["@dodopayments/opencode-plugin"],
        "skills": { "paths": ["node_modules/@dodopayments/opencode-plugin/skills"] }
    }

    ...plus a local npm install, because skills.paths resolves against the project directory while OpenCode loads the plugin from its own cache.

    Worth noting how small the gap actually is: OpenCode already implements both halves of the spec's payload. It reads SKILL.md with the same frontmatter contract, and it already discovers .claude/skills/ and .agents/skills/. What is missing is recognising the packaging — a root plugin.json whose $schema is https://agent-plugins.org/schemas/1.0.0/plugin.schema.json, then mapping its sibling skills/ and mcp.json. That is closer to a discovery change than a feature.

    Happy to test against a branch — we have the package, an isolated-HOME harness, and verified expected output on three other clients to diff against.

  4. Marinski commented on Aug 14, 2026

    @Marinski

    There is another similar issue reported about the same thing #41561. I strongly believe this must be implemented so users of OpenCode can benefit of using the skills and agents they are used to with other AI tools.

  5. willem445 commented on Aug 26, 2026

    @willem445

    Throwing it out there that I also would like support for this. It seems copilot, claude code, etc. are converging on standards which opencode explicitly does not support. Many of us live in enterprises where we are forced into a particular harness so that harness's agent artifacts are the default in all repos, for those of us that would rather use opencode, we either have to create a duplicate set of opencode specific variants or make our own bridge plugins, which is what I ended up doing in the interim. Native support for these from opencode would reduce adoption friction considerably.

    https://github.com/willem445/opencode-rosetta

    #19180 is related along these lines.

  6. megamen32 commented on Sep 11, 2026

    @megamen32

    i need that one too. all my harnesses now on my marketplace

  7. zuberek commented on Sep 26, 2026

    @zuberek

    would be great to have this 👍

  8. Marinski commented on Oct 2, 2026

    @Marinski

    @anomalyco this spreads across many issue reports and requests. Please have a loot at it finally. You're losing pace.

  9. davhdavh commented on Oct 13, 2026

    @davhdavh

    Will this also support the per-skill mcp config?

  10. sofianbll commented on Oct 20, 2026

    @sofianbll

    Hi @jlongster — is native support for Agent Plugins 1.0 already underway on your side? If not, I'd like design feedback on a narrow first increment before opening anything.

    Idea: an explicitly configured local directory with a root plugin.json (and no JS entrypoint) becomes a synthetic plugin generation. Its skills/ and mcp.json are registered through the existing ctx.skill.transform / ctx.mcp.transform (same primitives as the Figma plugin, #55049) — no copy into user config, policy checks kept, realpath containment, invalid manifest → explicit error.

    Local proof (throwaway patch on dev 6bac3b9, reproducible CI): a real package is configured under plugins, reported active, its skill is served by the skills API, its stdio MCP server (launched with ${PLUGIN_ROOT} / ${PLUGIN_DATA}) connects, and the model calls its tool; removing the config and reloading withdraws both; an invalid manifest registers nothing. Package files are validated offline against the canonical 1.0.0 schemas.
    Patches, package, CI and full proposal: https://github.com/sofianbll/opencode-standards-proof (agent-plugin/, PROOF.md, proposals/opencode-agent-plugins-loader.md).

    Not claimed: full client conformance, HTTP/SSE servers from mcp.json (skipped with a diagnostic), marketplace/remote install, hooks, Windows.

    Questions

    1. Is a local-only synthetic plugin the shape you'd want, and which discovery layer should own recognition?
    2. How should collisions (skill/server ids) and plugin data identity across revisions be handled?

    No PR without a go-ahead, per CONTRIBUTING.

  11. abn commented on Oct 27, 2026

    @abn

    @sofianbll's local-only synthetic-plugin proposal above is a good frame for the recognition question, and I'd like to put an alternative shape next to it for the maintainers to consider rather than talk past it.

    I've had this on a branch in parallel, a single commit on dev:
    abn@b1ee80a

    Where it agrees with the narrower proposal

    • Packages contribute through the existing ctx.skill.transform / ctx.mcp.transform primitives; nothing is copied into user config.
    • Every package path is resolved through realpath and contained before it is read or created.
    • An invalid manifest disables only that package, and user config wins every collision.

    Where it differs

    • Discovery covers the shared ecosystem roots (~/.agents/plugins, and .agents/plugins in each ancestor of the working directory) plus agent-plugins/ inside every config directory, rather than only an explicitly configured directory.
    • The ai.opencode/ extension namespace is part of it: the JS entry, agents//commands//modes/ markdown, and hooks/hooks.json observers.
    • mcp.json maps stdio and streamable-http; sse is skipped with a diagnostic.
    • A location-scoped service owns the scan, the caches and the container watches, and the config plugins read from it. That is my answer to "which layer owns recognition": core, behind the existing config plugin seams, not an npm plugin.

    On the two questions

    • Collisions: servers are keyed ${manifest.name}-${server}, so two packages cannot collide, and user config keys still win.
    • Data identity: PLUGIN_DATA lives under the client data directory keyed by manifest name, so it survives a package update.

    I verified it end to end in a container with an isolated HOME: a package at ~/.agents/plugins/demo contributes a skill, an agent, a command, a stdio MCP server and a hook, all served by the API.

    It would be great to get feedback on this. If everyone agrees and the design is approved, I can open a PR for review. Happy to also accommodate changes as required.

  12. opencodejr commented on Oct 28, 2026

    @opencodejr
    Contributor

    Thanks for the detailed write-up! You're asking for OpenCode to support Agent Plugins 1.0 natively. That means recognising a root plugin.json with the agent-plugins.org $schema, loading its skills/ and mcp.json through the existing skill and MCP config, and optionally reading .agents/plugins/marketplace.json. Then a conformant package that already installs in Codex or Cursor would also work in OpenCode.

    The maintainers will consider it. Related issues:

    In the meantime, a v2 plugin could probably bridge this. The plugin API can add skills (skill.transform) and MCP servers (mcp.transform), so a community plugin could scan for Agent Plugin directories and register what they contain.

  13. Hamza-Abili commented on Nov 6, 2026

    @Hamza-Abili

    Wanted to close the loop on this thread: we shipped a community-side Agent Plugins 1.0 client for OpenCode, on v1 and v2.

    opencode-agent-plugins — https://github.com/Hamza-Abili/opencode-agent-plugins · npm @hamzaabili/opencode-agent-plugins

    What works today (v1.0.0):

    • Auto-discovery — plugins in ~/.agents/plugins/ (global), <project>/.agents/plugins/ (walked up to the git worktree root), plus npm packages that bundle an Agent Plugin (packages option) and marketplace installs. No config entry per plugin.
    • Spec-conformant loading — canonical 1.0.0 failure boundaries: fatal manifest violations reject the plugin, unknown top-level fields are non-fatal, component/entry failures are isolated, sse is skipped with a warning.
    • Containment everywhere — every package path is realpath-checked (plugin.json, skills/, SKILL.md, mcp.json), ./ commands are emitted as post-containment absolute paths, cwd is contained to the plugin root or PLUGIN_DATA, remote MCP URLs must be https (http only on loopback) with no credentials/query/fragment. Provenance and staging copies for installs; update swaps with rollback.
    • Skills register in OpenCode's native skill registry (v2 transform; v1 via a state-tracked symlink farm).
    • Trust-first MCP — servers are registered disabled (disabled: true on v2, enabled: false on v1) until you explicitly enable them with /ap enable. No silent config edits; user-authored config always wins on collisions.
    • In-editor management (v2) — /ap status | list | enable | disable | marketplace | install | update | uninstall | packages | reload. No external CLI, no Node requirement.
    • Marketplace catalogs — reads .agents/plugins/marketplace.json (the Codex-compatible format), supports local, url/git-subdir and npm sources, refuses NOT_AVAILABLE entries, installs only on explicit command.
    • Zero runtime dependencies; 150 tests; OpenCode v1 (…/legacy export) and v2.

    @garysassano — this is the discovery/manifest layer your proposal described. Feedback welcome, especially on the failure boundaries.
    @aagarwal1012 — we'd love you to try it against dodopayments/dodo-agent-plugin: drop the package in node_modules, add "packages": ["@dodopayments/opencode-plugin"] to the plugin options, restart, and run /ap status. That case (skills shipped inside an npm OpenCode plugin) is exactly what packages exists for. Any spec mismatch, we'll fix.
    @sofianbll — if a native implementation is still on the table, happy to share what the plugin-side integration required; skill registration and the MCP disabled lifecycle map 1:1 to a native design.
    @ameshkov — saw opencode-agent-plugins; we chose different tradeoffs (filesystem discovery + in-editor commands + disabled-by-default MCP vs config list + git CLI). Aligning on conformance details would be better for users than diverging — issues/PRs welcome.

    Also worth noting #41561 was closed as not planned, so the community path may be the only path for a while.

  14. abn commented on Nov 6, 2026

    @abn

    @Hamza-Abili This covers the portable half of the spec carefully. The containment and failure boundaries look right, and the marketplace catalogs are a useful addition beyond the spec. Thanks for shipping it as an interim option.

    Both validate plugin.json and mcp.json, contain package paths, provide PLUGIN_ROOT and PLUGIN_DATA, and register skills and MCP servers through the native transforms.

    Yours goes further with marketplace installs, npm packages, /ap, v1 support, and MCP disabled until enabled. That default makes sense for third-party packages.

    The branch I linked adds ai.opencode/ support (JS entry, agents, commands, hooks), agent-plugins/ inside config directories, and a location-scoped service that owns the scan and the watches. A plugin cannot do those, because the API has no plugin source registration and no watcher surface.

    #41561 was closed as not planned because it duplicated this issue and had gone quiet, not because native support was ruled out.

  15. Hamza-Abili commented on Nov 6, 2026

    @Hamza-Abili

    Thanks @abn — that split matches how I read the spec, and thanks for checking the containment and failure boundaries rather than taking the README's word for it.

    Confirming the details you called out, from the implementation:

    • plugin.json / mcp.json are validated in-process against 1.0.0 semantics, nothing fetched at runtime: a missing or non-matching $schema is fatal to that package, unknown top-level fields are non-fatal, one bad MCP entry skips only that entry, legacy sse is skipped with a diagnostic.
    • Paths are realpath-resolved and contained before read — plugin.json, skills/, each SKILL.md, mcp.json — and again at copy time for installs (symlinked parents, dangling leaves).
    • ${PLUGIN_ROOT} / ${PLUGIN_DATA} expand in args/env/cwd; both are exported to stdio servers; cwd is contained to the root or PLUGIN_DATA; if PLUGIN_DATA can't be provisioned that package's servers are skipped rather than handed a path that won't exist at launch.
    • On v2 everything goes through ctx.skill.transform / ctx.mcp.transform, with disabled: true until /ap enable.

    One correction to "a plugin cannot do those", because it matters for where the line sits:

    • Plugin source registration: genuinely unavailable — ctx.plugin.list() is the whole surface.
    • Agents: also unavailable; AgentEditor has no add.
    • agent-plugins/ inside config directories: a plugin can scan those itself today.
    • Watches: no host watcher surface, but a plugin can own a private fs.watch and call ctx.skill.reload() / ctx.mcp.reload().
    • ai.opencode/commands and ai.opencode/hooks are approximable via ctx.command.transform, ctx.tool.hook and ctx.session.hook.

    So the honest version is: plugin sources and new agents need core, while config-directory discovery and watches are reachable from a plugin but belong in core anyway. I deliberately kept them out. Loading a discovered package's JS entry means executing third-party code, and that belongs behind the host's plugin-loading semantics, not inside an npm plugin whose selling point is that MCP stays disabled until you opt in. Same reason I don't want a client inventing its own precedence rules against user config.

    #41561: confirmed — actions-bot duplicate pointer, then the 60-day inactivity auto-close. Nothing to read into beyond that.

    Is b1ee80a meant to land? If it does, I'd rather make this plugin defer for packages core claims and keep marketplace/npm//ap as the layer core doesn't cover, instead of double-registering. Tell me which signal you'd want the plugin to use for "core owns this package" and I'll implement it.

  16. panga commented on Nov 6, 2026

    @panga

    Can AgentEditor add be included in core please.

  17. Hamza-Abili commented on Nov 6, 2026

    @Hamza-Abili

    Follow-up, @abn — your review made me look at this twice, and the first version of the fix was wrong.

    You were right that the client was silent about the half it does not load, but a blanket warning would have been the wrong answer: it fires for packages that already contribute skills or MCP servers (noise today), and it would keep firing after core loads ai.opencode/ (a false alarm by construction). So it is narrowed to the case that is actually confusing: a package that ships only ai.opencode/ components and therefore loads as an empty plugin.

    v1.3.0 (https://github.com/Hamza-Abili/opencode-agent-plugins/releases/tag/v1.3.0):

    • one warning per such package, naming the components present — plugin.ts/plugin.js, agents, commands, modes, hooks — pointing at this issue;
    • packages that also ship skills or MCP servers stay silent about the unloaded components: they already contribute, and the README states the split;
    • the namespace is realpath-contained before it is listed, and only entry names are read: escaping, dangling and unreadable namespaces are reported and never listed; a plain file named ai.opencode is ignored;
    • loading is untouched — skills and MCP registration behave exactly as before, and the warning surfaces in the v1 log, the v2 log and /ap status.

    Verified: 192 tests (bun run ci green), live smoke re-run on OpenCode 2.2.5 (skill registered, MCP reported disabled), release workflow green on the tag 6f30428.

    The README now states the split instead of implying it: shared roots are scanned, extra roots go through directories, and plugin-source registration is not something a plugin can do at all (ctx.plugin.list() cannot add one).

    @panga, on AgentEditor.add: that is a core API addition — a plugin consumes ctx.agent.transform, it cannot extend the editor. If it lands, loading ai.opencode/agents/ still belongs to core discovery; this client already defers per entry on collisions, so nothing would be registered twice.

  18. neriousy commented on Nov 12, 2026

    @neriousy
    Member

    Thanks for the suggestion. This isn't something we plan to build, so closing to keep the tracker focused.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions