diff --git a/molecule_runtime/a2a_mcp_server.py b/molecule_runtime/a2a_mcp_server.py index 33d93a7..c61f752 100644 --- a/molecule_runtime/a2a_mcp_server.py +++ b/molecule_runtime/a2a_mcp_server.py @@ -406,6 +406,7 @@ async def _handle_http_mcp(request) -> dict | None: async def _run_http_server(port: int): """Run MCP server over HTTP/SSE — compatible with Hermes MCP-native agents.""" try: + import uvicorn from starlette.applications import Starlette from starlette.routing import Route from starlette.responses import JSONResponse, Response @@ -480,8 +481,25 @@ async def _run_http_server(port: int): await server.serve() -async def main(): # pragma: no cover - """Entry point — select transport from CLI args or default to stdio.""" +async def main(transport: str = "stdio", port: int = 9100): # pragma: no cover + """Run the MCP server with the given transport and port.""" + if transport == "http": + await _run_http_server(port) + else: + await _handle_stdio() + + +if __name__ == "__main__" or ( + __spec__ is not None + and _os.path.basename(sys.argv[0]) == _os.path.basename(__spec__.origin) +): + # Fires for: + # python a2a_mcp_server.py → __name__ == "__main__" + # python -m molecule_runtime.a2a_mcp_server → sys.argv[0] = module path + # Does NOT fire for: + # import molecule_runtime.a2a_mcp_server (pytest or otherwise) + # → sys.argv[0] is the outer runner (pytest, python -c, etc.) + # → os.path.basename(sys.argv[0]) != os.path.basename(__spec__.origin) parser = argparse.ArgumentParser(description="A2A MCP Server") parser.add_argument( "--transport", @@ -496,12 +514,4 @@ async def main(): # pragma: no cover help="TCP port for HTTP transport (default 9100)", ) args = parser.parse_args() - - if args.transport == "http": - await _run_http_server(args.port) - else: - await _handle_stdio() - - -if __name__ == "__main__": # pragma: no cover - asyncio.run(main()) + asyncio.run(main(transport=args.transport, port=args.port))