@@ -45,8 +45,11 @@ export class McpTestClient {
4545 * at dist/index.js) — used by bundle tests to drive the esbuild
4646 * artifact from outside the repo tree. `command` (+ leading args)
4747 * replaces `node` entirely — used by the auth e2e to drive the real
48- * `q2 mcp` launcher. `env` REPLACES the child environment when
49- * given (callers spread process.env themselves if they want it).
48+ * `q2 mcp` launcher. `env` REPLACES the child environment when given
49+ * (callers spread process.env themselves if they want it); when omitted
50+ * the child inherits process.env minus the auth-gating vars
51+ * (QUARTO_HUB_MCP_CLIENT_ID/SECRET) so the server runs unauthenticated
52+ * regardless of the developer's shell (bd-uyiqciqk).
5053 */
5154 async start (
5255 args : string [ ] ,
@@ -55,9 +58,19 @@ export class McpTestClient {
5558 const [ program , leading ] = opts ?. command
5659 ? [ opts . command . program , opts . command . args ]
5760 : [ 'node' , [ opts ?. entry ?? SERVER_ENTRY ] ] ;
61+ // Don't let the developer's real auth config leak into the spawned
62+ // server: with QUARTO_HUB_MCP_CLIENT_ID/SECRET set it takes the OS-keychain
63+ // credential path, which fails nondeterministically against a populated
64+ // keychain. Strip them from the inherited env unless a test passes its own.
65+ let env = opts ?. env ;
66+ if ( ! env ) {
67+ env = { ...process . env } ;
68+ delete env [ 'QUARTO_HUB_MCP_CLIENT_ID' ] ;
69+ delete env [ 'QUARTO_HUB_MCP_CLIENT_SECRET' ] ;
70+ }
5871 this . proc = spawn ( program , [ ...leading , ...args ] , {
5972 stdio : [ 'pipe' , 'pipe' , 'pipe' ] ,
60- ... ( opts ?. env ? { env : opts . env } : { } ) ,
73+ env,
6174 } ) ;
6275
6376 this . proc . stdout ! . setEncoding ( 'utf-8' ) ;
0 commit comments