publish MCPs through a filtered Hermes group
This commit is contained in:
1 parent
2595bab17b
commit
167448d778
6 files changed
+54
-7
No files matched your search
@@ -13,6 +13,7 @@ import os
|
||||
import pathlib
|
||||
import re
|
||||
import urllib.error
|
||||
import urllib.parse
|
||||
import urllib.request
|
||||
from typing import Any
|
||||
|
||||
@@ -21,6 +22,7 @@ from mcp.server.fastmcp import FastMCP
|
||||
|
||||
API_BASE = os.environ.get("MCPHUB_API_URL", "http://127.0.0.1:3000/api").rstrip("/")
|
||||
TOKEN_FILE = pathlib.Path(os.environ.get("MCPHUB_API_TOKEN_FILE", "/app/data/client-token"))
|
||||
CLIENT_GROUP = os.environ.get("MCPHUB_CLIENT_GROUP", "hermes").strip()
|
||||
NAME_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]{0,62}$")
|
||||
NPM_PACKAGE_RE = re.compile(r"^(?:@[A-Za-z0-9._-]+/)?[A-Za-z0-9._-]+(?:@[A-Za-z0-9._+~-]+)?$")
|
||||
PYTHON_PACKAGE_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._-]*(?:==[A-Za-z0-9._+~-]+)?$")
|
||||
@@ -135,9 +137,35 @@ def _install(name: str, config: dict[str, Any]) -> str:
|
||||
if any(isinstance(row, dict) and row.get("name") == name for row in rows):
|
||||
raise HubError(f"Server already exists: {name}; inspect or update it instead")
|
||||
result = _request("POST", "/servers", {"name": name, "config": config})
|
||||
group_result = _add_to_group(name)
|
||||
verified = _request("GET", f"/servers/{name}")
|
||||
data = verified.get("data", verified) if isinstance(verified, dict) else verified
|
||||
return json.dumps({"installed": True, "server": _redact(data), "api_result": _redact(result)}, ensure_ascii=False)
|
||||
return json.dumps({
|
||||
"installed": True,
|
||||
"published_to": CLIENT_GROUP,
|
||||
"server": _redact(data),
|
||||
"api_result": _redact(result),
|
||||
"group_result": _redact(group_result),
|
||||
}, ensure_ascii=False)
|
||||
|
||||
|
||||
def _add_to_group(name: str, tools: list[str] | None = None) -> Any:
|
||||
if not CLIENT_GROUP:
|
||||
return {"skipped": "no-client-group"}
|
||||
group = urllib.parse.quote(CLIENT_GROUP, safe="")
|
||||
configs = _request("GET", f"/groups/{group}/server-configs")
|
||||
rows = configs.get("data", []) if isinstance(configs, dict) else []
|
||||
present = any(isinstance(row, dict) and row.get("name") == name for row in rows)
|
||||
result: Any = {"already_present": True}
|
||||
if not present:
|
||||
result = _request("POST", f"/groups/{group}/servers", {"serverName": name})
|
||||
if tools is not None:
|
||||
result = _request(
|
||||
"PUT",
|
||||
f"/groups/{group}/server-configs/{urllib.parse.quote(name, safe='')}/tools",
|
||||
{"tools": tools},
|
||||
)
|
||||
return result
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
@@ -197,6 +225,24 @@ def mcphub_admin_reload(name: str) -> str:
|
||||
return json.dumps(_redact(result), ensure_ascii=False)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def mcphub_admin_publish_to_hermes(name: str, tools: list[str] | None = None) -> str:
|
||||
"""Publish one installed server to the central Hermes group. Optionally expose only the named tools; omit tools to expose all."""
|
||||
name = _name(name)
|
||||
selected = None if tools is None else _args(tools)
|
||||
result = _add_to_group(name, selected)
|
||||
return json.dumps({"published": name, "group": CLIENT_GROUP, "result": _redact(result)}, ensure_ascii=False)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def mcphub_admin_unpublish_from_hermes(name: str) -> str:
|
||||
"""Remove one server from the central Hermes group without uninstalling or disabling the server itself."""
|
||||
name = _name(name)
|
||||
group = urllib.parse.quote(CLIENT_GROUP, safe="")
|
||||
result = _request("DELETE", f"/groups/{group}/servers/{urllib.parse.quote(name, safe='')}")
|
||||
return json.dumps({"unpublished": name, "group": CLIENT_GROUP, "result": _redact(result)}, ensure_ascii=False)
|
||||
|
||||
|
||||
@mcp.tool()
|
||||
def mcphub_admin_remove(name: str, confirmation: str) -> str:
|
||||
"""Permanently remove a server only after the user explicitly requested it. confirmation must exactly equal REMOVE:<name>."""
|
||||
|
||||
Reference in new issue
Block a user