config

package
v0.4.9 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 15, 2026 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Overview

Package config provides configuration loading and management for the registry server.

Index

Constants

View Source
const (
	// SourceFormatToolHive is the native ToolHive registry format
	SourceFormatToolHive = "toolhive"

	// SourceFormatUpstream is the upstream MCP registry format
	SourceFormatUpstream = "upstream"
)
View Source
const (
	// EnvPrefix is the prefix used for environment variables that override config values.
	// For example, THV_REGISTRY_REGISTRYNAME overrides registryName in the config file.
	EnvPrefix = "THV_REGISTRY"
)

Variables

View Source
var DefaultScopes = []string{"mcp-registry:read", "mcp-registry:write"}

DefaultScopes are the default OAuth scopes for the registry when not configured

Functions

This section is empty.

Types

type APIConfig

type APIConfig struct {
	// Endpoint is the base API URL (without path)
	// The registry handler will append the appropriate paths for the MCP Registry API v0.1:
	//   - /v0.1/servers - List all servers
	//   - /v0.1/servers/{name}/versions - List server versions
	//   - /v0.1/servers/{name}/versions/{version} - Get specific version
	// Example: "http://my-registry-api.default.svc.cluster.local/registry"
	Endpoint string `yaml:"endpoint" json:"endpoint"`
}

APIConfig defines API source configuration for upstream MCP Registry APIs

type AuthConfig added in v0.3.0

type AuthConfig struct {
	// Mode specifies the authentication mode (anonymous or oauth)
	// Defaults to "oauth" if not specified (security-by-default).
	// Use "anonymous" to explicitly disable authentication for development.
	Mode AuthMode `yaml:"mode,omitempty"`

	// PublicPaths defines additional paths that bypass authentication
	// These extend the default public paths (health, docs, swagger, well-known)
	// Example: ["/custom/public", "/metrics"]
	PublicPaths []string `yaml:"publicPaths,omitempty"`

	// OAuth contains OAuth/OIDC specific configuration
	// Required when Mode is "oauth"
	OAuth *OAuthConfig `yaml:"oauth,omitempty"`
}

AuthConfig defines authentication configuration for the registry server

func (*AuthConfig) Validate added in v0.3.0

func (a *AuthConfig) Validate(insecureAllowHTTP bool) error

Validate performs validation on the auth configuration. This method assumes Mode has already been resolved to a valid value (either explicitly set or defaulted by resolveAuthMode in serve.go). insecureAllowHTTP allows HTTP URLs for development (when THV_REGISTRY_INSECURE_URL is set).

type AuthMode added in v0.3.0

type AuthMode string

AuthMode represents the authentication mode

const (
	// AuthModeAnonymous allows unauthenticated access
	AuthModeAnonymous AuthMode = "anonymous"

	// AuthModeOAuth requires OAuth/OIDC authentication
	AuthModeOAuth AuthMode = "oauth"

	// DefaultAuthMode is the auth mode used when not explicitly configured.
	// OAuth is the default for a secure-by-default posture.
	DefaultAuthMode AuthMode = AuthModeOAuth
)

type Config

type Config struct {
	// RegistryName is the name/identifier for this registry instance
	// Defaults to "default" if not specified
	RegistryName string             `yaml:"registryName,omitempty"`
	Registries   []RegistryConfig   `yaml:"registries"`
	Database     *DatabaseConfig    `yaml:"database,omitempty"`
	FileStorage  *FileStorageConfig `yaml:"fileStorage,omitempty"`
	Auth         *AuthConfig        `yaml:"auth,omitempty"`
	// contains filtered or unexported fields
}

Config represents the root configuration structure

func LoadConfig

func LoadConfig(opts ...Option) (*Config, error)

LoadConfig loads and parses configuration from a YAML file with environment variable support. Configuration values can be overridden using environment variables with the THV_REGISTRY_ prefix. Nested keys use underscores as separators (e.g., THV_REGISTRY_DATABASE_HOST for database.host).

func (*Config) GetFileStorageBaseDir added in v0.3.0

func (c *Config) GetFileStorageBaseDir() string

GetFileStorageBaseDir returns the base directory for file storage Returns "./data" as the default if not specified

func (*Config) GetRegistryName

func (c *Config) GetRegistryName() string

GetRegistryName returns the registry name, using "default" if not specified

func (*Config) GetStorageType added in v0.3.0

func (c *Config) GetStorageType() StorageType

GetStorageType determines the storage type based on configuration Returns StorageTypeDatabase if database is configured Returns StorageTypeFile if file storage is configured or neither is configured (default)

type DatabaseConfig

