@@ -12,7 +12,10 @@ export interface GlobalOptions {
1212 rpc : boolean ;
1313}
1414
15+ type TransportType = "http" | "stdio" ;
16+
1517export interface SharedServerTargetOptions {
18+ transport ?: TransportType ;
1619 url ?: string ;
1720 accessToken ?: string ;
1821 oauthAccessToken ?: string ;
@@ -22,8 +25,10 @@ export interface SharedServerTargetOptions {
2225 header ?: string [ ] ;
2326 clientCapabilities ?: string | Record < string , unknown > ;
2427 command ?: string ;
28+ args ?: string [ ] ;
2529 commandArgs ?: string [ ] ;
2630 env ?: string [ ] ;
31+ cwd ?: string ;
2732 timeout ?: number ;
2833}
2934
@@ -33,6 +38,10 @@ function collectString(value: string, previous: string[] = []): string[] {
3338
3439export function addSharedServerOptions ( command : Command ) : Command {
3540 return command
41+ . option (
42+ "--transport <transport>" ,
43+ 'Explicit transport type: "http" or "stdio"' ,
44+ )
3645 . option ( "--url <url>" , "HTTP MCP server URL" )
3746 . option ( "--access-token <token>" , "Bearer access token for HTTP servers" )
3847 . option (
@@ -62,16 +71,20 @@ export function addSharedServerOptions(command: Command): Command {
6271 "Client capabilities advertised to the server as a JSON object" ,
6372 )
6473 . option ( "--command <command>" , "Command for a stdio MCP server" )
74+ . option (
75+ "--args <arg...>" ,
76+ "Preferred stdio command arguments. Pass multiple values or repeat the flag." ,
77+ )
6578 . option (
6679 "--command-args <arg>" ,
67- "Stdio command argument. Repeat to pass multiple arguments." ,
80+ "Legacy stdio command argument. Repeat to pass multiple arguments." ,
6881 collectString ,
6982 )
7083 . option (
71- "-- env <env>" ,
72- 'Stdio environment assignment in "KEY=VALUE" format. Repeat to pass multiple assignments .' ,
73- collectString ,
74- ) ;
84+ "-e, -- env <env... >" ,
85+ 'Stdio environment assignment in "KEY=VALUE" format. Pass multiple values or repeat the flag .' ,
86+ )
87+ . option ( "--cwd <path>" , "Working directory for the stdio MCP server process" ) ;
7588}
7689
7790export function getGlobalOptions ( command : Command ) : GlobalOptions {
@@ -204,21 +217,21 @@ export function parseServerConfig(
204217 const command = options . command ?. trim ( ) ;
205218 const hasUrl = Boolean ( url ) ;
206219 const hasCommand = Boolean ( command ) ;
220+ const transport = resolveTargetTransport ( options , hasUrl , hasCommand ) ;
221+ const cwd = options . cwd ?. trim ( ) ;
207222 const clientCapabilities = resolveClientCapabilities (
208223 options . clientCapabilities ,
209224 ) ;
210225
211- if ( hasUrl === hasCommand ) {
212- throw usageError ( "Specify exactly one target: either --url or --command." ) ;
213- }
214-
215- if ( hasUrl && url ) {
226+ if ( transport === "http" && url ) {
216227 if (
228+ ( options . args ?. length ?? 0 ) > 0 ||
217229 ( options . commandArgs ?. length ?? 0 ) > 0 ||
218- ( options . env ?. length ?? 0 ) > 0
230+ ( options . env ?. length ?? 0 ) > 0 ||
231+ cwd
219232 ) {
220233 throw usageError (
221- "--command-args and --env can only be used together with --command." ,
234+ "--args, -- command-args, --env, and --cwd can only be used together with --command." ,
222235 ) ;
223236 }
224237
@@ -281,10 +294,11 @@ export function parseServerConfig(
281294
282295 return {
283296 command,
284- args : parseCommandArgs ( options . commandArgs ) ,
297+ args : parseCommandArgs ( options . args , options . commandArgs ) ,
285298 env : parseEnvironmentOption ( options . env ) ,
299+ ...( cwd ? { cwd } : { } ) ,
286300 ...( clientCapabilities ? { clientCapabilities } : { } ) ,
287- stderr : "ignore " ,
301+ stderr : "pipe " ,
288302 timeout : options . timeout ,
289303 } ;
290304}
@@ -325,12 +339,17 @@ function parseHeader(entry: string): [string, string] {
325339 return [ key , value ] ;
326340}
327341
328- function parseCommandArgs ( values : string [ ] | undefined ) : string [ ] | undefined {
329- if ( ! values || values . length === 0 ) {
342+ function parseCommandArgs (
343+ values : string [ ] | undefined ,
344+ legacyValues : string [ ] | undefined ,
345+ ) : string [ ] | undefined {
346+ const combined = [ ...( values ?? [ ] ) , ...( legacyValues ?? [ ] ) ] ;
347+
348+ if ( combined . length === 0 ) {
330349 return undefined ;
331350 }
332351
333- return values ;
352+ return combined ;
334353}
335354
336355function parseEnvironmentOption (
@@ -377,6 +396,58 @@ function resolveClientCapabilities(
377396 return parseUnknownRecord ( value , "Client capabilities" ) ;
378397}
379398
399+ function resolveTargetTransport (
400+ options : SharedServerTargetOptions ,
401+ hasUrl : boolean ,
402+ hasCommand : boolean ,
403+ ) : TransportType {
404+ const transport = resolveTransportOption ( options . transport ) ;
405+
406+ if ( ! transport ) {
407+ if ( hasUrl === hasCommand ) {
408+ throw usageError ( "Specify exactly one target: either --url or --command." ) ;
409+ }
410+
411+ return hasUrl ? "http" : "stdio" ;
412+ }
413+
414+ if ( transport === "http" ) {
415+ if ( ! hasUrl ) {
416+ throw usageError ( "--transport http requires --url." ) ;
417+ }
418+ if ( hasCommand ) {
419+ throw usageError ( "--command can only be used with --transport stdio." ) ;
420+ }
421+
422+ return transport ;
423+ }
424+
425+ if ( ! hasCommand ) {
426+ throw usageError ( "--transport stdio requires --command." ) ;
427+ }
428+ if ( hasUrl ) {
429+ throw usageError ( "--url can only be used with --transport http." ) ;
430+ }
431+
432+ return transport ;
433+ }
434+
435+ function resolveTransportOption (
436+ value : string | undefined ,
437+ ) : TransportType | undefined {
438+ if ( value === undefined ) {
439+ return undefined ;
440+ }
441+
442+ if ( value === "http" || value === "stdio" ) {
443+ return value ;
444+ }
445+
446+ throw usageError (
447+ `Invalid transport "${ value } ". Use "http" or "stdio".` ,
448+ ) ;
449+ }
450+
380451export function resolveHttpAccessToken (
381452 options : Pick < SharedServerTargetOptions , "accessToken" | "oauthAccessToken" > ,
382453) : string | undefined {
0 commit comments