Skip to content

Commit 35e724b

Browse files
committed
Add config
1 parent aff644c commit 35e724b

File tree

7 files changed

+486
-1
lines changed

7 files changed

+486
-1
lines changed

README.md

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,84 @@ make build
1919

2020
Run the server:
2121
```bash
22+
# With configuration file
23+
./stackrox-mcp --config=examples/config-read-only.yaml
24+
25+
# Or using environment variables only
26+
export STACKROX_MCP__CENTRAL__URL=central.stackrox:8443
27+
export STACKROX_MCP__TOOLS__VULNERABILITY__ENABLED=true
2228
./stackrox-mcp
2329
```
2430

31+
## Configuration
32+
33+
The StackRox MCP server supports configuration through both YAML files and environment variables. Environment variables take precedence over YAML configuration.
34+
35+
### Configuration File
36+
37+
Specify a configuration file using the `--config` flag:
38+
39+
```bash
40+
./stackrox-mcp --config=/path/to/config.yaml
41+
```
42+
43+
See [examples/config-read-only.yaml](examples/config-read-only.yaml) for a complete configuration example.
44+
45+
### Environment Variables
46+
47+
All configuration options can be set via environment variables using the naming convention:
48+
49+
```
50+
STACKROX_MCP__SECTION__KEY
51+
```
52+
53+
Note the double underscore (`__`) separator between sections and keys.
54+
55+
#### Examples
56+
57+
```bash
58+
export STACKROX_MCP__CENTRAL__URL=central.stackrox:8443
59+
export STACKROX_MCP__GLOBAL__READ_ONLY_TOOLS=true
60+
export STACKROX_MCP__TOOLS__CONFIG_MANAGER__ENABLED=true
61+
```
62+
63+
### Configuration Options
64+
65+
#### Central Configuration
66+
67+
Configuration for connecting to StackRox Central.
68+
69+
| Option | Environment Variable | Type | Required | Default | Description |
70+
|--------|---------------------|------|----------|---------|-------------|
71+
| `central.url` | `STACKROX_MCP__CENTRAL__URL` | string | Yes | central.stackrox:8443 | URL of StackRox Central instance |
72+
| `central.insecure` | `STACKROX_MCP__CENTRAL__INSECURE` | bool | No | `false` | Skip TLS certificate verification |
73+
| `central.force_http1` | `STACKROX_MCP__CENTRAL__FORCE_HTTP1` | bool | No | `false` | Force HTTP/1.1 instead of HTTP/2 |
74+
75+
#### Global Configuration
76+
77+
Global MCP server settings.
78+
79+
| Option | Environment Variable | Type | Required | Default | Description |
80+
|--------|---------------------|------|----------|---------|-------------|
81+
| `global.read_only_tools` | `STACKROX_MCP__GLOBAL__READ_ONLY_TOOLS` | bool | No | `true` | Only allow read-only tools |
82+
83+
#### Tools Configuration
84+
85+
Enable or disable individual MCP tools. At least one tool has to be enabled.
86+
87+
| Option | Environment Variable | Type | Required | Default | Description |
88+
|--------|---------------------|------|----------|---------|-------------|
89+
| `tools.vulnerability.enabled` | `STACKROX_MCP__TOOLS__VULNERABILITY__ENABLED` | bool | No | `false` | Enable vulnerability management tools |
90+
| `tools.config_manager.enabled` | `STACKROX_MCP__TOOLS__CONFIG_MANAGER__ENABLED` | bool | No | `false` | Enable configuration management tools |
91+
92+
### Configuration Precedence
93+
94+
Configuration values are loaded in the following order (later sources override earlier ones):
95+
96+
1. Default values
97+
2. YAML configuration file (if provided via `--config`)
98+
3. Environment variables (highest precedence)
99+
25100
## Development
26101

27102
### Available Make Targets

cmd/stackrox-mcp/main.go

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,9 @@ package main
33
import (
44
"github.com/rs/zerolog"
55
"github.com/rs/zerolog/log"
6+
flag "github.com/spf13/pflag"
7+
8+
"github.com/stackrox/stackrox-mcp/internal/config"
69
)
710

