config

package
v1.2.0 Latest Latest
Warning

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

Go to latest
Published: Apr 25, 2026 License: MIT Imports: 8 Imported by: 0

Documentation

Index

Constants

View Source
const DefaultBaseURL = "https://api.clockify.me/api/v1"

Variables

This section is empty.

Functions

func IsDevControlPlaneDSN added in v1.1.0

func IsDevControlPlaneDSN(dsn string) bool

IsDevControlPlaneDSN reports whether dsn names one of the dev-only control-plane backends. "memory" / "memory://" keep state in process memory; a bare path or "file://..." rewrites a JSON file on every mutation. Neither is correct for a multi-process production deployment of streamable_http.

This predicate is the single source of truth for the fail-closed guard in Load() and the defence-in-depth guard in internal/runtime.BuildStore. Both callers refuse to run streamable_http against a dev DSN unless MCP_ALLOW_DEV_BACKEND=1 is explicit — Load() catches it at config time so operators see the error on startup instead of at first request.

func ProfileNames added in v1.1.0

func ProfileNames() []string

ProfileNames returns the profile names in a stable sorted order, suitable for error messages and the EnvSpec Enum list.

Types

type Config added in v0.6.0

type Config struct {
	// Clockify
	APIKey         string
	WorkspaceID    string
	BaseURL        string
	RequestTimeout time.Duration
	MaxRetries     int
	Insecure       bool
	Timezone       string

	// MCP transport
	Transport          string
	AuthMode           string
	HTTPBind           string
	GRPCBind           string
	BearerToken        string
	AllowedOrigins     []string
	AllowAnyOrigin     bool
	StrictHostCheck    bool
	MaxMessageSize     int64
	MetricsBind        string
	MetricsAuthMode    string
	MetricsBearerToken string

	// Enterprise shared-service
	ControlPlaneDSN string
	// ControlPlaneAuditCap is the max number of audit events retained
	// in the file-backed control-plane store. 0 keeps the historical
	// unbounded behaviour; non-zero enables FIFO eviction. Wired from
	// MCP_CONTROL_PLANE_AUDIT_CAP. Postgres deployments ignore this
	// field in favour of time-based retention (B2).
	ControlPlaneAuditCap int
	// ControlPlaneAuditRetention caps the age of retained audit
	// events. The B2 reaper calls Store.RetainAudit(ctx, retention)
	// on a one-hour ticker; events with `at < now - retention` are
	// removed from the backend. Zero disables retention. Wired from
	// MCP_CONTROL_PLANE_AUDIT_RETENTION; default 720h (30 days).
	ControlPlaneAuditRetention time.Duration
	SessionTTL                 time.Duration
	TenantClaim                string
	SubjectClaim               string
	DefaultTenantID            string
	OIDCIssuer                 string
	OIDCAudience               string
	OIDCJWKSURL                string
	OIDCJWKSPath               string
	// OIDCResourceURI is the canonical URI clients use to address this
	// MCP server. When set, every OIDC token must list this URI in its
	// audience claim — RFC 8707 / MCP OAuth 2.1 resource indicator
	// binding. Wired from MCP_RESOURCE_URI.
	OIDCResourceURI string
	// OIDCVerifyCacheTTL is the hard ceiling on cached OIDC verify
	// results. Larger values amortise the per-request verify cost but
	// extend the window before a revoked token is re-checked. Zero
	// selects the conservative 60s default baked into authn; values
	// outside [1s, 5m] are clamped at the authn layer. Wired from
	// MCP_OIDC_VERIFY_CACHE_TTL.
	OIDCVerifyCacheTTL time.Duration
	// OIDCStrict opts the server into stricter OIDC behaviour for
	// shared-service / hosted deployments. When true, config.Load
	// rejects oidc + (no audience + no resource URI) and the OIDC
	// authenticator rejects tokens missing an `exp` claim. Wired from
	// MCP_OIDC_STRICT=1.
	OIDCStrict           bool
	DisableInlineSecrets bool
	// ExposeAuthErrors controls whether HTTP transports include detailed
	// authenticator failure reasons in unauthenticated client responses.
	// Default false returns a generic "authentication failed" description
	// while server-side logs retain the detailed reason for operators.
	ExposeAuthErrors bool
	// RequireTenantClaim, when true, makes the OIDC authenticator
	// reject any token whose tenant claim is absent — instead of
	// quietly falling back to MCP_DEFAULT_TENANT_ID. Wired from
	// MCP_REQUIRE_TENANT_CLAIM=1; the default fallback is preserved
	// for backward-compat with self-hosted single-tenant deployments.
	RequireTenantClaim   bool
	ForwardTenantHeader  string
	ForwardSubjectHeader string
	MTLSTenantHeader     string
	// MTLSTenantSource selects how the mtls authenticator derives the
	// tenant identifier. "cert" (default) uses the verified client
	// certificate (URI SAN → Subject O fallback). "header" honours the
	// MTLSTenantHeader. "header_or_cert" tries the header first, then
	// the cert. Wired from MCP_MTLS_TENANT_SOURCE.
	MTLSTenantSource string
	// RequireMTLSTenant rejects authentication when the configured
	// tenant source(s) yield no tenant. Wired from
	// MCP_REQUIRE_MTLS_TENANT=1; default false preserves the
	// historical "fall back to MCP_DEFAULT_TENANT_ID" behaviour for
	// self-hosted single-tenant deployments.
	RequireMTLSTenant bool

	// Tool execution
	ToolTimeout               time.Duration
	ConcurrencyAcquireTimeout time.Duration

	// Dispatch-layer concurrency bound for stdio tools/call. 0 disables.
	MaxInFlightToolCalls int

	// Hard cap on entries aggregated by report tools. 0 disables.
	ReportMaxEntries int

	// DeltaFormat selects the resource notification diff algorithm.
	// "merge" (default) = RFC 7396 merge patch. "jsonpatch" = RFC 6902.
	DeltaFormat string

	// GRPCReauthInterval is how often long-lived gRPC streams re-validate
	// their auth token. 0 = disabled (per-stream validation only).
	GRPCReauthInterval time.Duration

	// AuditDurabilityMode controls behavior when audit persistence fails for
	// a successful non-read-only tool call.
	// "best_effort" (default): log + metric; the call still reports success.
	// "fail_closed": the call returns an error so the client knows the audit
	// trail is incomplete. The mutation already happened; this prevents
	// silent untracked mutations.
	AuditDurabilityMode string

	// HTTPInlineMetricsEnabled controls whether /metrics is mounted on the
	// main HTTP listener when MCP_TRANSPORT=http. Default: false (disabled).
	// The dedicated metrics listener (MCP_METRICS_BIND) is the preferred
	// pattern; this is a compatibility escape hatch that requires explicit
	// operator intent.
	HTTPInlineMetricsEnabled bool
	// HTTPInlineMetricsAuthMode governs auth for inline main-listener /metrics.
	// "inherit_main_bearer" (default when enabled): require the same bearer
	// token as the /mcp endpoint.
	// "static_bearer": require a separate MCP_HTTP_INLINE_METRICS_BEARER_TOKEN.
	// "none": unauthenticated — operator must opt in explicitly; startup warns.
	HTTPInlineMetricsAuthMode string
	// HTTPInlineMetricsBearerToken is the separate token for inline metrics
	// when HTTPInlineMetricsAuthMode == "static_bearer".
	HTTPInlineMetricsBearerToken string

	// HTTPLegacyPolicy governs startup behavior when MCP_TRANSPORT=http.
	// "warn" (default): emit structured startup warnings about legacy HTTP
	// limitations and recommend streamable_http.
	// "deny": refuse to start; operator must switch to streamable_http or
	// explicitly set MCP_HTTP_LEGACY_POLICY=allow.
	// "allow": permit startup without deny or warn behavior.
	HTTPLegacyPolicy string

	// GRPCTLSCert and GRPCTLSKey are paths to the server TLS cert and
	// private key for the gRPC transport. Both must be set together.
	GRPCTLSCert string
	GRPCTLSKey  string
	// HTTPTLSCert and HTTPTLSKey are paths to the server TLS cert and
	// private key for the streamable_http transport. Both must be set
	// together. Required when MCP_AUTH_MODE=mtls on streamable_http.
	// Legacy http (MCP_TRANSPORT=http) does not support TLS — see the
	// HTTPTLSCert validation in Load().
	HTTPTLSCert string
	HTTPTLSKey  string
	// MTLSCACertPath is the path to the CA cert for client certificate
	// verification. Required when MCP_AUTH_MODE=mtls on gRPC or
	// streamable_http.
	MTLSCACertPath string
}

func Load added in v0.6.0

func Load() (Config, error)

func (Config) Fingerprint added in v0.6.0

func (c Config) Fingerprint() map[string]any

type EnvSpec added in v1.0.1

type EnvSpec struct {
	Name         string
	Group        string
	Default      string
	Help         string
	Enum         []string
	AppliesTo    []string
	Deprecated   bool
	Replacement  string
	EssentialDoc bool
}

EnvSpec is the single source of truth for every environment variable the server honours. Help text (cmd/clockify-mcp/help_generated.go), the README essentials table, the config-doc-parity CI gate, and the default-parity test all derive from AllSpecs(). Adding a new Getenv in config.go without an entry here trips TestEnvSpec_CoversEveryGetenv.

func AllSpecs added in v1.0.1

func AllSpecs() []EnvSpec

AllSpecs returns the registry in declaration order. Order drives help output grouping; the README renderer sorts alphabetically by Name.

type Profile added in v1.1.0

type Profile struct {
	// Name is the stable identifier passed via --profile=<name> or
	// MCP_PROFILE=<name>. Hyphenated for CLI ergonomics.
	Name string

	// Summary is the one-line description shown in --help and by
	// the doctor subcommand. Keep under 80 characters.
	Summary string

	// Env is the map of env-var keys to the profile's default value.
	// Only unset keys receive a default; an operator who sets any of
	// these explicitly gets their value through. Keys MUST appear in
	// AllSpecs() — an un-specced key here trips the
	// TestProfile_KeysAreSpecced invariant.
	Env map[string]string
}

Profile is a named bundle of env-var defaults for a supported deployment shape. Applying a profile sets each of its Env keys only when the key is currently unset in the process environment; explicit values (from shell, container env, systemd EnvironmentFile, etc.) always win. The five canonical profiles map onto the five docs/deploy/ profile notes.

func AllProfiles added in v1.1.0

func AllProfiles() []Profile

AllProfiles returns a defensive copy of the profile registry in declaration order. Used by help output, the doctor subcommand, and the profile-keys parity test.

func ProfileByName added in v1.1.0

func ProfileByName(name string) (*Profile, error)

ProfileByName resolves a profile by its name. Returns an actionable error naming the valid choices when the name is unknown.

Jump to

Keyboard shortcuts

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