package config import ( "os" "strings" ) type Config struct { Port string // GITEA_MCP_PORT, default 8080 GiteaBaseURL string // GITEA_BASE_URL, e.g. https://gitea.d-ma.be DefaultToken string // GITEA_MCP_DEFAULT_TOKEN, service PAT; used by Gitea client for all upstream calls StaticToken string // GITEA_MCP_STATIC_TOKEN, optional static bearer for service-to-service auth AllowedOwners []string // GITEA_MCP_ALLOWED_OWNERS, comma-separated, default "mathias" OriginAllowlist []string // GITEA_MCP_ORIGIN_ALLOWLIST, comma-separated DexIssuerURL string // DEX_ISSUER_URL, e.g. https://auth.d-ma.be; empty disables JWT auth MCPAudience string // MCP_AUDIENCE, JWT audience claim to validate, e.g. claude-ai MCPResourceURL string // MCP_RESOURCE_URL, this server's public URL for /.well-known metadata } func Load() (Config, error) { cfg := Config{ Port: envOr("GITEA_MCP_PORT", "8080"), GiteaBaseURL: os.Getenv("GITEA_BASE_URL"), DefaultToken: os.Getenv("GITEA_MCP_DEFAULT_TOKEN"), StaticToken: os.Getenv("GITEA_MCP_STATIC_TOKEN"), AllowedOwners: splitCSV(envOr("GITEA_MCP_ALLOWED_OWNERS", "mathias")), OriginAllowlist: splitCSV(os.Getenv("GITEA_MCP_ORIGIN_ALLOWLIST")), DexIssuerURL: os.Getenv("DEX_ISSUER_URL"), MCPAudience: os.Getenv("MCP_AUDIENCE"), MCPResourceURL: os.Getenv("MCP_RESOURCE_URL"), } return cfg, nil } func envOr(key, def string) string { if v := os.Getenv(key); v != "" { return v } return def } func splitCSV(s string) []string { if s == "" { return nil } parts := strings.Split(s, ",") out := make([]string, 0, len(parts)) for _, p := range parts { if p = strings.TrimSpace(p); p != "" { out = append(out, p) } } return out }