Gherkin — 18 Operations for AI Agents

Gherkin feature files are executable specifications — the behavior contract shared by product, QA, and CI. act101 maps features, scenarios, and steps structurally, so agents connect a failing build to the behavior it broke.

This page is the canonical reference an AI coding agent uses to refactor, query, and analyze Gherkin 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 Gherkin examples

act101 reads a Gherkin feature file's Feature, Background, and Scenario sections as declarations. The skeleton names each one after its own keyword rather than its title, so Feature:, Background:, and every Scenario: come back with the identical keyword-only name regardless of what the section is actually about. symbols reads a narrower set — Feature and Scenario, not Background — but names each one after its real title instead: the feature's own heading and each scenario's own one-line description. The unit of structure in this grammar is the top-level section: neither query reads the individual Given/When/Then steps inside a scenario, or a scenario's own tags. 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 suite's feature, background, and scenarios as a skeleton

baggage_routing.feature is a transfer-hub acceptance suite: a Background puts the scanner online, one scenario routes a bag with enough connection time, and a second flags a bag with a short connection for manual handling.

$ act query skeleton baggage_routing.feature

Before

Feature: Baggage routing at the transfer hub
  Bags must reach the correct outbound flight before gate close.

  Background:
    Given the transfer hub scanner is online

  Scenario: Bag with enough connection time is routed automatically
    Given a bag tagged for flight "BA118" arrives at "T5-South"
    And the connection window is 90 minutes
    When the bag passes the transfer scanner
    Then the bag is routed to belt "12"
    And the bag status becomes "in transit"

  Scenario: Bag with a short connection is flagged for manual handling
    Given a bag tagged for flight "BA118" arrives at "T5-South"
    And the connection window is 25 minutes
    When the bag passes the transfer scanner
    Then the bag is flagged "short connection"
    And an agent is notified

  Scenario Outline: Oversized bags route to the oversize belt
    Given a bag weighing <weight> kg arrives at "T5-South"
    When the bag passes the transfer scanner
    Then the bag is routed to belt "<belt>"

    Examples:
      | weight | belt |
      | 35     | OS1  |
      | 40     | OS1  |

Output

{
    "type": "Skeleton",
    "declarations": [
        {
            "kind": "function",
            "name": "Feature:",
            "range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 1,
                    "column": 10,
                    "byte_offset": 9
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 1,
                    "column": 45,
                    "byte_offset": 44
                }
            },
            "name_range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 1,
                    "column": 1,
                    "byte_offset": 0
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 1,
                    "column": 9,
                    "byte_offset": 8
                }
            }
        },
        {
            "kind": "function",
            "name": "Background:",
            "range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 2,
                    "column": 65,
                    "byte_offset": 109
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 5,
                    "column": 45,
                    "byte_offset": 169
                }
            },
            "name_range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 2,
                    "column": 65,
                    "byte_offset": 109
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 4,
                    "column": 14,
                    "byte_offset": 124
                }
            }
        },
        {
            "kind": "function",
            "name": "Scenario:",
            "range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 7,
                    "column": 13,
                    "byte_offset": 183
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 7,
                    "column": 68,
                    "byte_offset": 238
                }
            },
            "name_range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 7,
                    "column": 3,
                    "byte_offset": 173
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 7,
                    "column": 12,
                    "byte_offset": 182
                }
            }
        },
        {
            "kind": "function",
            "name": "Scenario:",
            "range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 14,
                    "column": 13,
                    "byte_offset": 489
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 14,
                    "column": 71,
                    "byte_offset": 547
                }
            },
            "name_range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 14,
                    "column": 3,
                    "byte_offset": 479
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 14,
                    "column": 12,
                    "byte_offset": 488
                }
            }
        }
    ]
}

The skeleton reports four declarations — Feature:, Background:, and two entries both named Scenario: — one per section, but every name is the bare keyword rather than the section's own title, so the two scenarios are indistinguishable from each other by name.

List the feature and scenarios as symbols, under their own titles

The feature is titled "Baggage routing at the transfer hub"; its two scenarios are titled for what each one tests.

$ act query symbols baggage_routing.feature

Before

Feature: Baggage routing at the transfer hub
  Bags must reach the correct outbound flight before gate close.

  Background:
    Given the transfer hub scanner is online

  Scenario: Bag with enough connection time is routed automatically
    Given a bag tagged for flight "BA118" arrives at "T5-South"
    And the connection window is 90 minutes
    When the bag passes the transfer scanner
    Then the bag is routed to belt "12"
    And the bag status becomes "in transit"

  Scenario: Bag with a short connection is flagged for manual handling
    Given a bag tagged for flight "BA118" arrives at "T5-South"
    And the connection window is 25 minutes
    When the bag passes the transfer scanner
    Then the bag is flagged "short connection"
    And an agent is notified

  Scenario Outline: Oversized bags route to the oversize belt
    Given a bag weighing <weight> kg arrives at "T5-South"
    When the bag passes the transfer scanner
    Then the bag is routed to belt "<belt>"

    Examples:
      | weight | belt |
      | 35     | OS1  |
      | 40     | OS1  |

Output

{
    "type": "Symbols",
    "symbols": [
        {
            "name": "Baggage routing at the transfer hub",
            "kind": "class",
            "range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 1,
                    "column": 10,
                    "byte_offset": 9
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 1,
                    "column": 45,
                    "byte_offset": 44
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "Bag with enough connection time is routed automatically",
            "kind": "function",
            "range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 7,
                    "column": 13,
                    "byte_offset": 183
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 7,
                    "column": 68,
                    "byte_offset": 238
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "Bag with a short connection is flagged for manual handling",
            "kind": "function",
            "range": {
                "start": {
                    "file": "baggage_routing.feature",
                    "line": 14,
                    "column": 13,
                    "byte_offset": 489
                },
                "end": {
                    "file": "baggage_routing.feature",
                    "line": 14,
                    "column": 71,
                    "byte_offset": 547
                }
            },
            "visibility": "unknown"
        }
    ],
    "parse_error": true
}

symbols reports three declarations: the feature as class, named for its title, and the two scenarios as function, each named for its own one-line description — Background has no rule in symbols.scm and is absent here.

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

← GDShaderGleam →