config

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: Jul 8, 2026 License: MIT Imports: 28 Imported by: 0

Documentation

Overview

Package config provides configuration loading and parsing.

TOML Configuration Parsing

This package uses BurntSushi/toml v1.6.0+ for robust TOML parsing with:

  • TOML 1.1 specification support (default in v1.6.0+)
  • Column-level error reporting (Position.Line, Position.Col)
  • Duplicate key detection (improved in v1.6.0)
  • Metadata tracking for unknown field detection

Design Patterns

Streaming Decoder: Uses toml.NewDecoder() for memory efficiency with large configs Error Reporting: Wraps ParseError with %w to preserve structured type and surface full source context Unknown Fields: Uses MetaData.Undecoded() to reject configurations with unrecognized fields (spec §4.3.1) Validation: Multi-layer approach (parse → schema → field-level → variable expansion)

TOML 1.1 Features Used

  • Multi-line inline arrays: newlines allowed in array definitions
  • Improved duplicate detection: duplicate keys now properly reported as errors
  • Large float encoding: proper round-trip with exponent syntax

This file defines the core configuration types that are stable and rarely change.

Package config provides configuration loading and parsing. This file defines the feature registration framework for modular config handling.

Package config provides configuration loading and parsing. This file defines stdin (JSON) configuration types.

Package config provides configuration loading and parsing. This file defines the tracing configuration for OpenTelemetry OTLP export.

Index

Constants

View Source
const (
	DefaultPort              = 3000
	DefaultStartupTimeout    = 30   // seconds (per spec §4.1.3)
	DefaultToolTimeout       = 60   // seconds (per spec §4.1.3)
	DefaultKeepaliveInterval = 1500 // seconds (25 minutes) — keeps HTTP backend sessions alive
	DefaultConnectTimeout    = 30   // seconds — per-transport timeout for HTTP backend connect
	// DefaultPayloadDir is the default directory for storing large payloads.
	DefaultPayloadDir = "/tmp/jq-payloads"
	// DefaultLogDir is the default directory for storing log files.
	DefaultLogDir = "/tmp/gh-aw/mcp-logs"
	// DefaultWasmCacheDirName is the default subdirectory name for persisted wazero compilation artifacts.
	DefaultWasmCacheDirName = "wazero-cache"
	// DefaultPayloadSizeThreshold is the default threshold (in bytes) for storing payloads on disk.
	DefaultPayloadSizeThreshold = 524288
)

Core constants for configuration defaults

View Source
const (
	IntegrityNone       = "none"
	IntegrityUnapproved = "unapproved"
	IntegrityApproved   = "approved"
	IntegrityMerged     = "merged"
)
View Source
const (
	EnvGuardPolicyJSON       = "MCP_GATEWAY_GUARD_POLICY_JSON"
	EnvAllowOnlyScopePublic  = "MCP_GATEWAY_ALLOWONLY_SCOPE_PUBLIC"
	EnvAllowOnlyScopeOwner   = "MCP_GATEWAY_ALLOWONLY_SCOPE_OWNER"
	EnvAllowOnlyScopeRepo    = "MCP_GATEWAY_ALLOWONLY_SCOPE_REPO"
	EnvAllowOnlyMinIntegrity = "MCP_GATEWAY_ALLOWONLY_MIN_INTEGRITY"
	// EnvForcePublicRepos controls whether force-public-repos enforcement is active.
	// Default true (feature on). Set to "false" to opt out.
	EnvForcePublicRepos = "MCP_GATEWAY_FORCE_PUBLIC_REPOS"
)

Environment variable names for guard policy configuration.

View Source
const (
	ConfigSpecURL = "https://github.com/github/gh-aw/blob/main/docs/src/content/docs/reference/mcp-gateway.md"
	SchemaURL     = "https://raw.githubusercontent.com/github/gh-aw/v0.81.6/docs/public/schemas/mcp-gateway-config.schema.json"
)

Documentation URL constants

View Source
const DefaultTracingSampleRate = 1.0

DefaultTracingSampleRate is the default sample rate for tracing (100% sampling).

View Source
const DefaultTracingServiceName = "mcp-gateway"

DefaultTracingServiceName is the default service name for tracing.

View Source
const ToolTimeoutMin = 10

ToolTimeoutMin is the minimum allowed value for toolTimeout (seconds).

Variables

View Source
var RequiredEnvVars = []string{
	"MCP_GATEWAY_PORT",
	"MCP_GATEWAY_DOMAIN",
	"MCP_GATEWAY_AGENT_ID",
}

RequiredEnvVars lists the environment variables that must be set for the gateway to operate

View Source
var WriteSinkAcceptRules = "see godoc" // exists for documentation only

WriteSinkAcceptRules documents the mapping from allow-only repos configuration to the required write-sink accept values.

The write-sink accept field must be a superset of the agent's secrecy tags, which are determined by the allow-only repos configuration:

repos = "all"              → agent secrecy = []           → accept = ["*"] (wildcard)
repos = "public"           → agent secrecy = []           → accept = ["*"] (wildcard)
repos = ["O/R"]            → agent secrecy = ["private:O/R"]
                             accept = ["private:O/R"]
repos = ["O/*"]            → agent secrecy = ["private:O"]
                             accept = ["private:O"]
repos = ["O/P*"]           → agent secrecy = ["private:O/P*"]
                             accept = ["private:O/P*"]
repos = ["O/R1", "O/R2"]  → agent secrecy = ["private:O/R1", "private:O/R2"]
                             accept = ["private:O/R1", "private:O/R2"]
repos = ["O1/*", "O2/R"]  → agent secrecy = ["private:O1", "private:O2/R"]
                             accept = ["private:O1", "private:O2/R"]

The transformation rule:

repos entry "O/*"  (owner wildcard)  → accept "private:O"    (bare owner)
repos entry "O/P*" (prefix wildcard) → accept "private:O/P*" (prefix preserved)
repos entry "O/R"  (exact repo)      → accept "private:O/R"  (exact preserved)

Wildcard accept:

accept = ["*"] means "accept writes from any agent regardless of secrecy".
This is the correct configuration for repos="all" and repos="public" where
the agent has no secrecy tags. The write-sink is still required to prevent
the noop guard integrity violation (see WriteSinkGuard godoc).
The wildcard "*" must be the sole entry — it cannot be mixed with other patterns.

