Skip to main content
Glama
00011110

trayfeel

by 00011110

TrayFeel

Actuador emotivo de bandeja CD/DVD plug-and-play para agentes de IA.

TrayFeel convierte una unidad óptica Linux en un canal de lenguaje corporal físico: abrir, cerrar, pulsar, mover y un catálogo de emociones con nombre — expuesto como biblioteca Python, CLI, servidor MCP y daemon HTTP opcional.

Primero Linux. Con licencia MIT. Ruta ioctl en Python puro (no requiere binario eject).

Requisitos

  • Python 3.10+

  • Linux con unidad óptica /dev/sr* compatible con OPEN_TRAY / CLOSE_TRAY

  • Pertenencia del usuario al grupo cdrom (típico en Ubuntu/Debian)

sudo usermod -aG cdrom "$USER"
# log out and back in, then:
groups   # should list cdrom

Instalación

pip install trayfeel
# or from a checkout:
pip install -e ".[dev]"

Variables de entorno opcionales (ver .env.example):

Variable

Propósito

TRAYFEEL_DEVICE

Forzar ruta del dispositivo (por defecto: primer /dev/sr*)

TRAYFEEL_TOKEN

Token Bearer para el daemon HTTP

TRAYFEEL_CAMERA

/dev/videoN opcional para retroalimentación visual

TRAYFEEL_HOST / TRAYFEEL_PORT

Enlace del daemon (por defecto 127.0.0.1:8765)

Inicio rápido

trayfeel list-drives
trayfeel doctor
trayfeel status
trayfeel pulse
trayfeel emote laugh
trayfeel emote nod_yes --dry-run
trayfeel catalog

Python:

from trayfeel import Tray

with Tray() as tray:
    print(tray.status())
    tray.run("pulse")
    tray.emote("wave")

Seguridad

TrayFeel rechaza movimientos imprudentes por defecto:

  • flock exclusivo por dispositivo (~/.cache/trayfeel/…)

  • Límite de frecuencia (por defecto 30 acciones/minuto)

  • Intervalo mínimo entre movimientos (por defecto 200 ms)

  • Protección de disco — los patrones bruscos (pulse, wiggle, nod, …) se rechazan mientras haya un disco presente salvo que force=True

  • Enfriamiento tras muchos ciclos de abrir/cerrar

Anula con --force / force=True cuando aceptes el riesgo intencionadamente.

Emociones

Coreografías con nombre en trayfeel/emotions/catalog.yaml:

laugh, giggle, gasp, surprise, shrug, think, ponder, nod_yes, shake_no, applause, sulk, pout, excited, bored, angry, curious, wave, heartbeat, sigh, celebrate, confused, acknowledge, reject, greet, farewell, error, success, idle_breath

trayfeel emote celebrate
trayfeel emote think --dry-run

Primitivas

open, close, toggle, lock, unlock, status, pulse, wiggle, hold_open, nod, double_tap, spin_up, spin_down, sleep, wait

Servidor MCP

trayfeel mcp
# or: python -m trayfeel mcp

Herramientas: tray_status, tray_list_drives, tray_primitive, tray_emote, tray_catalog, tray_doctor.

Claude Desktop

Añade a claude_desktop_config.json:

{
  "mcpServers": {
    "trayfeel": {
      "command": "trayfeel",
      "args": ["mcp"]
    }
  }
}

Cursor

Añade una entrada de servidor MCP que apunte al mismo comando (trayfeel mcp o python -m trayfeel mcp). Asegúrate de que el entorno tenga permisos del grupo cdrom.

Los esquemas de herramientas para llamadas de función de OpenAI / Claude están en examples/openai_tools.json y examples/claude_tools.json. Notas de habilidades del agente: examples/agent_skill.md.

Daemon HTTP

Para agentes LAN que no pueden adjuntar MCP stdio:

export TRAYFEEL_TOKEN="$(openssl rand -hex 16)"
trayfeel daemon --host 0.0.0.0 --port 8765

Método

Ruta

Cuerpo

GET

/health

—

GET

/status

—

GET

/catalog

—

POST

/primitive

{"name":"pulse","open_ms":300}

POST

/emote

{"name":"wave"}

Envía Authorization: Bearer $TRAYFEEL_TOKEN cuando haya un token configurado.

Visión (opcional)

Si TRAYFEEL_CAMERA=/dev/video0 está configurado y ffmpeg está instalado, trayfeel vision captura un fotograma mediante V4L2 y devuelve una heurística de brillo/bordes de mejor esfuerzo. Si falta la cámara o ffmpeg, devuelve ok: false con un motivo — nunca bloquea el proceso.

Estructura de la biblioteca

trayfeel/
  core.py          # Tray, Emoter
  primitives.py    # motion primitives
  safety.py        # flock, rate limits, disc guards
  hardware/linux.py
  emotions/        # catalog.yaml + engine
  mcp_server.py
  daemon.py
  cli.py

Licencia

MIT — Copyright (c) 2026 TrayFeel contributors

Related MCP Connectors