Skip to content

Commit c24d241

Browse files
author
User
committed
Update share.py
1 parent 54257ee commit c24d241

File tree

1 file changed

+77
-76
lines changed

1 file changed

+77
-76
lines changed

src/mcpm/commands/share.py

Lines changed: 77 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,80 @@ def make_non_blocking(file_obj):
3636
fcntl.fcntl(fd, fcntl.F_SETFL, fl | os.O_NONBLOCK)
3737

3838

39+
def wait_for_random_port(process: subprocess.Popen, timeout: int = 20) -> Optional[int]:
40+
"""
41+
Wait for mcp-proxy to output the random port information.
42+
43+
Args:
44+
process: The mcp-proxy process
45+
timeout: Maximum time to wait in seconds
46+
47+
Returns:
48+
The detected port number or None if not found
49+
"""
50+
console.print("[cyan]Waiting for mcp-proxy to start...[/]")
51+
52+
# Wait for mcp-proxy to output the port information
53+
start_time = time.time()
54+
port_found = False
55+
actual_port = None
56+
57+
# Port detection loop
58+
while time.time() - start_time < timeout and not port_found:
59+
# Check if process is still running
60+
if process.poll() is not None:
61+
# Process terminated prematurely
62+
stderr_output = ""
63+
try:
64+
if process.stderr:
65+
stderr_output = process.stderr.read() or ""
66+
except (IOError, OSError):
67+
pass
68+
69+
console.print("[bold red]Error:[/] mcp-proxy terminated unexpectedly")
70+
console.print(f"[red]Error output:[/]\n{stderr_output}")
71+
sys.exit(1)
72+
73+
# Use select to wait for data to be available without blocking
74+
readable = []
75+
if process.stdout:
76+
readable.append(process.stdout)
77+
if process.stderr:
78+
readable.append(process.stderr)
79+
80+
if readable:
81+
# Wait for up to 1 second for output
82+
r, _, _ = select.select(readable, [], [], 1.0)
83+
84+
# Process available output
85+
for stream in r:
86+
try:
87+
line = stream.readline()
88+
if line:
89+
print(line.rstrip())
90+
91+
# Check for port information
92+
if "Uvicorn running on http://" in line:
93+
try:
94+
url_part = line.split("Uvicorn running on ")[1].split(" ")[0]
95+
actual_port = int(url_part.split(":")[-1].strip())
96+
port_found = True
97+
console.print(
98+
f"[cyan]mcp-proxy SSE server running on port [bold]{actual_port}[/bold][/]"
99+
)
100+
break
101+
except (ValueError, IndexError):
102+
pass
103+
except (IOError, OSError):
104+
# Resource temporarily unavailable - this is normal for non-blocking IO
105+
pass
106+
else:
107+
# No streams to read from, just wait a bit
108+
time.sleep(0.5)
109+
110+
return actual_port
111+
112+
39113
def start_mcp_proxy(command: str, port: Optional[int] = None) -> Tuple[subprocess.Popen, int]:
40114
"""
41115
Start mcp-proxy to convert a stdio MCP server to an SSE server.
@@ -79,87 +153,14 @@ def start_mcp_proxy(command: str, port: Optional[int] = None) -> Tuple[subproces
79153
# If port is None, we need to parse the output to find the random port
80154
actual_port = port
81155
if not actual_port:
82-
console.print("[cyan]Waiting for mcp-proxy to start...[/]")
83-
84-
# Wait for mcp-proxy to output the port information
85-
start_time = time.time()
86-
port_found = False
87-
timeout = 20 # Allow more time (20 seconds) for the server to start
156+
actual_port = wait_for_random_port(process)
88157

89-
# Port detection loop
90-
while time.time() - start_time < timeout and not port_found:
91-
# Check if process is still running
92-
if process.poll() is not None:
93-
# Process terminated prematurely
94-
stderr_output = ""
95-
try:
96-
if process.stderr:
97-
stderr_output = process.stderr.read() or ""
98-
except (IOError, OSError):
99-
pass
100-
101-
console.print("[bold red]Error:[/] mcp-proxy terminated unexpectedly")
102-
console.print(f"[red]Error output:[/]\n{stderr_output}")
103-
sys.exit(1)
104-
105-
# Use select to wait for data to be available without blocking
106-
readable = []
107-
if process.stdout:
108-
readable.append(process.stdout)
109-
if process.stderr:
110-
readable.append(process.stderr)
111-
112-
if readable:
113-
# Wait for up to 1 second for output
114-
r, _, _ = select.select(readable, [], [], 1.0)
115-
116-
# Process available output
117-
for stream in r:
118-
try:
119-
line = stream.readline()
120-
if line:
121-
print(line.rstrip())
122-
123-
# Check for port information
124-
if "Serving on" in line:
125-
try:
126-
actual_port = int(line.split(":")[-1].strip())
127-
port_found = True
128-
console.print(
129-
f"[cyan]mcp-proxy SSE server running on port [bold]{actual_port}[/bold][/]"
130-
)
131-
break
132-
except (ValueError, IndexError):
133-
pass
134-
elif "Uvicorn running on http://" in line:
135-
try:
136-
url_part = line.split("Uvicorn running on ")[1].split(" ")[0]
137-
actual_port = int(url_part.split(":")[-1].strip())
138-
port_found = True
139-
console.print(
140-
f"[cyan]mcp-proxy SSE server running on port [bold]{actual_port}[/bold][/]"
141-
)
142-
break
143-
except (ValueError, IndexError):
144-
pass
145-
except (IOError, OSError):
146-
# Resource temporarily unavailable - this is normal for non-blocking IO
147-
pass
148-
else:
149-
# No streams to read from, just wait a bit
150-
time.sleep(0.5)
151-
152-
# After the loop, check if we found the port
153-
if not port_found and not actual_port:
158+
# Check if we found the port
159+
if not actual_port:
154160
console.print("[bold red]Error:[/] Could not determine the port mcp-proxy is running on")
155161
process.terminate()
156162
sys.exit(1)
157163

158-
if not actual_port:
159-
console.print("[bold red]Error:[/] Could not determine the port mcp-proxy is running on")
160-
process.terminate()
161-
sys.exit(1)
162-
163164
return process, actual_port
164165

165166

0 commit comments

Comments
 (0)