MCPcopy Index your code
hub / github.com/MacroPower/kat

github.com/MacroPower/kat @v0.28.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v0.28.1 ↗ · + Follow
1,234 symbols 5,187 edges 125 files 561 documented · 45%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README


kat

Go Reference Go Report Card GitHub Downloads Latest tag License

kat automatically invokes manifest generators like helm or kustomize, and provides a persistent, navigable view of rendered resources, with support for live reloading, integrated validation, and more.

It is made of two main components, which can be used together or independently:

  1. A rule-based engine for automatically rendering and validating manifests
  2. A terminal UI for browsing and debugging rendered Kubernetes manifests

Together, these deliver a seamless development experience that maintains context and focus while iterating on Helm charts, Kustomize overlays, and other manifest generators.

❤️ Made with bubble tea, chroma, and other amazing libraries.

✨ Features

🔍️ Manifest browsing

  • Navigate hundreds of resources with fuzzy search and filtering
  • View individual resources in your terminal with syntax highlighting

⚡️ Live reload

  • Monitor source files with --watch for automatic re-rendering
  • Maintain your current context between reloads so you don't lose your place
  • Highlight changes with diff visualization between renders

🐛 Error handling

  • Surface rendering and validation errors as overlays
  • Works with reload; fix source files and watch errors disappear instantly

🧪 Tool integration

  • Define profiles for any manifest generator (Helm, Kustomize, CUE, KCL, Jsonnet, etc.)
  • Run tools like kubeconform or kyverno automatically on rendered manifests
  • Chain multiple tools together with pre and post-render hooks

🎯 Project detection

  • Select your defined profiles automatically using CEL expressions
  • Match projects based on file contents, structure, or naming patterns
  • Support for project-specific runtime configs via .katrc.yaml files

🔌 Plugin system

  • Add custom keybind-triggered commands for your specific workflows
  • Execute dry-runs, deployments, or any custom tooling without leaving kat

🤖 MCP server (Experimental)

  • Limit access to irrelevant context, improving performance and reducing cost
  • Force your AI to always follow the same rendering and validation pipeline
  • Enable iterative testing without handing over cluster or command-line access

🎨 Fully customizable

  • Choose from any available Chroma themes, or define your own
  • Remap any keybinding to match your preferences

📦 Installation

Homebrew

You can install kat using my tap.

With brew:

brew install macropower/tap/kat --cask

With your Brewfile:

tap "macropower/tap"
cask "kat"

Go

go install github.com/macropower/kat/cmd/kat@latest

Docker

Docker images are published to ghcr.io/macropower.

All images are configured with WORKDIR=/data, so you can mount your current directory there to run kat against your local files.

Run the latest alpine image:

docker run -it -v .:/data -e TERM=$TERM ghcr.io/macropower/kat:latest-alpine

The default config is located at /config/kat/config.yaml, and you can override it by mounting your own configuration file at that path.

There is also a scratch image that contains only the kat binary, which is useful when you want to build your own image (which I generally recommend doing):

FROM alpine:latest
COPY --from=ghcr.io/macropower/kat:latest /kat /usr/local/bin/kat
# Add whatever customization you need here.
ENTRYPOINT ["/usr/local/bin/kat"]

Nix (NUR)

You can install kat using my NUR.

With nix-env:

nix-env -iA kat -f https://github.com/macropower/nur-packages/archive/main.tar.gz

With nix-shell:

nix-shell -A kat https://github.com/macropower/nur-packages/archive/main.tar.gz

With your flake.nix:

{
  inputs = {
    macropower.url = "github:macropower/nur-packages";
  };
  # Reference the package as `inputs.macropower.packages.<system>.kat`
}

With devbox:

devbox add github:macropower/nur-packages#kat

GitHub CLI

gh release download -R macropower/kat -p "kat_$(uname -s)_$(uname -m).tar.gz" -O - | tar -xz

And then move kat to a directory in your PATH.

Curl

