Last generated July 6, 2026

MCPServer

MCPServer is the Schema for the mcpservers API

Full name:
mcpservers.muster.giantswarm.io
Group:
muster.giantswarm.io
Singular name:
mcpserver
Plural name:
mcpservers
Scope:
Namespaced
Versions:
v1alpha1

Version v1alpha1

Example CR

apiVersion: muster.giantswarm.io/v1alpha1
kind: MCPServer
metadata:
  name: git-tools
  namespace: default
spec:
  type: stdio
  autoStart: true
  command: npx
  args: ["@modelcontextprotocol/server-git"]
  env:
    GIT_ROOT: "/workspace"
    LOG_LEVEL: "info"
  description: "Git tools MCP server for repository operations"

Properties

.apiVersion

string

APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources

.kind

string

Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds

.metadata

object

.spec

object

MCPServerSpec defines the desired state of MCPServer

.spec.args

array

Args specifies the command line arguments for stdio type servers. This field is only available when Type is “stdio”.

.spec.args[*]

string

.spec.auth

object

Auth configures authentication behavior for this MCP server. This is only relevant for remote servers (streamable-http or sse).

.spec.auth.authorizationServer

object

AuthorizationServer is an opt-out for backends that don’t publish RFC 9728 Protected Resource Metadata. When set, muster’s per-server OAuth login flow (core_auth_login) skips PRM probing and uses these values directly. muster logs each override use at INFO so non-compliance is observable.

This override does NOT bypass mcp-go’s connect-time PRM probe; backends without RFC 9728 metadata still reconcile to “Auth Required” on first connect, then transition to “Connected” after muster auth login.

Setting AuthorizationServer does NOT change the RFC 8707 resource parameter — that remains driven by the MCP server URL.

AuthorizationServer is mutually exclusive with ForwardToken: true and TokenExchange.Enabled: true. The CRD admission rules above reject any CR that combines them. Only valid when Type is “oauth”.

Use case: Atlassian Remote MCP and similar backends that publish RFC 8414 metadata at their resource origin instead of via RFC 9728.

.spec.auth.authorizationServer.issuer

string Required

Issuer is the OAuth 2.0 / OIDC issuer URL. muster fetches AS metadata via the existing OAuth client, which performs RFC 8414 / OIDC discovery against this issuer.

.spec.auth.authorizationServer.scopes

string

Scopes is the OAuth scope parameter value (RFC 6749 §3.3 wire format: space-separated scope tokens). Matches existing TokenExchangeConfig.Scopes.

.spec.auth.forwardToken

boolean

ForwardToken enables ID token forwarding for SSO. When true, muster forwards the user’s ID token to this server instead of triggering a separate OAuth flow. The downstream server must be configured to trust muster’s client ID in its TrustedAudiences.

.spec.auth.localMint

object

LocalMint enables downstream auth via a per-backend token minted by muster from its own signing key. On each call muster reads the caller’s bearer as the subject and an optional X-Actor-Token header as the actor, then mints a token (sub=subject, act=actor, aud=Audience, iss=muster) through muster’s RFC 8693 broker.

Use LocalMint when the backend must authorize an agent acting on behalf of a human (OBO) and no shared remote IdP can issue a token with the backend’s audience. Requires muster’s OAuth server to run in JWT mode with a broker local-mint target whose audience equals Audience.

LocalMint is mutually exclusive with ForwardToken, TokenExchange, and AuthorizationServer (the CRD admission rules above reject combinations).

.spec.auth.localMint.audience

string

Audience is the minted token’s aud claim: the backend’s resource identifier. It must equal a configured broker local-mint target; the mint fails closed when no matching target exists.

.spec.auth.localMint.enabled

boolean

Enabled turns on local minting for this server.

.spec.auth.requiredAudiences

array

RequiredAudiences specifies additional audience(s) that the forwarded ID token should contain. When ForwardToken is true, muster will request these audiences from the upstream IdP (e.g., Dex) using cross-client scopes.

