Skip to main content
Glama
ober37

AC Infinity MCP

Server Configuration

Describes the environment variables required to run the server.

NameRequiredDescriptionDefault
AC_INFINITY_EMAILYesYour AC Infinity account email
AC_INFINITY_PASSWORDYesYour AC Infinity account password

Capabilities

Features and capabilities supported by this server

CapabilityDetails
tools
{
  "listChanged": false
}
prompts
{
  "listChanged": false
}
resources
{
  "subscribe": false,
  "listChanged": false
}
experimental
{}

Tools

Functions exposed to the LLM to take actions

NameDescription
discover_devicesA

Discover all AC Infinity devices from the cloud API. Returns device IDs, names, and online status. Use this to find device_ids for use in other tools.

Returns: JSON example::

    {
      "devices": [
        {"device_id": "C58ZA", "device_name": "Towlie Tent", "status": "online"},
        {"device_id": "D91XB", "device_name": "Veg Tent",    "status": "online"}
      ]
    }

Empty account returns ``{"devices": [], "message": "No devices found"}``.
On failure returns ``{"error": "...", "detail": "..."}``.
get_device_readingA

Get current sensor reading for a device by its AC Infinity device_id. Returns temperature, humidity, VPD, and timestamp.

Args: device_id: The AC Infinity device code (from discover_devices)

Returns: JSON example::

    {
      "device_id": "C58ZA",
      "device_name": "Towlie Tent",
      "temperature": 75.7,
      "unit": "°F",
      "humidity": 58.2,
      "vpd": 1.31,
      "timestamp": "2026-05-20T09:32:00 CDT",
      "ports": [
        {"port": 1, "name": "Inline Fan", "speed": 5},
        {"port": 2, "name": "Port 2", "speed": 0, "plug_status": "not powered"}
      ],
      "external_sensors": []
    }

Temperature and timestamp use the device's own unit preference and timezone
(from ``deviceInfo.unit`` and ``zoneId`` in the API response). Devices
without a configured timezone fall back to UTC.
``external_sensors`` excludes phantom entries (API-reported sensor slots
with no physical hardware connected — see API Quirk 20).
``plug_status`` is only present on a port entry when no current is detected,
the port is not running (speed 0 and no load), **and the port still has its
default name** (``"Port N"``). Custom-named ports are assumed to have a device
intentionally connected — ``loadState=0`` alone cannot distinguish "nothing
plugged in" from "device is off" for on/off devices. This matches the signal
used in ``get_port_status``.
On failure returns ``{"error": "...", "detail": "..."}``.
get_historical_readingsA

Query AC Infinity environment data across a date range with configurable sampling.

Args: device_id: The AC Infinity device code (from discover_devices) start_date: Start date in YYYY-MM-DD format end_date: End date in YYYY-MM-DD format sample_interval: Bucket size for averaging readings. Use "raw" for all records unmodified, or a duration string like "1m", "5m", "15m", "30m", "1h", "2h", "6h", "12h", "1d". "daily" is accepted as an alias for "1d". Default: "1h" (one averaged reading per hour). time_start: Optional UTC time filter in HH:MM format (e.g., "16:00"). If provided, only readings at or after this time are returned. Invalid HH:MM strings return a structured error. Note: time_start/time_end filters are in UTC. Use discover_devices to get the device's timezone for conversion. time_end: Optional UTC time filter in HH:MM format (e.g., "16:15"). If provided, only readings at or before this time are returned. Invalid HH:MM strings return a structured error.

    When both bounds are set and time_start > time_end (e.g. "22:00"–"06:00"),
    the window crosses midnight: the OR of [time_start, 24:00) and
    [00:00, time_end] is returned.

Returns: JSON with "readings" list and "statistics" summary. Each reading contains timestamp, temperature_c/f, humidity, vpd, and ports list. Statistics include min/avg/max per metric across the returned window. If any readings were dropped because their timestamps could not be parsed, the response also includes "dropped_readings" (count) and "drop_reason". See docs/API.md for full shape.

On failure returns ``{"error": "...", "detail": "..."}``.
check_vpd_driftA

Check if current VPD is within target range for a growth stage.

