refactor(client): replace cross-spawn with tinyexec - #2746
Draft
andriyor wants to merge 1 commit into
Draft
Conversation
tinyexec vendors cross-spawn's command normalization and has no dependencies of its own, so Windows .cmd/.bat handling is unchanged while the client's runtime tree drops from six packages to one. Two tinyexec defaults are switched off to keep spawn behavior identical: `nodePath: false` (it otherwise prepends every ancestor node_modules/.bin to the child's PATH) and a mask of parent env keys (it otherwise merges process.env in, voiding the getDefaultEnvironment() safelist). The child environment is byte-identical to the cross-spawn path. No public API change. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
🦋 Changeset detectedLatest commit: 4d77b52 The changes in this PR will be included in the next version bump. This PR includes changesets to release 6 packages
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
@modelcontextprotocol/client
@modelcontextprotocol/codemod
@modelcontextprotocol/core
@modelcontextprotocol/server
@modelcontextprotocol/server-legacy
@modelcontextprotocol/express
@modelcontextprotocol/fastify
@modelcontextprotocol/hono
@modelcontextprotocol/node
commit: |
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.
Motivation
StdioClientTransportspawns server processes throughcross-spawn, which brings five transitive dependencies (which,isexe,path-key,shebang-command,shebang-regex) and has been a recurring advisory target for consumers (#469, #488).tinyexecvendors cross-spawn's command normalization into its bundle and declares no dependencies of its own. Windows.cmd/.batshim resolution and argument escaping are therefore unchanged, while the client's runtime tree drops from six packages to one.Two tinyexec defaults had to be switched off
Both would otherwise have changed spawn behavior silently:
nodePath: false— tinyexec prepends every ancestornode_modules/.bindirectory to the child'sPATH, which would change how the server command resolves.maskInheritedEnvironment()— tinyexec does{...process.env, ...yourEnv}with no opt-out, which would void thegetDefaultEnvironment()safelist and leak the full parent environment to spawned servers. Masking every parent key withundefinedcancels the merge, since Node'sspawndropsundefinedentries.Verified the resulting child environment is byte-identical to the cross-spawn path (the
__CF_USER_TEXT_ENCODINGkey present on macOS comes from CoreFoundation and appears with plainchild_process.spawntoo):No public API change
StdioClientTransport,StdioServerParameters,getDefaultEnvironment, andDEFAULT_INHERITED_ENV_VARSare unaffected.@modelcontextprotocol/client/stdioremains the process-spawning subpath, and the built root entry stays free of spawn dependencies.crossSpawn.test.tsbecomestinyexec.test.tswith the same coverage plus pins for both defaults above, so a future tinyexec upgrade cannot quietly reintroduce either.@types/cross-spawnis dropped from the catalog and the threepackage.jsonfiles that referenced it; thebarrelCleanguards in client and server now watch fortinyexec.Testing
build:all,lint:all,typecheck:allclean.test:allgreen except two pre-existingprotocol:timeout:max-total [sse]failures, confirmed identical on unmodifiedmainin a separate worktree.Note
Per CONTRIBUTING I'd normally open an issue first — happy to do that, or to close this if the dependency direction doesn't fit the SDK's plans.
🤖 Generated with Claude Code