Skip to content

feat: support Claude Code alongside the Agent Plugins standard - #4

Merged
jbiskur merged 1 commit into
mainfrom
feat/claude-code-marketplace
Aug 11, 2026
Merged

feat: support Claude Code alongside the Agent Plugins standard#4
jbiskur merged 1 commit into
mainfrom
feat/claude-code-marketplace

Conversation

@jbiskur

@jbiskur jbiskur commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

Fixes This repository isn't a marketplace — no manifest found at .claude-plugin/marketplace.json.

Answer to "should we support both?" — yes, and the cost is low because the two formats overlap where it matters.

What differs

Concern Agent Plugins Claude Code
Plugin manifest plugin.json .claude-plugin/plugin.json
Marketplace .agents/plugins/marketplace.json (Codex) .claude-plugin/marketplace.json
MCP config mcp.json .mcp.json
Remote transport streamable-http http
Skills skills/ skills/

skills/ is shared, so the actual product isn't duplicated — only thin manifests are.

Schema came from Claude Code's docs and was cross-checked against Slack's official plugin, which ships .claude-plugin/, .codex-plugin/, .cursor-plugin/ and .agents/ side by side. This is the established multi-client pattern, not something I invented.

Verified

Claude Code 2.1.227 on macOS:

usable@usable   Version: 0.1.0   Scope: user   Status: ✔ enabled

claude plugin marketplace add ./ — note a bare . is rejected with Invalid marketplace source format.

OAuth client id

.mcp.json declares oauth.clientId: "mcp_oauth_client" — the field Claude Code reads, and the same one Slack's plugin uses. A client_id is a public identifier, not a secret, so it's safe to package.

mcp.json stays URL-only: the Agent Plugins schema defines no oauth field, and inventing one risks rejection by a strict client. Both clients' add commands are documented in authentication.md.

Duplication is guarded, not trusted

Shipping two configs invites drift, so CI now fails on it:

  • the two MCP documents must declare the same servers at the same URLs
  • the two plugin manifests must agree on name and version
  • oauth blocks validate fail-closed — only clientId, callbackPort, scopes permitted, so a clientSecret can't ship by being unrecognised

Twelve new self-tests, each confirmed to actually fail when the defect is introduced. Suite is 27/27.

Also added .claude-plugin/ and .mcp.json to the release allowlist — without that the published artifact would have shipped a package Claude Code cannot install.

Collision: now confirmed, was a hypothesis

A user-level MCP server named usable shadows the plugin's declaration. No plugin:usable:usable appeared, while other plugins' servers did show under that prefix.

I'd previously recorded this as a suspicion for Codex. It's real, and it means the MCP acceptance step can't be verified on a machine that already has such an entry. Documented with the remedy.

Not verified

Claude Code skills reaching the model. The plugin installs, but Claude Code exposes no CLI listing of available skills. The matrix records skills as ⏳ rather than assuming parity with Codex. To check, ask in a session: "Which skills do you have available?" and look for usable:usable-knowledge-workflow.

Claude Code rejected the repository with "no manifest found at
.claude-plugin/marketplace.json". It reads its own manifests, so
supporting both clients means shipping both sets. Only skills/ is
genuinely shared.

  concern            Agent Plugins                    Claude Code
  plugin manifest    plugin.json                      .claude-plugin/plugin.json
  marketplace        .agents/plugins/marketplace.json .claude-plugin/marketplace.json
  mcp config         mcp.json                         .mcp.json
  remote transport   streamable-http                  http

Schema taken from Claude Code's documentation and cross-checked against
Slack's official plugin, which ships .claude-plugin/, .codex-plugin/,
.cursor-plugin/ and .agents/ side by side — so this is the established
multi-client pattern, not an invention.

Verified on Claude Code 2.1.227: `claude plugin marketplace add ./`
registers and `claude plugin install usable@usable` installs and enables
at 0.1.0. Note a bare `.` is rejected; the ./ form is required.

OAuth client id: .mcp.json declares oauth.clientId = mcp_oauth_client,
which is where Claude Code reads it (same field Slack's plugin uses). A
client_id is a public identifier, not a secret, so it is safe to package.
mcp.json stays URL-only because the Agent Plugins schema defines no
oauth field and inventing one risks rejection by a strict client.

Duplication is a drift risk, so it is guarded rather than trusted:
- the two MCP documents must declare the same servers at the same URLs
- the two plugin manifests must agree on name and version
- oauth blocks are validated fail-closed — only clientId, callbackPort
  and scopes are permitted, so a clientSecret cannot ship by being an
  unrecognised field
Twelve new self-tests; suite is 27/27. Also added .claude-plugin/ and
.mcp.json to the release allowlist, without which the published artifact
would have shipped a package Claude Code could not install.

Collision now confirmed, not hypothesised: a user-level MCP server named
`usable` shadows the plugin's declaration. No plugin:usable:usable server
appeared while other plugins' servers did show under that prefix. This
was previously recorded as a suspicion for Codex; it is real, and it
means the MCP step cannot be verified on a machine that already has such
an entry. Documented in authentication.md with the remedy.

Claude Code skills are NOT yet confirmed reaching the model. The plugin
installs, but Claude Code exposes no CLI listing of available skills, so
the matrix records skills as untested rather than assuming parity with
Codex.

Co-Authored-By: Oz <oz-agent@warp.dev>
@jbiskur
jbiskur requested a review from a team as a code owner August 11, 2026 14:21
@jbiskur
jbiskur merged commit 8219d4d into main Aug 11, 2026
4 checks passed
@jbiskur
jbiskur deleted the feat/claude-code-marketplace branch August 11, 2026 14:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant