Skip to content
Merged
Show file tree
Hide file tree
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
52 changes: 26 additions & 26 deletions internal/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,30 +27,30 @@ const (
// DefaultListenIPv4 is the default interface used by the HTTP server.
DefaultListenIPv4 = "127.0.0.1"
// DefaultListenPort is the default port used by the HTTP server.
DefaultListenPort = "3000"
defaultListenAddr = DefaultListenIPv4 + ":" + DefaultListenPort
defaultRoutedMode = false
defaultUnifiedMode = false
defaultEnvFile = ""
defaultEnableDIFC = false
defaultLogDir = "/tmp/gh-aw/mcp-logs"
defaultParallelLaunch = true
DefaultListenPort = "3000"
defaultListenAddr = DefaultListenIPv4 + ":" + DefaultListenPort
defaultRoutedMode = false
defaultUnifiedMode = false
defaultEnvFile = ""
defaultEnableDIFC = false
defaultLogDir = "/tmp/gh-aw/mcp-logs"
defaultSequentialLaunch = false
)

var (
configFile string
configStdin bool
listenAddr string
routedMode bool
unifiedMode bool
envFile string
enableDIFC bool
logDir string
validateEnv bool
parallelLaunch bool
verbosity int // Verbosity level: 0 (default), 1 (-v info), 2 (-vv debug), 3 (-vvv trace)
debugLog = logger.New("cmd:root")
version = "dev" // Default version, overridden by SetVersion
configFile string
configStdin bool
listenAddr string
routedMode bool
unifiedMode bool
envFile string
enableDIFC bool
logDir string
validateEnv bool
sequentialLaunch bool
verbosity int // Verbosity level: 0 (default), 1 (-v info), 2 (-vv debug), 3 (-vvv trace)
debugLog = logger.New("cmd:root")
version = "dev" // Default version, overridden by SetVersion
)