Args: device_id: The AC Infinity device code (from discover_devices) stage: Growth stage - one of: clones, seedling, veg, early_flower, mid_flower, late_flower

Returns: JSON example::

    {
      "device_id": "C58ZA",
      "current_vpd": 1.58,
      "target_range": [1.0, 1.5],
      "stage": "veg",
      "status": "HIGH",
      "deviation": 0.08,
      "alert": "VPD 1.58 exceeds target 1.00–1.50. Raise humidity or lower temperature."
    }

``status`` is one of ``"OK"``, ``"LOW"``, or ``"HIGH"``.
``deviation`` is 0 when OK; positive when HIGH (kPa above upper bound);
negative when LOW (kPa below lower bound).
``alert`` is ``null`` when status is ``"OK"``.
On failure returns ``{"error": "...", "detail": "..."}``.
get_all_device_readingsA

Get current sensor readings for all AC Infinity devices. Useful for a full status check across all controllers. Returns a list of readings keyed by device_id.

Returns: JSON with "readings" list — one entry per device, same shape as get_device_reading. Devices that fail to parse individually include an "error" key instead of sensor fields. ports[].plug_status is present on not-powered port entries (same loadState == 0 AND speak == 0 condition as get_device_reading, and only on default-named "Port N" ports); omitted otherwise. external_sensors excludes phantom entries (API-reported sensor slots with no physical hardware connected — see API Quirk 20). On auth/API failure returns {"error": "...", "detail": "..."}.

get_environment_healthA

Calculate composite environment health score (0–100) for a device.

Args: device_id: The AC Infinity device code (from discover_devices) stage: Growth stage — one of: clones, seedling, veg, early_flower, mid_flower, late_flower. Default: veg.

Returns: JSON with score (0–100), grade (A–F), per-metric sub-scores, top_recommendation, actual sensor readings (temperature_c, temperature_f, humidity_pct, vpd_kpa), and a human_summary one-liner.

detect_environment_trendsA

Detect linear trends in temperature, humidity, and VPD over a look-back window.

Args: device_id: The AC Infinity device code (from discover_devices) days: Number of days to look back. Default: 7. Must be 1–30.

Returns: JSON with per-metric trend reports: slope (change/hour), direction, 7-day projection, and alert flag.

Note: The AC Infinity history API returns a maximum of ~1257 records per day regardless of page_size. For longer windows the data may be sparse.

get_port_activity_reportA

Build a per-port runtime activity report from historical data.

Args: device_id: The AC Infinity device code (from discover_devices) days: Number of days to analyze. Default: 7. Must be 1–30.

Returns: JSON with window_start_local and window_end_local (the exact local time range analyzed, e.g. 'May 23, 10:35 AM CDT' to 'May 24, 10:35 AM CDT'), per-port on_hours (total hours ON over the full period), off_hours, transitions, avg_speed_when_running, uptime_pct, and peak_hour_local (device-local time string with peak date, e.g. '3:00 PM CDT (peak on May 23)', or null if the port never ran). Note: data_quality is an internal classification field stripped from the JSON output before serialization — it is NOT present in the response JSON. Its effects are visible only in human_summary: toggle hardware (heaters, lights, humidifiers — loadType 4 or 128 on standard devices, or pattern-detected on devType=18/22 where loadType is unreliable) produces a ▎-prefixed caveat line; devType=22 (Q0KT4 Genetics Lab) produces a device-level Note about missing power-draw data. devType=18 (UIS 69 Pro+) does NOT emit this Note — its active ports produce reliable runtime data in historical records even though portsLoad is always 0. ports_excluded_count is the number of ports removed by the ghost-port filter, capped at devPortCount when the device's physical port count is known (prevents over-counting on sub-8-port devices; unknown/zero devPortCount means no cap). Six rules apply: Rule A (constant 100%% uptime + zero load), Rule B (auto-named Port N with low average runtime or zero load), Rule C (named port with zero transitions + zero load + < 1 h/day average runtime), Rule D (non-toggle named port with speed history ≤ 1 and zero load — confirmed toggle hardware with transitions > 0 is exempt; see Quirk 22 in docs/API.md), Rule E (named port, non-toggle hardware, zero current load, sub-threshold runtime — stale configured speed from a port previously set to OFF), and Rule F (phantom clone detection — custom-named ports sharing identical activity signatures with low average on-time are excluded as legacy controller artifacts; fires only when port_loads data is available; proper-subset guard ensures at least one port is always retained). The human_summary field already includes a brief note about excluded ports when ports_excluded_count > 0. Do not repeat the exclusion count in prose response. The transitions count uses debouncing (_MIN_DWELL_READINGS=2): single-reading state changes at automation window edges are not counted — only transitions where the new state persists for ≥ 2 consecutive readings are recorded.

