AC Infinity MCP
Server Configuration
Describes the environment variables required to run the server.
| Name | Required | Description | Default |
|---|---|---|---|
| AC_INFINITY_EMAIL | Yes | Your AC Infinity account email | |
| AC_INFINITY_PASSWORD | Yes | Your AC Infinity account password |
Capabilities
Features and capabilities supported by this server
| Capability | Details |
|---|---|
| tools | {
"listChanged": false
} |
| prompts | {
"listChanged": false
} |
| resources | {
"subscribe": false,
"listChanged": false
} |
| experimental | {} |
Tools
Functions exposed to the LLM to take actions
| Name | Description | ||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 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:: | ||||||||||||||||||||||||||||
| 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:: | ||||||||||||||||||||||||||||
| 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. Returns:
JSON with | ||||||||||||||||||||||||||||
| 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:: | ||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||
| 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. 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):: | ||||||||||||||||||||||||||||
| 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):: | ||||||||||||||||||||||||||||
| 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). | ||||||||||||||||||||||||||||
| 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). | ||||||||||||||||||||||||||||
| 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). | ||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||
| 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 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 | ||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||
| 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:
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 | ||||||||||||||||||||||||||||
| 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):
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 | ||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||
| 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
| ||||||||||||||||||||||||||||
| 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
| ||||||||||||||||||||||||||||
| 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 | ||||||||||||||||||||||||||||
| 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:
Defaults to dry_run=True. For live execution (dry_run=False), you must supply
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: |
Prompts
Interactive templates invoked by user choice
| Name | Description |
|---|---|
| vpd_troubleshooting | Step-by-step guide for diagnosing and fixing VPD issues. |
| new_grower_setup | Onboarding guide: from first connection to automated grow environment. |
| environment_alert_interpretation | Guide to interpreting alerts from check_vpd_drift and get_environment_health. |
Resources
Contextual data attached and managed by the client
| Name | Description |
|---|---|
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