This is used when the downstream server requires tokens with specific audiences, for example when forwarding tokens to Kubernetes for OIDC authentication: requiredAudiences: - “dex-k8s-authenticator”

At user authentication, muster collects all requiredAudiences from MCPServers with forwardToken: true and requests them all from the IdP.

.spec.auth.requiredAudiences[*]

string

.spec.auth.tokenExchange

object

TokenExchange enables SSO via RFC 8693 Token Exchange for cross-cluster SSO. When configured, muster exchanges its local token for a token valid on the remote cluster’s Identity Provider (e.g., Dex).

Use TokenExchange when: - The remote cluster has its own Dex instance - The remote Dex is configured with an OIDC connector for muster’s Dex - You need a token issued by the remote cluster’s IdP (not just forwarded)

Token exchange takes precedence over ForwardToken if both are configured.

.spec.auth.tokenExchange.clientCredentialsSecretRef

object

ClientCredentialsSecretRef references a Kubernetes Secret containing client credentials for authenticating with the remote Dex’s token endpoint. This is required when the remote Dex requires client authentication for token exchange (RFC 8693).

The secret should contain: - client-id: The OAuth client ID registered on the remote Dex - client-secret: The OAuth client secret for authentication

Example secret:

apiVersion: v1
kind: Secret
metadata:
  name: grizzly-token-exchange-credentials
  namespace: muster
type: Opaque
stringData:
  client-id: muster-token-exchange
  client-secret: <secret-value>

.spec.auth.tokenExchange.clientCredentialsSecretRef.clientIdKey

string

ClientIDKey is the key in the secret data that contains the client ID. Defaults to “client-id” if not specified.

.spec.auth.tokenExchange.clientCredentialsSecretRef.clientSecretKey

string

ClientSecretKey is the key in the secret data that contains the client secret. Defaults to “client-secret” if not specified.

.spec.auth.tokenExchange.clientCredentialsSecretRef.name

string Required

Name is the name of the Kubernetes Secret. Required.

.spec.auth.tokenExchange.clientCredentialsSecretRef.namespace

string

Namespace is the Kubernetes namespace where the secret is located. If not specified, defaults to the MCPServer’s namespace.

.spec.auth.tokenExchange.connectorId

string

ConnectorID is the ID of the OIDC connector on the remote Dex that trusts the local cluster’s Dex. Required when Enabled is true. Example: “cluster-a-dex”

.spec.auth.tokenExchange.dexTokenEndpoint

string

DexTokenEndpoint is the URL used to connect to the remote cluster’s Dex token endpoint. This may differ from the issuer URL when access goes through a proxy. Required when Enabled is true. Example: https://dex.cluster-b.example.com/token (direct) Example: https://dex-cluster.proxy.example.com/token (via proxy)

.spec.auth.tokenExchange.enabled

boolean

Enabled determines whether token exchange should be attempted.

.spec.auth.tokenExchange.expectedIssuer

string

ExpectedIssuer is the expected issuer URL in the exchanged token’s “iss” claim. This should match the remote Dex’s configured issuer URL. When access goes through a proxy, this differs from DexTokenEndpoint. If not specified, the issuer is derived from DexTokenEndpoint (backward compatible). Example: https://dex.cluster-b.example.com

.spec.auth.tokenExchange.scopes

string

Scopes are the scopes to request for the exchanged token.

.spec.auth.type

string

Type specifies the authentication type. Supported values: - “oauth”: OAuth 2.0/OIDC authentication - “none”: No authentication

.spec.autoStart

boolean

AutoStart determines whether this MCP server should be automatically started when the muster system initializes or when dependencies become available.

.spec.command

string

Command specifies the executable path for stdio type servers. This field is required when Type is “stdio”.

.spec.description

string

Description provides a human-readable description of this MCP server’s purpose.

.spec.env

object

Env contains environment variables to set for the MCP server. For stdio servers, these are passed to the process when it is started. For remote servers, these can be used for authentication or configuration.

.spec.family

object