811
func setupLogging() {
@@ -12,5 +15,14 @@ func setupLogging() {
1215
func main() {
1316
setupLogging()
1417

18+
configPath := flag.String("config", "", "Path to configuration file (optional)")
19+
flag.Parse()
20+
21+
cfg, err := config.LoadConfig(*configPath)
22+
if err != nil {
23+
log.Fatal().Err(err).Msg("Failed to load configuration")
24+
}
25+
log.Info().Interface("config", cfg).Msg("Configuration loaded successfully")
26+
1527
log.Info().Msg("Starting Stackrox MCP server")
1628
}

examples/config-read-only.yaml

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# StackRox MCP Server Configuration
2+
#
3+
# This is an example configuration file for the StackRox MCP server.
4+
# Copy this file and modify it according to your environment.
5+
#
6+
# Environment Variable Mapping:
7+
# All configuration options can be overridden using environment variables.
8+
# Environment variables take precedence over YAML configuration.
9+
#
10+
# Naming convention: STACKROX_MCP__SECTION__KEY
11+
# Example:
12+
# central:
13+
# url: central.stackrox:8443
14+
#
15+
# Can be overridden with:
16+
# STACKROX_MCP__CENTRAL__URL=central.stackrox:8443
17+
18+
# Central connection configuration
19+
central:
20+
# Central URL (required, default: central.stackrox:8443)
21+
# The URL of your StackRox Central instance
22+
url: central.stackrox:8443
23+
24+
# Allow insecure TLS connection (optional, default: false)
25+
# Set to true to skip TLS certificate verification
26+
insecure: false
27+
28+
# Force HTTP1 (optional, default: false)
29+
# Force HTTP/1.1 instead of HTTP/2
30+
force_http1: false
31+
32+
# Global MCP server configuration
33+
global:
34+
# Allow only read-only MCP tools (optional, default: true)
35+
# When true, only tools that perform read operations are available
36+
# When false, both read and write tools may be available (if implemented)
37+
read_only_tools: true
38+
39+
# Configuration of MCP tools
40+
# Each tool has an enable/disable flag. At least one tool has to be enabled.
41+
tools:
42+
# Vulnerability management tools
43+
vulnerability:
44+
# Enable vulnerability management tools (optional, default: false)
45+
enabled: true
46+
47+
# Configuration management tools
48+
config_manager:
49+
# Enable configuration management tools (optional, default: false)
50+
enabled: true

go.mod

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,21 @@ require (
99

1010
require (
1111
github.com/davecgh/go-spew v1.1.1 // indirect
12+
github.com/fsnotify/fsnotify v1.9.0 // indirect
13+
github.com/go-viper/mapstructure/v2 v2.4.0 // indirect
1214
github.com/mattn/go-colorable v0.1.13 // indirect
1315
github.com/mattn/go-isatty v0.0.19 // indirect
16+
github.com/pelletier/go-toml/v2 v2.2.4 // indirect
1417
github.com/pmezard/go-difflib v1.0.0 // indirect
15-
golang.org/x/sys v0.12.0 // indirect
18+
github.com/sagikazarmark/locafero v0.11.0 // indirect
19+
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 // indirect
20+
github.com/spf13/afero v1.15.0 // indirect
21+
github.com/spf13/cast v1.10.0 // indirect
22+
github.com/spf13/pflag v1.0.10 // indirect
23+
github.com/spf13/viper v1.21.0 // indirect
24+
github.com/subosito/gotenv v1.6.0 // indirect
25+
go.yaml.in/yaml/v3 v3.0.4 // indirect
26+
golang.org/x/sys v0.29.0 // indirect
27+
golang.org/x/text v0.28.0 // indirect
1628
gopkg.in/yaml.v3 v3.0.1 // indirect
1729
)

go.sum

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,50 @@
11
github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc=
22
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
33
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+
github.com/fsnotify/fsnotify v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
5+
github.com/fsnotify/fsnotify v1.9.0/go.mod h1:8jBTzvmWwFyi3Pb8djgCCO5IBqzKJ/Jwo8TRcHyHii0=
6+
github.com/go-viper/mapstructure/v2 v2.4.0 h1:EBsztssimR/CONLSZZ04E8qAkxNYq4Qp9LvH92wZUgs=
7+
github.com/go-viper/mapstructure/v2 v2.4.0/go.mod h1:oJDH3BJKyqBA2TXFhDsKDGDTlndYOZ6rGS0BRZIxGhM=
48
github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
59
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
610
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
711
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
812
github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA=
913
github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
14+
github.com/pelletier/go-toml/v2 v2.2.4 h1:mye9XuhQ6gvn5h28+VilKrrPoQVanw5PMw/TB0t5Ec4=
15+
github.com/pelletier/go-toml/v2 v2.2.4/go.mod h1:2gIqNv+qfxSVS7cM2xJQKtLSTLUE9V8t9Stt+h56mCY=
1016
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
1117
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
1218
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
1319
github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg=
1420
github.com/rs/zerolog v1.33.0 h1:1cU2KZkvPxNyfgEmhHAz/1A9Bz+llsdYzklWFzgp0r8=
1521
github.com/rs/zerolog v1.33.0/go.mod h1:/7mN4D5sKwJLZQ2b/znpjC3/GQWY/xaDXUM0kKWRHss=
22+
github.com/sagikazarmark/locafero v0.11.0 h1:1iurJgmM9G3PA/I+wWYIOw/5SyBtxapeHDcg+AAIFXc=
23+
github.com/sagikazarmark/locafero v0.11.0/go.mod h1:nVIGvgyzw595SUSUE6tvCp3YYTeHs15MvlmU87WwIik=
24+
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8 h1:+jumHNA0Wrelhe64i8F6HNlS8pkoyMv5sreGx2Ry5Rw=
25+
github.com/sourcegraph/conc v0.3.1-0.20240121214520-5f936abd7ae8/go.mod h1:3n1Cwaq1E1/1lhQhtRK2ts/ZwZEhjcQeJQ1RuC6Q/8U=
26+
github.com/spf13/afero v1.15.0 h1:b/YBCLWAJdFWJTN9cLhiXXcD7mzKn9Dm86dNnfyQw1I=
27+
github.com/spf13/afero v1.15.0/go.mod h1:NC2ByUVxtQs4b3sIUphxK0NioZnmxgyCrfzeuq8lxMg=
28+
github.com/spf13/cast v1.10.0 h1:h2x0u2shc1QuLHfxi+cTJvs30+ZAHOGRic8uyGTDWxY=
29+
github.com/spf13/cast v1.10.0/go.mod h1:jNfB8QC9IA6ZuY2ZjDp0KtFO2LZZlg4S/7bzP6qqeHo=
30+
github.com/spf13/pflag v1.0.10 h1:4EBh2KAYBwaONj6b2Ye1GiHfwjqyROoF4RwYO+vPwFk=
31+
github.com/spf13/pflag v1.0.10/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg=
32+
github.com/spf13/viper v1.21.0 h1:x5S+0EU27Lbphp4UKm1C+1oQO+rKx36vfCoaVebLFSU=
33+
github.com/spf13/viper v1.21.0/go.mod h1:P0lhsswPGWD/1lZJ9ny3fYnVqxiegrlNrEmgLjbTCAY=
1634
github.com/stretchr/testify v1.11.1 h1:7s2iGBzp5EwR7/aIZr8ao5+dra3wiQyKjjFuvgVKu7U=
1735
github.com/stretchr/testify v1.11.1/go.mod h1:wZwfW3scLgRK+23gO65QZefKpKQRnfz6sD981Nm4B6U=
36+
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
37+
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
38+
go.yaml.in/yaml/v3 v3.0.4 h1:tfq32ie2Jv2UxXFdLJdh3jXuOzWiL1fo0bu/FbuKpbc=
39+
go.yaml.in/yaml/v3 v3.0.4/go.mod h1:DhzuOOF2ATzADvBadXxruRBLzYTpT36CKvDb3+aBEFg=
1840
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
1941
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
2042
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
2143
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
44+
golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU=
45+
golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
46+
golang.org/x/text v0.28.0 h1:rhazDwis8INMIwQ4tpjLDzUhx6RlXqZNPEM0huQojng=
47+
golang.org/x/text v0.28.0/go.mod h1:U8nCwOR8jO/marOQ0QbDiOngZVEBB7MAiitBuMjXiNU=
2248
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
2349
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
2450
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

internal/config/config.go

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
package config
2+
3+
import (
4+
"fmt"
5+
"strings"
6+
7+
"github.com/spf13/viper"
8+
)
9+
10+
// Config represents the complete application configuration
11+
type Config struct {
12+
Central CentralConfig `mapstructure:"central"`
13+
Global GlobalConfig `mapstructure:"global"`
14+
Tools ToolsConfig `mapstructure:"tools"`
15+
}
16+
17+
// CentralConfig contains StackRox Central connection configuration
18+
type CentralConfig struct {
19+
URL string `mapstructure:"url"`
20+
Insecure bool `mapstructure:"insecure"`
21+
ForceHTTP1 bool `mapstructure:"force_http1"`
22+
}
23+
24+
// GlobalConfig contains global MCP server configuration
25+
type GlobalConfig struct {
26+
ReadOnlyTools bool `mapstructure:"read_only_tools"`
27+
}
28+
29+
// ToolsConfig contains configuration for individual MCP tools
30+
type ToolsConfig struct {
31+
Vulnerability VulnerabilityConfig `mapstructure:"vulnerability"`
32+
ConfigManager ConfigManagerConfig `mapstructure:"config_manager"`
33+
}
34+
35+
// VulnerabilityConfig contains configuration for vulnerability management tools
36+
type VulnerabilityConfig struct {
37+
Enabled bool `mapstructure:"enabled"`
38+
}
39+
40+
// ConfigManagerConfig contains configuration for config management tools
41+
type ConfigManagerConfig struct {
42+
Enabled bool `mapstructure:"enabled"`
43+
}
44+
45+
// LoadConfig loads configuration from YAML file and environment variables.
46+
// Environment variables take precedence over YAML configuration.
47+
// Env var naming convention: STACKROX_MCP__SECTION__KEY (double underscore as separator)
48+
// configPath: optional path to YAML configuration file (can be empty)
49+
func LoadConfig(configPath string) (*Config, error) {
50+
v := viper.New()
51+
52+
setDefaults(v)
53+
54+
// Set up environment variable support
55+
// Note: SetEnvPrefix adds a single underscore, so "STACKROX_MCP_" becomes the prefix
56+
// We want double underscores between sections, so we use "__" in the replacer
57+
v.SetEnvPrefix("STACKROX_MCP_")
58+
v.SetEnvKeyReplacer(strings.NewReplacer(".", "__"))
59+
v.AutomaticEnv()
60+
61+
if configPath != "" {
62+
v.SetConfigFile(configPath)
63+
if err := v.ReadInConfig(); err != nil {
64+
return nil, fmt.Errorf("failed to read config file: %w", err)
65+
}
66+
}
67+
68+
var cfg Config
69+
if err := v.Unmarshal(&cfg); err != nil {
70+
return nil, fmt.Errorf("failed to unmarshal config: %w", err)
71+
}
72+
73+
if err := cfg.Validate(); err != nil {
74+
return nil, fmt.Errorf("invalid configuration: %w", err)
75+
}
76+
77+
return &cfg, nil
78+
}
79+
80+
// setDefaults sets default values for configuration
81+
func setDefaults(v *viper.Viper) {
82+
v.SetDefault("central.url", "central.stackrox:8443")
83+
v.SetDefault("central.insecure", false)
84+
v.SetDefault("central.force_http1", false)
85+
86+
v.SetDefault("global.read_only_tools", true)
87+
88+
v.SetDefault("tools.vulnerability.enabled", false)
89+
v.SetDefault("tools.config_manager.enabled", false)
90+
}
91+
92+
// Validate validates the configuration
93+
func (c *Config) Validate() error {
94+
if c.Central.URL == "" {
95+
return fmt.Errorf("central.url is required")
96+
}
97+
98+
if !c.Tools.Vulnerability.Enabled && !c.Tools.ConfigManager.Enabled {
99+
return fmt.Errorf("at least one tool has to be enabled")
100+
}
101+
102+
return nil
103+
}

0 commit comments

Comments
 (0)