11import { Client } from "@modelcontextprotocol/sdk/client/index.js" ;
2+ import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js" ;
3+ import { fileURLToPath } from "url" ;
4+
25import {
36 SSEClientTransport ,
47 SseError ,
58} from "@modelcontextprotocol/sdk/client/sse.js" ;
69import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js" ;
710import { StreamableHTTPClientTransport } from "@modelcontextprotocol/sdk/client/streamableHttp.js" ;
811import { WebSocketClientTransport } from "@modelcontextprotocol/sdk/client/websocket.js" ;
9- import { Transport } from "@modelcontextprotocol/sdk/shared/transport.js" ;
1012import { Agent as HttpsAgent } from "https" ;
1113import {
1214 IDE ,
@@ -22,6 +24,7 @@ import {
2224 MCPServerStatus ,
2325 MCPTool ,
2426} from "../.." ;
27+ import { resolveRelativePathInDir } from "../../util/ideUtils" ;
2528import { getEnvPathFromUserShell } from "../../util/shellPath" ;
2629import { getOauthToken } from "./MCPOauth" ;
2730
@@ -38,6 +41,8 @@ const WINDOWS_BATCH_COMMANDS = [
3841 "bunx" ,
3942] ;
4043
44+ const COMMONS_ENV_VARS = [ "HOME" , "USER" , "USERPROFILE" , "LOGNAME" , "USERNAME" ] ;
45+
4146function is401Error ( error : unknown ) {
4247 return (
4348 ( error instanceof SseError && error . code === 401 ) ||
@@ -411,6 +416,44 @@ class MCPConnection {
411416 } ;
412417 }
413418
419+ /**
420+ * Resolves the current working directory of the current workspace.
421+ * @param cwd The cwd parameter provided by user.
422+ * @returns Current working directory (user-provided cwd or workspace root).
423+ */
424+ private async resolveCwd ( cwd ?: string ) {
425+ if ( ! cwd ) {
426+ return this . resolveWorkspaceCwd ( undefined ) ;
427+ }
428+
429+ if ( cwd . startsWith ( "file://" ) ) {
430+ return fileURLToPath ( cwd ) ;
431+ }
432+
433+ // Return cwd if cwd is an absolute path.
434+ if ( cwd . charAt ( 0 ) === "/" ) {
435+ return cwd ;
436+ }
437+
438+ return this . resolveWorkspaceCwd ( cwd ) ;
439+ }
440+
441+ private async resolveWorkspaceCwd ( cwd : string | undefined ) {
442+ const IDE = this . extras ?. ide ;
443+ if ( IDE ) {
444+ const target = cwd ?? "." ;
445+ const resolved = await resolveRelativePathInDir ( target , IDE ) ;
446+ if ( resolved ) {
447+ if ( resolved . startsWith ( "file://" ) ) {
448+ return fileURLToPath ( resolved ) ;
449+ }
450+ return resolved ;
451+ }
452+ return resolved ;
453+ }
454+ return cwd ;
455+ }
456+
414457 private constructWebsocketTransport (
415458 options : InternalWebsocketMcpOptions ,
416459 ) : WebSocketClientTransport {
@@ -464,7 +507,16 @@ class MCPConnection {
464507 private async constructStdioTransport (
465508 options : InternalStdioMcpOptions ,
466509 ) : Promise < StdioClientTransport > {
467- const env : Record < string , string > = options . env ? { ...options . env } : { } ;
510+ const commonEnvVars : Record < string , string > = Object . fromEntries (
511+ COMMONS_ENV_VARS . filter ( ( key ) => process . env [ key ] !== undefined ) . map (
512+ ( key ) => [ key , process . env [ key ] as string ] ,
513+ ) ,
514+ ) ;
515+
516+ const env = {
517+ ...commonEnvVars ,
518+ ...( options . env ?? { } ) ,
519+ } ;
468520
469521 if ( process . env . PATH !== undefined ) {
470522 // Set the initial PATH from process.env
@@ -488,11 +540,13 @@ class MCPConnection {
488540 options . args || [ ] ,
489541 ) ;
490542
543+ const cwd = await this . resolveCwd ( options . cwd ) ;
544+
491545 const transport = new StdioClientTransport ( {
492546 command,
493547 args,
494548 env,
495- cwd : options . cwd ,
549+ cwd,
496550 stderr : "pipe" ,
497551 } ) ;
498552
0 commit comments