type DatabaseConfig struct {
	// Host is the database server hostname or IP address
	Host string `yaml:"host"`

	// Port is the database server port
	Port int `yaml:"port"`

	// User is the database username for normal operations (SELECT, INSERT, UPDATE, DELETE)
	User string `yaml:"user"`

	// MigrationUser is the database username for schema migrations (optional)
	// This user typically has elevated privileges (CREATE, ALTER, DROP)
	// If not specified, defaults to User for backward compatibility
	MigrationUser string `yaml:"migrationUser,omitempty"`

	// Database is the database name
	Database string `yaml:"database"`

	// SSLMode is the SSL mode for the connection (disable, require, verify-ca, verify-full)
	SSLMode string `yaml:"sslMode,omitempty"`

	// MaxOpenConns is the maximum number of open connections to the database
	MaxOpenConns int32 `yaml:"maxOpenConns,omitempty"`

	// MaxIdleConns is the maximum number of idle connections in the pool
	MaxIdleConns int32 `yaml:"maxIdleConns,omitempty"`

	// ConnMaxLifetime is the maximum lifetime of a connection (e.g., "1h", "30m")
	ConnMaxLifetime string `yaml:"connMaxLifetime,omitempty"`
}

DatabaseConfig defines database connection settings

func (*DatabaseConfig) GetConnectionString

func (d *DatabaseConfig) GetConnectionString() string

GetConnectionString builds a PostgreSQL connection string for the application user. The connection string omits the password, allowing pgx to look up the password from PGPASSFILE or ~/.pgpass.

func (*DatabaseConfig) GetMigrationConnectionString added in v0.3.0

func (d *DatabaseConfig) GetMigrationConnectionString() string

GetMigrationConnectionString builds a PostgreSQL connection string for the migration user. Uses GetMigrationUser() which defaults to User if MigrationUser is not set. The connection string omits the password, allowing pgx to look up the password from PGPASSFILE or ~/.pgpass.

func (*DatabaseConfig) GetMigrationPassword added in v0.3.0

func (*DatabaseConfig) GetMigrationPassword() string

GetMigrationPassword returns the database password for the migration user. Returns empty string to let pgx use PGPASSFILE env var or ~/.pgpass. This allows different passwords for app user and migration user via pgpass.

func (*DatabaseConfig) GetMigrationUser added in v0.3.0

func (d *DatabaseConfig) GetMigrationUser() string

GetMigrationUser returns the database user for running migrations. If MigrationUser is not set, returns the regular User for backward compatibility.

func (*DatabaseConfig) GetPassword

func (*DatabaseConfig) GetPassword() string

GetPassword returns the database password for the application user. Returns empty string to let pgx use PGPASSFILE env var or ~/.pgpass. This is the recommended approach - use a pgpass file to provide credentials for both the application user and the migration user.

The pgpass file format is: hostname:port:database:username:password Example:

localhost:5432:registry:db_app:app_password
localhost:5432:registry:db_migrator:migration_password

See: https://www.postgresql.org/docs/current/libpq-pgpass.html

type FileConfig

type FileConfig struct {
	// Path is the path to the registry.json file on the local filesystem
	// Can be absolute or relative to the working directory
	// Mutually exclusive with URL and Data - exactly one must be specified
	Path string `yaml:"path,omitempty" json:"path,omitempty"`

	// URL is the HTTP/HTTPS URL to fetch the registry file from
	// Mutually exclusive with Path and Data - exactly one must be specified
	// HTTPS is required unless the host is localhost or THV_REGISTRY_INSECURE_URL=true
	URL string `yaml:"url,omitempty" json:"url,omitempty"`

	// Data is the inline registry data as a JSON string
	// Mutually exclusive with Path and URL - exactly one must be specified
	// Useful for API-created registries where the data is provided directly
	Data string `yaml:"data,omitempty" json:"data,omitempty"`

	// Timeout is the timeout for HTTP requests when using URL
	// Defaults to 30s if not specified
	// Only applicable when URL is set
	Timeout string `yaml:"timeout,omitempty" json:"timeout,omitempty"`
}

FileConfig defines file source configuration Supports local files, URL-hosted files, or inline data

type FileStorageConfig added in v0.3.0

type FileStorageConfig struct {
	// BaseDir is the base directory for file storage
	// Defaults to "./data" if not specified
	BaseDir string `yaml:"baseDir,omitempty"`
}

FileStorageConfig defines file storage settings

type FilterConfig

type FilterConfig struct {
	Names *NameFilterConfig `yaml:"names,omitempty" json:"names,omitempty"`
	Tags  *TagFilterConfig  `yaml:"tags,omitempty" json:"tags,omitempty"`
}

