Merge pull request #973 from AryanyAI/refactor/logging-mcp-scripts

refactor(mcp): replace print() with logging in setup scripts
This commit is contained in:
Hundao
2026-01-27 20:56:40 +08:00
committed by GitHub
3 changed files with 140 additions and 92 deletions
+61 -47
View File
@@ -6,11 +6,24 @@ This script installs the framework and configures the MCP server.
"""
import json
import logging
import os
import subprocess
import sys
from pathlib import Path
logger = logging.getLogger(__name__)
def setup_logger():
"""Configure logger for CLI usage with colored output."""
if not logger.handlers:
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter("%(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
class Colors:
"""ANSI color codes for terminal output."""
@@ -22,19 +35,19 @@ class Colors:
NC = "\033[0m" # No Color
def print_step(message: str, color: str = Colors.YELLOW):
"""Print a colored step message."""
print(f"{color}{message}{Colors.NC}")
def log_step(message: str):
"""Log a colored step message."""
logger.info(f"{Colors.YELLOW}{message}{Colors.NC}")
def print_success(message: str):
"""Print a success message."""
print(f"{Colors.GREEN}{message}{Colors.NC}")
def log_success(message: str):
"""Log a success message."""
logger.info(f"{Colors.GREEN}{message}{Colors.NC}")
def print_error(message: str):
"""Print an error message."""
print(f"{Colors.RED}{message}{Colors.NC}", file=sys.stderr)
def log_error(message: str):
"""Log an error message."""
logger.error(f"{Colors.RED}{message}{Colors.NC}")
def run_command(cmd: list, error_msg: str) -> bool:
@@ -43,52 +56,53 @@ def run_command(cmd: list, error_msg: str) -> bool:
subprocess.run(cmd, check=True, capture_output=True, text=True)
return True
except subprocess.CalledProcessError as e:
print_error(error_msg)
print(f"Error output: {e.stderr}", file=sys.stderr)
log_error(error_msg)
logger.error(f"Error output: {e.stderr}")
return False
def main():
"""Main setup function."""
print("=== Aden Hive Framework MCP Server Setup ===")
print()
setup_logger()
logger.info("=== Aden Hive Framework MCP Server Setup ===")
logger.info("")
# Get script directory
script_dir = Path(__file__).parent.absolute()
os.chdir(script_dir)
# Step 1: Install framework package
print_step("Step 1: Installing framework package...")
log_step("Step 1: Installing framework package...")
if not run_command(
[sys.executable, "-m", "pip", "install", "-e", "."], "Failed to install framework package"
):
sys.exit(1)
print_success("Framework package installed")
print()
log_success("Framework package installed")
logger.info("")
# Step 2: Install MCP dependencies
print_step("Step 2: Installing MCP dependencies...")
log_step("Step 2: Installing MCP dependencies...")
if not run_command(
[sys.executable, "-m", "pip", "install", "mcp", "fastmcp"],
"Failed to install MCP dependencies",
):
sys.exit(1)
print_success("MCP dependencies installed")
print()
log_success("MCP dependencies installed")
logger.info("")
# Step 3: Verify/create MCP configuration
print_step("Step 3: Verifying MCP server configuration...")
log_step("Step 3: Verifying MCP server configuration...")
mcp_config_path = script_dir / ".mcp.json"
if mcp_config_path.exists():
print_success("MCP configuration found at .mcp.json")
print("Configuration:")
log_success("MCP configuration found at .mcp.json")
logger.info("Configuration:")
with open(mcp_config_path) as f:
config = json.load(f)
print(json.dumps(config, indent=2))
logger.info(json.dumps(config, indent=2))
else:
print_error("No .mcp.json found")
print("Creating default MCP configuration...")
log_error("No .mcp.json found")
logger.info("Creating default MCP configuration...")
config = {
"mcpServers": {
@@ -103,11 +117,11 @@ def main():
with open(mcp_config_path, "w") as f:
json.dump(config, f, indent=2)
print_success("Created .mcp.json")
print()
log_success("Created .mcp.json")
logger.info("")
# Step 4: Test MCP server
print_step("Step 4: Testing MCP server...")
log_step("Step 4: Testing MCP server...")
try:
# Try importing the MCP server module
subprocess.run(
@@ -116,27 +130,27 @@ def main():
capture_output=True,
text=True,
)
print_success("MCP server module verified")
log_success("MCP server module verified")
except subprocess.CalledProcessError as e:
print_error("Failed to import MCP server module")
print(f"Error: {e.stderr}", file=sys.stderr)
log_error("Failed to import MCP server module")
logger.error(f"Error: {e.stderr}")
sys.exit(1)
print()
logger.info("")
# Success summary
print(f"{Colors.GREEN}=== Setup Complete ==={Colors.NC}")
print()
print("The MCP server is now ready to use!")
print()
print(f"{Colors.BLUE}To start the MCP server manually:{Colors.NC}")
print(" python -m framework.mcp.agent_builder_server")
print()
print(f"{Colors.BLUE}MCP Configuration location:{Colors.NC}")
print(f" {mcp_config_path}")
print()
print(f"{Colors.BLUE}To use with Claude Desktop or other MCP clients,{Colors.NC}")
print(f"{Colors.BLUE}add the following to your MCP client configuration:{Colors.NC}")
print()
logger.info(f"{Colors.GREEN}=== Setup Complete ==={Colors.NC}")
logger.info("")
logger.info("The MCP server is now ready to use!")
logger.info("")
logger.info(f"{Colors.BLUE}To start the MCP server manually:{Colors.NC}")
logger.info(" python -m framework.mcp.agent_builder_server")
logger.info("")
logger.info(f"{Colors.BLUE}MCP Configuration location:{Colors.NC}")
logger.info(f" {mcp_config_path}")
logger.info("")
logger.info(f"{Colors.BLUE}To use with Claude Desktop or other MCP clients,{Colors.NC}")
logger.info(f"{Colors.BLUE}add the following to your MCP client configuration:{Colors.NC}")
logger.info("")
example_config = {
"mcpServers": {
@@ -147,8 +161,8 @@ def main():
}
}
}
print(json.dumps(example_config, indent=2))
print()
logger.info(json.dumps(example_config, indent=2))
logger.info("")
if __name__ == "__main__":
+50 -35
View File
@@ -6,10 +6,23 @@ This script checks if the MCP server is properly installed and configured.
"""
import json
import logging
import subprocess
import sys
from pathlib import Path
logger = logging.getLogger(__name__)
def setup_logger():
"""Configure logger for CLI usage."""
if not logger.handlers:
handler = logging.StreamHandler(sys.stdout)
formatter = logging.Formatter("%(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
class Colors:
GREEN = "\033[0;32m"
@@ -21,29 +34,31 @@ class Colors:
def check(description: str) -> bool:
"""Print check description and return a context manager for result."""
print(f"Checking {description}...", end=" ")
logger.info(f"Checking {description}... ", extra={"end": ""})
sys.stdout.flush()
return True
def success(msg: str = "OK"):
"""Print success message."""
print(f"{Colors.GREEN}{msg}{Colors.NC}")
"""Log success message."""
logger.info(f"{Colors.GREEN}{msg}{Colors.NC}")
def warning(msg: str):
"""Print warning message."""
print(f"{Colors.YELLOW}{msg}{Colors.NC}")
"""Log warning message."""
logger.warning(f"{Colors.YELLOW}{msg}{Colors.NC}")
def error(msg: str):
"""Print error message."""
print(f"{Colors.RED}{msg}{Colors.NC}")
"""Log error message."""
logger.error(f"{Colors.RED}{msg}{Colors.NC}")
def main():
"""Run verification checks."""
print("=== MCP Server Verification ===")
print()
setup_logger()
logger.info("=== MCP Server Verification ===")
logger.info("")
script_dir = Path(__file__).parent.absolute()
all_checks_passed = True
@@ -61,7 +76,7 @@ def main():
success(f"installed at {framework_path}")
except subprocess.CalledProcessError:
error("framework package not found")
print(f" Run: pip install -e {script_dir}")
logger.info(f" Run: pip install -e {script_dir}")
all_checks_passed = False
# Check 2: MCP dependencies
@@ -75,7 +90,7 @@ def main():
if missing_deps:
error(f"missing: {', '.join(missing_deps)}")
print(f" Run: pip install {' '.join(missing_deps)}")
logger.info(f" Run: pip install {' '.join(missing_deps)}")
all_checks_passed = False
else:
success("all installed")
@@ -92,7 +107,7 @@ def main():
success("loads successfully")
except subprocess.CalledProcessError as e:
error("failed to import")
print(f" Error: {e.stderr}")
logger.error(f" Error: {e.stderr}")
all_checks_passed = False
# Check 4: MCP configuration file
@@ -106,9 +121,9 @@ def main():
if "mcpServers" in config and "agent-builder" in config["mcpServers"]:
server_config = config["mcpServers"]["agent-builder"]
success("found and valid")
print(f" Command: {server_config.get('command')}")
print(f" Args: {' '.join(server_config.get('args', []))}")
print(f" CWD: {server_config.get('cwd')}")
logger.info(f" Command: {server_config.get('command')}")
logger.info(f" Args: {' '.join(server_config.get('args', []))}")
logger.info(f" CWD: {server_config.get('cwd')}")
else:
warning("exists but missing agent-builder config")
all_checks_passed = False
@@ -117,8 +132,8 @@ def main():
all_checks_passed = False
else:
warning("not found (optional)")
print(f" Location would be: {mcp_config}")
print(" Run setup_mcp.py to create it")
logger.info(f" Location would be: {mcp_config}")
logger.info(" Run setup_mcp.py to create it")
# Check 5: Framework modules
check("core framework modules")
@@ -168,28 +183,28 @@ def main():
warning("server startup slow (might be OK)")
except subprocess.CalledProcessError as e:
error("server failed to start")
print(f" Error: {e.stderr}")
logger.error(f" Error: {e.stderr}")
all_checks_passed = False
print()
print("=" * 40)
logger.info("")
logger.info("=" * 40)
if all_checks_passed:
print(f"{Colors.GREEN}✓ All checks passed!{Colors.NC}")
print()
print("Your MCP server is ready to use.")
print()
print(f"{Colors.BLUE}To start the server:{Colors.NC}")
print(" python -m framework.mcp.agent_builder_server")
print()
print(f"{Colors.BLUE}To use with Claude Desktop:{Colors.NC}")
print(" Add the configuration from .mcp.json to your")
print(" Claude Desktop MCP settings")
logger.info(f"{Colors.GREEN}✓ All checks passed!{Colors.NC}")
logger.info("")
logger.info("Your MCP server is ready to use.")
logger.info("")
logger.info(f"{Colors.BLUE}To start the server:{Colors.NC}")
logger.info(" python -m framework.mcp.agent_builder_server")
logger.info("")
logger.info(f"{Colors.BLUE}To use with Claude Desktop:{Colors.NC}")
logger.info(" Add the configuration from .mcp.json to your")
logger.info(" Claude Desktop MCP settings")
else:
print(f"{Colors.RED}✗ Some checks failed{Colors.NC}")
print()
print("To fix issues, run:")
print(f" python {script_dir / 'setup_mcp.py'}")
print()
logger.info(f"{Colors.RED}✗ Some checks failed{Colors.NC}")
logger.info("")
logger.info("To fix issues, run:")
logger.info(f" python {script_dir / 'setup_mcp.py'}")
logger.info("")
if __name__ == "__main__":
+29 -10
View File
@@ -26,27 +26,46 @@ Note:
See aden_tools.credentials for details.
"""
import argparse
import logging
import os
import sys
logger = logging.getLogger(__name__)
def setup_logger():
"""Configure logger for MCP server."""
if not logger.handlers:
# For STDIO mode, log to stderr; for HTTP mode, log to stdout
stream = sys.stderr if "--stdio" in sys.argv else sys.stdout
handler = logging.StreamHandler(stream)
formatter = logging.Formatter("[MCP] %(message)s")
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
setup_logger()
# Suppress FastMCP banner in STDIO mode
if "--stdio" in sys.argv:
# Monkey-patch rich Console to redirect to stderr
import rich.console
_original_console_init = rich.console.Console.__init__
def _patched_console_init(self, *args, **kwargs):
kwargs['file'] = sys.stderr # Force all rich output to stderr
kwargs["file"] = sys.stderr # Force all rich output to stderr
_original_console_init(self, *args, **kwargs)
rich.console.Console.__init__ = _patched_console_init
from fastmcp import FastMCP
from starlette.requests import Request
from starlette.responses import PlainTextResponse
from fastmcp import FastMCP # noqa: E402
from starlette.requests import Request # noqa: E402
from starlette.responses import PlainTextResponse # noqa: E402
from aden_tools.credentials import CredentialManager, CredentialError
from aden_tools.tools import register_all_tools
from aden_tools.credentials import CredentialError, CredentialManager # noqa: E402
from aden_tools.tools import register_all_tools # noqa: E402
# Create credential manager
credentials = CredentialManager()
@@ -54,10 +73,10 @@ credentials = CredentialManager()
# Tier 1: Validate startup-required credentials (if any)
try:
credentials.validate_startup()
print("[MCP] Startup credentials validated")
logger.info("Startup credentials validated")
except CredentialError as e:
# Non-fatal - tools will validate their own credentials when called
print(f"[MCP] Warning: {e}", file=sys.stderr)
logger.warning(str(e))
mcp = FastMCP("tools")
@@ -65,7 +84,7 @@ mcp = FastMCP("tools")
tools = register_all_tools(mcp, credentials=credentials)
# Only print to stdout in HTTP mode (STDIO mode requires clean stdout for JSON-RPC)
if "--stdio" not in sys.argv:
print(f"[MCP] Registered {len(tools)} tools: {tools}")
logger.info(f"Registered {len(tools)} tools: {tools}")
@mcp.custom_route("/health", methods=["GET"])
@@ -105,7 +124,7 @@ def main() -> None:
# STDIO mode: only JSON-RPC messages go to stdout
mcp.run(transport="stdio")
else:
print(f"[MCP] Starting HTTP server on {args.host}:{args.port}")
logger.info(f"Starting HTTP server on {args.host}:{args.port}")
mcp.run(transport="http", host=args.host, port=args.port)