#11361

Expose inheritEnv: false for native MCP stdio server configuration

Openlilyshen0722opened 15d ago

Native MCP stdio servers inherit the full Pi process environment even when their env declaration contains only the variables intended for that server. Please expose inheritEnv: false in McpStdioServerConfig and pass it through createDefaultTransport.

This is an opt-in isolation request, rather than a change to the existing default. The standalone transport already supports it. It would let embedders keep provider keys and per-turn credential-file paths away from unrelated MCP subprocesses without maintaining a separate MCP bridge.

Verified with @earendil-works/pi-mcp 0.99.0 and 1.4.0. In the current source, the config shape has no inheritEnv option, and createDefaultTransport does not forward one. StdioTransport defaults to { ...process.env, ...options.env }.

Reproduction (Node 22.19+, synthetic marker only):

mkdir pi-mcp-env-repro && cd pi-mcp-env-repro
npm init -y
npm install @earendil-works/pi-mcp@1.4.0

Save as repro.mjs, then run node repro.mjs:

import { StdioTransport } from '@earendil-works/pi-mcp';
process.env.PI_MCP_UNDECLARED_MARKER = 'must-not-reach-server';
for (const inheritEnv of [undefined, false]) {
  const transport = new StdioTransport({
    command: process.execPath,
    args: ['-e', `process.stdout.write(JSON.stringify({
      jsonrpc: '2.0', method: 'probe',
      params: { marker: process.env.PI_MCP_UNDECLARED_MARKER ?? null,
                declared: process.env.DECLARED ?? null }
    }) + '\\n'); setInterval(() => {}, 1000)`],
    env: { DECLARED: 'intended-for-server' },
    ...(inheritEnv === undefined ? {} : { inheritEnv }),
  });
  const result = new Promise((resolve, reject) => {
    transport.onMessage(message => resolve(message.params));
    transport.onError(reject);
  });
  try {
    await transport.start();
    console.log(inheritEnv ?? 'default', await result);
  } finally {
    await transport.close();
  }
}

Observed: default includes the undeclared marker; false yields marker: null. Both retain DECLARED. The native CLI currently uses the default path.

Related migration need: a per-spawn credential delivery hook/descriptor would allow a launcher to send a credential to its intended stdio server without putting the value in Pi's environment or persistent mcp.json. This can be a separate follow-up; exposing the existing environment isolation option is the first small step.

Activity

0

No activity yet.