var rootCmd = &cobra.Command{
Expand All @@ -77,7 +77,7 @@ func init() {
rootCmd.Flags().BoolVar(&enableDIFC, "enable-difc", defaultEnableDIFC, "Enable DIFC enforcement and session requirement (requires sys___init call before tool access)")
rootCmd.Flags().StringVar(&logDir, "log-dir", getDefaultLogDir(), "Directory for log files (falls back to stdout if directory cannot be created)")
rootCmd.Flags().BoolVar(&validateEnv, "validate-env", false, "Validate execution environment (Docker, env vars) before starting")
rootCmd.Flags().BoolVar(&parallelLaunch, "parallel-launch", defaultParallelLaunch, "Launch MCP servers in parallel during startup (enabled by default)")
rootCmd.Flags().BoolVar(&sequentialLaunch, "sequential-launch", defaultSequentialLaunch, "Launch MCP servers sequentially during startup (parallel launch is default)")
rootCmd.Flags().CountVarP(&verbosity, "verbose", "v", "Increase verbosity level (use -v for info, -vv for debug, -vvv for trace)")

// Mark mutually exclusive flags
Expand Down Expand Up @@ -241,17 +241,17 @@ func run(cmd *cobra.Command, args []string) error {

// Apply command-line flags to config
cfg.EnableDIFC = enableDIFC
cfg.ParallelLaunch = parallelLaunch
cfg.SequentialLaunch = sequentialLaunch
if enableDIFC {
log.Println("DIFC enforcement and session requirement enabled")
} else {
log.Println("DIFC enforcement disabled (sessions auto-created for standard MCP client compatibility)")
}

if parallelLaunch {
log.Println("Parallel server launching enabled")
} else {
if sequentialLaunch {
log.Println("Sequential server launching enabled")
} else {
log.Println("Parallel server launching enabled (default)")
}

// Determine mode (default to unified if neither flag is set)
Expand Down
8 changes: 4 additions & 4 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ const (

// Config represents the MCPG configuration
type Config struct {
Servers map[string]*ServerConfig `toml:"servers"`
EnableDIFC bool `toml:"enable_difc"` // When true, enables DIFC enforcement and requires sys___init call before tool access. Default is false for standard MCP client compatibility.
ParallelLaunch bool `toml:"parallel_launch"` // When true (default), launches MCP servers in parallel during startup.
Gateway *GatewayConfig `toml:"gateway"` // Gateway configuration (port, API key, etc.)
Servers map[string]*ServerConfig `toml:"servers"`
EnableDIFC bool `toml:"enable_difc"` // When true, enables DIFC enforcement and requires sys___init call before tool access. Default is false for standard MCP client compatibility.
SequentialLaunch bool `toml:"sequential_launch"` // When true, launches MCP servers sequentially during startup. Default is false (parallel launch).
Gateway *GatewayConfig `toml:"gateway"` // Gateway configuration (port, API key, etc.)
}

// GatewayConfig represents gateway-level configuration
Expand Down
42 changes: 21 additions & 21 deletions internal/server/unified.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ type ToolInfo struct {

// UnifiedServer implements a unified MCP server that aggregates multiple backend servers
type UnifiedServer struct {
launcher *launcher.Launcher
sysServer *sys.SysServer
ctx context.Context
server *sdk.Server
sessions map[string]*Session // mcp-session-id -> Session
sessionMu sync.RWMutex
tools map[string]*ToolInfo // prefixed tool name -> tool info
toolsMu sync.RWMutex
parallelLaunch bool // When true (default), launches MCP servers in parallel during startup
launcher *launcher.Launcher
sysServer *sys.SysServer
ctx context.Context
server *sdk.Server
sessions map[string]*Session // mcp-session-id -> Session
sessionMu sync.RWMutex
tools map[string]*ToolInfo // prefixed tool name -> tool info
toolsMu sync.RWMutex
sequentialLaunch bool // When true, launches MCP servers sequentially during startup. Default is false (parallel launch).

// DIFC components
guardRegistry *guard.Registry
Expand All @@ -102,16 +102,16 @@ type UnifiedServer struct {

// NewUnified creates a new unified MCP server
func NewUnified(ctx context.Context, cfg *config.Config) (*UnifiedServer, error) {
logUnified.Printf("Creating new unified server: enableDIFC=%v, parallelLaunch=%v, servers=%d", cfg.EnableDIFC, cfg.ParallelLaunch, len(cfg.Servers))
logUnified.Printf("Creating new unified server: enableDIFC=%v, sequentialLaunch=%v, servers=%d", cfg.EnableDIFC, cfg.SequentialLaunch, len(cfg.Servers))
l := launcher.New(ctx, cfg)

us := &UnifiedServer{
launcher: l,
sysServer: sys.NewSysServer(l.ServerIDs()),
ctx: ctx,
sessions: make(map[string]*Session),
tools: make(map[string]*ToolInfo),
parallelLaunch: cfg.ParallelLaunch,
launcher: l,
sysServer: sys.NewSysServer(l.ServerIDs()),
ctx: ctx,
sessions: make(map[string]*Session),
tools: make(map[string]*ToolInfo),
sequentialLaunch: cfg.SequentialLaunch,

// Initialize DIFC components
guardRegistry: guard.NewRegistry(),
Expand Down Expand Up @@ -168,12 +168,12 @@ func (us *UnifiedServer) registerAllTools() error {

serverIDs := us.launcher.ServerIDs()

if us.parallelLaunch {
// Launch servers in parallel
return us.registerAllToolsParallel(serverIDs)
} else {
// Launch servers sequentially (original behavior)
if us.sequentialLaunch {
// Launch servers sequentially
return us.registerAllToolsSequential(serverIDs)
} else {
// Launch servers in parallel (default behavior)
return us.registerAllToolsParallel(serverIDs)
}
}

Expand Down
16 changes: 8 additions & 8 deletions internal/server/unified_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,30 +493,30 @@ func TestRequireSession_EdgeCases(t *testing.T) {
}
}

func TestUnifiedServer_ParallelLaunch_Enabled(t *testing.T) {
func TestUnifiedServer_SequentialLaunch_Enabled(t *testing.T) {
cfg := &config.Config{
Servers: map[string]*config.ServerConfig{},
ParallelLaunch: true,
Servers: map[string]*config.ServerConfig{},
SequentialLaunch: true,
}

ctx := context.Background()
us, err := NewUnified(ctx, cfg)
require.NoError(t, err, "NewUnified() failed")
defer us.Close()

assert.True(t, us.parallelLaunch, "ParallelLaunch should be enabled when configured")
assert.True(t, us.sequentialLaunch, "SequentialLaunch should be enabled when configured")
}

func TestUnifiedServer_ParallelLaunch_Disabled(t *testing.T) {
func TestUnifiedServer_SequentialLaunch_Disabled(t *testing.T) {
cfg := &config.Config{
Servers: map[string]*config.ServerConfig{},
ParallelLaunch: false,
Servers: map[string]*config.ServerConfig{},
SequentialLaunch: false,
}

ctx := context.Background()
us, err := NewUnified(ctx, cfg)
require.NoError(t, err, "NewUnified() failed")
defer us.Close()

assert.False(t, us.parallelLaunch, "ParallelLaunch should be disabled when configured")
assert.False(t, us.sequentialLaunch, "SequentialLaunch should be disabled (parallel launch is default) when configured")
}