Puppet — 18 Operations for AI Agents
Puppet manifests declare what whole fleets of machines should be — packages, services, files, in enforced order. act101 reads classes and resources as structure, so agents trace configuration intent across a sprawling control repo.
This page is the canonical reference an AI coding agent uses to refactor, query, and analyze Puppet 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 Puppet examples
act101 reads a Puppet manifest's class definitions, defined resource types, and function declarations as declarations — a defined resource type and a class definition are given the identical kind, class, so a reusable resource type is indistinguishable by kind from a real class. Nothing else in a Puppet file — a resource declaration (package/service/file), a variable assignment, a defined type's own parameters — is read by either query. symbols covers the identical three constructs one-for-one with skeleton; it adds nothing skeleton does not already show. 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 module's class, defined type, and function as a skeleton
nginx.pp packages an Nginx web-server module: the nginx class installs the package, runs the service, and manages its config file; nginx::vhost is a defined type instantiated once per virtual host; port_for picks the listening port for a given environment.
$ act query skeleton nginx.pp
Before
class nginx (
String $package_name = 'nginx',
) {
package { $package_name:
ensure => installed,
}
service { 'nginx':
ensure => running,
enable => true,
require => Package[$package_name],
}
file { '/etc/nginx/nginx.conf':
ensure => file,
source => 'puppet:///modules/nginx/nginx.conf',
notify => Service['nginx'],
}
}
define nginx::vhost (
String $server_name,
Integer $port = 80,
) {
file { "/etc/nginx/sites-available/${server_name}":
ensure => file,
content => template('nginx/vhost.erb'),
}
}
function port_for($env) {
if $env == 'production' {
return(443)
}
return(80)
}
Output
{
"type": "Skeleton",
"declarations": [
{
"kind": "class",
"name": "nginx",
"range": {
"start": {
"file": "nginx.pp",
"line": 1,
"column": 1,
"byte_offset": 0
},
"end": {
"file": "nginx.pp",
"line": 19,
"column": 2,
"byte_offset": 362
}
},
"name_range": {
"start": {
"file": "nginx.pp",
"line": 1,
"column": 7,
"byte_offset": 6
},
"end": {
"file": "nginx.pp",
"line": 1,
"column": 12,
"byte_offset": 11
}
}
},
{
"kind": "class",
"name": "nginx::vhost",
"range": {
"start": {
"file": "nginx.pp",
"line": 21,
"column": 1,
"byte_offset": 364
},
"end": {
"file": "nginx.pp",
"line": 29,
"column": 2,
"byte_offset": 559
}
},
"name_range": {
"start": {
"file": "nginx.pp",
"line": 21,
"column": 8,
"byte_offset": 371
},
"end": {
"file": "nginx.pp",
"line": 21,
"column": 20,
"byte_offset": 383
}
}
},
{
"kind": "function",
"name": "port_for",
"range": {
"start": {
"file": "nginx.pp",
"line": 31,
"column": 1,
"byte_offset": 561
},
"end": {
"file": "nginx.pp",
"line": 36,
"column": 2,
"byte_offset": 649
}
},
"name_range": {
"start": {
"file": "nginx.pp",
"line": 31,
"column": 10,
"byte_offset": 570
},
"end": {
"file": "nginx.pp",
"line": 31,
"column": 18,
"byte_offset": 578
}
}
}
]
}
The skeleton reports three declarations: nginx and nginx::vhost both come back kind class — a class definition and a defined resource type are not distinguished — and port_for as function; the package/service/file resources nginx declares are not read.
List the same class, defined type, and function as symbols
port_for branches on $env, returning 443 for production and 80 otherwise.
$ act query symbols nginx.pp
Before
class nginx (
String $package_name = 'nginx',
) {
package { $package_name:
ensure => installed,
}
service { 'nginx':
ensure => running,
enable => true,
require => Package[$package_name],
}
file { '/etc/nginx/nginx.conf':
ensure => file,
source => 'puppet:///modules/nginx/nginx.conf',
notify => Service['nginx'],
}
}
define nginx::vhost (
String $server_name,
Integer $port = 80,
) {
file { "/etc/nginx/sites-available/${server_name}":
ensure => file,
content => template('nginx/vhost.erb'),
}
}
function port_for($env) {
if $env == 'production' {
return(443)
}
return(80)
}
Output
{
"type": "Symbols",
"symbols": [
{
"name": "nginx",
"kind": "class",
"range": {
"start": {
"file": "nginx.pp",
"line": 1,
"column": 7,
"byte_offset": 6
},
"end": {
"file": "nginx.pp",
"line": 1,
"column": 12,
"byte_offset": 11
}
},
"visibility": "unknown"
},
{
"name": "nginx::vhost",
"kind": "class",
"range": {
"start": {
"file": "nginx.pp",
"line": 21,
"column": 8,
"byte_offset": 371
},
"end": {
"file": "nginx.pp",
"line": 21,
"column": 20,
"byte_offset": 383
}
},
"visibility": "unknown"
},
{
"name": "port_for",
"kind": "function",
"range": {
"start": {
"file": "nginx.pp",
"line": 31,
"column": 10,
"byte_offset": 570
},
"end": {
"file": "nginx.pp",
"line": 31,
"column": 18,
"byte_offset": 578
}
},
"visibility": "unknown"
}
]
}
symbols reports the identical three entries with the identical kinds skeleton already showed — this grammar's symbols query adds nothing skeleton does not already surface.
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