AC Infinity MCP
What is this?
ac-infinity-mcp is an MCP server that connects Claude (and other AI assistants) directly to your AC Infinity controllers — so you can read live sensor data, run analytics, and adjust fan speeds or port states using natural language, without opening the AC Infinity app.
Built with FastMCP and the AC Infinity cloud API.
Related MCP server: ambient-mcp
Example prompts
"What's the VPD trend in my tent over the last 7 days?" "Is my environment in the right range for late flower?" "Turn off port 3 on my 69 Pro controller — dry run first." "Show me which ports have been running the most this week." "Apply the veg stage template to port 1 — dry run first so I can see the settings." "My VPD is too high — what should I adjust?"
Compatible hardware
Controller | Reads | Writes | Notes |
UIS Controller 69 Pro | ✅ | ✅ | Legacy protocol |
UIS Controller 69 Pro+ | ✅ | ✅ | Legacy protocol |
UIS Controller 89 AI+ | ✅ | ⚠️ v1 read-only | New AI+ protocol — write support planned for v2 |
Tools
Category | Tool | What it does |
🔍 Discovery |
| List all your controllers and ports |
🌡️ Readings |
| Live temp, humidity, VPD, and port states for one device |
🌡️ Readings |
| Same, for all devices at once |
🌡️ Readings |
| Time-series data with optional bucketing (raw, 15m, 1h, 1d, …) |
📊 Analytics |
| VPD target compliance check for your current grow stage |
📊 Analytics |
| Composite health score (0–100, A–F) across temp, humidity, VPD |
📊 Analytics |
| Linear trend + 7-day projection per metric |
📊 Analytics |
| Per-port on/off hours, uptime %, and peak activity hour |
🔎 Port Status |
| Live port power level, load detection, active mode, and timer countdown |
🔎 Port Status |
| Full automation config: mode, VPD target, temp/humidity thresholds, schedule, cycle |
🔌 Write |
| Set fan or pump speed 1–10 ( |
🔌 Write |
| Turn a port fully on ( |
🔌 Write |
| Turn a port fully off ( |
⚙️ Automation |
| Enable VPD mode with a kPa target using built-in sensors ( |
⚙️ Automation |
| Enable AUTO mode with min/max °C thresholds ( |
⚙️ Automation |
| Enable AUTO mode with min/max % RH thresholds ( |
⚙️ Automation |
| Switch to any mode: OFF, ON, AUTO, VPD, CYCLE, SCHEDULE, TIMER_TO_ON, TIMER_TO_OFF ( |
🌱 Intelligence |
| One-click VPD + temp + humidity automation for a named grow stage ( |
🤖 Advance Automation |
| List all named Advance Automation programs on a device |
🤖 Advance Automation |
| Get full detail (schedule, port groups, run state) for one automation |
🤖 Advance Automation |
| Enable a disabled automation — reads state first, no-ops if already enabled ( |
🤖 Advance Automation |
| Disable an enabled automation — reads state first, no-ops if already disabled ( |
🤖 Advance Automation |
| Create a new named automation; the first rule can be off, on, cycle, auto (temp/humidity), or VPD ( |
🤖 Advance Automation |
| Delete an automation (disables first if active) ( |
🤖 Advance Automation |
| Add one rule (window + behavior) to an existing program — off, on, cycle, auto (temp/humidity), or VPD ( |
🤖 Advance Automation |
| Edit one rule in place — change its window, speed, mode, or sensor targets ( |
🤖 Advance Automation |
| Remove a single rule from a program, leaving the rest intact ( |
🤖 Advance Automation |
| Safely break a port out of automation control and lock co-governed ports to manual speed ( |
✦ All write tools (Write, Automation, and Intelligence categories) default to
dry_run=True— they return the exact payload they would send without making any changes to your equipment. Passdry_run=Falseonly when you're ready to execute.
📖 For a complete grower's guide with conversation examples for every tool, see docs/GUIDE.md.
MCP Prompts
Three built-in prompts are registered alongside the tools. In Claude Desktop and other MCP clients, these appear as slash commands or prompt suggestions.
Prompt | What it does |
| Step-by-step guide: diagnose HIGH or LOW VPD and which tools to call to fix it |
| Onboarding walkthrough: discover devices → apply a stage template → check your health score |
| How to read |
Quick start
Option 1: pip (simplest)
pip install git+https://github.com/ober37/ac-infinity-mcp.gitRequires Python 3.11+.
Option 2: isolated venv (recommended)
python3 -m venv ~/.venvs/ac-infinity-mcp
source ~/.venvs/ac-infinity-mcp/bin/activate
pip install git+https://github.com/ober37/ac-infinity-mcp.git
which ac-infinity-mcp # copy this path — you'll need it belowOption 3: uvx (no install)
uvx --from git+https://github.com/ober37/ac-infinity-mcp.git ac-infinity-mcpMCP client configuration
Claude Desktop
Edit ~/Library/Application Support/Claude/claude_desktop_config.json (macOS) or
%APPDATA%\Claude\claude_desktop_config.json (Windows):
{
"mcpServers": {
"ac-infinity": {
"command": "/path/to/ac-infinity-mcp",
"env": {
"AC_INFINITY_EMAIL": "you@example.com",
"AC_INFINITY_PASSWORD": "yourpassword"
}
}
}
}Replace /path/to/ac-infinity-mcp with the path printed by which ac-infinity-mcp.
Cursor / Windsurf
Add to your MCP settings:
{
"ac-infinity": {
"command": "/path/to/ac-infinity-mcp",
"env": {
"AC_INFINITY_EMAIL": "you@example.com",
"AC_INFINITY_PASSWORD": "yourpassword"
}
}
}Docker
cp .env.example .env
# fill in AC_INFINITY_EMAIL and AC_INFINITY_PASSWORD
docker compose up --buildThe container runs over stdio. Connect via a stdio bridge such as mcp-proxy.
Credentials are injected at runtime via
env_file— never baked into the image.
Environment variables
Variable | Required | Description |
| Yes | Your AC Infinity account email |
| Yes | Your AC Infinity account password |
⚠️ HTTP-only upstream: The AC Infinity cloud API does not support HTTPS. Credentials and sensor data traverse the network in plain text. This is an upstream limitation — see docs/API.md Quirk 8. Avoid running this server on untrusted networks.
Development
git clone https://github.com/ober37/ac-infinity-mcp.git
cd ac-infinity-mcp
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
cp .env.example .env # fill in credentials
# Lint + type-check
ruff check src/ tests/
mypy src/ac_infinity_mcp/
# Tests (unit + integration)
pytest tests/ -v
# Security audit
pip-auditSecurity
Vulnerabilities should be reported via GitHub Private Vulnerability Reporting. See SECURITY.md for the full disclosure policy, scope, and known limitations (including the HTTP-only upstream API). Accepted dependency CVEs are tracked in docs/SECURITY-RISKS.md.
License
MIT
Available Tools
25 toolsapply_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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes | ||
| stage | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses that it issues an atomic write, sets VPD mode with atType=8, stores temperature and humidity thresholds for fallback, and describes the dry_run behavior. No annotations provided, so description carries full burden and does so thoroughly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with purpose first, then dry_run explanation, table for stages, followed by Args and Returns. No unnecessary sentences, every part earns its place.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all aspects: what it does, parameters, defaults, return format, and error handling. Complements the output schema richness.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has zero descriptions, but the description explains each parameter in detail, including the stage table with exact targets for VPD, temperature, and humidity. This adds substantial meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states 'Apply a grow-stage automation template' which is a specific verb and resource. It explains the combined action of setting VPD, temperature, and humidity, distinguishing it from sibling tools that handle individual parameters.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides usage context: defaults to dry_run=True, set dry_run=False to actually write. Implicitly suggests previewing before applying, but does not explicitly mention when not to use or compare to individual automation tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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:
Checks that the port is actually under automation (idempotent: no-ops if not).
Finds the governing automation.
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.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes | ||
| dry_run | No | ||
| confirm_automation_name | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: idempotent, locks co-ports, requires safety confirmation, dry_run versus live, and return formats. It is transparent about every step and outcome.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with bullet points and sections, but it is somewhat verbose. However, it is front-loaded with the purpose and process, and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description is complete: it covers idempotent, dry_run, live, error responses, and safety confirmation. Given the output schema exists, the return values are adequately explained.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Despite 0% schema description coverage, the description explains each parameter in detail (device_id from discover_devices, port 1-based, dry_run default, confirm_automation_name required for live), adding significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's purpose: 'Break a port out of Advance Automation control and lock co-governed ports.' It uses a specific verb and resource, and the step-by-step process differentiates it from sibling tools like disable_advance_automation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explains when to use the tool ('safe way to manually override a port') and mentions idempotent behavior and dry_run default. It lacks explicit when-not-to-use or alternatives, but the context is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}``.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| stage | No | veg |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided; description fully details behavior: status values (OK, LOW, HIGH), deviation semantics, alert field (null when OK), and error format. It discloses return structure comprehensively.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with Args and Returns sections, front-loaded purpose. Includes a helpful JSON example. Slightly lengthy but every sentence adds value; no fluff.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given output schema is implicitly provided via example and field explanations, description covers return values, deviations, alerts, and error handling. Sufficient for an AI agent to use the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Input schema has 0% description coverage, providing only titles and types. Description adds meaning: device_id sourced from discover_devices, stage lists allowed values (clones, seedling, etc.) and default. This significantly enhances schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states the tool checks if current VPD is within target range for a growth stage, specifying the verb 'check', resource 'VPD', and context 'growth stage'. It distinguishes from sibling tools like 'set_vpd_automation' and 'detect_environment_trends'.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description explains parameters and return values, implying use when needing to verify VPD compliance. However, it does not explicitly exclude alternative tools or provide when-not guidance, so it scores 4.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| name | Yes | ||
| on_speed | Yes | ||
| port | Yes | ||
| off_speed | No | ||
| begin_time | No | ||
| end_time | No | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description fully discloses behavior: dry_run safety, automatic bitmask, off_speed unused, error handling with available_ports and suggested_reply, and return structure.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Structured clearly with purpose first then parameter details. Slightly verbose with return value enumeration but well-organized. Could be more concise without losing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Complete for a complex tool with 8 parameters and no annotations. Covers all inputs, behaviors, defaults, return types, and error cases. Output schema exists but description adds extra context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, yet description adds meaning for all 8 parameters: valid ranges, defaults, special values (255), and usage context like off_speed being compatibility-only.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Create a new Advance Automation on a device', specifying verb and resource. However, does not explicitly differentiate from sibling tools like set_temperature_automation or modify operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit when-to-use or alternative comparisons. Provides safety hints (dry_run default) but no guidance on when to choose this tool over others.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| automation_id | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but the description fully discloses the dry_run safety mechanism, the disabling step, and the error response format. This compensates for the lack of annotations.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Concise yet comprehensive: a single sentence for the main action, followed by necessary details in a structured format (Args, Returns). No superfluous content.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (3 params, output schema exists but not shown), the description covers all behavioral aspects, return format, and preconditions. No gaps identified.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description documents each parameter with its source (discover_devices, list_advance_automations) and default (dry_run=True), adding significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states 'Delete an Advance Automation from a device', using a specific action and resource. It uniquely identifies the tool's purpose among siblings like disable_advance_automation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear guidance: dry_run default, disabling before deletion, and references to other tools for obtaining device_id and automation_id. Also explains return behavior on failure.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| days | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden. It clearly explains the return format (JSON with slope, direction, projection, alert flag) and notes the API limitation of ~1257 records per day, which affects data density. This is sufficient transparency for a read-only analysis tool.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with Args and Returns sections, and the API limitation note is useful. It is fairly concise, though the note could be integrated more succinctly. Still, it avoids redundancy and is easy to parse.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the low complexity (2 parameters, no nested objects) and that an output schema exists, the description covers purpose, parameters, return structure, and a key limitation. It is fully informative for an AI agent to select and invoke the tool correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, but the description fully compensates by explaining device_id as 'The AC Infinity device code (from discover_devices)' and days with default, range (1–30). This adds crucial meaning beyond the schema's basic type info.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description explicitly states it detects linear trends in temperature, humidity, and VPD over a look-back window. The verb 'detect' and the resource 'environment trends' are specific and distinct from sibling tools like check_vpd_drift (focuses on drift) and get_historical_readings (raw data).
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for trend analysis but does not explicitly state when to use this tool versus alternatives like check_vpd_drift or get_environment_health. The note about API data sparsity provides some context, but explicit when-to-use and when-not-to-use guidance is missing.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| automation_id | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses key behaviors: no-op if already disabled, dry_run defaults to true, disabling sets governed ports to OFF, re-enabling restores ADVANCE mode immediately. Includes live-testing date for confidence.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections: purpose, behavior, arguments, returns. Slightly verbose but every sentence adds value. Could be tightened without losing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers all necessary context: preconditions, execution behavior, arguments, return format, error handling. Output schema is described adequately, making the tool fully understandable.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
With schema coverage at 0%, the description fully explains each parameter: device_id from discover_devices, automation_id from list_advance_automations, dry_run as boolean defaulting to true. Also details the return structure.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool's action: 'Disable a currently enabled Advance Automation.' It also notes that it reads current state and no-ops if already disabled, distinguishing it from similar tools like break_out_of_automation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Explicitly mentions default dry_run=True and contrasts with break_out_of_automation for controlled handoff. Provides clear instructions for when to use this tool vs. alternatives.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}``.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description discloses all behavioral traits: it is a read-only discovery operation, returns a list of devices with ID and status, and handles empty accounts and errors with specific response structures. This gives agents full transparency about the tool's behavior and error handling.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is extremely concise, front-loading the purpose in the first sentence and using a structured format with examples. Every sentence adds value, and there is no redundant information.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given zero parameters and the presence of an output schema, the description is complete. It covers all necessary information: purpose, output format, error cases, and guidance on using the results. There are no gaps for a simple discovery tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Since there are no parameters, the baseline is 4. The description adds value by explaining the purpose of the output (device_ids for other tools) and providing example responses, making the tool's usage clear despite no input parameters.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Discover all AC Infinity devices from the cloud API' and outlines the return values (device IDs, names, online status) and the purpose of finding device_ids for other tools. This distinguishes it from sibling tools that perform actions on devices.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description explicitly says 'Use this to find device_ids for use in other tools,' providing clear guidance on when to invoke it. It does not state exclusions, but the context of sibling tools makes it evident this is the primary device listing tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| automation_id | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: reads current state, no-ops if already enabled, uses a toggle endpoint, and explains the dry-run mode. No hidden side effects.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections, but slightly verbose. Every sentence adds value, though some could be tightened. Still clear and organized.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given small schema and no annotations, description covers all needed info: behavior, parameters, return values, error handling. Differentiates well from sibling automation tools.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but description defines each parameter: device_id from discover_devices, automation_id from list_advance_automations, dry_run default True. Adds essential context beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool enables a previously disabled Advance Automation, distinguishes from sibling tools like disable_advance_automation, and specifies it reads current state to avoid redundant toggles.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear guidance: defaults to dry_run=True, set to False to execute, and explains the toggle logic. Lacks explicit when-not-to-use but context from siblings fills the gap.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| automation_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully discloses behavior: it returns JSON with detail, including quirks like Quirk 21 for schedule modes and port resolution from bitmasks. It also specifies the failure response format. This provides comprehensive behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is detailed but well-structured with Args, Returns, and specific formatting details. Every sentence adds value, though it is somewhat lengthy. It could be slightly more concise, but the level of detail justifies the length.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the output schema exists, the description goes beyond by explaining return fields in detail, including edge cases like schedule_note and error responses. It covers everything needed for an agent to invoke and interpret the result correctly.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The input schema has 0% description coverage, but the description explains each parameter: device_id is 'The AC Infinity device code (from discover_devices)' and automation_id is 'the automation_id from list_advance_automations.' This adds necessary context beyond bare parameter names.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description starts with 'Get full detail for a single Advance Automation by ID,' using a specific verb and resource. It clearly distinguishes from siblings like list_advance_automations and create/delete/disable/enable, which are separate operations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions prerequisites ('device_id from discover_devices' and 'automation_id from list_advance_automations'), guiding the agent on when to use this tool. It does not explicitly state when not to use it or list alternatives, but the context is clear enough for an AI agent.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden and excellently discloses return format, device-level error handling, port_status condition, external_sensors filtering, and auth/API failure behavior.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear opening sentence followed by detailed return information. Every sentence adds value and is appropriately concise.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool has zero parameters and no annotations but an output schema, the description is highly complete, covering purpose, return format, error cases, and special conditions.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The tool has zero parameters, so baseline is 4. No parameter info needed.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states 'Get current sensor readings for all AC Infinity devices' with a specific verb and resource. It distinguishes itself from the sibling tool 'get_device_reading' which targets a single device.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description says 'Useful for a full status check across all controllers', implying when to use. However, it does not explicitly mention when not to use or directly reference the alternative single-device tool.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}``.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description thoroughly discloses behaviors: timezone/unit handling, exclusion of phantom external sensors, conditional plug_status field, and error format. This is highly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with a clear purpose, args section, return example, and edge case notes. Every sentence adds value, and it is front-loaded with the core function.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the complex return data and lack of annotations, the description is complete: it covers return fields, edge cases, error format, and parameter origin. The output schema presence reduces burden, but the description adds necessary context.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The schema has only a device_id string with no description. The description adds meaning by noting the device_id comes from discover_devices and showing an example. This compensates for 0% schema coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool gets current sensor reading for a device by device_id, listing the specific fields returned. It differentiates from siblings like get_all_device_readings by focusing on a single device.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for retrieving a single device's current reading, but does not explicitly mention alternatives like get_all_device_readings or when not to use it. The context is clear enough for basic guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| stage | No | veg |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the full burden. It describes a read-only calculation but does not explicitly state it is non-destructive, idempotent, or require specific permissions. The lack of explicit behavioral traits leaves some ambiguity.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is concise and well-structured, using separate sections for args and returns without unnecessary words. Every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description covers input and output comprehensively, including return JSON fields. It lacks examples or error handling notes, but given the existing output schema, it is sufficiently complete for an AI agent.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The description thoroughly explains both parameters: device_id as 'The AC Infinity device code (from discover_devices)' and stage with enumerated options and default. This compensates fully for the 0% schema description coverage.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool calculates a composite environment health score (0–100) for a device. It is distinct from sibling tools like get_all_device_readings or get_device_reading which provide raw data, making its purpose unique.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description implies usage for health assessment but does not explicitly specify when to use versus alternatives, such as when needing raw readings or trend detection. No when-not or alternative references are given.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}``.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| start_date | Yes | ||
| end_date | Yes | ||
| sample_interval | No | 1h | |
| time_start | No | ||
| time_end | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, the description carries full burden. It explains return format (readings, statistics, dropped_readings), error structure, and crossing midnight logic for time filters. It also notes timezone conversion hints. Missing rate limits or auth details, but overall transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with Args and Returns sections. It is fairly long but every sentence provides unique guidance. Could be slightly more concise, but no redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given 6 parameters, no annotations, and an output schema (though not shown), the description covers return shape, error cases, and references full docs. It is complete for a query tool, though could mention pagination or rate limits.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so description must compensate. It explains each parameter in detail: device_id source, date formats, sample_interval with examples and default, time_start/time_end format with crossing midnight logic and error handling. This adds significant value beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description states 'Query AC Infinity environment data across a date range with configurable sampling,' which is a specific verb+resource+scope. It clearly distinguishes from sibling tools like get_all_device_readings and get_device_reading.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions using device_id from discover_devices and gives format hints, but does not explicitly state when to use this tool vs alternatives. Usage is implied but not guided with exclusions or comparisons.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| days | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden and excels: it details data_quality stripping, ghost-port filter rules, debouncing, unreliable port caveats, and device-specific notes. All behavioral traits are disclosed.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is quite lengthy and could be more tightly organized. While it has sections (Args, Returns, Presentation guidance), it includes many granular details that might be streamlined for brevity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity and the presence of an output schema, the description covers all necessary aspects: parameters, return values, edge cases, and presentation. It is complete and leaves no significant gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description adds full meaning: device_id is explained as 'The AC Infinity device code (from discover_devices)' and days has default and range (1–30). This compensates completely for the schema gap.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool 'Build a per-port runtime activity report from historical data', using a specific verb and resource. It distinguishes itself from siblings like get_port_status by focusing on historical analysis over time.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides extensive guidance on presentation and interpretation, but does not explicitly state when to use this tool versus alternatives like get_port_status or list_advance_automations. The context is implicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}``.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, but description fully compensates by disclosing endpoint, both normal and ADVANCE modes, edge cases (disconnected ports), staleness handling, error format, and enrichment fields. Highly transparent.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections (Args, Returns, examples) and front-loaded purpose. Slightly verbose due to detailed edge-case explanations, but each sentence adds value. Good balance of completeness and readability.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's complexity (two modes, multiple fields, edge cases) and presence of output schema, description covers all necessary aspects: return values, failure handling, staleness, and human_summary variants. No gaps.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% description coverage, yet description adds clear meaning: device_id is 'AC Infinity device code (from discover_devices)' and port is '1-based port number'. Provides essential context beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Get the full automation configuration for a port' with specific verb and resource. Differentiates from siblings like set_port_mode and get_port_status by focusing on full automation configuration.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Implies usage context by detailing return values (mode, speed, automation targets). Lacks explicit alternatives or when-not-to-use guidance, but the description is informative enough for an agent to infer appropriate use cases.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, description fully carries behavioral disclosure. It details conditional field presence (plug_status, remain_time_seconds, automation_name, note), handling of edge cases (unpowered ports, default vs custom names), failure response format, and ADVANCE detection logic. Extremely thorough.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Front-loaded with core purpose, then detailed behavior. Slightly verbose with multiple paragraphs, but every sentence adds value. Could be more structured (e.g., bullet points for conditional fields), but still efficient.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite schema parameters being minimal, description and output schema (assumed present) together fully cover expected behavior. Includes JSON example, error handling, and edge cases. Context signals show output schema exists, so description need not repeat return values.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% coverage, so description adds essential meaning: device_id source (from discover_devices) and port numbering (1-based). This is clear and helpful, though could mention type or constraints (e.g., valid device IDs).
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Get the live operational status of a single port,' identifying specific verb and resource. Distinguishes from siblings like 'get_all_device_readings' and 'get_port_settings' by focusing on live status of a single port.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives. Does not mention when not to use or suggest other tools from the sibling list. Only implies usage for live status retrieval.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations provided, so description carries full burden. It discloses return format (JSON with automations list) and error behavior, but does not mention side effects, authentication requirements, or rate limits. Adequate for a read-only list operation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with header, explanations, arguments, and return examples. Front-loaded purpose clearly. Slightly verbose with docstring-style formatting but no wasted sentences.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given one parameter, no annotations, and presence of output schema, the description fully explains input, output structure including fields and error cases. No additional context needed.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
The single parameter 'device_id' is described as 'The AC Infinity device code (from discover_devices)', adding meaning beyond the schema which only specifies type string. Schema coverage is 0%, so description fully compensates.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the tool lists all Advance Automations on a device, explains that they are also called 'programs' and are named schedules governing ports, which distinguishes it from siblings that create, delete, or get individual automations.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
No explicit guidance on when to use this tool versus alternatives like 'get_advance_automation' or 'create_advance_automation'. The description simply states what it does without clarifying context for selection.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes | ||
| min_rh | Yes | ||
| max_rh | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses read-before-write, dry_run behavior, threshold rounding, valid ranges, and return format. No annotations provided, so description bears full burden and meets it thoroughly.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with clear sections (Args, Returns). Detailed but not overly verbose. A minor trim could improve conciseness, but it's effective.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations, the description covers all behavioral aspects: read-before-write, rounding, defaults, modes. Also describes return schema. Complete for a tool of this complexity.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description explains every parameter including device_id, port, min_rh (with rounding), max_rh (with constraint > min_rh), and dry_run (with default). Adds meaning beyond schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states 'Enable humidity automation on a port' using a specific sensor. Distinguishes itself from siblings like set_temperature_automation and set_vpd_automation by focusing on humidity.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Describes the effect (switches to AUTO mode, sets thresholds) and includes details like read-before-write and dry_run default. Does not explicitly mention when not to use, but the purpose is clear.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes | ||
| mode | Yes | ||
| dry_run | No | ||
| cycle_on_seconds | No | ||
| cycle_off_seconds | No | ||
| schedule_start | No | ||
| schedule_end | No | ||
| timer_duration_seconds | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries full weight. It discloses the use of read-before-write and the default dry_run=True, and explains the return format. While it does not cover permissions or rate limits, these are not expected for this tool. The behavioral details are sufficient for safe invocation.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured: a one-line summary, followed by important notes (supported modes, read-before-write, dry run default, alternative tools), then a clear args listing with each parameter's description and conditions. No extraneous text; every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Despite 9 parameters and conditional requirements, the description covers all aspects: purpose, usage notes, parameter semantics (including which modes require which parameters), and return structure. The presence of an output schema is noted, but the description already explains the return format. This is a complete and self-contained documentation.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema description coverage is 0%, so the description must compensate. It provides thorough explanations for each parameter, including conditional requirements for specific modes (e.g., cycle_on_seconds required for CYCLE, schedule_start/end required for SCHEDULE). This fully clarifies the meaning and constraints beyond the raw schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description opens with a clear verb and resource: 'Switch a port to a specific automation mode.' It lists all 8 modes and explicitly distinguishes from dedicated tools like set_vpd_automation, set_temperature_automation, and set_humidity_automation, making its purpose unambiguous.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description states when to use this tool and recommends alternative specialized tools for VPD, AUTO modes. However, it does not explicitly mention when not to use it (e.g., for simple on/off actions, where set_port_on/set_port_off may be more appropriate). This is a minor gap in comprehensive guidance.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}``.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Without annotations, description fully discloses key behaviors: read-before-write, dry_run effect, return value structure, warning for disconnected ports, and failure error. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with paragraphs for purpose, args, returns. Some redundancy (e.g., 'dry_run=True — set dry_run=False') but front-loaded and every sentence adds value.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
With output schema present, return values are well explained including warning and error. No mention of prerequisites or permissions, but overall complete for a state-changing tool.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema has 0% description coverage, so description compensates by explaining all three parameters: device_id (source), port (1-based), dry_run (dry run vs write). Adds meaningful context beyond schema types.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states the action ('Sets mode to OFF') and resource ('port'). Includes technical details (atType=1, onSpead=0) that differentiate it from sibling tools like set_port_on or set_port_speed.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides clear guidance on dry_run usage (default True, set False to write). States it works for all device types but does not explicitly exclude alternatives or specify when not to use.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}``.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description fully carries the transparency burden. It discloses read-before-write behavior, dry_run default, error handling, and warning conditions for disconnected ports. No contradictions.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with sections for args, returns, and warnings. It is front-loaded with the core action. However, it is slightly verbose; some sentences could be merged without losing clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given the tool's three parameters, the output schema is described in detail, covering all returned fields, warning conditions, and error cases. The description is fully complete for an AI agent to understand correct usage and expected output.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, but the description adds significant meaning: device_id is exemplified, port is specified as 1-based, and dry_run's behavior and default are explained. This compensates completely for the missing schema descriptions.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action: turning a port on at full speed (onSpeed=10). It specifies the tool's applicability to fan-type and on/off toggle devices, and the sibling context (e.g., set_port_off, set_port_speed) further distinguishes its purpose.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description mentions the types of devices it works for and the dry_run default, but does not explicitly provide when-to-use vs alternatives, when-not-to-use, or prerequisites. Usage is implied but not fully guided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}``.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes | ||
| speed | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description fully carries the burden of disclosing behavior. It explains the read-before-write approach, default dry_run=True, the response format including a warning for OFF mode, and failure output.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
The description is well-structured with Args, Returns, and an Example section, but it is somewhat lengthy. While every sentence adds value, a slightly more condensed version could be possible while retaining clarity.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
The description fully covers the tool's complexity, including edge cases (OFF mode), dry_run behavior, return values, and error handling. It provides sufficient context for correct invocation, given the output schema enriches this further.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so the description must fully explain parameters. It does so clearly: device_id (from discover_devices), port (1-based), speed (1-10), dry_run (boolean, default true). This adds significant meaning beyond the schema.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
The description clearly states the action as 'Set fan or dimmer speed on a specific port', with a specific verb and resource. It distinguishes itself from sibling tools like set_port_mode and set_port_on/off by focusing on speed setting.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
The description provides clear context for using the dry_run parameter and warns about the OFF mode requirement, but it does not explicitly state when to use this tool versus alternatives like set_port_mode. The guidance on dry_run usage is strong.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes | ||
| min_temp | Yes | ||
| max_temp | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Discloses read-before-write behavior, default dry_run=True, controller speed-up/slow-down logic, and failure return format. No annotations exist, so description carries full burden and does so well.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Well-structured with sections for purpose, usage, args, and returns. Slightly lengthy but justified by complexity; front-loaded with main action.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Covers prerequisites, behavior, parameter constraints, and return format. Output schema exists but description enriches understanding with unit and rounding details.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Explains all five parameters in detail, including device_id source, port numbering, threshold constraints, rounding, and dry_run purpose. Schema provides no descriptions, so this adds significant value.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Clearly states it enables temperature automation on a port, switches to AUTO mode, and sets thresholds. Distinguishes from sibling tools by focusing on temperature specifically.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Provides guidance on unit handling (preferred unit, call discover_devices), valid ranges, and rounding. Lacks explicit alternatives but gives sufficient context for correct usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
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": "..."}.
| Name | Required | Description | Default |
|---|---|---|---|
| device_id | Yes | ||
| port | Yes | ||
| target_vpd | Yes | ||
| dry_run | No |
Output Schema
| Name | Required | Description |
|---|---|---|
| result | Yes |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries full burden. It discloses dry_run default and meaning, read-before-write behavior, and return format including error handling. This provides sufficient behavioral transparency.
Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.
Is the description appropriately sized, front-loaded, and free of redundancy?
Description is concise and well-structured. Brief intro, clearly labeled Args section, and Returns section. Every sentence provides necessary information without redundancy.
Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.
Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?
Given no annotations but presence of output schema, the description covers behavior, parameters, and return format comprehensively. An agent can correctly invoke the tool based on this description.
Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.
Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?
Schema coverage is 0%, so description compensates fully. Each parameter is explained: device_id source, port 1-based, target_vpd range and typical stage values, dry_run default and effect. Adds significant value beyond schema titles.
Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.
Does the description clearly state what the tool does and how it differs from similar tools?
Description clearly states it enables VPD automation on a port using built-in sensors. The verb 'enable' and resource 'VPD automation on a port' are specific, and the tool is distinct from siblings like set_humidity_automation or set_temperature_automation.
Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.
Does the description explain when to use this tool, when not to, or what alternatives exist?
Description mentions switching to VPD mode and setting target, but does not explicitly state when to use this tool over alternatives. No when-not guidance is provided. However, the context of VPD automation is clear enough for an agent to infer appropriate usage.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
Tool Schema Changelog
Recent tool additions, removals, and schema changes observed during successful MCP inspections.
25 tool updates
v1.0.0-beta- First observed
apply_grow_stage_template - First observed
break_out_of_automation - First observed
check_vpd_drift - First observed
create_advance_automation - First observed
delete_advance_automation - First observed
detect_environment_trends - First observed
disable_advance_automation - First observed
discover_devices - First observed
enable_advance_automation - First observed
get_advance_automation - First observed
get_all_device_readings - First observed
get_device_reading - First observed
get_environment_health - First observed
get_historical_readings - First observed
get_port_activity_report - First observed
get_port_settings - First observed
get_port_status - First observed
list_advance_automations - First observed
set_humidity_automation - First observed
set_port_mode - First observed
set_port_off - First observed
set_port_on - First observed
set_port_speed - First observed
set_temperature_automation - First observed
set_vpd_automation
TDQS
Scored across 25 tools
Every tool has a clearly distinct purpose: discovery, reading, port control, automation management, and environmental analysis. Even closely related tools like set_port_on and set_port_off are differentiated by their specific action.
All tool names follow a consistent verb_noun pattern using lowercase and underscores (e.g., discover_devices, set_port_speed, list_advance_automations). No mixing of conventions.
With 25 tools, the server is comprehensive but slightly heavy. Each tool serves a clear purpose within the AC Infinity ecosystem, but the count is on the higher end of the ideal range.
The tool surface covers core CRUD operations, automations, port control, and environmental monitoring. Missing an update_advance_automation tool and some scheduling tweaks, but overall well-rounded.
Maintenance
Related MCP Connectors
- QuallaaOAuthcom.quallaa
Talk to your public-facing AI from any MCP client — Claude, ChatGPT, Cursor, Cline, Windsurf.
Hosted MCP server connecting claude.ai, ChatGPT and other AI apps to your own computer
The OpenRouter MCP server plugs OpenRouter into the AI tools you already use. Once connected, your assistant can pull live OpenRouter data (models, prices, your credits, rankings, and docs) and send quick test messages, all without leaving your editor.
- mcpOAuthai.butlerbrain
Persistent memory for AI assistants. Save once; recall from Claude, ChatGPT, or any MCP client.
Related MCP Servers
- FlicenseNot gradedqualityDmaintenanceA Multi-Agent Conversation Protocol server that provides an interface to Google's Cloud IoT API, allowing agents to interact with and manage IoT devices and registries through natural language.-
- AlicenseNot gradedqualityDmaintenanceAn MCP server that wraps the Ambient Weather REST API. Query your personal weather stations conversationally from Claude Code, Claude.ai, or any MCP-compatible client.1MIT
- AlicenseAqualityDmaintenanceEnables registration, monitoring, and control of IoT devices via AI agents, with local storage and no cloud API key required.9MIT
- AlicenseNot gradedqualityAmaintenanceMCP server that connects AI assistants like Claude to WHOOP health data, enabling natural language queries about recovery, sleep, workouts, and more.110 npm152MIT