Skip to content

Commit 12c2e71

Browse files
authored
Fix no exposed ports specified in options.ExposedPorts bug (#798)
As part of the network isolation changes, an assumption was introduced that all MCP servers have an exposed port. This is not the case for stdio - the proxy runner attaches to a stdio MCP server via the container's stdin/stdout. When the new code was run with a stdio container, the MCP container would run, the proxy runner process would die, and the following error would appear in the logs - `Error: failed to set up transport: failed to create container: no exposed ports specified in options.ExposedPorts.` This PR changes the logic to skip parsing the exposed ports when the transport type is stdio.
1 parent c4eeb5b commit 12c2e71

File tree

1 file changed

+24
-12
lines changed

1 file changed

+24
-12
lines changed

pkg/container/docker/client.go

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -457,21 +457,14 @@ func (c *Client) DeployWorkload(
457457
return "", 0, fmt.Errorf("failed to create mcp container: %v", err)
458458
}
459459

460-
// now create ingress container
461-
var firstPort string
462-
if len(options.ExposedPorts) == 0 {
463-
return "", 0, fmt.Errorf("no exposed ports specified in options.ExposedPorts")
460+
// Don't try and set up an ingress proxy if the transport type is stdio.
461+
if transportType == "stdio" {
462+
return containerId, 0, nil
464463
}
465-
for port := range options.ExposedPorts {
466-
firstPort = port
467464

468-
// need to strip the protocol
469-
firstPort = strings.Split(firstPort, "/")[0]
470-
break // take only the first one
471-
}
472-
firstPortInt, err := strconv.Atoi(firstPort)
465+
firstPortInt, err := extractFirstPort(options)
473466
if err != nil {
474-
return "", 0, fmt.Errorf("failed to convert port %s to int: %v", firstPort, err)
467+
return "", 0, err // extractFirstPort already wraps the error with context.
475468
}
476469

477470
if isolateNetwork {
@@ -484,6 +477,25 @@ func (c *Client) DeployWorkload(
484477
return containerId, firstPortInt, nil
485478
}
486479

480+
func extractFirstPort(options *runtime.DeployWorkloadOptions) (int, error) {
481+
var firstPort string
482+
if len(options.ExposedPorts) == 0 {
483+
return 0, fmt.Errorf("no exposed ports specified in options.ExposedPorts")
484+
}
485+
for port := range options.ExposedPorts {
486+
firstPort = port
487+
488+
// need to strip the protocol
489+
firstPort = strings.Split(firstPort, "/")[0]
490+
break // take only the first one
491+
}
492+
firstPortInt, err := strconv.Atoi(firstPort)
493+
if err != nil {
494+
return 0, fmt.Errorf("failed to convert port %s to int: %v", firstPort, err)
495+
}
496+
return firstPortInt, nil
497+
}
498+
487499
// ListWorkloads lists workloads
488500
func (c *Client) ListWorkloads(ctx context.Context) ([]runtime.ContainerInfo, error) {
489501
// Create filter for toolhive containers

0 commit comments

Comments
 (0)