simplify Athena runtime and centralize MCP management

This commit is contained in:
Mikei386 committed 2026-08-26 09:57:38 +02:00
1 parent 104c9904a5
commit ab671a6396
31 files changed
+918 -419

No files matched your search

+1 -33
View File
@@ -11,13 +11,6 @@ if [[ -s $STACK_ENV ]]; then
COMPOSE+=(--env-file "$STACK_ENV")
fi
COMPOSE+=(-f "$STACK_DIR/compose.yaml")
export SEARXNG_SETTINGS_FILE="${SEARXNG_SETTINGS_FILE:-$MCP_DIR/../web-search/searxng-settings.yml}"
[[ -s $SEARXNG_SETTINGS_FILE ]] || {
echo "SearXNG-Konfiguration fehlt: $SEARXNG_SETTINGS_FILE" >&2
exit 1
}
docker network inspect mike-ai-tools >/dev/null 2>&1 || \
docker network create --internal --subnet 172.30.40.0/24 mike-ai-tools >/dev/null
docker network inspect mike-ai-tools-egress >/dev/null 2>&1 || \
@@ -26,36 +19,11 @@ docker network inspect mike-ai-tools-egress >/dev/null 2>&1 || \
# One administrative MCP exposes ATHENA.md plus the bounded host operator.
"$MCP_DIR/../operator/install-operator.sh"
services=(searxng tinysearch mcp-athena-operator)
services=(mcp-athena-operator)
# Portable Fach-MCPs laufen zentral im MCPHub auf Unraid. Ihre Compose-Blöcke
# bleiben vorläufig als explizite Rollback-Profile erhalten, werden bei einer
# normalen Athena-Installation aber weder gebaut noch gestartet.
echo "ARR, Deemix, GitHub, Home Assistant und Navidrome werden über MCPHub auf Unraid bereitgestellt."
# TinySearch keeps the embedding bundle outside the container. Download it
# once on a fresh host; subsequent rebuilds reuse the named volume.
#
# Do not call `tinysearch setup` here. The pinned container image already
# contains a complete Playwright/Chromium installation, while that command
# unconditionally tries to install Chromium again. On IPv4-only hosts this
# redundant download can hang indefinitely. Prepare only the persistent ONNX
# bundle that is actually absent on a fresh installation.
docker volume create mike-ai-tools_tinysearch-models >/dev/null
tiny_image="marcellm01/tinysearch@sha256:7a7d0585f5000f462e699e42b97409715826a9e2edcd09a166afa93a4b7cba31"
if ! docker run --rm --entrypoint test \
-v mike-ai-tools_tinysearch-models:/data/models "$tiny_image" \
-f /data/models/all-minilm-l6-v2-onnx/model.onnx; then
echo "TinySearch-Modell wird einmalig geladen."
docker run --rm --entrypoint python \
-v mike-ai-tools_tinysearch-models:/data/models "$tiny_image" \
-c 'from tinysearch.services.onnx_bundle_service import ensure_onnx_bundle_sync; ensure_onnx_bundle_sync("fast")'
fi
"${COMPOSE[@]}" up -d --build "${services[@]}"
for webui in mike-ai-open-webui Open-WebUI; do
if docker container inspect "$webui" >/dev/null 2>&1; then
docker network connect mike-ai-tools "$webui" 2>/dev/null || true
fi
done
"${COMPOSE[@]}" ps
+25 -1
View File
@@ -13,6 +13,7 @@ import time
BEGIN = "# BEGIN MANAGED MCP SERVERS"
END = "# END MANAGED MCP SERVERS"
CLIENT_TOKEN = ""
def env_file(path: str) -> dict[str, str]:
@@ -37,7 +38,10 @@ def enabled(item: dict) -> bool:
if source:
values = env_file(source)
url_ready = bool(item.get("url")) or bool(values.get(item.get("url_env", "")))
key_ready = not item.get("key_env") or bool(values.get(item["key_env"]))
key_ready = (not item.get("key_env")
or bool(values.get(item["key_env"]))
or (item.get("key_env") == "MCPHUB_BEARER_TOKEN"
and bool(CLIENT_TOKEN)))
return url_ready and key_ready
return True
@@ -47,6 +51,8 @@ def resolved(item: dict) -> tuple[str, str]:
values = env_file(item["env_file"])
url = item.get("url") or values[item["url_env"]]
key = values.get(item.get("key_env", ""), "")
if not key and item.get("key_env") == "MCPHUB_BEARER_TOKEN":
key = CLIENT_TOKEN
return url, key
return item["url"], ""
@@ -72,6 +78,16 @@ def hermes_block(items: list[dict]) -> str:
])
if key:
lines.extend([" headers:", f" Authorization: {yaml_quote('Bearer ' + key)}"])
if "tool_include" in item:
lines.append(" tools:")
lines.append(" include:")
for tool in item["tool_include"]:
lines.append(f" - {yaml_quote(str(tool))}")
elif "tool_exclude" in item:
lines.append(" tools:")
lines.append(" exclude:")
for tool in item["tool_exclude"]:
lines.append(f" - {yaml_quote(str(tool))}")
lines.extend([
f" timeout: {int(item.get('timeout', 300))}",
" connect_timeout: 30",
@@ -103,6 +119,8 @@ def openwebui_connection(item: dict) -> dict:
config = {"enable": True, "access_grants": []}
if item.get("functions"):
config["function_name_filter_list"] = item["functions"]
elif item.get("tool_include"):
config["function_name_filter_list"] = ",".join(item["tool_include"])
return {
"url": url, "path": "", "type": "mcp",
"auth_type": item.get("auth_type", "none"), "headers": None,
@@ -135,11 +153,17 @@ def update_openwebui(db: pathlib.Path, items: list[dict]) -> None:
def main() -> None:
global CLIENT_TOKEN
parser = argparse.ArgumentParser()
parser.add_argument("--registry", type=pathlib.Path, required=True)
parser.add_argument("--hermes", type=pathlib.Path, action="append", default=[])
parser.add_argument("--openwebui-db", type=pathlib.Path)
parser.add_argument("--mcphub-token-file", type=pathlib.Path)
args = parser.parse_args()
if args.mcphub_token_file:
CLIENT_TOKEN = args.mcphub_token_file.read_text(encoding="utf-8").strip()
if not CLIENT_TOKEN:
raise SystemExit("MCPHub token file is empty")
if args.hermes:
block = hermes_block(active(args.registry, "hermes"))
for path in args.hermes: