Arduino — 18 Operations for AI Agents

Arduino sketches are how ideas become hardware: setup, loop, sensor reads, pin writes. act101 gives agents the sketch's structure at a glance, so embedded prototyping stays fast even as sketches grow past the prototype.

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

act101 reads an Arduino sketch as the C++ dialect it is: #include lines as include, #define macros as macro, free functions — including setup() and loop() — as function, and a top-level variable declaration as variable. symbols covers functions and the global variable identically, adds a function's own parameters, and reports the #define macros as kind: variable rather than macro, since its macro rule states no kind of its own and the underlying preprocessor node classifies as a variable; it also drops the bare #include line entirely, since no symbols rule matches it. The unit of structure in this grammar is the top-level declaration: statements inside a function body, other than a nested if, are not read as declarations by either query. 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 includes, macros, and functions as a skeleton

irrigation.ino runs a soil-moisture irrigation controller: three #define pin/threshold macros, a lastReading variable, an isSoilDry helper, and the sketch's setup/loop pair.

$ act query skeleton irrigation.ino

Before

#include <Wire.h>

#define MOISTURE_PIN A0
#define PUMP_RELAY_PIN 7
#define DRY_THRESHOLD 400

int lastReading = 0;

bool isSoilDry(int reading) {
  return reading > DRY_THRESHOLD;
}

void setup() {
  pinMode(PUMP_RELAY_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  lastReading = analogRead(MOISTURE_PIN);
  if (isSoilDry(lastReading)) {
    digitalWrite(PUMP_RELAY_PIN, HIGH);
    delay(3000);
    digitalWrite(PUMP_RELAY_PIN, LOW);
  }
  delay(60000);
}

Output

{
    "type": "Skeleton",
    "declarations": [
        {
            "kind": "include",
            "name": "#include <Wire.h>",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 1,
                    "column": 1,
                    "byte_offset": 0
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 2,
                    "column": 1,
                    "byte_offset": 18
                }
            }
        },
        {
            "kind": "macro",
            "name": "MOISTURE_PIN",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 3,
                    "column": 1,
                    "byte_offset": 19
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 4,
                    "column": 1,
                    "byte_offset": 43
                }
            },
            "name_range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 3,
                    "column": 9,
                    "byte_offset": 27
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 3,
                    "column": 21,
                    "byte_offset": 39
                }
            }
        },
        {
            "kind": "macro",
            "name": "PUMP_RELAY_PIN",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 4,
                    "column": 1,
                    "byte_offset": 43
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 5,
                    "column": 1,
                    "byte_offset": 68
                }
            },
            "name_range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 4,
                    "column": 9,
                    "byte_offset": 51
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 4,
                    "column": 23,
                    "byte_offset": 65
                }
            }
        },
        {
            "kind": "macro",
            "name": "DRY_THRESHOLD",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 5,
                    "column": 1,
                    "byte_offset": 68
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 6,
                    "column": 1,
                    "byte_offset": 94
                }
            },
            "name_range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 5,
                    "column": 9,
                    "byte_offset": 76
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 5,
                    "column": 22,
                    "byte_offset": 89
                }
            }
        },
        {
            "kind": "variable",
            "name": "lastReading",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 7,
                    "column": 1,
                    "byte_offset": 95
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 7,
                    "column": 21,
                    "byte_offset": 115
                }
            },
            "name_range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 7,
                    "column": 5,
                    "byte_offset": 99
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 7,
                    "column": 16,
                    "byte_offset": 110
                }
            }
        },
        {
            "kind": "function",
            "name": "isSoilDry",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 9,
                    "column": 1,
                    "byte_offset": 117
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 11,
                    "column": 2,
                    "byte_offset": 182
                }
            },
            "name_range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 9,
                    "column": 6,
                    "byte_offset": 122
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 9,
                    "column": 15,
                    "byte_offset": 131
                }
            }
        },
        {
            "kind": "function",
            "name": "setup",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 13,
                    "column": 1,
                    "byte_offset": 184
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 16,
                    "column": 2,
                    "byte_offset": 257
                }
            },
            "name_range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 13,
                    "column": 6,
                    "byte_offset": 189
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 13,
                    "column": 11,
                    "byte_offset": 194
                }
            }
        },
        {
            "kind": "function",
            "name": "loop",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 18,
                    "column": 1,
                    "byte_offset": 259
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 26,
                    "column": 2,
                    "byte_offset": 464
                }
            },
            "name_range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 18,
                    "column": 6,
                    "byte_offset": 264
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 18,
                    "column": 10,
                    "byte_offset": 268
                }
            }
        }
    ]
}

