Configuring extension hosts

Extension hosts are configured under [extension-hosts]. Each named entry describes one command replicated into a pool of identical worker processes.

[extension-hosts.framework]
enabled = true
command = ["php", ".mago/framework-worker.php"]
workers = 0
working-directory = "."
inherit-environment = true
environment = { APP_ENV = "analysis" }
maximum-payload-size = 67108864
request-timeout-ms = 30000
shutdown-timeout-ms = 250
stderr-tail-size = 65536

Options

OptionTypeDefaultDescription
enabledbooleantrueWhether Mago starts this host. A disabled host may omit command.
commandstring list[]Executable followed by literal arguments. No shell parsing is performed. Required when enabled.
workersnon-negative integer00 selects an adaptive pool with Mago's thread count as its ceiling. A positive value starts exactly that many processes.
working-directorypathconfig directoryWorking directory inherited by every worker process.
environmentstring map{}Variables added to, or replacing values in, the worker environment.
inherit-environmentbooleantrueWhether workers inherit Mago's process environment before environment is applied.
maximum-payload-sizepositive integer67108864Maximum payload bytes accepted in one protocol frame. The maximum representable value is 4294967295.
request-timeout-mspositive integer30000Deadline for an outer request, including nested metadata and type-comparison requests.
shutdown-timeout-msnon-negative integer250Grace period after shutdown before Mago forcibly terminates a worker.
stderr-tail-sizenon-negative integer65536Trailing worker standard-error bytes retained for failure diagnostics.

Command resolution

command is passed directly to the operating system. Shell syntax, redirects, variable expansion, and pipelines are not interpreted.

# `php` is resolved through PATH. The script resolves from the config directory.
command = ["php", ".mago/worker.php", "--project=storefront"]

A bare executable name such as php, node, or my-extension-host is resolved through PATH. A relative executable containing a directory component, such as ./tools/extension-host, resolves from the effective configuration file's directory. Remaining arguments are passed literally; the selected program interprets relative arguments from working-directory.

Adaptive and fixed pools

The default workers = 0 uses an adaptive pool. It starts at most three processes to avoid unnecessary PHP startup and memory costs, then may grow toward the global Mago thread count when sustained request contention and observed callback time justify more processes. An analyzer host with parallel after-file or targeted work may proactively reach half of that capacity, rounded up, before dispatch.

Use a fixed pool when an extension has a known external constraint:

[extension-hosts.database-aware]
command = ["php", ".mago/database-worker.php"]
workers = 2

A fixed pool does not grow or shrink. Avoid configuring more workers than Mago threads unless the extension spends substantial time awaiting cooperative I/O.

Environment isolation

To start from an empty environment and provide only explicit values:

[extension-hosts.isolated]
command = ["/usr/bin/php", ".mago/isolated-worker.php"]
inherit-environment = false
environment = {
  PATH = "/usr/bin:/bin",
  APP_ENV = "analysis",
}

Environment isolation is not a security sandbox. The worker retains the permissions of the Mago process.

Multiple hosts and extensions

Each host has its own command, limits, environment, and worker pool. One worker command may register several logical extensions:

(new Worker(
    LaravelExtension::create(),
    PHPUnitExtension::create(),
))->run();

Across all enabled hosts, extension identifiers, linter issue codes, and analyzer plugin selectors must remain unique. Extension identifiers and analyzer plugin selectors are compared ASCII case-insensitively; linter rule codes are case-sensitive. External linter codes and analyzer selectors must not collide with their native counterparts. Every process in one pool must advertise identical registration metadata.

Analyzer plugin selection

Analyzer plugins declare whether they are enabled by default. Explicitly enable plugins by identifier or alias under [analyzer]:

[analyzer]
plugins = ["acme/laravel"]

When disable-default-plugins = true, only explicitly listed plugins run. This setting applies to Mago's built-in analyzer plugins and external analyzer plugins together.

Layered configuration

Extension hosts participate in normal configuration merging. Host entries merge by their table name, so a project can inherit a host and disable or adjust it:

extends = "../mago.base.toml"

[extension-hosts.framework]
enabled = false

See Configuration for path resolution and merge precedence.

↳ Edit this page →