trayfeel
Click on "Deploy 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., "@trayfeelMake the tray do a happy dance motion"
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.
TrayFeel
Plug-and-play CD/DVD tray emotive actuator for AI agents.
TrayFeel turns a Linux optical drive into a physical body-language channel: open, close, pulse, wiggle, and a catalog of named emotions — exposed as a Python library, CLI, MCP server, and optional HTTP daemon.
Linux-first. MIT licensed. Pure-Python ioctl path (no eject binary required).
Requirements
Python 3.10+
Linux with
/dev/sr*optical drive supportingOPEN_TRAY/CLOSE_TRAYUser membership in the
cdromgroup (typical on Ubuntu/Debian)
sudo usermod -aG cdrom "$USER"
# log out and back in, then:
groups # should list cdromInstall
pip install trayfeel
# or from a checkout:
pip install -e ".[dev]"Optional env (see .env.example):
Variable | Purpose |
| Force device path (default: first |
| Bearer token for HTTP daemon |
| Optional |
| Daemon bind (default |
Quick start
trayfeel list-drives
trayfeel doctor
trayfeel status
trayfeel pulse
trayfeel emote laugh
trayfeel emote nod_yes --dry-run
trayfeel catalogPython:
from trayfeel import Tray
with Tray() as tray:
print(tray.status())
tray.run("pulse")
tray.emote("wave")Safety
TrayFeel refuses reckless motion by default:
Exclusive flock per device (
~/.cache/trayfeel/…)Rate limit (default 30 actions/minute)
Minimum interval between motions (default 200 ms)
Disc guard — slam patterns (
pulse,wiggle,nod, …) refused while a disc is present unlessforce=TrueCooldown after many open/close cycles
Override with --force / force=True when you intentionally accept the risk.
Emotions
Named choreographies in 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-runPrimitives
open, close, toggle, lock, unlock, status, pulse, wiggle, hold_open, nod, double_tap, spin_up, spin_down, sleep, wait
MCP server
trayfeel mcp
# or: python -m trayfeel mcpTools: tray_status, tray_list_drives, tray_primitive, tray_emote, tray_catalog, tray_doctor.
Claude Desktop
Add to claude_desktop_config.json:
{
"mcpServers": {
"trayfeel": {
"command": "trayfeel",
"args": ["mcp"]
}
}
}Cursor
Add an MCP server entry pointing at the same command (trayfeel mcp or python -m trayfeel mcp). Ensure the environment has cdrom group permissions.
Tool schemas for OpenAI / Claude function calling live in examples/openai_tools.json and examples/claude_tools.json. Agent skill notes: examples/agent_skill.md.
HTTP daemon
For LAN agents that cannot attach stdio MCP:
export TRAYFEEL_TOKEN="$(openssl rand -hex 16)"
trayfeel daemon --host 0.0.0.0 --port 8765Method | Path | Body |
GET |
| — |
GET |
| — |
GET |
| — |
POST |
|
|
POST |
|
|
Send Authorization: Bearer $TRAYFEEL_TOKEN when a token is configured.
Vision (optional)
If TRAYFEEL_CAMERA=/dev/video0 is set and ffmpeg is installed, trayfeel vision captures a frame via V4L2 and returns a best-effort brightness/edge heuristic. Missing camera or ffmpeg returns ok: false with a reason — it never crashes the process.
Library layout
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.pyLicense
MIT — Copyright (c) 2026 TrayFeel contributors
This server cannot be deployed
Maintenance
Related MCP Connectors
Shared control plane for AI coding agents — tasks, memory, decisions, file locks. 12 tools.
Remote Linux boxes for coding agents: Docker, a browser, screenshots, logs, human takeover.
Operate Linux, macOS and Windows from your LLM. Every action runs through an auditable allowlist.
Machine-readable utilities and datasets for AI agents.