Ports whose timing data is unreliable appear only as ▎-prefixed caveat
lines in human_summary grouped by current state, e.g.
"▎ Currently ON: Heater (Port 2)." or
"▎ Currently OFF: Humidifier (Port 3)."
Do NOT quote on_hours or uptime_pct for these ports —
relay the caveat lines verbatim instead.

All ports listed under the main runtime sentences have reliable timing data
and should be presented normally. When a device-level Note about missing load
data appears in human_summary (devType=22 devices only), relay it once — do not
add further caveats.

Presentation guidance: - Always refer to ports as 'Name (Port N)', e.g., 'Exhaust Fan (Port 3)'. - When presenting on_hours to a grower, translate it from raw hours to natural language, e.g.: "The fan ran for 36.0 hours over the past 3 days (about 50% of the time)." Do NOT describe on_hours as hours per day. - window_start_local and window_end_local show the exact analysis window in the device's local timezone. Use these when explaining why a device shows activity from multiple calendar days (the window is a rolling 24h/N-day span, not a calendar-day boundary). - peak_hour_local is in device-local time with the peak date, e.g. '3:00 PM CDT (peak on May 23)'. - Ports with a ▎ caveat line: relay the caveat verbatim, no runtime numbers.

get_port_statusA

Get the live operational status of a single port.

Reads real-time fields from the device info response: actual current power level, active automation mode, and remaining timer seconds.

Args: device_id: The AC Infinity device code (from discover_devices) port: 1-based port number

Returns: JSON example (port not powered)::

    {
      "device_id": "C58ZA",
      "port": 1,
      "port_name": "Port 1",
      "power_level": 0,
      "mode": "OFF",
      "plug_status": "not powered"
    }

``mode`` is one of: OFF, ON, AUTO, TIMER_TO_ON, TIMER_TO_OFF, CYCLE, SCHEDULE, VPD,
Automation. ``plug_status`` is only present when no current is detected on the port (the
port is not powered or nothing is connected). It is omitted when the port is running.
Only emitted for default-named ports (``"Port N"``) — custom-named ports are assumed to
have a device intentionally connected; ``loadState=0`` alone cannot distinguish "nothing
plugged in" from "device is off".
``remain_time_seconds`` is only present when a countdown timer is active (value > 0);
it is omitted when there is no active timer.
When ``mode`` is ``Automation``, the port is governed by a named Advance Automation
program in the AC Infinity app. ``automation_name`` is present only when the port is
under automation control and the governing automation name was successfully resolved;
absent otherwise.

When the port appears to have nothing connected (primary: ``portResistance == 65535``;
fallback for old firmware: default-named ``"Port N"`` with zero load, or a devType=18/22
controller), the response also includes a ``note`` field alerting the grower
(e.g. ``"Port 7 doesn't appear to have anything connected."``).

On failure returns ``{"error": "...", "detail": "..."}``.

Note on ADVANCE detection: ``isOpenAutomation==1`` in devInfoListAll is the primary
signal. For AI+ devices (no curMode field) and older firmware without isOpenAutomation,
a secondary call to getdevModeSettingList is made to check modeType.
get_port_settingsA

Get the full automation configuration for a port.

Calls the getdevModeSettingList endpoint and returns the active mode, speed target, and all configured automation targets (VPD, temperature, humidity, schedule, timer, cycle).

Args: device_id: The AC Infinity device code (from discover_devices) port: 1-based port number

Returns: JSON example (non-ADVANCE port)::

    {
      "device_id": "C58ZA",
      "port": 1,
      "mode": "AUTO",
      "speed_target": 5,
      "vpd_target_kpa": null,
      "temp_range": null,
      "humidity_range_pct": null,
      "schedule_window": null,
      "cycle_on_seconds": 300,
      "cycle_off_seconds": 60
    }