Family declares that this MCP server is an instance of a family of equivalent servers (for example, multiple kubernetes MCP servers pointed at different clusters). When set, the aggregator exposes tools from all servers in the same family under a single name ({musterPrefix}{family.name}{toolName}) with a required parameter (named by family.instanceArg) that selects which instance handles the call. The parameter is always required even for single-instance families so skills written against the family name remain stable as instances are added or removed. When unset, the legacy per-server prefixing applies ({musterPrefix}{toolPrefix-or-name}{toolName}).

.spec.family.instanceArg

string Required

InstanceArg names the required parameter callers use to select which family member handles the tool call (for example “management_cluster”, “country”, “model”). All servers declaring the same family.name must agree on InstanceArg; if they diverge, the aggregator falls back to per-server prefixing for the entire family and logs a warning.

.spec.family.name

string Required

Name is the family identifier. Servers sharing the same Name expose their tools as {musterPrefix}{Name}{toolName}.

.spec.headers

object

Headers contains HTTP headers to send with requests to remote MCP servers. This field is only relevant when Type is “streamable-http” or “sse”.

.spec.timeout

integer

Timeout specifies the connection timeout for remote operations (in seconds)

.spec.toolPrefix

string

ToolPrefix is an optional prefix that will be prepended to all tool names provided by this MCP server. This helps avoid naming conflicts when multiple servers provide tools with similar names.

.spec.type

string Required

Type specifies how this MCP server should be executed. Supported values: “stdio” for local processes, “streamable-http” for HTTP-based servers, “sse” for Server-Sent Events

.spec.url

string

URL is the endpoint where the remote MCP server can be reached This field is required when Type is “streamable-http” or “sse”. Examples: http://mcp-server:8080/mcp, https://api.example.com/mcp

.status

object

MCPServerStatus defines the observed state of MCPServer.

This status reflects server-side observable state including auth requirements. It captures infrastructure connectivity as well as whether the server demands authentication (e.g. “Auth Required”). Per-user session state (which specific user is authenticated, token expiry, etc.) is tracked separately in the Session Registry (internal/aggregator/session_registry.go).

Server-Side State (CRD): - State: Running/Connected/Starting/Connecting/Stopped/Disconnected/Auth Required/Failed - Conditions: Standard K8s conditions for detailed status

Per-User Session State (Session Registry): - ConnectionStatus: Connected, PendingAuth, Failed (per-user) - AuthStatus: Authenticated, AuthRequired, TokenExpired (per-user) - AvailableTools: Tools visible to this specific user

.status.conditions

array

Conditions represent the latest available observations of the MCPServer’s current state. Standard condition types: - Ready: True if infrastructure is reachable (process running or TCP connectable)

.status.conditions[*]

object

Condition contains details for one aspect of the current state of this API Resource.

.status.conditions[*].lastTransitionTime

string Required

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.

.status.conditions[*].message

string Required

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

.status.conditions[*].observedGeneration

integer

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.

.status.conditions[*].reason

string Required

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.

.status.conditions[*].status

string Required

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

.status.conditions[*].type

string Required

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

.status.consecutiveFailures

integer

ConsecutiveFailures tracks the number of consecutive connection failures. This is used for exponential backoff and to identify unreachable servers. Reset to 0 when a connection succeeds.

.status.lastAttempt

string

LastAttempt indicates when the last connection attempt was made. Used with ConsecutiveFailures to implement exponential backoff.

.status.lastConnected

string

LastConnected indicates when the server was last successfully connected

.status.lastError

string

LastError contains any error message from the most recent server operation. Note: Per-user authentication errors are tracked in the Session Registry, not here. This field only contains infrastructure-level errors.

.status.nextRetryAfter

string

NextRetryAfter indicates the earliest time when the next retry should be attempted. This is calculated based on exponential backoff from ConsecutiveFailures.

.status.restartCount

integer

RestartCount tracks how many times this server has been restarted (stdio only)

.status.state

string

State represents the high-level infrastructure state of the MCP server. This is independent of user session state (authentication, connection status).

For stdio servers: Running, Starting, Stopped, Failed For remote servers: Connected, Auth Required, Connecting, Disconnected, Failed


This documentation page shows information based on muster v0.22.10.