feat: add daemon mode for single-process multi-agent architecture

- Add --daemon flag to run as single process serving multiple agents
- Add --socket-path for Unix socket communication
- Add --max-connections to limit concurrent agent connections
- Implement file locking to prevent multiple daemon instances
- Set environment variables for daemon mode configuration

This ensures hanzo-mcp runs as single process even with 100+ agents
This commit is contained in:
2025-09-25 14:11:25 -05:00
parent 40168b911f
commit db8502d8f0
+44
View File
@@ -247,6 +247,27 @@ def main() -> None:
help="Run in development mode with hot reload",
)
_ = parser.add_argument(
"--daemon",
action="store_true",
help="Run as daemon process for multiple agent connections",
)
_ = parser.add_argument(
"--socket-path",
dest="socket_path",
default="/tmp/hanzo-mcp.sock",
help="Unix socket path for daemon mode (default: /tmp/hanzo-mcp.sock)",
)
_ = parser.add_argument(
"--max-connections",
dest="max_connections",
type=int,
default=100,
help="Maximum number of concurrent connections in daemon mode (default: 100)",
)
_ = parser.add_argument(
"--install",
action="store_true",
@@ -287,6 +308,9 @@ def main() -> None:
name: str = cast(str, args.name)
install: bool = cast(bool, args.install)
dev: bool = cast(bool, args.dev)
daemon: bool = cast(bool, args.daemon)
socket_path: str = cast(str, args.socket_path)
max_connections: int = cast(int, args.max_connections)
transport: str = cast(str, args.transport)
agent_model: str | None = cast(str | None, args.agent_model)
agent_max_tokens: int | None = cast(int | None, args.agent_max_tokens)
@@ -345,6 +369,26 @@ def main() -> None:
if not allowed_paths:
allowed_paths = [os.path.expanduser("~")]
# Set daemon mode environment variables
if daemon:
os.environ["HANZO_MCP_DAEMON"] = "true"
os.environ["HANZO_MCP_SOCKET_PATH"] = socket_path
os.environ["HANZO_MCP_MAX_CONNECTIONS"] = str(max_connections)
if transport != "stdio":
logger.info(f"Starting Hanzo MCP daemon on {socket_path}")
logger.info(f"Max connections: {max_connections}")
# Ensure only one daemon runs per socket
try:
import fcntl
lock_file = f"{socket_path}.lock"
with open(lock_file, 'w') as f:
fcntl.flock(f.fileno(), fcntl.LOCK_EX | fcntl.LOCK_NB)
except (ImportError, IOError):
# Fallback for systems without fcntl or if lock fails
pass
# Run in dev mode if requested
if dev:
from hanzo_mcp.dev_server import DevServer