When ``mode`` is ``"ADVANCE"``, ``speed_target`` is null (an automation governs
the port), and the response includes three additional enrichment fields:

- ``automation_running``: ``true`` if the governing automation has
  ``run_state=True``; ``false`` if an automation was found but none active;
  ``null`` when the secondary API call failed (degraded path).
- ``automation_configured``: ``true`` if the automations list is non-empty;
  ``false`` if empty; ``null`` when degraded.
- ``human_summary``: grower-readable description of the ADVANCE state.
  Three variants:
  - Governing found: ``"Port is running under 'Name' automation (target
    speed: N, current live speed: M). The automation is active."``
  - All disabled: ``"Port is in automation mode, but all automations are
    disabled. The port hasn't fully released. Ask me to list your
    automations for details."``
  - Degraded: ``"Port is in ADVANCE automation mode. Automation details
    could not be retrieved."``

``current_speed`` reflects the live fan speed from the device.
``automation_name``/``automation_id`` are populated from the governing
automation (or null if none active or secondary lookup degrades).
``automation_on_speed`` is read from the port group of the governing
automation whose ``grouptDevType`` bitmask covers this port (bitmask-matched);
null when no governing automation, no matching port group, or degraded.
``vpd_target_kpa`` is non-null only when VPD automation is active.
``temp_range`` / ``humidity_range_pct`` are non-null only when those
thresholds are enabled. ``schedule_window`` times are in device local time
(not UTC).

When the port appears to have nothing connected (primary: ``portResistance == 65535``;
fallback for old firmware: default-named ``"Port N"`` with zero load, or a devType=18/22
controller), the response includes a staleness-aware ``note`` field.
On the non-ADVANCE path, ``human_summary`` is overridden with a staleness statement
and ``note`` is set to a redirect hint, so the response doesn't contradict itself
(e.g. "Humidity automation: 60–100%") for a port with nothing connected.
On the ADVANCE path, ``human_summary`` is preserved (it already describes the
automation state) and only ``note`` is appended.
On failure returns ``{"error": "...", "detail": "..."}``.
set_port_speedA

Set fan or dimmer speed on a specific port.

Uses read-before-write: reads current mode settings then overlays the new speed value. Defaults to dry_run=True — set dry_run=False to write to the device.

Args: device_id: Device code from discover_devices (e.g. "C58ZA"). port: 1-based port number. speed: Target speed 1–10 (10 = full speed). dry_run: If True (default), returns the payload that would be sent without writing. Set to False to execute the change.

Returns: JSON with action, device_id, port, speed, dry_run, controller_type, sent, and payload (when dry_run=True).

When the port is in OFF mode (atType=0 or atType=1) at call time, the
response also includes a ``warning`` field telling the grower to ask
Claude to switch the port to ON mode to activate it. The speed is stored
on the controller but the port will not run until the mode is changed.

Example (dry_run=True)::

    {
      "action": "set Exhaust Fan (Port 2) speed to 5",
      "device_id": "C58ZA",
      "port": 2,
      "speed": 5,
      "dry_run": true,
      "controller_type": "legacy",
      "sent": false,
      "payload": { ... }
    }

On failure returns ``{"error": "..."}``.
set_port_onA

Turn a port on at full speed (onSpead=10).

Works for fan-type and on/off toggle devices. Uses read-before-write. Defaults to dry_run=True — set dry_run=False to write to the device.

Args: device_id: Device code from discover_devices (e.g. "C58ZA"). port: 1-based port number. dry_run: If True (default), returns the payload that would be sent without writing.

Returns: JSON with action, device_id, port, dry_run, controller_type, sent, and payload (when dry_run=True).

When the port appears to have nothing connected (primary: ``portResistance == 65535``;
fallback for old firmware: default-named ``"Port N"`` with zero load, or a devType=18/22
device), the response also includes a ``warning`` field alerting the grower.

On failure returns ``{"error": "..."}``.
set_port_offA

Sets mode to OFF (atType=1) and zeros speed (onSpead=0).

