Skip to main content

VirtualMCPServer

VirtualMCPServer (vMCP) aggregates the backend workloads belonging to an MCPGroup into a single endpoint. Clients see one MCP server; the operator handles tool aggregation, conflict resolution, auth, and optional composite tool workflows behind the scenes.

API: toolhive.stacklok.dev/v1alpha1 · Scope: Namespaced · Short names: vmcp, virtualmcp

Example

virtualmcpserver.yaml
apiVersion: toolhive.stacklok.dev/v1alpha1
kind: VirtualMCPServer
metadata:
name: my-virtualmcpserver
namespace: default
spec:
groupRef:
name: <string>
incomingAuth:
type: anonymous

Schema

spec

VirtualMCPServerSpec defines the desired state of VirtualMCPServer

FieldTypeDescription
authServerConfigobject

AuthServerConfig configures an embedded OAuth authorization server. When set, the vMCP server acts as an OIDC issuer, drives users through upstream IDPs, and issues ToolHive JWTs. The embedded AS becomes the IncomingAuth OIDC provider — its issuer must match IncomingAuth.OIDCConfigRef so that tokens it issues are accepted by the vMCP's incoming auth middleware. When nil, IncomingAuth uses an external IDP and behavior is unchanged.

configobject

Config is the Virtual MCP server configuration. The audit config from here is also supported, but not required.

embeddingServerRefobject

EmbeddingServerRef references an existing EmbeddingServer resource by name. When the optimizer is enabled, this field is required to point to a ready EmbeddingServer that provides embedding capabilities. The referenced EmbeddingServer must exist in the same namespace and be ready.

groupRefrequiredobject

GroupRef references the MCPGroup that defines backend workloads. The referenced MCPGroup must exist in the same namespace.

incomingAuthrequiredobject

IncomingAuth configures authentication for clients connecting to the Virtual MCP server. Must be explicitly set - use "anonymous" type when no authentication is required. This field takes precedence over config.IncomingAuth and should be preferred because it supports Kubernetes-native secret references (SecretKeyRef, ConfigMapRef) for secure dynamic discovery of credentials, rather than requiring secrets to be embedded in config.

outgoingAuthobject

OutgoingAuth configures authentication from Virtual MCP to backend MCPServers. This field takes precedence over config.OutgoingAuth and should be preferred because it supports Kubernetes-native secret references (SecretKeyRef, ConfigMapRef) for secure dynamic discovery of credentials, rather than requiring secrets to be embedded in config.

podTemplateSpecobject

PodTemplateSpec defines the pod template to use for the Virtual MCP server This allows for customizing the pod configuration beyond what is provided by the other fields. Note that to modify the specific container the Virtual MCP server runs in, you must specify the 'vmcp' container name in the PodTemplateSpec. This field accepts a PodTemplateSpec object as JSON/YAML.

replicasinteger

Replicas is the desired number of vMCP pod replicas. VirtualMCPServer creates a single Deployment for the vMCP aggregator process, so there is only one replicas field (unlike MCPServer which has separate Replicas and BackendReplicas for its two Deployments). When nil, the operator does not set Deployment.Spec.Replicas, leaving replica management to an HPA or other external controller.


format int32 · min 0
serviceAccountstring

ServiceAccount is the name of an already existing service account to use by the Virtual MCP server. If not specified, a ServiceAccount will be created automatically and used by the Virtual MCP server.

serviceTypestring

ServiceType specifies the Kubernetes service type for the Virtual MCP server


default "ClusterIP" · enum: ClusterIP | NodePort | LoadBalancer
sessionAffinitystring

SessionAffinity controls whether the Service routes repeated client connections to the same pod. MCP protocols (SSE, streamable-http) are stateful, so ClientIP is the default. Set to "None" for stateless servers or when using an external load balancer with its own affinity.


default "ClientIP" · enum: ClientIP | None
sessionStorageobject

SessionStorage configures session storage for stateful horizontal scaling. When nil, no session storage is configured.

telemetryConfigRefobject

TelemetryConfigRef references an MCPTelemetryConfig resource for shared telemetry configuration. The referenced MCPTelemetryConfig must exist in the same namespace as this VirtualMCPServer. Cross-namespace references are not supported for security and isolation reasons.

spec.authServerConfig

AuthServerConfig configures an embedded OAuth authorization server. When set, the vMCP server acts as an OIDC issuer, drives users through upstream IDPs, and issues ToolHive JWTs. The embedded AS becomes the IncomingAuth OIDC provider — its issuer must match IncomingAuth.OIDCConfigRef so that tokens it issues are accepted by the vMCP's incoming auth middleware. When nil, IncomingAuth uses an external IDP and behavior is unchanged.

FieldTypeDescription
authorizationEndpointBaseUrlstring

AuthorizationEndpointBaseURL overrides the base URL used for the authorization_endpoint in the OAuth discovery document. When set, the discovery document will advertise `{authorizationEndpointBaseUrl}/oauth/authorize` instead of `{issuer}/oauth/authorize`. All other endpoints (token, registration, JWKS) remain derived from the issuer. This is useful when the browser-facing authorization endpoint needs to be on a different host than the issuer used for backend-to-backend calls. Must be a valid HTTPS URL (or HTTP for localhost) without query, fragment, or trailing slash.


pattern ^https?://[^\s?#]+[^/\s?#]$
hmacSecretRefsobject[]

HMACSecretRefs references Kubernetes Secrets containing symmetric secrets for signing authorization codes and refresh tokens (opaque tokens). Current secret must be at least 32 bytes and cryptographically random. Supports secret rotation via multiple entries (first is current, rest are for verification). If not specified, an ephemeral secret will be auto-generated (development only - auth codes and refresh tokens will be invalid after restart).

issuerrequiredstring

Issuer is the issuer identifier for this authorization server. This will be included in the "iss" claim of issued tokens. Must be a valid HTTPS URL (or HTTP for localhost) without query, fragment, or trailing slash (per RFC 8414).


pattern ^https?://[^\s?#]+[^/\s?#]$
signingKeySecretRefsobject[]

SigningKeySecretRefs references Kubernetes Secrets containing signing keys for JWT operations. Supports key rotation by allowing multiple keys (oldest keys are used for verification only). If not specified, an ephemeral signing key will be auto-generated (development only - JWTs will be invalid after restart).

storageobject

Storage configures the storage backend for the embedded auth server. If not specified, defaults to in-memory storage.

tokenLifespansobject

TokenLifespans configures the duration that various tokens are valid. If not specified, defaults are applied (access: 1h, refresh: 7d, authCode: 10m).

upstreamProvidersrequiredobject[]

UpstreamProviders configures connections to upstream Identity Providers. The embedded auth server delegates authentication to these providers. MCPServer and MCPRemoteProxy support a single upstream; VirtualMCPServer supports multiple.

spec.authServerConfig.hmacSecretRefs[]

HMACSecretRefs references Kubernetes Secrets containing symmetric secrets for signing authorization codes and refresh tokens (opaque tokens). Current secret must be at least 32 bytes and cryptographically random. Supports secret rotation via multiple entries (first is current, rest are for verification). If not specified, an ephemeral secret will be auto-generated (development only - auth codes and refresh tokens will be invalid after restart).

FieldTypeDescription
keyrequiredstring

Key is the key within the secret

namerequiredstring

Name is the name of the secret

spec.authServerConfig.signingKeySecretRefs[]

SigningKeySecretRefs references Kubernetes Secrets containing signing keys for JWT operations. Supports key rotation by allowing multiple keys (oldest keys are used for verification only). If not specified, an ephemeral signing key will be auto-generated (development only - JWTs will be invalid after restart).

FieldTypeDescription
keyrequiredstring

Key is the key within the secret

namerequiredstring

Name is the name of the secret

