gree-ac-mcp-server
Click on "Deploy Server".
Wait a few minutes for the server to deploy. Once ready, it will show a "Started" state.
In the chat, type
@followed by the MCP server name and your instructions, e.g., "@gree-ac-mcp-serverSet living room AC to 24 degrees"
That's it! The server will respond to your query, and you can continue using it as needed.
Here is a step-by-step guide with screenshots.
gree-ac-mcp-server
A Model Context Protocol (MCP) server that controls GREE / EWPE-compatible WiFi air conditioners directly over their native UDP protocol. No Homebridge, no cloud — it talks straight to the units on your LAN.
The GREE wire protocol (AES encryption, scan/bind/status/command flow) is implemented from scratch based on eibenp/homebridge-gree-airconditioner and tomikaa87/gree-remote.
Two transports: MCP
stdio(for Claude Desktop and other local clients) andhttp(modern Streamable HTTP and legacy HTTP+SSE), with mandatory bearer auth on HTTP.Both encryption schemes: v1 (AES-128-ECB) and v2 (AES-128-GCM), auto-detected per device.
Background polling: each device is bound and polled continuously; tool calls fire immediately and the next poll confirms the new state.
Requirements
Node.js >= 22
The AC units must be on the same LAN/subnet as the server (UDP broadcast/unicast to port 7000).
Related MCP server: HueMCP
Install & build
npm install
npm run buildQuick start
cp config.example.json config.json
# edit config.json: set bearerToken and your devices' mac/address
# stdio (local MCP clients)
npm run start:stdio -- --config ./config.json
# HTTP (network clients)
npm run start:http -- --config ./config.json --host 0.0.0.0 --port 8080During development you can run the TypeScript directly with npm run dev:stdio / npm run dev:http.
CLI flags
Flag | Default | Description |
|
| Transport mode. |
|
| Path to the config file. Required for HTTP mode; optional for stdio (starts with no devices if omitted). |
|
| HTTP bind host (http mode). Overrides config. Must be non-empty. |
|
| HTTP bind port (http mode). Overrides config. Must be an integer 1–65535. |
|
| Log verbosity (JSON lines on stderr). |
The config file path may also be supplied via the GREE_MCP_CONFIG environment variable.
Configuration
JSON file validated with zod. On a validation error the server prints the offending field/device and exits non-zero. The server must be restarted to pick up config changes (hot-reload is not implemented).
Top-level fields
Field | Type | Default | Notes |
| string | — (required) | Token required on every HTTP/SSE request. Minimum 32 characters. Ignored in stdio mode. |
| number |
| UDP port the devices listen on. |
| number (ms) |
| Default status-poll interval. |
| number (ms) |
| Default retry/offline-detection interval. |
| string |
| Default HTTP bind host (overridable by |
| number |
| Default HTTP bind port (overridable by |
| string[] |
| Allowed CORS origins for HTTP mode. Empty disables CORS; |
| array | — (required, ≥1) | One entry per AC. Duplicate |
Per-device fields
Field | Type | Default | Notes |
| string | — (required) | Friendly name; usable as a tool selector alias. |
| string | — | Optional grouping label. |
| IPv4 string | — | If set, the server unicasts to it. If omitted, it discovers the IP by MAC via UDP broadcast, then caches it. |
| string | — (required) | 12 hex chars (separators/case are normalized). Primary key for all tools and binding. |
| string | — | Display only. |
| string | — | Optional separate fan name (display only). |
| string | — | Optional; reserved for key-cache identity. |
| number |
| Lower bound for |
| number |
| Upper bound for |
| enum | on= | Swing positions applied by |
| boolean |
| Gates the |
| boolean |
| Gates the |
| boolean |
| If the unit has no real sensor, estimate current temp from target and flag |
| number (°C) |
| Calibration added to the decoded current temperature. |
|
|
| Physical fan steps; used to map |
|
|
|
|
| number (ms) | inherits top-level | Per-device override. |
| number (ms) | inherits top-level | Per-device override. |
Note on
sensorOffsetand temperature decoding. Most GREE units report the internal sensor (TemSen) asactual°C + 40. The server subtracts that fixed base offset to decode, then adds yoursensorOffsetas a calibration on top. SocurrentTemperature = TemSen − 40 + sensorOffset.
Swing position enums
Vertical (
SwUpDn):default,full,fixed-top,fixed-upper-middle,fixed-middle,fixed-lower-middle,fixed-bottom(plusswing-top/swing-upper-middle/swing-middle/swing-lower-middle/swing-bottom).Horizontal (
SwingLfRig, only on units with horizontal louvers):default,full,fixed-left,fixed-center-left,fixed-center,fixed-center-right,fixed-right.
How to obtain a device's MAC
The MAC is the GREE device id (a 12-hex string, e.g. 502cc6aabbcc). Following the homebridge
plugin's documented method, the easiest way is to run this server (or the homebridge plugin)
with debug logging on the same LAN and watch the scan responses:
node dist/index.js --transport http --config ./config.json --log-level debugEvery discovered unit logs a device discovered line containing its mac, address, model
and firmware version. Other options:
Check your router's DHCP client list for the AC's WiFi adapter MAC (drop the colons, lowercase it).
Use the official GREE+ / EWPE Smart app, or any GREE scan utility, which reports the device id.
MCP tools
Every tool accepts a device selector: mac (canonical) or name (alias, matched against
config). Provide one of them. set_* tools fire the UDP command immediately and report
"command sent"; the background poll loop confirms the new state shortly after. If a device is
offline/unbound, write tools return an error instead of silently succeeding.
Tool | Input schema | Description |
|
| All configured devices with |
|
| Full decoded status of one device. |
|
| Calibrated current temp (°C). Flags |
|
| Turn the unit on/off. |
|
| Set mode (also powers on). |
|
| Set target °C. Rejected (not clamped) if out of the device's min/max range. |
|
| Set fan speed; |
|
| Apply the configured on/off swing positions. |
|
| X-Fan / blow. Only usable when |
|
| Display light. Only usable when |
|
| Quiet mode (turning on disables turbo). |
|
| Turbo/powerful mode (turning on disables quiet). |
Each device is also exposed as a resource at gree://device/<mac> returning its decoded
status as JSON.
Using with Claude Desktop (stdio)
Add to claude_desktop_config.json:
{
"mcpServers": {
"gree-ac": {
"command": "node",
"args": [
"/absolute/path/to/gree-ac-mcp-server/dist/index.js",
"--transport", "stdio",
"--config", "/absolute/path/to/config.json"
]
}
}
}No bearer token is needed in stdio mode (the process pipe is the trust boundary).
HTTP usage
Bearer auth is mandatory on /mcp, /sse and /messages. Missing/invalid tokens get
401 with a WWW-Authenticate: Bearer header. /healthz is unauthenticated and returns only anonymized device identifiers (vendor-prefix-only MAC, first-letter-only name).
CORS (browser clients)
For browser-based MCP clients (e.g. the MCP Inspector) set corsOrigins in the config. CORS is
disabled by default (no headers added), so non-browser clients like Claude Desktop are
unaffected. When enabled:
OPTIONSpreflight is answered before auth (preflight carries noAuthorizationheader).The
Mcp-Session-Idresponse header is exposed so client JS can read the session id.Auth is still enforced on the actual request; only listed origins get an
Access-Control-Allow-Origin.
// config.json
"corsOrigins": ["https://inspector.example.com"] // or ["*"] to allow any originHealth check
curl http://localhost:8080/healthz
# {"status":"ok","total":2,"bound":1,"unbound":1,
# "devices":[{"mac":"502cc6******","name":"T***","bound":true}]}Modern Streamable HTTP
Initialize (note the required Accept header and that the session id comes back in a response header):
curl -i -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
# -> response header: Mcp-Session-Id: <uuid>Then reuse that session id:
SID=<uuid-from-above>
# complete the handshake
curl -s -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" -H "Mcp-Session-Id: $SID" \
-d '{"jsonrpc":"2.0","method":"notifications/initialized"}'
# list devices
curl -s -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" -H "Mcp-Session-Id: $SID" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_devices","arguments":{}}}'
# turn a unit on
curl -s -X POST http://localhost:8080/mcp \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" -H "Mcp-Session-Id: $SID" \
-d '{"jsonrpc":"2.0","id":3,"method":"tools/call","params":{"name":"set_power","arguments":{"mac":"502cc6aabbcc","on":true}}}'Legacy HTTP+SSE
# 1) open the event stream (keeps running; prints the "endpoint" event with your sessionId)
curl -N http://localhost:8080/sse -H "Authorization: Bearer YOUR_TOKEN"
# 2) post messages to the endpoint reported by the stream (sessionId from the endpoint event)
curl -X POST "http://localhost:8080/messages?sessionId=YOUR_SESSION_ID" \
-H "Authorization: Bearer YOUR_TOKEN" -H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Docker
The image is multi-stage and runs as the non-root node user, defaulting to HTTP mode reading
/config/config.json.
Prebuilt multi-arch images (linux/amd64 + linux/arm64) are published to GitHub Container
Registry:
docker run --rm \
--network host \
-v "$(pwd)/config.json:/config/config.json:ro" \
ghcr.io/marcinn2/gree-ac-mcp:latestOr build it yourself:
docker build -t gree-ac-mcp-server .
docker run --rm \
--network host \
-v "$(pwd)/config.json:/config/config.json:ro" \
gree-ac-mcp-serverUDP discovery/broadcast needs L2 access to the AC's subnet.
--network hostis the simplest way to give the container that on Linux; otherwise set each device'saddressexplicitly and ensure UDP/7000 routing to the units works from the container network.
The container EXPOSEs 8080. Override the entrypoint args to change transport/port, e.g.
docker run ... gree-ac-mcp-server --transport http --config /config/config.json --port 9000.
Logging & security
Logs are JSON lines on stderr (stdout is reserved for the MCP channel in stdio mode), including device
mac,action, andoutcome.The bearer token and all AES/device keys are never logged.
Logs contain device identifiers (
mac, IP address). When running as a long-lived service (systemd, Docker, etc.), cap retention with normal log rotation so these don't accumulate indefinitely. Keep the default--log-level info;debuglogs more identifiers.HTTP mode uses plaintext bearer auth. Run it only on a trusted home LAN, or put a TLS-terminating reverse proxy (Caddy, nginx, …) in front of it — otherwise the token and request data are exposed in transit.
stdiomode has no network exposure.
This is a self-hosted, personal/household tool with no analytics, no third-party services, and no on-disk data persistence (device state is kept in memory only). Configuration — including your
bearerTokenand device MACs — lives in your localconfig.json, which.gitignorealready excludes from version control.
Testing
npm testCovers the protocol crypto (v1/v2 encrypt-decrypt round-trips and a known-answer vector, plus
envelope pack/unpack), config-schema validation (defaults, MAC normalization, interval
inheritance, duplicate-MAC/duplicate-name, bad-value and short-bearerToken rejection), the
bearer-auth middleware (accepts the correct token; rejects wrong, mismatched-length and malformed
ones), and the CORS middleware (origin allow-listing, wildcard, and preflight handling).
Project layout
src/
index.ts entrypoint: CLI args, config load, lifecycle
config.ts zod schema, validation, defaults
logger.ts JSON-lines logger (stderr)
gree/
protocol.ts AES v1/v2 + pack envelope
commands.ts field codes, value maps, swing maps
device.ts GreeDevice: scan/bind/poll/command state machine
manager.ts DeviceManager: registry, resolve, health summary
types.ts shared types
mcp/
server.ts McpServer construction
tools.ts tool handlers
resources.ts per-device resources
transport/
stdio.ts stdio transport
http.ts Streamable HTTP + legacy SSE + /healthz
auth/
bearer.ts bearer-token middlewareOut of scope
No GCloud-bridged / sub-device (bridge) topology. The reference plugin supports devices behind a bridge (
mac@bridgemac); this server intentionally targets directly-addressable WiFi units only. TODO: add bridge/sub-device discovery and thesubDev/sublisthandshake if needed.No web UI.
Disclaimer
This is an independent, unofficial project. It is not affiliated with, endorsed by, or supported by GREE Electric Appliances Inc. or any of its subsidiaries. "GREE" and any related trademarks belong to their respective owners and are used here only to describe compatibility.
I built this in my free time and maintain it as a personal hobby project. It is provided as-is, without any warranty; use it at your own risk. It controls real heating/cooling hardware, so test carefully in your own environment.
GDPR / data protection
This is a self-hosted, personal/household tool. It runs entirely on your own machine/LAN, has
no analytics or third-party services, makes no external network calls, and persists nothing to
disk (device state is kept in memory; your bearerToken and device MACs live only in your local
config.json). The only personal-data-adjacent values it handles are device identifiers (MAC
and LAN IP addresses), which may appear in logs.
Used for your own home, this typically falls under the GDPR "purely personal or household activity" exemption (Art. 2(2)(c), Recital 18), meaning the GDPR generally does not apply. If you instead deploy it in a context where you process other people's data (e.g. a workplace, rental property, or any commercial setting), you are the data controller and are solely responsible for your own GDPR compliance, including transport security, log retention, transparency, and any required legal basis.
Any compliance commentary, scan, or assessment associated with this project is a preliminary, informational aid only — it is not legal advice and is not a substitute for a qualified legal audit. The authors accept no liability for how the software is deployed or used.
Available Tools
12 toolsget_device_statusGet device statusA
Return the full decoded status of one device (power, mode, temperatures, fan, swing, xFan, light, quiet/turbo, etc).
| Name | Required | Description | Default |
|---|---|---|---|
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden for behavioral disclosure. It does reveal that the output is 'decoded' and comprehensive, but it does not mention side effects, failure behavior for unknown devices, offline devices, or whether the read is live or cached. 'Return' suggests a safe read, but that is implicit rather than stated.
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 a single, well-structured sentence that front-loads the action and resource, then efficiently lists the status fields. There is no fluff or redundant repetition of schema 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?
The description adequately explains what the tool returns, which matters since there is no output schema. However, it does not state that at least one of mac or name should be supplied, what happens when neither is provided, or how errors like an unknown device are handled. These gaps make it minimally viable but not fully complete.
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 100%, with both mac and name already clearly explained. The description adds no additional parameter-level guidance beyond the notion of operating on 'one device', so the baseline score of 3 is appropriate.
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 uses a specific verb ('Return') and a specific resource ('full decoded status of one device'), and enumerates the included fields. This clearly distinguishes it from sibling tools like list_devices (which lists devices) and the set_* tools (which are mutations).
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 phrase 'one device' implies this is for retrieving the status of a single device, and the sibling set_* tools imply that this is the read counterpart. However, there is no explicit statement about when to use this tool versus alternatives such as list_devices or get_room_temperature, nor any qualification about selectors being required.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
get_room_temperatureGet room temperatureA
Return the calibrated current temperature in °C. If the unit lacks a real sensor and fakeSensor is enabled, the value is derived from the target temperature and flagged with "estimated": true.
| Name | Required | Description | Default |
|---|---|---|---|
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations are provided, so the description carries the behavioral disclosure burden. It meaningfully explains the estimated-temperature behavior and the 'estimated': true flag, plus calibration and the °C unit. This goes beyond the name and schema. It does not cover errors, auth, or side effects, but as a simple read operation this is a solid level of 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?
Two short sentences with no filler. The primary result is front-loaded, and the important estimation caveat is placed second. Every sentence 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?
For a simple getter with two optional parameters and no output schema, the description covers the essential facts: unit, calibration, and the estimation edge case. It leaves exact response shape and usage differentiation implicit, but these are minor at this complexity level.
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 100%, with both mac and name already documented as identifier options. The description adds no parameter-specific semantics beyond the schema, so the baseline of 3 is appropriate.
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?
States a specific verb and resource: 'Return the calibrated current temperature in °C.' The resource is unambiguous and distinct from the setter siblings like set_target_temperature; only get_device_status could overlap, but the temperature-specific scope makes the purpose clear.
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 implied usage is obvious from the name and description: use this when you need the current room temperature. However, there is no explicit guidance on when to prefer this over the similarly read-oriented get_device_status, and no when-not-to-use or alternative routing is provided.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
list_devicesList devicesA
List all configured GREE air conditioners with their connectivity status and last-known state.
| Name | Required | Description | Default |
|---|---|---|---|
No parameters | |||
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
No annotations exist, so the description carries the behavioral transparency burden. 'List' implies read-only, and 'last-known state' adds useful context that data may be cached rather than live. However, it does not disclose other behavioral traits such as authentication requirements, rate limits, or side-effect-free guarantees beyond the name.
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?
A single sentence that starts with the action verb, clearly states the resource, and adds relevant detail. Every word earns its place with no redundancy or filler.
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?
For a zero-parameter list tool, the description provides sufficient context: what is listed and what fields are included. The absence of an output schema is partly mitigated by naming the returned attributes, though an explicit mention that it returns an array of device IDs would have made discovery equally complete. Minor gap, but not significant for this simple 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?
The tool has zero parameters, so the baseline is 4. The description does not need to explain parameter semantics, and none are missing. It correctly focuses on what the tool returns instead.
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 uses a specific verb ('List') with a clear resource ('all configured GREE air conditioners') and states exactly what information is included ('connectivity status and last-known state'). This clearly differentiates it from sibling tools like get_device_status (single device) and set_* mutations.
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 tool's purpose is clear and implies use when an overview of all devices is needed, but it does not explicitly mention when NOT to use it or point to alternatives like get_device_status for individual device details. There are no clear exclusions, so the usage guidance is implied rather than explicit.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_fan_speedSet fan speedB
Set the fan speed. "quiet" and "turbo" engage the dedicated modes. On 3-speed units the intermediate steps are mapped down gracefully.
| Name | Required | Description | Default |
|---|---|---|---|
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. | |
| speed | Yes | Fan speed level |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the behavioral disclosure burden. It does disclose useful behavior: quiet/turbo trigger dedicated modes and intermediate steps are mapped down on 3-speed units. However, it does not describe error behavior, response format, or what happens with the 'auto' value.
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 compact and front-loaded, with the core action in the first sentence and only relevant behavioral caveats afterward. Every sentence earns its place and there is no redundancy with the schema.
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?
For a simple setter this is mostly adequate, but gaps remain: the meaning of 'auto' is unexplained, the relationship to set_quiet_mode and set_turbo_mode is ambiguous, and the lack of an output schema means the agent gets no guidance about responses or errors. It covers the basics but not the full context an agent may need.
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 already documents all parameters with 100% coverage, so the baseline is 3. The description adds meaningful semantic detail for the speed enum, clarifying quiet/turbo behavior and how intermediate steps behave on 3-speed units, which goes beyond the schema's bare 'Fan speed level' description.
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 and resource: 'Set the fan speed.' It also adds relevant context about quiet/turbo and 3-speed behavior. However, it does not explicitly distinguish itself from the sibling tools set_quiet_mode and set_turbo_mode, so sibling differentiation is only implied.
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 when-not-to-use guidance is provided. The phrase 'quiet and turbo engage the dedicated modes' hints at special behavior but does not clarify whether set_quiet_mode/set_turbo_mode should be used instead, leaving an ambiguity that the description should resolve.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_lightSet display lightA
Turn the front-panel display light on/off. Only usable if lightControl is enabled in config.
| Name | Required | Description | Default |
|---|---|---|---|
| on | Yes | ||
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the disclosure burden. It clearly states the state-changing effect (on/off) and a config prerequisite. It does not detail failure modes or persistence, but the core behavior is 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?
Two short sentences, with the primary action front-loaded and the prerequisite in the second. Every word earns its place; no redundancy or filler.
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?
For a simple three-parameter toggle tool, the description covers the action and a key prerequisite. The schema already documents the mac/name selectors, so this is adequate; a note on behavior when lightControl is disabled would make it fully complete.
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 67% (mac and name have descriptions, on does not). The description's 'on/off' phrasing indirectly gives meaning to the undocumented `on` boolean, but it adds no direct parameter-level details 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?
States a specific verb and object: 'Turn the front-panel display light on/off.' This clearly distinguishes it from sibling tools like set_power or set_mode, which control different device functions.
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 a clear precondition: 'Only usable if lightControl is enabled in config.' However, it does not explicitly mention alternatives or exclusions (e.g., use another tool when lightControl is disabled), leaving some selection reasoning to inference.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_modeSet modeB
Set the operating mode. Also powers the unit on.
| Name | Required | Description | Default |
|---|---|---|---|
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| mode | Yes | Operating mode | |
| name | No | Device name from config, as a convenience alias for mac. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the burden. It does disclose a non-obvious behavioral side effect—powering the unit on—which adds transparency. However, it omits other potentially important behaviors such as failure conditions, response format, or how this interacts with set_power.
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?
Two short, front-loaded sentences convey the primary purpose and a key side effect with no filler. The description is efficient, though 'operating mode' is slightly redundant with the title.
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?
For a simple setter, the description covers the core action and a notable side effect, and the schema handles parameter details. But with no output schema and no annotations, there is no indication of return values or confirmation, and the overlap with set_power is left ambiguous.
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 100%, so the descriptions for mac, mode, and name already fully document the parameters. The tool description adds no additional meaning about parameter semantics beyond the word 'mode' in the verb phrase.
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 identifies the action ('Set') and the resource ('operating mode'), and it adds a meaningful secondary behavior ('Also powers the unit on'). It is specific enough to distinguish from most siblings, though it does not explicitly separate itself from set_power, which also relates to power state.
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. The note about powering the unit on hints at a use case, but the description never says to use set_power for power-only control or clarifies the relationship between the two tools.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_oscillationSet oscillation (swing)A
Enable or disable louver swing. Applies the per-device configured oscillation positions (no raw swing codes required).
| Name | Required | Description | Default |
|---|---|---|---|
| on | Yes | true = swing on, false = fixed/default | |
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of explaining behavior. It discloses a non-obvious trait: the tool applies per-device configured oscillation positions rather than accepting raw swing codes, which is not visible in the schema. However, it does not mention error conditions, prerequisites, or effects beyond toggling, leaving some behavioral gaps.
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 two concise sentences that front-load the primary action and then provide a valuable behavioral clarification. There is no redundancy or repetition of schema information. Both sentences earn their 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?
For a simple boolean setter with one required parameter and no output schema, the description covers the essential action and the key non-obvious behavior (using configured positions, no raw codes). Minor gaps such as handling of offline devices or response details are acceptable given the tool's simplicity. The definition is complete enough for an agent to call it 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 covers all three parameters with descriptions, so schema_description_coverage is 100%. The description adds useful context about device configuration but does not provide additional per-parameter semantics beyond what the schema already states. Baseline 3 is appropriate here.
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 uses a precise verb and resource pair ('Enable or disable louver swing'), making the action unmistakable. It also stands apart from the sibling set_* tools by targeting a specific feature (oscillation/swing). The added detail about per-device configured positions reinforces what the tool does without ambiguity.
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?
While the description does not explicitly name alternatives or when-not conditions, the sibling list and the clear 'louver swing' scope make the selection context apparent. The phrase 'no raw swing codes required' provides a helpful hint about the intended abstraction level when deciding to invoke this tool. This is clear context, despite lacking explicit exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_powerSet powerC
Turn a device on or off.
| Name | Required | Description | Default |
|---|---|---|---|
| on | Yes | true = on, false = off | |
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations, the description carries the full burden of behavioral disclosure, but it only restates the core power-toggle effect. It does not mention side effects, idempotency, device selection requirements, error behavior, or any additional context an agent would need for a state-changing 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?
The description is a single, front-loaded sentence with no filler or redundant content. Every word contributes to the core meaning, making it optimally concise for a simple tool.
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?
Although the schema documents parameters, the description fails to explain how the tool selects a device, especially since neither mac nor name is required while only 'on' is required. It also does not describe return behavior or any constraints, leaving important operational context missing for a mutation 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 description coverage is 100%, so the schema already documents the meaning and purpose of all parameters. The description adds no additional semantic information beyond the schema, so the baseline score of 3 is appropriate.
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 uses a specific verb and resource ('turn a device on or off') and clearly indicates the domain of power control, which distinguishes it from siblings like set_mode or set_temperature. However, it does not explicitly name any sibling or state the scope beyond the obvious power state change.
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 guidance is given on when to use this tool versus alternatives, nor are there prerequisites or exclusions. The description simply states what it does, leaving the agent to infer usage solely from the tool name and sibling context.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_quiet_modeSet quiet modeA
Enable/disable quiet mode. Turning it on disables turbo mode.
| Name | Required | Description | Default |
|---|---|---|---|
| on | Yes | ||
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations present, the description carries the full behavioral disclosure burden. It does reveal a concrete side effect (disabling turbo mode), but it omits other potentially relevant behaviors such as prerequisites, persistence, or effect on other device states.
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?
Two concise sentences, with the core operation first followed by the key behavioral caveat. No redundant phrasing.
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 definition covers the core operation and the most important interaction (turbo mode), but with no annotations or output schema, it leaves out context like return values, error cases, and prerequisites. It is adequate for a simple boolean setter but not rich enough to fully understand the device-state implications.
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 already documents mac and name, while 'on' lacks a description; the phrase 'turning it on' at least clarifies the true-value semantics for the required parameter. The description adds slightly more meaning than the schema alone but doesn't thoroughly explain the selector 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?
Description states a concrete action ('enable/disable') with a specific resource ('quiet mode'), and the side-effect clause ('Turning it on disables turbo mode') differentiates it from the sibling set_turbo_mode, making the tool's role 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 provides no explicit when-to-use guidance or mention of alternative tools. The clause about turbo mode implies a relationship to set_turbo_mode, but it does not tell the agent when to select this tool over a sibling or what exclusions apply.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_target_temperatureSet target temperatureA
Set the target temperature in °C. Rejected (not silently clamped) if outside the device's configured min/max range.
| Name | Required | Description | Default |
|---|---|---|---|
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. | |
| temperature | Yes | Target temperature in degrees Celsius |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description must carry the behavioral burden. It usefully discloses that out-of-range temperatures are rejected rather than silently clamped, which is a valuable, non-obvious behavior. However, it does not describe response/error shapes, required device state, permissions, or other side effects, leaving meaningful gaps.
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 two short sentences that front-load the core operation and then add a single high-value behavioral warning. There is no redundant or filler 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?
For a simple three-parameter setter, the description covers what the tool does and the most important failure mode, while the schema covers device selector semantics. It could go further by describing the success response or prerequisites, but those are minor gaps given the tool's low 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?
The schema already documents all three parameters at 100% coverage, so the baseline is 3. The description adds value by specifying that the temperature must be within the device's configured min/max range and that invalid values are rejected, which goes beyond the schema's simple 'degrees Celsius' description.
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 a specific verb ('Set') and a specific resource ('target temperature') with explicit units in °C, making the operation unambiguous. It is naturally distinguishable from sibling setters like set_power and set_mode because it names a unique resource and adds the non-clamping behavior.
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 this tool is for changing a device's target temperature, but it does not explicitly state when to use it versus alternatives or contrast it with sibling tools such as get_room_temperature or set_mode. The agent must infer the usage context from the tool name and sibling list.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_turbo_modeSet turbo modeB
Enable/disable turbo (powerful) mode. Turning it on disables quiet mode.
| Name | Required | Description | Default |
|---|---|---|---|
| on | Yes | ||
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
Because no annotations are provided, the description carries the full burden of behavioral disclosure. It does disclose a meaningful side effect ('Turning it on disables quiet mode'), which is valuable, but it remains silent on what happens when turbo is disabled, whether quiet mode is restored, or any failure/permission 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?
Two short sentences, front-loaded with the essential action, and every sentence adds information. There is no filler or 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?
For a simple setter with three parameters and no output schema, the description covers the main action and one key side effect. However, with no annotations and a closely related sibling set_quiet_mode, it should clarify the inverse relationship (what happens when turbo is disabled) and selection guidance to be fully complete.
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 already documents mac and name, covering 67% of parameters. The description's enable/disable wording maps naturally to the required boolean 'on' parameter, but it adds no extra detail about parameter precedence, format constraints, or behavior when both selectors are supplied.
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 ('Enable/disable') and the target resource ('turbo (powerful) mode'). The added note about disabling quiet mode gives useful context, but it does not explicitly differentiate this from the sibling set_quiet_mode or set_mode tools.
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 is given about when to use this tool versus its alternatives. With siblings like set_quiet_mode and set_mode, an agent must infer the intended usage from the name alone, since the description never mentions preferred contexts or exclusions.
Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.
set_xfanSet X-Fan (blow)A
Enable/disable X-Fan (keeps the fan running after shutdown to dry the coil). Only usable if xFan is enabled in config.
| Name | Required | Description | Default |
|---|---|---|---|
| on | Yes | ||
| mac | No | Device MAC (12 hex chars, the canonical identifier). Preferred selector. | |
| name | No | Device name from config, as a convenience alias for mac. |
TDQS
Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?
With no annotations provided, the description carries the full burden of behavioral disclosure. It explains the post-shutdown fan behavior and the config prerequisite, which are meaningful behavioral traits. It does not cover every edge case (e.g., error behavior when config is disabled), but the core effect and condition are 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?
Two short sentences with no wordiness. The action and feature explanation are front-loaded, and the config prerequisite follows naturally. Every sentence contributes useful 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?
For a simple boolean toggle with no output schema, the description explains the purpose, the effect, and the one critical precondition. Device selection is covered by the schema descriptions of mac and name. It is complete enough for an agent to invoke the tool correctly, though it omits potential failure behavior when the config prerequisite is unmet.
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 67%: the mac and name parameters are described in the schema, but the required 'on' parameter has no schema description. The tool description's 'Enable/disable' implicitly maps to the 'on' boolean but does not explicitly say 'true enables, false disables' or discuss any side effects. This adds some meaning over the schema but leaves the most important parameter underspecified.
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 uses a specific verb ('Enable/disable') and a specific resource ('X-Fan'), and immediately defines what X-Fan does ('keeps the fan running after shutdown to dry the coil'). This clearly distinguishes the tool from sibling fan controls like set_fan_speed or set_turbo_mode.
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 a concrete precondition: 'Only usable if xFan is enabled in config.' This tells the agent when the tool is applicable and when it should not be attempted. It does not explicitly name alternatives, but the unique X-Fan feature and the precondition provide clear usage context.
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.
12 tool updates
v0.1.0- First observed
get_device_status - First observed
get_room_temperature - First observed
list_devices - First observed
set_fan_speed - First observed
set_light - First observed
set_mode - First observed
set_oscillation - First observed
set_power - First observed
set_quiet_mode - First observed
set_target_temperature - First observed
set_turbo_mode - First observed
set_xfan
TDQS
Scored across 12 tools
Each tool targets a distinct control or status query: list/get for reading, set for writing, and within set_* each corresponds to a different AC function (power, mode, temperature, fan, oscillation, xfan, light, quiet, turbo). The only potential overlap is that set_mode also powers the unit on, but the description explicitly notes this, making it clear rather than ambiguous.
All tools follow a consistent verb_noun snake_case pattern: list_devices, get_device_status, and set_power etc. The verbs are limited to list/get/set, and the nouns match the domain entities. The only slight exception is set_xfan (rather than set_x_fan), but this is minor and doesn't break the pattern.
Twelve tools is well within the ideal 3–15 range and each tool addresses a distinct aspect of controlling a GREE AC. The set is neither inflated with redundant operations nor so small that it feels thin.
The tool surface covers the full lifecycle of controlling a device: discovering it, reading full status and current temperature, and setting all major operating parameters (power, mode, target temperature, fan speed, oscillation, xfan, light, quiet, turbo). No critical control is missing, and the config-dependent tools are clearly documented.
Maintenance
Related MCP Connectors
Superseded by io.github.f-tiger/hvac-btu-heat-klimaanlage — same server, same URL.
Superseded by io.github.f-tiger/hvac-btu-heat-klimaanlage — same server, same URL.
Control a Loxone Miniserver smart home: lights, blinds, climate, scenes and energy.
Control your Tesla - wake it, warm it up, unlock and more. Get your developer token at https://Infoseek.ai/mcp. Also requires your own Tesla developer token which is tied to your car/fleet.
Related MCP Servers
- AlicenseNot gradedqualityCmaintenanceSmart Device Control 🎮 💡 Lights: Brightness, color, RGB 🌡️ Climate: Temperature, HVAC, humidity 🚪 Covers: Position and tilt 🔌 Switches: On/off 🚨 Sensors: State monitoring Intelligent Organization 🏠 Grouping with context awareness. Robust Architecture 🛠️ Error handling, state validation ...52 npm56Apache 2.0
- AlicenseAqualityDmaintenanceEnables discovery and control of Philips Hue lighting devices via a local bridge using the CLIP v2 API, without any cloud dependency.10MIT
- FlicenseBqualityCmaintenanceControl a Vizio SmartCast TV over your local network via the SmartCast local API, with no cloud required.7-
- AlicenseAqualityBmaintenanceLocal MCP server for controlling Midea air conditioners via LAN or cloud, providing tools for device management and state control.65MIT