@@ -62,9 +62,10 @@ type MCPServerOptions struct {
6262
6363func NewMCPServerOptions (streams genericiooptions.IOStreams ) * MCPServerOptions {
6464 return & MCPServerOptions {
65- IOStreams : streams ,
66- Profile : "full" ,
67- ListOutput : "table" ,
65+ IOStreams : streams ,
66+ Profile : "full" ,
67+ ListOutput : "table" ,
68+ StaticConfig : & config.StaticConfig {},
6869 }
6970}
7071
@@ -76,7 +77,7 @@ func NewMCPServer(streams genericiooptions.IOStreams) *cobra.Command {
7677 Long : long ,
7778 Example : examples ,
7879 RunE : func (c * cobra.Command , args []string ) error {
79- if err := o .Complete (); err != nil {
80+ if err := o .Complete (c ); err != nil {
8081 return err
8182 }
8283 if err := o .Validate (); err != nil {
@@ -98,16 +99,14 @@ func NewMCPServer(streams genericiooptions.IOStreams) *cobra.Command {
9899 cmd .Flags ().StringVar (& o .SSEBaseUrl , "sse-base-url" , o .SSEBaseUrl , "SSE public base URL to use when sending the endpoint message (e.g. https://example.com)" )
99100 cmd .Flags ().StringVar (& o .Kubeconfig , "kubeconfig" , o .Kubeconfig , "Path to the kubeconfig file to use for authentication" )
100101 cmd .Flags ().StringVar (& o .Profile , "profile" , o .Profile , "MCP profile to use (one of: " + strings .Join (mcp .ProfileNames , ", " )+ ")" )
101- cmd .Flags ().StringVar (& o .ListOutput , "list-output" , o .ListOutput , "Output format for resource list operations (one of: " + strings .Join (output .Names , ", " )+ ")" )
102+ cmd .Flags ().StringVar (& o .ListOutput , "list-output" , o .ListOutput , "Output format for resource list operations (one of: " + strings .Join (output .Names , ", " )+ "). Defaults to table. " )
102103 cmd .Flags ().BoolVar (& o .ReadOnly , "read-only" , o .ReadOnly , "If true, only tools annotated with readOnlyHint=true are exposed" )
103104 cmd .Flags ().BoolVar (& o .DisableDestructive , "disable-destructive" , o .DisableDestructive , "If true, tools annotated with destructiveHint=true are disabled" )
104105
105106 return cmd
106107}
107108
108- func (m * MCPServerOptions ) Complete () error {
109- m .initializeLogging ()
110-
109+ func (m * MCPServerOptions ) Complete (cmd * cobra.Command ) error {
111110 if m .ConfigPath != "" {
112111 cnf , err := config .ReadConfig (m .ConfigPath )
113112 if err != nil {
@@ -116,16 +115,47 @@ func (m *MCPServerOptions) Complete() error {
116115 m .StaticConfig = cnf
117116 }
118117
118+ m .loadFlags (cmd )
119+
120+ m .initializeLogging ()
121+
119122 return nil
120123}
121124
125+ func (m * MCPServerOptions ) loadFlags (cmd * cobra.Command ) {
126+ if cmd .Flag ("log-level" ).Changed {
127+ m .StaticConfig .LogLevel = m .LogLevel
128+ }
129+ if cmd .Flag ("sse-port" ).Changed {
130+ m .StaticConfig .SSEPort = m .SSEPort
131+ }
132+ if cmd .Flag ("http-port" ).Changed {
133+ m .StaticConfig .HTTPPort = m .HttpPort
134+ }
135+ if cmd .Flag ("sse-base-url" ).Changed {
136+ m .StaticConfig .SSEBaseURL = m .SSEBaseUrl
137+ }
138+ if cmd .Flag ("kubeconfig" ).Changed {
139+ m .StaticConfig .KubeConfig = m .Kubeconfig
140+ }
141+ if cmd .Flag ("list-output" ).Changed || m .StaticConfig .ListOutput == "" {
142+ m .StaticConfig .ListOutput = m .ListOutput
143+ }
144+ if cmd .Flag ("read-only" ).Changed {
145+ m .StaticConfig .ReadOnly = m .ReadOnly
146+ }
147+ if cmd .Flag ("disable-destructive" ).Changed {
148+ m .StaticConfig .DisableDestructive = m .DisableDestructive
149+ }
150+ }
151+
122152func (m * MCPServerOptions ) initializeLogging () {
123153 flagSet := flag .NewFlagSet ("klog" , flag .ContinueOnError )
124154 klog .InitFlags (flagSet )
125155 loggerOptions := []textlogger.ConfigOption {textlogger .Output (m .Out )}
126- if m .LogLevel >= 0 {
127- loggerOptions = append (loggerOptions , textlogger .Verbosity (m .LogLevel ))
128- _ = flagSet .Parse ([]string {"--v" , strconv .Itoa (m .LogLevel )})
156+ if m .StaticConfig . LogLevel >= 0 {
157+ loggerOptions = append (loggerOptions , textlogger .Verbosity (m .StaticConfig . LogLevel ))
158+ _ = flagSet .Parse ([]string {"--v" , strconv .Itoa (m .StaticConfig . LogLevel )})
129159 }
130160 logger := textlogger .NewLogger (textlogger .NewConfig (loggerOptions ... ))
131161 klog .SetLoggerWithOptions (logger )
@@ -140,16 +170,16 @@ func (m *MCPServerOptions) Run() error {
140170 if profile == nil {
141171 return fmt .Errorf ("Invalid profile name: %s, valid names are: %s\n " , m .Profile , strings .Join (mcp .ProfileNames , ", " ))
142172 }
143- listOutput := output .FromString (m .ListOutput )
173+ listOutput := output .FromString (m .StaticConfig . ListOutput )
144174 if listOutput == nil {
145- return fmt .Errorf ("Invalid output name: %s, valid names are: %s\n " , m .ListOutput , strings .Join (output .Names , ", " ))
175+ return fmt .Errorf ("Invalid output name: %s, valid names are: %s\n " , m .StaticConfig . ListOutput , strings .Join (output .Names , ", " ))
146176 }
147177 klog .V (1 ).Info ("Starting kubernetes-mcp-server" )
148178 klog .V (1 ).Infof (" - Config: %s" , m .ConfigPath )
149179 klog .V (1 ).Infof (" - Profile: %s" , profile .GetName ())
150180 klog .V (1 ).Infof (" - ListOutput: %s" , listOutput .GetName ())
151- klog .V (1 ).Infof (" - Read-only mode: %t" , m .ReadOnly )
152- klog .V (1 ).Infof (" - Disable destructive tools: %t" , m .DisableDestructive )
181+ klog .V (1 ).Infof (" - Read-only mode: %t" , m .StaticConfig . ReadOnly )
182+ klog .V (1 ).Infof (" - Disable destructive tools: %t" , m .StaticConfig . DisableDestructive )
153183
154184 if m .Version {
155185 _ , _ = fmt .Fprintf (m .Out , "%s\n " , version .Version )
@@ -158,9 +188,9 @@ func (m *MCPServerOptions) Run() error {
158188 mcpServer , err := mcp .NewServer (mcp.Configuration {
159189 Profile : profile ,
160190 ListOutput : listOutput ,
161- ReadOnly : m .ReadOnly ,
162- DisableDestructive : m .DisableDestructive ,
163- Kubeconfig : m .Kubeconfig ,
191+ ReadOnly : m .StaticConfig . ReadOnly ,
192+ DisableDestructive : m .StaticConfig . DisableDestructive ,
193+ Kubeconfig : m .StaticConfig . KubeConfig ,
164194 StaticConfig : m .StaticConfig ,
165195 })
166196 if err != nil {
@@ -170,19 +200,19 @@ func (m *MCPServerOptions) Run() error {
170200
171201 ctx := context .Background ()
172202
173- if m .SSEPort > 0 {
174- sseServer := mcpServer .ServeSse (m .SSEBaseUrl )
203+ if m .StaticConfig . SSEPort > 0 {
204+ sseServer := mcpServer .ServeSse (m .StaticConfig . SSEBaseURL )
175205 defer func () { _ = sseServer .Shutdown (ctx ) }()
176- klog .V (0 ).Infof ("SSE server starting on port %d and path /sse" , m .SSEPort )
177- if err := sseServer .Start (fmt .Sprintf (":%d" , m .SSEPort )); err != nil {
206+ klog .V (0 ).Infof ("SSE server starting on port %d and path /sse" , m .StaticConfig . SSEPort )
207+ if err := sseServer .Start (fmt .Sprintf (":%d" , m .StaticConfig . SSEPort )); err != nil {
178208 return fmt .Errorf ("failed to start SSE server: %w\n " , err )
179209 }
180210 }
181211
182- if m .HttpPort > 0 {
212+ if m .StaticConfig . HTTPPort > 0 {
183213 httpServer := mcpServer .ServeHTTP ()
184- klog .V (0 ).Infof ("Streaming HTTP server starting on port %d and path /mcp" , m .HttpPort )
185- if err := httpServer .Start (fmt .Sprintf (":%d" , m .HttpPort )); err != nil {
214+ klog .V (0 ).Infof ("Streaming HTTP server starting on port %d and path /mcp" , m .StaticConfig . HTTPPort )
215+ if err := httpServer .Start (fmt .Sprintf (":%d" , m .StaticConfig . HTTPPort )); err != nil {
186216 return fmt .Errorf ("failed to start streaming HTTP server: %w\n " , err )
187217 }
188218 }
0 commit comments