FilterConfig defines filtering rules for registry entries

type GitConfig

type GitConfig struct {
	// Repository is the Git repository URL (HTTP/HTTPS/SSH)
	Repository string `yaml:"repository" json:"repository"`

	// Branch is the Git branch to use (mutually exclusive with Tag and Commit)
	Branch string `yaml:"branch,omitempty" json:"branch,omitempty"`

	// Tag is the Git tag to use (mutually exclusive with Branch and Commit)
	Tag string `yaml:"tag,omitempty" json:"tag,omitempty"`

	// Commit is the Git commit SHA to use (mutually exclusive with Branch and Tag)
	Commit string `yaml:"commit,omitempty" json:"commit,omitempty"`

	// Path is the path to the registry file within the repository
	Path string `yaml:"path,omitempty" json:"path,omitempty"`
}

GitConfig defines Git source settings

type KubernetesConfig added in v0.3.4

type KubernetesConfig struct{}

KubernetesConfig defines configuration for Kubernetes-based registries Kubernetes registries discover MCP servers from running Kubernetes resources No configuration is actually needed here.

type ManagedConfig added in v0.3.0

type ManagedConfig struct {
}

ManagedConfig defines configuration for managed registries Managed registries are directly manipulated via API and do not sync from external sources Note: Initially empty, may be used as a placeholder for future configuration options

type NameFilterConfig

type NameFilterConfig struct {
	Include []string `yaml:"include,omitempty" json:"include,omitempty"`
	Exclude []string `yaml:"exclude,omitempty" json:"exclude,omitempty"`
}

NameFilterConfig defines name-based filtering

type OAuthConfig added in v0.3.0

type OAuthConfig struct {
	// ResourceURL is the URL identifying this protected resource (RFC 9728)
	// Used in the /.well-known/oauth-protected-resource endpoint
	ResourceURL string `yaml:"resourceUrl,omitempty"`

	// Providers defines the OAuth/OIDC providers for authentication
	// Multiple providers can be configured (e.g., Kubernetes + external IDP)
	Providers []OAuthProviderConfig `yaml:"providers,omitempty"`

	// ScopesSupported defines the OAuth scopes supported by this resource (RFC 9728)
	// Defaults to ["mcp-registry:read", "mcp-registry:write"] if not specified
	ScopesSupported []string `yaml:"scopesSupported,omitempty"`

	// Realm is the protection space identifier for WWW-Authenticate header (RFC 7235)
	// Defaults to "mcp-registry" if not specified
	Realm string `yaml:"realm,omitempty"`
}

OAuthConfig defines OAuth/OIDC specific authentication settings

func (*OAuthConfig) GetScopes added in v0.3.0

func (o *OAuthConfig) GetScopes() []string

GetScopes returns the configured OAuth scopes or defaults if not specified

type OAuthProviderConfig added in v0.3.0

type OAuthProviderConfig struct {
	// Name is a unique identifier for this provider (e.g., "kubernetes", "keycloak")
	Name string `yaml:"name"`

	// IssuerURL is the OIDC issuer URL (e.g., https://accounts.google.com)
	// The JWKS URL will be discovered automatically from .well-known/openid-configuration
	// unless JwksUrl is explicitly specified
	IssuerURL string `yaml:"issuerUrl"`

	// JwksUrl is the URL to fetch the JSON Web Key Set (JWKS) from
	// If specified, OIDC discovery is skipped and this URL is used directly
	// Example: https://kubernetes.default.svc/openid/v1/jwks
	JwksUrl string `yaml:"jwksUrl,omitempty"`

	// Audience is the expected audience claim in the token (REQUIRED)
	// Per RFC 6749 Section 4.1.3, tokens must be validated against expected audience
	// For Kubernetes, this is typically the API server URL
	Audience string `yaml:"audience"`

	// ClientID is the OAuth client ID for token introspection (optional)
	ClientID string `yaml:"clientId,omitempty"`

	// ClientSecretFile is the path to a file containing the client secret
	// The file should contain only the secret with optional trailing whitespace
	ClientSecretFile string `yaml:"clientSecretFile,omitempty"`

	// CACertPath is the path to a CA certificate bundle for verifying the provider's TLS certificate
	// Required for Kubernetes in-cluster authentication or self-signed certificates
	CACertPath string `yaml:"caCertPath,omitempty"`

	// AuthTokenFile is the path to a file containing a bearer token for authenticating to OIDC/JWKS endpoints
	// Useful when the OIDC discovery or JWKS endpoint requires authentication
	// Example: /var/run/secrets/kubernetes.io/serviceaccount/token
	AuthTokenFile string `yaml:"authTokenFile,omitempty"`

	// IntrospectionURL is the OAuth 2.0 Token Introspection endpoint (RFC 7662)
	// Used for validating opaque (non-JWT) tokens
	// If not specified, only JWT tokens can be validated via JWKS
	IntrospectionURL string `yaml:"introspectionUrl,omitempty"`

	// AllowPrivateIP allows JWKS/OIDC endpoints on private IP addresses
	// Required when the OAuth provider (e.g., Kubernetes API server) is running on a private network
	// Example: Set to true when using https://kubernetes.default.svc as the issuer URL
	AllowPrivateIP bool `yaml:"allowPrivateIP,omitempty"`
}

