edge-connect-mcp/config.go

274 lines
8.3 KiB
Go

package main
import (
"fmt"
"log"
"os"
"strconv"
"strings"
"time"
"github.com/joho/godotenv"
)
type Config struct {
// Edge Connect API Configuration
BaseURL string `json:"base_url"`
AuthType string `json:"auth_type"` // "token", "credentials", or "none"
// Authentication - Token
Token string `json:"token,omitempty"`
// Authentication - Credentials
Username string `json:"username,omitempty"`
Password string `json:"password,omitempty"`
// Default Region
DefaultRegion string `json:"default_region"`
// Retry Configuration
RetryMaxRetries int `json:"retry_max_retries"`
RetryInitialDelay time.Duration `json:"retry_initial_delay"`
RetryMaxDelay time.Duration `json:"retry_max_delay"`
RetryMultiplier float64 `json:"retry_multiplier"`
// Server Mode Configuration
ServerMode string `json:"server_mode"` // "stdio" or "remote"
// Remote Server Configuration
RemoteHost string `json:"remote_host"`
RemotePort int `json:"remote_port"`
RemoteAuthRequired bool `json:"remote_auth_required"`
RemoteAuthTokens []string `json:"remote_auth_tokens,omitempty"`
// Debug
Debug bool `json:"debug"`
// OAuth Configuration
OAuthEnabled bool `json:"oauth_enabled"`
OAuthMode string `json:"oauth_mode"` // "resource_server"
OAuthResourceURI string `json:"oauth_resource_uri"`
OAuthAuthServers []string `json:"oauth_auth_servers"`
OAuthIssuer string `json:"oauth_issuer"`
OAuthJWKSURL string `json:"oauth_jwks_url"`
// Basic Auth Server (for testing)
OAuthAuthServerEnabled bool `json:"oauth_auth_server_enabled"`
OAuthAuthServerPort int `json:"oauth_auth_server_port"`
OAuthClientID string `json:"oauth_client_id"`
OAuthRedirectURI string `json:"oauth_redirect_uri"`
}
func LoadConfig() (*Config, error) {
// Load .env file if it exists (optional)
// Silently ignore if .env doesn't exist - environment variables will be used
if err := godotenv.Load(); err != nil {
// Try .env in current directory first
if err := godotenv.Load(".env"); err != nil {
// Not an error - just means we'll use environment variables only
log.Printf("No .env file found, using environment variables only")
}
} else {
log.Printf("Loaded configuration from .env file")
}
cfg := &Config{
// Default values
DefaultRegion: "EU",
RetryMaxRetries: 3,
RetryInitialDelay: 1 * time.Second,
RetryMaxDelay: 30 * time.Second,
RetryMultiplier: 2.0,
Debug: false,
ServerMode: "stdio",
RemoteHost: "0.0.0.0",
RemotePort: 8080,
RemoteAuthRequired: false,
OAuthEnabled: false,
OAuthMode: "resource_server",
OAuthAuthServerEnabled: false,
OAuthAuthServerPort: 8081,
}
// Load Edge Connect API configuration
if baseURL := os.Getenv("EDGE_CONNECT_BASE_URL"); baseURL != "" {
cfg.BaseURL = baseURL
}
if authType := os.Getenv("EDGE_CONNECT_AUTH_TYPE"); authType != "" {
cfg.AuthType = authType
}
if token := os.Getenv("EDGE_CONNECT_TOKEN"); token != "" {
cfg.Token = token
}
if username := os.Getenv("EDGE_CONNECT_USERNAME"); username != "" {
cfg.Username = username
}
if password := os.Getenv("EDGE_CONNECT_PASSWORD"); password != "" {
cfg.Password = password
}
if region := os.Getenv("EDGE_CONNECT_DEFAULT_REGION"); region != "" {
cfg.DefaultRegion = region
}
if debug := os.Getenv("EDGE_CONNECT_DEBUG"); debug == "true" || debug == "1" {
cfg.Debug = true
}
// Load Server Mode configuration
if serverMode := os.Getenv("MCP_SERVER_MODE"); serverMode != "" {
cfg.ServerMode = serverMode
}
if remoteHost := os.Getenv("MCP_REMOTE_HOST"); remoteHost != "" {
cfg.RemoteHost = remoteHost
}
if remotePortStr := os.Getenv("MCP_REMOTE_PORT"); remotePortStr != "" {
if port, err := strconv.Atoi(remotePortStr); err == nil {
cfg.RemotePort = port
}
}
if authRequired := os.Getenv("MCP_REMOTE_AUTH_REQUIRED"); authRequired == "true" || authRequired == "1" {
cfg.RemoteAuthRequired = true
}
if authTokens := os.Getenv("MCP_REMOTE_AUTH_TOKENS"); authTokens != "" {
// Support comma-separated list of tokens
cfg.RemoteAuthTokens = strings.Split(authTokens, ",")
// Trim whitespace from each token
for i, token := range cfg.RemoteAuthTokens {
cfg.RemoteAuthTokens[i] = strings.TrimSpace(token)
}
}
// Load OAuth configuration
if oauthEnabled := os.Getenv("OAUTH_ENABLED"); oauthEnabled == "true" || oauthEnabled == "1" {
cfg.OAuthEnabled = true
}
if oauthMode := os.Getenv("OAUTH_MODE"); oauthMode != "" {
cfg.OAuthMode = oauthMode
}
if oauthResourceURI := os.Getenv("OAUTH_RESOURCE_URI"); oauthResourceURI != "" {
cfg.OAuthResourceURI = oauthResourceURI
}
if oauthAuthServers := os.Getenv("OAUTH_AUTH_SERVERS"); oauthAuthServers != "" {
// Support comma-separated list of authorization servers
cfg.OAuthAuthServers = strings.Split(oauthAuthServers, ",")
// Trim whitespace from each server
for i, server := range cfg.OAuthAuthServers {
cfg.OAuthAuthServers[i] = strings.TrimSpace(server)
}
}
if oauthIssuer := os.Getenv("OAUTH_ISSUER"); oauthIssuer != "" {
cfg.OAuthIssuer = oauthIssuer
}
if oauthJWKSURL := os.Getenv("OAUTH_JWKS_URL"); oauthJWKSURL != "" {
cfg.OAuthJWKSURL = oauthJWKSURL
}
// Load Basic Auth Server configuration
if authServerEnabled := os.Getenv("OAUTH_AUTH_SERVER_ENABLED"); authServerEnabled == "true" || authServerEnabled == "1" {
cfg.OAuthAuthServerEnabled = true
}
if authServerPortStr := os.Getenv("OAUTH_AUTH_SERVER_PORT"); authServerPortStr != "" {
if port, err := strconv.Atoi(authServerPortStr); err == nil {
cfg.OAuthAuthServerPort = port
}
}
if oauthClientID := os.Getenv("OAUTH_CLIENT_ID"); oauthClientID != "" {
cfg.OAuthClientID = oauthClientID
}
if oauthRedirectURI := os.Getenv("OAUTH_REDIRECT_URI"); oauthRedirectURI != "" {
cfg.OAuthRedirectURI = oauthRedirectURI
}
return cfg, nil
}
func (c *Config) Validate() error {
// Validate Edge Connect API configuration
if c.BaseURL == "" {
return fmt.Errorf("base_url is required (set EDGE_CONNECT_BASE_URL)")
}
if c.AuthType == "" {
return fmt.Errorf("auth_type is required (set EDGE_CONNECT_AUTH_TYPE to 'token', 'credentials', or 'none')")
}
if c.AuthType != "token" && c.AuthType != "credentials" && c.AuthType != "none" {
return fmt.Errorf("auth_type must be 'token', 'credentials', or 'none'")
}
if c.AuthType == "token" && c.Token == "" {
return fmt.Errorf("token is required when auth_type is 'token' (set EDGE_CONNECT_TOKEN)")
}
if c.AuthType == "credentials" && (c.Username == "" || c.Password == "") {
return fmt.Errorf("username and password are required when auth_type is 'credentials' (set EDGE_CONNECT_USERNAME and EDGE_CONNECT_PASSWORD)")
}
// Validate Server Mode configuration
if c.ServerMode != "stdio" && c.ServerMode != "remote" {
return fmt.Errorf("server_mode must be 'stdio' or 'remote'")
}
if c.ServerMode == "remote" {
if c.RemotePort <= 0 || c.RemotePort > 65535 {
return fmt.Errorf("remote_port must be between 1 and 65535")
}
if c.RemoteAuthRequired && len(c.RemoteAuthTokens) == 0 {
return fmt.Errorf("remote_auth_tokens is required when remote_auth_required is true (set MCP_REMOTE_AUTH_TOKENS)")
}
}
// Validate OAuth configuration
if c.OAuthEnabled {
if c.OAuthResourceURI == "" {
return fmt.Errorf("oauth_resource_uri is required when oauth is enabled (set OAUTH_RESOURCE_URI)")
}
if len(c.OAuthAuthServers) == 0 {
return fmt.Errorf("oauth_auth_servers is required when oauth is enabled (set OAUTH_AUTH_SERVERS)")
}
if c.OAuthIssuer == "" {
return fmt.Errorf("oauth_issuer is required when oauth is enabled (set OAUTH_ISSUER)")
}
if c.OAuthJWKSURL == "" {
return fmt.Errorf("oauth_jwks_url is required when oauth is enabled (set OAUTH_JWKS_URL)")
}
}
// Validate Basic Auth Server configuration
if c.OAuthAuthServerEnabled {
if c.OAuthAuthServerPort <= 0 || c.OAuthAuthServerPort > 65535 {
return fmt.Errorf("oauth_auth_server_port must be between 1 and 65535")
}
if c.OAuthClientID == "" {
return fmt.Errorf("oauth_client_id is required when auth server is enabled (set OAUTH_CLIENT_ID)")
}
if c.OAuthRedirectURI == "" {
return fmt.Errorf("oauth_redirect_uri is required when auth server is enabled (set OAUTH_REDIRECT_URI)")
}
}
return nil
}