|
1 | 1 | #!/usr/bin/env python |
2 | 2 | import os |
3 | 3 | import logging |
| 4 | +import socket |
4 | 5 | import sys |
5 | 6 | from contextvars import ContextVar |
6 | 7 | from dataclasses import dataclass |
@@ -38,6 +39,18 @@ def safe_print(text): |
38 | 39 | print(text.encode('ascii', errors='replace').decode(), file=sys.stderr) |
39 | 40 |
|
40 | 41 |
|
| 42 | +def check_port(port): |
| 43 | + # Check port availability before starting HTTP server |
| 44 | + try: |
| 45 | + with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s: |
| 46 | + s.bind(('', port)) |
| 47 | + except OSError as e: |
| 48 | + safe_print(f"Socket error: {e}") |
| 49 | + safe_print( |
| 50 | + f"Port {port} is already in use. Cannot start HTTP server.") |
| 51 | + sys.exit(1) |
| 52 | + |
| 53 | + |
41 | 54 | dotenv.load_dotenv() |
42 | 55 | mcp = FastMCP("Alertmanager MCP") |
43 | 56 |
|
@@ -756,13 +769,19 @@ def run_server(): |
756 | 769 |
|
757 | 770 | # Launch the server with the selected transport mode |
758 | 771 | if args.transport == 'sse': |
| 772 | + # Check port availability before starting HTTP server |
| 773 | + check_port(args.port) |
| 774 | + |
759 | 775 | safe_print("Running server with SSE transport (web-based)") |
760 | 776 | # Run with SSE transport (web-based) |
761 | 777 | # Create a Starlette app to serve the MCP server |
762 | 778 | starlette_app = create_starlette_app(mcp_server, debug=True) |
763 | 779 | # Start the web server with the configured host and port |
764 | 780 | uvicorn.run(starlette_app, host=args.host, port=args.port) |
765 | 781 | elif args.transport == 'http': |
| 782 | + # Check port availability before starting HTTP server |
| 783 | + check_port(args.port) |
| 784 | + |
766 | 785 | safe_print("Running server with http transport (streamable HTTP)") |
767 | 786 | # Run with streamable-http transport served by uvicorn so host/port |
768 | 787 | # CLI/env variables control the listening socket (same pattern as SSE). |
|
0 commit comments