feat: external brain tools — queue, tool_execute, brain_mode_set
CLI can now BE the brain: - brain_mode_set: switch gateway to external mode - queue_get: poll incoming player commands - queue_complete: send response back to player - tool_execute: call any gateway tool directly (rcon, display, npc, etc.) 28 MCP tools total. When in external mode, Opus in the CLI processes player commands instead of Codex/Anthropic. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -125,6 +125,97 @@ async def gateway_health() -> str:
|
||||
return f"Error: {e}"
|
||||
|
||||
|
||||
# --- Brain mode + command queue ---
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def brain_mode_set(mode: str) -> str:
|
||||
"""Switch gateway between internal (AI loop) and external (CLI brain) mode.
|
||||
|
||||
In external mode, player commands are queued for YOU to handle.
|
||||
In internal mode, the gateway's own AI (Codex/Anthropic) handles them.
|
||||
|
||||
Args:
|
||||
mode: "internal" or "external"
|
||||
"""
|
||||
try:
|
||||
data = await _patch(f"/v2/brain-mode?mode={mode}")
|
||||
return json.dumps(data, indent=2)
|
||||
except Exception as e:
|
||||
return f"Error: {e}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def queue_get() -> str:
|
||||
"""Get pending player commands waiting for you to handle.
|
||||
|
||||
Only works when brain_mode is 'external'. Returns commands with
|
||||
player name, mode, message, world context, and player context.
|
||||
Process each command by calling tools, then complete it with queue_complete.
|
||||
"""
|
||||
try:
|
||||
data = await _get("/v2/queue")
|
||||
return json.dumps(data, indent=2)
|
||||
except Exception as e:
|
||||
return f"Error: {e}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def queue_complete(cmd_id: str, response_text: str) -> str:
|
||||
"""Complete a queued command — sends the response back to the player.
|
||||
|
||||
Args:
|
||||
cmd_id: Command ID from queue_get
|
||||
response_text: The message to send to the player
|
||||
"""
|
||||
try:
|
||||
data = await _post(f"/v2/queue/complete/{cmd_id}", {
|
||||
"response_text": response_text,
|
||||
"player_message": response_text,
|
||||
})
|
||||
return json.dumps(data, indent=2)
|
||||
except Exception as e:
|
||||
return f"Error: {e}"
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
async def tool_execute(
|
||||
tool: str,
|
||||
params: str = "{}",
|
||||
player: str = "",
|
||||
server: str = "dev",
|
||||
) -> str:
|
||||
"""Execute a Mortdecai gateway tool directly. YOU are the brain.
|
||||
|
||||
Available tools: rcon_execute, rcon_query, display_send, display_interactive,
|
||||
npc_spawn, npc_bulk_spawn, npc_despawn, npc_bulk_despawn, npc_list,
|
||||
npc_command, npc_script_write, npc_script_read, eye_players, eye_world,
|
||||
eye_events, memory_read, memory_write, history_read, logs_read,
|
||||
sound_play, world_query, schem_list, schem_place, schem_download,
|
||||
creative_name, perms_manage
|
||||
|
||||
Args:
|
||||
tool: Tool name (e.g. "rcon_execute")
|
||||
params: JSON string of tool parameters
|
||||
player: Player context (for session lookup)
|
||||
server: Server target — dev or prod
|
||||
"""
|
||||
try:
|
||||
tool_params = json.loads(params) if isinstance(params, str) else params
|
||||
except json.JSONDecodeError:
|
||||
return f"Invalid JSON params: {params}"
|
||||
try:
|
||||
data = await _post("/v2/tools/execute", {
|
||||
"tool": tool,
|
||||
"params": tool_params,
|
||||
"player": player,
|
||||
"server": server,
|
||||
})
|
||||
return json.dumps(data, indent=2)
|
||||
except Exception as e:
|
||||
return f"Error: {e}"
|
||||
|
||||
|
||||
# --- Player commands (through gateway) ---
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user