Repository navigation
fix(mcp): reject broken server commands, carry Codex MCP auth, cite dialect facts - #47
Merged
Merged
Conversation
…facts
A command such as `${CLAUDE_PLUGIN_ROOT}/bin/server --stdio` passed build
and validate for Agent Plugins output, because the root variable was
rewritten to `./bin/server --stdio` and only bare names were checked for
spaces. Clients run the whole value as one file name, so the server never
starts. A `./` command that contains whitespace is now a build error that
says to move the arguments into `args`.
Codex reads per-server MCP auth from `extensions["com.openai"].auth` in
mcp.json, but the Agent Plugins 1.0 server shape is closed, so pluginpack
rejected the field and Codex auth could not be expressed. The codex target
now renders MCP config in a `codex` dialect that passes a per-server
`extensions` object through, limited to the `com.openai` namespace, and
codex validation accepts the same shape. The agent-plugins target keeps the
strict shape, with or without `clients.codex`, because other conforming
clients skip a server with an unknown field. CONFORMANCE.md records the
conflict and the overrides workaround.
The native MCP dialect rules (variable names per client, Cursor inferring
the transport, Cursor having no plugin-data variable) had no citations,
although every other target fact does. Each rule now carries a
documentation URL and a verification date, taken from the Claude Code,
Cursor and Copilot CLI plugin references, and the existing citation test
covers them. CONFORMANCE.md lists the facts and two places where current
behavior is not backed by the docs.
A `./` or root-variable command that names a file the plugin does not ship
built cleanly and validated cleanly. The build now warns, naming the target,
plugin, server and missing file. It does not fail, because a file such as a
compiled binary can be added to the output after the build. Validation of
an Agent Plugins package reports the missing file as an error.
Claude Code resolves plugin variables only in a stdio server's command,
args and env, and it starts plugin MCP servers in the session's working
directory whatever cwd says. Writing cwd as ${CLAUDE_PLUGIN_ROOT}/... looked
right but left the server in the wrong directory, so the claude dialect now
fails the build for any server with cwd and says how to fix it: resolve
paths in args with ${CLAUDE_PLUGIN_ROOT}, or use a claude-only MCP config
override.
The dialect cites the Claude Code plugins reference for the rule, and
CONFORMANCE.md now states exactly what the Copilot docs cover: they document
expansion for Agent Plugins packages and for agent frontmatter, not for the
legacy .mcp.json the copilot target emits, so that rewriting stays
unverified rather than proven.
…ship
The build already warned when a ./ or root-variable command named a file
missing from the output, but the common form, command "node" with
args ["${PLUGIN_ROOT}/server.js"], went unchecked. The build now warns for
any args entry that starts with a plugin-root variable and names neither a
shipped file nor a shipped directory. It stays a warning, like the command
check, because the file can be added after the build.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
MCP rendering (#37) let broken servers through, and could not express one documented Codex feature:
${CLAUDE_PLUGIN_ROOT}/scripts/server.sh --stdiobecame./scripts/server.sh --stdio, which clients run as one filename. Build and validate both passed.extensions["com.openai"]inmcp.json. pluginpack rejected the field, so a remote server that needs auth could not be built for Codex.cwdfor plugin MCP servers. It substitutes${CLAUDE_PLUGIN_ROOT}only incommand,argsandenv. A real Claude Code 2.1.284 run started the server in the user's directory. pluginpack still wrotecwd, so the server started in the wrong place without an error../command naming a file the plugin does not ship built and validated cleanly.Change
./or root-variable command containing whitespace, and says to move arguments intoargs.codexMCP dialect allows a per-serverextensionsobject limited tocom.openai.agent-pluginsstays on the strict 1.0 schema, and its error names the per-target override workaround. CONFORMANCE.md records the conflict between the Agent Plugins 1.0 schema and the Codex docs.documentationUrlandverifiedAt, and the existing citation test covers them. CONFORMANCE.md states that the cited Copilot docs cover Agent Plugins packages, not the legacy.mcp.jsonthat thecopilottarget writes. Copilot rewriting is unchanged.claudedialect fails the build when a stdio server setscwd. The error names the plugin, the server and the field, and gives both fixes../or root-variable command, or a root-variableargsentry, names a file the plugin does not ship. Packagevalidatefails on a missing command file.Breaking changes
A claude MCP server with
cwdnow fails the build. In 0.11, that output started the server in the wrong directory.Testing
npm run checkpasses. Each new test was confirmed to fail with thesrc/changes stashed. All cited URLs were fetched and checked against the stated facts.