How to Configure Custom TOML Filters in RTK for Specific Projects

Configure custom TOML filters in RTK by creating a .rtk/filters.toml file in your project root, defining filter rules using the TOML DSL, and marking the file as trusted with rtk trust .rtk/filters.toml so that TomlFilterRegistry loads it at runtime.

RTK is an extensible command runner that uses TOML-based output filtering to clean up and transform command output before displaying it. By configuring custom TOML filters in RTK for specific projects, you can strip debug noise, truncate long logs, and highlight errors without modifying the underlying tools. This project-local configuration lives in your repository and is parsed dynamically, allowing you to tailor output processing to each codebase.

How RTK Loads Filter Configurations

RTK builds a filter registry at runtime by searching for TOML definitions in a strict priority order (first match wins). According to the source code in src/core/toml_filter.rs【L5-L8】, the hierarchy is:

  1. Project-local .rtk/filters.toml — stored in the repository root and loaded only when the file is trusted
  2. User-global ~/.config/rtk/filters.toml — applies to every project
  3. Built-in filters compiled into the binary from src/filters/*.toml【L31-L33】
  4. Passthrough — if no TOML matches, the command runs unfiltered

The registry is instantiated by TomlFilterRegistry::load() in src/core/toml_filter.rs【L85-L103】, which parses the TOML and prepares the filtering pipeline without requiring recompilation.

Creating a Trusted Project-Local Filter

To use a custom filter for a single repository, you must create the file in a specific location and explicitly authorize it.

File Location and Trust Requirements

Place your configuration at .rtk/filters.toml in the project root. RTK will ignore this file until you mark it as trusted. Run the trust command from your repository root:

rtk trust .rtk/filters.toml

This command calculates the SHA256 hash of the file and stores it in ~/.local/share/rtk/trust.db. On every subsequent run, RTK verifies the hash against the recorded value in src/hooks/trust.rs【L191-L199】 to prevent execution of untrusted code.

The Trust Security Model

The trust mechanism exists because TOML filters execute regex transformations that could potentially expose sensitive data or modify output maliciously. Until you explicitly trust the file, RTK skips the project-local filter and falls back to user-global or built-in rules.

TOML Filter DSL Reference

The filter syntax is documented in src/filters/README.md【L27-L62】. Each filter is defined under a [filters.<name>] table with the following fields:

  • description (string) — Human-readable summary of the filter’s purpose.
  • match_command (regex) — Pattern that determines which commands trigger this filter.
  • strip_ansi (bool) — Remove ANSI escape sequences before applying other rules.
  • strip_lines_matching / keep_lines_matching (regex[]) — Arrays of patterns to drop or preserve lines.
  • replace ([{ pattern, replacement }]) — Array of regex substitution objects.
  • match_output ([{ pattern, message }]) — Short-circuit: return message if pattern matches the entire output.
  • truncate_lines_at (int) — Maximum characters per line.
  • max_lines, head_lines, tail_lines (int) — Limit the number of lines kept.
  • on_empty (string) — Fallback text when filtering removes all content.
  • filter_stderr (bool) — Merge stderr into stdout before filtering.

Inline Testing

You can validate filters by adding test cases directly in the TOML. These are executed by cargo test or rtk test to prevent regressions【L41-L45】:

[[tests.mytool]]
name = "removes debug lines"
input = """
INFO: start
DEBUG: hidden detail
RESULT: success
"""
expected = """
INFO: start
RESULT: success
"""

Step-by-Step Configuration Guide

Follow these steps to activate a custom filter for your project:

  1. Create the directory .rtk/ in your repository root if it does not exist.
  2. Create .rtk/filters.toml and define your filter using the TOML DSL.
  3. Trust the file by running rtk trust .rtk/filters.toml to authorize RTK to load it.
  4. Run your command — RTK now applies the custom filter before printing output.

All processing happens at runtime; no recompilation of RTK is required.

Working Example: Cleaning Build Output

Here is a complete .rtk/filters.toml that strips noisy debug lines from a fictional mytool command and limits output to 30 lines:

[filters.mytool]
description = "Strip noisy 'debug' lines from mytool output"
match_command = "^mytool\\b"
strip_ansi = true

# Remove empty lines and lines starting with "DEBUG:"

strip_lines_matching = [
  "^\\s*$",
  "^DEBUG:",
]

# Keep at most 30 lines after stripping

max_lines = 30

# Friendly note when everything is filtered away

on_empty = "mytool: no relevant output"

[[tests.mytool]]
name = "removes debug lines"
input = """
INFO: start
DEBUG: hidden detail
RESULT: success
"""
expected = """
INFO: start
RESULT: success
"""

Explanation: The filter activates for any command starting with mytool. It first strips ANSI codes, then removes empty lines and debug statements, and finally truncates to 30 lines. If all lines are removed, it displays the on_empty message. Running cargo test validates the [[tests.mytool]] block against the expected output.

Trusting and Running the Filter


# In the project root:

rtk trust .rtk/filters.toml

# Output:

# [rtk] .rtk/filters.toml trusted (sha256: <hash>)

# Now run the command:

rtk mytool --verbose-flag

The output will be filtered according to your TOML rules.

Summary

  • RTK searches for filters in the order: project-local .rtk/filters.toml, user-global ~/.config/rtk/filters.toml, then built-in src/filters/*.toml.
  • Project-local filters require explicit trust via rtk trust .rtk/filters.toml to prevent untrusted code execution, with hashes stored in ~/.local/share/rtk/trust.db.
  • The TomlFilterRegistry::load() function in src/core/toml_filter.rs dynamically parses TOML at runtime.
  • The TOML DSL supports regex-based line filtering, replacements, truncation, and inline test cases defined in src/filters/README.md.

Frequently Asked Questions

What is the priority order for filter loading in RTK?

RTK checks for TOML filter definitions in four locations in descending priority: first the project-local .rtk/filters.toml (if trusted), then the user-global ~/.config/rtk/filters.toml, followed by built-in filters compiled from src/filters/*.toml, and finally falls back to unfiltered passthrough if none match. This hierarchy is implemented in src/core/toml_filter.rs【L5-L8】.

How do I debug a custom TOML filter that is not applying?

First, verify the file is trusted by running rtk trust .rtk/filters.toml again—RTK skips untrusted project-local files silently. Second, check that your match_command regex actually matches your command invocation. Finally, add inline [[tests]] blocks and run rtk test or cargo test to validate your regex patterns without running the full command.

Can I use regular expressions in all pattern fields?

Yes, any field ending in _matching or named pattern accepts valid regular expressions. This includes match_command, strip_lines_matching, keep_lines_matching, and the pattern keys inside replace and match_output arrays. Refer to src/filters/README.md【L27-L62】 for the complete syntax reference.

Where does RTK store trust records for project filters?

Trust hashes are stored in ~/.local/share/rtk/trust.db. Each time you run a command, RTK recalculates the SHA256 hash of .rtk/filters.toml and compares it against this database, as defined in src/hooks/trust.rs【L191-L199】. If the file is modified, you must re-run rtk trust to update the stored hash.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →