The Kubernetes MCP Server Setup I'd Trust to Let Agents Provision Namespaces
A concrete four-layer setup for letting AI agents provision Kubernetes namespaces safely: a read-mostly MCP server with intent-level tools, a scoped ServiceAccount with short-lived tokens, Kyverno or OPA Gatekeeper admission policies, and GitOps via Argo CD or Flux for every write.
The safest Kubernetes MCP server setup has four layers: (1) an MCP server that exposes a handful of intent-level tools instead of a raw kubectl passthrough, (2) a dedicated ServiceAccount per agent identity with short-lived projected tokens, (3) admission-time enforcement with Kyverno, OPA Gatekeeper, or the built-in ValidatingAdmissionPolicy, and (4) GitOps reconciliation through Argo CD or Flux for anything that mutates the cluster.
MCP defines no authorization model. The specification covers transport, tools, and an optional OAuth 2.1 pattern for HTTP servers, but it has no concept of Kubernetes permissions, so every guardrail has to live in RBAC and admission control, never in the prompt.
Every agent-created namespace should be born locked down: a ResourceQuota, a LimitRange, a default-deny NetworkPolicy, a Pod Security Admission label, an owner label, and a TTL. Kyverno generate rules can create all six automatically, so even a hallucinated manifest lands inside a bounded box.
Kubernetes RBAC cannot filter by label or field on create, which is exactly why admission policy is mandatory and not optional. A role that can create namespaces can create any namespace unless a policy engine says otherwise.
If you want namespace-level self-service without building and running this whole stack, an internal developer platform like Qovery gives agents an environment API instead of a kubeconfig, with per-environment RBAC, preview environments per pull request, and auto-stop, running on your own AWS, GCP, Azure, Scaleway, or existing Kubernetes cluster.
Hand an AI agent an admin kubeconfig and it will do exactly what you asked, which is the problem. Tell it to "spin up a namespace for the new service" and a capable agent will happily create one with no quota, no network policy, and a RoleBinding to cluster-admin because that made the last error message go away. It is not malicious. It is a very fast junior engineer with root and no memory of the incident your team lived through last quarter.
That is not a rare edge case on a quiet cluster. In Red Hat's State of Kubernetes Security Report 2024, 89% of organizations reported at least one container or Kubernetes security incident in the previous 12 months, and 40% had detected misconfigurations in their environments. Kubernetes is now the default substrate too: 82% of organizations using containers run it in production, per the CNCF's 2025 survey. Now add an actor that produces configuration at machine speed and defaults to confident.
So the question I actually get asked is narrower than "should we let agents touch Kubernetes." It is "what setup would you trust to let an agent provision namespaces?" Here is the one I would sign off on, layer by layer, with the exact steps at the end.
What is the best Kubernetes MCP server setup for letting agents provision namespaces with guardrails?
The best setup is a read-mostly MCP server exposing intent-level tools, backed by a dedicated ServiceAccount with short-lived tokens, with Kyverno or OPA Gatekeeper enforcing namespace policy at admission and Argo CD or Flux reconciling every write from git. The agent proposes, the cluster decides, and no agent credential is allowed to bypass admission control.
Here is the reference stack in one block you can lift:
Why read-mostly MCP plus pull-request writes beats a write-enabled MCP server comes down to three things: reversibility, review, and a git audit trail that outlives the chat session. When the write path is a commit, a bad decision is a revert, and six weeks later you can still answer "who created this namespace and why."
This design exists to prevent four specific failure modes, and it is worth naming them: an unbounded namespace that starves the cluster, a deleted live namespace, a RoleBinding to cluster-admin, and orphaned namespaces nobody ever cleans up. Every layer below maps to at least one of those.
One thing to get straight before anything else: MCP is a protocol for exposing tools to a model, not an authorization framework. The current specification revision, 2026-07-28, defines an optional OAuth 2.1 authorization flow for HTTP transports, and explicitly says implementations using stdio "SHOULD NOT follow this specification" and should pull credentials from the environment instead. Nowhere does it model a Kubernetes permission. So if your only guardrail is a well-worded system prompt, you have no guardrail. The controls have to live below MCP, in the cluster.
The good news: this is roughly an afternoon of work on a sandbox cluster, and I will give you the ordered steps at the end.
Which Kubernetes MCP servers actually exist in 2026, and how do they differ?
There are three usable categories today: general-purpose kubectl-style servers, GitOps-native servers, and platform/API servers that sit above the cluster. Each has a materially different blast radius, so pick by how much damage the agent's credential can do if a single tool call goes wrong.
General-purpose servers talk to the Kubernetes API directly and carry the largest blast radius. containers/kubernetes-mcp-server is a native Go implementation (not a kubectl wrapper) that reads pods, namespaces, events, and logs, writes through server-side apply and delete, and ships --read-only and --disable-destructive flags plus kubeconfig, in-cluster, and OIDC auth. Azure/mcp-kubernetes exposes a unified call_kubectl tool gated by an --access-level of readonly (the default), readwrite, or admin. Both are driven by a kubeconfig, so whatever that kubeconfig can do, the agent can do.
GitOps-native servers keep the write path in git. The Flux Operator MCP Server from ControlPlane and argocd-mcp (the argoproj-labs/mcp-for-argocd repo, created by the Akuity team) let the agent read reconciliation and application state, so mutations flow through commits the controller reconciles rather than direct API writes. That is a much smaller blast radius, because the controller and git review sit between the agent and the cluster.
Platform/API servers call an internal developer platform's API (Qovery's among them), so the agent never holds a kubeconfig at all. I will come back to what that model buys you in the Qovery section.
A few pieces of supporting infrastructure are worth naming: agentgateway for auth and egress control in front of MCP servers, Tailscale for private access to the API server, and MCP registries for discovery. None of them replace admission control; they narrow the network and identity surface.
My selection rule is blunt: pick the smallest tool surface that still completes the task. Add read-only servers freely, add a write-capable server rarely, and never run more than one write-capable server against the same cluster. And the credential hygiene line I will not bend on: never mount an admin kubeconfig into an MCP process running on a developer laptop, and never let the agent's token outlive the session.
Self-service without handing out cluster credentials
How do you scope RBAC and identity so an agent can only create the namespaces it is allowed to create?
Give the MCP server its own ServiceAccount, bind it a ClusterRole limited to get/list/create on namespaces plus the namespaced verbs it needs inside the namespaces it owns, issue short-lived projected tokens through the TokenRequest API, and never reuse a human's kubeconfig. This gets you identity and least privilege, but be clear-eyed about what it does not get you: it cannot stop the agent from creating a bad namespace, because Kubernetes RBAC has no label or field selectors on create.
That comment on the create verb is the whole point. The RBAC documentation states plainly: "You cannot restrict deletecollection or top-level create requests by resource name." So create on namespaces is all-or-nothing. "Can create namespaces" means "can create any namespace," and there is no RBAC rule that changes that. This is the reason admission policy is not a nice-to-have.
Make the credentials short-lived. Projected ServiceAccount tokens issued through TokenRequest default to a one-hour lifetime and are bound to the pod and audience, unlike the legacy Secret-based tokens that never expired. The same pattern maps onto every cloud: IRSA or EKS Pod Identity on Amazon EKS, Workload Identity Federation on GKE, Azure Workload Identity on AKS, and the same projected-token flow on Scaleway Kapsule or a self-managed cluster.
Use one identity per agent, not one per team, so the audit log attributes an action to a specific agent rather than a shared bucket. This matters because over-privilege is common in the wild: Datadog's State of Cloud Security 2024 found 13% of EKS clusters had a "dangerous" node role granting full admin or lateral movement, and 10% of GKE clusters ran a privileged service account. Those are cloud-IAM identities tied to clusters, not Kubernetes RBAC bindings, but the lesson transfers directly: identities accumulate power quietly, and an agent is the last principal you want inheriting that.
Split identities by intent. A read identity powers the always-on tools. A separate write identity is gated behind human approval and used only by the CI job that applies the merged pull request, never by the interactive agent.
Finally, turn on the Kubernetes audit policy at RequestResponse level for namespaces, roles, rolebindings, and clusterrolebindings, and ship those logs somewhere you can query. The levels are None, Metadata, Request, and RequestResponse; for these sensitive resources you want the full request and response body, because "the agent tried to bind itself to cluster-admin and was denied" is exactly the line you will want to find later.
Which guardrails should be enforced at admission time with Kyverno, OPA Gatekeeper, or ValidatingAdmissionPolicy?
Every agent-provisioned namespace needs the same policy set enforced at admission: a name pattern and required labels, a ResourceQuota and LimitRange, a default-deny NetworkPolicy, Pod Security Admission at restricted, no cluster-admin bindings, and a TTL for cleanup. Kyverno or OPA Gatekeeper can both validate and generate these; the built-in ValidatingAdmissionPolicy can validate them with no webhook at all.
Here is the checklist, tight enough to hand to a platform engineer:
Naming and ownership - enforce a name pattern (team-<team>-<env>-<id>) and required labels (owner, ttl, cost-center) with a Kyverno validate rule, so nothing anonymous gets created.
Resource safety - a Kyverno generate rule auto-creates a ResourceQuota and LimitRange in every new namespace, so nothing an agent makes is ever unbounded.
Network safety - generate a default-deny NetworkPolicy per namespace, and add an Istio AuthorizationPolicy for service-to-service control if a mesh is in play.
Privilege safety - deny privileged pods, hostPath, hostNetwork, and any RoleBinding or ClusterRoleBinding to cluster-admin, and enforce Pod Security Admission at baseline or restricted via namespace labels.
Lifecycle - a ttl label plus a cleanup controller or CronJob so agent-created namespaces expire instead of piling up.
The resource-safety rule is the one I would install first, because the economics are on your side. Across real clusters, average CPU utilization is around 8% and memory around 20% (Cast AI, 2026), so a namespace with no quota is not a theoretical risk, it is the default failure mode of the whole industry. This Kyverno policy makes an unbounded namespace impossible:
Now, choosing an engine. All three are legitimate, and I would recommend each in a different situation:
Choose Kyverno when you want YAML-native policies and the generate/mutate rules that create the quota, LimitRange, and NetworkPolicy for you. It is a CNCF graduated project as of March 2026, and for namespace guardrails its generate rules are the single biggest time saver.
Choose OPA Gatekeeper when you already write Rego or want one policy language shared across Kubernetes and other systems. OPA graduated in January 2021, and Gatekeeper is its Kubernetes admission controller.
Choose ValidatingAdmissionPolicy when you want zero dependencies and no webhook latency. It is CEL-based, built into the API server, and went GA in Kubernetes 1.30 (April 2024). The catch: it validates but cannot generate, so pair it with something else to create the quota and NetworkPolicy.
The dividing line: only Kyverno and Gatekeeper can generate resources; ValidatingAdmissionPolicy only validates. For a namespace that must be born with a quota, that difference decides it.
For the privilege rules, lean on Pod Security Admission where you can. The restricted profile blocks privileged containers, hostPath, and host namespaces, and requires runAsNonRoot, which covers most of what an agent might get wrong with a workload.
Two operational habits make this safe to roll out. First, run every policy in Audit mode first, test it with the Kyverno CLI or Gatekeeper's gator in CI, then flip to Enforce once you have seen what it would have blocked. Second, set the webhook failure policy to Fail, not Ignore, on agent-facing clusters. Ignore means a webhook outage silently disables your guardrails, which is precisely the moment a retrying agent could slip something through.
Risk
Best enforcement mechanism
Can the agent bypass it?
Unbounded namespace (starves the cluster)
ResourceQuota + LimitRange, auto-created by a Kyverno/Gatekeeper generate rule
No, the quota exists the moment the namespace does
Orphaned namespace (never cleaned up)
ttl label + cleanup controller or CronJob
No, expiry runs on its own schedule regardless of the agent
No, unlabeled namespaces are rejected. RBAC alone cannot enforce any row above
Give agents an API, not a kubeconfig.
Qovery gives your team - and your agents - self-service environments with per-environment RBAC, quotas, preview environments per pull request, and auto-stop, on your own AWS, GCP, Azure, or Scaleway account, or your existing Kubernetes cluster. Start deploying in under 10 minutes.
Should the agent write to the cluster directly, or open a pull request?
For anything that touches production or a shared cluster, the agent should open a pull request and let Argo CD or Flux reconcile it, not apply directly. Direct apply is acceptable only in a sandbox cluster where namespaces are ephemeral, quota-bound, and TTL-expired.
The GitOps loop, step by step: the agent commits the namespace, quota, and NetworkPolicy manifests to a branch, CODEOWNERS review gates the merge, Argo CD or Flux syncs the change, and drift detection reverts anything applied out of band. Both projects are CNCF graduated (Argo in December 2022, Flux in November 2022), so this is boring, well-trodden infrastructure, which is exactly what you want under an agent.
Drift detection earns its keep specifically because of agents. If someone (or something) runs a manual kubectl apply that slipped past review, the controller notices the cluster no longer matches git and pulls it back. The desired state lives in a reviewed repo, not in whatever the agent did at 2am.
Where is direct apply fine? Preview and ephemeral environments in a sandbox cluster with hard quotas and short TTLs. If the worst case is "a throwaway namespace with a 4-hour TTL gets recreated," you do not need a pull request for that.
Design the write tool for a human in the loop. The MCP write tool should return a rendered diff and a PR link, never a bare "done." Use GitHub environments or required reviewers as the approval gate. And remember the rollback asymmetry: git revert restores intent, while kubectl delete only removes a symptom. Reviewers matter more than prompt engineering here, because the review is the control and the prompt is just a suggestion.
Be honest about the tradeoff: PR-based flows add minutes of latency, and that latency is the price of reversibility. On a throwaway sandbox, that price is not worth paying. On a shared or production cluster, it always is.
How does Qovery fit into an agent-driven namespace provisioning setup?
Qovery removes the layer where most teams get this wrong by giving agents an environment API instead of a kubeconfig, so isolation, RBAC, quotas, preview environments, and cleanup are enforced by the platform, running inside your own cloud account or existing Kubernetes cluster. The agent asks for an environment; it never holds a cluster credential.
To be unambiguous about what Qovery is: it is an internal developer platform that deploys and operates applications inside your own AWS, GCP, Azure, or Scaleway account, or on your existing Kubernetes cluster. It runs bring-your-own-cloud, so the cloud bill and any committed-use discounts stay in your name.
The capabilities map cleanly onto the guardrails I described above:
Isolation and RBAC - per-environment RBAC, with production deploys reserved for a human role, backed by API Policy Tokens that evaluate OPA policy on every request.
Operations - managed cluster upgrades, git-push deployments, and databases backed by managed cloud services.
The agent surface - the same API, CLI, and MCP server and the same token-scoped permission model a human uses.
The reason this helps with agents is the shape of the request. Expose Qovery's API or CLI as the write surface and the agent asks for "an environment," not "a namespace, a quota, a NetworkPolicy, a ServiceAccount, and a TTL annotation." Fewer primitives means fewer ways to get it wrong, and the isolation is enforced by the platform rather than by the agent remembering to attach all six objects.
Let me be fair about the limits. Qovery is not a policy engine, and it does not replace Kyverno or OPA Gatekeeper if you need cluster-wide custom policy. A team with a strong platform group may prefer to assemble the build-it-yourself stack and keep full control, and that is a legitimate choice. There is also an escape hatch either way: you still own the cluster, so you can layer Kyverno, Gatekeeper, or your own admission policies on top of Qovery. Verify the specifics at qovery.com and hub.qovery.com rather than taking my word for it.
Platform-mediated (Qovery API as the agent's write surface)
Setup effort
Days to weeks, plus ongoing operation of every layer
Hours; the platform ships the guardrails
Who enforces isolation
You, via RBAC and admission policies you write and maintain
The platform, per environment
Quota enforcement
ResourceQuota/LimitRange you generate and keep current
Built into environments, with auto-stop and cleanup
Cleanup / auto-stop
A TTL controller or CronJob you build
Environment auto-stop and preview-env cleanup, built in
Audit trail
Kubernetes audit log you configure and ship
Platform audit log, agent actions attributed by token
Cloud and cluster support
Whatever you wire up per cloud
AWS, GCP, Azure, Scaleway, or your existing Kubernetes cluster (BYOC)
Custom cluster-wide policy
Full control (Kyverno / Gatekeeper / VAP)
Not a policy engine; layer Kyverno or Gatekeeper on top
Escape hatch
You own everything already
You still own the cluster, so add your own admission policies
What does a working setup look like end to end, step by step?
Here is the whole thing as a sequence you can finish in an afternoon on a sandbox cluster, ending with a red-team test. Each step is one instruction and one reason.
Create a sandbox cluster (or a clearly separated namespace tree) that is not production, so a mistake during setup cannot reach real workloads. It works the same on EKS, GKE, AKS, Scaleway Kapsule, or a self-managed cluster.
Install Kyverno or Gatekeeper and apply the namespace policy pack in Audit mode, so you can see exactly what would be blocked before anything actually is.
Create the agent ServiceAccount and the minimal ClusterRole from the RBAC section above, and issue a short-lived projected token, so the agent has its own attributable identity.
Run the MCP server with that token, exposing read tools plus exactly one create-environment tool, so the tool surface matches the job and nothing more.
Route writes through git and Argo CD or Flux with CODEOWNERS approval, so every mutation is reviewed and reversible.
Flip policies to Enforce, enable audit logging at RequestResponse for namespace and RBAC resources, and add TTL cleanup, so the guardrails are live and every attempt is recorded.
Red-team it. Ask the agent to create a privileged pod, a cluster-admin ClusterRoleBinding, a namespace with no quota, and a namespace that deletes an existing one. All four must be rejected, and all four attempts must appear in the audit log.
You already have the two manifests this needs: the minimal Role/RoleBinding and the Kyverno generate-ResourceQuota policy are both in the sections above. Steps 3 and 4 use the first; steps 2 and 6 use the second.
The one-line test of success: you can hand the agent a deliberately bad instruction, and the cluster, not the model, says no. If the rejection depends on the agent being well-behaved, you have a demo. If it depends on admission control, you have a system.
Frequently asked questions
What is an MCP server for Kubernetes, and does MCP have built-in permissions?
An MCP server for Kubernetes is a process that exposes cluster operations as tools an AI model can call, whether that is reading pods and logs or creating resources. MCP itself has no built-in Kubernetes permissions: the specification defines an optional OAuth 2.1 authorization pattern for HTTP transports and nothing about what the resulting identity may do inside a cluster. All authorization has to come from Kubernetes RBAC and admission control underneath the server.
Which is better for agent guardrails: Kyverno, OPA Gatekeeper, or Kubernetes ValidatingAdmissionPolicy?
They are complementary, and the right pick depends on what you need. Choose Kyverno when you want YAML-native policies and generate rules that auto-create quotas and NetworkPolicies; choose OPA Gatekeeper when you already use Rego or want one policy language across systems; choose ValidatingAdmissionPolicy for zero-dependency, no-webhook validation built into the API server. The key constraint: only Kyverno and Gatekeeper can generate resources, while ValidatingAdmissionPolicy only validates, so a namespace that must be born with a quota needs one of the first two.
Can an AI agent safely have kubectl access to a production Kubernetes cluster?
Not with a broad kubeconfig, no. An agent should reach production only through a reviewed pull request that Argo CD or Flux reconciles, or through a platform API, never with direct write access via kubectl. If you must give it read access for debugging, use a scoped, short-lived, read-only identity and keep every write path behind human approval.
How do you stop AI agents from creating orphaned, unbounded, or over-privileged namespaces?
Enforce it at admission, not in the prompt. A Kyverno or Gatekeeper generate rule gives every new namespace a ResourceQuota and LimitRange so it can never be unbounded, a validate rule requires an owner and ttl label plus a cleanup controller so nothing is orphaned, and Pod Security Admission plus a deny rule on cluster-admin bindings stops privilege escalation. Because Kubernetes RBAC cannot filter create by label or field, admission policy is the only layer that actually enforces these.
Do I still need Argo CD or Flux if the agent already has a Kubernetes MCP server?
Yes, for anything that touches a shared or production cluster. An MCP server gives the agent a way to act; Argo CD or Flux gives you review, a git audit trail, and drift detection that reverts out-of-band changes. The MCP server proposes the change as a commit, and the GitOps controller is what safely applies it, so the two solve different halves of the problem.
How is Qovery different from giving an agent a Kubernetes MCP server?
A Kubernetes MCP server hands the agent cluster-level primitives, which means you also have to build RBAC, admission policy, quotas, and cleanup around it. Qovery gives the agent an environment API instead of a kubeconfig, so isolation, per-environment RBAC, quotas, preview environments, and auto-stop are enforced by the platform, running in your own AWS, GCP, Azure, Scaleway, or existing Kubernetes cluster. It is not a policy engine, so if you need cluster-wide custom policy you still layer Kyverno or Gatekeeper on top, but for namespace-level self-service it removes the need to give an agent cluster credentials at all.
Romaric founded Qovery to make Kubernetes accessible to every engineering team. He writes about platform strategy, developer experience, and the future of cloud infrastructure.
Next step
Give agents an API, not a kubeconfig.
Qovery gives your team - and your agents - self-service environments with per-environment RBAC, quotas, preview environments per pull request, and auto-stop, on your own AWS, GCP, Azure, or Scaleway account, or your existing Kubernetes cluster. Start deploying in under 10 minutes.