OK

ovn-kubernetes/ovn-kubernetes-mcp

Developer tools
11 stars 24 forks Quality 72 Trend 28Apache-2.0

Repo hosting the Model Context Protocol Server for troubleshooting OVN-Kubernetes

Overview

Repo hosting the Model Context Protocol Server for troubleshooting OVN-Kubernetes. To use the MCP server, ensure you have Go installed with a version greater than or equal to the version specified in the go.mod file. The server currently supports 2 transport modes: stdio and http. For stdio mode, the server can be run and connected to by using the following configuration in an MCP host (Cursor, Claude, etc.): For http mode, the server should be started separately: The following configuration should be used in an MCP host (Cursor, Claude, etc.) to connect to the server: For offline troubleshooting (e.g., analyzing sosreports, must-gathers), use --mode offline: Must-gather tools require the omc binary. Some must-gather tools also require the ovsdb-tool binary; if it is not available, those tools are not registered.

README

ovn-kubernetes-mcp

Repo hosting the Model Context Protocol Server for troubleshooting OVN-Kubernetes.

Table of Contents


Operating Modes

Mode Description
live-cluster (default) Connect to a live Kubernetes cluster for real-time debugging (requires kubeconfig).
offline Analyze sosreports and must-gathers without cluster access.
dual Exposes tools from dual live-cluster and offline modes (requires kubeconfig for live-cluster tools).

How to connect to the MCP Server

To use the MCP server, ensure you have Go installed with a version greater than or equal to the version specified in the go.mod file.

The server currently supports 2 transport modes: stdio and http.

Command-line options

Option Default Description
--mode live-cluster Server mode: live-cluster, offline, or dual.
--transport stdio Transport: stdio or http.
--host localhost Address the HTTP server binds to (http only). Use 0.0.0.0 in a container so clients can reach the listener.
--port 8080 Port for HTTP transport.
--kubeconfig (none) Path to kubeconfig file. Omit when using in-cluster ServiceAccount credentials (for example the pod deployment); otherwise set for live-cluster and dual.
--pwru-image docker.io/cilium/pwru:v1.0.10 Container image for the pwru network tool (kernel packet tracing).
--tcpdump-image nicolaka/netshoot:v0.15 Container image for the tcpdump network tool (packet capture).
--kernel-image nicolaka/netshoot:v0.15 Container image for kernel tools (conntrack, ip, iptables, nft).
--tool-timeout 120 Timeout in seconds for tool operations. Set to 0 to disable.
--disable-categories (none) Comma-separated tool categories to hide from clients (valid: kernel, kubernetes, must-gather, network-tools, ovn, ovs, sosreport). See Selectively exposing tools.
--disable-tools (none) Comma-separated tool names to hide from clients (e.g. tcpdump,pwru). See Selectively exposing tools.

Live Cluster Mode

For stdio mode, the server can be run and connected to by using the following configuration in an MCP host (Cursor, Claude, etc.):

{
  "mcpServers": {
    "ovn-kubernetes": {
      "command": "go",
      "args": [
        "run",
        "github.com/ovn-kubernetes/ovn-kubernetes-mcp/cmd/ovnk-mcp-server@latest",
        "--kubeconfig",
        "/PATH-TO-THE-KUBECONFIG-FILE"
      ]
    }
  }
}

For http mode, the server should be started separately:

go run github.com/ovn-kubernetes/ovn-kubernetes-mcp/cmd/ovnk-mcp-server@latest --transport http --kubeconfig /PATH-TO-THE-KUBECONFIG-FILE

The following configuration should be used in an MCP host (Cursor, Claude, etc.) to connect to the server:

{
  "mcpServers": {
    "ovn-kubernetes": {
      "url": "http://localhost:8080"
    }
  }
}

Offline Mode

For offline troubleshooting (e.g., analyzing sosreports, must-gathers), use --mode offline:

For stdio mode:

{
  "mcpServers": {
    "ovn-kubernetes": {
      "command": "go",
      "args": [
        "run",
        "github.com/ovn-kubernetes/ovn-kubernetes-mcp/cmd/ovnk-mcp-server@latest",
        "--mode",
        "offline"
      ]
    }
  }
}

For http mode:

go run github.com/ovn-kubernetes/ovn-kubernetes-mcp/cmd/ovnk-mcp-server@latest --transport http --mode offline

Note: Must-gather tools require the omc binary. Some must-gather tools also require the ovsdb-tool binary; if it is not available, those tools are not registered.

Dual Mode

For using dual live-cluster (needs kubeconfig) and offline tools, use --mode dual:

For stdio mode:

{
  "mcpServers": {
    "ovn-kubernetes": {
      "command": "go",
      "args": [
        "run",
        "github.com/ovn-kubernetes/ovn-kubernetes-mcp/cmd/ovnk-mcp-server@latest",
        "--mode",
        "dual",
        "--kubeconfig",
        "/PATH-TO-THE-KUBECONFIG-FILE"
      ]
    }
  }
}

For http mode:

go run github.com/ovn-kubernetes/ovn-kubernetes-mcp/cmd/ovnk-mcp-server@latest --transport http --mode dual --kubeconfig /PATH-TO-THE-KUBECONFIG-FILE

Local development

When developing or building locally, run make build and use the binary path as the command.

  • Use --mode to choose the mode.
  • For live-cluster or dual, add --kubeconfig /path/to/kubeconfig.
  • For offline, omit --kubeconfig.

stdio:

{
  "mcpServers": {
    "ovn-kubernetes": {
      "command": "/PATH-TO-THE-LOCAL-GIT-REPO/_output/ovnk-mcp-server",
      "args": [
        "--mode",
        "",
        "--kubeconfig",
        "/PATH-TO-THE-KUBECONFIG-FILE"
      ]
    }
  }
}

http:

/PATH-TO-THE-LOCAL-GIT-REPO/_output/ovnk-mcp-server --transport http --mode  --kubeconfig /PATH-TO-THE-KUBECONFIG-FILE

For offline mode, omit the --kubeconfig argument in dual examples above.

Kubernetes deployment

The manifests under config/ run the server in the cluster as HTTP (config/deployment.yaml): --transport=http, --host=0.0.0.0, --port=8080, and --mode=live-cluster. There is no --kubeconfig argument in that deployment; the pod uses its ServiceAccount credentials to connect to the Kubernetes API server.

Apply the manifests with:

make deploy-ovnk-mcp-k8s IMAGE=/ovnk-mcp-server:

IMAGE is optional if the image already matches what the manifests expect. Remove the stack with make undeploy-ovnk-mcp-k8s.

Service: a ClusterIP Service ovnk-mcp-server in namespace ovn-kubernetes-mcp exposes port 8080 to the pod (config/service.yaml).

NetworkPolicy: config/networkpolicy.yaml selects the MCP server pod and sets ingress: [], which denies all ingress to that pod from the cluster network. So other workloads cannot reach the MCP HTTP endpoint through the Service, and there is no in-manifest Ingress or LoadBalancer for public access.

Connecting an LLM client (Cursor, Claude, and so on) from your machine: the usual pattern is to use kubectl port-forward from a kube context that can access the cluster. That forwards a local port to the Service without relying on in-cluster ingress to the pod (the forward is set up by the kubelet). In one terminal:

kubectl port-forward -n ovn-kubernetes-mcp svc/ovnk-mcp-server 8080:8080

Then configure the host’s MCP client for streamable HTTP against the forwarded port (same shape as HTTP live-cluster above):

{
  "mcpServers": {
    "ovn-kubernetes": {
      "url": "http://127.0.0.1:8080"
    }
  }
}

Keep the port-forward process running while you use the tools. The server URL is the base of the HTTP transport; clients that implement MCP Streamable HTTP negotiate on top of that.

Security note: the shipped manifests do not add TLS or application-level auth on the MCP HTTP listener. Treat network access as sensitive: use port-forward or private networking, and rely on Kubernetes RBAC (who may port-forward or change NetworkPolicy) to limit who can reach the server.

Allowing only a trusted in-cluster pod: leave config/networkpolicy.yaml in place. For a pod that is allowed to talk to the MCP server (for example a single well-known automation or gateway workload), add a second NetworkPolicy in namespace ovn-kubernetes-mcp. Policies that select the same pod are additive: allowed ingress is the union of every matching policy’s ingress rules, so the deny-all policy keeps every other source blocked while your new policy explicitly permits the trusted peer on port 8080 only.

  1. Give the trusted client pod a narrow, unique label (example below uses app.kubernetes.io/name: ovnk-mcp-trusted-client).
  2. Apply a policy that uses the same podSelector as the shipped policy (MCP server labels: app.kubernetes.io/name: ovn-kubernetes-mcp and app.kubernetes.io/component: mcp-server) and an ingress rule whose from matches only that client, with ports limited to 8080 / TCP.
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: ovnk-mcp-server-allow-trusted-client
  namespace: ovn-kubernetes-mcp
spec:
  podSelector:
    matchLabels:
      app.kubernetes.io/name: ovn-kubernetes-mcp
      app.kubernetes.io/component: mcp-server
  policyTypes:
    - Ingress
  ingress:
    - from:
        - podSelector:
            matchLabels:
              app.kubernetes.io/name: ovnk-mcp-trusted-client
      ports:
        - port: 8080
          protocol: TCP

From that client pod, call the Service at http://ovnk-mcp-server.ovn-kubernetes-mcp.svc:8080 (or the fully qualified *.svc.cluster.local name). If the client runs in another namespace, use a from entry with both namespaceSelector and podSelector as described under Targeting multiple namespaces by label. Prefer explicit labels over wide selectors, and keep trusting this path only for workloads you control—there is still no MCP-level authentication on the wire.


