@@ -1745,39 +1745,234 @@ async def run_tool_from_cli(args):
17451745 sys .exit (1 )
17461746
17471747
1748+ async def run_tool_from_cli_enhanced (
1749+ spec_source : str ,
1750+ output_name : str | None = None ,
1751+ auth_enabled : bool = True ,
1752+ webhooks_enabled : bool = True ,
1753+ admin_ui_enabled : bool = True ,
1754+ storage_enabled : bool = True ,
1755+ business_port : int = 8000 ,
1756+ admin_port : int | None = None ,
1757+ ):
1758+ """Enhanced CLI helper with full configuration options."""
1759+ result = await generate_mock_api_tool (
1760+ spec_url_or_path = spec_source ,
1761+ output_dir_name = output_name ,
1762+ auth_enabled = auth_enabled ,
1763+ webhooks_enabled = webhooks_enabled ,
1764+ admin_ui_enabled = admin_ui_enabled ,
1765+ storage_enabled = storage_enabled ,
1766+ business_port = business_port ,
1767+ admin_port = admin_port ,
1768+ )
1769+ print (result )
1770+
1771+ if "Error" in result :
1772+ sys .exit (1 )
1773+
1774+
17481775def main_cli ():
1776+ # Handle imports for different execution contexts
1777+ if __package__ is None or __package__ == "" :
1778+ from __init__ import __version__
1779+ else :
1780+ from . import __version__
1781+
17491782 parser = argparse .ArgumentParser (
1750- description = "MockLoop API Mock Generator (CLI Test Utility for Tool Logic)"
1783+ prog = "mockloop-mcp" ,
1784+ description = "MockLoop MCP Server - Generate and manage mock API servers from specifications" ,
1785+ epilog = "For more information, visit: https://github.com/mockloop/mockloop-mcp" ,
1786+ formatter_class = argparse .RawDescriptionHelpFormatter ,
17511787 )
1788+
1789+ # Add version argument
17521790 parser .add_argument (
1753- "spec_source" , help = "URL or local file path to the API specification."
1791+ "--version" , "-V" ,
1792+ action = "version" ,
1793+ version = f"%(prog)s { __version__ } " ,
1794+ help = "Show version information and exit"
17541795 )
1755- parser .add_argument (
1756- "-o" ,
1757- "--output-name" ,
1758- help = "Optional name for the generated mock server directory." ,
1796+
1797+ # Add mode selection arguments
1798+ mode_group = parser .add_mutually_exclusive_group ()
1799+ mode_group .add_argument (
1800+ "--stdio" ,
1801+ action = "store_true" ,
1802+ help = "Run in stdio mode for MCP client communication"
1803+ )
1804+ mode_group .add_argument (
1805+ "--sse" ,
1806+ action = "store_true" ,
1807+ help = "Run in Server-Sent Events mode (default)"
1808+ )
1809+ mode_group .add_argument (
1810+ "--cli" ,
1811+ action = "store_true" ,
1812+ help = "Run in CLI mode for direct API generation"
1813+ )
1814+
1815+ # CLI-specific arguments (only used when --cli is specified)
1816+ cli_group = parser .add_argument_group ("CLI mode options" )
1817+ cli_group .add_argument (
1818+ "spec_source" ,
1819+ nargs = "?" ,
1820+ help = "URL or local file path to the API specification (required for CLI mode)"
1821+ )
1822+ cli_group .add_argument (
1823+ "-o" , "--output-name" ,
1824+ help = "Optional name for the generated mock server directory" ,
17591825 default = None ,
17601826 )
1761- # output_base_dir is handled by the generator.py, not passed to tool directly
1827+ cli_group .add_argument (
1828+ "--auth-enabled" ,
1829+ action = "store_true" ,
1830+ default = True ,
1831+ help = "Enable authentication middleware (default: enabled)"
1832+ )
1833+ cli_group .add_argument (
1834+ "--no-auth" ,
1835+ action = "store_true" ,
1836+ help = "Disable authentication middleware"
1837+ )
1838+ cli_group .add_argument (
1839+ "--webhooks-enabled" ,
1840+ action = "store_true" ,
1841+ default = True ,
1842+ help = "Enable webhook support (default: enabled)"
1843+ )
1844+ cli_group .add_argument (
1845+ "--no-webhooks" ,
1846+ action = "store_true" ,
1847+ help = "Disable webhook support"
1848+ )
1849+ cli_group .add_argument (
1850+ "--admin-ui-enabled" ,
1851+ action = "store_true" ,
1852+ default = True ,
1853+ help = "Enable admin UI (default: enabled)"
1854+ )
1855+ cli_group .add_argument (
1856+ "--no-admin-ui" ,
1857+ action = "store_true" ,
1858+ help = "Disable admin UI"
1859+ )
1860+ cli_group .add_argument (
1861+ "--storage-enabled" ,
1862+ action = "store_true" ,
1863+ default = True ,
1864+ help = "Enable storage functionality (default: enabled)"
1865+ )
1866+ cli_group .add_argument (
1867+ "--no-storage" ,
1868+ action = "store_true" ,
1869+ help = "Disable storage functionality"
1870+ )
1871+ cli_group .add_argument (
1872+ "--mock-port" ,
1873+ type = int ,
1874+ default = 8000 ,
1875+ help = "Port for the mock API (default: 8000)"
1876+ )
1877+ cli_group .add_argument (
1878+ "--admin-port" ,
1879+ type = int ,
1880+ help = "Port for the admin API (if different from business port)"
1881+ )
1882+
1883+ # Logging and debug options
1884+ debug_group = parser .add_argument_group ("debug and logging options" )
1885+ debug_group .add_argument (
1886+ "-v" , "--verbose" ,
1887+ action = "store_true" ,
1888+ help = "Enable verbose output"
1889+ )
1890+ debug_group .add_argument (
1891+ "-q" , "--quiet" ,
1892+ action = "store_true" ,
1893+ help = "Suppress non-error output"
1894+ )
1895+ debug_group .add_argument (
1896+ "--log-level" ,
1897+ choices = ["DEBUG" , "INFO" , "WARNING" , "ERROR" , "CRITICAL" ],
1898+ default = "INFO" ,
1899+ help = "Set logging level (default: INFO)"
1900+ )
1901+
17621902 args = parser .parse_args ()
17631903
1764- import asyncio
1904+ # Configure logging based on arguments
1905+ log_level = getattr (logging , args .log_level .upper ())
1906+ if args .verbose :
1907+ log_level = logging .DEBUG
1908+ elif args .quiet :
1909+ log_level = logging .ERROR
1910+
1911+ logging .basicConfig (
1912+ level = log_level ,
1913+ format = "%(asctime)s - %(name)s - %(levelname)s - %(message)s"
1914+ )
1915+
1916+ # Handle CLI mode
1917+ if args .cli or args .spec_source :
1918+ if not args .spec_source :
1919+ parser .error ("spec_source is required when using CLI mode" )
1920+
1921+ # Process boolean flags
1922+ auth_enabled = args .auth_enabled and not args .no_auth
1923+ webhooks_enabled = args .webhooks_enabled and not args .no_webhooks
1924+ admin_ui_enabled = args .admin_ui_enabled and not args .no_admin_ui
1925+ storage_enabled = args .storage_enabled and not args .no_storage
17651926
1766- asyncio .run (run_tool_from_cli (args ))
1927+ import asyncio
1928+ asyncio .run (run_tool_from_cli_enhanced (
1929+ args .spec_source ,
1930+ args .output_name ,
1931+ auth_enabled ,
1932+ webhooks_enabled ,
1933+ admin_ui_enabled ,
1934+ storage_enabled ,
1935+ args .mock_port ,
1936+ args .admin_port
1937+ ))
1938+ else :
1939+ # Default behavior - show help if no mode specified
1940+ parser .print_help ()
1941+ sys .exit (0 )
17671942
17681943
17691944def main ():
17701945 """Main entry point for the mockloop-mcp CLI command."""
17711946 import sys
17721947 import os
17731948
1949+ # Handle version and help early for better UX
1950+ if "--version" in sys .argv or "-V" in sys .argv :
1951+ # Handle imports for different execution contexts
1952+ if __package__ is None or __package__ == "" :
1953+ from __init__ import __version__
1954+ else :
1955+ from . import __version__
1956+ print (f"mockloop-mcp { __version__ } " )
1957+ sys .exit (0 )
1958+
1959+ if "--help" in sys .argv or "-h" in sys .argv :
1960+ main_cli ()
1961+ return
1962+
17741963 # Auto-detect stdio mode when run by Claude or other MCP clients
17751964 # This happens when stdin is not a terminal (piped) and no explicit flags are given
17761965 is_stdin_piped = not sys .stdin .isatty ()
17771966 has_explicit_flags = any (arg .startswith ("-" ) for arg in sys .argv [1 :])
17781967
1779- # Check for explicit --stdio flag or auto-detect stdio mode
1780- if "--stdio" in sys .argv or (is_stdin_piped and not has_explicit_flags ):
1968+ # Check for explicit mode flags
1969+ has_stdio_flag = "--stdio" in sys .argv
1970+ has_sse_flag = "--sse" in sys .argv
1971+ has_cli_flag = "--cli" in sys .argv
1972+ has_positional_args = any (not arg .startswith ("-" ) for arg in sys .argv [1 :])
1973+
1974+ # Determine mode based on flags and context
1975+ if has_stdio_flag or (is_stdin_piped and not has_explicit_flags and not has_positional_args ):
17811976 # Remove --stdio from sys.argv if present
17821977 if "--stdio" in sys .argv :
17831978 sys .argv .remove ("--stdio" )
@@ -1791,13 +1986,18 @@ def main():
17911986
17921987 import asyncio
17931988 asyncio .run (run_stdio_server ())
1794- elif "--cli" in sys .argv :
1795- # Remove --cli from sys.argv so argparse doesn't see it
1796- sys .argv .remove ("--cli" )
1989+ elif has_cli_flag or has_positional_args :
1990+ # CLI mode - either explicit --cli flag or positional arguments provided
17971991 main_cli ()
1798- else :
1799- # Start the MCP server in SSE mode (existing behavior)
1992+ elif has_sse_flag :
1993+ # Remove --sse from sys.argv if present
1994+ if "--sse" in sys .argv :
1995+ sys .argv .remove ("--sse" )
1996+ # Start the MCP server in SSE mode
18001997 server .run ()
1998+ else :
1999+ # Default behavior - show help
2000+ main_cli ()
18012001
18022002
18032003# To run the MCP server:
0 commit comments