diff --git a/dashboard/app.py b/dashboard/app.py
index aff0447..2340853 100644
--- a/dashboard/app.py
+++ b/dashboard/app.py
@@ -31,6 +31,7 @@
from dashboard import gpu_stats, settings
from dashboard import routes_gpu as _routes_gpu
+from dashboard import routes_model_config as _routes_model_config
from dashboard import routes_registry as _routes_registry
from dashboard.orchestration_db import get_job_counts, get_outbox_stats
from dashboard.routes_hub import router as hub_router
@@ -2118,6 +2119,7 @@ def _empty_payload():
_routes_gpu.register(app, _ops_request)
_routes_registry.register(app, _ops_request)
+_routes_model_config.register(app, _ops_request)
mimetypes.add_type("application/octet-stream", ".stl")
diff --git a/dashboard/routes_model_config.py b/dashboard/routes_model_config.py
new file mode 100644
index 0000000..88a78f7
--- /dev/null
+++ b/dashboard/routes_model_config.py
@@ -0,0 +1,38 @@
+"""Model-config control-plane passthrough to ops-controller (/model-config).
+
+Thin proxy (like routes_registry): the browser never sees the ops-controller
+token β _ops_request injects it. Drives the dashboard's Model Control flag UI.
+"""
+from __future__ import annotations
+
+from fastapi import APIRouter, HTTPException, Request
+
+router = APIRouter(prefix="/api/model-config")
+
+_ops_request = None
+_registered = False
+
+
+def register(app, ops_request):
+ """Wire routes onto `app`. `ops_request` is dashboard.app._ops_request."""
+ global _ops_request, _registered
+ _ops_request = ops_request
+ if _registered:
+ return
+ _registered = True
+
+ @router.get("")
+ async def get_model_config(request: Request):
+ code, data = await _ops_request("GET", "/model-config", request=request)
+ if code >= 400:
+ raise HTTPException(status_code=code, detail=(data.get("detail", data) if isinstance(data, dict) else data))
+ return data
+
+ @router.post("")
+ async def post_model_config(body: dict, request: Request):
+ code, data = await _ops_request("POST", "/model-config", request=request, json=body)
+ if code >= 400:
+ raise HTTPException(status_code=code, detail=(data.get("detail", data) if isinstance(data, dict) else data))
+ return data
+
+ app.include_router(router)
diff --git a/dashboard/static/index.html b/dashboard/static/index.html
index 873cddc..000bc41 100644
--- a/dashboard/static/index.html
+++ b/dashboard/static/index.html
@@ -1646,6 +1646,7 @@
Ordo AI Stack Dashboard
+
@@ -1988,6 +1989,14 @@
Model Registry
+
+
+
Model Control
+
All llama.cpp launch parameters as feature flags. Baseline = .env defaults; per-model overrides live in the registry. "Apply & restart" renders the effective config to .env and recreates llamacpp (+ model-gateway when context changes).