Selectively exposing tools

By default the server registers every tool listed in Tools available in MCP Server. Two CLI flags let you hide specific categories or individual tools so clients never see them in tools/list and any direct tools/call against them is rejected:

Flag Example Effect
--disable-categories --disable-categories=kernel,network-tools Hides every tool registered by the listed categories. Categories are the bold headings in the tool table below (ovn, ovs, kubernetes, kernel, network-tools, sosreport, must-gather). Unknown category names cause the server to refuse to start.
--disable-tools --disable-tools=tcpdump,pwru Hides individual tools by their registered name (the value in the Tool column below). Unknown tool names cause the server to refuse to start, the same as unknown categories.

The two flags can be combined; the union of their resolved tool names is hidden. The startup log line Hiding N tool(s) from clients: ... lists the final set so you can verify the configuration.

Filtering happens at the MCP protocol layer (in middleware), so tools are still registered with the server but never advertised to or callable by clients. Backwards compatible: omitting both flags exposes all tools as before.

Examples

Production-leaning: drop packet capture and the wider kernel toolset.

ovnk-mcp-server --disable-tools=tcpdump,pwru --disable-categories=kernel

Restrict to OVN/OVS introspection and basic Kubernetes lookups.

ovnk-mcp-server --disable-categories=kernel,network-tools,must-gather,sosreport

In a Kubernetes manifest the same options go straight into the container args:

args:
  - --transport=http
  - --host=0.0.0.0
  - --port=8080
  - --mode=live-cluster
  - --disable-tools=tcpdump,pwru
  - --disable-categories=kernel

Full parameter reference: User Guide.

Tools available in MCP Server

Live Cluster Mode

Available when running with --mode live-cluster or --mode dual (and with a valid kubeconfig).

Category Tool Description
kubernetes pod-logs Get container logs from a pod in the Kubernetes cluster.
resource-get Get a specific Kubernetes resource by name.
resource-list List Kubernetes resources of a specific kind.
ovn ovn-show Display a comprehensive overview of OVN configuration from either the Northbound or Southbound database.
ovn-get Query records from an OVN database table with flexible filtering.
ovn-lflow-list List logical flows from the OVN Southbound database.
ovn-trace Trace a packet through the OVN logical network.
ovs ovs-vsctl ovs-vsctl allows to run an ovs-vsctl command against an ovnkube-node pod to inspect the OVS switch configuration.
ovs-ofctl ovs-ofctl allows to run an ovs-ofctl command against an ovnkube-node pod to inspect the OpenFlow state of an OVS bridge.
ovs-appctl ovs-appctl allows to run an ovs-appctl command against an ovnkube-node pod to interact with the OVS daemons for datapath and OpenFlow debugging.
kernel get-conntrack get-conntrack allows to interact with the connection tracking system of a Kubernetes node.
get-iptables get-iptables allows to interact with kernel to list packet filter rules.
get-nft get-nft allows to interact with kernel to list packet filtering and classification rules.
get-ip get-ip allows to interact with kernel to list routing, network devices, interfaces.
network-tools tcpdump Capture network packets on a node or inside a pod with strict safety controls.
pwru Trace packets through the Linux kernel networking stack using eBPF.

Offline Mode

Available when running with --mode offline or --mode dual. No cluster access required.

Category Tool Description
sosreport sos-list-plugins List enabled sosreport plugins with their command counts.
sos-list-commands List all commands collected by a specific sosreport plugin.
sos-search-commands Search for commands across all plugins by pattern.
sos-get-command Get command output using filepath from manifest.
sos-get-pod-logs Get Kubernetes pod container logs from a sosreport.
must-gather must-gather-get-resource Get a specific Kubernetes resource from a must-gather archive.
must-gather-list-resources List Kubernetes resources of a specific kind from a must-gather archive.
must-gather-pod-logs Get container logs from a pod in a must-gather archive.
must-gather-ovnk-info Get OVN-Kubernetes networking information from a must-gather archive.
must-gather-list-northbound-databases List OVN Northbound database files available in a must-gather archive.
must-gather-list-southbound-databases List OVN Southbound database files available in a must-gather archive.
must-gather-query-database Query an OVN database from a must-gather archive using ovsdb-tool.
View the full README on GitHub

Install

This server does not publish a one-line install command.

Open the repository installation guide New to MCP? Start with the mcpskill.org guide →

Configuration

{ "mcpServers": { "ovn-kubernetes": { "command": "go", "args": [ "run", "github.com/ovn-kubernetes/ovn-kubernetes-mcp/cmd/ovnk-mcp-server@latest", "--kubeconfig", "/PATH-TO-THE-KUBECONFIG-FILE" ] } } }