Positivo PCUIRN MCP Server
Click on "Install 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., "@Positivo PCUIRN MCP ServerLiga o ar no 23"
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.
Casa Inteligente — Positivo PCUIRN
Control the Positivo Smart Controle Universal 2 (PCUIRN) outside the official app: REST API, web UI, and MCP tools for Cursor / Claude Desktop.
The device is a Tuya-based IR blaster. This project reverse-engineers the Positivo Casa Inteligente mobile API (not Smart Life) and documents how IR commands reach your TV and air conditioner through the cloud.
Disclaimer: This is an unofficial community project. It is not affiliated with Positivo or Tuya. Use at your own risk.
TL;DR
Setup:
npm install→ copy.env.example→ paste Positivo app email + password → configure MCP in Cursor (once)Use: open Cursor chat and say "liga o ar no 23" or "turn on the TV" — done. No
npm start, no device IDs, no Tuya Cloud.
What works
Feature | Method | Notes |
TV power, volume, channels, navigation | Cloud IR | Works without closing the mobile app |
AC on/off, mode, temperature, fan | Cloud IR | Gree-style button keys ( |
Device discovery | Positivo API / UDP scan |
|
Local LAN control | TuyAPI | Optional; only one client at a time |
Cursor / Claude chat control | MCP server |
|
Related MCP server: Smartest-TV
Requirements
Node.js 18+
A Positivo Casa Inteligente account (same email/password as the mobile app)
PCUIRN paired in the app with IR remotes configured (TV, AC, etc.)
Setup (5 minutes)
What you actually need
| Required? | Used for |
| Yes | Login to Positivo API |
| Yes | Login to Positivo API |
| No | Local LAN only ( |
| No | Local LAN only |
| No | Local LAN only |
| No | Alternative way to get |
Cloud control (TV, AC, API, web UI, MCP) only needs your Positivo app email and password. No Tuya IoT Cloud developer account, no Smart Life, no iot.tuya.com project.
The PCUIRN must already be paired in the Positivo app with your IR remotes (TV, AC, etc.) configured.
Quick start
git clone https://github.com/YOUR_USER/positivo-pcuirn.git
cd positivo-pcuirn
npm install
cp .env.example .envEdit .env — only these two lines are required:
POSITIVO_EMAIL=your@email.com
POSITIVO_PASSWORD=your_app_passwordThen:
npm run build # install + build frontend (first time only)
npm start # API + UI → http://localhost:3000Test from another terminal:
# Health check
curl http://localhost:3000/api/health
# List IR remotes (TV, AC…)
curl http://localhost:3000/api/remotes
# Turn on TV
curl -X POST http://localhost:3000/api/tv/send \
-H "Content-Type: application/json" \
-d '{"command":"power"}'
# AC at 23°C (cool, auto fan)
curl -X POST http://localhost:3000/api/ac/send \
-H "Content-Type: application/json" \
-d '{"action":"set","mode":0,"temp":23,"fan":0}'On first run, login happens automatically and the session is saved to storage/session.json (gitignored). You don't need to run any other setup script.
Optional: device ID / localKey (local LAN only)
Skip this if you only use cloud control (TV, AC, Cursor, web UI).
One command does everything — login, list devices, print .env lines, save cache:
node positivo.jsLook for Smart Controle Universal 2 (productId: lwpag3bu0faaowlj). Copy the printed lines into .env only if you need local control (probe.js).
If IP is missing, run node discover.js to find it on your Wi-Fi.
You do not need Tuya IoT Cloud (iot.tuya.com) for normal use — see SETUP-TUYA.md only as a last resort.
Cursor MCP (one-time)
Cursor Settings → MCP → add server (see
mcp/cursor-mcp.example.json)Set the absolute path to
mcp/server.jsRestart Cursor
The MCP server uses the same .env (email + password). npm start does not need to be running for Cursor control.
Development (split API + UI)
# Terminal 1
npm run dev
# Terminal 2
npm run frontend:dev # http://localhost:5173 (proxies to API)How to use
After setup, pick how you want to control things. No device IDs, no curl, no Tuya Cloud required for the options below.
1. Cursor / Claude — just ask (recommended)
With MCP configured, talk to the AI in normal language. It calls the tools and sends IR commands over the cloud.
You don't need npm start running. Only .env with email + password.
Examples (Portuguese or English — both work):
You say | What happens |
"Liga o ar no 23" | AC on, cool mode, 23°C |
"Desliga o ar" | AC off |
"Coloca o ar em 16 graus" | Sets temperature to 16°C |
"Liga a TV" | TV power |
"Aumenta o volume da TV" | Volume up |
"Turn on the AC at 23 degrees" | Same as above |
"Mute the TV" | TV mute |
The agent picks the right MCP tool (ac_set_temperature, tv_power, etc.) automatically. You never type tool names yourself.
If something fails, check that MCP is enabled in Cursor and .env has the correct Positivo credentials.
2. Web UI
npm startOpen http://localhost:3000 — buttons for TV and AC (mode, temperature, fan).
3. API / curl / scripts
With npm start running:
curl -X POST http://localhost:3000/api/ac/send \
-H "Content-Type: application/json" \
-d '{"action":"set","mode":0,"temp":23,"fan":0}'Or without the server:
node test-control.js send TV power
node test-control.js send "Ar condicionado" "power off"How it was built (reverse engineering)
1. The hardware
Item | Value |
Product | Positivo Smart Controle Universal 2 |
Internal name | PCUIRN |
Tuya |
|
Role | IR gateway — exposes virtual remotes (TV, AC) as Tuya sub-devices |
The gateway stores learned IR codes. Virtual remotes appear as separate devices under your account.
2. Positivo uses Tuya, but not Smart Life
The official app talks to Tuya's mobile API at https://a1.tuyaus.com/api.json (US region). Authentication uses the same account as the Positivo app — not a Tuya IoT Cloud developer project.
App credentials (clientId, signing secret, virtual deviceId) were extracted from the Positivo Casa Inteligente APK. They live in positivo.js and are app-level constants, not user secrets. Your personal credentials go only in .env.
3. Request signing
Every API call is signed with HMAC-SHA256. The implementation in positivo.js follows the Tuya mobile SDK:
Sort selected query parameters
Hash
postDatawith a custom MD5 shuffle (mobileHash)Build
key=value||key=valuestringSign with the app secret
Password login uses RSA encryption of the MD5-hashed password (encPassword), matching Tuya's mobile flow.
4. Session management
After login, a sid (session id) is cached in storage/session.json (gitignored). The client revalidates the session and re-logins when it expires.
5. Listing devices
tuya.m.location.list
→ tuya.m.my.group.device.list (per home/group)
→ tuya.m.device.get (per device → deviceId, localKey, ip, productId)node positivo.js prints everything you need for .env and writes devices.json locally (also gitignored).
6. IR remotes and buttons
IR remotes are sub-devices of the gateway:
tuya.m.device.sub.list # list remotes (TV, AC, …)
tuya.m.infrared.record.get # remote metadata
tuya.m.infrared.keydata.get # button list + compressed IR payloads
tuya.m.device.dp.publish # send IR (DPS payload)Important constants discovered:
Constant | Value | Meaning |
|
| Vendor code for Positivo IR payloads |
Gateway |
| Used to auto-detect the PCUIRN |
Each button maps to a DPS object. Learned buttons use study_key; preloaded Gree AC codes use send_ir with a compressed pulse and extension field 99999.
7. Gree air conditioner key format
The AC remote uses Tuya's standard Gree encoding. Button names follow:
M{mode}_T{temp}_S{fan} # cool/heat/auto/dry
M2_S{fan} # fan-only mode (no temperature)Mode | Value |
Cool |
|
Heat |
|
Fan |
|
Auto |
|
Dry |
|
Examples: M0_T23_S0 = cool 23°C auto fan, power on / power off for toggle.
This mapping is in lib/commands.js.
8. Cloud vs local control
Cloud (recommended): tuya.m.device.dp.publish via the Positivo API. The gateway receives the command over the internet. No need to close the mobile app.
Local (optional): Direct TCP to the device with TuyAPI using DEVICE_ID, DEVICE_LOCAL_KEY, and DEVICE_IP. Only one connection at a time — close the app first. Test with node probe.js.
LAN discovery: node discover.js broadcasts on Tuya UDP ports 6666/6667 to find devices on your Wi-Fi.
9. Alternative: Tuya IoT Cloud (optional, rarely needed)
Only for local LAN control when node positivo.js does not return a localKey. Cloud IR does not use this. See SETUP-TUYA.md.
REST API
Base URL: http://localhost:3000
Method | Endpoint | Description |
GET |
| Health check |
GET |
| List account devices |
GET |
| TV/AC command catalog |
GET |
| IR remotes on the gateway |
GET |
| Buttons for a remote |
POST |
| Send TV command ( |
POST |
| Send AC action |
POST |
| Raw IR ( |
GET |
| Local DPS via TuyAPI |
Examples
# List remotes
curl http://localhost:3000/api/remotes
# TV power
curl -X POST http://localhost:3000/api/tv/send \
-H "Content-Type: application/json" \
-d '{"command":"power"}'
# AC: cool mode, 23°C, auto fan
curl -X POST http://localhost:3000/api/ac/send \
-H "Content-Type: application/json" \
-d '{"action":"set","mode":0,"temp":23,"fan":0}'
# AC off
curl -X POST http://localhost:3000/api/ac/send \
-H "Content-Type: application/json" \
-d '{"action":"off"}'Web UI
See How to use → Web UI.
MCP server (reference)
Tools exposed to Cursor / Claude Desktop. For day-to-day use, just ask in chat — see How to use → Cursor.
Tools
Tool | Action |
| TV power toggle |
| Volume |
| Mute |
| Channels |
| Navigation |
| Any catalog command by id |
| AC power |
| Mode + temp + fan (numeric) |
| Set temp (cool mode) |
| Set mode by name |
| Show available commands |
Cursor config
{
"mcpServers": {
"casa-inteligente": {
"command": "node",
"args": ["/absolute/path/to/positivo-pcuirn/mcp/server.js"]
}
}
}Claude Desktop
Same config in ~/Library/Application Support/Claude/claude_desktop_config.json (macOS).
CLI scripts
Script | Purpose |
| Login + list devices, write |
| Force fresh login |
| UDP scan for Tuya devices on LAN |
| Test local TuyAPI connection |
| List devices via Tuya IoT Cloud |
| List devices (service layer) |
| Send IR via cloud |
| Run MCP server (stdio) |
Project structure
lib/
positivo-client.js # Tuya mobile API + IR layer
commands.js # TV/AC command catalog (Gree keys)
service.js # Shared service for API + MCP
local-device.js # TuyAPI local connection
positivo.js # Login, signing, session cache
src/server.js # Express API + static UI
mcp/server.js # MCP stdio server
frontend/ # React UI
storage/session.json # Cached login session (gitignored)
devices.json # Device cache from positivo.js (gitignored)Security & secrets
Never commit:
File | Contains |
| Your email, password, device keys |
| Active API session |
| Device IDs, local keys, IPs |
| Local IDE paths |
Copy .env.example → .env and use devices.example.json as a reference for the cache format.
If localKey values were ever committed or shared, rotate them by removing and re-adding the device in the Positivo app, then re-run node positivo.js.
The CLIENT_ID / SECRET_KEY in positivo.js are embedded in the public APK — they identify the app, not your account.
License
MIT — see LICENSE.
This server cannot be installed
Maintenance
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.
Latest Blog Posts
MCP directory API
We provide all the information about MCP servers via our MCP API.
curl -X GET 'https://glama.ai/api/mcp/v1/servers/gabriellhuver/unofficial-positivo-pcuirn'
If you have feedback or need assistance with the MCP directory API, please join our Discord server