curl -s https://api.github.com/repos/macropower/kat/releases/latest | \
  jq -r ".assets[] |
    select(.name | test(\"kat_$(uname -s)_$(uname -m).tar.gz\")) |
    .browser_download_url" | \
  xargs curl -L | tar -xz

And then move kat to a directory in your PATH.

Or, download a binary from releases.

Note: The default kat configuration contains references to helm, kustomize, and yq. If you want to use kat with these tools, you will need to install them separately.

🔏 Verification

You can verify the authenticity and integrity of kat releases.

See verification for more details.

🚀 Usage

Show help:

kat --help

Render a project in the current directory:

kat

Render a project and enable watch (live reloading):

kat -w

Render a project in a specific directory:

kat ./example/helm

Render a project in a specific directory using the ks profile:

kat ./example/kustomize ks

Render a project with custom profile arguments:

kat ./example/helm -- -g -f prod-values.yaml

kat ./example/kustomize ks -- --enable-helm

Render a project with command passthrough:

kat ./example/helm task -- helm:render

Read from stdin (disables rendering engine):

cat ./example/kustomize/resources.yaml | kat -

Send output to a file (disables TUI):

kat ./example/helm > manifest.yaml

You can optionally start kat with an MCP server by using the --serve-mcp flag:

kat --serve-mcp :50165

See MCP Server for more details.

⚙️ Configuration

When you first run kat, it will attempt to add default configuration files to $XDG_CONFIG_HOME/kat/ (or ~/.config/kat/). This configuration allows you to customize the behavior of kat, such as the UI style, keybindings, rules for project detection, and profiles for rendering different types of projects.

Note that JSON schemas are also included in the configuration directory, which can be used by your editor's YAML language server.

Some of the default behavior around loading configuration can be overridden with command line flags or environment variables. See kat --help for details.

Over time, the default configuration may change, and the schema is currently still evolving. If you want to reset your configuration to the latest defaults, you can use kat --write-config, which will move your existing configuration to a backup file and generate a new default configuration.

You can find the default configuration file as well as JSON schemas in api.

🛠️ Rules and Profiles

You can customize how kat detects and renders different types of projects using rules and profiles in the configuration file. This system uses CEL (Common Expression Language) expressions to provide flexible file matching and processing.

🎯 Rules

Rules determine which profile should be used. Each rule contains:

  • match (required): A CEL expression that returns true if the rule should be applied
  • profile (required): The name of the profile to use when this rule matches

Rules use boolean CEL expressions with access to:

  • files (list): All file paths in the directory
  • dir (string): The directory path being processed
rules:
  - # Select the Helm profile if any Helm chart files exist
    match: >-
      files.exists(f, pathBase(f) in ["Chart.yaml", "Chart.yml"])
    profile: helm

  - # Select the Kustomize profile if any Kustomization files exist
    match: >-
      files.exists(f, pathBase(f) in ["kustomization.yaml", "kustomization.yml"])
    profile: ks

  - # Fallback: select the YAML profile if any YAML files exist
    match: >-
      files.exists(f, pathExt(f) in [".yaml", ".yml"])
    profile: yaml

🎭 Profiles

Profiles define how to render projects. They can be automatically selected by rules, or manually specified when kat is invoked. Each profile contains:

  • command (required): The command to execute
  • args: Arguments to pass to the command
  • extraArgs: Arguments that can be overridden from the CLI
  • env: List of environment variables for the command
  • envFrom: List of sources for environment variables
  • source: Define which files to watch for changes (when watch is enabled)
  • reload: Define conditions for when events should trigger a reload
  • ui: UI configuration overrides
  • hooks: Initialization and rendering hooks
  • init hooks are executed once when kat is initialized
  • preRender hooks are executed before the profile's command is run
  • postRender hooks are executed after the profile's command has run, and are provided the rendered output via stdin
  • plugins: Custom commands that can be executed on-demand with keybinds
  • description (required): Human-readable description of what the plugin does
  • keys (required): Array of key bindings that trigger the plugin
  • command (required): The command to execute
  • args: Arguments to pass to the command
profiles:
  helm:
    command: helm
    args: [template, .]
    extraArgs: [-g]
    source: >-
      files.filter(f, pathExt(f) in [".yaml", ".yml", ".tpl"])
    reload: >-
      fs.event.has(fs.WRITE, fs.CREATE, fs.REMOVE)
    envFrom:
      - callerRef:
          pattern: "^HELM_.+"
    ui:
      theme: dracula
    hooks:
      init:
        - command: helm
          args: [version, --short]
      preRender:
        - command: helm
          args: [dependency, build]
          envFrom:
            - callerRef:
                pattern: "^HELM_.+"
      postRender:
        # Pass the rendered manifest via stdin to `kubeconform`.
        - command: kubeconform
          args: [-strict, -summary]
    plugins:
      dry-run:
        command: helm
        args: [install, ., -g, --dry-run]
        envFrom:
          - callerRef:
              pattern: "^HELM_.+"
        description: invoke helm dry-run
        keys:
          - code: ctrl+r
            alias: ⌃r

  ks:
    command: kustomize
    args: [build, .]
    source: >-
      files.filter(f, pathExt(f) in [".yaml", ".yml"])
    reload: >-
      fs.event.has(fs.WRITE, fs.CREATE, fs.REMOVE)
    env:
      - name: KUSTOMIZE_ENABLE_ALPHA_COMMANDS
        value: "true"
    ui:
      compact: true
      theme: tokyonight-storm
    hooks:
      init:
        - command: kustomize
          args: [version]

🧩 CEL Functions

kat provides custom CEL functions for use in rules and profiles:

Path Functions:

  • pathBase(string): Returns the filename (e.g., "Chart.yaml")
  • pathExt(string): Returns the file extension (e.g., ".yaml")
  • pathDir(string): Returns the directory path

YAML Functions:

  • yamlPath(file, path): Reads a YAML file and extracts a value using a JSONPath expression

Event Functions:

  • has(event, flag...): Checks if a file system event contains specific flags

File System Constants:

  • fs.CREATE, fs.WRITE, fs.REMOVE, fs.RENAME, fs.CHMOD: File system event types

Render Status Constants:

  • render.STAGE_NONE, render.STAGE_PRE_RENDER, render.STAGE_RENDER, render.STAGE_POST_RENDER: Render stages
  • render.RESULT_NONE, render.RESULT_OK, render.RESULT_ERROR, render.RESULT_CANCEL: Render results

You can combine these with CEL's built-in functions like exists(), filter(), in, contains(), matches(), and logical operators.

Example:

rules:
  - match: >-
      files.exists(f,
        pathBase(f) == "Chart.yaml" &&
        yamlPath(f, "$.apiVersion") == "v2")
    profile: helm

profiles:
  helm:
    command: helm
    args: [template, .]
    extraArgs: [-g]
    source: >-
      files.filter(f,
        pathExt(f) in [".yaml", ".yml", ".tpl"])
    reload: >-
      fs.event.has(fs.WRITE, fs.RENAME) &&
      render.result != render.RESULT_CANCEL

For more details on CEL expressions and examples, see the CEL documentation.

🪄 Project Configuration

Projects can include their own .katrc.yaml file to define project-specific rules and profiles. For example, you can

Extension points exported contracts — how you extend this code

Event (Interface)
Event represents an event related to command execution. [6 implementers]
pkg/command/command.go
Validator (Interface)
Validator validates configuration data against a schema. [6 implementers]
pkg/config/loader.go
Executor (Interface)
Executor executes a profile's commands. [3 implementers]
pkg/profile/profile.go
KeyBindRenderer (Interface)
(no doc) [5 implementers]
pkg/ui/statusbar/help.go
TrustPrompter (Interface)
TrustPrompter handles interactive trust prompts for project configurations. [2 implementers]
pkg/policy/trust.go
CommandRunner (Interface)
(no doc) [3 implementers]
pkg/mcp/server.go
PrintFunc (FuncType)
PrintFunc returns property instance.
pkg/yaml/printer.go
Object (Interface)
Object is the interface that all config types implement.
api/v1beta1/meta.go

Core symbols most depended-on inside this repo

Run
called by 202
pkg/command/command.go
New
called by 153
pkg/keys/keys.go
Error
called by 125
pkg/yaml/error.go
Render
called by 112
pkg/ui/statusbar/help.go
NewBind
called by 87
pkg/keys/keys.go
String
called by 85
pkg/profile/profile.go
NewCommand
called by 59
pkg/execs/command.go
WithArgs
called by 45
pkg/profile/profile.go

Shape

Function 532
Method 516
Struct 134
TypeAlias 23
FuncType 15
Interface 14

Languages

Go100%

Modules by API surface

pkg/ui/list/list.go48 symbols
pkg/ui/configeditor/field_filepicker.go42 symbols
pkg/command/command.go41 symbols
pkg/command/runner.go39 symbols
pkg/ui/pager/pager.go38 symbols
pkg/profile/profile.go33 symbols
pkg/command/runner_test.go31 symbols
pkg/ui/yamls/chroma_test.go30 symbols
pkg/ui/filepicker/filepicker.go30 symbols
pkg/ui/yamls/chroma.go24 symbols
pkg/ui/ui.go24 symbols
pkg/ui/common/common.go23 symbols

For agents

$ claude mcp add kat \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact