unifi-network-mcp 0.4.1__tar.gz → 0.4.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/PKG-INFO +1 -1
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/_version.py +2 -2
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/config/config.yaml +1 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/main.py +14 -12
- unifi_network_mcp-0.4.2/src/utils/config_helpers.py +38 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/.gitignore +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/.well-known/mcp-server.json +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/LICENSE +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/README.md +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/pyproject.toml +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/bootstrap.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/jobs.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/client_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/connection_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/device_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/event_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/firewall_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/hotspot_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/network_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/qos_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/routing_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/stats_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/system_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/traffic_route_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/usergroup_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/managers/vpn_manager.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/runtime.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/schemas.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tool_index.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/clients.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/config.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/devices.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/events.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/firewall.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/hotspot.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/network.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/port_forwards.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/qos.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/routing.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/stats.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/system.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/traffic_routes.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/usergroups.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools/vpn.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/tools_manifest.json +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/utils/confirmation.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/utils/diagnostics.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/utils/lazy_tool_loader.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/utils/meta_tools.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/utils/permissions.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/utils/tool_loader.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/validator_registry.py +0 -0
- {unifi_network_mcp-0.4.1 → unifi_network_mcp-0.4.2}/src/validators.py +0 -0
|
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
|
|
|
28
28
|
commit_id: COMMIT_ID
|
|
29
29
|
__commit_id__: COMMIT_ID
|
|
30
30
|
|
|
31
|
-
__version__ = version = '0.4.
|
|
32
|
-
__version_tuple__ = version_tuple = (0, 4,
|
|
31
|
+
__version__ = version = '0.4.2'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 4, 2)
|
|
33
33
|
|
|
34
34
|
__commit_id__ = commit_id = None
|
|
@@ -10,9 +10,11 @@ Responsibilities:
|
|
|
10
10
|
import asyncio
|
|
11
11
|
import logging
|
|
12
12
|
import os
|
|
13
|
-
import sys
|
|
13
|
+
import sys
|
|
14
14
|
import traceback
|
|
15
15
|
|
|
16
|
+
import uvicorn.config
|
|
17
|
+
|
|
16
18
|
from src.bootstrap import (
|
|
17
19
|
UNIFI_TOOL_REGISTRATION_MODE,
|
|
18
20
|
logger,
|
|
@@ -26,6 +28,7 @@ from src.runtime import (
|
|
|
26
28
|
server,
|
|
27
29
|
)
|
|
28
30
|
from src.tool_index import register_tool, tool_index_handler
|
|
31
|
+
from src.utils.config_helpers import parse_config_bool
|
|
29
32
|
from src.utils.diagnostics import diagnostics_enabled, wrap_tool
|
|
30
33
|
from src.utils.lazy_tool_loader import setup_lazy_loading
|
|
31
34
|
from src.utils.meta_tools import register_load_tools, register_meta_tools
|
|
@@ -310,17 +313,16 @@ async def main_async():
|
|
|
310
313
|
host = config.server.get("host", "0.0.0.0")
|
|
311
314
|
port = int(config.server.get("port", 3000))
|
|
312
315
|
http_cfg = config.server.get("http", {})
|
|
313
|
-
|
|
314
|
-
if isinstance(http_enabled_raw, str):
|
|
315
|
-
http_enabled = http_enabled_raw.strip().lower() in {"1", "true", "yes", "on"}
|
|
316
|
-
else:
|
|
317
|
-
http_enabled = bool(http_enabled_raw)
|
|
316
|
+
http_enabled = parse_config_bool(http_cfg.get("enabled", False))
|
|
318
317
|
|
|
319
|
-
# Only the main container process (PID 1) should bind the HTTP SSE port
|
|
318
|
+
# Only the main container process (PID 1) should bind the HTTP SSE port,
|
|
319
|
+
# unless http.force=true is set in config (for local development/testing).
|
|
320
|
+
force_http = parse_config_bool(http_cfg.get("force", False))
|
|
320
321
|
is_main_container_process = os.getpid() == 1
|
|
321
|
-
if http_enabled and not is_main_container_process:
|
|
322
|
+
if http_enabled and not is_main_container_process and not force_http:
|
|
322
323
|
logger.info(
|
|
323
|
-
"HTTP SSE enabled in config but skipped in exec session (PID %s != 1)"
|
|
324
|
+
"HTTP SSE enabled in config but skipped in exec session (PID %s != 1). "
|
|
325
|
+
"Set UNIFI_MCP_HTTP_FORCE=true to override.",
|
|
324
326
|
os.getpid(),
|
|
325
327
|
)
|
|
326
328
|
http_enabled = False
|
|
@@ -338,9 +340,9 @@ async def main_async():
|
|
|
338
340
|
server.settings.host = host
|
|
339
341
|
server.settings.port = port
|
|
340
342
|
|
|
341
|
-
#
|
|
342
|
-
# when running alongside stdio transport
|
|
343
|
-
|
|
343
|
+
# Redirect uvicorn access logs to stderr to prevent stdout conflicts
|
|
344
|
+
# when running alongside stdio transport (stdout is used for JSON-RPC)
|
|
345
|
+
uvicorn.config.LOGGING_CONFIG["handlers"]["access"]["stream"] = "ext://sys.stderr"
|
|
344
346
|
|
|
345
347
|
await server.run_sse_async()
|
|
346
348
|
logger.info("HTTP SSE started via run_sse_async() using server.settings host/port.")
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"""Configuration parsing utilities.
|
|
2
|
+
|
|
3
|
+
This module provides helpers for parsing configuration values that may come
|
|
4
|
+
from OmegaConf-resolved environment variables (which can be strings like
|
|
5
|
+
"true"/"false") or direct boolean values.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from typing import Any
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
def parse_config_bool(value: Any, default: bool = False) -> bool:
|
|
12
|
+
"""Parse a config value as boolean, handling string values from env vars.
|
|
13
|
+
|
|
14
|
+
OmegaConf resolves ${oc.env:VAR,default} to strings when the env var is set,
|
|
15
|
+
so "true"/"false" strings need to be parsed explicitly.
|
|
16
|
+
|
|
17
|
+
Args:
|
|
18
|
+
value: The config value to parse (string, bool, or None)
|
|
19
|
+
default: Default value if value is None
|
|
20
|
+
|
|
21
|
+
Returns:
|
|
22
|
+
Boolean interpretation of the value
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
>>> parse_config_bool("true")
|
|
26
|
+
True
|
|
27
|
+
>>> parse_config_bool("false")
|
|
28
|
+
False
|
|
29
|
+
>>> parse_config_bool(True)
|
|
30
|
+
True
|
|
31
|
+
>>> parse_config_bool(None, default=True)
|
|
32
|
+
True
|
|
33
|
+
"""
|
|
34
|
+
if value is None:
|
|
35
|
+
return default
|
|
36
|
+
if isinstance(value, str):
|
|
37
|
+
return value.strip().lower() in {"1", "true", "yes", "on"}
|
|
38
|
+
return bool(value)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|