diff --git a/agents/mcp_server/server.py b/agents/mcp_server/server.py index 1a40bb9..f3fd5c0 100644 --- a/agents/mcp_server/server.py +++ b/agents/mcp_server/server.py @@ -23,7 +23,7 @@ CLOUD_RUN_SERVICE = os.environ.get("CLOUD_RUN_SERVICE", "osvauco-agent") MCP_SECRET = os.environ.get("MCP_SECRET", "") # Secret Manager: mcp-server-key -# ── Auth ─────────────────────────────────────────────────────────────────── +# ── Auth ─────────────────────────────────────────────────────────────────────────── def verify_token(x_mcp_key: str = Header(default="")): """Enkel API-nøkkel auth. Byttes ut med IAP når tjenesten er på Cloud Run bak LB.""" if MCP_SECRET and x_mcp_key != MCP_SECRET: @@ -31,7 +31,7 @@ def verify_token(x_mcp_key: str = Header(default="")): return True -# ── Models ────────────────────────────────────────────────────────────────── +# ── Models ────────────────────────────────────────────────────────────────────────── class PushStaticRequest(BaseModel): file_path: str # Lokal sti relativt til repo-rot, f.eks. "static/jason.html" content: str # Fil-innhold (tekst/HTML) @@ -49,7 +49,7 @@ class ToolCallRequest(BaseModel): params: dict = {} -# ── Lifespan ────────────────────────────────────────────────────────────────── +# ── Lifespan ────────────────────────────────────────────────────────────────────────────── @asynccontextmanager async def lifespan(app: FastAPI): logger.info(f"OPAX-MCP starting | project={PROJECT_ID} | bucket={STATIC_BUCKET}") @@ -65,13 +65,13 @@ app = FastAPI( ) -# ── Health ─────────────────────────────────────────────────────────────────── +# ── Health ───────────────────────────────────────────────────────────────────────────── @app.get("/health") async def health(): return {"status": "ok", "service": "opax-mcp", "project": PROJECT_ID} -# ── MCP Tool Registry ────────────────────────────────────────────────────────── +# ── MCP Tool Registry ────────────────────────────────────────────────────────────────── @app.get("/mcp/tools") async def list_tools(_: bool = Depends(verify_token)): """MCP tool manifest — returnerer alle tilgjengelige verktøy med schema.""" @@ -117,7 +117,7 @@ async def list_tools(_: bool = Depends(verify_token)): } -# ── Tool: push_static ─────────────────────────────────────────────────────────── +# ── Tool: push_static ───────────────────────────────────────────────────────────────────── @app.post("/tools/push_static") async def push_static(req: PushStaticRequest, _: bool = Depends(verify_token)): """ @@ -148,16 +148,20 @@ async def push_static(req: PushStaticRequest, _: bool = Depends(verify_token)): raise HTTPException(status_code=500, detail=str(e)) -# ── Tool: get_build_status ───────────────────────────────────────────────────────── +# ── Tool: get_build_status ───────────────────────────────────────────────────────────────────── @app.get("/tools/get_build_status") async def get_build_status(_: bool = Depends(verify_token)): """ - Hent siste Cloud Build-kjøring. - Wrapper rundt samme logikk som /opax/build-status i osvauco-agent. + Hent siste Cloud Build-kjøring fra us-central1. """ try: from google.cloud.devtools import cloudbuild_v1 - client = cloudbuild_v1.CloudBuildClient() + from google.api_core.client_options import ClientOptions + client = cloudbuild_v1.CloudBuildClient( + client_options=ClientOptions( + api_endpoint=f"{REGION}-cloudbuild.googleapis.com" + ) + ) request = cloudbuild_v1.ListBuildsRequest( project_id=PROJECT_ID, filter='trigger_id!=""', @@ -183,23 +187,28 @@ async def get_build_status(_: bool = Depends(verify_token)): "commit": (b.substitutions or {}).get("SHORT_SHA", ""), "duration_s": duration_s, "log_url": b.log_url or "", + "region": REGION, } except Exception as e: logger.error(f"[get_build_status] Failed: {e}", exc_info=True) return {"status": "error", "message": str(e)} -# ── Tool: deploy_service ────────────────────────────────────────────────────────── +# ── Tool: deploy_service ────────────────────────────────────────────────────────────────────── @app.post("/tools/deploy_service") async def deploy_service(req: DeployServiceRequest, _: bool = Depends(verify_token)): """ Trigger Cloud Build for å bygge + deploye osvauco-agent. - Bruker Cloud Build Run trigger API. HITL-gate: logger kallet og returnerer build-ID for oppfølging. """ try: from google.cloud.devtools import cloudbuild_v1 - client = cloudbuild_v1.CloudBuildClient() + from google.api_core.client_options import ClientOptions + client = cloudbuild_v1.CloudBuildClient( + client_options=ClientOptions( + api_endpoint=f"{REGION}-cloudbuild.googleapis.com" + ) + ) trigger_id = req.trigger_id or os.environ.get("CLOUD_BUILD_TRIGGER_ID", "") if not trigger_id: @@ -224,7 +233,7 @@ async def deploy_service(req: DeployServiceRequest, _: bool = Depends(verify_tok "build_id": build_id, "branch": req.branch, "trigger_id": trigger_id, - "message": f"Build triggered. Kall GET /tools/get_build_status for status.", + "message": "Build triggered. Kall GET /tools/get_build_status for status.", } except HTTPException: raise @@ -233,7 +242,7 @@ async def deploy_service(req: DeployServiceRequest, _: bool = Depends(verify_tok raise HTTPException(status_code=500, detail=str(e)) -# ── Tool: get_logs ────────────────────────────────────────────────────────────────── +# ── Tool: get_logs ─────────────────────────────────────────────────────────────────────────────── @app.get("/tools/get_logs") async def get_logs( lines: int = 50, @@ -276,14 +285,9 @@ async def get_logs( raise HTTPException(status_code=500, detail=str(e)) -# ── MCP unified tool call endpoint ──────────────────────────────────────────────── +# ── MCP unified tool call endpoint ──────────────────────────────────────────────────────────── @app.post("/mcp/call") async def mcp_call(req: ToolCallRequest, _: bool = Depends(verify_token)): - """ - Unified MCP tool call endpoint. - Jason/Emma kaller denne med {tool: "push_static", params: {...}} - — slipper å vite individuelle endepunkt-URLer. - """ tool = req.tool params = req.params