The skeleton reports the #include <Wire.h> line as include, MOISTURE_PIN/PUMP_RELAY_PIN/DRY_THRESHOLD as macro, lastReading as variable, and isSoilDry/setup/loop as function.

List the functions, variable, and a parameter as symbols

isSoilDry takes one parameter, reading, and compares it against DRY_THRESHOLD to decide whether loop should turn the pump relay on.

$ act query symbols irrigation.ino

Before

#include <Wire.h>

#define MOISTURE_PIN A0
#define PUMP_RELAY_PIN 7
#define DRY_THRESHOLD 400

int lastReading = 0;

bool isSoilDry(int reading) {
  return reading > DRY_THRESHOLD;
}

void setup() {
  pinMode(PUMP_RELAY_PIN, OUTPUT);
  Serial.begin(9600);
}

void loop() {
  lastReading = analogRead(MOISTURE_PIN);
  if (isSoilDry(lastReading)) {
    digitalWrite(PUMP_RELAY_PIN, HIGH);
    delay(3000);
    digitalWrite(PUMP_RELAY_PIN, LOW);
  }
  delay(60000);
}

Output

{
    "type": "Symbols",
    "symbols": [
        {
            "name": "MOISTURE_PIN",
            "kind": "variable",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 3,
                    "column": 9,
                    "byte_offset": 27
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 3,
                    "column": 21,
                    "byte_offset": 39
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "PUMP_RELAY_PIN",
            "kind": "variable",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 4,
                    "column": 9,
                    "byte_offset": 51
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 4,
                    "column": 23,
                    "byte_offset": 65
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "DRY_THRESHOLD",
            "kind": "variable",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 5,
                    "column": 9,
                    "byte_offset": 76
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 5,
                    "column": 22,
                    "byte_offset": 89
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "lastReading",
            "kind": "variable",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 7,
                    "column": 5,
                    "byte_offset": 99
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 7,
                    "column": 16,
                    "byte_offset": 110
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "isSoilDry",
            "kind": "function",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 9,
                    "column": 6,
                    "byte_offset": 122
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 9,
                    "column": 15,
                    "byte_offset": 131
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "reading",
            "kind": "parameter",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 9,
                    "column": 20,
                    "byte_offset": 136
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 9,
                    "column": 27,
                    "byte_offset": 143
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "setup",
            "kind": "function",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 13,
                    "column": 6,
                    "byte_offset": 189
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 13,
                    "column": 11,
                    "byte_offset": 194
                }
            },
            "visibility": "unknown"
        },
        {
            "name": "loop",
            "kind": "function",
            "range": {
                "start": {
                    "file": "irrigation.ino",
                    "line": 18,
                    "column": 6,
                    "byte_offset": 264
                },
                "end": {
                    "file": "irrigation.ino",
                    "line": 18,
                    "column": 10,
                    "byte_offset": 268
                }
            },
            "visibility": "unknown"
        }
    ]
}

symbols reports the same three macros as kind: variable rather than macro, drops the #include line, and adds reading as a parameter of isSoilDry; lastReading, isSoilDry, setup, and loop keep the kinds skeleton reported.

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

← ApexAssembly →