@@ -9,10 +9,9 @@ import (
9
9
10
10
"github.com/spf13/cobra"
11
11
12
+ "github.com/StacklokLabs/toolhive/pkg/api"
13
+ "github.com/StacklokLabs/toolhive/pkg/api/factory"
12
14
"github.com/StacklokLabs/toolhive/pkg/client"
13
- "github.com/StacklokLabs/toolhive/pkg/container"
14
- rt "github.com/StacklokLabs/toolhive/pkg/container/runtime"
15
- "github.com/StacklokLabs/toolhive/pkg/labels"
16
15
"github.com/StacklokLabs/toolhive/pkg/logger"
17
16
)
18
17
@@ -34,14 +33,13 @@ const (
34
33
unknownTransport = "unknown"
35
34
)
36
35
37
- // ContainerOutput represents container information for JSON output
38
- type ContainerOutput struct {
36
+ // ServerOutput represents server information for JSON output
37
+ type ServerOutput struct {
39
38
ID string `json:"id"`
40
39
Name string `json:"name"`
41
40
Image string `json:"image"`
42
41
State string `json:"state"`
43
42
Transport string `json:"transport"`
44
- ToolType string `json:"tool_type,omitempty"`
45
43
Port int `json:"port"`
46
44
URL string `json:"url"`
47
45
}
@@ -51,106 +49,93 @@ func init() {
51
49
listCmd .Flags ().StringVar (& listFormat , "format" , "text" , "Output format (json, text, or mcpservers)" )
52
50
}
53
51
54
- func listCmdFunc (_ * cobra.Command , _ []string ) error {
52
+ func listCmdFunc (cmd * cobra.Command , _ []string ) error {
55
53
// Create context
56
54
ctx , cancel := context .WithCancel (context .Background ())
57
55
defer cancel ()
58
56
59
- // Create container runtime
60
- runtime , err := container .NewFactory ().Create (ctx )
57
+ // Get debug mode flag
58
+ debugMode , _ := cmd .Flags ().GetBool ("debug" )
59
+
60
+ // Create API client factory
61
+ apiFactory , err := factory .New (
62
+ factory .WithClientType (factory .LocalClientType ),
63
+ factory .WithDebug (debugMode ),
64
+ )
61
65
if err != nil {
62
- return fmt .Errorf ("failed to create container runtime : %v" , err )
66
+ return fmt .Errorf ("failed to create API client factory : %v" , err )
63
67
}
64
68
65
- // List containers
66
- containers , err := runtime . ListContainers (ctx )
69
+ // Create API client
70
+ apiClient , err := apiFactory . Create (ctx )
67
71
if err != nil {
68
- return fmt .Errorf ("failed to list containers : %v" , err )
72
+ return fmt .Errorf ("failed to create API client : %v" , err )
69
73
}
74
+ defer apiClient .Close ()
70
75
71
- // Filter containers to only show those managed by ToolHive
72
- var toolHiveContainers []rt. ContainerInfo
73
- for _ , c := range containers {
74
- if labels . IsToolHiveContainer ( c . Labels ) {
75
- toolHiveContainers = append ( toolHiveContainers , c )
76
- }
76
+ // Create list options
77
+ listOpts := & api. ListOptions {
78
+ Status : "running" ,
79
+ }
80
+ if listAll {
81
+ listOpts . Status = "all"
77
82
}
78
83
79
- // Filter containers if not showing all
80
- if ! listAll {
81
- var runningContainers []rt.ContainerInfo
82
- for _ , c := range toolHiveContainers {
83
- if c .State == "running" {
84
- runningContainers = append (runningContainers , c )
85
- }
86
- }
87
- toolHiveContainers = runningContainers
84
+ // List servers
85
+ servers , err := apiClient .Server ().List (ctx , listOpts )
86
+ if err != nil {
87
+ return fmt .Errorf ("failed to list servers: %v" , err )
88
88
}
89
89
90
- if len (toolHiveContainers ) == 0 {
91
- logger .Log .Infof ("No MCP servers found" )
90
+ if len (servers ) == 0 {
91
+ if listAll {
92
+ fmt .Printf ("No MCP servers found\n " )
93
+ } else {
94
+ fmt .Printf ("No running MCP servers found\n " )
95
+ }
92
96
return nil
93
97
}
94
98
95
99
// Output based on format
96
100
switch listFormat {
97
101
//nolint:goconst
98
102
case "json" :
99
- return printJSONOutput (toolHiveContainers )
103
+ return printJSONOutput (servers )
100
104
case "mcpservers" :
101
- return printMCPServersOutput (toolHiveContainers )
105
+ return printMCPServersOutput (servers )
102
106
default :
103
- printTextOutput (toolHiveContainers )
107
+ printTextOutput (servers )
104
108
return nil
105
109
}
106
110
}
107
111
108
- // printJSONOutput prints container information in JSON format
109
- func printJSONOutput (containers []rt. ContainerInfo ) error {
110
- var output []ContainerOutput
112
+ // printJSONOutput prints server information in JSON format
113
+ func printJSONOutput (servers []* api. Server ) error {
114
+ var output []ServerOutput
111
115
112
- for _ , c := range containers {
116
+ for _ , s := range servers {
113
117
// Truncate container ID to first 12 characters (similar to Docker)
114
- truncatedID := c . ID
118
+ truncatedID := s . ContainerID
115
119
if len (truncatedID ) > 12 {
116
120
truncatedID = truncatedID [:12 ]
117
121
}
118
122
119
- // Get container name from labels
120
- name := labels .GetContainerName (c .Labels )
121
- if name == "" {
122
- name = c .Name // Fallback to container name
123
- }
124
-
125
- // Get transport type from labels
126
- transport := labels .GetTransportType (c .Labels )
127
- if transport == "" {
128
- transport = unknownTransport
129
- }
130
-
131
- // Get tool type from labels
132
- toolType := labels .GetToolType (c .Labels )
133
-
134
- // Get port from labels
135
- port , err := labels .GetPort (c .Labels )
136
- if err != nil {
137
- port = 0
138
- }
123
+ // Get state from status
124
+ state := string (s .Status )
139
125
140
126
// Generate URL for the MCP server
141
127
url := ""
142
- if port > 0 {
143
- url = client .GenerateMCPServerURL (defaultHost , port , name )
128
+ if s . HostPort > 0 {
129
+ url = client .GenerateMCPServerURL (defaultHost , s . HostPort , s . Name )
144
130
}
145
131
146
- output = append (output , ContainerOutput {
132
+ output = append (output , ServerOutput {
147
133
ID : truncatedID ,
148
- Name : name ,
149
- Image : c .Image ,
150
- State : c .State ,
151
- Transport : transport ,
152
- ToolType : toolType ,
153
- Port : port ,
134
+ Name : s .Name ,
135
+ Image : s .Image ,
136
+ State : state ,
137
+ Transport : s .Transport ,
138
+ Port : s .HostPort ,
154
139
URL : url ,
155
140
})
156
141
}
@@ -168,39 +153,24 @@ func printJSONOutput(containers []rt.ContainerInfo) error {
168
153
169
154
// printMCPServersOutput prints MCP servers configuration in JSON format
170
155
// This format is compatible with client configuration files
171
- func printMCPServersOutput (containers []rt. ContainerInfo ) error {
156
+ func printMCPServersOutput (servers []* api. Server ) error {
172
157
// Create a map to hold the MCP servers configuration
173
158
mcpServers := make (map [string ]map [string ]string )
174
159
175
- for _ , c := range containers {
176
- // Get container name from labels
177
- name := labels .GetContainerName (c .Labels )
178
- if name == "" {
179
- name = c .Name // Fallback to container name
180
- }
181
-
182
- // Get tool type from labels
183
- toolType := labels .GetToolType (c .Labels )
184
-
185
- // Only include containers with tool type "mcp"
186
- if toolType != "mcp" {
160
+ for _ , s := range servers {
161
+ // Only include running servers
162
+ if s .Status != api .ServerStatusRunning {
187
163
continue
188
164
}
189
165
190
- // Get port from labels
191
- port , err := labels .GetPort (c .Labels )
192
- if err != nil {
193
- port = 0
194
- }
195
-
196
166
// Generate URL for the MCP server
197
167
url := ""
198
- if port > 0 {
199
- url = client .GenerateMCPServerURL (defaultHost , port , name )
168
+ if s . HostPort > 0 {
169
+ url = client .GenerateMCPServerURL (defaultHost , s . HostPort , s . Name )
200
170
}
201
171
202
172
// Add the MCP server to the map
203
- mcpServers [name ] = map [string ]string {
173
+ mcpServers [s . Name ] = map [string ]string {
204
174
"url" : url ,
205
175
}
206
176
}
@@ -218,52 +188,37 @@ func printMCPServersOutput(containers []rt.ContainerInfo) error {
218
188
return nil
219
189
}
220
190
221
- // printTextOutput prints container information in text format
222
- func printTextOutput (containers []rt. ContainerInfo ) {
191
+ // printTextOutput prints server information in text format
192
+ func printTextOutput (servers []* api. Server ) {
223
193
// Create a tabwriter for pretty output
224
194
w := tabwriter .NewWriter (os .Stdout , 0 , 0 , 3 , ' ' , 0 )
225
195
fmt .Fprintln (w , "CONTAINER ID\t NAME\t IMAGE\t STATE\t TRANSPORT\t PORT\t URL" )
226
196
227
- // Print container information
228
- for _ , c := range containers {
197
+ // Print server information
198
+ for _ , s := range servers {
229
199
// Truncate container ID to first 12 characters (similar to Docker)
230
- truncatedID := c . ID
200
+ truncatedID := s . ContainerID
231
201
if len (truncatedID ) > 12 {
232
202
truncatedID = truncatedID [:12 ]
233
203
}
234
204
235
- // Get container name from labels
236
- name := labels .GetContainerName (c .Labels )
237
- if name == "" {
238
- name = c .Name // Fallback to container name
239
- }
240
-
241
- // Get transport type from labels
242
- transport := labels .GetTransportType (c .Labels )
243
- if transport == "" {
244
- transport = unknownTransport
245
- }
246
-
247
- // Get port from labels
248
- port , err := labels .GetPort (c .Labels )
249
- if err != nil {
250
- port = 0
251
- }
205
+ // Get state from status
206
+ state := string (s .Status )
252
207
253
208
// Generate URL for the MCP server
254
209
url := ""
255
- if port > 0 {
256
- url = client .GenerateMCPServerURL (defaultHost , port , name )
210
+ if s . HostPort > 0 {
211
+ url = client .GenerateMCPServerURL (defaultHost , s . HostPort , s . Name )
257
212
}
258
213
259
- // Print container information
214
+ // Print server information
260
215
fmt .Fprintf (w , "%s\t %s\t %s\t %s\t %s\t %d\t %s\n " ,
261
216
truncatedID ,
262
- name ,
263
- c .Image ,
264
- c . State ,
265
- transport ,
266
- port ,
217
+ s . Name ,
218
+ s .Image ,
219
+ state ,
220
+ s . Transport ,
221
+ s . HostPort ,
267
222
url ,
268
223
)
269
224
}
0 commit comments