Skip to content

Commit e74ada1

Browse files
committed
changes from review
1 parent f8c38c6 commit e74ada1

File tree

6 files changed

+121
-114
lines changed

6 files changed

+121
-114
lines changed

cmd/thv/app/list.go

Lines changed: 3 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import (
1010

1111
"github.com/stacklok/toolhive/pkg/core"
1212
"github.com/stacklok/toolhive/pkg/logger"
13-
"github.com/stacklok/toolhive/pkg/transport/types"
1413
"github.com/stacklok/toolhive/pkg/workloads"
1514
)
1615

@@ -109,14 +108,12 @@ func printMCPServersOutput(workloadList []core.Workload) error {
109108
mcpServers := make(map[string]map[string]string)
110109

111110
for _, c := range workloadList {
112-
// Determine the effective transport type to show to users
113-
// This is the transport they actually connect to, not the underlying MCP server transport
114-
effectiveTransport := getEffectiveTransportType(c)
115-
111+
// Use the effective transport type for display - this shows what clients actually connect to
112+
// (e.g., sse/streamable-http for stdio servers with proxy mode)
116113
// Add the MCP server to the map
117114
mcpServers[c.Name] = map[string]string{
118115
"url": c.URL,
119-
"type": effectiveTransport,
116+
"type": c.EffectiveTransportType.String(),
120117
}
121118
}
122119

@@ -162,17 +159,3 @@ func printTextOutput(workloadList []core.Workload) {
162159
logger.Errorf("Warning: Failed to flush tabwriter: %v", err)
163160
}
164161
}
165-
166-
// getEffectiveTransportType determines the effective transport type that clients should use
167-
// This handles the case where stdio MCP servers are proxied through SSE or streamable-http
168-
func getEffectiveTransportType(workload core.Workload) string {
169-
// If the underlying transport is stdio and we have a proxy mode set,
170-
// return the proxy mode as that's what clients actually connect to
171-
if workload.TransportType == types.TransportTypeStdio && workload.ProxyMode != "" {
172-
return workload.ProxyMode
173-
}
174-
175-
// For all other cases (direct sse, streamable-http, or when no proxy mode is set),
176-
// return the transport type directly
177-
return workload.TransportType.String()
178-
}

cmd/thv/app/list_test.go

Lines changed: 0 additions & 70 deletions
This file was deleted.

pkg/core/workload.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ type Workload struct {
2727
ToolType string `json:"tool_type"`
2828
// TransportType is the type of transport used for this workload.
2929
TransportType types.TransportType `json:"transport_type"`
30+
// EffectiveTransportType is the transport type that clients should use to connect.
31+
// For stdio transports with proxy mode, this will be the proxy mode (sse/streamable-http).
32+
// For direct transports, this will be the same as TransportType.
33+
EffectiveTransportType types.TransportType `json:"effective_transport_type"`
3034
// ProxyMode is the proxy mode for stdio transport (sse or streamable-http).
3135
ProxyMode string `json:"proxy_mode,omitempty"`
3236
// Status is the current status of the workload.

pkg/workloads/manager.go

Lines changed: 16 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,20 +1173,24 @@ func (d *defaultManager) getRemoteWorkloadsFromState(
11731173
)
11741174
}
11751175

1176+
// Calculate effective transport type
1177+
effectiveTransportType := types.GetEffectiveTransportType(transportType, string(runConfig.ProxyMode))
1178+
11761179
// Create a workload from the run configuration
11771180
workload := core.Workload{
1178-
Name: name,
1179-
Package: "remote",
1180-
Status: workloadStatus.Status,
1181-
URL: proxyURL,
1182-
Port: runConfig.Port,
1183-
TransportType: transportType,
1184-
ProxyMode: string(runConfig.ProxyMode),
1185-
ToolType: "remote",
1186-
Group: runConfig.Group,
1187-
CreatedAt: workloadStatus.CreatedAt,
1188-
Labels: runConfig.ContainerLabels,
1189-
Remote: true,
1181+
Name: name,
1182+
Package: "remote",
1183+
Status: workloadStatus.Status,
1184+
URL: proxyURL,
1185+
Port: runConfig.Port,
1186+
TransportType: transportType,
1187+
EffectiveTransportType: effectiveTransportType,
1188+
ProxyMode: string(runConfig.ProxyMode),
1189+
ToolType: "remote",
1190+
Group: runConfig.Group,
1191+
CreatedAt: workloadStatus.CreatedAt,
1192+
Labels: runConfig.ContainerLabels,
1193+
Remote: true,
11901194
}
11911195

