Skip to main content
Glama

Vivint Security System MCP Server

by bradmb

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)

  1. Clone and enter the project
cd /Users/brad/GitHub # Or your workspace directory # git clone <your-remote> mcp-server-template cd mcp-server-template
  1. Create an environment and install dependencies

Option A: venv

python -m venv .venv source .venv/bin/activate pip install -r requirements.txt

Option B: conda

conda create -n mcp-server python=3.13 -y conda activate mcp-server pip install -r requirements.txt
  1. Configure environment
cp .env.example .env # Edit .env and set at minimum: # VIVINT_USERNAME=your_email@example.com # VIVINT_PASSWORD=your_password
  1. Enable 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=HS256

Generate a short‑lived JWT for local testing:

python src/generate_token.py --type token --hours 24 --subject local-dev
  1. Start the server
python src/server.py # Endpoint: http://localhost:8000/mcp
  1. Test with MCP Inspector
npx @modelcontextprotocol/inspector

Then connect with:

  • Transport: Streamable HTTP
  • URL: http://localhost:8000/mcp
  • If AUTH_ENABLED=true: add the header Authorization: Bearer

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=1

Notes:

  • 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=false

Warning: Do not disable authentication if your server is reachable from the internet.

2FA/MFA setup and token persistence

Interactive (recommended)

python setup_mfa.py

What 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.py

Validation

python test_mfa.py

Token file security: treat .vivint_tokens.json as a secret and restrict permissions (chmod 600).

Running and debugging

Start:

python src/server.py

Explicit host/port:

HOST=********* PORT=8000 python src/server.py

Verbose logs:

DEBUG_MODE=true LOG_LEVEL=DEBUG python src/server.py

Debug 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 up

OAuth redirect URIs can be updated automatically:

python update_oauth_uris.py --auto-tunnel

Manual alternative:

cloudflared tunnel --url http://localhost:8000 # Your MCP endpoint is: https://<random>.trycloudflare.com/mcp

Deploying 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.

-
security - not tested
F
license - not found
-
quality - not tested

hybrid server

The server is able to function both locally and remotely, depending on the configuration or use case.

Provides read-only access to Vivint home security systems through an unofficial API. Enables monitoring of system status, devices, sensors, cameras, locks, thermostats, and recent events through natural language.

  1. Features
    1. Prerequisites
      1. Quick start (local)
        1. Example .env
          1. Authentication options
            1. 2FA/MFA setup and token persistence
              1. Running and debugging
                1. Testing with MCP Inspector
                  1. Cloudflare tunnel (optional)
                    1. Deploying to Render
                      1. Tool reference
                        1. Architecture
                          1. Troubleshooting
                            1. Security
                              1. Limitations & disclaimers
                                1. License

                                  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/bradmb/vivint-mcp'

                                  If you have feedback or need assistance with the MCP directory API, please join our Discord server