Tags, Filters and Group By
Use tags, grouping and filters to organize port forwards in the desktop app, kftui and the CLI.
Tags let you label configs by team, environment or another value you choose. Use grouping and filters to organize the list and choose which configs appear.
Watch the tags walkthrough video for these features in the app.
kftray saves the view settings, so the desktop app and kftui use the same grouping and filters. By default, they group configs by context without filters.
Tags
A tag is a key=value pair, like team=payments or env=prod, or a bare key, like pinned. Tags are optional and live in the configuration JSON:
{
"alias": "payments-api",
"service": "payments-api",
"namespace": "payments",
"context": "prod-eu",
"local_port": 8080,
"remote_port": 80,
"tags": {
"team": "payments",
"env": "prod",
"pinned": ""
}
}kftray stores a key without a value as an empty string. Configs without tags don't need the field, and exports skip it when it's empty.
| Rule | Detail |
|---|---|
| Keys | Lowercase letters, digits, ., _, - and /, up to 63 characters |
| Values | Up to 128 characters, no , or = |
| Normalization | kftray removes spaces at the start and end of keys and values. It also converts keys to lowercase |
| Duplicates | kftray rejects two keys that match after normalization, like Env and env |
Tags travel with the configuration, so exports, imports and GitHub sync include them.
Editing tags
Open the add or edit dialog and use the "Tags" field. Type team=payments or pinned and press Enter to add a tag. The field suggests keys and values that other configurations already use.
Invalid tags show an error under the field and block saving. Each key holds one value, so to change a value, remove the old tag first.
Group by
Choose one of these fields to group configs:
| Field | Groups by |
|---|---|
context | Kubernetes context (default) |
namespace | Kubernetes namespace |
kubeconfig | Kubeconfig file |
workload_type | service, pod, proxy or expose |
protocol | tcp or udp |
tag:<key> | The value of a tag, like tag:team |
none | A single list with everything |
kftray sorts groups alphabetically. Configs without the grouping field appear in an "Ungrouped" section at the end. For example, grouping by tag:team puts configs without a team tag there. When a tag has no value, such as pinned, its key becomes the group name.
Filters
Filters narrow the list to the configurations you want. You can filter by any field you can group by.
- Several values of the same field match any of them. Setting
namespacetoapiandwebshows both namespaces. - Filters on different fields must all match.
env=prodpluscontext=prod-eushows only prod configurations inprod-eu. - "Has tag" matches any configuration with that key, whatever its value.
Search narrows the filtered list and also matches tags. In the desktop app, "Start All" starts only visible configs. "Stop All" stops every running forward, including those hidden by a filter.
Desktop app
The view controls sit in the toolbar next to "Start All" and "Stop All":
| Control | What it does |
|---|---|
| Group by (layers icon) | Choose the field to group by. The icon turns blue when the grouping isn't the default context grouping |
| Filter (funnel icon) | Pick values to filter by. Each value shows its config count. A badge on the icon shows the number of active filters |
| Expand/collapse | Expand or collapse every group |
The filter menu lists active filters at the top. You can remove each one or use "Clear all". If nothing matches your search and filters, the list shows a button that clears both.
Terminal (kftui)
Press v to open the view popup. It lists grouping options, a "has tag" row for each tag key and each value you can filter by.
| Key | Action |
|---|---|
↑ ↓ | Move through the options |
Enter / Space | Pick a group by option or toggle a filter |
c | Clear all filters |
Esc / v | Close the popup |
Changes apply right away. When you group by a field other than context, a "Group" column shows each group's name on its first row.
Selections are cleared
Changing the view or saving tags reorders the tables, so kftui clears the rows you marked with Space. That stops bulk actions like delete or start from hitting configurations that moved into those rows.
CLI
kftui accepts the same filters and grouping as flags:
# Start only the payments team's forwards, without the TUI
kftui --auto-start --non-interactive --filter tag:team=payments
# Filters are repeatable and must all match
kftui --auto-start --filter tag:env=dev --filter namespace=api,web
# Only configurations that have the "pinned" tag
kftui --auto-start --filter tag:pinned
# Open the TUI grouped by a tag
kftui --group-by tag:team| Flag | Format |
|---|---|
--filter <COND> | field=value1,value2, tag:<key>=value or tag:<key> for "has tag". Repeat the flag to add conditions |
--group-by <FIELD> | context, namespace, kubeconfig, workload_type, protocol, tag:<key> or none |
With --auto-start, kftui starts only matching configurations. When configs come from --configs-path, --json, --stdin or --github-url, it starts only the imported configurations that match.
The flags apply to that session only and leave the saved view unchanged. kftui rejects an invalid field or tag key before it starts.
MCP server
The MCP server uses the same tags and filter syntax:
create_configandupdate_configtake atagsmap.update_configreplaces the whole map, and an empty map{}removes all tags.list_configstakesfilters, a list of conditions in the--filtersyntax, for example["tag:env=dev"]or["namespace=api,web"]. All conditions must match.