Sink Visibility:

When sink-visibility is "public", the write-sink guard ignores accept patterns
entirely and blocks ANY agent with non-empty secrecy. This prevents data
exfiltration from private repos to public outputs (GitLost vulnerability class).

The gh-aw compiler MUST check the safe-outputs target repository visibility
and set sink-visibility accordingly:
  - Public repo target  → sink-visibility = "public"
  - Private repo target → sink-visibility = "private"
  - Internal repo target → sink-visibility = "internal"

Note: min-integrity has no effect on these rules (it only affects integrity labels).

Functions

func AllIntegrityLevels added in v0.3.23

func AllIntegrityLevels() []string

AllIntegrityLevels returns the canonical ordered list of all valid integrity-level values. The returned slice is a defensive copy and safe for callers to modify.

func AppendConfigDocsFooter added in v0.3.26

func AppendConfigDocsFooter(sb *strings.Builder)

AppendConfigDocsFooter appends standard documentation links to an error message

func ExpandRawJSONVariables

func ExpandRawJSONVariables(data []byte) ([]byte, error)

ExpandRawJSONVariables expands all ${VAR} expressions in JSON data before schema validation. This ensures the schema validates the expanded values, not the variable syntax. It collects undefined variables and reports the first undefined variable as an error.

func FormatConfigError added in v0.3.33

func FormatConfigError(err error) string

FormatConfigError returns a rich diagnostic message for TOML parse errors. When err wraps a toml.ParseError, it returns ParseError.ErrorWithUsage() which includes a source-code snippet and column pointer, e.g.:

toml: line 5 (field command): expected "=", got "[" instead

  3 | [servers.github]
  4 | command = "docker"
  5 | [servers.github
      | ^

For all other error types, it falls back to err.Error().

func GetGatewayAgentIDFromEnv added in v0.3.24

func GetGatewayAgentIDFromEnv() string

GetGatewayAgentIDFromEnv returns the gateway agent identifier from environment. New name MCP_GATEWAY_AGENT_ID takes precedence over deprecated MCP_GATEWAY_API_KEY.

func GetGatewayDomainFromEnv

func GetGatewayDomainFromEnv() string

GetGatewayDomainFromEnv returns the MCP_GATEWAY_DOMAIN value

func GetGatewayPortFromEnv

func GetGatewayPortFromEnv() (int, error)

GetGatewayPortFromEnv returns the MCP_GATEWAY_PORT value, parsed as int

func GetGatewaySessionTimeoutFromEnv added in v0.3.7

func GetGatewaySessionTimeoutFromEnv() time.Duration

GetGatewaySessionTimeoutFromEnv returns MCP_GATEWAY_SESSION_TIMEOUT as a duration. Defaults to 6 hours when the variable is unset or invalid.

func GetGatewayToolTimeoutFromEnv added in v0.3.4

func GetGatewayToolTimeoutFromEnv() (int, bool, error)

GetGatewayToolTimeoutFromEnv returns the MCP_GATEWAY_TOOL_TIMEOUT value, parsed as int. Returns (0, false) when the environment variable is not set or empty. Returns an error when the variable is set but invalid (non-integer or below minimum of 10).

func GuardPolicyToMap added in v0.3.22

func GuardPolicyToMap(policy interface{}) (map[string]interface{}, error)

GuardPolicyToMap converts a policy value to a generic map through a JSON roundtrip. It returns an error if the value cannot be serialized or does not decode to a JSON object.

func IsStdioServerType added in v0.3.31

func IsStdioServerType(t string) bool

IsStdioServerType reports whether t is a stdio-family server type. Empty type, "stdio", and the "local" alias all map to stdio.

func IsValidAllowOnlyReposValue added in v0.3.25

func IsValidAllowOnlyReposValue(repos interface{}) bool

IsValidAllowOnlyReposValue returns true when repos is either "all"/"public" (case-insensitive) or a valid non-empty allow-only scope array.

func NormalizeIntegrityLevel added in v0.3.23

func NormalizeIntegrityLevel(raw string, optional bool) (string, error)

NormalizeIntegrityLevel trims and lowercases an integrity-level string and validates it against the canonical set. If optional is true, an empty value is allowed and returns an empty string.

func NormalizeScopeKind added in v0.2.8

func NormalizeScopeKind(policy map[string]interface{}) map[string]interface{}

NormalizeScopeKind returns a copy of the policy map with the scope_kind field normalized to lowercase trimmed string form. Other fields are preserved as-is.

func NormalizeServerType added in v0.3.31

func NormalizeServerType(t string) string

NormalizeServerType maps legacy/empty type strings to canonical values. "" and "local" normalize to "stdio"; all other values are returned unchanged.

func RegisterDefaults

func RegisterDefaults(fn DefaultsSetter)

RegisterDefaults registers a function that sets defaults for a config feature. Called during init() in feature-specific config files.

func RegisterStdinConverter

func RegisterStdinConverter(fn StdinConverter)

RegisterStdinConverter registers a function that converts stdin config for a feature. Called during init() in feature-specific config files.

func ValidateAndNormalizeIntegrityField added in v0.3.28

func ValidateAndNormalizeIntegrityField(fieldPath, raw string, optional bool) (string, error)

ValidateAndNormalizeIntegrityField validates and normalizes a named integrity-level field. It wraps NormalizeIntegrityLevel and prefixes the field path in any error message.

func ValidateGuardPolicy added in v0.1.10

func ValidateGuardPolicy(policy *GuardPolicy) error

ValidateGuardPolicy validates AllowOnly or WriteSink policy input.

func ValidateStringArrayField added in v0.3.25

func ValidateStringArrayField(field string, raw interface{}, requireNonEmpty bool) error

ValidateStringArrayField validates that raw is an array of non-empty strings. When requireNonEmpty is true, an empty array is rejected.

func ValidateWriteSinkPolicy added in v0.1.14

func ValidateWriteSinkPolicy(ws *WriteSinkPolicy) error

ValidateWriteSinkPolicy validates a write-sink policy.

Types

type AllowOnlyPolicy added in v0.1.10

type AllowOnlyPolicy struct {
	Repos                interface{}    `toml:"repos" json:"repos"`
	MinIntegrity         string         `toml:"min-integrity" json:"min-integrity"`
	ToolCallLimits       map[string]int `toml:"tool-call-limits" json:"tool-call-limits,omitempty"`
	BlockedUsers         []string       `toml:"blocked-users" json:"blocked-users,omitempty"`
	RefusalLabels        []string       `toml:"refusal-labels" json:"refusal-labels,omitempty"`
	ApprovalLabels       []string       `toml:"approval-labels" json:"approval-labels,omitempty"`
	TrustedUsers         []string       `toml:"trusted-users" json:"trusted-users,omitempty"`
	EndorsementReactions []string       `toml:"endorsement-reactions" json:"endorsement-reactions,omitempty"`
	DisapprovalReactions []string       `toml:"disapproval-reactions" json:"disapproval-reactions,omitempty"`
	DisapprovalIntegrity string         `toml:"disapproval-integrity" json:"disapproval-integrity,omitempty"`
	EndorserMinIntegrity string         `toml:"endorser-min-integrity" json:"endorser-min-integrity,omitempty"`
	PromotionLabel       string         `toml:"promotion-label" json:"promotion-label,omitempty"`
	DemotionLabel        string         `toml:"demotion-label" json:"demotion-label,omitempty"`
}

AllowOnlyPolicy configures scope and minimum required integrity.

func (AllowOnlyPolicy) MarshalJSON added in v0.1.10

func (p AllowOnlyPolicy) MarshalJSON() ([]byte, error)

func (*AllowOnlyPolicy) UnmarshalJSON added in v0.1.10

func (p *AllowOnlyPolicy) UnmarshalJSON(data []byte) error

type AuthConfig added in v0.2.10

type AuthConfig struct {
	// Type is the authentication type. Currently only "github-oidc" is supported.
	Type string `toml:"type" json:"type"`

	// Audience is the intended audience for the OIDC token.
	// If empty, defaults to the server URL.
	Audience string `toml:"audience" json:"audience,omitempty"`
}

AuthConfig configures upstream authentication for HTTP MCP servers.

type Config

type Config struct {
	// Servers maps server names to their configurations
	Servers map[string]*ServerConfig `toml:"servers" json:"servers"`

	// Guards maps guard names to their configurations
	Guards map[string]*GuardConfig `toml:"guards" json:"guards,omitempty"`

	// Gateway holds global gateway settings
	Gateway *GatewayConfig `toml:"gateway" json:"gateway,omitempty"`

	// DIFCMode specifies the guards enforcement mode: strict (default), filter, or propagate
	// strict: deny access that violates guards rules
	// filter: silently remove tools/resources that violate guards rules
	// propagate: auto-adjust agent labels on reads to allow access
	DIFCMode string `toml:"guards_mode" json:"guards_mode,omitempty"`

	// SequentialLaunch launches servers sequentially instead of in parallel
	SequentialLaunch bool `toml:"sequential_launch" json:"sequential_launch,omitempty"`

	// GuardPolicy optionally overrides per-guard policy via CLI/environment precedence.
	GuardPolicy *GuardPolicy `toml:"-" json:"-"`

	// GuardPolicySource describes where GuardPolicy was resolved from (cli|env|config|legacy).
	GuardPolicySource string `toml:"-" json:"-"`
}

Config represents the internal gateway configuration. Feature-specific fields are added in their respective config_*.go files.

func LoadFromFile

func LoadFromFile(path string) (*Config, error)

LoadFromFile parses a TOML configuration file at path and returns the validated Config, or an error if the file cannot be opened, parsed, contains unknown fields, or fails schema/field-level validation (e.g. no servers defined, containerization, auth, tracing, or trusted_bots checks).

This function uses the BurntSushi/toml v1.6.0+ parser with TOML 1.1 support, which enables modern syntax features like newlines in inline tables and improved duplicate key detection.

Error Handling:

  • Parse errors include both line AND column numbers (v1.5.0+ feature)
  • Unknown fields are rejected with an error per spec §4.3.1
  • Metadata tracks all decoded keys for validation purposes

Callers that need structured parse-error details (line, column, source snippet) can extract the original toml.ParseError via errors.As:

var perr toml.ParseError
if errors.As(err, &perr) {
	fmt.Println(perr.Position())
}

Example usage with TOML 1.1 multi-line arrays:

[servers.github]
command = "docker"
args = [
	"run", "--rm", "-i",
	"--name", "awmg-github-mcp"
]

func LoadFromStdin

func LoadFromStdin() (*Config, error)

LoadFromStdin loads configuration from stdin JSON.

func (*Config) EnsureGatewayDefaults added in v0.2.12

func (cfg *Config) EnsureGatewayDefaults()

EnsureGatewayDefaults guarantees that cfg.Gateway is non-nil and that all gateway-level fields have sensible defaults applied. This matches the invariants enforced by the standard loaders (LoadFromFile, LoadFromStdin), and can be used by callers that construct Config values manually (e.g. in tests) to avoid nil-pointer panics and ensure consistent defaults.

func (*Config) GetAgentID added in v0.3.24

func (c *Config) GetAgentID() string

GetAgentID returns the gateway agent identifier, handling a nil Gateway safely.

type DefaultsSetter

type DefaultsSetter func(cfg *Config)

DefaultsSetter sets default values for a Config. Features register these to apply their defaults during loading.

type EnvValidationResult

type EnvValidationResult struct {
	IsContainerized    bool
	ContainerID        string
	DockerAccessible   bool
	MissingEnvVars     []string
	PortMapped         bool
	StdinInteractive   bool
	LogDirMounted      bool
	ValidationErrors   []string
	ValidationWarnings []string
}

EnvValidationResult holds the result of environment validation. It captures various aspects of the execution environment including containerization status, Docker accessibility, and validation errors/warnings.

This type implements the error interface through its Error() method, which returns a formatted error message containing all validation failures. Use IsValid() to check if all critical validations passed before attempting to start the gateway.

Fields:

  • IsContainerized: Whether the gateway is running inside a Docker container
  • ContainerID: The Docker container ID if containerized
  • DockerAccessible: Whether the Docker daemon is accessible
  • MissingEnvVars: List of required environment variables that are not set
  • PortMapped: Whether the gateway port is mapped to the host (containerized mode)
  • StdinInteractive: Whether stdin is interactive (containerized mode)
  • LogDirMounted: Whether the log directory is mounted (containerized mode)
  • ValidationErrors: Critical errors that prevent the gateway from starting
  • ValidationWarnings: Non-critical issues that should be addressed

func ValidateContainerizedEnvironment

func ValidateContainerizedEnvironment(containerID string) *EnvValidationResult

ValidateContainerizedEnvironment performs additional validation for containerized mode This is called by run_containerized.sh through the binary or by the Go code directly

func ValidateExecutionEnvironment

func ValidateExecutionEnvironment() *EnvValidationResult

ValidateExecutionEnvironment performs comprehensive validation of the execution environment It checks Docker accessibility, required environment variables, and containerization status

func (*EnvValidationResult) Error

func (r *EnvValidationResult) Error() string

Error returns a combined error message for all validation errors

func (*EnvValidationResult) IsValid

func (r *EnvValidationResult) IsValid() bool

IsValid returns true if all critical validations passed

type FeatureConfig

type FeatureConfig interface {
	// FeatureName returns the name of the feature for logging
	FeatureName() string
}

FeatureConfig represents a modular configuration feature. Each feature defines its own config processing in a separate file.

type GatewayConfig

type GatewayConfig struct {
	// Port is the HTTP port to listen on
	Port int `toml:"port" json:"port,omitempty"`

	// AgentID is the gateway agent/session identifier.
	AgentID string `toml:"agent_id" json:"agent_id,omitempty"`

	// APIKey is a deprecated alias for AgentID.
	APIKey string `toml:"api_key" json:"api_key,omitempty"`

	// Domain is the gateway domain for external access
	Domain string `toml:"domain" json:"domain,omitempty"`

	// StartupTimeout is the maximum time (seconds) to wait for server startup
	StartupTimeout int `toml:"startup_timeout" json:"startup_timeout,omitempty"`

	// ToolTimeout is the maximum time (seconds) to wait for tool execution
	ToolTimeout int `toml:"tool_timeout" json:"tool_timeout,omitempty"`

	// KeepaliveInterval is the interval (seconds) for sending keepalive pings to HTTP
	// backends. This prevents long-running sessions from being expired by the remote
	// server's idle timeout (typically 30 minutes). Set to -1 to disable keepalive
	// pings entirely (useful when higher-level timeouts manage session lifecycle).
	// Default: 1500 (25 minutes)
	KeepaliveInterval int `toml:"keepalive_interval" json:"keepalive_interval,omitempty"`

	// PayloadDir is the directory for storing large payloads
	PayloadDir string `toml:"payload_dir" json:"payload_dir,omitempty"`

	// PayloadPathPrefix is the path prefix to use when returning payloadPath to clients.
	// This allows remapping the host filesystem path to a path accessible in the client/agent container.
	// If empty, the actual filesystem path (PayloadDir) is returned.
	// Example: If PayloadDir="/tmp/jq-payloads" and PayloadPathPrefix="/workspace/payloads",
	// then payloadPath will be "/workspace/payloads/{sessionID}/{queryID}/payload.json"
	PayloadPathPrefix string `toml:"payload_path_prefix" json:"payload_path_prefix,omitempty"`

	// PayloadSizeThreshold is the size threshold (in bytes) for storing payloads to disk.
	// Payloads larger than this threshold are stored to disk, smaller ones are returned inline.
	// Default: 524288 bytes (512KB)
	PayloadSizeThreshold int `toml:"payload_size_threshold" json:"payload_size_threshold,omitempty"`

	// URLDomainAudit enables URL domain observation in middleware/guard logging.
	// This is currently toggled via CLI/environment and not loaded from config files.
	URLDomainAudit bool `toml:"-" json:"-"`

	// TrustedBots is an optional list of additional bot usernames that should be treated
	// as trusted. Objects authored by these bots receive "approved" integrity regardless
	// of their author_association. This list is merged with the guard's built-in trusted
	// bot list and is purely additive (it cannot remove built-in trusted bots).
	// Example values: "copilot-swe-agent[bot]", "my-org-bot[bot]"
	TrustedBots []string `toml:"trusted_bots" json:"trusted_bots,omitempty"`

	// ForcePublicRepos controls whether the gateway automatically overrides the
	// allow-only policy to repos="public" when the GITHUB_REPOSITORY repo is public.
	// nil / omitted → enabled by default (auto-force when repo is public)
	// true  → explicitly enabled
	// false → disabled (opt-out via private-to-public-flows: allow)
	// Corresponds to env var MCP_GATEWAY_FORCE_PUBLIC_REPOS.
	ForcePublicRepos *bool `toml:"force_public_repos" json:"forcePublicRepos,omitempty"`

	// SinkVisibilityExemptServers lists server IDs that are exempt from the
	// default sink-visibility="public" enforcement. By default, all non-safe-outputs
	// write-sink servers are assigned sink-visibility="public" (security-by-default).
	// Servers in this list retain their configured (or omitted) sink-visibility as-is.
	// Use ["*"] to exempt all servers (equivalent to disabling the default).
	// Set by the compiler when private-to-public-flows is configured in frontmatter.
	SinkVisibilityExemptServers []string `toml:"sink_visibility_exempt_servers" json:"sinkVisibilityExemptServers,omitempty"`

	// Tracing holds OpenTelemetry OTLP tracing configuration (legacy TOML key).
	// New configurations should use the opentelemetry key (spec §4.1.3.6).
	// When Endpoint is set, traces are exported to the specified OTLP endpoint.
	// When omitted or Endpoint is empty, a noop tracer is used (zero overhead).
	Tracing *TracingConfig `toml:"tracing" json:"tracing,omitempty"`

	// Opentelemetry holds OpenTelemetry OTLP tracing configuration per spec §4.1.3.6.
	// This key takes precedence over the legacy tracing key when both are present.
	// MUST use an HTTPS endpoint when configured.
	Opentelemetry *TracingConfig `toml:"opentelemetry" json:"opentelemetry,omitempty"`
	// contains filtered or unexported fields
}

GatewayConfig holds global gateway settings. Feature-specific fields are added in their respective config_*.go files.

func (*GatewayConfig) HTTPKeepaliveInterval added in v0.2.12

func (g *GatewayConfig) HTTPKeepaliveInterval() time.Duration

HTTPKeepaliveInterval returns the keepalive interval as a time.Duration. A negative KeepaliveInterval disables keepalive (returns 0).

type GuardConfig added in v0.1.10

type GuardConfig struct {
	// Type is the guard type: "wasm", "noop", etc.
	Type string `toml:"type" json:"type"`

	// Path is the path to the guard implementation (e.g., WASM file)
	Path string `toml:"path" json:"path,omitempty"`

	// Config holds guard-specific configuration
	Config map[string]interface{} `toml:"config" json:"config,omitempty"`

	// Policy holds guard policy configuration for label_agent lifecycle initialization
	Policy *GuardPolicy `toml:"policy" json:"policy,omitempty"`
}

GuardConfig represents a guard configuration for DIFC enforcement.

type GuardPolicy added in v0.1.10

type GuardPolicy struct {
	// Hyphenated keys intentionally match the policy schema field names.
	AllowOnly *AllowOnlyPolicy `toml:"allow-only" json:"allow-only,omitempty"`
	WriteSink *WriteSinkPolicy `toml:"write-sink" json:"write-sink,omitempty"`
}

GuardPolicy represents the policy payload passed to guard label_agent.

func BuildAllowOnlyPolicy added in v0.1.16

func BuildAllowOnlyPolicy(public bool, owner, repo, minIntegrity string) (*GuardPolicy, error)

BuildAllowOnlyPolicy constructs an AllowOnly GuardPolicy from the provided parameters. Exactly one of public or owner must be set. If repo is set, owner must also be set. Returns nil, nil if no scope or integrity is specified (indicating no policy).

func ParseGuardPolicyJSON added in v0.1.10

func ParseGuardPolicyJSON(policyJSON string) (*GuardPolicy, error)

ParseGuardPolicyJSON parses policy JSON and validates it.

func ParsePolicyMap added in v0.1.16

func ParsePolicyMap(raw map[string]interface{}) (*GuardPolicy, error)

ParsePolicyMap parses a GuardPolicy from a raw map using either the modern allow-only/write-sink format or the legacy repos/min-integrity format.

func ParseServerGuardPolicy added in v0.1.16

func ParseServerGuardPolicy(serverID string, raw map[string]interface{}) (*GuardPolicy, error)

ParseServerGuardPolicy parses a guard policy from a server-specific raw policy map. It handles both the modern allow-only/write-sink format and the legacy repos/min-integrity format. The serverID is used to look for a server-keyed nested policy map.

func ResolveGuardPolicyOverride added in v0.3.7

func ResolveGuardPolicyOverride(
	cliChanged bool,
	cliPolicyJSON string,
	allowOnlyPublic bool,
	allowOnlyOwner, allowOnlyRepo, allowOnlyMinIntegrity string,
) (*GuardPolicy, string, error)

ResolveGuardPolicyOverride resolves a guard policy override from CLI and environment inputs. Precedence: changed CLI flags > MCP_GATEWAY_GUARD_POLICY_JSON > AllowOnly environment variables.

func (*GuardPolicy) IsWriteSinkPolicy added in v0.1.14

func (p *GuardPolicy) IsWriteSinkPolicy() bool

IsWriteSinkPolicy returns true if this policy configures a write-sink guard.

func (GuardPolicy) MarshalJSON added in v0.1.10

func (p GuardPolicy) MarshalJSON() ([]byte, error)

func (*GuardPolicy) UnmarshalJSON added in v0.1.10

func (p *GuardPolicy) UnmarshalJSON(data []byte) error

type NormalizedGuardPolicy added in v0.1.10

type NormalizedGuardPolicy struct {
	ScopeKind            string         `json:"scope_kind"`
	ScopeValues          []string       `json:"scope_values,omitempty"`
	MinIntegrity         string         `json:"min-integrity"`
	ToolCallLimits       map[string]int `json:"tool-call-limits,omitempty"`
	BlockedUsers         []string       `json:"blocked-users,omitempty"`
	RefusalLabels        []string       `json:"refusal-labels,omitempty"`
	ApprovalLabels       []string       `json:"approval-labels,omitempty"`
	TrustedUsers         []string       `json:"trusted-users,omitempty"`
	EndorsementReactions []string       `json:"endorsement-reactions,omitempty"`
	DisapprovalReactions []string       `json:"disapproval-reactions,omitempty"`
	DisapprovalIntegrity string         `json:"disapproval-integrity,omitempty"`
	EndorserMinIntegrity string         `json:"endorser-min-integrity,omitempty"`
	PromotionLabel       string         `json:"promotion-label,omitempty"`
	DemotionLabel        string         `json:"demotion-label,omitempty"`
}

NormalizedGuardPolicy is a canonical policy representation for caching and observability.

func NormalizeGuardPolicy added in v0.1.10

func NormalizeGuardPolicy(policy *GuardPolicy) (*NormalizedGuardPolicy, error)

NormalizeGuardPolicy validates and normalizes an allow-only policy shape.

type ServerConfig

type ServerConfig struct {
	// Type is the server type: "stdio" or "http"
	Type string `toml:"type" json:"type,omitempty"`

	// Command is the executable command (for stdio servers)
	Command string `toml:"command" json:"command,omitempty"`

	// Args are the command arguments (for stdio servers)
	Args []string `toml:"args" json:"args,omitempty"`

	// Env holds environment variables for the server
	Env map[string]string `toml:"env" json:"env,omitempty"`

	// WorkingDirectory is the working directory for the server
	WorkingDirectory string `toml:"working_directory" json:"working_directory,omitempty"`

	// URL is the HTTP endpoint (for http servers)
	URL string `toml:"url" json:"url,omitempty"`

	// Headers are HTTP headers to send (for http servers)
	Headers map[string]string `toml:"headers" json:"headers,omitempty"`

	// Auth configures upstream authentication for HTTP MCP servers.
	Auth *AuthConfig `toml:"auth" json:"auth,omitempty"`

	// Tools is an optional list of tools to filter/expose
	Tools []string `toml:"tools" json:"tools,omitempty"`

	// ToolResponseFilters configures per-tool jq expressions that transform tool
	// response data before it is returned to the agent and before large-payload
	// preview/schema processing runs.
	ToolResponseFilters map[string]string `toml:"tool_response_filters" json:"tool_response_filters,omitempty"`

	// Registry is the URI to the installation location in an MCP registry (informational)
	Registry string `toml:"registry" json:"registry,omitempty"`

	// GuardPolicies holds guard policies for access control at the MCP gateway level.
	// The structure is server-specific. For GitHub MCP server, see the GitHub guard policy schema.
	GuardPolicies map[string]interface{} `toml:"guard_policies" json:"guard-policies,omitempty"`

	// Guard is the name of the guard to use for this server (requires DIFC)
	Guard string `toml:"guard" json:"guard,omitempty"`

	// ConnectTimeout is the timeout (in seconds) used for SDK-managed HTTP transport connect attempts.
	// The gateway tries multiple transports in sequence (streamable HTTP → SSE → plain JSON-RPC).
	// This timeout applies to the streamable HTTP and SSE connection attempts; the plain JSON-RPC
	// fallback uses the HTTP client's request timeout instead. Increase this for backends that are
	// slow to initialize. Only applies to HTTP server types. Default: 30 seconds.
	ConnectTimeout int `toml:"connect_timeout" json:"connect_timeout,omitempty"`

	// ToolTimeout is the per-server maximum time (seconds) to wait for a single tool invocation.
	// When set, this overrides the global gateway.tool_timeout for calls to this server only.
	// Minimum: 10. When 0 (unset), the global gateway.tool_timeout is used.
	ToolTimeout int `toml:"tool_timeout" json:"tool_timeout,omitempty"`

	// RateLimitThreshold is the number of consecutive rate-limit errors from this backend
	// that will trip the circuit breaker (transition CLOSED → OPEN). When OPEN, requests
	// are immediately rejected until the cooldown period elapses. Default: 3.
	// Supported in TOML config only; the JSON stdin config does not currently accept this field.
	RateLimitThreshold int `toml:"rate_limit_threshold" json:"-"`

	// RateLimitCooldown is the number of seconds the circuit breaker stays OPEN before
	// allowing a single probe request (transition OPEN → HALF-OPEN). If the probe
	// succeeds the circuit closes; if rate-limited again it re-opens. Default: 60.
	// Supported in TOML config only; the JSON stdin config does not currently accept this field.
	RateLimitCooldown int `toml:"rate_limit_cooldown" json:"-"`
}

ServerConfig represents an individual MCP server configuration.

func (*ServerConfig) HTTPConnectTimeout added in v0.2.20

func (s *ServerConfig) HTTPConnectTimeout() time.Duration

HTTPConnectTimeout returns the per-transport connect timeout as a Duration. Returns DefaultConnectTimeout when the field is zero or negative.

type StdinConfig

type StdinConfig struct {
	// MCPServers maps server names to their configurations
	MCPServers map[string]*StdinServerConfig `json:"mcpServers"`

	// Gateway holds global gateway settings
	Gateway *StdinGatewayConfig `json:"gateway,omitempty"`

	// Guards holds guard configurations for DIFC enforcement
	Guards map[string]*StdinGuardConfig `json:"guards,omitempty"`

	// CustomSchemas defines custom server types
	CustomSchemas map[string]interface{} `json:"customSchemas,omitempty"`
}

StdinConfig represents the JSON configuration format read from stdin.

type StdinConverter

type StdinConverter func(cfg *Config, stdinCfg *StdinConfig)

StdinConverter converts stdin-specific config to internal Config. Features register these to handle their stdin config fields.

type StdinGatewayConfig

type StdinGatewayConfig struct {
	Port                        *int                      `json:"port,omitempty"`
	AgentID                     string                    `json:"agentId,omitempty"`
	APIKey                      string                    `json:"apiKey,omitempty"`
	Domain                      string                    `json:"domain,omitempty"`
	StartupTimeout              *int                      `json:"startupTimeout,omitempty"`
	ToolTimeout                 *int                      `json:"toolTimeout,omitempty"`
	KeepaliveInterval           *int                      `json:"keepaliveInterval,omitempty"`
	PayloadDir                  string                    `json:"payloadDir,omitempty"`
	PayloadPathPrefix           *string                   `json:"payloadPathPrefix,omitempty"`
	PayloadSizeThreshold        *int                      `json:"payloadSizeThreshold,omitempty"`
	TrustedBots                 []string                  `json:"trustedBots,omitempty"`
	ForcePublicRepos            *bool                     `json:"forcePublicRepos,omitempty"`
	SinkVisibilityExemptServers []string                  `json:"sinkVisibilityExemptServers,omitempty"`
	OpenTelemetry               *StdinOpenTelemetryConfig `json:"opentelemetry,omitempty"`
	// contains filtered or unexported fields
}

StdinGatewayConfig represents gateway configuration in stdin JSON format. Uses pointers for optional fields to distinguish between unset and zero values.

func (*StdinGatewayConfig) UnmarshalJSON added in v0.3.24

func (g *StdinGatewayConfig) UnmarshalJSON(data []byte) error

UnmarshalJSON enables backward-compatible parsing for gateway.apiKey and tracks deprecated field usage for warning emission.

type StdinGuardConfig added in v0.1.10

type StdinGuardConfig struct {
	// Type is the guard type: "wasm", "noop", etc.
	Type string `json:"type"`

	// Path is the path to the guard implementation (e.g., WASM file)
	Path string `json:"path,omitempty"`

	// Config holds guard-specific configuration
	Config map[string]interface{} `json:"config,omitempty"`

	// Policy holds guard policy configuration for label_agent lifecycle initialization
	Policy *GuardPolicy `json:"policy,omitempty"`
}

StdinGuardConfig represents a guard configuration in stdin JSON format.

type StdinOpenTelemetryConfig added in v0.2.14

type StdinOpenTelemetryConfig struct {
	// Endpoint is the OTLP/HTTP collector URL. MUST be HTTPS. Supports ${VAR} expansion.
	Endpoint string `json:"endpoint"`

	// TraceID is the parent trace ID (32-char lowercase hex, W3C format). Supports ${VAR}.
	TraceID string `json:"traceId,omitempty"`

	// SpanID is the parent span ID (16-char lowercase hex, W3C format). Ignored without TraceID. Supports ${VAR}.
	SpanID string `json:"spanId,omitempty"`

	// ServiceName is the service.name resource attribute. Default: "mcp-gateway".
	ServiceName string `json:"serviceName,omitempty"`
}

StdinOpenTelemetryConfig represents the OpenTelemetry configuration in stdin JSON format (spec §4.1.3.6).

type StdinServerConfig

type StdinServerConfig struct {
	// Type is the server type: "stdio", "local", or "http"
	Type string `json:"type"`

	// Container is the Docker image for stdio servers
	Container string `json:"container,omitempty"`

	// Entrypoint overrides the container entrypoint
	Entrypoint string `json:"entrypoint,omitempty"`

	// EntrypointArgs are additional arguments to the entrypoint
	EntrypointArgs []string `json:"entrypointArgs,omitempty"`

	// Args are additional Docker runtime arguments (passed before container image)
	Args []string `json:"args,omitempty"`

	// Mounts are volume mounts for the container
	Mounts []string `json:"mounts,omitempty"`

	// Env holds environment variables
	Env map[string]string `json:"env,omitempty"`

	// URL is the HTTP endpoint (for http servers)
	URL string `json:"url,omitempty"`

	// Headers are HTTP headers to send (for http servers)
	Headers map[string]string `json:"headers,omitempty"`

	// Tools is an optional list of tools to filter/expose
	Tools []string `json:"tools,omitempty"`

	// ToolResponseFilters configures per-tool jq expressions that transform tool
	// response data before it is returned to the agent.
	ToolResponseFilters map[string]string `json:"tool_response_filters,omitempty"`

	// Registry is the URI to the installation location in an MCP registry (informational)
	Registry string `json:"registry,omitempty"`

	// GuardPolicies holds guard policies for access control at the MCP gateway level.
	// The structure is server-specific. For GitHub MCP server, see the GitHub guard policy schema.
	GuardPolicies map[string]interface{} `json:"guard-policies,omitempty"`

	// Guard is the name of the guard to use for this server (requires DIFC)
	Guard string `json:"guard,omitempty"`

	// Auth configures upstream authentication for HTTP MCP servers.
	Auth *AuthConfig `json:"auth,omitempty"`

	// ConnectTimeout is the per-transport timeout (in seconds) for connecting to HTTP backends.
	// Only applies to HTTP server types. Default: 30 seconds.
	ConnectTimeout *int `json:"connectTimeout,omitempty"`

	// ToolTimeout is the per-server maximum time (seconds) to wait for a single tool invocation.
	// When set to a positive value, this overrides the global gateway.toolTimeout for calls to
	// this server only. Minimum: 10. Omit the field (or set to 0) to fall back to the global
	// gateway.toolTimeout (or MCP_GATEWAY_TOOL_TIMEOUT env fallback).
	ToolTimeout *int `json:"toolTimeout,omitempty"`

	// AdditionalProperties stores any extra fields for custom server types
	// This allows custom schemas to define their own fields beyond the standard ones
	AdditionalProperties map[string]interface{} `json:"-"`
	// contains filtered or unexported fields
}

StdinServerConfig represents a single server configuration in stdin JSON format. Note: unlike TOML ServerConfig, this struct intentionally has no Command field; stdio servers must use Container instead.

func (*StdinServerConfig) UnmarshalJSON added in v0.1.6

func (s *StdinServerConfig) UnmarshalJSON(data []byte) error

UnmarshalJSON implements custom JSON unmarshaling to capture additional properties

type TracingConfig added in v0.2.13

type TracingConfig struct {
	// Endpoint is the OTLP HTTP endpoint to export traces to.
	// When using the opentelemetry section (spec §4.1.3.6), this MUST be an HTTPS URL.
	// If empty, tracing is disabled and a noop tracer is used.
	Endpoint string `toml:"endpoint" json:"endpoint,omitempty"`

	// Headers is a comma-separated list of key=value HTTP headers sent with every OTLP
	// export request (e.g. "Authorization=Bearer ${OTEL_TOKEN},X-Custom=value").
	// Supports ${VAR} variable expansion (expanded at config load time).
	Headers string `toml:"headers" json:"headers,omitempty"`

	// TraceID is an optional W3C trace ID (32-char lowercase hex) used to construct the
	// parent traceparent header, linking gateway spans into a pre-existing trace.
	// Supports ${VAR} variable expansion (expanded at config load time).
	// Must be 32 lowercase hex characters and must not be all zeros.
	TraceID string `toml:"trace_id" json:"traceId,omitempty"`

	// SpanID is an optional W3C span ID (16-char lowercase hex) paired with TraceID
	// to construct the parent traceparent header. Ignored when TraceID is absent.
	// Supports ${VAR} variable expansion (expanded at config load time).
	// Must be 16 lowercase hex characters and must not be all zeros.
	SpanID string `toml:"span_id" json:"spanId,omitempty"`

	// ServiceName is the service name reported in traces.
	// Defaults to "mcp-gateway".
	ServiceName string `toml:"service_name" json:"serviceName,omitempty"`

	// SampleRate controls the fraction of traces that are sampled and exported.
	// Valid range: 0.0 (no sampling) to 1.0 (sample everything).
	// Defaults to 1.0 (100% sampling).
	// Uses a pointer so that 0.0 can be distinguished from "unset".
	// Note: SampleRate is a gateway extension field not present in spec §4.1.3.6.
	SampleRate *float64 `toml:"sample_rate" json:"sampleRate,omitempty"`

	// SignalPath is the OTLP signal path appended to the base endpoint URL.
	// Defaults to "/v1/traces" per the OpenTelemetry specification.
	// Override this only if your collector uses a non-standard ingest path.
	SignalPath string `toml:"signal_path" json:"signalPath,omitempty"`
}

TracingConfig holds OpenTelemetry tracing configuration. Tracing is disabled when Endpoint is empty.

Configuration can also be provided via standard OTEL environment variables:

  • OTEL_EXPORTER_OTLP_ENDPOINT — overrides Endpoint
  • OTEL_SERVICE_NAME — overrides ServiceName

Example TOML (spec §4.1.3.6, using the opentelemetry section):

[gateway.opentelemetry]
endpoint = "https://otel-collector.example.com"
service_name = "mcp-gateway"
trace_id = "4bf92f3577b34da6a3ce929d0e0e4736"
span_id = "00f067aa0ba902b7"
headers = "Authorization=Bearer ${OTEL_TOKEN}"

func (*TracingConfig) GetSampleRate added in v0.2.13

func (c *TracingConfig) GetSampleRate() float64

GetSampleRate returns the configured sample rate, defaulting to 1.0 if unset.

type ValidationError

type ValidationError struct {
	Field      string
	Message    string
	JSONPath   string
	Suggestion string
}

ValidationError represents a configuration validation error with context. It provides detailed information about what went wrong during configuration validation, including the field that failed, a human-readable message, the JSON path to the error location, and a suggestion for how to fix it.

This error type implements the error interface and formats itself with helpful context when Error() is called, including the JSON path and suggestion if available.

func AbsolutePath added in v0.3.26

func AbsolutePath(value, fieldName, jsonPath string) *ValidationError

AbsolutePath validates that a directory path is an absolute path Per MCP Gateway schema: Unix paths start with '/', Windows paths start with a drive letter followed by ':\' Pattern: ^(/|[A-Za-z]:\\) Returns nil if valid, *ValidationError if invalid

func InvalidPattern added in v0.3.26

func InvalidPattern(fieldName, value, jsonPath, suggestion string) *ValidationError

InvalidPattern creates a ValidationError for values that don't match a required pattern. Used by validation_schema.go for container, mount, URL, and other pattern validations.

func InvalidValue added in v0.3.26

func InvalidValue(fieldName, message, jsonPath, suggestion string) *ValidationError

InvalidValue creates a ValidationError for field values that violate a constraint. The message describes the specific constraint violation.

func MissingRequired added in v0.3.26

func MissingRequired(fieldName, serverType, jsonPath, suggestion string) *ValidationError

MissingRequired creates a ValidationError for missing required fields

func MountFormat added in v0.3.26

func MountFormat(mount, jsonPath string, index int) *ValidationError

MountFormat validates a mount specification in the format "source:dest:mode" Returns nil if valid, *ValidationError if invalid Per MCP Gateway specification v1.8.0 section 4.1.5: - Host path MUST be an absolute path - Container path MUST be an absolute path - Mode MUST be either "ro" (read-only) or "rw" (read-write)

func NonEmptyString added in v0.3.26

func NonEmptyString(value, fieldName, jsonPath string) *ValidationError

NonEmptyString validates that a string field is not empty (minLength: 1) Returns nil if valid, *ValidationError if invalid

func PortRange added in v0.3.26

func PortRange(port int, jsonPath string) *ValidationError

PortRange validates that a port is in the valid range (1-65535) Returns nil if valid, *ValidationError if invalid

func PositiveInteger added in v0.3.26

func PositiveInteger(value int, fieldName, jsonPath string) *ValidationError

PositiveInteger validates that a value is at least 1. Returns nil if valid, *ValidationError if invalid. It delegates to TimeoutMinimum with min=1, then overrides Message and Suggestion to use "positive integer" phrasing instead of the generic "must be at least N" wording produced by TimeoutMinimum.

func RequiredStringField added in v0.3.33

func RequiredStringField(value, fieldName, jsonPath, suggestion string) *ValidationError

RequiredStringField validates that a required string field is not empty. It returns a *ValidationError with structured context (Field, JSONPath, Suggestion) so that callers get consistent, machine-readable validation errors instead of plain fmt.Errorf strings. Returns nil if the value is non-empty.

func SchemaValidationError added in v0.3.26

func SchemaValidationError(serverType, message, jsonPath, suggestion string) *ValidationError

SchemaValidationError creates a ValidationError for custom schema validation failures. Used by validation.go for the various stages of custom schema fetching, parsing, and validation.

func TimeoutMinimum added in v0.3.26

func TimeoutMinimum(timeout, min int, fieldName, jsonPath string) *ValidationError

TimeoutMinimum validates that a timeout value is at least min. Returns nil if valid, *ValidationError if below the minimum.

func TimeoutPositive added in v0.3.26

func TimeoutPositive(timeout int, fieldName, jsonPath string) *ValidationError

TimeoutPositive validates that a timeout value is at least 1. Returns nil if valid, *ValidationError if invalid. It delegates to PositiveInteger, then overrides the Suggestion with a timeout-specific message: "Use a positive number of seconds (e.g., 30)".

func TimeoutRange added in v0.3.26

func TimeoutRange(timeout, min, max int, fieldName, jsonPath string) *ValidationError

TimeoutRange validates that a timeout value is within [min, max] (inclusive). Returns nil if valid, *ValidationError if outside the range.

func UndefinedVariable added in v0.3.26

func UndefinedVariable(varName, jsonPath string) *ValidationError

UndefinedVariable creates a ValidationError for undefined environment variables

func UnsupportedField added in v0.3.26

func UnsupportedField(fieldName, message, jsonPath, suggestion string) *ValidationError

UnsupportedField creates a ValidationError for unsupported or unrecognized fields. It is an alias for InvalidValue retained for semantic clarity at call sites where the issue is structural (field shouldn't exist) rather than a value constraint.

func UnsupportedType added in v0.3.26

func UnsupportedType(fieldName, actualType, jsonPath, suggestion string) *ValidationError

UnsupportedType creates a ValidationError for unsupported type values

func (*ValidationError) Error added in v0.3.26

func (e *ValidationError) Error() string

type WriteSinkPolicy added in v0.1.14

type WriteSinkPolicy struct {
	Accept         []string `toml:"accept" json:"accept"`
	SinkVisibility string   `toml:"sink-visibility" json:"sink-visibility,omitempty"`
}

WriteSinkPolicy configures a write-sink guard that accepts writes from agents carrying the listed secrecy labels.

The optional SinkVisibility field declares the visibility of the output channel's target repository. When set to "public", the write-sink guard blocks any agent with a non-empty secrecy label from writing — regardless of the accept patterns — because public outputs are readable by anyone on the internet and would leak private data.

Valid values:

  • "public" — target is a public repo; agents with non-empty secrecy are BLOCKED
  • "private" — target is a private repo; standard accept-pattern matching applies
  • "internal" — target is an org-internal repo; same behavior as "private"

When omitted, the guard falls back to accept-pattern matching only (backward compatible). The gh-aw compiler MUST check the safe-outputs target repository visibility and set this field accordingly to prevent data exfiltration from private repos to public outputs (see: GitLost vulnerability class).

Jump to

Keyboard shortcuts

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