@@ -609,6 +609,218 @@ describe('setup-ai-agents generator', () => {
609609 } ) ;
610610 } ) ;
611611
612+ describe ( 'MCP config extra args preservation' , ( ) => {
613+ it ( 'should preserve extra args in gemini MCP config' , async ( ) => {
614+ const options : SetupAiAgentsGeneratorSchema = {
615+ directory : '.' ,
616+ agents : [ 'gemini' ] ,
617+ } ;
618+
619+ tree . write (
620+ '.gemini/settings.json' ,
621+ JSON . stringify ( {
622+ mcpServers : {
623+ 'nx-mcp' : {
624+ type : 'stdio' ,
625+ command : 'npx' ,
626+ args : [ 'nx' , 'mcp' , '--transport' , 'http' ] ,
627+ } ,
628+ } ,
629+ } )
630+ ) ;
631+
632+ await setupAiAgentsGenerator ( tree , options ) ;
633+
634+ const config = JSON . parse (
635+ tree . read ( '.gemini/settings.json' ) ?. toString ( ) ?? '{}'
636+ ) ;
637+ expect ( config . mcpServers [ 'nx-mcp' ] . args ) . toEqual ( [
638+ 'nx' ,
639+ 'mcp' ,
640+ '--transport' ,
641+ 'http' ,
642+ ] ) ;
643+ } ) ;
644+
645+ it ( 'should preserve multiple extra args in gemini MCP config' , async ( ) => {
646+ const options : SetupAiAgentsGeneratorSchema = {
647+ directory : '.' ,
648+ agents : [ 'gemini' ] ,
649+ } ;
650+
651+ tree . write (
652+ '.gemini/settings.json' ,
653+ JSON . stringify ( {
654+ mcpServers : {
655+ 'nx-mcp' : {
656+ type : 'stdio' ,
657+ command : 'npx' ,
658+ args : [
659+ 'nx' ,
660+ 'mcp' ,
661+ '--experimental-polygraph' ,
662+ '--transport' ,
663+ 'http' ,
664+ ] ,
665+ } ,
666+ } ,
667+ } )
668+ ) ;
669+
670+ await setupAiAgentsGenerator ( tree , options ) ;
671+
672+ const config = JSON . parse (
673+ tree . read ( '.gemini/settings.json' ) ?. toString ( ) ?? '{}'
674+ ) ;
675+ expect ( config . mcpServers [ 'nx-mcp' ] . args ) . toEqual ( [
676+ 'nx' ,
677+ 'mcp' ,
678+ '--experimental-polygraph' ,
679+ '--transport' ,
680+ 'http' ,
681+ ] ) ;
682+ } ) ;
683+
684+ it ( 'should preserve extra args when upgrading from Nx 21 to 22 (gemini)' , async ( ) => {
685+ readModulePackageJsonSpy . mockReturnValue ( {
686+ packageJson : { name : 'nx' , version : '22.0.0' } ,
687+ path : '/fake/path/package.json' ,
688+ } ) ;
689+
690+ const options : SetupAiAgentsGeneratorSchema = {
691+ directory : '.' ,
692+ agents : [ 'gemini' ] ,
693+ } ;
694+
695+ // Simulate old Nx 21 config with extra args
696+ tree . write (
697+ '.gemini/settings.json' ,
698+ JSON . stringify ( {
699+ mcpServers : {
700+ 'nx-mcp' : {
701+ type : 'stdio' ,
702+ command : 'npx' ,
703+ args : [ 'nx-mcp' , '--minimal' , '--transport' , 'http' ] ,
704+ } ,
705+ } ,
706+ } )
707+ ) ;
708+
709+ await setupAiAgentsGenerator ( tree , options ) ;
710+
711+ const config = JSON . parse (
712+ tree . read ( '.gemini/settings.json' ) ?. toString ( ) ?? '{}'
713+ ) ;
714+ // Should update base args to v22 format but preserve extras
715+ expect ( config . mcpServers [ 'nx-mcp' ] . args ) . toEqual ( [
716+ 'nx' ,
717+ 'mcp' ,
718+ '--minimal' ,
719+ '--transport' ,
720+ 'http' ,
721+ ] ) ;
722+ } ) ;
723+
724+ it ( 'should preserve extra args from versioned nx-mcp base command (gemini)' , async ( ) => {
725+ const options : SetupAiAgentsGeneratorSchema = {
726+ directory : '.' ,
727+ agents : [ 'gemini' ] ,
728+ } ;
729+
730+ tree . write (
731+ '.gemini/settings.json' ,
732+ JSON . stringify ( {
733+ mcpServers : {
734+ 'nx-mcp' : {
735+ type : 'stdio' ,
736+ command : 'npx' ,
737+ args : [ 'nx-mcp@latest' , '--experimental-polygraph' ] ,
738+ } ,
739+ } ,
740+ } )
741+ ) ;
742+
743+ await setupAiAgentsGenerator ( tree , options ) ;
744+
745+ const config = JSON . parse (
746+ tree . read ( '.gemini/settings.json' ) ?. toString ( ) ?? '{}'
747+ ) ;
748+ expect ( config . mcpServers [ 'nx-mcp' ] . args ) . toEqual ( [
749+ 'nx' ,
750+ 'mcp' ,
751+ '--experimental-polygraph' ,
752+ ] ) ;
753+ } ) ;
754+
755+ it ( 'should preserve extra args in opencode MCP command' , async ( ) => {
756+ const options : SetupAiAgentsGeneratorSchema = {
757+ directory : '.' ,
758+ agents : [ 'opencode' ] ,
759+ } ;
760+
761+ tree . write (
762+ 'opencode.json' ,
763+ JSON . stringify ( {
764+ mcp : {
765+ 'nx-mcp' : {
766+ type : 'local' ,
767+ command : [
768+ 'npx' ,
769+ 'nx' ,
770+ 'mcp' ,
771+ '--experimental-polygraph' ,
772+ '--transport' ,
773+ 'http' ,
774+ ] ,
775+ enabled : true ,
776+ } ,
777+ } ,
778+ } )
779+ ) ;
780+
781+ await setupAiAgentsGenerator ( tree , options ) ;
782+
783+ const config = JSON . parse (
784+ tree . read ( 'opencode.json' ) ?. toString ( ) ?? '{}'
785+ ) ;
786+ expect ( config . mcp [ 'nx-mcp' ] . command ) . toEqual ( [
787+ 'npx' ,
788+ 'nx' ,
789+ 'mcp' ,
790+ '--experimental-polygraph' ,
791+ '--transport' ,
792+ 'http' ,
793+ ] ) ;
794+ } ) ;
795+
796+ it ( 'should not add extra args when none exist in existing config' , async ( ) => {
797+ const options : SetupAiAgentsGeneratorSchema = {
798+ directory : '.' ,
799+ agents : [ 'gemini' ] ,
800+ } ;
801+
802+ tree . write (
803+ '.gemini/settings.json' ,
804+ JSON . stringify ( {
805+ mcpServers : {
806+ 'nx-mcp' : {
807+ type : 'stdio' ,
808+ command : 'npx' ,
809+ args : [ 'nx' , 'mcp' ] ,
810+ } ,
811+ } ,
812+ } )
813+ ) ;
814+
815+ await setupAiAgentsGenerator ( tree , options ) ;
816+
817+ const config = JSON . parse (
818+ tree . read ( '.gemini/settings.json' ) ?. toString ( ) ?? '{}'
819+ ) ;
820+ expect ( config . mcpServers [ 'nx-mcp' ] . args ) . toEqual ( [ 'nx' , 'mcp' ] ) ;
821+ } ) ;
822+ } ) ;
823+
612824 describe ( 'Nx version-specific MCP configuration' , ( ) => {
613825 it ( 'should use "nx mcp" for Nx 22+ (gemini)' , async ( ) => {
614826 readModulePackageJsonSpy . mockReturnValue ( {
0 commit comments