jq — 18 Operations for AI Agents

jq filters are how JSON gets reshaped in pipelines everywhere — extraction, transformation, one-liners promoted to production. act101 reads filter programs as structure, so agents understand what a transformation does before the data hits it.

This page is the canonical reference an AI coding agent uses to refactor, query, and analyze jq code through the act MCP server. 18 operations available: 0 refactor, 18 query, 0 analysis. Each operation is callable from Claude Code, Cursor, Codex, OpenCode, or any MCP-compatible agent host. Click any operation for a stable anchor link suitable for citation.

18Query

Worked jq examples

act101 reads a jq script's function definitions — def name: body; or def name(args): body; — as declarations; that is the only construct the skeleton surfaces, so a script built entirely from filter pipelines and no def reports no declarations at all. symbols covers the same function definitions and adds one more construct the skeleton does not read: variable bindings introduced with EXPR as $name. Both a function name and a bound variable come back kind: unknown in symbols, since the rule's @definition capture states no kind and jq's generic identifier/variable node kinds carry none by default. The unit of structure in this grammar is the top-level definition or binding: neither query descends into a function's own filter pipeline or its parameter list. Each example below is the verbatim output of the command shown, run against the file shown. Query outputs are pretty-printed with the timing block omitted.

Read the fleet rollout helpers as a skeleton

rollout-batch.jq defines three functions — is_stale, needs_update, and rollout_batch — that together select devices due for a firmware update.

$ act query skeleton rollout-batch.jq

Before

def is_stale($max_age): .last_seen_days > $max_age;

def needs_update: .current_version != .target_version;

def rollout_batch($max_age):
  [.devices[] | select(is_stale($max_age) and needs_update)];

.fleet_name as $fleet
| rollout_batch(30)
| map({fleet: $fleet, device_id, current_version, target_version})

Output

{
    "type": "Skeleton",
    "declarations": [
        {
            "kind": "function",
            "name": "is_stale",
            "range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 1,
                    "column": 1,
                    "byte_offset": 0
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 1,
                    "column": 52,
                    "byte_offset": 51
                }
            },
            "name_range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 1,
                    "column": 5,
                    "byte_offset": 4
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 1,
                    "column": 13,
                    "byte_offset": 12
                }
            }
        },
        {
            "kind": "function",
            "name": "needs_update",
            "range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 3,
                    "column": 1,
                    "byte_offset": 53
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 3,
                    "column": 55,
                    "byte_offset": 107
                }
            },
            "name_range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 3,
                    "column": 5,
                    "byte_offset": 57
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 3,
                    "column": 17,
                    "byte_offset": 69
                }
            }
        },
        {
            "kind": "function",
            "name": "rollout_batch",
            "range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 5,
                    "column": 1,
                    "byte_offset": 109
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 6,
                    "column": 62,
                    "byte_offset": 199
                }
            },
            "name_range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 5,
                    "column": 5,
                    "byte_offset": 113
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 5,
                    "column": 18,
                    "byte_offset": 126
                }
            }
        }
    ]
}

The skeleton reports exactly these three function declarations; the script's own .fleet_name as $fleet binding and its filter pipeline are not read.

List the functions and the fleet-name binding as symbols

The script also binds $fleet from .fleet_name before running the rollout filter.

$ act query symbols rollout-batch.jq

Before

def is_stale($max_age): .last_seen_days > $max_age;

def needs_update: .current_version != .target_version;

def rollout_batch($max_age):
  [.devices[] | select(is_stale($max_age) and needs_update)];

.fleet_name as $fleet
| rollout_batch(30)
| map({fleet: $fleet, device_id, current_version, target_version})

Output

{
    "type": "Symbols",
    "symbols": [
        {
            "name": "is_stale",
            "kind": "unknown",
            "range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 1,
                    "column": 5,
                    "byte_offset": 4
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 1,
                    "column": 13,
                    "byte_offset": 12
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "needs_update",
            "kind": "unknown",
            "range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 3,
                    "column": 5,
                    "byte_offset": 57
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 3,
                    "column": 17,
                    "byte_offset": 69
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "rollout_batch",
            "kind": "unknown",
            "range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 5,
                    "column": 5,
                    "byte_offset": 113
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 5,
                    "column": 18,
                    "byte_offset": 126
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "$fleet",
            "kind": "unknown",
            "range": {
                "start": {
                    "file": "rollout-batch.jq",
                    "line": 8,
                    "column": 16,
                    "byte_offset": 216
                },
                "end": {
                    "file": "rollout-batch.jq",
                    "line": 8,
                    "column": 22,
                    "byte_offset": 222
                }
            },
            "visibility": "unknown"
        }
    ]
}

symbols adds $fleet to the same three functions, for four entries total, but reports every one as kind: unknown, since none of symbols.scm's rules state an explicit kind.

Query

18 query tools, the same on every supported language. Descriptions live in the shared reference: /docs/query-tools.

callers control_flow data_flow definition diagnostics effect_closure effect_summary fix_auto get_type graph import_organize interface mutations references repo_outline skeleton symbols symbols_batch

← JinjaJSDoc →