Developer Guide

Set up a complete local development environment with a single command.

Table of contents

  1. Overview
  2. Prerequisites
  3. Quick Start
    1. 1. Build the CLI
    2. 2. Create the development environment
    3. 3. Follow the printed instructions
  4. Step-by-Step Walkthrough
    1. Set kubeconfig to access hub cluster
    2. Login to authenticate to the hub
    3. Create a site in the hub
    4. Wait for the site kubeconfig secret and extract it
    5. Deploy the agent into the agent cluster
    6. Verify the agent is connected
  5. Command Reference
    1. kedge dev init
    2. kedge dev update
    3. kedge dev delete
  6. Configuration
    1. Hub cluster
    2. Agent cluster
    3. Docker network
  7. Useful Commands
  8. Troubleshooting
    1. Tilt-cluster E2E: a resource never becomes Ready
    2. Hub chart not found
    3. Agent can’t connect to hub
    4. Site kubeconfig secret not created
    5. Cluster already exists
  9. Architecture
  10. MCP Integration
    1. URL format
    2. Getting the URL
    3. Kubernetes resource
    4. How it works

Overview

The kedge dev command creates a complete local development environment with:

  • Hub cluster — A kind cluster running kedge-hub with embedded kcp
  • Agent cluster — A second kind cluster for deploying the kedge-agent

Both clusters share a Docker network, allowing the agent to connect to the hub.


Prerequisites

Tool Description
Docker Container runtime (must be running)
kind Kubernetes in Docker (installed automatically by the command)
Helm For deploying the agent chart

Quick Start

1. Build the CLI

make build-kedge

2. Create the development environment

./bin/kedge dev init --worker-count 1 --chart-path deploy/charts/kedge-hub

This creates two kind clusters:

  • kedge-hub — Hub cluster with kedge-hub installed
  • kedge-agent — Worker cluster (empty, ready for agent deployment)

The default --worker-count is 0 (hub only). Use --worker-count N to spin up additional worker kind clusters when developing agents.

3. Follow the printed instructions

The command outputs step-by-step instructions for:

  1. Setting up kubeconfig
  2. Logging into the hub
  3. Creating a site
  4. Deploying the agent

Step-by-Step Walkthrough

Set kubeconfig to access hub cluster

export KUBECONFIG=kedge-hub.kubeconfig

Login to authenticate to the hub

kedge login --hub-url https://kedge.localhost:9443 --insecure-skip-tls-verify --token=dev-token

Create a site in the hub

kedge site create my-site --labels env=dev

Wait for the site kubeconfig secret and extract it

kubectl get secret -n kedge-system site-my-site-kubeconfig \
  -o jsonpath='{.data.kubeconfig}' | base64 -d > site-kubeconfig

The secret is created automatically after the site is registered.

Deploy the agent into the agent cluster

First, create a namespace and secret with the site kubeconfig:

kubectl --kubeconfig kedge-agent.kubeconfig create namespace kedge-system

kubectl --kubeconfig kedge-agent.kubeconfig create secret generic site-kubeconfig \
  -n kedge-system \
  --from-file=kubeconfig=site-kubeconfig

Then install the agent Helm chart:

helm install kedge-agent deploy/charts/kedge-agent \
  --kubeconfig kedge-agent.kubeconfig \
  -n kedge-system \
  --set agent.edgeName=my-edge \
  --set agent.hub.existingSecret=site-kubeconfig

Verify the agent is connected

kedge site list
kedge site get my-site

The site should show tunnelConnected: true and have a recent heartbeat.


Command Reference

kedge dev init

Initializes a local kedge environment.

kedge dev init [flags]

Flags:

Flag Default Description
--hub-cluster-name kedge-hub Name of the hub kind cluster
--agent-cluster-name kedge-agent Name of the worker (agent) kind cluster(s)
--worker-count 0 Number of worker kind clusters (0 = hub only)
--chart-path oci://ghcr.io/faroshq/charts/kedge-hub Hub Helm chart (local path or OCI)
--chart-version (auto) Helm chart version (for OCI charts)
--image ghcr.io/faroshq/kedge-hub Hub container image
--tag (auto) Hub image tag
--kind-network kedge-dev Docker network for kind clusters
--wait-for-ready-timeout 2m Timeout waiting for cluster readiness

--agent-count is accepted as a deprecated alias for --worker-count.

Examples:

# Hub-only local environment (end users)
kedge dev init

# Hub + 1 worker (typical developer setup)
kedge dev init --worker-count 1 --chart-path deploy/charts/kedge-hub

# Hub + 3 workers
kedge dev init --worker-count 3

# Published OCI chart, pinned version
kedge dev init --chart-path oci://ghcr.io/faroshq/charts/kedge-hub --chart-version 0.1.0

kedge dev update

Upgrades the kedge-hub Helm release on the existing hub kind cluster (image, tag, chart version, …). Kind clusters themselves are not modified.

kedge dev update [flags]

kedge dev delete

Deletes the local kedge environment.

kedge dev delete [flags]