Works for all device types including toggle hardware (heaters, lights, on/off outlets). Uses read-before-write. Defaults to dry_run=True — set dry_run=False to write to the device.

Args: device_id: Device code from discover_devices (e.g. "C58ZA"). port: 1-based port number. dry_run: If True (default), returns the payload that would be sent without writing.

Returns: JSON with action, device_id, port, dry_run, controller_type, sent, and payload (when dry_run=True).

When the port appears to have nothing connected (primary: ``portResistance == 65535``;
fallback for old firmware: default-named ``"Port N"`` with zero load, or a devType=18/22
device), the response also includes a ``warning`` field alerting the grower.

On failure returns ``{"error": "..."}``.
set_vpd_automationA

Enable VPD automation on a port using the built-in temperature and humidity sensors.

Switches the port to VPD mode (atType=8) and sets the VPD target. Uses read-before-write. Defaults to dry_run=True — set dry_run=False to write to the device.

Args: device_id: Device code from discover_devices (e.g. "C58ZA"). port: 1-based port number. target_vpd: Target VPD in kPa, range 0.1–3.0. Typical ranges by stage: seedling/clones 0.8–1.2, veg 1.0–1.5, early_flower 1.0–1.8, mid_flower 1.2–2.0, late_flower 1.2–1.8. dry_run: If True (default), returns the payload that would be sent without writing.

Returns: JSON with action, device_id, port, target_vpd_kpa, dry_run, controller_type, sent, and payload (when dry_run=True). On failure returns {"error": "..."}.

set_temperature_automationA

Enable temperature automation on a port using the built-in temperature sensor.

Switches the port to AUTO mode (atType=3) and sets the temperature thresholds. The controller speeds up when temperature exceeds max_temp and slows down below min_temp. Uses read-before-write. Defaults to dry_run=True.

Pass values in the device's preferred unit (°F or °C). Call discover_devices first to check temp_unit. Valid range: 32–122°F or 0–50°C (device API cap = 50°C).

Args: device_id: Device code from discover_devices (e.g. "C58ZA"). port: 1-based port number. min_temp: Minimum temperature threshold in the device's preferred unit. Sub-degree values are rounded to the nearest integer. max_temp: Maximum temperature threshold in the device's preferred unit. Must exceed min_temp. Sub-degree values are rounded to the nearest integer. dry_run: If True (default), returns the payload that would be sent without writing.

Returns: JSON with action, device_id, port, min_temp, max_temp, unit, dry_run, controller_type, sent, and payload (when dry_run=True). On failure returns {"error": "..."}.

set_humidity_automationA

Enable humidity automation on a port using the built-in humidity sensor.

Switches the port to AUTO mode (atType=3) and sets the humidity thresholds. The controller speeds up when humidity exceeds max_rh and slows down below min_rh. Uses read-before-write. Defaults to dry_run=True.

Args: device_id: Device code from discover_devices (e.g. "C58ZA"). port: 1-based port number. min_rh: Minimum relative humidity threshold (%), range 0–100. Sub-percent values are rounded to the nearest integer (e.g. 50.5 → 51). max_rh: Maximum relative humidity threshold (%), range 0–100. Must exceed min_rh. Sub-percent values are rounded to the nearest integer. dry_run: If True (default), returns the payload that would be sent without writing.

Returns: JSON with action, device_id, port, min_rh, max_rh, dry_run, controller_type, sent, and payload (when dry_run=True). On failure returns {"error": "..."}.

set_port_modeA

Switch a port to a specific automation mode.

All 8 AC Infinity automation modes are supported. Mode-specific parameters are required for CYCLE, SCHEDULE, TIMER_TO_ON, and TIMER_TO_OFF modes. Uses read-before-write. Defaults to dry_run=True.

For setting automation targets alongside the mode, prefer the dedicated tools: set_vpd_automation (VPD mode), set_temperature_automation and set_humidity_automation (AUTO mode).

