0.004     2026-10-31 01:38:48Z
  - Fix cluster-scoped permissions being empty. The RBAC discovery sent a
    SelfSubjectRulesReview without a namespace, which the API server
    rejects with 400 "no namespace on request" - so every cluster-scoped
    kind (Node, Namespace, CRDs) was denied, also for a cluster-admin.
    The cluster scope is derived from the namespace reviews now: what all
    of them have in common is what the account may do cluster-wide.
  - BEHAVIOUR CHANGE: a cluster-scoped kind is called without a namespace
    and checked against the cluster scope; a namespaced kind without a
    namespace answers "namespace required" instead of "Permission denied"
    (k20).
  - Fix MCP_K8S_NAMESPACES keeping whitespace around names ('default,
    production' lost "production") and empty elements, and the plural
    heuristic turning Gateway into "gatewaies" (k21).
  - Fix k8s_apply failing with 415 when updating an existing custom resource:
    the fallback patch is strategic only for built-in kinds (IO::K8s::Api::*)
    and a merge patch for all others (k19).
  - Fix k8s_apply treating any create error whose body merely contains "409"
    as a conflict and patching over the real error. The decision now comes
    from Kubernetes::REST::APIError->is_conflict; the string match remains
    only for errors that are not such objects (k18).
  - Fix k8s_events and k8s_list resource=Event returning only event names:
    the summary now carries type, reason, message, count, timestamps and
    involvedObject (kind/name), also for events.k8s.io note/regarding (k17).

0.003     2026-10-01 16:06:40Z
  - Require IO::K8s 1.109 and Kubernetes::REST 1.109: string-map fields
    (labels, annotations, ConfigMap data, ...) now serialize numeric values
    as JSON strings, which the API server requires.
  - Fix RBAC-aware tool descriptions reaching only run_stdio clients. They
    are now built on the first tools/list or tools/call of any transport,
    so the Net::Async::MCP path from README, an embedded to_stdio and the
    HTTP to_action all tell the LLM which resources exist per namespace. A
    server whose API cannot be built answers tools/list with a JSON-RPC
    error instead of the static list.
  - Fix k8s_get output => 'yaml' writing booleans as
    "!!perl/scalar:JSON::PP::Boolean 1", which kubectl rejects. YAML now
    comes from IO::K8s to_yaml; the optional YAML::XS dependency and its
    silent fallback to JSON are gone.
  - k8s_patch takes an optional subresource => 'status', routed to
    patch_status() with a merge default (an explicit patch_type wins) and
    gated on <plural>/status. Without it a status write to the main
    endpoint returned 2xx while the API server dropped the status.
  - Fix RBAC discovery dropping every subresource but pods/log, which
    denied a narrow Role granting e.g. patch on deployments/status.
    Subresources are kept as the API server reports them; tool
    descriptions are unchanged.
  - BEHAVIOUR CHANGE: a namespace whose only grants are subresources now
    counts as reachable. With more than one reachable namespace, tools ask
    for an explicit namespace instead of auto-filling.
  - k8s_logs reads logs through Kubernetes::REST's log(); an HTTP error
    now reads "Failed to get logs for pod/<name>: ... 404 ..." instead of
    "Error getting logs: 404 ...".
  - Plural lookup resolves built-in Kinds through IO::K8s's upstream
    plurals without a request; expand_class() no longer downloads
    /openapi/v2. CRDs without a class still come from API discovery.
  - Fix MCP_K8S_TOKEN, MCP_K8S_SERVER and MCP_K8S_CONTEXT being ignored
    when set only in the environment; all three auth tiers honour them
    now (closes #1).
  - MCP::K8s->new takes kubeconfig_path, passed through to
    Kubernetes::REST::Kubeconfig, so an embedder names the kubeconfig file
    directly instead of going through KUBECONFIG. No new env var.
  - Require MCP 0.15, Kubernetes::REST 1.108 and IO::K8s 1.108.
  - The Net::Async::MCP examples in README and examples/ need
    Net::Async::MCP 0.004 or newer: MCP 0.15 speaks the stateless
    2026-07-28 revision, which 0.003 rejects with "-32602 Missing protocol
    version". Not a dependency of this distribution; mcp-k8s is unaffected.

0.002     2026-03-05 21:29:05Z

  - MCP::K8s now inherits from MCP::Server instead of composing it
  - Backward compatible: ->server returns $self
  - Lazy permission discovery: RBAC discovery no longer runs at
    construction time, only when actually needed (first tool call
    or run_stdio). Allows creating MCP::K8s instances without a
    cluster connection.
  - Tool descriptions are updated dynamically after discovery
    instead of eagerly during BUILD

0.001     2026-02-24 02:12:29Z

  - Initial release
  - RBAC-aware MCP server for Kubernetes
    - Dynamic tool discovery via SelfSubjectRulesReview
    - Dynamic tool descriptions reflecting actual permissions
    - Wildcard handling for verbs and resources
    - Permission check before every tool call
  - 10 MCP tools:
    - k8s_permissions — show RBAC permissions
    - k8s_list — list resources with label/field selectors
    - k8s_get — get resource in summary, JSON, or YAML format
    - k8s_create — create a resource from manifest
    - k8s_patch — strategic merge, JSON merge, or JSON patch
    - k8s_delete — delete a resource
    - k8s_logs — pod container logs via raw API endpoint
    - k8s_events — dedicated event listing with object/field filters
    - k8s_rollout_restart — rolling restart for Deployments,
      StatefulSets, DaemonSets (same as kubectl rollout restart)
    - k8s_apply — create-or-update semantics (like kubectl apply),
      tries create first, falls back to strategic merge patch on 409
  - Three authentication methods (tried in order):
    - Direct token via MCP_K8S_TOKEN + MCP_K8S_SERVER
    - In-cluster service account auto-detection
    - Kubeconfig fallback with MCP_K8S_CONTEXT support
  - Dynamic resource plural discovery via API server endpoints
    - 4-tier lookup: static map, IO::K8s class, API discovery, heuristic
    - Supports CRDs (e.g. Cilium) without configuration
  - Auto-namespace detection (single namespace auto-fill,
    in-cluster namespace from mounted service account)
  - Example RBAC manifests in examples/:
    - readonly-serviceaccount.yaml
    - deployer-serviceaccount.yaml
    - full-ops-serviceaccount.yaml
  - Live demo script examples/raider-configmap-demo.pl
    (Langertha::Raider + MCP::K8s)
  - MCP::Kubernetes alias module for CPAN discoverability
