feat(mcp): hovedhusets egen gateway paa /hovedhus/mcp
Selvstaendig under-app med egen Authentik-provider (hovedhus-mcp, gruppe Hovedhus), egen OIDCProxy/noegle/lager og backends fra data/hovedhus_gateway.json, aldrig fra mcp_registry.json. Ingen statiske noegler; UserGate kraever navngiven bruger og fejler lukket. Claude-Session: https://claude.ai/code/session_012LCTmU2ewo8tnM1dByYAoG
This commit is contained in:
@@ -7,6 +7,7 @@ from fastapi.staticfiles import StaticFiles
|
||||
from fastapi.templating import Jinja2Templates
|
||||
from starlette.middleware.sessions import SessionMiddleware
|
||||
|
||||
import contextlib
|
||||
import time
|
||||
|
||||
import authentik as ak
|
||||
@@ -20,11 +21,30 @@ import ytdl as yt
|
||||
import mcpkeys
|
||||
import mcp_server
|
||||
import mcp_gateway
|
||||
import mcp_hovedhus
|
||||
|
||||
# Portalens egen MCP (FastMCP), monteret in-process på /mcp. json_response=True
|
||||
# => almindelig JSON (ingen SSE), så det passerer edge'en utunet. Bearer-gated.
|
||||
mcp_app = mcp_gateway.gateway.http_app(path="/mcp", json_response=True)
|
||||
app = FastAPI(title="Weircon Portal", lifespan=mcp_app.lifespan)
|
||||
|
||||
# Hovedhusets gateway (/hovedhus/mcp) er en selvstændig under-app med egen
|
||||
# auth, så dens middleware kun gælder under /hovedhus. Begge apps har en
|
||||
# lifespan (StreamableHTTP-sessionerne), og FastAPI tager kun én.
|
||||
hh_app = (mcp_hovedhus.gateway.http_app(path="/mcp", json_response=True)
|
||||
if mcp_hovedhus.gateway else None)
|
||||
|
||||
|
||||
@contextlib.asynccontextmanager
|
||||
async def _lifespan(a):
|
||||
async with mcp_app.lifespan(a):
|
||||
if hh_app is None:
|
||||
yield
|
||||
else:
|
||||
async with hh_app.lifespan(hh_app):
|
||||
yield
|
||||
|
||||
|
||||
app = FastAPI(title="Weircon Portal", lifespan=_lifespan)
|
||||
for _mcp_route in mcp_app.routes:
|
||||
app.router.routes.append(_mcp_route)
|
||||
# route-extend copies routes but NOT middleware — carry FastMCP's auth/context
|
||||
@@ -34,6 +54,13 @@ for _mcp_mw in reversed(mcp_app.user_middleware):
|
||||
app.add_middleware(SessionMiddleware, secret_key=config.SECRET_KEY, https_only=True,
|
||||
same_site="lax", max_age=60 * 60 * 12)
|
||||
app.mount("/static", StaticFiles(directory=config.BASE / "static"), name="static")
|
||||
if hh_app is not None:
|
||||
# OAuth-metadata skal ligge i roden (RFC 8414/9728) med stien som suffiks.
|
||||
# Den bare /.well-known/openid-configuration tilhører hovedgatewayen.
|
||||
for _r in mcp_hovedhus.gateway.auth.get_well_known_routes(mcp_path="/mcp"):
|
||||
if _r.path != "/.well-known/openid-configuration":
|
||||
app.router.routes.append(_r)
|
||||
app.mount(mcp_hovedhus.PREFIX, hh_app)
|
||||
templates = Jinja2Templates(directory=str(config.BASE / "templates"))
|
||||
|
||||
oauth = OAuth()
|
||||
|
||||
Reference in New Issue
Block a user