{ "components": { "schemas": { "github_com_stacklok_toolhive-core_registry_types.Registry": { "description": "Full registry data", "properties": { "groups": { "description": "Groups is a slice of group definitions containing related MCP servers", "items": { "$ref": "#/components/schemas/registry.Group" }, "type": "array", "uniqueItems": false }, "last_updated": { "description": "LastUpdated is the timestamp when the registry was last updated, in RFC3339 format", "type": "string" }, "remote_servers": { "additionalProperties": { "$ref": "#/components/schemas/registry.RemoteServerMetadata" }, "description": "RemoteServers is a map of server names to their corresponding remote server definitions\nThese are MCP servers accessed via HTTP/HTTPS using the thv proxy command", "type": "object" }, "servers": { "additionalProperties": { "$ref": "#/components/schemas/registry.ImageMetadata" }, "description": "Servers is a map of server names to their corresponding server definitions", "type": "object" }, "version": { "description": "Version is the schema version of the registry", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_cmd_thv-operator_api_v1alpha1.RateLimitBucket": { "description": "PerUser token bucket configuration for this tool.\n+optional", "properties": { "maxTokens": { "description": "MaxTokens is the maximum number of tokens (bucket capacity).\nThis is also the burst size: the maximum number of requests that can be served\ninstantaneously before the bucket is depleted.\n+kubebuilder:validation:Required\n+kubebuilder:validation:Minimum=1", "type": "integer" }, "refillPeriod": { "$ref": "#/components/schemas/v1.Duration" } }, "type": "object" }, "github_com_stacklok_toolhive_cmd_thv-operator_api_v1alpha1.RateLimitConfig": { "description": "RateLimitConfig contains the CRD rate limiting configuration.\nWhen set, rate limiting middleware is added to the proxy middleware chain.", "properties": { "perUser": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_cmd_thv-operator_api_v1alpha1.RateLimitBucket" }, "shared": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_cmd_thv-operator_api_v1alpha1.RateLimitBucket" }, "tools": { "description": "Tools defines per-tool rate limit overrides.\nEach entry applies additional rate limits to calls targeting a specific tool name.\nA request must pass both the server-level limit and the per-tool limit.\n+listType=map\n+listMapKey=name\n+optional", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_cmd_thv-operator_api_v1alpha1.ToolRateLimitConfig" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "github_com_stacklok_toolhive_cmd_thv-operator_api_v1alpha1.ToolRateLimitConfig": { "properties": { "name": { "description": "Name is the MCP tool name this limit applies to.\n+kubebuilder:validation:Required\n+kubebuilder:validation:MinLength=1", "type": "string" }, "perUser": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_cmd_thv-operator_api_v1alpha1.RateLimitBucket" }, "shared": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_cmd_thv-operator_api_v1alpha1.RateLimitBucket" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_audit.Config": { "description": "DEPRECATED: Middleware configuration.\nAuditConfig contains the audit logging configuration", "properties": { "component": { "description": "Component is the component name to use in audit events.\n+optional", "type": "string" }, "enabled": { "description": "Enabled controls whether audit logging is enabled.\nWhen true, enables audit logging with the configured options.\n+kubebuilder:default=false\n+optional", "type": "boolean" }, "eventTypes": { "description": "EventTypes specifies which event types to audit. If empty, all events are audited.\n+optional", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "excludeEventTypes": { "description": "ExcludeEventTypes specifies which event types to exclude from auditing.\nThis takes precedence over EventTypes.\n+optional", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "includeRequestData": { "description": "IncludeRequestData determines whether to include request data in audit logs.\n+kubebuilder:default=false\n+optional", "type": "boolean" }, "includeResponseData": { "description": "IncludeResponseData determines whether to include response data in audit logs.\n+kubebuilder:default=false\n+optional", "type": "boolean" }, "logFile": { "description": "LogFile specifies the file path for audit logs. If empty, logs to stdout.\n+optional", "type": "string" }, "maxDataSize": { "description": "MaxDataSize limits the size of request/response data included in audit logs (in bytes).\n+kubebuilder:default=1024\n+optional", "type": "integer" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_auth.TokenValidatorConfig": { "description": "DEPRECATED: Middleware configuration.\nOIDCConfig contains OIDC configuration", "properties": { "allowPrivateIP": { "description": "AllowPrivateIP allows JWKS/OIDC endpoints on private IP addresses", "type": "boolean" }, "audience": { "description": "Audience is the expected audience for the token", "type": "string" }, "authTokenFile": { "description": "AuthTokenFile is the path to file containing bearer token for authentication", "type": "string" }, "cacertPath": { "description": "CACertPath is the path to the CA certificate bundle for HTTPS requests", "type": "string" }, "clientID": { "description": "ClientID is the OIDC client ID", "type": "string" }, "clientSecret": { "description": "ClientSecret is the optional OIDC client secret for introspection", "type": "string" }, "insecureAllowHTTP": { "description": "InsecureAllowHTTP allows HTTP (non-HTTPS) OIDC issuers for development/testing\nWARNING: This is insecure and should NEVER be used in production", "type": "boolean" }, "introspectionURL": { "description": "IntrospectionURL is the optional introspection endpoint for validating tokens", "type": "string" }, "issuer": { "description": "Issuer is the OIDC issuer URL (e.g., https://accounts.google.com)", "type": "string" }, "jwksurl": { "description": "JWKSURL is the URL to fetch the JWKS from", "type": "string" }, "resourceURL": { "description": "ResourceURL is the explicit resource URL for OAuth discovery (RFC 9728)", "type": "string" }, "scopes": { "description": "Scopes is the list of OAuth scopes to advertise in the well-known endpoint (RFC 9728)\nIf empty, defaults to [\"openid\"]", "items": { "type": "string" }, "type": "array" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_auth_awssts.Config": { "description": "AWSStsConfig contains AWS STS token exchange configuration for accessing AWS services", "properties": { "fallback_role_arn": { "description": "FallbackRoleArn is the IAM role ARN to assume when no role mapping matches.", "type": "string" }, "region": { "description": "Region is the AWS region for STS and SigV4 signing.", "type": "string" }, "role_claim": { "description": "RoleClaim is the JWT claim to use for role mapping (default: \"groups\").", "type": "string" }, "role_mappings": { "description": "RoleMappings maps JWT claim values to IAM roles with priority.", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_auth_awssts.RoleMapping" }, "type": "array", "uniqueItems": false }, "service": { "description": "Service is the AWS service name for SigV4 signing (default: \"aws-mcp\").", "type": "string" }, "session_duration": { "description": "SessionDuration is the duration in seconds for assumed role credentials (default: 3600).", "type": "integer" }, "session_name_claim": { "description": "SessionNameClaim is the JWT claim to use for role session name (default: \"sub\").", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_auth_awssts.RoleMapping": { "properties": { "claim": { "description": "Claim is the simple claim value to match (e.g., group name).\nInternally compiles to a CEL expression: \"\u003cclaim_value\u003e\" in claims[\"\u003crole_claim\u003e\"]\nMutually exclusive with Matcher.", "type": "string" }, "matcher": { "description": "Matcher is a CEL expression for complex matching against JWT claims.\nThe expression has access to a \"claims\" variable containing all JWT claims.\nExamples:\n - \"admins\" in claims[\"groups\"]\n - claims[\"sub\"] == \"user123\" \u0026\u0026 !(\"act\" in claims)\nMutually exclusive with Claim.", "type": "string" }, "priority": { "description": "Priority determines selection order (lower number = higher priority).\nWhen multiple mappings match, the one with the lowest priority is selected.\nWhen nil (omitted), the mapping has the lowest possible priority, and\nconfiguration order acts as tie-breaker via stable sort.", "type": "integer" }, "role_arn": { "description": "RoleArn is the IAM role ARN to assume when this mapping matches.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_auth_remote.Config": { "description": "RemoteAuthConfig contains OAuth configuration for remote MCP servers", "properties": { "authorize_url": { "type": "string" }, "bearer_token": { "description": "Bearer token configuration (alternative to OAuth)", "type": "string" }, "bearer_token_file": { "type": "string" }, "cached_client_id": { "description": "Cached DCR client credentials for persistence across restarts.\nThese are obtained during Dynamic Client Registration and needed to refresh tokens.\nClientID is stored as plain text since it's public information.", "type": "string" }, "cached_client_secret_ref": { "type": "string" }, "cached_refresh_token_ref": { "description": "Cached OAuth token reference for persistence across restarts.\nThe refresh token is stored securely in the secret manager, and this field\ncontains the reference to retrieve it (e.g., \"OAUTH_REFRESH_TOKEN_workload\").\nThis enables session restoration without requiring a new browser-based login.", "type": "string" }, "cached_reg_token_ref": { "description": "RegistrationAccessToken is used to update/delete the client registration.\nStored as a secret reference since it's sensitive.", "type": "string" }, "cached_secret_expiry": { "description": "ClientSecretExpiresAt indicates when the client secret expires (if provided by the DCR server).\nA zero value means the secret does not expire.", "type": "string" }, "cached_token_expiry": { "type": "string" }, "callback_port": { "type": "integer" }, "client_id": { "type": "string" }, "client_secret": { "type": "string" }, "client_secret_file": { "type": "string" }, "issuer": { "description": "OAuth endpoint configuration (from registry)", "type": "string" }, "oauth_params": { "additionalProperties": { "type": "string" }, "description": "OAuth parameters for server-specific customization", "type": "object" }, "resource": { "description": "Resource is the OAuth 2.0 resource indicator (RFC 8707).", "type": "string" }, "scopes": { "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "skip_browser": { "type": "boolean" }, "timeout": { "example": "5m", "type": "string" }, "token_url": { "type": "string" }, "use_pkce": { "type": "boolean" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_auth_tokenexchange.Config": { "description": "TokenExchangeConfig contains token exchange configuration for external authentication", "properties": { "audience": { "description": "Audience is the target audience for the exchanged token", "type": "string" }, "client_id": { "description": "ClientID is the OAuth 2.0 client identifier", "type": "string" }, "client_secret": { "description": "ClientSecret is the OAuth 2.0 client secret", "type": "string" }, "external_token_header_name": { "description": "ExternalTokenHeaderName is the name of the custom header to use when HeaderStrategy is \"custom\"", "type": "string" }, "header_strategy": { "description": "HeaderStrategy determines how to inject the token\nValid values: HeaderStrategyReplace (default), HeaderStrategyCustom", "type": "string" }, "scopes": { "description": "Scopes is the list of scopes to request for the exchanged token", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "subject_token_type": { "description": "SubjectTokenType specifies the type of the subject token being exchanged.\nCommon values: tokenTypeAccessToken (default), tokenTypeIDToken, tokenTypeJWT.\nIf empty, defaults to tokenTypeAccessToken.", "type": "string" }, "token_url": { "description": "TokenURL is the OAuth 2.0 token endpoint URL", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_auth_upstreamswap.Config": { "description": "UpstreamSwapConfig contains configuration for upstream token swap middleware.\nWhen set along with EmbeddedAuthServerConfig, this middleware exchanges ToolHive JWTs\nfor upstream IdP tokens before forwarding requests to the MCP server.", "properties": { "custom_header_name": { "description": "CustomHeaderName is the header name when HeaderStrategy is \"custom\".", "type": "string" }, "header_strategy": { "description": "HeaderStrategy determines how to inject the token: \"replace\" (default) or \"custom\".", "type": "string" }, "provider_name": { "description": "ProviderName identifies which upstream provider's tokens to retrieve for injection.\nThis is required and must match a configured upstream provider name.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver.OAuth2UpstreamRunConfig": { "description": "OAuth2Config contains OAuth 2.0-specific configuration.\nRequired when Type is \"oauth2\", must be nil when Type is \"oidc\".", "properties": { "authorization_endpoint": { "description": "AuthorizationEndpoint is the URL for the OAuth authorization endpoint.", "type": "string" }, "client_id": { "description": "ClientID is the OAuth 2.0 client identifier registered with the upstream IDP.", "type": "string" }, "client_secret_env_var": { "description": "ClientSecretEnvVar is the name of an environment variable containing the client secret.\nMutually exclusive with ClientSecretFile. Optional for public clients using PKCE.", "type": "string" }, "client_secret_file": { "description": "ClientSecretFile is the path to a file containing the OAuth 2.0 client secret.\nMutually exclusive with ClientSecretEnvVar. Optional for public clients using PKCE.", "type": "string" }, "redirect_uri": { "description": "RedirectURI is the callback URL where the upstream IDP will redirect after authentication.\nWhen not specified, defaults to `{issuer}/oauth/callback`.", "type": "string" }, "scopes": { "description": "Scopes are the OAuth scopes to request from the upstream IDP.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "token_endpoint": { "description": "TokenEndpoint is the URL for the OAuth token endpoint.", "type": "string" }, "token_response_mapping": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.TokenResponseMappingRunConfig" }, "userinfo": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.UserInfoRunConfig" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver.OIDCUpstreamRunConfig": { "description": "OIDCConfig contains OIDC-specific configuration.\nRequired when Type is \"oidc\", must be nil when Type is \"oauth2\".", "properties": { "client_id": { "description": "ClientID is the OAuth 2.0 client identifier registered with the upstream IDP.", "type": "string" }, "client_secret_env_var": { "description": "ClientSecretEnvVar is the name of an environment variable containing the client secret.\nMutually exclusive with ClientSecretFile. Optional for public clients using PKCE.", "type": "string" }, "client_secret_file": { "description": "ClientSecretFile is the path to a file containing the OAuth 2.0 client secret.\nMutually exclusive with ClientSecretEnvVar. Optional for public clients using PKCE.", "type": "string" }, "issuer_url": { "description": "IssuerURL is the OIDC issuer URL for automatic endpoint discovery.\nMust be a valid HTTPS URL.", "type": "string" }, "redirect_uri": { "description": "RedirectURI is the callback URL where the upstream IDP will redirect after authentication.\nWhen not specified, defaults to `{issuer}/oauth/callback`.", "type": "string" }, "scopes": { "description": "Scopes are the OAuth scopes to request from the upstream IDP.\nIf not specified, defaults to [\"openid\", \"offline_access\"].", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "userinfo_override": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.UserInfoRunConfig" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver.RunConfig": { "description": "EmbeddedAuthServerConfig contains configuration for the embedded OAuth2/OIDC authorization server.\nWhen set, the proxy runner will start an embedded auth server that delegates to upstream IDPs.\nThis is the serializable RunConfig; secrets are referenced by file paths or env var names.", "properties": { "allowed_audiences": { "description": "AllowedAudiences is the list of valid resource URIs that tokens can be issued for.\nPer RFC 8707, the \"resource\" parameter in authorization and token requests is\nvalidated against this list. Required for MCP compliance.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "authorization_endpoint_base_url": { "description": "AuthorizationEndpointBaseURL overrides the base URL used for the authorization_endpoint\nin the OAuth discovery document. When set, the discovery document will advertise\n`{authorization_endpoint_base_url}/oauth/authorize` instead of `{issuer}/oauth/authorize`.\nAll other endpoints remain derived from the issuer.", "type": "string" }, "hmac_secret_files": { "description": "HMACSecretFiles contains file paths to HMAC secrets for signing authorization codes\nand refresh tokens (opaque tokens).\nFirst file is the current secret (must be at least 32 bytes), subsequent files\nare for rotation/verification of existing tokens.\nIf empty, an ephemeral secret will be auto-generated (development only).", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "issuer": { "description": "Issuer is the issuer identifier for this authorization server.\nThis will be included in the \"iss\" claim of issued tokens.\nMust be a valid HTTPS URL (or HTTP for localhost) without query, fragment, or trailing slash.", "type": "string" }, "schema_version": { "description": "SchemaVersion is the version of the RunConfig schema.", "type": "string" }, "scopes_supported": { "description": "ScopesSupported lists the OAuth 2.0 scope values advertised in discovery documents.\nIf empty, defaults to registration.DefaultScopes ([\"openid\", \"profile\", \"email\", \"offline_access\"]).", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "signing_key_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.SigningKeyRunConfig" }, "storage": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver_storage.RunConfig" }, "token_lifespans": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.TokenLifespanRunConfig" }, "upstreams": { "description": "Upstreams configures connections to upstream Identity Providers.\nAt least one upstream is required - the server delegates authentication to these providers.\nMultiple upstreams are supported for sequential authorization chains.", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.UpstreamRunConfig" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver.SigningKeyRunConfig": { "description": "SigningKeyConfig configures the signing key provider for JWT operations.\nIf nil or empty, an ephemeral signing key will be auto-generated (development only).", "properties": { "fallback_key_files": { "description": "FallbackKeyFiles are filenames of additional keys for verification (relative to KeyDir).\nThese keys are included in the JWKS endpoint for token verification but are NOT\nused for signing new tokens. Useful for key rotation.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "key_dir": { "description": "KeyDir is the directory containing PEM-encoded private key files.\nAll key filenames are relative to this directory.\nIn Kubernetes, this is typically a mounted Secret volume.", "type": "string" }, "signing_key_file": { "description": "SigningKeyFile is the filename of the primary signing key (relative to KeyDir).\nThis key is used for signing new tokens.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver.TokenLifespanRunConfig": { "description": "TokenLifespans configures the duration that various tokens are valid.\nIf nil, defaults are applied (access: 1h, refresh: 7d, authCode: 10m).", "properties": { "access_token_lifespan": { "description": "AccessTokenLifespan is the duration that access tokens are valid.\nIf empty, defaults to 1 hour.", "type": "string" }, "auth_code_lifespan": { "description": "AuthCodeLifespan is the duration that authorization codes are valid.\nIf empty, defaults to 10 minutes.", "type": "string" }, "refresh_token_lifespan": { "description": "RefreshTokenLifespan is the duration that refresh tokens are valid.\nIf empty, defaults to 7 days (168h).", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver.TokenResponseMappingRunConfig": { "description": "TokenResponseMapping configures custom field extraction from non-standard token responses.\nWhen set, the token exchange bypasses golang.org/x/oauth2 and extracts fields using\nthe configured dot-notation paths.", "properties": { "access_token_path": { "description": "AccessTokenPath is the dot-notation path to the access token (required).", "type": "string" }, "expires_in_path": { "description": "ExpiresInPath is the dot-notation path to the expires_in value. Defaults to \"expires_in\".", "type": "string" }, "refresh_token_path": { "description": "RefreshTokenPath is the dot-notation path to the refresh token. Defaults to \"refresh_token\".", "type": "string" }, "scope_path": { "description": "ScopePath is the dot-notation path to the scope. Defaults to \"scope\".", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver.UpstreamProviderType": { "description": "Type specifies the provider type: \"oidc\" or \"oauth2\".", "enum": ["oidc", "oauth2"], "type": "string", "x-enum-varnames": [ "UpstreamProviderTypeOIDC", "UpstreamProviderTypeOAuth2" ] }, "github_com_stacklok_toolhive_pkg_authserver.UpstreamRunConfig": { "properties": { "name": { "description": "Name uniquely identifies this upstream.\nUsed for routing decisions and session binding in multi-upstream scenarios.\nIf empty when only one upstream is configured, defaults to \"default\".", "type": "string" }, "oauth2_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.OAuth2UpstreamRunConfig" }, "oidc_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.OIDCUpstreamRunConfig" }, "type": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.UpstreamProviderType" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver.UserInfoFieldMappingRunConfig": { "description": "FieldMapping contains custom field mapping configuration for non-standard providers.\nIf nil, standard OIDC field names are used (\"sub\", \"name\", \"email\").", "properties": { "email_fields": { "description": "EmailFields is an ordered list of field names to try for the email address.\nThe first non-empty value found will be used.\nDefault: [\"email\"]", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "name_fields": { "description": "NameFields is an ordered list of field names to try for the display name.\nThe first non-empty value found will be used.\nDefault: [\"name\"]", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "subject_fields": { "description": "SubjectFields is an ordered list of field names to try for the user ID.\nThe first non-empty value found will be used.\nDefault: [\"sub\"]", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver.UserInfoRunConfig": { "description": "UserInfo contains configuration for fetching user information (required for OAuth2).", "properties": { "additional_headers": { "additionalProperties": { "type": "string" }, "description": "AdditionalHeaders contains extra headers to include in the userinfo request.\nUseful for providers that require specific headers (e.g., GitHub's Accept header).", "type": "object" }, "endpoint_url": { "description": "EndpointURL is the URL of the userinfo endpoint.", "type": "string" }, "field_mapping": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.UserInfoFieldMappingRunConfig" }, "http_method": { "description": "HTTPMethod is the HTTP method to use for the userinfo request.\nIf not specified, defaults to GET.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver_storage.ACLUserRunConfig": { "description": "ACLUserConfig contains ACL user authentication configuration.", "properties": { "password_env_var": { "description": "PasswordEnvVar is the environment variable containing the Redis password.", "type": "string" }, "username_env_var": { "description": "UsernameEnvVar is the environment variable containing the Redis username.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver_storage.RedisRunConfig": { "description": "RedisConfig is the Redis-specific configuration when Type is \"redis\".", "properties": { "acl_user_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver_storage.ACLUserRunConfig" }, "auth_type": { "description": "AuthType must be \"aclUser\" - only ACL user authentication is supported.", "type": "string" }, "dial_timeout": { "description": "DialTimeout is the timeout for establishing connections (e.g., \"5s\").", "type": "string" }, "key_prefix": { "description": "KeyPrefix for multi-tenancy, typically \"thv:auth:{ns}:{name}:\".", "type": "string" }, "read_timeout": { "description": "ReadTimeout is the timeout for read operations (e.g., \"3s\").", "type": "string" }, "sentinel_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver_storage.SentinelRunConfig" }, "sentinel_tls": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver_storage.RedisTLSRunConfig" }, "tls": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver_storage.RedisTLSRunConfig" }, "write_timeout": { "description": "WriteTimeout is the timeout for write operations (e.g., \"3s\").", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver_storage.RedisTLSRunConfig": { "description": "SentinelTLS configures TLS for Sentinel connections.\nFalls back to TLS config when nil.", "properties": { "ca_cert_file": { "description": "CACertFile is the path to a PEM-encoded CA certificate file.", "type": "string" }, "insecure_skip_verify": { "description": "InsecureSkipVerify skips certificate verification.", "type": "boolean" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver_storage.RunConfig": { "description": "Storage configures the storage backend for the auth server.\nIf nil, defaults to in-memory storage.", "properties": { "redis_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver_storage.RedisRunConfig" }, "type": { "description": "Type specifies the storage backend type. Defaults to \"memory\".", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authserver_storage.SentinelRunConfig": { "description": "SentinelConfig contains Sentinel-specific configuration.", "properties": { "db": { "description": "DB is the Redis database number (default: 0).", "type": "integer" }, "master_name": { "description": "MasterName is the name of the Redis Sentinel master.", "type": "string" }, "sentinel_addrs": { "description": "SentinelAddrs is the list of Sentinel addresses (host:port).", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_authz.Config": { "description": "DEPRECATED: Middleware configuration.\nAuthzConfig contains the authorization configuration", "properties": { "type": { "description": "Type is the type of authorization configuration (e.g., \"cedarv1\").", "type": "string" }, "version": { "description": "Version is the version of the configuration format.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_client.ClientApp": { "description": "ClientType is the type of MCP client", "enum": [ "roo-code", "cline", "cursor", "vscode-insider", "vscode", "claude-code", "windsurf", "windsurf-jetbrains", "amp-cli", "amp-vscode", "amp-cursor", "amp-vscode-insider", "amp-windsurf", "lm-studio", "goose", "trae", "continue", "opencode", "kiro", "antigravity", "zed", "gemini-cli", "vscode-server", "mistral-vibe", "codex" ], "type": "string", "x-enum-varnames": [ "RooCode", "Cline", "Cursor", "VSCodeInsider", "VSCode", "ClaudeCode", "Windsurf", "WindsurfJetBrains", "AmpCli", "AmpVSCode", "AmpCursor", "AmpVSCodeInsider", "AmpWindsurf", "LMStudio", "Goose", "Trae", "Continue", "OpenCode", "Kiro", "Antigravity", "Zed", "GeminiCli", "VSCodeServer", "MistralVibe", "Codex" ] }, "github_com_stacklok_toolhive_pkg_client.ClientAppStatus": { "properties": { "client_type": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_client.ClientApp" }, "installed": { "description": "Installed indicates whether the client is installed on the system", "type": "boolean" }, "registered": { "description": "Registered indicates whether the client is registered in the ToolHive configuration", "type": "boolean" }, "supports_skills": { "description": "SupportsSkills indicates whether ToolHive can install skills for this client", "type": "boolean" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_client.RegisteredClient": { "properties": { "groups": { "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "name": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_client.ClientApp" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_container_runtime.WorkloadStatus": { "description": "Current status of the workload", "enum": [ "running", "stopped", "error", "starting", "stopping", "unhealthy", "removing", "unknown", "unauthenticated", "running", "stopped", "error", "starting", "stopping", "unhealthy", "removing", "unknown", "unauthenticated", "running", "stopped", "error", "starting", "stopping", "unhealthy", "removing", "unknown", "unauthenticated" ], "type": "string", "x-enum-varnames": [ "WorkloadStatusRunning", "WorkloadStatusStopped", "WorkloadStatusError", "WorkloadStatusStarting", "WorkloadStatusStopping", "WorkloadStatusUnhealthy", "WorkloadStatusRemoving", "WorkloadStatusUnknown", "WorkloadStatusUnauthenticated" ] }, "github_com_stacklok_toolhive_pkg_container_templates.RuntimeConfig": { "description": "RuntimeConfig allows overriding the default runtime configuration\nfor this specific workload (base images and packages)", "properties": { "additional_packages": { "description": "AdditionalPackages lists extra packages to install in the builder and\nruntime stages.\nExamples for Alpine: [\"git\", \"make\", \"gcc\"]\nExamples for Debian: [\"git\", \"build-essential\"]", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "builder_image": { "description": "BuilderImage is the full image reference for the builder stage.\nAn empty string signals \"use the default for this transport type\" during config merging.\nExamples: \"golang:1.25-alpine\", \"node:22-alpine\", \"python:3.13-slim\"", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_core.Workload": { "properties": { "created_at": { "description": "CreatedAt is the timestamp when the workload was created.", "type": "string" }, "group": { "description": "Group is the name of the group this workload belongs to, if any.", "type": "string" }, "labels": { "additionalProperties": { "type": "string" }, "description": "Labels are the container labels (excluding standard ToolHive labels)", "type": "object" }, "name": { "description": "Name is the name of the workload.\nIt is used as a unique identifier.", "type": "string" }, "package": { "description": "Package specifies the Workload Package used to create this Workload.", "type": "string" }, "port": { "description": "Port is the port on which the workload is exposed.\nThis is embedded in the URL.", "type": "integer" }, "proxy_mode": { "description": "ProxyMode is the proxy mode that clients should use to connect.\nFor stdio transports, this will be the proxy mode (sse or streamable-http).\nFor direct transports (sse/streamable-http), this will be the same as TransportType.", "type": "string" }, "remote": { "description": "Remote indicates whether this is a remote workload (true) or a container workload (false).", "type": "boolean" }, "started_at": { "description": "StartedAt is when the container was last started (changes on restart)", "type": "string" }, "status": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_container_runtime.WorkloadStatus" }, "status_context": { "description": "StatusContext provides additional context about the workload's status.\nThe exact meaning is determined by the status and the underlying runtime.", "type": "string" }, "tools": { "description": "ToolsFilter is the filter on tools applied to the workload.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "transport_type": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_transport_types.TransportType" }, "url": { "description": "URL is the URL of the workload exposed by the ToolHive proxy.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_groups.Group": { "properties": { "name": { "type": "string" }, "registered_clients": { "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "skills": { "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_ignore.Config": { "description": "IgnoreConfig contains configuration for ignore processing", "properties": { "loadGlobal": { "description": "Whether to load global ignore patterns", "type": "boolean" }, "printOverlays": { "description": "Whether to print resolved overlay paths for debugging", "type": "boolean" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_registry.OAuthPublicConfig": { "description": "AuthConfig contains the non-secret OAuth configuration when auth is configured.\nNil when auth_status is \"none\".", "properties": { "audience": { "type": "string" }, "client_id": { "type": "string" }, "issuer": { "type": "string" }, "scopes": { "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_runner.HeaderForwardConfig": { "description": "HeaderForward contains configuration for injecting headers into requests to remote servers.", "properties": { "add_headers_from_secret": { "additionalProperties": { "type": "string" }, "description": "AddHeadersFromSecret is a map of header names to secret names.\nThe key is the header name, the value is the secret name in ToolHive's secrets manager.\nResolved at runtime via WithSecrets() into resolvedHeaders.\nThe actual secret value is only held in memory, never persisted.", "type": "object" }, "add_plaintext_headers": { "additionalProperties": { "type": "string" }, "description": "AddPlaintextHeaders is a map of header names to literal values to inject into requests.\nWARNING: These values are stored in plaintext in the configuration.\nFor sensitive values (API keys, tokens), use AddHeadersFromSecret instead.", "type": "object" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_runner.RunConfig": { "properties": { "allow_docker_gateway": { "description": "AllowDockerGateway permits outbound connections to Docker gateway addresses\n(host.docker.internal, gateway.docker.internal, 172.17.0.1). These are\nblocked by default in the egress proxy even when InsecureAllowAll is set.\nOnly applicable to Docker deployments with network isolation enabled.", "type": "boolean" }, "audit_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_audit.Config" }, "audit_config_path": { "description": "DEPRECATED: Middleware configuration.\nAuditConfigPath is the path to the audit configuration file", "type": "string" }, "authz_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authz.Config" }, "authz_config_path": { "description": "DEPRECATED: Middleware configuration.\nAuthzConfigPath is the path to the authorization configuration file", "type": "string" }, "aws_sts_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_auth_awssts.Config" }, "base_name": { "description": "BaseName is the base name used for the container (without prefixes)", "type": "string" }, "cmd_args": { "description": "CmdArgs are the arguments to pass to the container", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "container_labels": { "additionalProperties": { "type": "string" }, "description": "ContainerLabels are the labels to apply to the container", "type": "object" }, "container_name": { "description": "ContainerName is the name of the container", "type": "string" }, "debug": { "description": "Debug indicates whether debug mode is enabled", "type": "boolean" }, "embedded_auth_server_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_authserver.RunConfig" }, "endpoint_prefix": { "description": "EndpointPrefix is an explicit prefix to prepend to SSE endpoint URLs.\nThis is used to handle path-based ingress routing scenarios.", "type": "string" }, "env_file_dir": { "description": "DEPRECATED: No longer appears to be used.\nEnvFileDir is the directory path to load environment files from", "type": "string" }, "env_vars": { "additionalProperties": { "type": "string" }, "description": "EnvVars are the parsed environment variables as key-value pairs", "type": "object" }, "group": { "description": "Group is the name of the group this workload belongs to, if any", "type": "string" }, "header_forward": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_runner.HeaderForwardConfig" }, "host": { "description": "Host is the host for the HTTP proxy", "type": "string" }, "ignore_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_ignore.Config" }, "image": { "description": "Image is the Docker image to run", "type": "string" }, "isolate_network": { "description": "IsolateNetwork indicates whether to isolate the network for the container", "type": "boolean" }, "jwks_auth_token_file": { "description": "DEPRECATED: No longer appears to be used.\nJWKSAuthTokenFile is the path to file containing auth token for JWKS/OIDC requests", "type": "string" }, "k8s_pod_template_patch": { "description": "K8sPodTemplatePatch is a JSON string to patch the Kubernetes pod template\nOnly applicable when using Kubernetes runtime", "type": "string" }, "middleware_configs": { "description": "MiddlewareConfigs contains the list of middleware to apply to the transport\nand the configuration for each middleware.", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_transport_types.MiddlewareConfig" }, "type": "array", "uniqueItems": false }, "mutating_webhooks": { "description": "MutatingWebhooks contains the configuration for mutating webhook middleware.\nMutating webhooks run before validating webhooks, per RFC THV-0017 ordering.", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_webhook.Config" }, "type": "array", "uniqueItems": false }, "name": { "description": "Name is the name of the MCP server", "type": "string" }, "oidc_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_auth.TokenValidatorConfig" }, "permission_profile_name_or_path": { "description": "PermissionProfileNameOrPath is the name or path of the permission profile", "type": "string" }, "port": { "description": "Port is the port for the HTTP proxy to listen on (host port)", "type": "integer" }, "proxy_mode": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_transport_types.ProxyMode" }, "publish": { "description": "Publish lists ports to publish to the host in format \"hostPort:containerPort\"", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "rate_limit_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_cmd_thv-operator_api_v1alpha1.RateLimitConfig" }, "rate_limit_namespace": { "description": "RateLimitNamespace is the Kubernetes namespace for Redis key derivation.", "type": "string" }, "registry_api_url": { "description": "RegistryAPIURL is the registry API URL that served this server's metadata.\nEmpty when the server was not discovered via registry lookup.", "type": "string" }, "registry_server_name": { "description": "RegistryServerName is the registry entry name used to look up this server's metadata.\nEmpty when the server was not discovered via registry lookup.", "type": "string" }, "registry_url": { "description": "RegistryURL is the registry URL that served this server's metadata.\nEmpty when the server was not discovered via registry lookup.", "type": "string" }, "remote_auth_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_auth_remote.Config" }, "remote_url": { "description": "RemoteURL is the URL of the remote MCP server (if running remotely)", "type": "string" }, "runtime_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_container_templates.RuntimeConfig" }, "scaling_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_runner.ScalingConfig" }, "schema_version": { "description": "SchemaVersion is the version of the RunConfig schema", "type": "string" }, "secrets": { "description": "Secrets are the secret parameters to pass to the container\nFormat: \"\u003csecret name\u003e,target=\u003ctarget environment variable\u003e\"", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "target_host": { "description": "TargetHost is the host to forward traffic to (only applicable to SSE transport)", "type": "string" }, "target_port": { "description": "TargetPort is the port for the container to expose (only applicable to SSE transport)", "type": "integer" }, "telemetry_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_telemetry.Config" }, "thv_ca_bundle": { "description": "DEPRECATED: No longer appears to be used.\nThvCABundle is the path to the CA certificate bundle for ToolHive HTTP operations", "type": "string" }, "token_exchange_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_auth_tokenexchange.Config" }, "tools_filter": { "description": "DEPRECATED: Middleware configuration.\nToolsFilter is the list of tools to filter", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "tools_override": { "additionalProperties": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_runner.ToolOverride" }, "description": "DEPRECATED: Middleware configuration.\nToolsOverride is a map from an actual tool to its overridden name and/or description", "type": "object" }, "transport": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_transport_types.TransportType" }, "trust_proxy_headers": { "description": "TrustProxyHeaders indicates whether to trust X-Forwarded-* headers from reverse proxies", "type": "boolean" }, "upstream_swap_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_auth_upstreamswap.Config" }, "validating_webhooks": { "description": "ValidatingWebhooks contains the configuration for validating webhook middleware.", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_webhook.Config" }, "type": "array", "uniqueItems": false }, "volumes": { "description": "Volumes are the directory mounts to pass to the container\nFormat: \"host-path:container-path[:ro]\"", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_runner.ScalingConfig": { "description": "ScalingConfig contains configuration for horizontal scaling of the proxy runner.\nOnly applicable when running in Kubernetes with the ToolHive operator.\nWhen nil, no scaling configuration is applied (single-replica default behavior).", "properties": { "backend_replicas": { "description": "BackendReplicas is the desired StatefulSet replica count for the proxy runner backend.\nWhen nil, replicas are unmanaged (preserving HPA or manual kubectl control).\nWhen set (including 0), the value is an explicit replica count.", "type": "integer" }, "session_redis": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_runner.SessionRedisConfig" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_runner.SessionRedisConfig": { "description": "SessionRedis holds non-sensitive Redis connection parameters for distributed session storage.\nPopulated only when MCPServer.spec.sessionStorage.provider == \"redis\".\nThe Redis password is not included — it is injected as env var THV_SESSION_REDIS_PASSWORD.\n+optional", "properties": { "address": { "description": "Address is the Redis server address (host:port).", "type": "string" }, "db": { "description": "DB is the Redis database number.", "type": "integer" }, "key_prefix": { "description": "KeyPrefix is an optional prefix applied to all Redis keys used by ToolHive.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_runner.ToolOverride": { "properties": { "description": { "description": "Description is the redefined description of the tool", "type": "string" }, "name": { "description": "Name is the redefined name of the tool", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_secrets.SecretParameter": { "description": "Bearer token for authentication (alternative to OAuth)", "properties": { "name": { "type": "string" }, "target": { "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_skills.BuildResult": { "properties": { "reference": { "description": "Reference is the OCI reference of the built skill artifact.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_skills.Dependency": { "properties": { "digest": { "description": "Digest is the OCI digest for upgrade detection.", "type": "string" }, "name": { "description": "Name is the dependency name.", "type": "string" }, "reference": { "description": "Reference is the OCI reference for the dependency.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_skills.InstallStatus": { "description": "Status is the current installation status.", "enum": ["installed", "pending", "failed"], "type": "string", "x-enum-varnames": [ "InstallStatusInstalled", "InstallStatusPending", "InstallStatusFailed" ] }, "github_com_stacklok_toolhive_pkg_skills.InstalledSkill": { "description": "InstalledSkill contains the full installation record.", "properties": { "clients": { "description": "Clients is the list of client identifiers the skill is installed for.\nTODO: Refactor client.ClientApp to a shared package so it can be used here instead of []string.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "dependencies": { "description": "Dependencies is the list of external skill dependencies.", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.Dependency" }, "type": "array", "uniqueItems": false }, "digest": { "description": "Digest is the OCI digest (sha256:...) for upgrade detection.", "type": "string" }, "installed_at": { "description": "InstalledAt is the timestamp when the skill was installed.", "type": "string" }, "metadata": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.SkillMetadata" }, "project_root": { "description": "ProjectRoot is the project root path for project-scoped skills. Empty for user-scoped.", "type": "string" }, "reference": { "description": "Reference is the full OCI reference (e.g. ghcr.io/org/skill:v1).", "type": "string" }, "scope": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.Scope" }, "status": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.InstallStatus" }, "tag": { "description": "Tag is the OCI tag (e.g. v1.0.0).", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_skills.LocalBuild": { "properties": { "description": { "description": "Description is the skill description extracted from the artifact metadata, if available.", "type": "string" }, "digest": { "description": "Digest is the OCI digest of the artifact (sha256:...).", "type": "string" }, "name": { "description": "Name is the skill name extracted from the artifact metadata, if available.", "type": "string" }, "tag": { "description": "Tag is the OCI tag or name used to reference the artifact.", "type": "string" }, "version": { "description": "Version is the skill version extracted from the artifact metadata, if available.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_skills.Scope": { "description": "Scope for the installation", "enum": ["user", "project"], "type": "string", "x-enum-varnames": ["ScopeUser", "ScopeProject"] }, "github_com_stacklok_toolhive_pkg_skills.SkillInfo": { "properties": { "installed_skill": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.InstalledSkill" }, "metadata": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.SkillMetadata" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_skills.SkillMetadata": { "description": "Metadata contains the skill's metadata.", "properties": { "author": { "description": "Author is the skill author or maintainer.", "type": "string" }, "description": { "description": "Description is a human-readable description of the skill.", "type": "string" }, "name": { "description": "Name is the unique name of the skill.", "type": "string" }, "tags": { "description": "Tags is a list of tags for categorization.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "version": { "description": "Version is the semantic version of the skill.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_skills.ValidationResult": { "properties": { "errors": { "description": "Errors is a list of validation errors, if any.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "valid": { "description": "Valid indicates whether the skill definition is valid.", "type": "boolean" }, "warnings": { "description": "Warnings is a list of non-blocking validation warnings, if any.", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_telemetry.Config": { "description": "DEPRECATED: Middleware configuration.\nTelemetryConfig contains the OpenTelemetry configuration", "properties": { "caCertPath": { "description": "CACertPath is the file path to a CA certificate bundle for the OTLP endpoint.\nWhen set, the OTLP exporters use this CA to verify the collector's TLS certificate\ninstead of relying solely on the system CA pool.\n+optional", "type": "string" }, "customAttributes": { "additionalProperties": { "type": "string" }, "description": "CustomAttributes contains custom resource attributes to be added to all telemetry signals.\nThese are parsed from CLI flags (--otel-custom-attributes) or environment variables\n(OTEL_RESOURCE_ATTRIBUTES) as key=value pairs.\n+optional", "type": "object" }, "enablePrometheusMetricsPath": { "description": "EnablePrometheusMetricsPath controls whether to expose Prometheus-style /metrics endpoint.\nThe metrics are served on the main transport port at /metrics.\nThis is separate from OTLP metrics which are sent to the Endpoint.\n+kubebuilder:default=false\n+optional", "type": "boolean" }, "endpoint": { "description": "Endpoint is the OTLP endpoint URL\n+optional", "type": "string" }, "environmentVariables": { "description": "EnvironmentVariables is a list of environment variable names that should be\nincluded in telemetry spans as attributes. Only variables in this list will\nbe read from the host machine and included in spans for observability.\nExample: [\"NODE_ENV\", \"DEPLOYMENT_ENV\", \"SERVICE_VERSION\"]\n+optional", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "headers": { "additionalProperties": { "type": "string" }, "description": "Headers contains authentication headers for the OTLP endpoint.\n+optional", "type": "object" }, "insecure": { "description": "Insecure indicates whether to use HTTP instead of HTTPS for the OTLP endpoint.\n+kubebuilder:default=false\n+optional", "type": "boolean" }, "metricsEnabled": { "description": "MetricsEnabled controls whether OTLP metrics are enabled.\nWhen false, OTLP metrics are not sent even if an endpoint is configured.\nThis is independent of EnablePrometheusMetricsPath.\n+kubebuilder:default=false\n+optional", "type": "boolean" }, "samplingRate": { "description": "SamplingRate is the trace sampling rate (0.0-1.0) as a string.\nOnly used when TracingEnabled is true.\nExample: \"0.05\" for 5% sampling.\n+kubebuilder:default=\"0.05\"\n+optional", "type": "string" }, "serviceName": { "description": "ServiceName is the service name for telemetry.\nWhen omitted, defaults to the server name (e.g., VirtualMCPServer name).\n+optional", "type": "string" }, "serviceVersion": { "description": "ServiceVersion is the service version for telemetry.\nWhen omitted, defaults to the ToolHive version.\n+optional", "type": "string" }, "tracingEnabled": { "description": "TracingEnabled controls whether distributed tracing is enabled.\nWhen false, no tracer provider is created even if an endpoint is configured.\n+kubebuilder:default=false\n+optional", "type": "boolean" }, "useLegacyAttributes": { "description": "UseLegacyAttributes controls whether legacy (pre-MCP OTEL semconv) attribute names\nare emitted alongside the new standard attribute names. When true, spans include both\nold and new attribute names for backward compatibility with existing dashboards.\nCurrently defaults to true; this will change to false in a future release.\n+kubebuilder:default=true\n+optional", "type": "boolean" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_transport_types.MiddlewareConfig": { "properties": { "parameters": { "description": "Parameters is a JSON object containing the middleware parameters.\nIt is stored as a raw message to allow flexible parameter types.", "type": "object" }, "type": { "description": "Type is a string representing the middleware type.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_transport_types.ProxyMode": { "description": "ProxyMode is the effective HTTP protocol the proxy uses.\nFor stdio transports, this is the configured mode (sse or streamable-http).\nFor direct transports (sse/streamable-http), this matches the transport type.\nNote: \"sse\" is deprecated; use \"streamable-http\" instead.", "enum": ["sse", "streamable-http", "sse", "streamable-http"], "type": "string", "x-enum-varnames": ["ProxyModeSSE", "ProxyModeStreamableHTTP"] }, "github_com_stacklok_toolhive_pkg_transport_types.TransportType": { "description": "Transport is the transport mode (stdio, sse, or streamable-http)", "enum": [ "stdio", "sse", "streamable-http", "inspector", "stdio", "sse", "streamable-http", "inspector", "stdio", "sse", "streamable-http", "inspector" ], "type": "string", "x-enum-varnames": [ "TransportTypeStdio", "TransportTypeSSE", "TransportTypeStreamableHTTP", "TransportTypeInspector" ] }, "github_com_stacklok_toolhive_pkg_webhook.Config": { "properties": { "failure_policy": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_webhook.FailurePolicy" }, "hmac_secret_ref": { "description": "HMACSecretRef is an optional reference to an HMAC secret for payload signing.", "type": "string" }, "name": { "description": "Name is a unique identifier for this webhook.", "type": "string" }, "timeout": { "description": "Timeout is the maximum time to wait for a webhook response.", "type": "integer" }, "tls_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_webhook.TLSConfig" }, "url": { "description": "URL is the HTTPS endpoint to call.", "type": "string" } }, "type": "object" }, "github_com_stacklok_toolhive_pkg_webhook.FailurePolicy": { "description": "FailurePolicy determines behavior when the webhook call fails.", "enum": ["fail", "ignore"], "type": "string", "x-enum-varnames": ["FailurePolicyFail", "FailurePolicyIgnore"] }, "github_com_stacklok_toolhive_pkg_webhook.TLSConfig": { "description": "TLSConfig holds optional TLS configuration (CA bundles, client certs).", "properties": { "ca_bundle_path": { "description": "CABundlePath is the path to a CA certificate bundle for server verification.", "type": "string" }, "client_cert_path": { "description": "ClientCertPath is the path to a client certificate for mTLS.", "type": "string" }, "client_key_path": { "description": "ClientKeyPath is the path to a client key for mTLS.", "type": "string" }, "insecure_skip_verify": { "description": "InsecureSkipVerify disables server certificate verification.\nWARNING: This should only be used for development/testing.", "type": "boolean" } }, "type": "object" }, "permissions.InboundNetworkPermissions": { "description": "Inbound defines inbound network permissions", "properties": { "allow_host": { "description": "AllowHost is a list of allowed hosts for inbound connections", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "permissions.NetworkPermissions": { "description": "Network defines network permissions", "properties": { "inbound": { "$ref": "#/components/schemas/permissions.InboundNetworkPermissions" }, "mode": { "description": "Mode specifies the network mode for the container (e.g., \"host\", \"bridge\", \"none\")\nWhen empty, the default container runtime network mode is used", "type": "string" }, "outbound": { "$ref": "#/components/schemas/permissions.OutboundNetworkPermissions" } }, "type": "object" }, "permissions.OutboundNetworkPermissions": { "description": "Outbound defines outbound network permissions", "properties": { "allow_host": { "description": "AllowHost is a list of allowed hosts", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "allow_port": { "description": "AllowPort is a list of allowed ports", "items": { "type": "integer" }, "type": "array", "uniqueItems": false }, "insecure_allow_all": { "description": "InsecureAllowAll allows all outbound network connections", "type": "boolean" } }, "type": "object" }, "permissions.Profile": { "description": "Permission profile to apply", "properties": { "name": { "description": "Name is the name of the profile", "type": "string" }, "network": { "$ref": "#/components/schemas/permissions.NetworkPermissions" }, "privileged": { "description": "Privileged indicates whether the container should run in privileged mode\nWhen true, the container has access to all host devices and capabilities\nUse with extreme caution as this removes most security isolation", "type": "boolean" }, "read": { "description": "Read is a list of mount declarations that the container can read from\nThese can be in the following formats:\n- A single path: The same path will be mounted from host to container\n- host-path:container-path: Different paths for host and container\n- resource-uri:container-path: Mount a resource identified by URI to a container path", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "write": { "description": "Write is a list of mount declarations that the container can write to\nThese follow the same format as Read mounts but with write permissions", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.RegistryType": { "description": "Type of registry (file, url, or default)", "enum": ["file", "url", "api", "default"], "type": "string", "x-enum-varnames": [ "RegistryTypeFile", "RegistryTypeURL", "RegistryTypeAPI", "RegistryTypeDefault" ] }, "pkg_api_v1.UpdateRegistryAuthRequest": { "description": "OAuth authentication configuration (optional)", "properties": { "audience": { "description": "OAuth audience (optional)", "type": "string" }, "client_id": { "description": "OAuth client ID", "type": "string" }, "issuer": { "description": "OIDC issuer URL", "type": "string" }, "scopes": { "description": "OAuth scopes (optional)", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.UpdateRegistryRequest": { "description": "Request containing registry configuration updates", "properties": { "allow_private_ip": { "description": "Allow private IP addresses for registry URL or API URL", "type": "boolean" }, "api_url": { "description": "MCP Registry API URL", "type": "string" }, "auth": { "$ref": "#/components/schemas/pkg_api_v1.UpdateRegistryAuthRequest" }, "local_path": { "description": "Local registry file path", "type": "string" }, "url": { "description": "Registry URL (for remote registries)", "type": "string" } }, "type": "object" }, "pkg_api_v1.UpdateRegistryResponse": { "description": "Response containing update result", "properties": { "type": { "description": "Registry type after update", "type": "string" } }, "type": "object" }, "pkg_api_v1.buildListResponse": { "description": "Response containing a list of locally-built OCI skill artifacts", "properties": { "builds": { "description": "List of locally-built OCI skill artifacts", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.LocalBuild" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.buildSkillRequest": { "description": "Request to build a skill from a local directory", "properties": { "path": { "description": "Path to the skill definition directory", "type": "string" }, "tag": { "description": "OCI tag for the built artifact", "type": "string" } }, "type": "object" }, "pkg_api_v1.bulkClientRequest": { "properties": { "groups": { "description": "Groups is the list of groups configured on the client.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "names": { "description": "Names is the list of client names to operate on.", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_client.ClientApp" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.bulkOperationRequest": { "properties": { "group": { "description": "Group name to operate on (mutually exclusive with names)", "type": "string" }, "names": { "description": "Names of the workloads to operate on", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.clientStatusResponse": { "properties": { "clients": { "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_client.ClientAppStatus" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.createClientRequest": { "properties": { "groups": { "description": "Groups is the list of groups configured on the client.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "name": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_client.ClientApp" } }, "type": "object" }, "pkg_api_v1.createClientResponse": { "properties": { "groups": { "description": "Groups is the list of groups configured on the client.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "name": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_client.ClientApp" } }, "type": "object" }, "pkg_api_v1.createGroupRequest": { "properties": { "name": { "description": "Name of the group to create", "type": "string" } }, "type": "object" }, "pkg_api_v1.createGroupResponse": { "properties": { "name": { "description": "Name of the created group", "type": "string" } }, "type": "object" }, "pkg_api_v1.createRequest": { "description": "Request to create a new workload", "properties": { "authz_config": { "description": "Authorization configuration", "type": "string" }, "cmd_arguments": { "description": "Command arguments to pass to the container", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "env_vars": { "additionalProperties": { "type": "string" }, "description": "Environment variables to set in the container", "type": "object" }, "group": { "description": "Group name this workload belongs to", "type": "string" }, "header_forward": { "$ref": "#/components/schemas/pkg_api_v1.headerForwardConfig" }, "headers": { "items": { "$ref": "#/components/schemas/registry.Header" }, "type": "array", "uniqueItems": false }, "host": { "description": "Host to bind to", "type": "string" }, "image": { "description": "Docker image to use", "type": "string" }, "name": { "description": "Name of the workload", "type": "string" }, "network_isolation": { "description": "Whether network isolation is turned on. This applies the rules in the permission profile.", "type": "boolean" }, "oauth_config": { "$ref": "#/components/schemas/pkg_api_v1.remoteOAuthConfig" }, "oidc": { "$ref": "#/components/schemas/pkg_api_v1.oidcOptions" }, "permission_profile": { "$ref": "#/components/schemas/permissions.Profile" }, "proxy_mode": { "description": "Proxy mode to use", "type": "string" }, "proxy_port": { "description": "Port for the HTTP proxy to listen on", "type": "integer" }, "runtime_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_container_templates.RuntimeConfig" }, "secrets": { "description": "Secret parameters to inject", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_secrets.SecretParameter" }, "type": "array", "uniqueItems": false }, "target_port": { "description": "Port to expose from the container", "type": "integer" }, "tools": { "description": "Tools filter", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "tools_override": { "additionalProperties": { "$ref": "#/components/schemas/pkg_api_v1.toolOverride" }, "description": "Tools override", "type": "object" }, "transport": { "description": "Transport configuration", "type": "string" }, "trust_proxy_headers": { "description": "Whether to trust X-Forwarded-* headers from reverse proxies", "type": "boolean" }, "url": { "description": "Remote server specific fields", "type": "string" }, "volumes": { "description": "Volume mounts", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.createSecretRequest": { "description": "Request to create a new secret", "properties": { "key": { "description": "Secret key name", "type": "string" }, "value": { "description": "Secret value", "type": "string" } }, "type": "object" }, "pkg_api_v1.createSecretResponse": { "description": "Response after creating a secret", "properties": { "key": { "description": "Secret key that was created", "type": "string" }, "message": { "description": "Success message", "type": "string" } }, "type": "object" }, "pkg_api_v1.createWorkloadResponse": { "description": "Response after successfully creating a workload", "properties": { "name": { "description": "Name of the created workload", "type": "string" }, "port": { "description": "Port the workload is listening on", "type": "integer" } }, "type": "object" }, "pkg_api_v1.getRegistryResponse": { "description": "Response containing registry details", "properties": { "auth_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_registry.OAuthPublicConfig" }, "auth_status": { "description": "AuthStatus is one of: \"none\", \"configured\", \"authenticated\".\nIntentionally omits omitempty — see registryInfo for rationale.", "type": "string" }, "auth_type": { "description": "AuthType is \"oauth\", \"bearer\" (future), or empty string when no auth.\nIntentionally omits omitempty — see registryInfo for rationale.", "type": "string" }, "last_updated": { "description": "Last updated timestamp", "type": "string" }, "name": { "description": "Name of the registry", "type": "string" }, "registry": { "$ref": "#/components/schemas/github_com_stacklok_toolhive-core_registry_types.Registry" }, "server_count": { "description": "Number of servers in the registry", "type": "integer" }, "source": { "description": "Source of the registry (URL, file path, or empty string for built-in)", "type": "string" }, "type": { "$ref": "#/components/schemas/pkg_api_v1.RegistryType" }, "version": { "description": "Version of the registry schema", "type": "string" } }, "type": "object" }, "pkg_api_v1.getSecretsProviderResponse": { "description": "Response containing secrets provider details", "properties": { "capabilities": { "$ref": "#/components/schemas/pkg_api_v1.providerCapabilitiesResponse" }, "name": { "description": "Name of the secrets provider", "type": "string" }, "provider_type": { "description": "Type of the secrets provider", "type": "string" } }, "type": "object" }, "pkg_api_v1.getServerResponse": { "description": "Response containing server details", "properties": { "is_remote": { "description": "Indicates if this is a remote server", "type": "boolean" }, "remote_server": { "$ref": "#/components/schemas/registry.RemoteServerMetadata" }, "server": { "$ref": "#/components/schemas/registry.ImageMetadata" } }, "type": "object" }, "pkg_api_v1.groupListResponse": { "properties": { "groups": { "description": "List of groups", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_groups.Group" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.headerForwardConfig": { "description": "HeaderForward configures headers to inject into requests to remote MCP servers.\nUse this to add custom headers like X-Tenant-ID or correlation IDs.", "properties": { "add_headers_from_secret": { "additionalProperties": { "type": "string" }, "description": "AddHeadersFromSecret maps header names to secret names in ToolHive's secrets manager.\nKey: HTTP header name, Value: secret name in the secrets manager", "type": "object" }, "add_plaintext_headers": { "additionalProperties": { "type": "string" }, "description": "AddPlaintextHeaders contains literal header values to inject.\nWARNING: These values are stored and transmitted in plaintext.\nUse AddHeadersFromSecret for sensitive data like API keys.", "type": "object" } }, "type": "object" }, "pkg_api_v1.installSkillRequest": { "description": "Request to install a skill", "properties": { "clients": { "description": "Clients lists target client identifiers (e.g., \"claude-code\"),\nor [\"all\"] to target every skill-supporting client.\nOmitting this field installs to all available clients.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "force": { "description": "Force allows overwriting unmanaged skill directories", "type": "boolean" }, "group": { "description": "Group is the group name to add the skill to after installation", "type": "string" }, "name": { "description": "Name or OCI reference of the skill to install", "type": "string" }, "project_root": { "description": "ProjectRoot is the project root path for project-scoped installs", "type": "string" }, "scope": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.Scope" }, "version": { "description": "Version to install (empty means latest)", "type": "string" } }, "type": "object" }, "pkg_api_v1.installSkillResponse": { "description": "Response after successfully installing a skill", "properties": { "skill": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.InstalledSkill" } }, "type": "object" }, "pkg_api_v1.listSecretsResponse": { "description": "Response containing a list of secret keys", "properties": { "keys": { "description": "List of secret keys", "items": { "$ref": "#/components/schemas/pkg_api_v1.secretKeyResponse" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.listServersResponse": { "description": "Response containing a list of servers", "properties": { "remote_servers": { "description": "List of remote servers in the registry (if any)", "items": { "$ref": "#/components/schemas/registry.RemoteServerMetadata" }, "type": "array", "uniqueItems": false }, "servers": { "description": "List of container servers in the registry", "items": { "$ref": "#/components/schemas/registry.ImageMetadata" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.oidcOptions": { "description": "OIDC configuration options", "properties": { "audience": { "description": "Expected audience", "type": "string" }, "client_id": { "description": "OAuth2 client ID", "type": "string" }, "client_secret": { "description": "OAuth2 client secret", "type": "string" }, "introspection_url": { "description": "Token introspection URL for OIDC", "type": "string" }, "issuer": { "description": "OIDC issuer URL", "type": "string" }, "jwks_url": { "description": "JWKS URL for key verification", "type": "string" }, "scopes": { "description": "OAuth scopes to advertise in well-known endpoint (RFC 9728)", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.providerCapabilitiesResponse": { "description": "Capabilities of the secrets provider", "properties": { "can_cleanup": { "description": "Whether the provider can cleanup all secrets", "type": "boolean" }, "can_delete": { "description": "Whether the provider can delete secrets", "type": "boolean" }, "can_list": { "description": "Whether the provider can list secrets", "type": "boolean" }, "can_read": { "description": "Whether the provider can read secrets", "type": "boolean" }, "can_write": { "description": "Whether the provider can write secrets", "type": "boolean" } }, "type": "object" }, "pkg_api_v1.pushSkillRequest": { "description": "Request to push a built skill artifact", "properties": { "reference": { "description": "OCI reference to push", "type": "string" } }, "type": "object" }, "pkg_api_v1.registryInfo": { "description": "Basic information about a registry", "properties": { "auth_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_registry.OAuthPublicConfig" }, "auth_status": { "description": "AuthStatus is one of: \"none\", \"configured\", \"authenticated\".\nIntentionally omits omitempty so clients always receive the field,\neven when the value is \"none\" (the zero-value equivalent).", "type": "string" }, "auth_type": { "description": "AuthType is \"oauth\", \"bearer\" (future), or empty string when no auth.\nIntentionally omits omitempty so clients can distinguish \"no auth\nconfigured\" (empty string) from \"field missing\" without extra logic.", "type": "string" }, "last_updated": { "description": "Last updated timestamp", "type": "string" }, "name": { "description": "Name of the registry", "type": "string" }, "server_count": { "description": "Number of servers in the registry", "type": "integer" }, "source": { "description": "Source of the registry (URL, file path, or empty string for built-in)", "type": "string" }, "type": { "$ref": "#/components/schemas/pkg_api_v1.RegistryType" }, "version": { "description": "Version of the registry schema", "type": "string" } }, "type": "object" }, "pkg_api_v1.registryListResponse": { "description": "Response containing a list of registries", "properties": { "registries": { "description": "List of registries", "items": { "$ref": "#/components/schemas/pkg_api_v1.registryInfo" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.remoteOAuthConfig": { "description": "OAuth configuration for remote server authentication", "properties": { "authorize_url": { "description": "OAuth authorization endpoint URL (alternative to issuer for non-OIDC OAuth)", "type": "string" }, "bearer_token": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_secrets.SecretParameter" }, "callback_port": { "description": "Specific port for OAuth callback server", "type": "integer" }, "client_id": { "description": "OAuth client ID for authentication", "type": "string" }, "client_secret": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_secrets.SecretParameter" }, "issuer": { "description": "OAuth/OIDC issuer URL (e.g., https://accounts.google.com)", "type": "string" }, "oauth_params": { "additionalProperties": { "type": "string" }, "description": "Additional OAuth parameters for server-specific customization", "type": "object" }, "resource": { "description": "OAuth 2.0 resource indicator (RFC 8707)", "type": "string" }, "scopes": { "description": "OAuth scopes to request", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "skip_browser": { "description": "Whether to skip opening browser for OAuth flow (defaults to false)", "type": "boolean" }, "token_url": { "description": "OAuth token endpoint URL (alternative to issuer for non-OIDC OAuth)", "type": "string" }, "use_pkce": { "description": "Whether to use PKCE for the OAuth flow", "type": "boolean" } }, "type": "object" }, "pkg_api_v1.secretKeyResponse": { "description": "Secret key information", "properties": { "description": { "description": "Optional description of the secret", "type": "string" }, "key": { "description": "Secret key name", "type": "string" } }, "type": "object" }, "pkg_api_v1.setupSecretsRequest": { "description": "Request to setup a secrets provider", "properties": { "password": { "description": "Password for encrypted provider (optional, can be set via environment variable)\nTODO Review environment variable for this", "type": "string" }, "provider_type": { "description": "Type of the secrets provider (encrypted, 1password, environment)", "type": "string" } }, "type": "object" }, "pkg_api_v1.setupSecretsResponse": { "description": "Response after initializing a secrets provider", "properties": { "message": { "description": "Success message", "type": "string" }, "provider_type": { "description": "Type of the secrets provider that was setup", "type": "string" } }, "type": "object" }, "pkg_api_v1.skillListResponse": { "description": "Response containing a list of installed skills", "properties": { "skills": { "description": "List of installed skills", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.InstalledSkill" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.toolOverride": { "description": "Tool override", "properties": { "description": { "description": "Description of the tool", "type": "string" }, "name": { "description": "Name of the tool", "type": "string" } }, "type": "object" }, "pkg_api_v1.updateRequest": { "description": "Request to update an existing workload (name cannot be changed)", "properties": { "authz_config": { "description": "Authorization configuration", "type": "string" }, "cmd_arguments": { "description": "Command arguments to pass to the container", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "env_vars": { "additionalProperties": { "type": "string" }, "description": "Environment variables to set in the container", "type": "object" }, "group": { "description": "Group name this workload belongs to", "type": "string" }, "header_forward": { "$ref": "#/components/schemas/pkg_api_v1.headerForwardConfig" }, "headers": { "items": { "$ref": "#/components/schemas/registry.Header" }, "type": "array", "uniqueItems": false }, "host": { "description": "Host to bind to", "type": "string" }, "image": { "description": "Docker image to use", "type": "string" }, "network_isolation": { "description": "Whether network isolation is turned on. This applies the rules in the permission profile.", "type": "boolean" }, "oauth_config": { "$ref": "#/components/schemas/pkg_api_v1.remoteOAuthConfig" }, "oidc": { "$ref": "#/components/schemas/pkg_api_v1.oidcOptions" }, "permission_profile": { "$ref": "#/components/schemas/permissions.Profile" }, "proxy_mode": { "description": "Proxy mode to use", "type": "string" }, "proxy_port": { "description": "Port for the HTTP proxy to listen on", "type": "integer" }, "runtime_config": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_container_templates.RuntimeConfig" }, "secrets": { "description": "Secret parameters to inject", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_secrets.SecretParameter" }, "type": "array", "uniqueItems": false }, "target_port": { "description": "Port to expose from the container", "type": "integer" }, "tools": { "description": "Tools filter", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "tools_override": { "additionalProperties": { "$ref": "#/components/schemas/pkg_api_v1.toolOverride" }, "description": "Tools override", "type": "object" }, "transport": { "description": "Transport configuration", "type": "string" }, "trust_proxy_headers": { "description": "Whether to trust X-Forwarded-* headers from reverse proxies", "type": "boolean" }, "url": { "description": "Remote server specific fields", "type": "string" }, "volumes": { "description": "Volume mounts", "items": { "type": "string" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.updateSecretRequest": { "description": "Request to update an existing secret", "properties": { "value": { "description": "New secret value", "type": "string" } }, "type": "object" }, "pkg_api_v1.updateSecretResponse": { "description": "Response after updating a secret", "properties": { "key": { "description": "Secret key that was updated", "type": "string" }, "message": { "description": "Success message", "type": "string" } }, "type": "object" }, "pkg_api_v1.validateSkillRequest": { "description": "Request to validate a skill definition", "properties": { "path": { "description": "Path to the skill definition directory", "type": "string" } }, "type": "object" }, "pkg_api_v1.versionResponse": { "properties": { "version": { "type": "string" } }, "type": "object" }, "pkg_api_v1.workloadListResponse": { "description": "Response containing a list of workloads", "properties": { "workloads": { "description": "List of container information for each workload", "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_core.Workload" }, "type": "array", "uniqueItems": false } }, "type": "object" }, "pkg_api_v1.workloadStatusResponse": { "description": "Response containing workload status information", "properties": { "status": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_container_runtime.WorkloadStatus" } }, "type": "object" }, "registry.EnvVar": { "properties": { "default": { "description": "Default is the value to use if the environment variable is not explicitly provided\nOnly used for non-required variables", "type": "string" }, "description": { "description": "Description is a human-readable explanation of the variable's purpose", "type": "string" }, "name": { "description": "Name is the environment variable name (e.g., API_KEY)", "type": "string" }, "required": { "description": "Required indicates whether this environment variable must be provided\nIf true and not provided via command line or secrets, the user will be prompted for a value", "type": "boolean" }, "secret": { "description": "Secret indicates whether this environment variable contains sensitive information\nIf true, the value will be stored as a secret rather than as a plain environment variable", "type": "boolean" } }, "type": "object" }, "registry.Group": { "properties": { "description": { "description": "Description is a human-readable description of the group's purpose and functionality", "type": "string" }, "name": { "description": "Name is the identifier for the group, used when referencing the group in commands", "type": "string" }, "remote_servers": { "additionalProperties": { "$ref": "#/components/schemas/registry.RemoteServerMetadata" }, "description": "RemoteServers is a map of server names to their corresponding remote server definitions within this group", "type": "object" }, "servers": { "additionalProperties": { "$ref": "#/components/schemas/registry.ImageMetadata" }, "description": "Servers is a map of server names to their corresponding server definitions within this group", "type": "object" } }, "type": "object" }, "registry.Header": { "properties": { "choices": { "description": "Choices provides a list of valid values for the header (optional)", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "default": { "description": "Default is the value to use if the header is not explicitly provided\nOnly used for non-required headers", "type": "string" }, "description": { "description": "Description is a human-readable explanation of the header's purpose", "type": "string" }, "name": { "description": "Name is the header name (e.g., X-API-Key, Authorization)", "type": "string" }, "required": { "description": "Required indicates whether this header must be provided\nIf true and not provided via command line or secrets, the user will be prompted for a value", "type": "boolean" }, "secret": { "description": "Secret indicates whether this header contains sensitive information\nIf true, the value will be stored as a secret rather than as plain text", "type": "boolean" } }, "type": "object" }, "registry.ImageMetadata": { "description": "Container server details (if it's a container server)", "properties": { "args": { "description": "Args are the default command-line arguments to pass to the MCP server container.\nThese arguments will be used only if no command-line arguments are provided by the user.\nIf the user provides arguments, they will override these defaults.", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "custom_metadata": { "additionalProperties": {}, "description": "CustomMetadata allows for additional user-defined metadata", "type": "object" }, "description": { "description": "Description is a human-readable description of the server's purpose and functionality", "type": "string" }, "docker_tags": { "description": "DockerTags lists the available Docker tags for this server image", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "env_vars": { "description": "EnvVars defines environment variables that can be passed to the server", "items": { "$ref": "#/components/schemas/registry.EnvVar" }, "type": "array", "uniqueItems": false }, "image": { "description": "Image is the Docker image reference for the MCP server", "type": "string" }, "metadata": { "$ref": "#/components/schemas/registry.Metadata" }, "name": { "description": "Name is the identifier for the MCP server, used when referencing the server in commands\nIf not provided, it will be auto-generated from the registry key", "type": "string" }, "overview": { "description": "Overview is a longer Markdown-formatted description for web display.\nUnlike the Description field (limited to 500 chars), this supports\nfull Markdown and is intended for rich rendering on catalog pages.", "type": "string" }, "permissions": { "$ref": "#/components/schemas/permissions.Profile" }, "provenance": { "$ref": "#/components/schemas/registry.Provenance" }, "proxy_port": { "description": "ProxyPort is the port for the HTTP proxy to listen on (host port)\nIf not specified, a random available port will be assigned", "type": "integer" }, "repository_url": { "description": "RepositoryURL is the URL to the source code repository for the server", "type": "string" }, "status": { "description": "Status indicates whether the server is currently active or deprecated", "type": "string" }, "tags": { "description": "Tags are categorization labels for the server to aid in discovery and filtering", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "target_port": { "description": "TargetPort is the port for the container to expose (only applicable to SSE and Streamable HTTP transports)", "type": "integer" }, "tier": { "description": "Tier represents the tier classification level of the server, e.g., \"Official\" or \"Community\"", "type": "string" }, "title": { "description": "Title is an optional human-readable display name for the server.\nIf not provided, the Name field is used for display purposes.", "type": "string" }, "tools": { "description": "Tools is a list of tool names provided by this MCP server", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "transport": { "description": "Transport defines the communication protocol for the server\nFor containers: stdio, sse, or streamable-http\nFor remote servers: sse or streamable-http (stdio not supported)", "type": "string" } }, "type": "object" }, "registry.KubernetesMetadata": { "description": "Kubernetes contains Kubernetes-specific metadata when the MCP server is deployed in a cluster.\nThis field is optional and only populated when:\n- The server is served from ToolHive Registry Server\n- The server was auto-discovered from a Kubernetes deployment\n- The Kubernetes resource has the required registry annotations", "properties": { "image": { "description": "Image is the container image used by the Kubernetes workload (applicable to MCPServer)", "type": "string" }, "kind": { "description": "Kind is the Kubernetes resource kind (e.g., MCPServer, VirtualMCPServer, MCPRemoteProxy)", "type": "string" }, "name": { "description": "Name is the Kubernetes resource name", "type": "string" }, "namespace": { "description": "Namespace is the Kubernetes namespace where the resource is deployed", "type": "string" }, "transport": { "description": "Transport is the transport type configured for the Kubernetes workload (applicable to MCPServer)", "type": "string" }, "uid": { "description": "UID is the Kubernetes resource UID", "type": "string" } }, "type": "object" }, "registry.Metadata": { "description": "Metadata contains additional information about the server such as popularity metrics", "properties": { "kubernetes": { "$ref": "#/components/schemas/registry.KubernetesMetadata" }, "last_updated": { "description": "LastUpdated is the timestamp when the server was last updated, in RFC3339 format", "type": "string" }, "stars": { "description": "Stars represents the popularity rating or number of stars for the server", "type": "integer" } }, "type": "object" }, "registry.OAuthConfig": { "description": "OAuthConfig provides OAuth/OIDC configuration for authentication to the remote server\nUsed with the thv proxy command's --remote-auth flags", "properties": { "authorize_url": { "description": "AuthorizeURL is the OAuth authorization endpoint URL\nUsed for non-OIDC OAuth flows when issuer is not provided", "type": "string" }, "callback_port": { "description": "CallbackPort is the specific port to use for the OAuth callback server\nIf not specified, a random available port will be used", "type": "integer" }, "client_id": { "description": "ClientID is the OAuth client ID for authentication", "type": "string" }, "issuer": { "description": "Issuer is the OAuth/OIDC issuer URL (e.g., https://accounts.google.com)\nUsed for OIDC discovery to find authorization and token endpoints", "type": "string" }, "oauth_params": { "additionalProperties": { "type": "string" }, "description": "OAuthParams contains additional OAuth parameters to include in the authorization request\nThese are server-specific parameters like \"prompt\", \"response_mode\", etc.", "type": "object" }, "resource": { "description": "Resource is the OAuth 2.0 resource indicator (RFC 8707)", "type": "string" }, "scopes": { "description": "Scopes are the OAuth scopes to request\nIf not specified, defaults to [\"openid\", \"profile\", \"email\"] for OIDC", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "token_url": { "description": "TokenURL is the OAuth token endpoint URL\nUsed for non-OIDC OAuth flows when issuer is not provided", "type": "string" }, "use_pkce": { "description": "UsePKCE indicates whether to use PKCE for the OAuth flow\nDefaults to true for enhanced security", "type": "boolean" } }, "type": "object" }, "registry.Provenance": { "description": "Provenance contains verification and signing metadata", "properties": { "attestation": { "$ref": "#/components/schemas/registry.VerifiedAttestation" }, "cert_issuer": { "type": "string" }, "repository_ref": { "type": "string" }, "repository_uri": { "type": "string" }, "runner_environment": { "type": "string" }, "signer_identity": { "type": "string" }, "sigstore_url": { "type": "string" } }, "type": "object" }, "registry.RemoteServerMetadata": { "description": "Remote server details (if it's a remote server)", "properties": { "custom_metadata": { "additionalProperties": {}, "description": "CustomMetadata allows for additional user-defined metadata", "type": "object" }, "description": { "description": "Description is a human-readable description of the server's purpose and functionality", "type": "string" }, "env_vars": { "description": "EnvVars defines environment variables that can be passed to configure the client\nThese might be needed for client-side configuration when connecting to the remote server", "items": { "$ref": "#/components/schemas/registry.EnvVar" }, "type": "array", "uniqueItems": false }, "headers": { "description": "Headers defines HTTP headers that can be passed to the remote server for authentication\nThese are used with the thv proxy command's authentication features", "items": { "$ref": "#/components/schemas/registry.Header" }, "type": "array", "uniqueItems": false }, "metadata": { "$ref": "#/components/schemas/registry.Metadata" }, "name": { "description": "Name is the identifier for the MCP server, used when referencing the server in commands\nIf not provided, it will be auto-generated from the registry key", "type": "string" }, "oauth_config": { "$ref": "#/components/schemas/registry.OAuthConfig" }, "overview": { "description": "Overview is a longer Markdown-formatted description for web display.\nUnlike the Description field (limited to 500 chars), this supports\nfull Markdown and is intended for rich rendering on catalog pages.", "type": "string" }, "proxy_port": { "description": "ProxyPort is the port for the HTTP proxy to listen on (host port)\nIf not specified, a random available port will be assigned", "type": "integer" }, "repository_url": { "description": "RepositoryURL is the URL to the source code repository for the server", "type": "string" }, "status": { "description": "Status indicates whether the server is currently active or deprecated", "type": "string" }, "tags": { "description": "Tags are categorization labels for the server to aid in discovery and filtering", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "tier": { "description": "Tier represents the tier classification level of the server, e.g., \"Official\" or \"Community\"", "type": "string" }, "title": { "description": "Title is an optional human-readable display name for the server.\nIf not provided, the Name field is used for display purposes.", "type": "string" }, "tools": { "description": "Tools is a list of tool names provided by this MCP server", "items": { "type": "string" }, "type": "array", "uniqueItems": false }, "transport": { "description": "Transport defines the communication protocol for the server\nFor containers: stdio, sse, or streamable-http\nFor remote servers: sse or streamable-http (stdio not supported)", "type": "string" }, "url": { "description": "URL is the endpoint URL for the remote MCP server (e.g., https://api.example.com/mcp)", "type": "string" } }, "type": "object" }, "registry.VerifiedAttestation": { "properties": { "predicate": {}, "predicate_type": { "type": "string" } }, "type": "object" }, "v1.Duration": { "description": "RefillPeriod is the duration to fully refill the bucket from zero to maxTokens.\nThe effective refill rate is maxTokens / refillPeriod tokens per second.\nFormat: Go duration string (e.g., \"1m0s\", \"30s\", \"1h0m0s\").\n+kubebuilder:validation:Required", "type": "object" } } }, "info": { "description": "This is the ToolHive API server.", "title": "ToolHive API", "version": "1.0" }, "externalDocs": { "description": "", "url": "" }, "paths": { "/api/openapi.json": { "get": { "description": "Returns the OpenAPI specification for the API", "responses": { "200": { "content": { "application/json": { "schema": { "type": "object" } } }, "description": "OpenAPI specification" } }, "summary": "Get OpenAPI specification", "tags": ["system"] } }, "/api/v1beta/clients": { "get": { "description": "List all registered clients in ToolHive", "responses": { "200": { "content": { "application/json": { "schema": { "items": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_client.RegisteredClient" }, "type": "array" } } }, "description": "OK" } }, "summary": "List all clients", "tags": ["clients"] }, "post": { "description": "Register a new client with ToolHive", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.createClientRequest", "summary": "client", "description": "Client to register" } ] } } }, "description": "Client to register", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.createClientResponse" } } }, "description": "OK" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Invalid request or unsupported client type" } }, "summary": "Register a new client", "tags": ["clients"] } }, "/api/v1beta/clients/register": { "post": { "description": "Register multiple clients with ToolHive", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.bulkClientRequest", "summary": "clients", "description": "Clients to register" } ] } } }, "description": "Clients to register", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "items": { "$ref": "#/components/schemas/pkg_api_v1.createClientResponse" }, "type": "array" } } }, "description": "OK" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Invalid request or unsupported client type" } }, "summary": "Register multiple clients", "tags": ["clients"] } }, "/api/v1beta/clients/unregister": { "post": { "description": "Unregister multiple clients from ToolHive", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.bulkClientRequest", "summary": "clients", "description": "Clients to unregister" } ] } } }, "description": "Clients to unregister", "required": true }, "responses": { "204": { "description": "No Content" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Invalid request or unsupported client type" } }, "summary": "Unregister multiple clients", "tags": ["clients"] } }, "/api/v1beta/clients/{name}": { "delete": { "description": "Unregister a client from ToolHive", "parameters": [ { "description": "Client name to unregister", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "No Content" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Invalid request or unsupported client type" } }, "summary": "Unregister a client", "tags": ["clients"] } }, "/api/v1beta/clients/{name}/groups/{group}": { "delete": { "description": "Unregister a client from a specific group in ToolHive", "parameters": [ { "description": "Client name to unregister", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } }, { "description": "Group name to remove client from", "in": "path", "name": "group", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "description": "No Content" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Invalid request or unsupported client type" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Client or group not found" } }, "summary": "Unregister a client from a specific group", "tags": ["clients"] } }, "/api/v1beta/discovery/clients": { "get": { "description": "List all clients compatible with ToolHive and their status.\nEach object includes supports_skills when ToolHive can install skills for that client.", "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.clientStatusResponse" } } }, "description": "OK" } }, "summary": "List all clients status", "tags": ["discovery"] } }, "/api/v1beta/groups": { "get": { "description": "Get a list of all groups", "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.groupListResponse" } } }, "description": "OK" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "List all groups", "tags": ["groups"] }, "post": { "description": "Create a new group with the specified name", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.createGroupRequest", "summary": "group", "description": "Group creation request" } ] } } }, "description": "Group creation request", "required": true }, "responses": { "201": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.createGroupResponse" } } }, "description": "Created" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "409": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Conflict" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Create a new group", "tags": ["groups"] } }, "/api/v1beta/groups/{name}": { "delete": { "description": "Delete a group by name.", "parameters": [ { "description": "Group name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } }, { "description": "Delete all workloads in the group (default: false, moves workloads to default group)", "in": "query", "name": "with-workloads", "schema": { "type": "boolean" } } ], "responses": { "204": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "No Content" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Delete a group", "tags": ["groups"] }, "get": { "description": "Get details of a specific group", "parameters": [ { "description": "Group name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_groups.Group" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Get group details", "tags": ["groups"] } }, "/api/v1beta/registry": { "get": { "description": "Get a list of the current registries", "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.registryListResponse" } } }, "description": "OK" } }, "summary": "List registries", "tags": ["registry"] }, "post": { "description": "Add a new registry", "requestBody": { "content": { "application/json": { "schema": { "type": "object" } } } }, "responses": { "501": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Implemented" } }, "summary": "Add a registry", "tags": ["registry"] } }, "/api/v1beta/registry/auth/login": { "post": { "description": "Trigger an interactive OAuth flow to authenticate with the configured registry. Only available in serve mode.", "responses": { "200": { "content": { "application/json": { "schema": { "additionalProperties": { "type": "string" }, "type": "object" } } }, "description": "Authenticated successfully" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request - Registry OAuth not configured" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Registry login", "tags": ["registry"] } }, "/api/v1beta/registry/auth/logout": { "post": { "description": "Clear cached OAuth tokens for the configured registry. Only available in serve mode.", "responses": { "200": { "content": { "application/json": { "schema": { "additionalProperties": { "type": "string" }, "type": "object" } } }, "description": "Logged out successfully" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request - Registry OAuth not configured" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Registry logout", "tags": ["registry"] } }, "/api/v1beta/registry/{name}": { "delete": { "description": "Remove a specific registry", "parameters": [ { "description": "Registry name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "No Content" }, "403": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Forbidden - blocked by policy" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Remove a registry", "tags": ["registry"] }, "get": { "description": "Get details of a specific registry", "parameters": [ { "description": "Registry name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.getRegistryResponse" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Get a registry", "tags": ["registry"] }, "put": { "description": "Update registry URL or local path for the default registry", "parameters": [ { "description": "Registry name (must be 'default')", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.UpdateRegistryRequest", "summary": "body", "description": "Registry configuration" } ] } } }, "description": "Registry configuration", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.UpdateRegistryResponse" } } }, "description": "OK" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "403": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Forbidden - blocked by policy" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" }, "502": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Gateway - Registry validation failed" }, "504": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Gateway Timeout - Registry unreachable" } }, "summary": "Update registry configuration", "tags": ["registry"] } }, "/api/v1beta/registry/{name}/servers": { "get": { "description": "Get a list of servers in a specific registry", "parameters": [ { "description": "Registry name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.listServersResponse" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "List servers in a registry", "tags": ["registry"] } }, "/api/v1beta/registry/{name}/servers/{serverName}": { "get": { "description": "Get details of a specific server in a registry", "parameters": [ { "description": "Registry name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } }, { "description": "ImageMetadata name", "in": "path", "name": "serverName", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.getServerResponse" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Get a server from a registry", "tags": ["registry"] } }, "/api/v1beta/secrets": { "post": { "description": "Setup the secrets provider with the specified type and configuration.", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.setupSecretsRequest", "summary": "request", "description": "Setup secrets provider request" } ] } } }, "description": "Setup secrets provider request", "required": true }, "responses": { "201": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.setupSecretsResponse" } } }, "description": "Created" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Setup or reconfigure secrets provider", "tags": ["secrets"] } }, "/api/v1beta/secrets/default": { "get": { "description": "Get details of the default secrets provider", "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.getSecretsProviderResponse" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found - Provider not setup" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Get secrets provider details", "tags": ["secrets"] } }, "/api/v1beta/secrets/default/keys": { "get": { "description": "Get a list of all secret keys from the default provider", "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.listSecretsResponse" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found - Provider not setup" }, "405": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Method Not Allowed - Provider doesn't support listing" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "List secrets", "tags": ["secrets"] }, "post": { "description": "Create a new secret in the default provider (encrypted provider only)", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.createSecretRequest", "summary": "request", "description": "Create secret request" } ] } } }, "description": "Create secret request", "required": true }, "responses": { "201": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.createSecretResponse" } } }, "description": "Created" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found - Provider not setup" }, "405": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Method Not Allowed - Provider doesn't support writing" }, "409": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Conflict - Secret already exists" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Create a new secret", "tags": ["secrets"] } }, "/api/v1beta/secrets/default/keys/{key}": { "delete": { "description": "Delete a secret from the default provider (encrypted provider only)", "parameters": [ { "description": "Secret key", "in": "path", "name": "key", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "No Content" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found - Provider not setup or secret not found" }, "405": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Method Not Allowed - Provider doesn't support deletion" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Delete a secret", "tags": ["secrets"] }, "put": { "description": "Update an existing secret in the default provider (encrypted provider only)", "parameters": [ { "description": "Secret key", "in": "path", "name": "key", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.updateSecretRequest", "summary": "request", "description": "Update secret request" } ] } } }, "description": "Update secret request", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.updateSecretResponse" } } }, "description": "OK" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found - Provider not setup or secret not found" }, "405": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Method Not Allowed - Provider doesn't support writing" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Update a secret", "tags": ["secrets"] } }, "/api/v1beta/skills": { "get": { "description": "Get a list of all installed skills", "parameters": [ { "description": "Filter by scope (user or project)", "in": "query", "name": "scope", "schema": { "enum": ["user", "project"], "type": "string" } }, { "description": "Filter by client app", "in": "query", "name": "client", "schema": { "type": "string" } }, { "description": "Filter by project root path", "in": "query", "name": "project_root", "schema": { "type": "string" } }, { "description": "Filter by group name", "in": "query", "name": "group", "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.skillListResponse" } } }, "description": "OK" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "List all installed skills", "tags": ["skills"] }, "post": { "description": "Install a skill from a remote source", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.installSkillRequest", "summary": "request", "description": "Install request" } ] } } }, "description": "Install request", "required": true }, "responses": { "201": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.installSkillResponse" } } }, "description": "Created", "headers": { "Location": { "description": "URI of the installed skill resource", "schema": { "type": "string" } } } }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "409": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Conflict" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Install a skill", "tags": ["skills"] } }, "/api/v1beta/skills/build": { "post": { "description": "Build a skill from a local directory", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.buildSkillRequest", "summary": "request", "description": "Build request" } ] } } }, "description": "Build request", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.BuildResult" } } }, "description": "OK" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Build a skill", "tags": ["skills"] } }, "/api/v1beta/skills/builds": { "get": { "description": "Get a list of all locally-built OCI skill artifacts in the local store", "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.buildListResponse" } } }, "description": "OK" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "List locally-built skill artifacts", "tags": ["skills"] } }, "/api/v1beta/skills/builds/{tag}": { "delete": { "description": "Remove a locally-built OCI skill artifact and its blobs from the local store", "parameters": [ { "description": "Artifact tag", "in": "path", "name": "tag", "required": true, "schema": { "type": "string" } } ], "responses": { "204": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "No Content" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Delete a locally-built skill artifact", "tags": ["skills"] } }, "/api/v1beta/skills/push": { "post": { "description": "Push a built skill artifact to a remote registry", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.pushSkillRequest", "summary": "request", "description": "Push request" } ] } } }, "description": "Push request", "required": true }, "responses": { "204": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "No Content" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Push a skill", "tags": ["skills"] } }, "/api/v1beta/skills/validate": { "post": { "description": "Validate a skill definition", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.validateSkillRequest", "summary": "request", "description": "Validate request" } ] } } }, "description": "Validate request", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.ValidationResult" } } }, "description": "OK" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Validate a skill", "tags": ["skills"] } }, "/api/v1beta/skills/{name}": { "delete": { "description": "Remove an installed skill", "parameters": [ { "description": "Skill name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } }, { "description": "Scope to uninstall from (user or project)", "in": "query", "name": "scope", "schema": { "enum": ["user", "project"], "type": "string" } }, { "description": "Project root path for project-scoped skills", "in": "query", "name": "project_root", "schema": { "type": "string" } } ], "responses": { "204": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "No Content" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Uninstall a skill", "tags": ["skills"] }, "get": { "description": "Get detailed information about a specific skill", "parameters": [ { "description": "Skill name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } }, { "description": "Filter by scope (user or project)", "in": "query", "name": "scope", "schema": { "enum": ["user", "project"], "type": "string" } }, { "description": "Project root path for project-scoped skills", "in": "query", "name": "project_root", "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_skills.SkillInfo" } } }, "description": "OK" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" }, "500": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Internal Server Error" } }, "summary": "Get skill details", "tags": ["skills"] } }, "/api/v1beta/version": { "get": { "description": "Returns the current version of the server", "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.versionResponse" } } }, "description": "OK" } }, "summary": "Get server version", "tags": ["version"] } }, "/api/v1beta/workloads": { "get": { "description": "Get a list of all running workloads, optionally filtered by group", "parameters": [ { "description": "List all workloads, including stopped ones", "in": "query", "name": "all", "schema": { "type": "boolean" } }, { "description": "Filter workloads by group name", "in": "query", "name": "group", "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.workloadListResponse" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Group not found" } }, "summary": "List all workloads", "tags": ["workloads"] }, "post": { "description": "Create and start a new workload", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.createRequest", "summary": "request", "description": "Create workload request" } ] } } }, "description": "Create workload request", "required": true }, "responses": { "201": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.createWorkloadResponse" } } }, "description": "Created" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "409": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Conflict" } }, "summary": "Create a new workload", "tags": ["workloads"] } }, "/api/v1beta/workloads/delete": { "post": { "description": "Delete multiple workloads by name or by group asynchronously.\nReturns 202 Accepted immediately. Deletion happens in the background.", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.bulkOperationRequest", "summary": "request", "description": "Bulk delete request (names or group)" } ] } } }, "description": "Bulk delete request (names or group)", "required": true }, "responses": { "202": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Accepted - deletion started" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" } }, "summary": "Delete workloads in bulk", "tags": ["workloads"] } }, "/api/v1beta/workloads/restart": { "post": { "description": "Restart multiple workloads by name or by group", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.bulkOperationRequest", "summary": "request", "description": "Bulk restart request (names or group)" } ] } } }, "description": "Bulk restart request (names or group)", "required": true }, "responses": { "202": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Accepted" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" } }, "summary": "Restart workloads in bulk", "tags": ["workloads"] } }, "/api/v1beta/workloads/stop": { "post": { "description": "Stop multiple workloads by name or by group", "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.bulkOperationRequest", "summary": "request", "description": "Bulk stop request (names or group)" } ] } } }, "description": "Bulk stop request (names or group)", "required": true }, "responses": { "202": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Accepted" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" } }, "summary": "Stop workloads in bulk", "tags": ["workloads"] } }, "/api/v1beta/workloads/{name}": { "delete": { "description": "Delete a workload asynchronously. Returns 202 Accepted immediately.\nThe deletion happens in the background. Poll the workload list to confirm deletion.", "parameters": [ { "description": "Workload name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "202": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Accepted - deletion started" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Delete a workload", "tags": ["workloads"] }, "get": { "description": "Get details of a specific workload", "parameters": [ { "description": "Workload name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.createRequest" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Get workload details", "tags": ["workloads"] } }, "/api/v1beta/workloads/{name}/edit": { "post": { "description": "Update an existing workload configuration", "parameters": [ { "description": "Workload name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "oneOf": [ { "type": "object" }, { "$ref": "#/components/schemas/pkg_api_v1.updateRequest", "summary": "request", "description": "Update workload request" } ] } } }, "description": "Update workload request", "required": true }, "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.createWorkloadResponse" } } }, "description": "OK" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Update workload", "tags": ["workloads"] } }, "/api/v1beta/workloads/{name}/export": { "get": { "description": "Export a workload's run configuration as JSON", "parameters": [ { "description": "Workload name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/github_com_stacklok_toolhive_pkg_runner.RunConfig" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Export workload configuration", "tags": ["workloads"] } }, "/api/v1beta/workloads/{name}/logs": { "get": { "description": "Retrieve at most 1000 lines of logs for a specific workload by name.", "parameters": [ { "description": "Workload name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "content": { "text/plain": { "schema": { "type": "string" } } }, "description": "Logs for the specified workload" }, "400": { "content": { "text/plain": { "schema": { "type": "string" } } }, "description": "Invalid workload name" }, "404": { "content": { "text/plain": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Get logs for a specific workload", "tags": ["logs"] } }, "/api/v1beta/workloads/{name}/proxy-logs": { "get": { "description": "Retrieve at most 1000 lines of proxy logs for a specific workload by name from the file system.", "parameters": [ { "description": "Workload name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "content": { "text/plain": { "schema": { "type": "string" } } }, "description": "Proxy logs for the specified workload" }, "400": { "content": { "text/plain": { "schema": { "type": "string" } } }, "description": "Invalid workload name" }, "404": { "content": { "text/plain": { "schema": { "type": "string" } } }, "description": "Proxy logs not found for workload" } }, "summary": "Get proxy logs for a specific workload", "tags": ["logs"] } }, "/api/v1beta/workloads/{name}/restart": { "post": { "description": "Restart a running workload", "parameters": [ { "description": "Workload name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "202": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Accepted" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Restart a workload", "tags": ["workloads"] } }, "/api/v1beta/workloads/{name}/status": { "get": { "description": "Get the current status of a specific workload", "parameters": [ { "description": "Workload name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/pkg_api_v1.workloadStatusResponse" } } }, "description": "OK" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Get workload status", "tags": ["workloads"] } }, "/api/v1beta/workloads/{name}/stop": { "post": { "description": "Stop a running workload", "parameters": [ { "description": "Workload name", "in": "path", "name": "name", "required": true, "schema": { "type": "string" } } ], "responses": { "202": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Accepted" }, "400": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Bad Request" }, "404": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "Not Found" } }, "summary": "Stop a workload", "tags": ["workloads"] } }, "/health": { "get": { "description": "Check if the API is healthy", "responses": { "204": { "content": { "application/json": { "schema": { "type": "string" } } }, "description": "No Content" } }, "summary": "Health check", "tags": ["system"] } } }, "openapi": "3.1.0" }