Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 16 additions & 3 deletions ts-packages/quarto-hub-mcp/src/mcp-test-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,11 @@ export class McpTestClient {
* at dist/index.js) — used by bundle tests to drive the esbuild
* artifact from outside the repo tree. `command` (+ leading args)
* replaces `node` entirely — used by the auth e2e to drive the real
* `q2 mcp` launcher. `env` REPLACES the child environment when
* given (callers spread process.env themselves if they want it).
* `q2 mcp` launcher. `env` REPLACES the child environment when given
* (callers spread process.env themselves if they want it); when omitted
* the child inherits process.env minus the auth-gating vars
* (QUARTO_HUB_MCP_CLIENT_ID/SECRET) so the server runs unauthenticated
* regardless of the developer's shell (bd-uyiqciqk).
*/
async start(
args: string[],
Expand All @@ -55,9 +58,19 @@ export class McpTestClient {
const [program, leading] = opts?.command
? [opts.command.program, opts.command.args]
: ['node', [opts?.entry ?? SERVER_ENTRY]];
// Don't let the developer's real auth config leak into the spawned
// server: with QUARTO_HUB_MCP_CLIENT_ID/SECRET set it takes the OS-keychain
// credential path, which fails nondeterministically against a populated
// keychain. Strip them from the inherited env unless a test passes its own.
let env = opts?.env;
if (!env) {
env = { ...process.env };
delete env['QUARTO_HUB_MCP_CLIENT_ID'];
delete env['QUARTO_HUB_MCP_CLIENT_SECRET'];
}
this.proc = spawn(program, [...leading, ...args], {
stdio: ['pipe', 'pipe', 'pipe'],
...(opts?.env ? { env: opts.env } : {}),
env,
});

this.proc.stdout!.setEncoding('utf-8');
Expand Down
Loading