GN — 18 Operations for AI Agents
GN files generate the build behind Chromium-scale projects — targets, deps, and configs across thousands of directories. act101 reads those declarations structurally, so agents trace a build target through the tree without grep archaeology.
This page is the canonical reference an AI coding agent uses to refactor, query, and analyze GN 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.
Worked GN examples
act101 reads a GN build file's three top-level constructs: an import() statement surfaces as an import, named for the imported .gni path; a top-level variable assignment surfaces as a variable; and a named target or config block — action("name") { ... }, config("name") { ... }, or any other call whose first argument is a string — surfaces as a function, named for that string rather than the call's own identifier. symbols covers the variable and named-target cases too, but reports the two kinds differently: a top-level assignment keeps kind: variable, while a named target comes back kind: unknown, since only the assignment rule's underlying node maps to a stated kind. The unit of structure this grammar exposes is the target's declared name, the first string argument passed to whatever function declares it. 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 import, variables, and named targets as a skeleton
BUILD.gn packages a sensor daemon into a container image: it imports container.gni, sets image_name and base_image, then declares a build_rootfs action, a sensor_agent_image target, and an image_defaults config.
$ act query skeleton BUILD.gn
Before
import("//build/container.gni")
image_name = "sensor-agent"
base_image = "distroless/static"
action("build_rootfs") {
script = "//tools/build_rootfs.py"
outputs = [ "$target_out_dir/rootfs.tar" ]
}
container_image("sensor_agent_image") {
base = base_image
entrypoint = [ "/sensor-agent" ]
rootfs = ":build_rootfs"
}
config("image_defaults") {
defines = [ "IMAGE_NAME=\"$image_name\"" ]
}
Output
{
"type": "Skeleton",
"declarations": [
{
"kind": "import",
"name": "//build/container.gni",
"range": {
"start": {
"file": "BUILD.gn",
"line": 1,
"column": 1,
"byte_offset": 0
},
"end": {
"file": "BUILD.gn",
"line": 1,
"column": 32,
"byte_offset": 31
}
},
"name_range": {
"start": {
"file": "BUILD.gn",
"line": 1,
"column": 9,
"byte_offset": 8
},
"end": {
"file": "BUILD.gn",
"line": 1,
"column": 30,
"byte_offset": 29
}
}
},
{
"kind": "variable",
"name": "image_name",
"range": {
"start": {
"file": "BUILD.gn",
"line": 3,
"column": 1,
"byte_offset": 33
},
"end": {
"file": "BUILD.gn",
"line": 3,
"column": 28,
"byte_offset": 60
}
},
"name_range": {
"start": {
"file": "BUILD.gn",
"line": 3,
"column": 1,
"byte_offset": 33
},
"end": {
"file": "BUILD.gn",
"line": 3,
"column": 11,
"byte_offset": 43
}
}
},
{
"kind": "variable",
"name": "base_image",
"range": {
"start": {
"file": "BUILD.gn",
"line": 4,
"column": 1,
"byte_offset": 61
},
"end": {
"file": "BUILD.gn",
"line": 4,
"column": 33,
"byte_offset": 93
}
},
"name_range": {
"start": {
"file": "BUILD.gn",
"line": 4,
"column": 1,
"byte_offset": 61
},
"end": {
"file": "BUILD.gn",
"line": 4,
"column": 11,
"byte_offset": 71
}
}
},
{
"kind": "function",
"name": "build_rootfs",
"range": {
"start": {
"file": "BUILD.gn",
"line": 6,
"column": 1,
"byte_offset": 95
},
"end": {
"file": "BUILD.gn",
"line": 6,
"column": 23,
"byte_offset": 117
}
},
"name_range": {
"start": {
"file": "BUILD.gn",
"line": 6,
"column": 9,
"byte_offset": 103
},
"end": {
"file": "BUILD.gn",
"line": 6,
"column": 21,
"byte_offset": 115
}
}
},
{
"kind": "function",
"name": "sensor_agent_image",
"range": {
"start": {
"file": "BUILD.gn",
"line": 11,
"column": 1,
"byte_offset": 205
},
"end": {
"file": "BUILD.gn",
"line": 11,
"column": 38,
"byte_offset": 242
}
},
"name_range": {
"start": {
"file": "BUILD.gn",
"line": 11,
"column": 18,
"byte_offset": 222
},
"end": {
"file": "BUILD.gn",
"line": 11,
"column": 36,
"byte_offset": 240
}
}
},
{
"kind": "function",
"name": "image_defaults",
"range": {
"start": {
"file": "BUILD.gn",
"line": 17,
"column": 1,
"byte_offset": 330
},
"end": {
"file": "BUILD.gn",
"line": 17,
"column": 25,
"byte_offset": 354
}
},
"name_range": {
"start": {
"file": "BUILD.gn",
"line": 17,
"column": 9,
"byte_offset": 338
},
"end": {
"file": "BUILD.gn",
"line": 17,
"column": 23,
"byte_offset": 352
}
}
}
]
}
The skeleton reports the import declaration named //build/container.gni, image_name and base_image as variable declarations, and build_rootfs, sensor_agent_image, and image_defaults as function declarations, each named for the target's own string argument.
List the variables and named targets as symbols
sensor_agent_image reads base_image for its base attribute and depends on build_rootfs through the rootfs attribute.
$ act query symbols BUILD.gn
Before
import("//build/container.gni")
image_name = "sensor-agent"
base_image = "distroless/static"
action("build_rootfs") {
script = "//tools/build_rootfs.py"
outputs = [ "$target_out_dir/rootfs.tar" ]
}
container_image("sensor_agent_image") {
base = base_image
entrypoint = [ "/sensor-agent" ]
rootfs = ":build_rootfs"
}
config("image_defaults") {
defines = [ "IMAGE_NAME=\"$image_name\"" ]
}
Output
{
"type": "Symbols",
"symbols": [
{
"name": "image_name",
"kind": "variable",
"range": {
"start": {
"file": "BUILD.gn",
"line": 3,
"column": 1,
"byte_offset": 33
},
"end": {
"file": "BUILD.gn",
"line": 3,
"column": 11,
"byte_offset": 43
}
},
"visibility": "unknown"
},
{
"name": "base_image",
"kind": "variable",
"range": {
"start": {
"file": "BUILD.gn",
"line": 4,
"column": 1,
"byte_offset": 61
},
"end": {
"file": "BUILD.gn",
"line": 4,
"column": 11,
"byte_offset": 71
}
},
"visibility": "unknown"
},
{
"name": "build_rootfs",
"kind": "unknown",
"range": {
"start": {
"file": "BUILD.gn",
"line": 6,
"column": 9,
"byte_offset": 103
},
"end": {
"file": "BUILD.gn",
"line": 6,
"column": 21,
"byte_offset": 115
}
},
"visibility": "unknown"
},
{
"name": "sensor_agent_image",
"kind": "unknown",
"range": {
"start": {
"file": "BUILD.gn",
"line": 11,
"column": 18,
"byte_offset": 222
},
"end": {
"file": "BUILD.gn",
"line": 11,
"column": 36,
"byte_offset": 240
}
},
"visibility": "unknown"
},
{
"name": "image_defaults",
"kind": "unknown",
"range": {
"start": {
"file": "BUILD.gn",
"line": 17,
"column": 9,
"byte_offset": 338
},
"end": {
"file": "BUILD.gn",
"line": 17,
"column": 23,
"byte_offset": 352
}
},
"visibility": "unknown"
}
]
}
symbols reports image_name and base_image as variable, and build_rootfs, sensor_agent_image, and image_defaults as kind: unknown; the import statement itself doesn't appear.
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