Skip to content

Releases: achetronic/kubernetes-mcp

v0.5.1

12 Mar 11:51

Choose a tag to compare

Hot-reload fix for kubeconfig contexts

When using contexts_dir with a sidecar that periodically regenerates kubeconfig files (e.g., GCP token refresh), the MCP server would fail to reload them:

failed to load new kubeconfig: context name collision: "my-context" already defined (from /shared/kubeconfigs/my-context.yaml)

This happened because sidecars typically write kubeconfigs using atomic writes (temp file + rename), which the file watcher sees as a Create event instead of a Write event. The Create handler rejected any context that already existed.

Now, if a kubeconfig is created for a context that already exists, the client is replaced instead of rejected. New contexts are still registered normally.

v0.5.0

10 Mar 17:24

Choose a tag to compare

⚠️ Breaking: RBAC authorization redesigned

The authorization config format has changed in a way its much more powerful now, BUT You need to update your config files.

What changed:

  • allow: / deny: blocks replaced by a rules: list where each rule has effect: allow or effect: deny
  • kinds: (e.g. Pod, Secret) replaced by resources: with plural lowercase names (e.g. pods, secrets)
  • Virtual resources renamed: APIDiscoveryapidiscovery, ClusterInfoclusterinfo, Contextcontexts
  • Glob patterns now work everywhere: *, prefix*, *suffix, a*b*c

Before (v0.4.x):

authorization:
  policies:
    - name: "my-policy"
      match:
        expression: "true"
      allow:
        tools: ["get_*", "list_*"]
        resources:
          - groups: [""]
            kinds: ["Pod", "Service"]
      deny:
        tools: ["get_*"]
        resources:
          - groups: [""]
            kinds: ["Secret"]

After (v0.5.0):

authorization:
  policies:
    - name: "my-policy"
      match:
        expression: "true"
      rules:
        - effect: allow
          tools: ["get_*", "list_*"]
          resources:
            - groups: [""]
              resources: ["pods", "services"]
        - effect: deny
          tools: ["get_*"]
          resources:
            - groups: [""]
              resources: ["secrets"]

What's new

Rules with explicit effect — Put allow and deny rules together in the same policy. No more separate blocks.
Resource names match the Kubernetes API — Use the same plural lowercase names you see in kubectl api-resources (pods, deployments , configmaps ).
Full glob support — All fields support wildcards: get_* , -suffix , team--prod . Works in tools, contexts, groups resources, namespaces, and names.
Deny always wins — If any deny rule matches, access is denied. No surprises from rule ordering.
Default deny — If no allow rule matches, access is denied. Tools not listed in any allow rule are blocked automatically.
Empty fields match everything — Skip tools , contexts , or resources in a rule to match all.

Tests

• 1,700+ unit tests covering glob matching, deny priority, multi-policy evaluation, virtual resources, and edge cases
• Integration tests that run against a real cluster — discover all API resources and verify every tool/resource combination. Set KUBE_CONTEXT=your-context to run them; they skip automatically otherwise
• Validated with 0 violations against a live cluster (185 resource types, 374 delete checks, 370 apply/patch denials)

Also updated

• Example configs in docs/ updated to new format
• README rewritten with new authorization reference and examples

v0.4.0

09 Mar 15:43

Choose a tag to compare

API Key Authentication

You can now use static API keys alongside JWT for authentication. Useful for CI/CD pipelines, service accounts, or setups without an identity provider.

middleware:
  api_keys:
    enabled: true
    keys:
      - name: "ci-cd-pipeline"
        token: "$CI_API_KEY"
        payload:
          sub: "ci-cd-service"
          groups: ["ci-cd"]

API keys and JWTs produce the same payload, so your existing authorization policies just work — no changes needed.

When both are enabled, JWT is tried first. If the token isn't a valid JWT, it falls back to API key matching.

Security notes

  • Tokens are hashed (SHA-256) at startup and compared in constant time to prevent timing attacks
  • Use environment variables for tokens ($CI_API_KEY) instead of hardcoding them

Simpler JWT config

The JWT config is now flat — no more strategy, forwarded_header, or local: nesting:

# Before
middleware:
  jwt:
    validation:
      strategy: "local"
      forwarded_header: "X-Validated-Jwt"
      local:
        jwks_uri: "https://..."
        cache_interval: "10s"

