"""Homebox inventory tools, loaded from the homebox-mcp server over stdio. Admin-only: the tools are only compiled into the admin agent, and each call re-checks ``is_admin`` in the run config as a second line of defense. """ import logging import os from langchain_core.tools import BaseTool, StructuredTool from utils.mcp_tools import admin_only_message, load_stdio_tools, select_tools logger = logging.getLogger(__name__) # Read + safe writes only. The server exposes ~39 tools; exposing all of them # would blow the local model's 32k context and allow deletes. HOMEBOX_TOOL_ALLOWLIST = ( "search_items", "get_item", "list_locations", "location_contents", "list_tags", "warranties_expiring", "inventory_stats", "list_maintenance", "create_item", "set_item", "move_item", "log_maintenance", ) LABEL = "Homebox" ADMIN_ONLY_MESSAGE = admin_only_message(LABEL) def select_homebox_tools(mcp_tools: list[BaseTool]) -> list[StructuredTool]: """Keep allowlisted tools (in allowlist order) and wrap them admin-only.""" return select_tools(mcp_tools, HOMEBOX_TOOL_ALLOWLIST, "homebox", LABEL) async def load_homebox_tools() -> list[StructuredTool]: """Start homebox-mcp and return the wrapped tools, or [] if unavailable.""" url = os.getenv("HOMEBOX_URL") token = os.getenv("HOMEBOX_TOKEN") if not url or not token: logger.info("Homebox MCP not configured (HOMEBOX_URL/HOMEBOX_TOKEN unset)") return [] return await load_stdio_tools( server="homebox", command=os.getenv("HOMEBOX_MCP_COMMAND", "homebox-mcp"), env={"HOMEBOX_URL": url, "HOMEBOX_TOKEN": token}, allowlist=HOMEBOX_TOOL_ALLOWLIST, prefix="homebox", label=LABEL, )