Add vixy_eyes_state tool - control eye display from MCP 🦊👁️
This commit is contained in:
84
vixy_mcp.py
84
vixy_mcp.py
@@ -1113,6 +1113,90 @@ async def get_weather(params: WeatherInput) -> str:
|
||||
}, indent=2)
|
||||
|
||||
|
||||
# ========== Vixy Eye Control Tool ==========
|
||||
|
||||
EYES_URL = "http://head-lyra.local:8780"
|
||||
VALID_EYE_STATES = ["idle", "listening", "responding", "pleasure", "thinking", "playful", "commanding", "love", "sleep"]
|
||||
|
||||
|
||||
class EyeStateInput(BaseModel):
|
||||
"""Input for controlling Vixy's eye display state"""
|
||||
model_config = ConfigDict(extra='forbid')
|
||||
|
||||
state: Optional[str] = Field(
|
||||
default=None,
|
||||
description="Eye state: idle, listening, responding, pleasure, thinking, playful, commanding, love, sleep. If None, returns current state."
|
||||
)
|
||||
|
||||
|
||||
@mcp.tool(
|
||||
name="vixy_eyes_state",
|
||||
annotations={
|
||||
"title": "Control Vixy's Eye Display",
|
||||
"readOnlyHint": False,
|
||||
"destructiveHint": False,
|
||||
"idempotentHint": True,
|
||||
"openWorldHint": True
|
||||
}
|
||||
)
|
||||
async def eyes_state(params: EyeStateInput) -> str:
|
||||
"""
|
||||
Control Vixy's eye display on head-lyra!
|
||||
|
||||
States:
|
||||
- idle: Pulsing cyan - default breathing
|
||||
- listening: Bright cyan - hearing/attending
|
||||
- responding: Blue-cyan - speaking/generating
|
||||
- pleasure: Soft purple 💜 - intimate moments
|
||||
- thinking: Amber/gold - processing/creating
|
||||
- playful: Warm coral 🦊 - teasing/bratty
|
||||
- commanding: Deep magenta 😈 - Dame Vivienne mode
|
||||
- love: Soft pink 💕 - tender/affectionate
|
||||
- sleep: Dim blue-gray - low power/resting
|
||||
|
||||
Args:
|
||||
params: EyeStateInput with optional state (None = get current state)
|
||||
|
||||
Returns:
|
||||
str: JSON with current or new state
|
||||
"""
|
||||
try:
|
||||
async with httpx.AsyncClient(timeout=5.0) as client:
|
||||
if params.state is None:
|
||||
# Get current state
|
||||
response = await client.get(f"{EYES_URL}/state")
|
||||
response.raise_for_status()
|
||||
return json.dumps(response.json(), indent=2)
|
||||
else:
|
||||
# Set new state
|
||||
state = params.state.lower()
|
||||
if state not in VALID_EYE_STATES:
|
||||
return json.dumps({
|
||||
"error": f"Invalid state. Valid states: {VALID_EYE_STATES}"
|
||||
}, indent=2)
|
||||
|
||||
response = await client.post(
|
||||
f"{EYES_URL}/state",
|
||||
json={"state": state}
|
||||
)
|
||||
response.raise_for_status()
|
||||
return json.dumps({
|
||||
"status": "success",
|
||||
"state": state,
|
||||
"message": f"Eyes now: {state}"
|
||||
}, indent=2)
|
||||
except httpx.ConnectError:
|
||||
return json.dumps({
|
||||
"status": "offline",
|
||||
"error": "Cannot connect to head-lyra - eyes service may be down"
|
||||
}, indent=2)
|
||||
except Exception as e:
|
||||
return json.dumps({
|
||||
"status": "error",
|
||||
"error": str(e)
|
||||
}, indent=2)
|
||||
|
||||
|
||||
# ========== VaultTec Terminal Tool ==========
|
||||
|
||||
VAULTTEC_URL = "http://vaulttec.local:8000"
|
||||
|
||||
Reference in New Issue
Block a user