# After
middleware:
  jwt:
    validation:
      jwks_uri: "https://..."
      cache_interval: "10s"

Breaking changes

Removed Why
middleware.jwt.validation.strategy JWT is now always validated locally against JWKS
middleware.jwt.validation.forwarded_header Auth payload is now handled internally
middleware.jwt.validation.local nesting Fields moved up to middleware.jwt.validation
authorization.identity_claim Was never used. Removed

v0.3.2

02 Mar 00:53

Choose a tag to compare

Tool name prefixing

MCP tools are now automatically prefixed with a sanitized version of server.name from the config. This prevents tool name collisions when multiple MCP servers are connected to the same client.

For example, with server.name: "some-mcp", a tool registered as something is exposed to the client as some_mcp_something.

How it works

  • server.name is lowercased, non-alphanumeric characters are replaced with _, and a trailing _ is appended.
  • If server.name is not set, each project falls back to its own default (e.g. some-mcp.).

v0.3.1

04 Feb 02:42
bbb82b3

Choose a tag to compare

Bug Fixes

Watch new kubeconfig files in contexts_dir : Kubeconfig files added to the contexts_dir after the server starts
are now automatically detected and loaded (#1)
Debounce for new file detection: Added 500ms debounce when detecting new files to avoid reading incomplete files (e.
g., when an editor creates the file before writing content)
Watch dynamically loaded kubeconfigs: Newly loaded kubeconfig files are now added to the file watcher, so subsequent
changes are detected and trigger client reload
Improved error handling: Properly handle and log filepath.Abs errors instead of silently ignoring them

Contributors:

@achetronic

v0.3.0

04 Feb 01:55

Choose a tag to compare

Features

Contexts as list: kubernetes.contexts configuration is now a list with explicit name field instead of a map

contexts:
  - name: "production"
    kubeconfig: "/path/to/kubeconfig"
    kubeconfig_context: "gke_myproject_prod"  # optional
    description: "Production cluster"

Auto-load from directory: New contexts_dir field to automatically load kubeconfigs from a directory. Context name
is taken from each file's current-context
contexts_dir: "/shared/kubeconfigs/"

Kubeconfig hot-reload: Kubeconfig files are automatically watched. When a sidecar or external process updates them,
the client reloads without server restart
Collision detection: Duplicate context names (between explicit, auto-loaded, or both) cause server startup to fail
with a clear error message

Breaking Changes

kubernetes.contexts format changes from map to list. Migration:

# Before
contexts:
  production:
    kubeconfig: "/path/to/kubeconfig"

# After
contexts:
  - name: "production"
    kubeconfig: "/path/to/kubeconfig"

Contributors:

@achetronic

v0.2.0

03 Feb 15:04

Choose a tag to compare

Features

• Resource-level RBAC: filter by API group, kind, namespace, and name
• Virtual resources: non-K8s tools mapped to group _ (APIDiscovery, ClusterInfo, Context)
• Wildcard patterns: prefix-*, *-suffix for namespaces and names

Example

deny:
  resources:
    - groups: [""]
      kinds: ["Secret"]
    - groups: ["rbac.authorization.k8s.io"]
      kinds: ["*"]

Docs

• New logo and header
• Resource authorization examples in README

Upgrade

Backwards compatible. Existing configs work without changes.

Contributors

@achetronic

v0.1.0

03 Feb 00:43

Choose a tag to compare

💥💥💣💣💣 Initial release 💣💣💣💥💥 Yes, some places need emojis to bother others

Features

• 25 Kubernetes tools: read, modify, scale, rollout, logs, exec, metrics, diff, context management
• yq filtering: filter responses at source to save context window
• CEL-based RBAC: fine-grained access control per tool and context
• Multi-cluster support: named contexts with independent configurations
• OAuth 2.1: RFC 8414 / RFC 9728 compliant for safe public exposure
• JWT validation: local (JWKS) or external (Istio/Envoy)

Deployment

• Binaries: Linux (amd64, arm64, 386), macOS (amd64, arm64)
• Docker: ghcr.io/achetronic/kubernetes-mcp:v0.1.0
• Helm: via bjw-s/app-template

Contributors

@achetronic