Args: device_id: Device code from discover_devices (e.g. "C58ZA"). port: 1-based port number. mode: One of OFF, ON, AUTO, VPD, CYCLE, SCHEDULE, TIMER_TO_ON, TIMER_TO_OFF. dry_run: If True (default), returns the payload without writing. cycle_on_seconds: CYCLE mode — seconds the port runs per cycle. Required for CYCLE. cycle_off_seconds: CYCLE mode — seconds the port is off per cycle. Required for CYCLE. schedule_start: SCHEDULE mode — start time as "HH:MM" in device local time. Required for SCHEDULE. schedule_end: SCHEDULE mode — end time as "HH:MM" in device local time. Required for SCHEDULE. timer_duration_seconds: TIMER_TO_ON / TIMER_TO_OFF — countdown duration in seconds. Required for TIMER_TO_ON and TIMER_TO_OFF.

Returns: JSON with action, device_id, port, mode, dry_run, controller_type, sent, and payload (when dry_run=True). On failure returns {"error": "..."}.

apply_grow_stage_templateA

Apply a grow-stage automation template (VPD + temperature + humidity) in one call.

Issues a single atomic write that puts the port in VPD mode (atType=8) with the stage's VPD midpoint as the active target, and simultaneously stores the stage's temperature and humidity thresholds on the controller for fallback when the user later switches modes. Defaults to dry_run=True — set dry_run=False to write.

Stage targets (VPD midpoint used as single target):

Stage

VPD (kPa)

Temp (°C)

Humidity (%)

clones

1.00

22–26

70–80

seedling

1.00

22–26

65–75

veg

1.25

20–28

50–70

early_flower

1.40

20–26

40–60

mid_flower

1.60

18–25

35–55

late_flower

1.50

18–24

30–50

Args: device_id: Device code from discover_devices (e.g. "C58ZA"). port: 1-based port number. stage: Growth stage name. One of: clones, seedling, veg, early_flower, mid_flower, late_flower. dry_run: If True (default), returns the payload without writing.

Returns: JSON with action, device_id, port, stage, dry_run, controller_type, sent, per-target summary (vpd/temperature/humidity), and payload (when dry_run=True). On failure returns {"error": "..."}.

list_advance_automationsA

List all Advance Automations configured on a device.

Advance Automations (also called "programs" in the AC Infinity app) are named schedules that can govern one or more ports simultaneously.

Args: device_id: The AC Infinity device code (from discover_devices).

Returns: JSON with "automations" list. Each entry includes automation_id, name, enabled status, and currently_running flag. Empty: {"device_id": "...", "automations": []}. On failure returns {"error": "...", "detail": "..."}.

get_advance_automationA

Get full detail for a single Advance Automation by ID.

Args: device_id: The AC Infinity device code (from discover_devices). automation_id: The automation_id from list_advance_automations.

