from __future__ import annotations import os import sys from pathlib import Path from typing import Any PLUGIN_DIR = Path(__file__).resolve().parent / "BioSPPy" / "mcp_output" / "mcp_plugin" if str(PLUGIN_DIR) not in sys.path: sys.path.insert(0, str(PLUGIN_DIR)) try: from fastapi import FastAPI # type: ignore[import-not-found] except Exception: FastAPI = None try: import uvicorn # type: ignore[import-not-found] except Exception: uvicorn = None if FastAPI is None: raise RuntimeError("fastapi is required to run app.py") app = FastAPI(title="BioSPPy MCP Supplementary App", version="1.0.0") def _extract_tool_info(app_obj: Any) -> list[dict[str, str | None]]: tools = getattr(app_obj, "tools", None) if tools is None: return [] if isinstance(tools, dict): iterable = list(tools.values()) elif isinstance(tools, list): iterable = tools else: try: iterable = list(tools) except Exception: return [] result: list[dict[str, str | None]] = [] for tool in iterable: name = getattr(tool, "name", None) description = getattr(tool, "description", None) if name is None and isinstance(tool, dict): name = tool.get("name") description = tool.get("description") result.append({"name": str(name) if name is not None else None, "description": str(description) if description is not None else None}) return result @app.get("/") def root() -> dict[str, Any]: return { "service": "BioSPPy MCP Deployment", "description": "Supplementary FastAPI app for local inspection; MCP server is started by start_mcp.py.", "mcp_http_endpoint": "/mcp", } @app.get("/health") def health() -> dict[str, str]: return {"status": "healthy"} @app.get("/tools") def tools() -> dict[str, Any]: try: from mcp_service import create_app # type: ignore[import-not-found] mcp_app = create_app() return {"status": "ok", "tools": _extract_tool_info(mcp_app)} except Exception as exc: return {"status": "error", "tools": [], "error": str(exc)} if __name__ == "__main__": port = int(os.getenv("PORT", "7860")) if uvicorn is None: raise RuntimeError("uvicorn is required to run app.py directly") uvicorn.run(app, host="0.0.0.0", port=port)