Skip to main content
Glama

VisionCore AI — Centro de Vigilancia Autónomo 🛡️👁️

Sistema de videovigilancia con comprensión semántica de escena. N nodos de captura transmiten fotogramas a un núcleo FastAPI; un modelo de visión local interpreta lo que ve; un motor de reglas decide si eso merece una alarma; y un servidor MCP le da a un agente de IA las herramientas de un operador de sala.

Todo corre en local. Ninguna imagen sale de la máquina.


🎯 Qué lo diferencia

Un VMS clásico (Milestone, Genetec, Avigilon) detecta objetos: "persona en polígono 3", "movimiento en zona 2". Configuras zonas y ajustas umbrales de píxeles.

VisionCore entiende situaciones, y las reglas se escriben en lenguaje natural:

Capacidad

VMS clásico

VisionCore

"Alguien deja un bulto y se aleja"

No es una clase de objeto

Una pregunta en la regla

Persona a las 10:00 vs a las 03:00

Misma detección, misma alarma

Ventana horaria por regla

"¿Por qué sonó esa alarma?"

Umbral superado

Motivo en lenguaje natural

Consultar el estado

Interfaz propietaria

El agente pregunta y responde

Las reglas ejemplo que vienen de fábrica: fuego o humo, presencia en horario restringido, objeto abandonado, persona en el suelo, aglomeración inusual.


Related MCP server: MCP-SOC Middleware

🏗️ Arquitectura

Dos procesos que comparten estado por SQLite (WAL, lectura concurrente):

  [ capture_node ] --HTTP--> [ server/main.py ]  <--\
  [ capture_node ] --HTTP-->    FastAPI             |
   hilo por camara              + monitor           |  storage/visioncore.db
   recarga en caliente          + alarmas           |
                                + voz               |
                                                    |
                              [ mcp_server.py ] <---/
                                stdio -> agente IA
  • client/capture_node.py — Un proceso, N cámaras, un hilo cada una. Webcam por índice o cámara IP por RTSP. Recarga en caliente: editas cameras.json y añade, quita o reconfigura sin reiniciar.

  • server/main.py — Ingesta HTTP con escritura atómica, API de operador y arranque del monitor.

  • server/monitor.py — Barrido autónomo con cadencia adaptativa y puerta de movimiento.

  • server/rules.py — Motor de reglas semánticas con ventana horaria.

  • server/alarms.py — Ciclo de vida de alarmas, antirruido y escalado.

  • server/voice.py — Anuncios TTS locales con cola de prioridad.

  • mcp_server.py — Herramientas MCP para el agente.

Ciclo de vida de una alarma

NUEVA ──(nadie la atiende en escalate_after_s)──> ESCALADA
  │                                                  │
  └──────────(operador la reconoce)─────────────────┘
                      │
                      ▼
                 RECONOCIDA ──(operador cierra)──> RESUELTA

Todo queda en audit_log: quién reconoció qué y cuándo.


⚡ Las tres optimizaciones que lo hacen viable

Un modelo de visión local tarda segundos por imagen. Sin esto, seis cámaras serían imposibles.

1. Puerta de movimiento. Compara una miniatura 32×32 en gris con la última escena analizada. Si la diferencia media queda bajo el umbral, no se llama al modelo. Un pasillo vacío de madrugada cuesta cero.

2. Cadencia adaptativa. Tres ritmos: alarma → 10s, movimiento sin alarma → 30s, escena quieta → hasta 300s. El cómputo se gasta donde pasa algo.

3. Cola de análisis asíncrona. Las herramientas MCP nunca bloquean: devuelven el último análisis si es reciente, o encolan y responden al instante. El trabajo lento lo hace el monitor.


⚙️ Puesta en marcha

python -m venv venv
venv\Scripts\Activate.ps1
pip install -r requirements.txt

copy .env.example .env
copy client\cameras.example.json client\cameras.json

Edita .env con tu LM_STUDIO_TOKEN y VISION_MODEL. Ambos archivos están en .gitignore: el .env por el token, cameras.json porque las URLs RTSP llevan usuario y clave.

El modelo de visión

Esto decide si el sistema es usable. Medido en una GTX 1660 Ti (6 GB):

Modelo

Latencia por análisis

Gemma 4 12B QAT (7.15 GB, mitad en CPU)

~137 s

Qwen3-VL-4B (entra completo en GPU)

~6.5 s

Dos ajustes obligatorios en LM Studio antes de arrancar:

  • Custom Fields → Enable Thinking: OFF. Los modelos de razonamiento gastan todo el presupuesto de tokens pensando y devuelven respuesta vacía. LM Studio ignora reasoning_effort por API; hay que apagarlo en la interfaz.

  • Parallel: 2. Cada slot reserva su propia KV cache. Con 4 no caben las capas en GPU.

Arranque

python -m server.main                    # nucleo + monitor + voz
python -m client.capture_node            # todas las camaras habilitadas
python -m client.capture_node --list     # ver que hay definido
python -m client.capture_node --only patio

Documentación interactiva en http://127.0.0.1:8000/docs.

Servidor MCP

{
  "mcpServers": {
    "visioncore": {
      "command": "F:\\vision-core-mcp\\venv\\Scripts\\python.exe",
      "args": ["F:\\vision-core-mcp\\mcp_server.py"],
      "cwd": "F:\\vision-core-mcp"
    }
  }
}

Herramientas: situation_report, active_alarms, analyze_scene, check_analysis, sweep_all_cameras, acknowledge_alarm, resolve_alarm, announce, audit_trail, list_cameras, system_status.


📷 Cámaras

client/cameras.json:

{
  "server_url": "http://localhost:8000",
  "defaults": { "fps": 1, "max_width": 640, "jpeg_quality": 80 },
  "cameras": [
    { "camera_id": "entrada", "location": "entrada_principal",
      "source": 0, "enabled": true },
    { "camera_id": "calle", "location": "acera_norte",
      "source": "rtsp://usuario:clave@192.168.1.50:554/stream1",
      "enabled": false, "fps": 0.5 }
  ]
}

Guardas el archivo y el supervisor aplica los cambios: arranca las nuevas, para las que quitaste o deshabilitaste, y reinicia solo las que cambiaron. Si guardas JSON inválido a medio editar, mantiene la configuración anterior en vez de tumbar las cámaras.


🔔 Reglas

rules.json en la raíz (si no existe se usa el catálogo por defecto):

{
  "rules": [{
    "rule_id": "intrusion_nocturna",
    "name": "Presencia en horario restringido",
    "prompt": "¿Hay alguna persona en la escena? ¿Su comportamiento parece normal o furtivo?",
    "cameras": ["*"],
    "min_level": "VERDE",
    "require_keywords": ["persona", "hombre", "mujer"],
    "exclude_keywords": ["nadie", "vacio"],
    "active_window": "22:00-06:00",
    "priority": 2,
    "cooldown_s": 60,
    "escalate_after_s": 120,
    "actions": ["voice", "log", "webhook"]
  }]
}

El modelo responde con {"respuesta": true|false, "nivel": ..., "descripcion": ..., "motivo": ...}. La regla dispara solo si respuesta es true. Las palabras clave son un filtro adicional, con detección de negación y sin sensibilidad a tildes.


🔌 API

Método

Ruta

Qué hace

GET

/health

Estado y avisos de configuración

GET

/api/situation

Parte de situación completo

POST

/api/register

Alta de cámara

POST

/api/upload/{id}

Ingesta de fotograma

GET

/api/cameras

Cámaras, online/offline, frame disponible

DELETE

/api/cameras/{id}

Baja de cámara

POST

/api/analyze/{id}

Análisis inmediato (bloquea)

GET

/api/alerts

Histórico de análisis

GET

/api/alarms

Alarmas del ciclo de vida

POST

/api/alarms/{id}/ack

Reconocer

POST

/api/alarms/{id}/resolve

Cerrar

GET

/api/rules

Reglas cargadas y cuáles están activas ahora

POST

/api/monitor/tick

Forzar un ciclo

POST

/api/voice/announce

Megafonía manual

GET

/api/audit

Registro de auditoría

/api/alerts son análisis; /api/alarms son alarmas. Se confunden fácil y responden preguntas distintas.


🧪 Tests

pytest

167 tests. Corren sin LM Studio, sin cámara, sin tarjeta de sonido y sin red.


🩹 Bugs corregidos

Los que costaron más tiempo, por si vuelven:

Problema

Efecto

Token de LM Studio escrito en el código

Credencial expuesta

BASE_DIR/server/storage calculado desde dentro de server/

FastAPI escribía en una carpeta y el MCP leía en otra: el análisis nunca veía los fotogramas

Se leía result["output"] de /v1/chat/completions

Campo inexistente ahí; devolvía el JSON crudo como si fuera el informe

from mcp.server.mcpserver import MCPServer

No existe en el SDK; el servidor MCP nunca importó

Herramienta MCP bloqueando 137 s

El cliente cortaba antes; curl funcionaba porque no tiene timeout

Modelo de razonamiento con presupuesto corto

597 de 600 tokens pensando, content vacío, 200 s tirados

require_keywords por subcadena

"No se observa ninguna persona caída" generaba alarma

Palabras clave con tilde

"caid" nunca coincidió con "caída"; la regla llevaba meses sin funcionar

Puerta de movimiento por hash MD5

El ruido del sensor cambia el JPEG siempre: no ahorró nada

Movimiento sin alarma tratado como calma

La cadencia se relajaba justo tras detectar actividad

camera_id sin sanear en la ruta

Un id ../../ escribía fuera de storage/

Escritura directa del JPEG

El MCP podía leer un fotograma a medio escribir

Bucle de registro sin pausa al fallar

100% de CPU hasta que el servidor respondiera

pydantic==2.6.4 fijado

Chocaba con el SDK de MCP; pip abortaba la instalación entera


🚧 Qué falta para producción crítica

Honestamente, esto es una arquitectura sólida y un producto demostrable. No es todavía un sistema certificable para infraestructura crítica:

  • Seguridad. Sin TLS, sin autenticación de nodos, sin roles de operador. Cualquiera en la red puede subir fotogramas y cerrar alarmas.

  • Redundancia. Un proceso, un SQLite, una GPU. Sin failover.

  • Cadena de custodia. La evidencia no está firmada ni sellada en tiempo.

  • Latencia. ~6.5 s por análisis sirve para vigilancia por eventos, no para detección de intrusión en tiempo real.

El siguiente salto arquitectónico es la detección en dos etapas: un detector rápido (YOLO, ~20 ms) mira todos los fotogramas y el VLM solo interpreta lo que el detector marca. El detector dice "hay una persona"; el VLM dice "está forzando la puerta".


📄 Licencia

Internal Proprietary — Vertex Coders LLC. All Rights Reserved.

F
license - not found
Not graded
quality - not tested
C
maintenance

Maintenance

Maintainers
Response time
Release cycle
Releases (12mo)
Commit activity

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    A
    quality
    A
    maintenance
    Enables AI agents to interact seamlessly with Splunk environments through 20+ tools for search, analytics, data discovery, administration, and health monitoring. Features AI-powered troubleshooting workflows and supports multiple Splunk instances with production-ready security.
    56
    27
    Apache 2.0
  • A
    license
    Not graded
    quality
    C
    maintenance
    Enables AI agents to interact with Splunk SIEM and TheHive SOAR through a unified MCP interface, providing 12 tools for alert triage, case management, and security operations.
    MIT
  • F
    license
    A
    quality
    C
    maintenance
    Enables AI assistants to perform defensive security tasks such as vulnerability detection, CVE lookup, phishing/link safety checks, and security report generation via MCP tools.
    23

View all related MCP servers

Related MCP Connectors

  • Runtime permission, approval, and audit layer for AI agent tool execution.

  • Pay-per-call cybersecurity for AI agents: vuln scans, threat intel, compliance, code security.

  • Security firewall for AI agents — scans MCP calls for injection, secrets, and risks.

View all MCP Connectors

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/Denisijcu/vision-core-mcp'

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