This removes the hub kind cluster, any worker kind clusters that were created (pass the same --worker-count you used at init time), and cleans up kubeconfig files.


Configuration

Hub cluster

The hub cluster is configured with:

  • Port mappings: localhost:9443 -> hub service
  • NodePort service on port 31443
  • Self-signed TLS certificate
  • Static auth token: dev-token
  • Dev mode enabled (relaxed security)

Agent cluster

The agent cluster is a plain kind cluster with no special configuration. The agent is deployed via Helm chart and connects to the hub through the shared Docker network.

Docker network

Both clusters are created on the kedge-dev Docker network, allowing them to communicate using container IPs. The hub’s internal IP is displayed after cluster creation.


Useful Commands

# List all sites
kedge site list

# Get site details
kedge site get my-site

# Check agent logs
kubectl --kubeconfig kedge-agent.kubeconfig logs \
  -n kedge-system \
  -l app.kubernetes.io/name=kedge-agent -f

# Check hub logs
kubectl --kubeconfig kedge-hub.kubeconfig logs \
  -n kedge-system \
  -l app.kubernetes.io/name=kedge-hub -f

# Delete the dev environment
kedge dev delete

Troubleshooting

Tilt-cluster E2E: a resource never becomes Ready

The Tilt E2E workflow waits for each Tilt resource (e.g. kedge-hub) to reach update=ok runtime=ok. When one times out, the wait helper now prints a collapsible diagnostics for stuck resource '<name>' group in the job log containing: the resource’s own Tilt logs (e.g. the hub’s klog stdout, which shows where bootstrap stalled), a cluster-wide kubectl get pods -A, a describe + log tail for every non-Running pod, and the recent cluster events. Open that group first when a run times out — it usually points straight at the stuck step (slow kcp bootstrap, a crashlooping pod, an image pull, …).

Hub chart not found

If you see:

Error: failed to locate OCI chart: ghcr.io/faroshq/charts/kedge-hub:0.1.0: not found

Use the local chart path instead:

kedge dev init --chart-path deploy/charts/kedge-hub

Agent can’t connect to hub

  1. Check the hub is running:
    kubectl --kubeconfig kedge-hub.kubeconfig get pods -n kedge-system
    
  2. Verify the site kubeconfig has the correct hub IP:
    cat site-kubeconfig | grep server
    

    The server URL should use the hub’s Docker network IP, not localhost.

  3. Check agent logs:
    kubectl --kubeconfig kedge-agent.kubeconfig logs \
      -n kedge-system \
      -l app.kubernetes.io/name=kedge-agent
    

Site kubeconfig secret not created

The secret is created by the hub’s RBAC controller after the site is registered. Wait a few seconds and check:

kubectl get secret -n kedge-system site-my-site-kubeconfig

If it doesn’t appear, check hub logs for errors.

Cluster already exists

If the clusters already exist, the command will skip creation and reuse them. To start fresh:

kedge dev delete
kedge dev init --chart-path deploy/charts/kedge-hub

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                     Docker Network (kedge-dev)                  │
│                                                                 │
│  ┌─────────────────────────┐    ┌─────────────────────────┐   │
│  │   kedge-hub cluster     │    │   kedge-agent cluster   │   │
│  │                         │    │                         │   │
│  │  ┌───────────────────┐  │    │  ┌───────────────────┐  │   │
│  │  │    kedge-hub      │  │◄───┼──│   kedge-agent     │  │   │
│  │  │  (StatefulSet)    │  │    │  │   (Deployment)    │  │   │
│  │  └───────────────────┘  │    │  └───────────────────┘  │   │
│  │                         │    │                         │   │
│  │  Port: 31443 (NodePort) │    │                         │   │
│  └───────────┬─────────────┘    └─────────────────────────┘   │
│              │                                                  │
└──────────────┼──────────────────────────────────────────────────┘
               │
               ▼
        localhost:9443
        (for CLI access)

The agent establishes a reverse WebSocket tunnel to the hub, allowing the hub to proxy API requests to the agent’s cluster.


MCP Integration

kedge exposes all connected Kubernetes clusters as a single Model Context Protocol (MCP) server.

URL format

https://<hub>/services/mcp/<workspace-cluster-id>/apis/kedge.faros.sh/v1alpha1/kubernetesmcps/<name>/mcp

Getting the URL

kedge mcp url --name default

This prints the URL and a ready-to-use claude mcp add command with your bearer token.

Kubernetes resource

A default Kubernetes object is auto-created in every tenant workspace. It selects which kubernetes-type edges are included via spec.edgeSelector (empty = all connected kubernetes edges).

How it works

  1. The hub’s MCP virtual workspace handler validates the bearer token.
  2. Lists all Edge objects in the workspace, filters to spec.type: kubernetes + connected + label selector.
  3. Builds a MultiEdgeKedgeEdgeProvider that dials each edge over its revdial tunnel.
  4. Passes control to kubernetes-mcp-server which implements the MCP protocol.

See DEVELOPERS.md for the full internals reference.