Make — 18 Operations for AI Agents
This page is the canonical reference an AI coding agent uses to refactor, query, and analyze Make 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 Make examples
act101 reads a Makefile's two top-level constructs: a rule's target, from target: prerequisites, surfaces as a function declaration named for the target; a variable assignment, whether a plain VAR = value line or a multi-line define VAR ... endef block, surfaces as a variable declaration named for the variable. symbols reports the identical set under the same two kinds — this grammar has no separate nested-declaration tier for symbols to add. The unit of structure is the rule and the assignment: act101 does not read a rule's prerequisite list or its recipe body as declarations of their own. 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 rule targets and variables as a skeleton
firmware.mk builds a signed firmware image: it links firmware.elf, converts it to firmware.bin, signs it into firmware.signed, then flashes it, using two variables and one multi-line define.
$ act query skeleton firmware.mk
Before
TOOLCHAIN := arm-none-eabi
SIGNING_KEY := keys/ota-signing.pem
firmware.elf: boot.o sensor.o
$(TOOLCHAIN)-ld -o firmware.elf boot.o sensor.o
firmware.bin: firmware.elf
$(TOOLCHAIN)-objcopy -O binary firmware.elf firmware.bin
firmware.signed: firmware.bin
openssl dgst -sha256 -sign $(SIGNING_KEY) -out firmware.sig firmware.bin
flash: firmware.signed
dfu-util -a 0 -D firmware.bin
define BUILD_STAMP
echo "Built $(shell date)" > build.stamp
endef
Output
{
"type": "Skeleton",
"declarations": [
{
"kind": "variable",
"name": "TOOLCHAIN",
"range": {
"start": {
"file": "firmware.mk",
"line": 1,
"column": 1,
"byte_offset": 0
},
"end": {
"file": "firmware.mk",
"line": 2,
"column": 1,
"byte_offset": 27
}
},
"name_range": {
"start": {
"file": "firmware.mk",
"line": 1,
"column": 1,
"byte_offset": 0
},
"end": {
"file": "firmware.mk",
"line": 1,
"column": 10,
"byte_offset": 9
}
}
},
{
"kind": "variable",
"name": "SIGNING_KEY",
"range": {
"start": {
"file": "firmware.mk",
"line": 2,
"column": 1,
"byte_offset": 27
},
"end": {
"file": "firmware.mk",
"line": 4,
"column": 1,
"byte_offset": 64
}
},
"name_range": {
"start": {
"file": "firmware.mk",
"line": 2,
"column": 1,
"byte_offset": 27
},
"end": {
"file": "firmware.mk",
"line": 2,
"column": 12,
"byte_offset": 38
}
}
},
{
"kind": "function",
"name": "firmware.elf",
"range": {
"start": {
"file": "firmware.mk",
"line": 4,
"column": 1,
"byte_offset": 64
},
"end": {
"file": "firmware.mk",
"line": 7,
"column": 1,
"byte_offset": 144
}
},
"name_range": {
"start": {
"file": "firmware.mk",
"line": 4,
"column": 1,
"byte_offset": 64
},
"end": {
"file": "firmware.mk",
"line": 4,
"column": 13,
"byte_offset": 76
}
}
},
{
"kind": "function",
"name": "firmware.bin",
"range": {
"start": {
"file": "firmware.mk",
"line": 7,
"column": 1,
"byte_offset": 144
},
"end": {
"file": "firmware.mk",
"line": 10,
"column": 1,
"byte_offset": 230
}
},
"name_range": {
"start": {
"file": "firmware.mk",
"line": 7,
"column": 1,
"byte_offset": 144
},
"end": {
"file": "firmware.mk",
"line": 7,
"column": 13,
"byte_offset": 156
}
}
},
{
"kind": "function",
"name": "firmware.signed",
"range": {
"start": {
"file": "firmware.mk",
"line": 10,
"column": 1,
"byte_offset": 230
},
"end": {
"file": "firmware.mk",
"line": 13,
"column": 1,
"byte_offset": 335
}
},
"name_range": {
"start": {
"file": "firmware.mk",
"line": 10,
"column": 1,
"byte_offset": 230
},
"end": {
"file": "firmware.mk",
"line": 10,
"column": 16,
"byte_offset": 245
}
}
},
{
"kind": "function",
"name": "flash",
"range": {
"start": {
"file": "firmware.mk",
"line": 13,
"column": 1,
"byte_offset": 335
},
"end": {
"file": "firmware.mk",
"line": 16,
"column": 1,
"byte_offset": 390
}
},
"name_range": {
"start": {
"file": "firmware.mk",
"line": 13,
"column": 1,
"byte_offset": 335
},
"end": {
"file": "firmware.mk",
"line": 13,
"column": 6,
"byte_offset": 340
}
}
},
{
"kind": "variable",
"name": "BUILD_STAMP",
"range": {
"start": {
"file": "firmware.mk",
"line": 16,
"column": 1,
"byte_offset": 390
},
"end": {
"file": "firmware.mk",
"line": 19,
"column": 1,
"byte_offset": 457
}
},
"name_range": {
"start": {
"file": "firmware.mk",
"line": 16,
"column": 8,
"byte_offset": 397
},
"end": {
"file": "firmware.mk",
"line": 16,
"column": 19,
"byte_offset": 408
}
}
}
]
}
The skeleton reports TOOLCHAIN and SIGNING_KEY as variable declarations, the four rule targets firmware.elf, firmware.bin, firmware.signed, and flash as function declarations, and the define BUILD_STAMP ... endef block as a third variable; the prerequisite lists and recipe shell commands don't appear.
List the same rules and variables as symbols
The same file signs firmware.bin with openssl dgst before flash runs dfu-util against the signed image.
$ act query symbols firmware.mk
Before
TOOLCHAIN := arm-none-eabi
SIGNING_KEY := keys/ota-signing.pem
firmware.elf: boot.o sensor.o
$(TOOLCHAIN)-ld -o firmware.elf boot.o sensor.o
firmware.bin: firmware.elf
$(TOOLCHAIN)-objcopy -O binary firmware.elf firmware.bin
firmware.signed: firmware.bin
openssl dgst -sha256 -sign $(SIGNING_KEY) -out firmware.sig firmware.bin
flash: firmware.signed
dfu-util -a 0 -D firmware.bin
define BUILD_STAMP
echo "Built $(shell date)" > build.stamp
endef
Output
{
"type": "Symbols",
"symbols": [
{
"name": "TOOLCHAIN",
"kind": "variable",
"range": {
"start": {
"file": "firmware.mk",
"line": 1,
"column": 1,
"byte_offset": 0
},
"end": {
"file": "firmware.mk",
"line": 1,
"column": 10,
"byte_offset": 9
}
},
"visibility": "unknown"
},
{
"name": "SIGNING_KEY",
"kind": "variable",
"range": {
"start": {
"file": "firmware.mk",
"line": 2,
"column": 1,
"byte_offset": 27
},
"end": {
"file": "firmware.mk",
"line": 2,
"column": 12,
"byte_offset": 38
}
},
"visibility": "unknown"
},
{
"name": "firmware.elf",
"kind": "function",
"range": {
"start": {
"file": "firmware.mk",
"line": 4,
"column": 1,
"byte_offset": 64
},
"end": {
"file": "firmware.mk",
"line": 4,
"column": 13,
"byte_offset": 76
}
},
"visibility": "unknown"
},
{
"name": "firmware.bin",
"kind": "function",
"range": {
"start": {
"file": "firmware.mk",
"line": 7,
"column": 1,
"byte_offset": 144
},
"end": {
"file": "firmware.mk",
"line": 7,
"column": 13,
"byte_offset": 156
}
},
"visibility": "unknown"
},
{
"name": "firmware.signed",
"kind": "function",
"range": {
"start": {
"file": "firmware.mk",
"line": 10,
"column": 1,
"byte_offset": 230
},
"end": {
"file": "firmware.mk",
"line": 10,
"column": 16,
"byte_offset": 245
}
},
"visibility": "unknown"
},
{
"name": "flash",
"kind": "function",
"range": {
"start": {
"file": "firmware.mk",
"line": 13,
"column": 1,
"byte_offset": 335
},
"end": {
"file": "firmware.mk",
"line": 13,
"column": 6,
"byte_offset": 340
}
},
"visibility": "unknown"
},
{
"name": "BUILD_STAMP",
"kind": "variable",
"range": {
"start": {
"file": "firmware.mk",
"line": 16,
"column": 8,
"byte_offset": 397
},
"end": {
"file": "firmware.mk",
"line": 16,
"column": 19,
"byte_offset": 408
}
},
"visibility": "unknown"
}
]
}
symbols reports the identical seven entries as skeleton — two variable assignments, four function rule targets, and the BUILD_STAMP define as a third variable — since Make has no nested declaration tier below the rule and the assignment.
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