How RTK Parses and Filters AWS CLI JSON Output for Compact EC2 Listings

RTK forces --output json on AWS CLI commands, deserializes the response with serde_json, and extracts specific EC2 fields into human-readable lines while truncating large result sets and preserving the full JSON via a tee file for later retrieval.

The rtk-ai/rtk repository provides a Rust-based toolkit that treats the AWS CLI as a subprocess while adding intelligent filtering for structured operations. When you run EC2 describe commands, RTK intercepts the verbose JSON output and transforms it into compact, token-friendly listings optimized for LLM consumption.

Command Routing and JSON Acquisition

Dispatching to the Filter Pipeline

When you execute rtk aws ec2 describe-instances, the run function matches the "ec2" and "describe-instances" command pattern in the dispatch table and delegates to run_aws_filtered with filter_ec2_instances as the target filter function. This routing occurs in src/cmds/cloud/aws_cmd.rs at lines 55-68.

Forcing Structured Output with --output json

The run_aws_filtered function never relies on the AWS CLI's default table or text output. Instead, it calls run_aws_json (lines 90-108), which strips any user-supplied output format flags and injects --output json to guarantee machine-readable JSON. This ensures consistent parsing regardless of the user's AWS CLI configuration.

The EC2 Filtering Pipeline

Deserializing AWS JSON with serde_json

Once the AWS CLI returns the raw JSON string, filter_ec2_instances (lines 507-558) deserializes it using serde_json. The filter walks the Reservations → Instances hierarchy, navigating the nested structure where actual instance data resides within the Instances array of each reservation object.

Field Extraction and Line Formatting

For each instance found in the JSON hierarchy, RTK extracts specific fields to build a compact single-line representation:

  • InstanceId: The unique identifier (e.g., i-0123abcd)
  • State.Name: Current lifecycle state (running, stopped, etc.)
  • InstanceType: The size classification (t2.micro, t3.small, etc.)
  • PrivateIpAddress/PublicIpAddress: Network addresses (public shown as "pub:" prefix)
  • SubnetId/VpcId: Networking context identifiers
  • SecurityGroups: List of SG IDs joined by commas and wrapped in brackets
  • Tags → Name: The human-readable Name tag with a "-" fallback

The formatted output follows the pattern: i-0123abcd running t2.micro 10.0.0.5 pub:54.210.12.34 vpc-0a1b2c3d subnet-0e1f2g3h sg:[sg-0a1b2c3d] (my-web-server).

Handling Large Result Sets

RTK caps visible output to MAX_ITEMS (default 20) to prevent context window overflow. When instances exceed this limit, the output appends "... +N more" and sets truncated = true in the FilterResult. The run_aws_filtered function (lines 63-71) then force-tees the complete raw JSON to a side-track file in .rtk/tee/, ensuring the LLM can retrieve full data via the internal slug reference if needed.

Code Example: From Verbose JSON to Compact Listings


# RTK produces compact, filtered output (default max 20 items)

$ rtk aws ec2 describe-instances
EC2: 27 instances
  i-0a1b2c3d4e5f6g7h8 running t2.micro 10.0.1.12 pub:- vpc-01 subnet-02 sg:[sg-03] (web-01)
  i-1b2c3d4e5f6g7h8i9 stopped  t3.small 10.0.1.13 pub:- vpc-01 subnet-02 sg:[sg-03] (db-01)
  ...
  ... +7 more

When truncation occurs, the full JSON remains accessible in the tee directory. For unfiltered access to the raw AWS CLI output, use the proxy command:


# Direct AWS CLI access without RTK filtering

$ rtk proxy aws ec2 describe-instances
{
  "Reservations": [
    {
      "Instances": [
        {
          "InstanceId": "i-0a1b2c3d4e5f6g7h8",
          "State": { "Name": "running" },
          "InstanceType": "t2.micro"
        }
      ]
    }
  ]
}

Summary

  • RTK routes EC2 commands through run_aws_filtered in src/cmds/cloud/aws_cmd.rs (lines 55-68) to enable structured parsing.
  • The system forces --output json via run_aws_json (lines 90-108) to ensure consistent machine-readable input.
  • filter_ec2_instances (lines 507-558) uses serde_json to extract InstanceId, State, Type, IPs, VPC/Subnet, Security Groups, and Name tags into compact single-line formats.
  • Large result sets truncate at 20 items with an overflow indicator, but the full JSON persists in a tee file for complete data retrieval.
  • This architecture balances concise LLM-friendly output with guaranteed access to unfiltered AWS CLI data.

Frequently Asked Questions

How does RTK handle AWS CLI output format flags?

RTK actively strips any user-provided output format flags (like --output table or --output text) and injects --output json via the run_aws_json function. This guarantees that downstream filters always receive valid JSON regardless of the user's default AWS CLI configuration or explicit format arguments.

What EC2 instance fields does RTK extract from the JSON?

According to the filter_ec2_instances implementation in aws_cmd.rs, RTK extracts InstanceId, State.Name, InstanceType, PrivateIpAddress, PublicIpAddress (prefixed as "pub:"), SubnetId, VpcId, SecurityGroups (comma-joined), and the Name tag from the Tags array. These fields provide sufficient context for instance identification without the verbosity of the full AWS response.

How does RTK handle large numbers of EC2 instances?

The filter caps output at MAX_ITEMS (default 20). When the reservation count exceeds this limit, it appends "... +N more" to the listing and sets the truncated flag. Simultaneously, run_aws_filtered force-tees the complete raw JSON to .rtk/tee/ so the full dataset remains accessible through RTK's internal retrieval system even when the display truncates.

Can I access the full JSON if RTK truncates the output?

Yes. When truncation occurs, RTK writes the complete AWS CLI JSON response to a side-track file via the tee mechanism in src/core/tee.rs. While the internal slug isn't exposed to end-users directly, the architecture ensures the LLM can reference and retrieve the full dataset if subsequent queries require fields not shown in the compact listing.

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 →