Skip to content

Chain Combinations

fsuite tools communicate via two pipe-friendly output modes:

  • -o paths — one file path per line (the pipe currency)
  • -o json — structured data for programmatic decisions

The rule: producers output paths, consumers read paths from stdin.

ToolFlagWhat it produces
fsearch-o pathsFile paths matching a glob/name pattern
fcontent-o pathsFile paths containing a literal string
ToolStdin behaviorNotes
fcontentReads paths, searches inside themup to 2000 files
fmapReads paths, maps symbolsup to 2000 files
fread--from-stdin --stdin-format=pathsup to --max-files
fedit--targets-file -batch patches

ftree, fprobe, fcase, freplay, fmetrics take arguments only — they don’t accept piped path lists, so they sit at chain endpoints, not in the middle. The stdin-capable consumers above (fcontent, fmap, fread, fedit) can be in the middle of a chain or at an endpoint depending on whether you feed them stdin.

⚠ MCP CALLERS — SEQUENTIAL LIMIT

If you call fsuite tools through the MCP server, every call is sequential. The MCP protocol does not pipe — the agent constructs the chain by calling tools one at a time and reusing prior results.

Escape hatch: install fsuite as native Debian package or shell scripts and pipe directly. You can keep fbash as your MCP entry point and run real Unix pipes inside it: fbash "fsearch -o paths '*.py' | fmap -o json". That unlocks combination calls instead of being trapped in sequential MCP.

ChainPurposeExample
fsearch | fcontentFind files by name, search insidefsearch -o paths '*.py' src | fcontent "def authenticate"
fsearch | fmapFind files, map symbolsfsearch -o paths '*.rs' src | fmap -o json
fcontent | fmapFind files containing text, map symbolsfcontent -o paths "TODO" src | fmap -o json
fcontent | fcontentProgressive narrowingfcontent -o paths "import" src | fcontent "authenticate"
fsearch fcontent fmap
fsearch -o paths '*.py' | fcontent -o paths "class" | fmap -o json
Terminal window
fsearch -o paths '*.sh' \
| fcontent -o paths "function" \
| fmap -o json \
| python3 -c "..."

Tested: produced 1956 symbols from the fsuite repo in one pipeline.

Pattern 1 — “What uses this function?”

Section titled “Pattern 1 — “What uses this function?””
Terminal window
fcontent -o paths "authenticate" src | fmap -o json

Pattern 2 — “Find all Python tests and see what they test”

Section titled “Pattern 2 — “Find all Python tests and see what they test””
Terminal window
fsearch -o paths 'test_*.py' tests | fmap -o json

Pattern 3 — “Which configs mention this key?”

Section titled “Pattern 3 — “Which configs mention this key?””
Terminal window
fsearch -o paths '*.json' . | fcontent "api_key"
fcase init ftree fsearch │ fcontent fmap fread fedit fcase resolve
Terminal window
ftree --snapshot -o json /project
fsearch -o paths '*.rs' src | fcontent -o paths "pub fn" | fmap -o json
fread src/auth.rs --symbol authenticate
fcase init auth-fix --goal "Fix authenticate bypass"
fedit src/auth.rs --function authenticate --replace "return true" --with "return verify(token)"
fmetrics stats
Terminal window
fprobe scan binary --pattern "renderTool" --context 300
fprobe window binary --offset 112730723 --before 50 --after 200
fprobe strings binary --filter "diffAdded"

The key move: use fedit --symbol for each symbol instead of doing a text-replace across files. Zero ambiguity.

fcontent fsearch fmap fedit --symbol
initopen the seam
notecapture evidence
handoffpass to next agent
resolveclose + archive

Rerun a traced investigation step-by-step. Useful for post-mortems and regression tests.

Terminal window
freplay --session <id>

Ask the telemetry database what worked last time and what probably works next.

fmetrics import fmetrics stats fmetrics predict
ChainWhy it fails
fread | anythingfread outputs file content, not paths
fedit | anythingfedit outputs diffs, not paths
ftree | fcontentftree outputs a tree, not paths
fmap | freadfmap outputs symbol data, not paths
fprobe | anythingfprobe outputs JSON/text, not paths
fcase | anythingfcase outputs investigation state, not paths