hanzo-mcp 0.15.8: require hanzoai>=2.2.1, never silence stderr

Floor hanzoai at 2.2.1 — the first release that actually ships
hanzoai.protocols, which permissions.py imports.

Drop the stderr→devnull redirect in stdio mode. The MCP stdio protocol
rides stdout alone; stderr is the channel clients log for diagnostics.
Silencing it turned the missing-module crash into a zero-byte mystery —
the client log literally suggests printing to stderr while the server
was throwing tracebacks into devnull. Run-loop failures also log with
exc_info so the traceback reaches the client log.
This commit is contained in:
2026-06-10 20:03:53 -07:00
parent f6c66faf98
commit 8a89329f35
2 changed files with 9 additions and 9 deletions
+6 -7
View File
@@ -83,10 +83,9 @@ def main() -> None:
handlers=[], # No handlers for stdio to prevent protocol corruption
)
# Redirect stderr to devnull for stdio transport to prevent any output
# Store handles for proper cleanup to avoid resource leaks
_stderr_devnull = open(os.devnull, "w")
sys.stderr = _stderr_devnull
# stderr stays attached: the stdio protocol rides stdout only, and MCP
# clients capture stderr for diagnostics. Silencing it hides startup
# tracebacks and turns any crash into an undiagnosable failure.
# Suppress stdout during potentially noisy imports unless user requested help/version
_stdout_devnull = None
@@ -371,8 +370,8 @@ def main() -> None:
pass
sys.stdout = original_stdout
# Note: We intentionally keep stderr redirected to devnull for stdio transport
# to prevent any library noise from corrupting the protocol
# stderr is never redirected: it cannot corrupt the stdio protocol and is
# the only channel where startup failures are visible to MCP clients
# Parse timeout arguments with human-readable format support
command_timeout = _parse_timeout_arg(str(args.command_timeout))
@@ -556,7 +555,7 @@ def main() -> None:
logger.info("\nShutting down...")
sys.exit(0)
except Exception as e:
logger.error(f"Server error: {e}")
logger.error(f"Server error: {e}", exc_info=True)
sys.exit(1)
+3 -2
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "hanzo-mcp"
version = "0.15.7"
version = "0.15.8"
description = "The Zen of Hanzo MCP: One server to rule them all. The ultimate MCP that orchestrates all others."
readme = "README.md"
requires-python = ">=3.12"
@@ -18,7 +18,8 @@ classifiers = [
keywords = ["mcp", "claude", "hanzo", "code", "agent"]
dependencies = [
# Hanzo AI core SDK (canonical types, config, session, MCP client)
"hanzoai>=2.2.0",
# 2.2.1 is the first release shipping hanzoai.protocols (permissions.py imports it)
"hanzoai>=2.2.1",
# Core MCP dependencies
"mcp>=1.25.0",
"fastmcp>=2.14.4",