OAuthProviderConfig defines configuration for an OAuth/OIDC provider

func (*OAuthProviderConfig) GetClientSecret added in v0.3.0

func (p *OAuthProviderConfig) GetClientSecret() (string, error)

GetClientSecret returns the client secret by reading from the file specified in ClientSecretFile. Returns empty string if ClientSecretFile is not configured. Returns an error if the file cannot be read.

type Option

type Option func(*loaderConfig) error

Option defines the interface for configuration options

func WithConfigPath

func WithConfigPath(path string) Option

WithConfigPath loads configuration from a YAML file

type RegistryConfig added in v0.3.0

type RegistryConfig struct {
	// Name is the identifier for this registry
	Name string `yaml:"name"`

	// Format specifies the data format (toolhive or upstream)
	Format string `yaml:"format"`

	// Type-specific configurations (only one should be set)
	Git        *GitConfig        `yaml:"git,omitempty"`
	API        *APIConfig        `yaml:"api,omitempty"`
	File       *FileConfig       `yaml:"file,omitempty"`
	Managed    *ManagedConfig    `yaml:"managed,omitempty"`
	Kubernetes *KubernetesConfig `yaml:"kubernetes,omitempty"`

	// Per-registry sync policy
	// Note: Not applicable for non-synced registries (managed and kubernetes) - will be ignored if set
	SyncPolicy *SyncPolicyConfig `yaml:"syncPolicy,omitempty"`

	// Per-registry filtering rules
	// Note: Not applicable for non-synced registries (managed and kubernetes) - will be ignored if set
	Filter *FilterConfig `yaml:"filter,omitempty"`
}

RegistryConfig defines a single registry data source configuration

func (*RegistryConfig) GetType added in v0.3.0

func (r *RegistryConfig) GetType() SourceType

GetType returns the inferred type of the registry config based on which field is present

func (*RegistryConfig) IsNonSyncedRegistry added in v0.3.4

func (r *RegistryConfig) IsNonSyncedRegistry() bool

IsNonSyncedRegistry returns true if the registry type doesn't sync from external sources. This includes managed registries (manipulated via API) and kubernetes registries (query live deployments). Non-synced registries do not require sync policy configuration and skip the sync loop.

type SourceType added in v0.4.7

type SourceType string

SourceType represents the type of registry data source

const (
	// SourceTypeGit is the type for registry data stored in Git repositories
	SourceTypeGit SourceType = "git"

	// SourceTypeAPI is the type for registry data fetched from API endpoints
	SourceTypeAPI SourceType = "api"

	// SourceTypeFile is the type for registry data stored in local files
	SourceTypeFile SourceType = "file"

	// SourceTypeManaged is the type for registries directly managed via API
	// Managed registries do not sync from external sources
	SourceTypeManaged SourceType = "managed"

	// SourceTypeKubernetes is the type for registries that query Kubernetes deployments
	// Kubernetes registries discover MCP servers from running Kubernetes resources
	SourceTypeKubernetes SourceType = "kubernetes"
)

type StorageType added in v0.3.0

type StorageType string

StorageType is an enum of supported storage backends for registry data.

const (
	// StorageTypeDatabase stores registry data in PostgreSQL database
	StorageTypeDatabase StorageType = "database"

	// StorageTypeFile stores registry data in local JSON files
	StorageTypeFile StorageType = "file"
)

type SyncPolicyConfig

type SyncPolicyConfig struct {
	Interval string `yaml:"interval" json:"interval"`
}

SyncPolicyConfig defines synchronization settings

type TagFilterConfig

type TagFilterConfig struct {
	Include []string `yaml:"include,omitempty" json:"include,omitempty"`
	Exclude []string `yaml:"exclude,omitempty" json:"exclude,omitempty"`
}

TagFilterConfig defines tag-based filtering

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL