# /// script
# requires-python = ">=3.12"
# dependencies = ["mcp>=1.26,<2", "httpx>=0.28,<1"]
# ///
"""Optional stdio bridge for local clients; all permissions stay on the server.

Run with uv run /absolute/path/indoo_stdio.py. Set INDOO_API_URL and INDOO_TOKEN
in the host's environment/secret manager. stdout is reserved for MCP messages.
"""

import asyncio
import os
from urllib.parse import urlsplit

import httpx
from mcp.server.lowlevel import Server
from mcp.server.stdio import stdio_server
from mcp.types import CallToolResult, TextContent, Tool


async def main() -> None:
    base = os.environ.get("INDOO_API_URL", "https://indoo.ai").rstrip("/")
    token = os.environ.get("INDOO_TOKEN", "")
    parsed = urlsplit(base)
    if parsed.scheme != "https" and not (
        parsed.scheme == "http" and parsed.hostname in {"localhost", "127.0.0.1", "::1"}
    ):
        raise SystemExit("INDOO_API_URL must use HTTPS (HTTP loopback is allowed for local development).")
    if parsed.username or parsed.password or parsed.query or parsed.fragment or not parsed.netloc or parsed.path:
        raise SystemExit("INDOO_API_URL must be an origin without credentials, path, query or fragment.")
    if not token:
        raise SystemExit("Set INDOO_TOKEN in your client environment, not in a chat message.")
    server = Server("indoo-stdio", version="1.0.0")
    async with httpx.AsyncClient(base_url=base, headers={"Authorization": f"Bearer {token}"},
                                 timeout=60, follow_redirects=False) as client:
        @server.list_tools()
        async def tools():
            response = await client.get("/v1/assistant/tools")
            if response.status_code != 200:
                raise ValueError("Cannot load Indoo tools. Check your URL and connection token.")
            return [Tool.model_validate(item) for item in response.json()["tools"]]

        @server.call_tool()
        async def call(name, arguments):
            if not name.replace("_", "").isalnum():
                raise ValueError("Invalid tool name")
            try:
                response = await client.post(f"/v1/assistant/tools/{name}", json={"arguments": arguments})
                if response.is_success:
                    return response.json()
                detail = response.json().get("detail", "Request failed")
                return CallToolResult(isError=True, content=[TextContent(type="text", text=str(detail))])
            except (httpx.HTTPError, ValueError):
                return CallToolResult(isError=True, content=[TextContent(type="text", text="Connection interrupted. Check saved jobs before retrying; reuse the same idempotency key.")])

        async with stdio_server() as (read_stream, write_stream):
            await server.run(read_stream, write_stream, server.create_initialization_options())


if __name__ == "__main__":
    asyncio.run(main())