spec.authServerConfig.storage

Storage configures the storage backend for the embedded auth server. If not specified, defaults to in-memory storage.

FieldTypeDescription
redisobject

Redis configures the Redis storage backend. Required when type is "redis".

typestring

Type specifies the storage backend type. Valid values: "memory" (default), "redis".


default "memory" · enum: memory | redis
spec.authServerConfig.storage.redis

Redis configures the Redis storage backend. Required when type is "redis".

FieldTypeDescription
aclUserConfigrequiredobject

ACLUserConfig configures Redis ACL user authentication.

dialTimeoutstring

DialTimeout is the timeout for establishing connections. Format: Go duration string (e.g., "5s", "1m").


default "5s" · pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
readTimeoutstring

ReadTimeout is the timeout for socket reads. Format: Go duration string (e.g., "3s", "1m").


default "3s" · pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
sentinelConfigrequiredobject

SentinelConfig holds Redis Sentinel configuration.

sentinelTlsobject

SentinelTLS configures TLS for connections to Sentinel instances. Presence of this field enables TLS. Omit to use plaintext. When omitted, sentinel connections use plaintext (no fallback to TLS config).

tlsobject

TLS configures TLS for connections to the Redis/Valkey master. Presence of this field enables TLS. Omit to use plaintext.

writeTimeoutstring

WriteTimeout is the timeout for socket writes. Format: Go duration string (e.g., "3s", "1m").


default "3s" · pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
spec.authServerConfig.storage.redis.aclUserConfig

ACLUserConfig configures Redis ACL user authentication.

FieldTypeDescription
passwordSecretRefrequiredobject

PasswordSecretRef references a Secret containing the Redis ACL password.

usernameSecretRefrequiredobject

UsernameSecretRef references a Secret containing the Redis ACL username.

spec.authServerConfig.storage.redis.aclUserConfig.passwordSecretRef

PasswordSecretRef references a Secret containing the Redis ACL password.

FieldTypeDescription
keyrequiredstring

Key is the key within the secret

namerequiredstring

Name is the name of the secret

spec.authServerConfig.storage.redis.aclUserConfig.usernameSecretRef

UsernameSecretRef references a Secret containing the Redis ACL username.

FieldTypeDescription
keyrequiredstring

Key is the key within the secret

namerequiredstring

Name is the name of the secret

spec.authServerConfig.storage.redis.sentinelConfig

SentinelConfig holds Redis Sentinel configuration.

FieldTypeDescription
dbinteger

DB is the Redis database number.


default 0 · format int32
masterNamerequiredstring

MasterName is the name of the Redis master monitored by Sentinel.

sentinelAddrsstring[]

SentinelAddrs is a list of Sentinel host:port addresses. Mutually exclusive with SentinelService.

sentinelServiceobject

SentinelService enables automatic discovery from a Kubernetes Service. Mutually exclusive with SentinelAddrs.

spec.authServerConfig.storage.redis.sentinelConfig.sentinelService

SentinelService enables automatic discovery from a Kubernetes Service. Mutually exclusive with SentinelAddrs.

FieldTypeDescription
namerequiredstring

Name of the Sentinel Service.

namespacestring

Namespace of the Sentinel Service (defaults to same namespace).

portinteger

Port of the Sentinel service.


default 26379 · format int32
spec.authServerConfig.storage.redis.sentinelTls

SentinelTLS configures TLS for connections to Sentinel instances. Presence of this field enables TLS. Omit to use plaintext. When omitted, sentinel connections use plaintext (no fallback to TLS config).

FieldTypeDescription
caCertSecretRefobject

CACertSecretRef references a Secret containing a PEM-encoded CA certificate for verifying the server. When not specified, system root CAs are used.

insecureSkipVerifyboolean

InsecureSkipVerify skips TLS certificate verification. Use when connecting to services with self-signed certificates.

spec.authServerConfig.storage.redis.sentinelTls.caCertSecretRef

CACertSecretRef references a Secret containing a PEM-encoded CA certificate for verifying the server. When not specified, system root CAs are used.

FieldTypeDescription
keyrequiredstring

Key is the key within the secret

namerequiredstring

Name is the name of the secret

spec.authServerConfig.storage.redis.tls

TLS configures TLS for connections to the Redis/Valkey master. Presence of this field enables TLS. Omit to use plaintext.

FieldTypeDescription
caCertSecretRefobject

CACertSecretRef references a Secret containing a PEM-encoded CA certificate for verifying the server. When not specified, system root CAs are used.

insecureSkipVerifyboolean

InsecureSkipVerify skips TLS certificate verification. Use when connecting to services with self-signed certificates.

spec.authServerConfig.storage.redis.tls.caCertSecretRef

CACertSecretRef references a Secret containing a PEM-encoded CA certificate for verifying the server. When not specified, system root CAs are used.

FieldTypeDescription
keyrequiredstring

Key is the key within the secret

namerequiredstring

Name is the name of the secret

spec.authServerConfig.tokenLifespans

TokenLifespans configures the duration that various tokens are valid. If not specified, defaults are applied (access: 1h, refresh: 7d, authCode: 10m).

FieldTypeDescription
accessTokenLifespanstring

AccessTokenLifespan is the duration that access tokens are valid. Format: Go duration string (e.g., "1h", "30m", "24h"). If empty, defaults to 1 hour.


pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
authCodeLifespanstring

AuthCodeLifespan is the duration that authorization codes are valid. Format: Go duration string (e.g., "10m", "5m"). If empty, defaults to 10 minutes.


pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
refreshTokenLifespanstring

RefreshTokenLifespan is the duration that refresh tokens are valid. Format: Go duration string (e.g., "168h", "7d" as "168h"). If empty, defaults to 7 days (168h).


pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
spec.authServerConfig.upstreamProviders[]

UpstreamProviders configures connections to upstream Identity Providers. The embedded auth server delegates authentication to these providers. MCPServer and MCPRemoteProxy support a single upstream; VirtualMCPServer supports multiple.

FieldTypeDescription
namerequiredstring

Name uniquely identifies this upstream provider. Used for routing decisions and session binding in multi-upstream scenarios. Must be lowercase alphanumeric with hyphens (DNS-label-like).


pattern ^[a-z0-9]([a-z0-9-]*[a-z0-9])?$ · minLength 1 · maxLength 63
oauth2Configobject

OAuth2Config contains OAuth 2.0-specific configuration. Required when Type is "oauth2", must be nil when Type is "oidc".

oidcConfigobject

OIDCConfig contains OIDC-specific configuration. Required when Type is "oidc", must be nil when Type is "oauth2".

typerequiredstring

Type specifies the provider type: "oidc" or "oauth2"


enum: oidc | oauth2
spec.authServerConfig.upstreamProviders.oauth2Config

OAuth2Config contains OAuth 2.0-specific configuration. Required when Type is "oauth2", must be nil when Type is "oidc".

FieldTypeDescription
authorizationEndpointrequiredstring

AuthorizationEndpoint is the URL for the OAuth authorization endpoint.


pattern ^https?://.*$
clientIdrequiredstring

ClientID is the OAuth 2.0 client identifier registered with the upstream IDP.

clientSecretRefobject

ClientSecretRef references a Kubernetes Secret containing the OAuth 2.0 client secret. Optional for public clients using PKCE instead of client secret.

redirectUristring

RedirectURI is the callback URL where the upstream IDP will redirect after authentication. When not specified, defaults to `{resourceUrl}/oauth/callback` where `resourceUrl` is the URL associated with the resource (e.g., MCPServer or vMCP) using this config.

scopesstring[]

Scopes are the OAuth scopes to request from the upstream IDP.

tokenEndpointrequiredstring

TokenEndpoint is the URL for the OAuth token endpoint.


pattern ^https?://.*$
tokenResponseMappingobject