Returns: JSON with automation detail including name, enabled status, schedule (with mode: "continuous" or "scheduled" per Quirk 21; begin_time/end_time as "HH:MM" or null; optional schedule_note when scheduled mode has no time window configured), port_groups (each entry has device_type listing the actual port names governed by that group, resolved from the grouptDevType bitmask — e.g. "Left Fan (Port 5), Right Fan (Port 6)", formatted as "Name (Port N)" for each bit set; "Unknown" when bitmask is 0), governed_ports (list of ports this automation controls, decoded from the automation's port_group bitmasks), port_resolution status ("resolved" or "error"), and human_summary (adapts to continuous/scheduled/no-window variants). On failure returns {"error": "..."}.

enable_advance_automationA

Enable a previously disabled Advance Automation.

Reads current state before toggling — no-ops if already enabled. Defaults to dry_run=True — set dry_run=False to execute.

IMPORTANT: The AC Infinity API uses a toggle endpoint (updateGroupsIsOn). This tool reads the current enabled state first and only calls the API if the automation is currently disabled, ensuring the toggle results in enabled.

Args: device_id: The AC Infinity device code (from discover_devices). automation_id: The automation_id from list_advance_automations. dry_run: If True (default), returns the action plan without executing.

Returns: JSON with action, automation_name, automation_id, dry_run, sent. On failure returns {"error": "..."}.

disable_advance_automationA

Disable a currently enabled Advance Automation.

Reads current state before toggling — no-ops if already disabled. Defaults to dry_run=True — set dry_run=False to execute.

Live-tested (2026-05-22): disabling sets governed ports to OFF; re-enabling immediately restores ADVANCE mode at automation-defined speeds — no next-trigger wait. Use break_out_of_automation for a controlled handoff that also locks co-governed ports to safe manual speeds.

Args: device_id: The AC Infinity device code (from discover_devices). automation_id: The automation_id from list_advance_automations. dry_run: If True (default), returns the action plan without executing.

Returns: JSON with action, automation_name, automation_id, governed_ports (list of {port, port_name} dicts decoded from the automation's grouptDevType bitmasks), human_summary, dry_run, sent, and to_restore (natural-language hint for re-enabling). On failure returns {"error": "..."}.

create_advance_automationA

Create a new Advance Automation on a device.

Defaults to dry_run=True for safety. Set dry_run=False to send the automation to the device. The port bitmask (grouptDevType) is computed automatically from the port number (Port N → 2^(N-1)).

Args: device_id: The AC Infinity device code (from discover_devices). name: Automation name (max 64 chars, control chars stripped). on_speed: Fan speed when automation is active (1–10). port: 1-based port number the automation should control (1–8). off_speed: Not used — On mode relies on the port's own minimum speed setting. Parameter accepted for compatibility but not sent to the device. begin_time: Schedule start in minutes since midnight (0–1439, or 255=always active). Default: 0 (midnight). Use 255 for "always active" (runs 00:00–23:59 every day). end_time: Schedule end in minutes since midnight (0–1439, or 255=always active). Default: 1439 (23:59). Use 255 for "always active". dry_run: If True (default), previews the automation without sending it. Set to False to create the automation on the device.

Returns: JSON with action, name, port, port_name, on_speed, min_speed (the port's configured minimum speed — used when the automation is inactive), begin_time, end_time, schedule_summary, dry_run, sent. Live responses also include automation_id (for programmatic chaining — do not surface to the user; use name instead). On failure returns {"error": "..."}. When the specified port does not exist on the device, returns {"error": "Port N not found on device X", "available_ports": [{"port": N, "name": "..."}], "suggested_reply": "..."}. Port names absent or empty in the API response fall back to "Port N"; control chars are sanitized.

delete_advance_automationA

Delete an Advance Automation from a device.

If the automation is currently enabled, it is disabled first before deletion. Defaults to dry_run=True — set dry_run=False to delete.

Args: device_id: The AC Infinity device code (from discover_devices). automation_id: The automation_id from list_advance_automations. dry_run: If True (default), returns the action plan without executing.

Returns: JSON with action, automation_name, automation_id, was_enabled, dry_run, sent. On failure returns {"error": "..."}.

break_out_of_automationA

Break a port out of Advance Automation control and lock co-governed ports.

This is the safe way to manually override a port that is currently under Advance Automation. It:

  1. Checks that the port is actually under automation (idempotent: no-ops if not).

  2. Finds the governing automation.

  3. Identifies all other ports in the same automation as the target port (co-ports). Only those ports are locked — ports in other automations or empty ports are unaffected.

  4. On dry_run=False: a. Disables the automation. b. Locks each co-port to its current manual speed (prevents unexpected speed changes). c. Leaves the target port free for your manual change.

Defaults to dry_run=True. For live execution (dry_run=False), you must supply confirm_automation_name matching the automation name (case-insensitive) as a safety confirmation.

Args: device_id: The AC Infinity device code (from discover_devices). port: The port number you want to break free (1-based). dry_run: If True (default), returns the execution plan without making changes. confirm_automation_name: Required when dry_run=False — the name of the automation to disable, for safety confirmation.

Returns: Dry-run: JSON plan with sequence of steps, co_ports_to_lock, estimated_duration. Live: JSON with co_ports_locked and target_port_freed. Idempotent: {"info": "Port is not currently under automation control."} On failure returns {"error": "..."}.

Prompts

Interactive templates invoked by user choice

NameDescription
vpd_troubleshootingStep-by-step guide for diagnosing and fixing VPD issues.
new_grower_setupOnboarding guide: from first connection to automated grow environment.
environment_alert_interpretationGuide to interpreting alerts from check_vpd_drift and get_environment_health.

Resources

Contextual data attached and managed by the client

NameDescription

No resources

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/ober37/ac-infinity-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server