11921196
// Apply label filtering
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
package types
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/assert"
7+
8+
"github.com/stacklok/toolhive/pkg/transport/types"
9+
)
10+
11+
func TestGetEffectiveTransportType(t *testing.T) {
12+
t.Parallel()
13+
14+
tests := []struct {
15+
name string
16+
transportType types.TransportType
17+
proxyMode string
18+
expectedTransport types.TransportType
19+
}{
20+
{
21+
name: "stdio transport with sse proxy mode should return sse",
22+
transportType: types.TransportTypeStdio,
23+
proxyMode: "sse",
24+
expectedTransport: types.TransportTypeSSE,
25+
},
26+
{
27+
name: "stdio transport with streamable-http proxy mode should return streamable-http",
28+
transportType: types.TransportTypeStdio,
29+
proxyMode: "streamable-http",
30+
expectedTransport: types.TransportTypeStreamableHTTP,
31+
},
32+
{
33+
name: "stdio transport with empty proxy mode should return stdio",
34+
transportType: types.TransportTypeStdio,
35+
proxyMode: "",
36+
expectedTransport: types.TransportTypeStdio,
37+
},
38+
{
39+
name: "sse transport should return sse regardless of proxy mode",
40+
transportType: types.TransportTypeSSE,
41+
proxyMode: "streamable-http", // This shouldn't matter for non-stdio
42+
expectedTransport: types.TransportTypeSSE,
43+
},
44+
{
45+
name: "streamable-http transport should return streamable-http",
46+
transportType: types.TransportTypeStreamableHTTP,
47+
proxyMode: "",
48+
expectedTransport: types.TransportTypeStreamableHTTP,
49+
},
50+
{
51+
name: "stdio transport with invalid proxy mode should return stdio",
52+
transportType: types.TransportTypeStdio,
53+
proxyMode: "invalid-mode",
54+
expectedTransport: types.TransportTypeStdio,
55+
},
56+
}
57+
58+
for _, tt := range tests {
59+
t.Run(tt.name, func(t *testing.T) {
60+
t.Parallel()
61+
62+
result := GetEffectiveTransportType(tt.transportType, tt.proxyMode)
63+
assert.Equal(t, tt.expectedTransport, result, "Effective transport type should match expected")
64+
})
65+
}
66+
}

pkg/workloads/types/types.go

Lines changed: 32 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,39 @@ func WorkloadFromContainerInfo(container *runtime.ContainerInfo) (core.Workload,
9595
return core.Workload{}, err
9696
}
9797

98+
// Calculate effective transport type
99+
effectiveTransportType := GetEffectiveTransportType(tType, runConfig.ProxyMode)
100+
98101
// Translate to the domain model.
99102
return core.Workload{
100-
Name: name, // Use the calculated workload name (base name), not container name
101-
Package: container.Image,
102-
URL: url,
103-
ToolType: toolType,
104-
TransportType: tType,
105-
ProxyMode: runConfig.ProxyMode,
106-
Status: container.State,
107-
StatusContext: container.Status,
108-
CreatedAt: container.Created,
109-
Port: port,
110-
Labels: userLabels,
111-
Group: runConfig.Group,
103+
Name: name, // Use the calculated workload name (base name), not container name
104+
Package: container.Image,
105+
URL: url,
106+
ToolType: toolType,
107+
TransportType: tType,
108+
EffectiveTransportType: effectiveTransportType,
109+
ProxyMode: runConfig.ProxyMode,
110+
Status: container.State,
111+
StatusContext: container.Status,
112+
CreatedAt: container.Created,
113+
Port: port,
114+
Labels: userLabels,
115+
Group: runConfig.Group,
112116
}, nil
113117
}
118+
119+
// GetEffectiveTransportType determines the effective transport type that clients should use
120+
// This handles the case where stdio MCP servers are proxied through SSE or streamable-http
121+
func GetEffectiveTransportType(transportType types.TransportType, proxyMode string) types.TransportType {
122+
// If the underlying transport is stdio and we have a proxy mode set,
123+
// return the proxy mode as that's what clients actually connect to
124+
if transportType == types.TransportTypeStdio && proxyMode != "" {
125+
if proxyType, err := types.ParseTransportType(proxyMode); err == nil {
126+
return proxyType
127+
}
128+
}
129+
130+
// For all other cases (direct sse, streamable-http, or when no proxy mode is set),
131+
// return the transport type directly
132+
return transportType
133+
}

0 commit comments

Comments
 (0)