New cli tool for working on config, new irule testing framework, new MCP and Claude Skills
[Tool] f5 — single-file CLI for cleaning, grepping, redacting, and round-tripping BIG-IP configs (zipapp, Python 3.10+)
Hey r/f5networks,
I've been working on a Tcl language server with deep BIG-IP support (github.com/bitwisecook/tcl-lsp) and split out a standalone CLI from it called f5. It's a single-file Python zipapp — no pip install, no venv, just drop the .pyz on your PATH. Posting in case it's useful for anyone here.
What it does
It operates on bigip.conf / SCF / UCS files (and can fetch from a live BIG-IP over iControl REST or SSH). Because it shares a parser and reference graph with the LSP, every verb sees the whole config — virtuals, pools, monitors, profiles, persistence, SNAT pools, data groups, iFiles, GTM wide-IPs, and the iRule bodies that reference them — as one connected object graph.
Verbs grouped by what you're trying to do (the standalone irule CLI from earlier releases is now folded in here as the f5 irule verb group, alongside everything else):
Live BIG-IP round-trip:
f5 fetch— pull SCF or UCS from a live BIG-IP device over iControl REST or SSH (ssh/scp). Credentials resolve from CLI flags, env vars, an XDGhosts.toml, or interactive prompt.f5 pull— fetch a single object (virtual / pool / node / rule) from a live BIG-IP.f5 push— replace or create a single object on a live BIG-IP via iControl REST.
Format conversion & file management:
f5 extract— convert a local UCS archive to an SCF text file.f5 convert— convert between UCS / SCF / AS3 declaration formats.f5 split— split an SCF into per-partition files under a directory (suitable for git).f5 merge— concatenate split per-partition SCFs back into a singlebigip.conf.f5 tmsh— emit atmsh create(or--modify) script that creates every object in the input config, in dependency order, ready to paste into a BIG-IP shell.
Inspection & analysis:
f5 stats— print object counts, partition breakdown, and top-references for a config — the "what's in this thing?" overview.f5 graph— emit the object reference graph as DOT, JSON, or Mermaid.f5 grep— list every BIG-IP object related to a given object path, regex, or CIDR by walking the forward-and-reverse reference graph.--cidr 10.0.0.0/8finds objects that mention an IP in that range anywhere — header, body, or iRule text (catchesclass match … "10.0.0.0/8",IP::client_addr equals "10.0.0.5", etc.).f5 explain— describe the resolved profile / iRule / persistence / SNAT / pool plan for a virtual or pool. "What actually happens to this thing?" in one command.f5 diff— object-aware diff between twobigip.conf/ SCF files; ignores property ordering and iRule whitespace.f5 validate— run BIG-IP best-practice / structural checks (orphans, empty pools, monitor/cert mismatches, etc.).
Cleanup & refactoring:
f5 cleanup— generate atmsh deletescript for every object the config defines but no virtual server (or wide-IP) actually references, in reverse-topological order so each delete runs only after the things that point at it are gone. iRule bodies are walked too (pool …,SSL::profile …,class match …,persist …,snatpool …,node …,LSN::pool …,ifile …,HTTP::respond ifile …), with copy-propagation throughset var /Common/foo; pool $var-style bindings so refs through local variables aren't missed.f5 rename— rename a BIG-IP object's full path and update every reference to it across headers, bodies, and iRule scripts.
**Redaction
f5 redact— strip passwords, PEM blocks, and other secrets, and remap public IPs into a configurable CIDR pool while preserving CIDR relationships (a /24 of real IPs lands in a /24 of redacted IPs). Sidecar map file makes redaction reversible and stable across runs.f5 unredact— reverse a previousf5 redactusing its sidecar map file. Walks the map in reverse over any text, including support emails and log snippets.
PCAP & Wireshark integration:
f5 pcap-remap— apply anf5 redactmap to a PCAP: rewrites IPv4/IPv6 src/dst, recomputes IP and TCP/UDP/ICMP checksums, and parses the F5 Ethernet trailer (legacy + DPT,tcpdump -i 0.0:nnnp) to rewrite peer IPs at schema-known offsets. Schema ported from Wireshark'spacket-f5ethtrailer.c.f5 enrich-pcapng— inject a Name Resolution Block (and optional TLS keylog DSB) into a.pcapngso Wireshark resolves BIG-IP names natively and decrypts TLS sessions inline.f5 enrich-wireshark— generate a Wireshark profile directory (hosts / subnets / vlans / column layouts / coloring rules) tailored to a specific BIG-IP config.f5 explain-flow— for every unique flow in a PCAP, find the matching virtual server and print the per-flow plan: profiles in attach order, LTM policies, APM access profile, expected iRule event firing sequence, the verbatimwhen EVENT { … }body for each event, persistence, SNAT, default pool & members, and any GTM wide-IPs. Optional--tshark/--keylogfor richer L7 + TLS decoding;--simulateruns each matched session under the test orchestrator.
iRules-specific (the old standalone irule CLI is now this verb group):
f5 irule event-order— show the iRules events used in a file in canonical firing order.f5 irule event-info— look up iRules event metadata and the commands that are valid in that event.f5 irule lint— run iRule-only lint rules over abigip.conf/ SCF. Backed by a shared lint registry (irule-deprecated-command,irule-empty-when-block,irule-unknown-event,irule-missing-object, …) that's also used byf5 validate, so whatlintflags is a strict subset ofvalidate.f5 irule trace— static event-flow trace from a starting event — see which events fire next, and which iRule bodies they activate.f5 irule extract— write each iRule body to a standalone.tclfile.f5 irule format(aliasfmt) — pretty-print iRule source with canonical indentation and spacing. Accepts.irul/.irule/.tclfiles,bigip.conf/ SCF / UCS,--sourcesnippets, or stdin. Single rule → stdout (or-o FILE); multiple rules →-o DIRfor one file per rule.f5 irule minify(aliasmin) — strip comments, collapse whitespace, join commands with semicolons.--compactrewrites var/proc names to short identifiers,--symbol-map FILEwrites the original→compacted mapping,--aggressiveruns every optimiser pass then minifies,--isolatedalso compacts globals for self-contained scripts.f5 irule context— bundle each iRule with the BIG-IP objects it references (pools, data groups, persistence profiles, SNAT pools, profiles, monitors, nodes, called rules) plus a one-hop transitive expansion (pool members → nodes; pool monitor → monitor). Designed to be dropped into an LLM prompt. Output as JSON or as a Tcl-flavoured text block;--rule /Common/foo(repeatable) limits output to specific rules.
Shell integration:
f5 completion— print a bash / fish / zsh completion script for thef5CLI (verb names, every flag,*.conf/*.scfpaths).
iRule test framework + Event Orchestrator
Bundled in is an iRule Event Orchestrator — a deterministic test harness that runs in plain tclsh, no BIG-IP required. It simulates the BIG-IP event lifecycle, pool selection, data groups, session/persist tables, SNAT, profiles, and multi-TMM CMP behaviour, so you can finally write proper unit tests for iRules and run them in CI.
Minimal example:
::orch::configure_tests \
-profiles {TCP HTTP} \
-irule { when HTTP_REQUEST { pool web_pool } } \
-setup { ::orch::add_pool web_pool {{10.0.0.1:80}} }
::orch::test "routing-1.0" "basic request goes to web_pool" -body {
::orch::run_http_request -host "example.com" -uri "/"
::orch::assert_that pool_selected equals "web_pool"
}
exit [::orch::done]
Highlights:
- Canonical event firing order driven by configured profiles (TCP / SSL / HTTP / WebSocket / SIP / DNS).
- Stub commands for
pool,node,snat,persist,table,class match,HTTP::*,SSL::*,IP::*,LB::*,session,STATS::*,log,after,clock, … with introspectable side-effects. - Readable assertions (
pool_selected,node_selected,http_respond_status,log_lines,table_get,persist_lookup, …). - Multi-TMM / CMP simulation with a fake CMP distribution function — catches the classic "works on TMM 0 but breaks under CMP spread" bugs (
static::writes in hot events, races ontableshared state). - Auto-generate tests from an iRule's CFG with
generate-test(CLI), thegenerate_irule_testMCP tool, or the "Generate iRule Test" command in VS Code / JetBrains / Sublime / Zed. - Runs in plain
tclsh8.4 / 8.5 / 8.6 / 9.0 → trivial to wire into GitHub Actions / GitLab / Jenkins.
Generate and run:
uv run python -m ai.claude.tcl_ai generate-test path/to/my.irule
tclsh path/to/my.irule.test.tcl
Companion MCP tool + Claude Code skills
The cleanup and PCAP-vs-config pipelines are also reachable from AI tooling, so f5, the MCP server, and the skill pack drive the same Python underneath:
- New MCP tool —
explain_flow— added to the existingtcl-lsp-mcp-server.pyzMCP server. Same compute path asf5 explain-flow, exposed as a typed tool to any MCP-compatible client (Claude Desktop, Cursor, Continue, custom agents). - New MCP tool —
irule_with_context— same compute path asf5 irule context. What an agent should call before reasoning about an iRule end-to-end: the returned bundle carries the rule body plus every referenced BIG-IP object's source (pools, data groups, persistence, SNAT pools, profiles, monitors, nodes, called rules) with optional transitive expansion, so the agent doesn't have to hand-walk the config or be force-fed an entirebigip.conf. - New Claude Code skill —
bigip-cleanup— drives the same reference-graph walker behindf5 cleanup. Ask Claude "find the orphaned objects in this bigip.conf and write me the delete script" and it runs the full pipeline (cleanup report + orderedtmsh deletescript + summary). - New Claude Code skill —
explain-flow— drives the same code asf5 explain-flowand theexplain_flowMCP tool, with a structured narration prompt so the model walks the per-flow plan field by field. Ask "explain this PCAP against the attached config" and you get the matched VIP, profile chain, iRule events that fired, observed pool member, termination cause, and (with--simulate) the actual orchestrator outcome.
Both skills ship in the tcl-lsp-claude-skills-<version>.zip bundle. Install user-level or project-scoped:
unzip tcl-lsp-claude-skills-<version>.zip -d ~/.claude/skills/
# or, project-scoped:
unzip tcl-lsp-claude-skills-<version>.zip -d ./.claude/skills/
Wire the MCP server into Claude Desktop with one entry in claude_desktop_config.json:
{
"mcpServers": {
"tcl-lsp": {
"command": "/path/to/tcl-lsp-mcp-server.pyz"
}
}
}
The Python is shared all the way down, so a fix or feature added to an f5 verb is immediately picked up by the MCP tool and the skill — no parallel implementations to drift apart.
Install (as a .pyz)
Minimum requirements: Python 3.10+. That's literally it — no pip, no venv, no compile step.
mkdir -p ~/.local/bin
curl -L -o ~/.local/bin/f5 \
https://github.com/bitwisecook/tcl-lsp/releases/latest/download/f5-<version>.pyz
chmod +x ~/.local/bin/f5
f5 --help
System-wide is the same file in /usr/local/bin/f5. If you don't trust the shebang, invoke it explicitly: python3 ~/.local/bin/f5 cleanup ….
Optional dependencies
Everything below is opt-in. f5 works without any of them; verbs that use one degrade gracefully when it isn't on PATH.
tshark(Wireshark CLI) — forf5 explain-flow --tsharkand--keylog. Adds HTTP method/Host/URI, TLS SNI/version/cipher/ALPN, TLS alerts, F5 reset cause. With--keylog FILE(NSS-formatSSLKEYLOGFILE), HTTPS payloads decrypt so HTTP decoding works on TLS-wrapped sessions. Without tshark, the built-in libpcap+pcapng walker still handles common TLS ClientHello / HTTP request prefixes.tclsh— forf5 explain-flow --simulateand for running the generated iRule Event Orchestrator test files.--simulatereplays each matched session's iRule with the captured HTTP/TLS state and reports actual pool/node selection,HTTP::responddecisions, log lines, and side-effects (one tclsh subprocess per session). The test framework itself is pure Tcl and runs ontclsh8.4 / 8.5 / 8.6 / 9.0.ssh/scp— forf5 fetch/pull/pushover SSH (the alternative to iControl REST for live BIG-IP round-trip).
Shell completion
f5 completion bash > ~/.local/share/bash-completion/completions/f5
f5 completion fish > ~/.config/fish/completions/f5.fish
f5 completion zsh > "${ZDOTDIR:-$HOME}/.zsh/completions/_f5"
Covers verb names, every flag, and *.conf / *.scf positional paths. --hint prints install instructions alongside the script.
Quick try
f5 cleanup samples/bigip/bigip.conf
f5 grep --cidr 10.0.0.0/8 bigip.conf
f5 explain virtual /Common/my_vs bigip.conf
f5 diff old.scf new.scf
f5 explain-flow capture.pcap bigip.conf --tshark
Repo + releases: https://github.com/bitwisecook/tcl-lsp
Coming next: I'm putting together a web UI for this — drop in a bigip.conf (or point it at a live device) in a browser and get the cleanup report, reference graph, explain virtual view, redact/unredact round-trip, explain-flow PCAP-vs-config trace, and the iRule test orchestrator with results, logs, and pool selection shown next to the iRule source. Same engine underneath, no install beyond a browser. Will post here when it's ready for testers — watch the repo if you want a heads-up.
Happy to take feature requests, bug reports, and "I wish there was a verb that did X" suggestions — especially from anyone with a "we keep meaning to clean this config up" backlog. Cheers.