Provides read-only access to Vivint home security systems, enabling monitoring of system armed states, security sensors, cameras, smart locks, thermostats, recent events, and device health status through eight comprehensive tools.
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., "@Vivint Security System MCP Serverare any doors or windows open right now?"
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.
Vivint Security System MCP Server
A FastMCP server that exposes read-only access to your Vivint home security system over the Model Context Protocol (MCP) via Streamable HTTP at the /mcp endpoint.
Important: This integration uses an unofficial, reverse‑engineered API (vivintpy). Vivint has no official public API. Use at your own risk and review your Terms of Service.
Features
Eight read-only tools are exposed to MCP clients:
get_system_status — Overall system armed state and metadata
get_all_devices — Complete device inventory
get_security_sensors — Motion/door/window/smoke/CO/flood sensors
get_cameras — Camera status and capabilities
get_locks — Smart lock states and battery level
get_thermostats — Climate data and setpoints
get_recent_events — Recent activity snapshots
get_device_health — Battery/online/attention summaries
Endpoint base path: /mcp (clients must include this path).
Prerequisites
Python 3.13+
A Vivint account (recommend a dedicated, least‑privilege user)
Node.js (for MCP Inspector via npx)
Optional: Cloudflared (to expose your local server)
macOS, Linux, or Windows. Commands below use macOS/zsh patterns.
Quick start (local)
Clone and enter the project
cd /Users/brad/GitHub
# Or your workspace directory
# git clone <your-remote> mcp-server-template
cd mcp-server-templateCreate an environment and install dependencies
Option A: venv
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtOption B: conda
conda create -n mcp-server python=3.13 -y
conda activate mcp-server
pip install -r requirements.txtConfigure environment
cp .env.example .env
# Edit .env and set at minimum:
# VIVINT_USERNAME=your_email@example.com
# VIVINT_PASSWORD=your_passwordEnable authentication (recommended)
Generate a strong HMAC secret and add it to .env:
python src/generate_token.py --type secret
# Copy the printed AUTH_SECRET=... into your .env
# Ensure AUTH_ENABLED=true, AUTH_TYPE=jwt, JWT_ALGORITHM=HS256Generate a short‑lived JWT for local testing:
python src/generate_token.py --type token --hours 24 --subject local-devStart the server
python src/server.py
# Endpoint: http://localhost:8000/mcpTest with MCP Inspector
npx @modelcontextprotocol/inspectorThen connect with:
Transport: Streamable HTTP
URL: http://localhost:8000/mcp
If AUTH_ENABLED=true: add the header Authorization: Bearer <your_jwt>
Example .env
Copy/paste and edit values as needed. Do not commit this file.
# Environment
ENVIRONMENT=development
PORT=8000
# HOST optional; defaults internally (container vs. strict local)
# HOST=*******
# Logging / debug
DEBUG_MODE=false
LOG_LEVEL=INFO
# Vivint credentials (required)
VIVINT_USERNAME=your_email@example.com
VIVINT_PASSWORD=your_password
# If you have multiple systems, set a specific one
# VIVINT_SYSTEM_ID=
# Session management (seconds)
SESSION_REFRESH_INTERVAL=900
TOKEN_REFRESH_INTERVAL=18000
# Authentication (recommended in all environments)
AUTH_ENABLED=true
AUTH_TYPE=jwt
JWT_ALGORITHM=HS256
AUTH_SECRET=replace-with-strong-secret
JWT_ISSUER=vivint-mcp-server
JWT_AUDIENCE=vivint-mcp-client
TOKEN_EXPIRY_HOURS=24
# 2FA/MFA
# VIVINT_MFA_CODE=123456
VIVINT_REFRESH_TOKEN_FILE=.vivint_tokens.json
VIVINT_MFA_AUTO_WAIT=false
# OAuth (optional)
# OAUTH_CLIENT_ID=
# OAUTH_CLIENT_SECRET=
OAUTH_REDIRECT_URIS=https://claude.ai/api/mcp/auth_callback,http://localhost:3000/callback,http://localhost:8080/callback
OAUTH_DISABLE_NEW_CLIENTS=false
# CLOUDFLARE_TUNNEL_URL=https://your-tunnel.trycloudflare.com
# Rate limiting for login endpoints
RATE_LIMIT_ENABLED=true
RATE_LIMIT_LOCKOUT_MINUTES=5
RATE_LIMIT_MAX_ATTEMPTS=1Notes:
The server binds to HOST and PORT (defaults provided). For containers, bind‑all is recommended; for strict local, use a loopback address. The default HOST in code is redacted (*******).
All URLs must include the /mcp base path.
Authentication options
JWT (HMAC, HS256) — recommended for single‑user/local
Generate secret: python src/generate_token.py --type secret
Configure .env: AUTH_ENABLED=true, AUTH_TYPE=jwt, JWT_ALGORITHM=HS256, AUTH_SECRET=...
Create token: python src/generate_token.py --type token --hours 24 --subject local-dev
Verify token: python src/generate_token.py --verify ""
Use with Inspector: Authorization: Bearer
JWT (RSA, RS256) — multi‑client
Generate keys: python src/generate_token.py --type keypair
Configure .env: JWT_PRIVATE_KEY, JWT_PUBLIC_KEY, JWT_ALGORITHM=RS256
Generate tokens with the private key (same script) and verify with the public key.
OAuth 2.0 — optional
Generate a client: python src/generate_oauth_credentials.py
Ensure OAUTH_REDIRECT_URIS includes https://claude.ai/api/mcp/auth_callback (for Claude) and any local callbacks.
Start the server and complete the flow using the server’s OAuth endpoints. In production, consider setting OAUTH_DISABLE_NEW_CLIENTS=true.
Disable auth (development only)
# In .env
AUTH_ENABLED=falseWarning: Do not disable authentication if your server is reachable from the internet.
2FA/MFA setup and token persistence
Interactive (recommended)
python setup_mfa.pyWhat it does:
Prompts for a fresh 6‑digit code when required
Saves refresh tokens to VIVINT_REFRESH_TOKEN_FILE (default: .vivint_tokens.json)
Validates the connection
Non‑interactive (one‑off)
export VIVINT_MFA_CODE=123456
python src/server.pyValidation
python test_mfa.pyToken file security: treat .vivint_tokens.json as a secret and restrict permissions (chmod 600).
Running and debugging
Start:
python src/server.pyExplicit host/port:
HOST=********* PORT=8000 python src/server.pyVerbose logs:
DEBUG_MODE=true LOG_LEVEL=DEBUG python src/server.pyDebug endpoint (when available): /debug/oauth requires DEBUG_MODE=true.
Testing with MCP Inspector
Launch: npx @modelcontextprotocol/inspector
Transport: Streamable HTTP
URL: http://localhost:8000/mcp
If auth enabled: add Authorization: Bearer
Try tools: get_system_status, get_all_devices, get_device_health
Cloudflare tunnel (optional)
If you want to test over the internet without opening ports:
Helper scripts in repo:
./start_tunnel.sh # Starts a Quick Tunnel, prints public URL and saves it to .mcp_public_url
./tunnel_status.sh # Shows status and tests the endpoint
./stop_tunnel.sh # Stops the tunnel and cleans upOAuth redirect URIs can be updated automatically:
python update_oauth_uris.py --auto-tunnelManual alternative:
cloudflared tunnel --url http://localhost:8000
# Your MCP endpoint is: https://<random>.trycloudflare.com/mcpDeploying to Render
Use the button above or set up a Web Service that runs:
Build: pip install -r requirements.txt
Start: python src/server.py
Environment variables (minimum):
ENVIRONMENT=production
AUTH_ENABLED=true
AUTH_TYPE=jwt (or oauth)
For JWT HS: AUTH_SECRET=, JWT_ALGORITHM=HS256
For JWT RS: JWT_PRIVATE_KEY, JWT_PUBLIC_KEY, JWT_ALGORITHM=RS256
VIVINT_USERNAME, VIVINT_PASSWORD
Optional: VIVINT_SYSTEM_ID, LOG_LEVEL=WARNING/ERROR
Your endpoint will be: https://.onrender.com/mcp
Tool reference
get_system_status() → { armed, arm_state, is_disarmed, is_armed_stay, is_armed_away, system_id, panel_id, panel_name, timestamp, ... }
get_all_devices() → [ { id, name, type, panel_id, system_id, state, is_online, battery_level, last_update_time, ... } ]
get_security_sensors() → [ { id, name, sensor_type, triggered, bypassed, zone_id, ... } ]
get_cameras() → [ { id, name, resolution, night_vision, motion_detection, rtsp_available, ... } ]
get_locks() → [ { id, name, locked, tamper_status, battery_level, last_operated_at, ... } ]
get_thermostats() → [ { id, name, current_temperature, target_temperature, heat_setpoint, cool_setpoint, mode, ... } ]
get_recent_events(hours=24) → [ { id, type, description, timestamp, device_id, device_name } ]
get_device_health() → { total_devices, online_devices, offline_devices, low_battery_devices, devices_needing_attention, ... }
Return fields are best‑effort and depend on your account/devices; errors are returned as { error, timestamp }.
Architecture
Core files
src/server.py — FastMCP app, auth setup (JWT/OAuth), tool registration, HTTP transport on /mcp
src/vivint_client.py — vivintpy wrapper, session lifecycle, MFA handling
src/token_manager.py — secure token persistence and validation
src/config.py — environment variable parsing and validation
setup_mfa.py, test_mfa.py — interactive MFA onboarding and validation
start_tunnel.sh, tunnel_status.sh, stop_tunnel.sh — Cloudflared helpers
render.yaml — Render deployment config
Session notes
Sessions are refreshed periodically; tokens auto‑refresh ~5–6 hours
Device and state shapes come from vivintpy and can change upstream
Troubleshooting
Authentication
“AUTH_SECRET is required” → Add AUTH_SECRET for HS* or JWT_PUBLIC_KEY for RS*
“MFA required” → export VIVINT_MFA_CODE or run setup_mfa.py
OAuth redirect mismatch → Ensure the exact URL is in OAUTH_REDIRECT_URIS, restart server
Connectivity
Inspector can’t connect → Server running? Port correct? URL includes /mcp?
Render 502 → Ensure HOST/PORT are correct for container; ENVIRONMENT=production
Devices
No devices → Confirm account/system access; set VIVINT_SYSTEM_ID when multiple systems exist
Rate limits
Login locked → Adjust RATE_LIMIT_* or wait for lockout to expire
Debugging
DEBUG_MODE=true LOG_LEVEL=DEBUG for verbose logs
/debug/oauth (if enabled) inspects OAuth configuration
Security
Keep AUTH_ENABLED=true in production
Rotate AUTH_SECRET/keys regularly
Use a dedicated Vivint user
Do not commit .env or token files; treat .vivint_tokens.json as a secret (chmod 600)
Keep DEBUG_MODE=false in production
Be mindful that vivintpy is unofficial and may break without notice
Limitations & disclaimers
Unofficial API usage via vivintpy (no guarantees; subject to breakage)
Read‑only access only; no device control
May violate provider terms — proceed responsibly
License
MIT — see LICENSE.
This project is not affiliated with or endorsed by Vivint.
This server cannot be installed
Resources
Unclaimed servers have limited discoverability.
Looking for Admin?
If you are the server author, to access and configure the admin panel.