Skip to content

Flux MCP Server Config API

This document describes a declarative API for configuring a subset of features of the Flux MCP Server.

Overview

The Config API supports:

  • MCP Transport Modes - How the MCP server receives and sends messages
    • Streamable HTTP - HTTP transport with support for streaming responses and authentication
    • Standard Input/Output (stdio) - Simple transport using standard input and output streams
  • Authentication - Secure access control for MCP server operations when running with Streamable HTTP
    • Credentials - How credentials are extracted from incoming requests
    • Providers - How extracted credentials are validated and converted to user sessions

A YAML configuration file defines the features and settings to be used by the MCP server. This file must be specified with --config=<path to file> when starting the MCP server. If this flag is not specified, the MCP server will start with default settings.

The legacy sse transport mode can only be specified using the --transport=sse flag.

Example:

# /etc/flux-mcp/config.yaml
apiVersion: mcp.fluxcd.controlplane.io/v1
kind: Config
spec:
  transport: http # or stdio
  authentication:
    credentials:
      - type: BearerToken
    providers:
      - name: external
        type: OIDC
        issuerURL: "https://auth.example.com"
        audience: "https://flux-mcp.example.com"
        impersonation:
          username: "claims.sub"
        scopes:
          expression: "claims.scopes"
flux-operator-mcp serve --config=/etc/flux-mcp/config.yaml

Config API

apiVersion: mcp.fluxcd.controlplane.io/v1
kind: Config
spec:

  # Transport mode for MCP communication. Supported values: "http", "stdio". Default: "stdio"
  transport: http

  # If true, the MCP server will operate in read-only mode. The MCP server will run in read-only
  # mode if at least one between this field or the CLI flag --read-only is set to true.
  readonly: false # Optional, default is false.

  # Authentication configuration (optional)
  authentication:

    # Methods for extracting credentials. At least one method must be defined.
    credentials:
      - type: BearerToken
      - type: BasicAuth
      - type: CustomHTTPHeader
        headers:
          token: "X-Auth-Token"

    # Authentication providers. At least one provider must be defined.
    providers:
      - name: external
        type: OIDC
        issuerURL: "https://auth.example.com"
        audience: "https://flux-mcp.example.com"

Authentication

Authentication is only supported in the Streamable HTTP MCP transport mode. When authentication is configured, it provides secure access control with support for multiple credential extraction methods and multiple authentication providers.

Credentials

The field spec.authentication.credentials defines how credentials are extracted from incoming HTTP requests. The first credential that successfully extracts the information from a request is used.

BearerToken

Extracts a token from the Authorization: Bearer <token> header.

spec:
  authentication:
    credentials:
      - type: BearerToken

BasicAuth

Extracts username and password from the Authorization: Basic base64(<username>+":"+<password>) header.

spec:
  authentication:
    credentials:
      - type: BasicAuth

CustomHTTPHeader

Extracts credentials from custom HTTP headers.

spec:
  authentication:
    credentials:
      - type: CustomHTTPHeader
        headers:
          username: "X-Username" # Header containing username (optional)
          password: "X-Password" # Header containing password (optional)
          token: "X-Auth-Token"  # Header containing token (optional)

Providers

Authentication providers validate extracted credentials and extract user information from these credentials to create a user session. Multiple providers can be configured under spec.authentication.providers to support different authentication systems. The first provider that successfully validates the extracted credentials and successfully extracts a user session is used.

A user session consists of a username, a list of groups, and a list of scopes.

The username and groups in a user session are used for Kubernetes impersonation. RBAC permissions are expected to be properly granted to this username and groups separately, the MCP server is not responsible for managing these permissions.

OIDC Provider

The OIDC provider validates JSON Web Tokens (JWT) against an OpenID Connect provider. An HTTP call is made to the provider's /.well-known/openid-configuration endpoint to fetch the provider's public keys and other metadata. The public keys are used to validate the token's signature. If the signature is valid, and the standard claims (iss, aud, exp, etc.) are valid, the token is considered valid.

If a token is considered valid, the provider proceeds to extract the user session information from the token's claims, and then finally to validate custom properties defined in the configuration. The extraction and validation rules are defined using Common Expression Language (CEL) expressions. A map with the claims of the JWT is passed to the CEL expressions. References for writing CEL expressions:

Multiple OIDC providers can be defined to support multiple OIDC providers.

Each OIDC provider under spec.authentication.providers supports the following configuration:

spec:
  authentication:
    providers:
      - # Required fields
        name: external                                      # Provider name (must be unique)
        type: OIDC                                          # Provider type
        issuerURL: "https://auth.example.com"               # OIDC issuer URL for fetching public keys
        audience: "https://flux-mcp.example.com"            # Expected "aud" claim in the JWT

        # Optional fields
        variables:                                          # Named variables for reuse in other expressions
          - name: username
            expression: "claims.sub"
          - name: domain
            expression: "claims.email.split('@')[1]"
        validations:                                        # Custom claim and variables validations
          - expression: "variables.domain == 'example.com'" # CEL expression returning bool
            message: "email domain not allowed"
        impersonation:                                      # Kubernetes impersonation configuration
          username: "variables.username"                    # CEL expression returning string
          groups: "claims.groups"                           # CEL expression returning []string
        scopes:                                             # Scopes extraction
          expression: "claims.scopes"                       # CEL expression returning []string
Scopes

Scopes provide fine-grained access control for MCP operations. When configured, the scopes extracted from authentication credentials are used by the MCP tools to limit access to certain operations.

The scopes in a user session are used by the MCP tools individually to limit access to certain operations. Even though a user or group may have RBAC permissions to perform an operation in the Kubernetes cluster, the MCP tools will deny the operation if the required scope is not present in the user session. The opposite is not true, i.e. having the required scope does not guarantee that the operation will be allowed by Kubernetes RBAC.

The scopes required by each MCP tool are documented in the tools reference.

Configuration Examples

Basic OIDC Authentication

apiVersion: mcp.fluxcd.controlplane.io/v1
kind: Config
spec:
  transport: http
  authentication:
    credentials:
      - type: BearerToken
    providers:
      - name: external
        type: OIDC
        issuerURL: "https://auth.example.com"
        audience: "https://flux-mcp.example.com"

Advanced OIDC with Variables and Validations

apiVersion: mcp.fluxcd.controlplane.io/v1
kind: Config
spec:
  transport: http
  authentication:
    credentials:
      - type: BearerToken
      - type: BasicAuth
    providers:
      - name: external
        type: OIDC
        issuerURL: "https://auth.example.com"
        audience: "https://flux-mcp.example.com"
        variables:
          - name: email
            expression: "claims.email"
          - name: department
            expression: "claims.department"
        validations:
          - expression: "variables.email.endsWith('@example.com')"
            message: "Only example.com emails allowed"
          - expression: "variables.department in ['engineering', 'devops']"
            message: "Access restricted to engineering and devops"
        impersonation:
          username: "claims.preferred_username"
          groups: "claims.groups + ['authenticated']"
        scopes:
          expression: "claims.scopes"

OIDC with Variable Referencing

This example demonstrates how variables can reference previously declared variables, enabling complex data transformations and validations:

apiVersion: mcp.fluxcd.controlplane.io/v1
kind: Config
spec:
  transport: http
  authentication:
    credentials:
      - type: BearerToken
    providers:
      - name: external
        type: OIDC
        issuerURL: "https://auth.example.com"
        audience: "https://flux-mcp.example.com"
        variables:
          - name: email
            expression: "claims.email"                  # Extract email from claims
          - name: domain
            expression: "variables.email.split('@')[1]" # Extract domain from email variable
          - name: normalized_domain
            expression: "variables.domain.lowerAscii()" # Normalize domain using previous variable
          - name: username_prefix
            expression: "variables.email.split('@')[0]" # Extract username part from email
        validations:
          - expression: "variables.normalized_domain in ['example.com', 'corp.example.com']"
            message: "Email domain not allowed"
          - expression: "size(variables.username_prefix) >= 3"
            message: "Username must be at least 3 characters"
        impersonation:
          username: "variables.email"
          groups: "['users', 'domain:' + variables.normalized_domain]"
        scopes:
          expression: "['read', 'write:' + variables.normalized_domain]"