Skip to content

fix(mcp): reject broken server commands, carry Codex MCP auth, cite dialect facts - #47

Merged
steve-calvert-glean merged 4 commits into
mainfrom
fix/mcp-validation
Oct 21, 2026
Merged

steve-calvert-glean merged 4 commits into
mainfrom
fix/mcp-validation

Conversation

@steve-calvert-glean

Copy link
Copy Markdown
Contributor

Problem

MCP rendering (#37) let broken servers through, and could not express one documented Codex feature:

  • ${CLAUDE_PLUGIN_ROOT}/scripts/server.sh --stdio became ./scripts/server.sh --stdio, which clients run as one filename. Build and validate both passed.
  • Codex documents per-server auth under extensions["com.openai"] in mcp.json. pluginpack rejected the field, so a remote server that needs auth could not be built for Codex.
  • The per-host variable and transport facts that feat: render MCP config into each target's MCP dialect #37 relies on had no citations. One of them, "Cursor has no plugin-data variable", is now a build error.
  • Claude Code ignores cwd for plugin MCP servers. It substitutes ${CLAUDE_PLUGIN_ROOT} only in command, args and env. A real Claude Code 2.1.284 run started the server in the user's directory. pluginpack still wrote cwd, so the server started in the wrong place without an error.
  • A ./ command naming a file the plugin does not ship built and validated cleanly.

Change

  • Agent Plugins output rejects a ./ or root-variable command containing whitespace, and says to move arguments into args.
  • A new codex MCP dialect allows a per-server extensions object limited to com.openai. agent-plugins stays 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.
  • Each native dialect rule carries a documentationUrl and verifiedAt, and the existing citation test covers them. CONFORMANCE.md states that the cited Copilot docs cover Agent Plugins packages, not the legacy .mcp.json that the copilot target writes. Copilot rewriting is unchanged.
  • The claude dialect fails the build when a stdio server sets cwd. The error names the plugin, the server and the field, and gives both fixes.
  • The build warns when a ./ or root-variable command, or a root-variable args entry, names a file the plugin does not ship. Package validate fails on a missing command file.

Breaking changes

A claude MCP server with cwd now fails the build. In 0.11, that output started the server in the wrong directory.

Testing

npm run check passes. Each new test was confirmed to fail with the src/ changes stashed. All cited URLs were fetched and checked against the stated facts.

…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.
@steve-calvert-glean steve-calvert-glean added the breaking Considered a breaking change label Oct 21, 2026
@steve-calvert-glean
steve-calvert-glean marked this pull request as ready for review October 21, 2026 23:58
@steve-calvert-glean
steve-calvert-glean merged commit 6ef9f5c into main Oct 21, 2026
@steve-calvert-glean
steve-calvert-glean deleted the fix/mcp-validation branch October 21, 2026 23:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

breaking Considered a breaking change

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant