Skip to main content
Glama
00011110

trayfeel

by 00011110

TrayFeel

AI 에이전트용 플러그 앤 플레이 CD/DVD 트레이 감정 표현 액추에이터.

TrayFeel은 Linux 광학 드라이브를 물리적 바디랭귀지 채널로 바꿔줍니다: 열기, 닫기, 펄스, 흔들기, 그리고 명명된 감정 카탈로그 — Python 라이브러리, CLI, MCP 서버, 선택적 HTTP 데몬으로 제공됩니다.

Linux 우선. MIT 라이선스. 순수 Python ioctl 경로(eject 바이너리 불필요).

요구 사항

  • Python 3.10+

  • OPEN_TRAY / CLOSE_TRAY를 지원하는 /dev/sr* 광학 드라이브가 있는 Linux

  • cdrom 그룹의 사용자 멤버십(Ubuntu/Debian에서 일반적)

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

설치

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

선택적 환경 변수(.env.example 참조):

변수

용도

TRAYFEEL_DEVICE

장치 경로 강제 지정(기본값: 첫 번째 /dev/sr*)

TRAYFEEL_TOKEN

HTTP 데몬용 Bearer 토큰

TRAYFEEL_CAMERA

비전 피드백용 선택적 /dev/videoN

TRAYFEEL_HOST / TRAYFEEL_PORT

데몬 바인드(기본값 127.0.0.1:8765)

빠른 시작

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")

안전

TrayFeel은 기본적으로 무모한 동작을 거부합니다:

  • 장치별 독점 flock(~/.cache/trayfeel/…)

  • 속도 제한(기본값 분당 30회 동작)

  • 동작 간 최소 간격(기본값 200ms)

  • 디스크 보호 — 디스크가 있는 동안 force=True 없이는 슬램 패턴(pulse, wiggle, nod, …) 거부

  • 쿨다운 — 많은 열기/닫기 주기 이후

의도적으로 위험을 감수할 때는 --force / force=True로 재정의하세요.

감정

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

기본 동작

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

MCP 서버

trayfeel mcp
# or: python -m trayfeel mcp

도구: tray_status, tray_list_drives, tray_primitive, tray_emote, tray_catalog, tray_doctor.

Claude Desktop

claude_desktop_config.json에 추가:

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

Cursor

동일한 명령(trayfeel mcp 또는 python -m trayfeel mcp)을 가리키는 MCP 서버 항목을 추가하세요. 환경에 cdrom 그룹 권한이 있는지 확인하세요.

OpenAI / Claude 함수 호출용 도구 스키마는 examples/openai_tools.json 및 examples/claude_tools.json에 있습니다. 에이전트 스킬 노트: examples/agent_skill.md.

HTTP 데몬

stdio MCP를 연결할 수 없는 LAN 에이전트용:

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

메서드

경로

본문

GET

/health

—

GET

/status

—

GET

/catalog

—

POST

/primitive

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

POST

/emote

{"name":"wave"}

토큰이 설정된 경우 Authorization: Bearer $TRAYFEEL_TOKEN을 보내세요.

비전(선택 사항)

TRAYFEEL_CAMERA=/dev/video0이 설정되고 ffmpeg가 설치된 경우, trayfeel vision은 V4L2를 통해 프레임을 캡처하고 최선 노력(best-effort) 밝기/엣지 휴리스틱을 반환합니다. 카메라나 ffmpeg가 없으면 이유와 함께 ok: false를 반환합니다 — 프로세스가 중단되지 않습니다.

라이브러리 구조

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

라이선스

MIT — Copyright (c) 2026 TrayFeel contributors

Related MCP Connectors