cli.py•6.55 kB
#!/usr/bin/env python3
"""
CLI for running the Resemble AI MCP server.
This module provides a command-line interface for starting the server
with different implementations: MCP SDK, direct HTTP, or SDK-based.
Usage:
python -m src.cli [options]
Options:
--implementation IMPL Server implementation to use: mcp, http, direct, sdk, stdio, auto [default: auto]
--port PORT Port to run the server on [default: 8083]
--host HOST Host to bind the server to [default: 0.0.0.0]
"""
import argparse
import logging
import os
import sys
from pathlib import Path
import importlib
from typing import Optional
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='[%(levelname)s] %(asctime)s - %(message)s',
datefmt='%Y-%m-%d %H:%M:%S'
)
logger = logging.getLogger("resemble-cli")
def import_module_safely(module_name: str) -> Optional[object]:
"""
Import a module safely, returning None if it fails.
Args:
module_name: The name of the module to import
Returns:
The imported module or None if import failed
"""
try:
return importlib.import_module(module_name)
except ImportError as e:
logger.error(f"Failed to import {module_name}: {str(e)}")
return None
except Exception as e:
logger.error(f"Error importing {module_name}: {str(e)}")
return None
def main():
parser = argparse.ArgumentParser(description="Resemble AI MCP Server")
parser.add_argument(
"--implementation",
choices=["mcp", "http", "direct", "sdk", "stdio", "auto"],
default="auto",
help="Server implementation to use: auto (try in order), mcp (MCP SDK with SSE), stdio (MCP SDK with StdIO), http (FastAPI), direct (direct API calls), sdk (Resemble SDK)"
)
parser.add_argument(
"--port",
type=int,
default=8083,
help="Port to run the server on"
)
parser.add_argument(
"--host",
default="0.0.0.0",
help="Host to bind the server to"
)
args = parser.parse_args()
# Ensure we're running from the project root directory
project_root = Path(__file__).parent.parent
os.chdir(project_root)
implementation = args.implementation
# If auto mode, try implementations in order of preference
if implementation == "auto":
# Check if MCP SDK is available
mcp_module = import_module_safely("mcp.server")
if mcp_module:
logger.info("MCP SDK found, using MCP implementation")
implementation = "mcp"
else:
logger.warning("MCP SDK not found, falling back to HTTP implementation")
implementation = "http"
# Start the appropriate server implementation
try:
if implementation == "mcp":
logger.info(f"Starting MCP SDK server on {args.host}:{args.port}")
try:
# Import the MCP server module
mcp_server = import_module_safely("src.resemble_mcp_server")
if mcp_server and hasattr(mcp_server, "start_server"):
mcp_server.start_server(host=args.host, port=args.port)
else:
logger.error("Failed to import MCP server module. Falling back to HTTP implementation.")
# Fall back to HTTP implementation
http_server = import_module_safely("src.resemble_http_server")
if http_server and hasattr(http_server, "start_server"):
http_server.start_server(host=args.host, port=args.port)
else:
logger.error("Both MCP and HTTP server implementations failed.")
sys.exit(1)
except ImportError as e:
logger.error(f"Failed to import MCP server: {str(e)}")
logger.error("Falling back to HTTP implementation.")
# Fall back to HTTP implementation
http_server = import_module_safely("src.resemble_http_server")
if http_server and hasattr(http_server, "start_server"):
http_server.start_server(host=args.host, port=args.port)
else:
logger.error("Both MCP and HTTP server implementations failed.")
sys.exit(1)
elif implementation == "http":
logger.info(f"Starting HTTP server on {args.host}:{args.port}")
http_server = import_module_safely("src.resemble_http_server")
if http_server and hasattr(http_server, "start_server"):
http_server.start_server(host=args.host, port=args.port)
else:
logger.error("This implementation doesn't support the start_server method")
sys.exit(1)
elif implementation == "direct":
logger.info(f"Starting direct API server on {args.host}:{args.port}")
direct_server = import_module_safely("src.resemble_ai_server")
if hasattr(direct_server, "start_server"):
direct_server.start_server(host=args.host, port=args.port)
else:
logger.error("This implementation doesn't support the start_server method")
sys.exit(1)
elif implementation == "sdk":
logger.info(f"Starting SDK server on {args.host}:{args.port}")
sdk_server = import_module_safely("src.resemble_ai_sdk_server")
if hasattr(sdk_server, "start_server"):
sdk_server.start_server(host=args.host, port=args.port)
else:
logger.error("This implementation doesn't support the start_server method")
sys.exit(1)
elif implementation == "stdio":
logger.info("Starting StdIO server")
stdio_server = import_module_safely("src.resemble_stdio_server")
if stdio_server and hasattr(stdio_server, "start_server"):
stdio_server.start_server()
else:
logger.error("StdIO implementation not available")
sys.exit(1)
else:
logger.error(f"Unknown implementation: {implementation}")
sys.exit(1)
except Exception as e:
logger.error(f"Error starting server: {str(e)}")
logger.exception(e)
sys.exit(1)
if __name__ == "__main__":
main()