TokenResponseMapping configures custom field extraction from non-standard token responses. Some OAuth providers (e.g., GovSlack) nest token fields under non-standard paths instead of returning them at the top level. When set, ToolHive performs the token exchange HTTP call directly and extracts fields using the configured dot-notation paths. If nil, standard OAuth 2.0 token response parsing is used.

userInforequiredobject

UserInfo contains configuration for fetching user information from the upstream provider. Required for OAuth2 providers to resolve user identity.

spec.authServerConfig.upstreamProviders.oauth2Config.clientSecretRef

ClientSecretRef references a Kubernetes Secret containing the OAuth 2.0 client secret. Optional for public clients using PKCE instead of client secret.

FieldTypeDescription
keyrequiredstring

Key is the key within the secret

namerequiredstring

Name is the name of the secret

spec.authServerConfig.upstreamProviders.oauth2Config.tokenResponseMapping

TokenResponseMapping configures custom field extraction from non-standard token responses. Some OAuth providers (e.g., GovSlack) nest token fields under non-standard paths instead of returning them at the top level. When set, ToolHive performs the token exchange HTTP call directly and extracts fields using the configured dot-notation paths. If nil, standard OAuth 2.0 token response parsing is used.

FieldTypeDescription
accessTokenPathrequiredstring

AccessTokenPath is the dot-notation path to the access token in the response. Example: "authed_user.access_token"


minLength 1
expiresInPathstring

ExpiresInPath is the dot-notation path to the expires_in value (in seconds). If not specified, defaults to "expires_in".

refreshTokenPathstring

RefreshTokenPath is the dot-notation path to the refresh token in the response. If not specified, defaults to "refresh_token".

scopePathstring

ScopePath is the dot-notation path to the scope string in the response. If not specified, defaults to "scope".

spec.authServerConfig.upstreamProviders.oauth2Config.userInfo

UserInfo contains configuration for fetching user information from the upstream provider. Required for OAuth2 providers to resolve user identity.

FieldTypeDescription
additionalHeadersmap<string, string>

AdditionalHeaders contains extra headers to include in the userinfo request. Useful for providers that require specific headers (e.g., GitHub's Accept header).

endpointUrlrequiredstring

EndpointURL is the URL of the userinfo endpoint.


pattern ^https?://.*$
fieldMappingobject

FieldMapping contains custom field mapping configuration for non-standard providers. If nil, standard OIDC field names are used ("sub", "name", "email").

httpMethodstring

HTTPMethod is the HTTP method to use for the userinfo request. If not specified, defaults to GET.


enum: GET | POST
spec.authServerConfig.upstreamProviders.oauth2Config.userInfo.fieldMapping

FieldMapping contains custom field mapping configuration for non-standard providers. If nil, standard OIDC field names are used ("sub", "name", "email").

FieldTypeDescription
emailFieldsstring[]

EmailFields is an ordered list of field names to try for the email address. The first non-empty value found will be used. Default: ["email"]

nameFieldsstring[]

NameFields is an ordered list of field names to try for the display name. The first non-empty value found will be used. Default: ["name"]

subjectFieldsstring[]

SubjectFields is an ordered list of field names to try for the user ID. The first non-empty value found will be used. Default: ["sub"]

spec.authServerConfig.upstreamProviders.oidcConfig

OIDCConfig contains OIDC-specific configuration. Required when Type is "oidc", must be nil when Type is "oauth2".

FieldTypeDescription
clientIdrequiredstring

ClientID is the OAuth 2.0 client identifier registered with the upstream IDP.

clientSecretRefobject

ClientSecretRef references a Kubernetes Secret containing the OAuth 2.0 client secret. Optional for public clients using PKCE instead of client secret.

issuerUrlrequiredstring

IssuerURL is the OIDC issuer URL for automatic endpoint discovery. Must be a valid HTTPS URL.


pattern ^https://.*$
redirectUristring

RedirectURI is the callback URL where the upstream IDP will redirect after authentication. When not specified, defaults to `{resourceUrl}/oauth/callback` where `resourceUrl` is the URL associated with the resource (e.g., MCPServer or vMCP) using this config.

scopesstring[]

Scopes are the OAuth scopes to request from the upstream IDP. If not specified, defaults to ["openid", "offline_access"].

userInfoOverrideobject

UserInfoOverride allows customizing UserInfo fetching behavior for OIDC providers. By default, the UserInfo endpoint is discovered automatically via OIDC discovery. Use this to override the endpoint URL, HTTP method, or field mappings for providers that return non-standard claim names in their UserInfo response.

spec.authServerConfig.upstreamProviders.oidcConfig.clientSecretRef

ClientSecretRef references a Kubernetes Secret containing the OAuth 2.0 client secret. Optional for public clients using PKCE instead of client secret.

FieldTypeDescription
keyrequiredstring

Key is the key within the secret

namerequiredstring

Name is the name of the secret

spec.authServerConfig.upstreamProviders.oidcConfig.userInfoOverride

UserInfoOverride allows customizing UserInfo fetching behavior for OIDC providers. By default, the UserInfo endpoint is discovered automatically via OIDC discovery. Use this to override the endpoint URL, HTTP method, or field mappings for providers that return non-standard claim names in their UserInfo response.

FieldTypeDescription
additionalHeadersmap<string, string>

AdditionalHeaders contains extra headers to include in the userinfo request. Useful for providers that require specific headers (e.g., GitHub's Accept header).

endpointUrlrequiredstring

EndpointURL is the URL of the userinfo endpoint.


pattern ^https?://.*$
fieldMappingobject

FieldMapping contains custom field mapping configuration for non-standard providers. If nil, standard OIDC field names are used ("sub", "name", "email").

httpMethodstring

HTTPMethod is the HTTP method to use for the userinfo request. If not specified, defaults to GET.


enum: GET | POST
spec.authServerConfig.upstreamProviders.oidcConfig.userInfoOverride.fieldMapping

FieldMapping contains custom field mapping configuration for non-standard providers. If nil, standard OIDC field names are used ("sub", "name", "email").

FieldTypeDescription
emailFieldsstring[]

EmailFields is an ordered list of field names to try for the email address. The first non-empty value found will be used. Default: ["email"]

nameFieldsstring[]

NameFields is an ordered list of field names to try for the display name. The first non-empty value found will be used. Default: ["name"]

subjectFieldsstring[]

SubjectFields is an ordered list of field names to try for the user ID. The first non-empty value found will be used. Default: ["sub"]

spec.config

Config is the Virtual MCP server configuration. The audit config from here is also supported, but not required.

FieldTypeDescription
aggregationobject

Aggregation defines tool aggregation and conflict resolution strategies. Supports ToolConfigRef for Kubernetes-native MCPToolConfig resource references.

auditobject

Audit configures audit logging for the Virtual MCP server. When present, audit logs include MCP protocol operations. See audit.Config for available configuration options.

backendsobject[]

Backends defines pre-configured backend servers for static mode. When OutgoingAuth.Source is "inline", this field contains the full list of backend servers with their URLs and transport types, eliminating the need for K8s API access. When OutgoingAuth.Source is "discovered", this field is empty and backends are discovered at runtime via Kubernetes API.

compositeToolRefsobject[]

CompositeToolRefs references VirtualMCPCompositeToolDefinition resources for complex, reusable workflows. Only applicable when running in Kubernetes. Referenced resources must be in the same namespace as the VirtualMCPServer.

compositeToolsobject[]

CompositeTools defines inline composite tool workflows. Full workflow definitions are embedded in the configuration. For Kubernetes, complex workflows can also reference VirtualMCPCompositeToolDefinition CRDs.

groupRefstring

Group references an existing MCPGroup that defines backend workloads. In standalone CLI mode, this is set from the YAML config file. In Kubernetes, the operator populates this from spec.groupRef during conversion.

incomingAuthobject

IncomingAuth configures how clients authenticate to the virtual MCP server. When using the Kubernetes operator, this is populated by the converter from VirtualMCPServerSpec.IncomingAuth and any values set here will be superseded.

metadatamap<string, string>

Metadata stores additional configuration metadata.

namestring

Name is the virtual MCP server name.

operationalobject

Operational configures operational settings.

optimizerobject

Optimizer configures the MCP optimizer for context optimization on large toolsets. When enabled, vMCP exposes only find_tool and call_tool operations to clients instead of all backend tools directly. This reduces token usage by allowing LLMs to discover relevant tools on demand rather than receiving all tool definitions.

outgoingAuthobject

OutgoingAuth configures how the virtual MCP server authenticates to backends. When using the Kubernetes operator, this is populated by the converter from VirtualMCPServerSpec.OutgoingAuth and any values set here will be superseded.

sessionStorageobject

SessionStorage configures session storage for stateful horizontal scaling. When provider is "redis", the operator injects Redis connection parameters (address, db, keyPrefix) here. The Redis password is provided separately via the THV_SESSION_REDIS_PASSWORD environment variable.

telemetryobject

Telemetry configures OpenTelemetry-based observability for the Virtual MCP server including distributed tracing, OTLP metrics export, and Prometheus metrics endpoint. Deprecated (Kubernetes operator only): When deploying via the operator, use VirtualMCPServer.spec.telemetryConfigRef to reference a shared MCPTelemetryConfig resource instead. This field remains valid for standalone (non-operator) deployments.

spec.config.aggregation

Aggregation defines tool aggregation and conflict resolution strategies. Supports ToolConfigRef for Kubernetes-native MCPToolConfig resource references.

FieldTypeDescription
conflictResolutionstring

ConflictResolution defines the strategy for resolving tool name conflicts. - prefix: Automatically prefix tool names with workload identifier - priority: First workload in priority order wins - manual: Explicitly define overrides for all conflicts


default "prefix" · enum: prefix | priority | manual
conflictResolutionConfigobject

ConflictResolutionConfig provides configuration for the chosen strategy.

excludeAllToolsboolean

ExcludeAllTools hides all backend tools from MCP clients when true. Hidden tools are NOT advertised in tools/list responses, but they ARE available in the routing table for composite tools to use. This enables the use case where you want to hide raw backend tools from direct client access while exposing curated composite tool workflows.

toolsobject[]

Tools defines per-workload tool filtering and overrides.

spec.config.aggregation.conflictResolutionConfig

ConflictResolutionConfig provides configuration for the chosen strategy.

FieldTypeDescription
prefixFormatstring

PrefixFormat defines the prefix format for the "prefix" strategy. Supports placeholders: {workload}, {workload}_, {workload}.


default "{workload}_"
priorityOrderstring[]

PriorityOrder defines the workload priority order for the "priority" strategy.

spec.config.aggregation.tools[]

Tools defines per-workload tool filtering and overrides.

FieldTypeDescription
excludeAllboolean

ExcludeAll hides all tools from this workload from MCP clients when true. Hidden tools are NOT advertised in tools/list responses, but they ARE available in the routing table for composite tools to use. This enables the use case where you want to hide raw backend tools from direct client access while exposing curated composite tool workflows.

filterstring[]

Filter is an allow-list of tool names to advertise to MCP clients. Tools NOT in this list are hidden from clients (not in tools/list response) but remain available in the routing table for composite tools to use. This enables selective exposure of backend tools while allowing composite workflows to orchestrate all backend capabilities. Only used if ToolConfigRef is not specified.

overridesmap<string, object>

Overrides is an inline map of tool overrides for renaming and description changes. Overrides are applied to tools before conflict resolution and affect both advertising and routing (the overridden name is used everywhere). Only used if ToolConfigRef is not specified.

toolConfigRefobject

ToolConfigRef references an MCPToolConfig resource for tool filtering and renaming. If specified, Filter and Overrides are ignored. Only used when running in Kubernetes with the operator.

workloadrequiredstring

Workload is the name of the backend MCPServer workload.

spec.config.aggregation.tools.overrides

Overrides is an inline map of tool overrides for renaming and description changes. Overrides are applied to tools before conflict resolution and affect both advertising and routing (the overridden name is used everywhere). Only used if ToolConfigRef is not specified.

FieldTypeDescription
annotationsobject

Annotations overrides specific tool annotation fields. Only specified fields are overridden; others pass through from the backend.

descriptionstring

Description is the new tool description.

namestring

Name is the new tool name (for renaming).

spec.config.aggregation.tools.overrides.annotations

Annotations overrides specific tool annotation fields. Only specified fields are overridden; others pass through from the backend.

<CRDFields>: no object at path "spec.config.aggregation.tools.overrides.annotations" in VirtualMCPServer.
spec.config.aggregation.tools.toolConfigRef

ToolConfigRef references an MCPToolConfig resource for tool filtering and renaming. If specified, Filter and Overrides are ignored. Only used when running in Kubernetes with the operator.

FieldTypeDescription
namerequiredstring

Name is the name of the MCPToolConfig resource in the same namespace.

spec.config.audit

Audit configures audit logging for the Virtual MCP server. When present, audit logs include MCP protocol operations. See audit.Config for available configuration options.

FieldTypeDescription
componentstring

Component is the component name to use in audit events.

enabledboolean

Enabled controls whether audit logging is enabled. When true, enables audit logging with the configured options.


default false
eventTypesstring[]

EventTypes specifies which event types to audit. If empty, all events are audited.

excludeEventTypesstring[]

ExcludeEventTypes specifies which event types to exclude from auditing. This takes precedence over EventTypes.

includeRequestDataboolean

IncludeRequestData determines whether to include request data in audit logs.


default false
includeResponseDataboolean

IncludeResponseData determines whether to include response data in audit logs.


default false
logFilestring

LogFile specifies the file path for audit logs. If empty, logs to stdout.

maxDataSizeinteger

MaxDataSize limits the size of request/response data included in audit logs (in bytes).


default 1024
spec.config.backends[]

Backends defines pre-configured backend servers for static mode. When OutgoingAuth.Source is "inline", this field contains the full list of backend servers with their URLs and transport types, eliminating the need for K8s API access. When OutgoingAuth.Source is "discovered", this field is empty and backends are discovered at runtime via Kubernetes API.

FieldTypeDescription
caBundlePathstring

CABundlePath is the file path to a custom CA certificate bundle for TLS verification. Only valid when Type is "entry". The operator mounts CA bundles at /etc/toolhive/ca-bundles/<name>/ca.crt.

metadatamap<string, string>

Metadata is a custom key-value map for storing additional backend information such as labels, tags, or other arbitrary data (e.g., "env": "prod", "region": "us-east-1"). This is NOT Kubernetes ObjectMeta - it's a simple string map for user-defined metadata. Reserved keys: "group" is automatically set by vMCP and any user-provided value will be overridden.

namerequiredstring

Name is the backend identifier. Must match the backend name from the MCPGroup for auth config resolution.

transportrequiredstring

Transport is the MCP transport protocol: "sse" or "streamable-http" Only network transports supported by vMCP client are allowed.


enum: sse | streamable-http
typestring

Type is the backend workload type: "entry" for MCPServerEntry backends, or empty for container/proxy backends. Entry backends connect directly to remote MCP servers.


enum: entry |
urlrequiredstring

URL is the backend's MCP server base URL.


pattern ^https?://
spec.config.compositeToolRefs[]

CompositeToolRefs references VirtualMCPCompositeToolDefinition resources for complex, reusable workflows. Only applicable when running in Kubernetes. Referenced resources must be in the same namespace as the VirtualMCPServer.

FieldTypeDescription
namerequiredstring

Name is the name of the VirtualMCPCompositeToolDefinition resource in the same namespace.

spec.config.compositeTools[]

CompositeTools defines inline composite tool workflows. Full workflow definitions are embedded in the configuration. For Kubernetes, complex workflows can also reference VirtualMCPCompositeToolDefinition CRDs.

FieldTypeDescription
descriptionstring

Description describes what the workflow does.

namerequiredstring

Name is the workflow name (unique identifier).

outputobject

Output defines the structured output schema for this workflow. If not specified, the workflow returns the last step's output (backward compatible).

parametersobject

Parameters defines input parameter schema in JSON Schema format. Should be a JSON Schema object with "type": "object" and "properties". Example: { "type": "object", "properties": { "param1": {"type": "string", "default": "value"}, "param2": {"type": "integer"} }, "required": ["param2"] } We use json.Map rather than a typed struct because JSON Schema is highly flexible with many optional fields (default, enum, minimum, maximum, pattern, items, additionalProperties, oneOf, anyOf, allOf, etc.). Using json.Map allows full JSON Schema compatibility without needing to define every possible field, and matches how the MCP SDK handles inputSchema.

stepsrequiredobject[]

Steps are the workflow steps to execute.

timeoutstring

Timeout is the maximum workflow execution time.


pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
spec.config.compositeTools.output

Output defines the structured output schema for this workflow. If not specified, the workflow returns the last step's output (backward compatible).

FieldTypeDescription
propertiesrequiredmap<string, object>

Properties defines the output properties. Map key is the property name, value is the property definition.

requiredstring[]

Required lists property names that must be present in the output.

spec.config.compositeTools.output.properties

Properties defines the output properties. Map key is the property name, value is the property definition.

FieldTypeDescription
default

Default is the fallback value if template expansion fails. Type coercion is applied to match the declared Type.

descriptionstring

Description is a human-readable description exposed to clients and models

propertiesobject

Properties defines nested properties for object types. Each nested property has full metadata (type, description, value/properties).

typestring

Type is the JSON Schema type: "string", "integer", "number", "boolean", "object", "array"


enum: string | integer | number | boolean | object | array
valuestring

Value is a template string for constructing the runtime value. For object types, this can be a JSON string that will be deserialized. Supports template syntax: {{.steps.step_id.output.field}}, {{.params.param_name}}

spec.config.compositeTools.steps[]

Steps are the workflow steps to execute.

FieldTypeDescription
argumentsobject

Arguments is a map of argument values with template expansion support. Supports Go template syntax with .params and .steps for string values. Non-string values (integers, booleans, arrays, objects) are passed as-is. Note: the templating is only supported on the first level of the key-value pairs.

collectionstring

Collection is a Go template expression that resolves to a JSON array or a slice. Only used when Type is "forEach".

conditionstring

Condition is a template expression that determines if the step should execute

defaultResults

DefaultResults provides fallback output values when this step is skipped (due to condition evaluating to false) or fails (when onError.action is "continue"). Each key corresponds to an output field name referenced by downstream steps. Required if the step may be skipped AND downstream steps reference this step's output.

dependsOnstring[]

DependsOn lists step IDs that must complete before this step

idrequiredstring

ID is the unique identifier for this step.

itemVarstring

ItemVar is the variable name used to reference the current item in forEach templates. Defaults to "item" if not specified. Only used when Type is "forEach".

maxIterationsinteger

MaxIterations limits the number of items that can be iterated over. Defaults to 100, hard cap at 1000. Only used when Type is "forEach".

maxParallelinteger

MaxParallel limits the number of concurrent iterations in a forEach step. Defaults to the DAG executor's maxParallel (10). Only used when Type is "forEach".

messagestring

Message is the elicitation message Only used when Type is "elicitation"

onCancelobject

OnCancel defines the action to take when the user cancels/dismisses the elicitation Only used when Type is "elicitation"

onDeclineobject

OnDecline defines the action to take when the user explicitly declines the elicitation Only used when Type is "elicitation"

onErrorobject

OnError defines error handling behavior

schemaobject

Schema defines the expected response schema for elicitation

stepobject

InnerStep defines the step to execute for each item in the collection. Only used when Type is "forEach". Only tool-type inner steps are supported.

timeoutstring

Timeout is the maximum execution time for this step


pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
toolstring

Tool is the tool to call (format: "workload.tool_name") Only used when Type is "tool"

typestring

Type is the step type (tool, elicitation, etc.)


default "tool" · enum: tool | elicitation | forEach
spec.config.compositeTools.steps.onCancel

OnCancel defines the action to take when the user cancels/dismisses the elicitation Only used when Type is "elicitation"

FieldTypeDescription
actionstring

Action defines the action to take when the user declines or cancels - skip_remaining: Skip remaining steps in the workflow - abort: Abort the entire workflow execution - continue: Continue to the next step


default "abort" · enum: skip_remaining | abort | continue
spec.config.compositeTools.steps.onDecline

OnDecline defines the action to take when the user explicitly declines the elicitation Only used when Type is "elicitation"

FieldTypeDescription
actionstring

Action defines the action to take when the user declines or cancels - skip_remaining: Skip remaining steps in the workflow - abort: Abort the entire workflow execution - continue: Continue to the next step


default "abort" · enum: skip_remaining | abort | continue
spec.config.compositeTools.steps.onError

OnError defines error handling behavior

FieldTypeDescription
actionstring

Action defines the action to take on error


default "abort" · enum: abort | continue | retry
retryCountinteger

RetryCount is the maximum number of retries Only used when Action is "retry"

retryDelaystring

RetryDelay is the delay between retry attempts Only used when Action is "retry"


pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
spec.config.incomingAuth

IncomingAuth configures how clients authenticate to the virtual MCP server. When using the Kubernetes operator, this is populated by the converter from VirtualMCPServerSpec.IncomingAuth and any values set here will be superseded.

FieldTypeDescription
authzobject

Authz contains authorization configuration (optional).

oidcobject

OIDC contains OIDC configuration (when Type = "oidc").

typerequiredstring

Type is the auth type: "oidc", "local", "anonymous"

spec.config.incomingAuth.authz

Authz contains authorization configuration (optional).

FieldTypeDescription
policiesstring[]

Policies contains Cedar policy definitions (when Type = "cedar").

primaryUpstreamProviderstring

PrimaryUpstreamProvider names the upstream IDP provider whose access token should be used as the source of JWT claims for Cedar evaluation. When empty, claims from the ToolHive-issued token are used. Must match an upstream provider name configured in the embedded auth server (e.g. "default", "github"). Only relevant when the embedded auth server is active.

typerequiredstring

Type is the authz type: "cedar", "none"

spec.config.incomingAuth.oidc

OIDC contains OIDC configuration (when Type = "oidc").

FieldTypeDescription
audiencerequiredstring

Audience is the required token audience.

clientIdrequiredstring

ClientID is the OAuth client ID.

clientSecretEnvstring

ClientSecretEnv is the name of the environment variable containing the client secret. This is the secure way to reference secrets - the actual secret value is never stored in configuration files, only the environment variable name. The secret value will be resolved from this environment variable at runtime.

insecureAllowHttpboolean

InsecureAllowHTTP allows HTTP (non-HTTPS) OIDC issuers for development/testing WARNING: This is insecure and should NEVER be used in production

introspectionUrlstring

IntrospectionURL is the token introspection endpoint URL (RFC 7662). When set, enables token introspection for opaque (non-JWT) tokens.

issuerrequiredstring

Issuer is the OIDC issuer URL.


pattern ^https?://
jwksAllowPrivateIpboolean

JwksAllowPrivateIP allows OIDC discovery and JWKS fetches to private IP addresses. Enable when the embedded auth server runs on a loopback address and the OIDC middleware needs to fetch its JWKS from that address. Use with caution - only enable for trusted internal IDPs or testing.

jwksUrlstring

JWKSURL is the explicit JWKS endpoint URL. When set, skips OIDC discovery and fetches the JWKS directly from this URL. This is useful when the OIDC issuer does not serve a /.well-known/openid-configuration.

protectedResourceAllowPrivateIpboolean

ProtectedResourceAllowPrivateIP allows protected resource endpoint on private IP addresses Use with caution - only enable for trusted internal IDPs or testing

resourcestring

Resource is the OAuth 2.0 resource indicator (RFC 8707). Used in WWW-Authenticate header and OAuth discovery metadata (RFC 9728). If not specified, defaults to Audience.

scopesstring[]

Scopes are the required OAuth scopes.

spec.config.operational

Operational configures operational settings.

FieldTypeDescription
failureHandlingobject

FailureHandling configures failure handling behavior.

logLevelstring

LogLevel sets the logging level for the Virtual MCP server. The only valid value is "debug" to enable debug logging. When omitted or empty, the server uses info level logging.


enum: debug
timeoutsobject

Timeouts configures timeout settings.

spec.config.operational.failureHandling

FailureHandling configures failure handling behavior.

FieldTypeDescription
circuitBreakerobject

CircuitBreaker configures circuit breaker behavior.

healthCheckIntervalstring

HealthCheckInterval is the interval between health checks.


default "30s" · pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
healthCheckTimeoutstring

HealthCheckTimeout is the maximum duration for a single health check operation. Should be less than HealthCheckInterval to prevent checks from queuing up.


default "10s" · pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
partialFailureModestring

PartialFailureMode defines behavior when some backends are unavailable. - fail: Fail entire request if any backend is unavailable - best_effort: Continue with available backends


default "fail" · enum: fail | best_effort
statusReportingIntervalstring

StatusReportingInterval is the interval for reporting status updates to Kubernetes. This controls how often the vMCP runtime reports backend health and phase changes. Lower values provide faster status updates but increase API server load.


default "30s" · pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
unhealthyThresholdinteger

UnhealthyThreshold is the number of consecutive failures before marking unhealthy.


default 3
spec.config.operational.failureHandling.circuitBreaker

CircuitBreaker configures circuit breaker behavior.

FieldTypeDescription
enabledboolean

Enabled controls whether circuit breaker is enabled.


default false
failureThresholdinteger

FailureThreshold is the number of failures before opening the circuit. Must be >= 1.


default 5 · min 1
timeoutstring

Timeout is the duration to wait before attempting to close the circuit. Must be >= 1s to prevent thrashing.


default "60s" · pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
spec.config.operational.timeouts

Timeouts configures timeout settings.

FieldTypeDescription
defaultstring

Default is the default timeout for backend requests.


default "30s" · pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
perWorkloadmap<string, string>

PerWorkload defines per-workload timeout overrides.

spec.config.optimizer

Optimizer configures the MCP optimizer for context optimization on large toolsets. When enabled, vMCP exposes only find_tool and call_tool operations to clients instead of all backend tools directly. This reduces token usage by allowing LLMs to discover relevant tools on demand rather than receiving all tool definitions.

FieldTypeDescription
embeddingServicestring

EmbeddingService is the full base URL of the embedding service endpoint (e.g., http://my-embedding.default.svc.cluster.local:8080) for semantic tool discovery. In a Kubernetes environment, it is more convenient to use the VirtualMCPServerSpec.EmbeddingServerRef field instead of setting this directly. EmbeddingServerRef references an EmbeddingServer CRD by name, and the operator automatically resolves the referenced resource's Status.URL to populate this field. This provides managed lifecycle (the operator watches the EmbeddingServer for readiness and URL changes) and avoids hardcoding service URLs in the config. If both EmbeddingServerRef and this field are set, EmbeddingServerRef takes precedence and this value is overridden with a warning.

embeddingServiceTimeoutstring

EmbeddingServiceTimeout is the HTTP request timeout for calls to the embedding service. Defaults to 30s if not specified.


default "30s" · pattern ^([0-9]+(\.[0-9]+)?(ns|us|µs|ms|s|m|h))+$
hybridSearchSemanticRatiostring

HybridSearchSemanticRatio controls the balance between semantic (meaning-based) and keyword search results. 0.0 = all keyword, 1.0 = all semantic. Defaults to "0.5" if not specified or empty. Serialized as a string because CRDs do not support float types portably.


pattern ^([0-9]*[.])?[0-9]+$
maxToolsToReturninteger

MaxToolsToReturn is the maximum number of tool results returned by a search query. Defaults to 8 if not specified or zero.


min 1 · max 50
semanticDistanceThresholdstring

SemanticDistanceThreshold is the maximum distance for semantic search results. Results exceeding this threshold are filtered out from semantic search. This threshold does not apply to keyword search. Range: 0 = identical, 2 = completely unrelated. Defaults to "1.0" if not specified or empty. Serialized as a string because CRDs do not support float types portably.


pattern ^([0-9]*[.])?[0-9]+$
spec.config.outgoingAuth

OutgoingAuth configures how the virtual MCP server authenticates to backends. When using the Kubernetes operator, this is populated by the converter from VirtualMCPServerSpec.OutgoingAuth and any values set here will be superseded.

FieldTypeDescription
backendsmap<string, object>

Backends contains per-backend auth configuration.

defaultobject

Default is the default auth strategy for backends without explicit config.

sourcerequiredstring

Source defines how to discover backend auth: "inline", "discovered" - inline: Explicit configuration in OutgoingAuth - discovered: Auto-discover from backend MCPServer.externalAuthConfigRef (Kubernetes only)

spec.config.outgoingAuth.backends

Backends contains per-backend auth configuration.

FieldTypeDescription
headerInjectionobject

HeaderInjection contains configuration for header injection auth strategy. Used when Type = "header_injection".

tokenExchangeobject

TokenExchange contains configuration for token exchange auth strategy. Used when Type = "token_exchange".

typestring

Type is the auth strategy: "unauthenticated", "header_injection", "token_exchange", "upstream_inject"

upstreamInjectobject

UpstreamInject contains configuration for upstream inject auth strategy. Used when Type = "upstream_inject".

spec.config.outgoingAuth.backends.headerInjection

HeaderInjection contains configuration for header injection auth strategy. Used when Type = "header_injection".

<CRDFields>: no object at path "spec.config.outgoingAuth.backends.headerInjection" in VirtualMCPServer.
spec.config.outgoingAuth.backends.tokenExchange

TokenExchange contains configuration for token exchange auth strategy. Used when Type = "token_exchange".

<CRDFields>: no object at path "spec.config.outgoingAuth.backends.tokenExchange" in VirtualMCPServer.
spec.config.outgoingAuth.backends.upstreamInject

UpstreamInject contains configuration for upstream inject auth strategy. Used when Type = "upstream_inject".

<CRDFields>: no object at path "spec.config.outgoingAuth.backends.upstreamInject" in VirtualMCPServer.
spec.config.outgoingAuth.default

Default is the default auth strategy for backends without explicit config.

FieldTypeDescription
headerInjectionobject

HeaderInjection contains configuration for header injection auth strategy. Used when Type = "header_injection".

tokenExchangeobject

TokenExchange contains configuration for token exchange auth strategy. Used when Type = "token_exchange".

typerequiredstring

Type is the auth strategy: "unauthenticated", "header_injection", "token_exchange", "upstream_inject"

upstreamInjectobject

UpstreamInject contains configuration for upstream inject auth strategy. Used when Type = "upstream_inject".

spec.config.outgoingAuth.default.headerInjection

HeaderInjection contains configuration for header injection auth strategy. Used when Type = "header_injection".

FieldTypeDescription
headerNamerequiredstring

HeaderName is the name of the header to inject (e.g., "Authorization").

headerValuestring

HeaderValue is the static header value to inject. Either HeaderValue or HeaderValueEnv should be set, not both.

headerValueEnvstring

HeaderValueEnv is the environment variable name containing the header value. The value will be resolved at runtime from this environment variable. Either HeaderValue or HeaderValueEnv should be set, not both.

spec.config.outgoingAuth.default.tokenExchange

TokenExchange contains configuration for token exchange auth strategy. Used when Type = "token_exchange".

FieldTypeDescription
audiencestring

Audience is the target audience for the exchanged token.

clientIdstring

ClientID is the OAuth client ID for the token exchange request.

clientSecretstring

ClientSecret is the OAuth client secret (use ClientSecretEnv for security).

clientSecretEnvstring

ClientSecretEnv is the environment variable name containing the client secret. The value will be resolved at runtime from this environment variable.

scopesstring[]

Scopes are the requested scopes for the exchanged token.

subjectProviderNamestring

SubjectProviderName selects which upstream provider's token to use as the subject token. When set, the token is looked up from Identity.UpstreamTokens instead of using Identity.Token. When left empty and an embedded authorization server is configured, the system automatically populates this field with the first configured upstream provider name. Set it explicitly to override that default or to select a specific provider when multiple upstreams are configured.

subjectTokenTypestring

SubjectTokenType is the token type of the incoming subject token. Defaults to "urn:ietf:params:oauth:token-type:access_token" if not specified.

tokenUrlrequiredstring

TokenURL is the OAuth token endpoint URL for token exchange.

spec.config.outgoingAuth.default.upstreamInject

UpstreamInject contains configuration for upstream inject auth strategy. Used when Type = "upstream_inject".

FieldTypeDescription
providerNamerequiredstring

ProviderName is the name of the upstream provider configured in the embedded authorization server. Must match an entry in AuthServer.Upstreams.

spec.config.sessionStorage

SessionStorage configures session storage for stateful horizontal scaling. When provider is "redis", the operator injects Redis connection parameters (address, db, keyPrefix) here. The Redis password is provided separately via the THV_SESSION_REDIS_PASSWORD environment variable.

FieldTypeDescription
addressstring

Address is the Redis server address (required when provider is redis).

dbinteger

DB is the Redis database number.


default 0 · format int32 · min 0
keyPrefixstring

KeyPrefix is an optional prefix for all Redis keys used by ToolHive.

providerrequiredstring

Provider is the session storage backend type.


enum: memory | redis
spec.config.telemetry

Telemetry configures OpenTelemetry-based observability for the Virtual MCP server including distributed tracing, OTLP metrics export, and Prometheus metrics endpoint. Deprecated (Kubernetes operator only): When deploying via the operator, use VirtualMCPServer.spec.telemetryConfigRef to reference a shared MCPTelemetryConfig resource instead. This field remains valid for standalone (non-operator) deployments.

FieldTypeDescription
caCertPathstring

CACertPath is the file path to a CA certificate bundle for the OTLP endpoint. When set, the OTLP exporters use this CA to verify the collector's TLS certificate instead of relying solely on the system CA pool.

customAttributesmap<string, string>

CustomAttributes contains custom resource attributes to be added to all telemetry signals. These are parsed from CLI flags (--otel-custom-attributes) or environment variables (OTEL_RESOURCE_ATTRIBUTES) as key=value pairs.

enablePrometheusMetricsPathboolean

EnablePrometheusMetricsPath controls whether to expose Prometheus-style /metrics endpoint. The metrics are served on the main transport port at /metrics. This is separate from OTLP metrics which are sent to the Endpoint.


default false
endpointstring

Endpoint is the OTLP endpoint URL

environmentVariablesstring[]

EnvironmentVariables is a list of environment variable names that should be included in telemetry spans as attributes. Only variables in this list will be read from the host machine and included in spans for observability. Example: ["NODE_ENV", "DEPLOYMENT_ENV", "SERVICE_VERSION"]

headersmap<string, string>

Headers contains authentication headers for the OTLP endpoint.

insecureboolean

Insecure indicates whether to use HTTP instead of HTTPS for the OTLP endpoint.


default false
metricsEnabledboolean

MetricsEnabled controls whether OTLP metrics are enabled. When false, OTLP metrics are not sent even if an endpoint is configured. This is independent of EnablePrometheusMetricsPath.


default false
samplingRatestring

SamplingRate is the trace sampling rate (0.0-1.0) as a string. Only used when TracingEnabled is true. Example: "0.05" for 5% sampling.


default "0.05"
serviceNamestring

ServiceName is the service name for telemetry. When omitted, defaults to the server name (e.g., VirtualMCPServer name).

serviceVersionstring

ServiceVersion is the service version for telemetry. When omitted, defaults to the ToolHive version.

tracingEnabledboolean

TracingEnabled controls whether distributed tracing is enabled. When false, no tracer provider is created even if an endpoint is configured.


default false
useLegacyAttributesboolean

UseLegacyAttributes controls whether legacy (pre-MCP OTEL semconv) attribute names are emitted alongside the new standard attribute names. When true, spans include both old and new attribute names for backward compatibility with existing dashboards. Currently defaults to true; this will change to false in a future release.


default true

spec.embeddingServerRef

EmbeddingServerRef references an existing EmbeddingServer resource by name. When the optimizer is enabled, this field is required to point to a ready EmbeddingServer that provides embedding capabilities. The referenced EmbeddingServer must exist in the same namespace and be ready.

FieldTypeDescription
namerequiredstring

Name is the name of the EmbeddingServer resource

spec.groupRef

GroupRef references the MCPGroup that defines backend workloads. The referenced MCPGroup must exist in the same namespace.

FieldTypeDescription
namerequiredstring

Name is the name of the MCPGroup resource in the same namespace


minLength 1

spec.incomingAuth

IncomingAuth configures authentication for clients connecting to the Virtual MCP server. Must be explicitly set - use "anonymous" type when no authentication is required. This field takes precedence over config.IncomingAuth and should be preferred because it supports Kubernetes-native secret references (SecretKeyRef, ConfigMapRef) for secure dynamic discovery of credentials, rather than requiring secrets to be embedded in config.

FieldTypeDescription
authzConfigobject

AuthzConfig defines authorization policy configuration Reuses MCPServer authz patterns

oidcConfigRefobject

OIDCConfigRef references a shared MCPOIDCConfig resource for OIDC authentication. The referenced MCPOIDCConfig must exist in the same namespace as this VirtualMCPServer. Per-server overrides (audience, scopes) are specified here; shared provider config lives in the MCPOIDCConfig resource.

typerequiredstring

Type defines the authentication type: anonymous or oidc When no authentication is required, explicitly set this to "anonymous"


enum: anonymous | oidc
spec.incomingAuth.authzConfig

AuthzConfig defines authorization policy configuration Reuses MCPServer authz patterns

FieldTypeDescription
configMapobject

ConfigMap references a ConfigMap containing authorization configuration Only used when Type is "configMap"

inlineobject

Inline contains direct authorization configuration Only used when Type is "inline"

typerequiredstring

Type is the type of authorization configuration


default "configMap" · enum: configMap | inline
spec.incomingAuth.authzConfig.configMap

ConfigMap references a ConfigMap containing authorization configuration Only used when Type is "configMap"

FieldTypeDescription
keystring

Key is the key in the ConfigMap that contains the authorization configuration


default "authz.json"
namerequiredstring

Name is the name of the ConfigMap

spec.incomingAuth.authzConfig.inline

Inline contains direct authorization configuration Only used when Type is "inline"

FieldTypeDescription
entitiesJsonstring

EntitiesJSON is a JSON string representing Cedar entities


default "[]"
policiesrequiredstring[]

Policies is a list of Cedar policy strings

spec.incomingAuth.oidcConfigRef

OIDCConfigRef references a shared MCPOIDCConfig resource for OIDC authentication. The referenced MCPOIDCConfig must exist in the same namespace as this VirtualMCPServer. Per-server overrides (audience, scopes) are specified here; shared provider config lives in the MCPOIDCConfig resource.

FieldTypeDescription
audiencerequiredstring

Audience is the expected audience for token validation. This MUST be unique per server to prevent token replay attacks.


minLength 1
namerequiredstring

Name is the name of the MCPOIDCConfig resource


minLength 1
resourceUrlstring

ResourceURL is the public URL for OAuth protected resource metadata (RFC 9728). When the server is exposed via Ingress or gateway, set this to the external URL that MCP clients connect to. If not specified, defaults to the internal Kubernetes service URL.

scopesstring[]

Scopes is the list of OAuth scopes to advertise in the well-known endpoint (RFC 9728). If empty, defaults to ["openid"].

spec.outgoingAuth

OutgoingAuth configures authentication from Virtual MCP to backend MCPServers. This field takes precedence over config.OutgoingAuth and should be preferred because it supports Kubernetes-native secret references (SecretKeyRef, ConfigMapRef) for secure dynamic discovery of credentials, rather than requiring secrets to be embedded in config.

FieldTypeDescription
backendsmap<string, object>

Backends defines per-backend authentication overrides Works in all modes (discovered, inline)

defaultobject

Default defines default behavior for backends without explicit auth config

sourcestring

Source defines how backend authentication configurations are determined - discovered: Automatically discover from backend's MCPServer.spec.externalAuthConfigRef - inline: Explicit per-backend configuration in VirtualMCPServer


default "discovered" · enum: discovered | inline
spec.outgoingAuth.backends

Backends defines per-backend authentication overrides Works in all modes (discovered, inline)

FieldTypeDescription
externalAuthConfigRefobject

ExternalAuthConfigRef references an MCPExternalAuthConfig resource Only used when Type is "externalAuthConfigRef"

typestring

Type defines the authentication type


enum: discovered | externalAuthConfigRef
spec.outgoingAuth.backends.externalAuthConfigRef

ExternalAuthConfigRef references an MCPExternalAuthConfig resource Only used when Type is "externalAuthConfigRef"

<CRDFields>: no object at path "spec.outgoingAuth.backends.externalAuthConfigRef" in VirtualMCPServer.
spec.outgoingAuth.default

Default defines default behavior for backends without explicit auth config

FieldTypeDescription
externalAuthConfigRefobject

ExternalAuthConfigRef references an MCPExternalAuthConfig resource Only used when Type is "externalAuthConfigRef"

typerequiredstring

Type defines the authentication type


enum: discovered | externalAuthConfigRef
spec.outgoingAuth.default.externalAuthConfigRef

ExternalAuthConfigRef references an MCPExternalAuthConfig resource Only used when Type is "externalAuthConfigRef"

FieldTypeDescription
namerequiredstring

Name is the name of the MCPExternalAuthConfig resource

spec.sessionStorage

SessionStorage configures session storage for stateful horizontal scaling. When nil, no session storage is configured.

FieldTypeDescription
addressstring

Address is the Redis server address (required when provider is redis)


minLength 1
dbinteger

DB is the Redis database number


default 0 · format int32 · min 0
keyPrefixstring

KeyPrefix is an optional prefix for all Redis keys used by ToolHive

passwordRefobject

PasswordRef is a reference to a Secret key containing the Redis password

providerrequiredstring

Provider is the session storage backend type


enum: memory | redis
spec.sessionStorage.passwordRef

PasswordRef is a reference to a Secret key containing the Redis password

FieldTypeDescription
keyrequiredstring

Key is the key within the secret

namerequiredstring

Name is the name of the secret

spec.telemetryConfigRef

TelemetryConfigRef references an MCPTelemetryConfig resource for shared telemetry configuration. The referenced MCPTelemetryConfig must exist in the same namespace as this VirtualMCPServer. Cross-namespace references are not supported for security and isolation reasons.

FieldTypeDescription
namerequiredstring

Name is the name of the MCPTelemetryConfig resource


minLength 1
serviceNamestring

ServiceName overrides the telemetry service name for this specific server. This MUST be unique per server for proper observability (e.g., distinguishing traces and metrics from different servers sharing the same collector). If empty, defaults to the server name with "thv-" prefix at runtime.

status

VirtualMCPServerStatus defines the observed state of VirtualMCPServer

FieldTypeDescription
backendCountinteger

BackendCount is the number of healthy/ready backends (excludes unavailable, degraded, and unknown backends)


format int32
conditionsobject[]

Conditions represent the latest available observations of the VirtualMCPServer's state

discoveredBackendsobject[]

DiscoveredBackends lists discovered backend configurations from the MCPGroup

messagestring

Message provides additional information about the current phase

observedGenerationinteger

ObservedGeneration is the most recent generation observed for this VirtualMCPServer


format int64
oidcConfigHashstring

OIDCConfigHash is the hash of the referenced MCPOIDCConfig spec for change detection. Only populated when IncomingAuth.OIDCConfigRef is set.

phasestring

Phase is the current phase of the VirtualMCPServer


default "Pending" · enum: Pending | Ready | Degraded | Failed
telemetryConfigHashstring

TelemetryConfigHash is the hash of the referenced MCPTelemetryConfig spec for change detection. Only populated when TelemetryConfigRef is set.

urlstring

URL is the URL where the Virtual MCP server can be accessed

status.conditions[]

Conditions represent the latest available observations of the VirtualMCPServer's state

FieldTypeDescription
lastTransitionTimerequiredstring

lastTransitionTime is the last time the condition transitioned from one status to another. This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.


format date-time
messagerequiredstring

message is a human readable message indicating details about the transition. This may be an empty string.


maxLength 32768
observedGenerationinteger

observedGeneration represents the .metadata.generation that the condition was set based upon. For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date with respect to the current state of the instance.


format int64 · min 0
reasonrequiredstring

reason contains a programmatic identifier indicating the reason for the condition's last transition. Producers of specific condition types may define expected values and meanings for this field, and whether the values are considered a guaranteed API. The value should be a CamelCase string. This field may not be empty.


pattern ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ · minLength 1 · maxLength 1024
statusrequiredstring

status of the condition, one of True, False, Unknown.


enum: True | False | Unknown
typerequiredstring

type of condition in CamelCase or in foo.example.com/CamelCase.


pattern ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ · maxLength 316

status.discoveredBackends[]

DiscoveredBackends lists discovered backend configurations from the MCPGroup

FieldTypeDescription
authConfigRefstring

AuthConfigRef is the name of the discovered MCPExternalAuthConfig (if any)

authTypestring

AuthType is the type of authentication configured

circuitBreakerStatestring

CircuitBreakerState is the current circuit breaker state (closed, open, half-open). Empty when circuit breaker is disabled or not configured.


enum: closed | open | half-open
circuitLastChangedstring

CircuitLastChanged is the timestamp when the circuit breaker state last changed. Empty when circuit breaker is disabled or has never changed state.


format date-time
consecutiveFailuresinteger

ConsecutiveFailures is the current count of consecutive health check failures. Resets to 0 when the backend becomes healthy again.

lastHealthCheckstring

LastHealthCheck is the timestamp of the last health check


format date-time
messagestring

Message provides additional information about the backend status

namerequiredstring

Name is the name of the backend MCPServer

statusstring

Status is the current status of the backend (ready, degraded, unavailable, unknown). Use BackendHealthStatus.ToCRDStatus() to populate this field.

urlstring

URL is the URL of the backend MCPServer

References: