Skip to content

Commit 45c0c61

Browse files
committed
Implement commands using new client/server interface
Signed-off-by: Juan Antonio Osorio <[email protected]>
1 parent aaa3caa commit 45c0c61

19 files changed

+1685
-470
lines changed

cmd/thv/app/config.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66

77
"github.com/spf13/cobra"
88

9+
"github.com/StacklokLabs/toolhive/pkg/api"
910
"github.com/StacklokLabs/toolhive/pkg/client"
1011
"github.com/StacklokLabs/toolhive/pkg/config"
1112
"github.com/StacklokLabs/toolhive/pkg/container"
@@ -240,7 +241,7 @@ func addRunningMCPsToClient(clientName string) error {
240241
// Filter containers to only show those managed by ToolHive and running
241242
var runningContainers []rt.ContainerInfo
242243
for _, c := range containers {
243-
if labels.IsToolHiveContainer(c.Labels) && c.State == "running" {
244+
if labels.IsToolHiveContainer(c.Labels) && c.State == string(api.ServerStatusRunning) {
244245
runningContainers = append(runningContainers, c)
245246
}
246247
}

cmd/thv/app/list.go

+74-119
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,9 @@ import (
99

1010
"github.com/spf13/cobra"
1111

12+
"github.com/StacklokLabs/toolhive/pkg/api"
13+
"github.com/StacklokLabs/toolhive/pkg/api/factory"
1214
"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"
1615
"github.com/StacklokLabs/toolhive/pkg/logger"
1716
)
1817

@@ -34,14 +33,13 @@ const (
3433
unknownTransport = "unknown"
3534
)
3635

37-
// ContainerOutput represents container information for JSON output
38-
type ContainerOutput struct {
36+
// ServerOutput represents server information for JSON output
37+
type ServerOutput struct {
3938
ID string `json:"id"`
4039
Name string `json:"name"`
4140
Image string `json:"image"`
4241
State string `json:"state"`
4342
Transport string `json:"transport"`
44-
ToolType string `json:"tool_type,omitempty"`
4543
Port int `json:"port"`
4644
URL string `json:"url"`
4745
}
@@ -51,106 +49,93 @@ func init() {
5149
listCmd.Flags().StringVar(&listFormat, "format", "text", "Output format (json, text, or mcpservers)")
5250
}
5351

54-
func listCmdFunc(_ *cobra.Command, _ []string) error {
52+
func listCmdFunc(cmd *cobra.Command, _ []string) error {
5553
// Create context
5654
ctx, cancel := context.WithCancel(context.Background())
5755
defer cancel()
5856

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+
)
6165
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)
6367
}
6468

65-
// List containers
66-
containers, err := runtime.ListContainers(ctx)
69+
// Create API client
70+
apiClient, err := apiFactory.Create(ctx)
6771
if err != nil {
68-
return fmt.Errorf("failed to list containers: %v", err)
72+
return fmt.Errorf("failed to create API client: %v", err)
6973
}
74+
defer apiClient.Close()
7075

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"
7782
}
7883

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)
8888
}
8989

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+
}
9296
return nil
9397
}
9498

9599
// Output based on format
96100
switch listFormat {
97101
//nolint:goconst
98102
case "json":
99-
return printJSONOutput(toolHiveContainers)
103+
return printJSONOutput(servers)
100104
case "mcpservers":
101-
return printMCPServersOutput(toolHiveContainers)
105+
return printMCPServersOutput(servers)
102106
default:
103-
printTextOutput(toolHiveContainers)
107+
printTextOutput(servers)
104108
return nil
105109
}
106110
}
107111

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
111115

112-
for _, c := range containers {
116+
for _, s := range servers {
113117
// Truncate container ID to first 12 characters (similar to Docker)
114-
truncatedID := c.ID
118+
truncatedID := s.ContainerID
115119
if len(truncatedID) > 12 {
116120
truncatedID = truncatedID[:12]
117121
}
118122

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)
139125

140126
// Generate URL for the MCP server
141127
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)
144130
}
145131

146-
output = append(output, ContainerOutput{
132+
output = append(output, ServerOutput{
147133
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,
154139
URL: url,
155140
})
156141
}
@@ -168,39 +153,24 @@ func printJSONOutput(containers []rt.ContainerInfo) error {
168153

169154
// printMCPServersOutput prints MCP servers configuration in JSON format
170155
// This format is compatible with client configuration files
171-
func printMCPServersOutput(containers []rt.ContainerInfo) error {
156+
func printMCPServersOutput(servers []*api.Server) error {
172157
// Create a map to hold the MCP servers configuration
173158
mcpServers := make(map[string]map[string]string)
174159

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 {
187163
continue
188164
}
189165

190-
// Get port from labels
191-
port, err := labels.GetPort(c.Labels)
192-
if err != nil {
193-
port = 0
194-
}
195-
196166
// Generate URL for the MCP server
197167
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)
200170
}
201171

202172
// Add the MCP server to the map
203-
mcpServers[name] = map[string]string{
173+
mcpServers[s.Name] = map[string]string{
204174
"url": url,
205175
}
206176
}
@@ -218,52 +188,37 @@ func printMCPServersOutput(containers []rt.ContainerInfo) error {
218188
return nil
219189
}
220190

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) {
223193
// Create a tabwriter for pretty output
224194
w := tabwriter.NewWriter(os.Stdout, 0, 0, 3, ' ', 0)
225195
fmt.Fprintln(w, "CONTAINER ID\tNAME\tIMAGE\tSTATE\tTRANSPORT\tPORT\tURL")
226196

227-
// Print container information
228-
for _, c := range containers {
197+
// Print server information
198+
for _, s := range servers {
229199
// Truncate container ID to first 12 characters (similar to Docker)
230-
truncatedID := c.ID
200+
truncatedID := s.ContainerID
231201
if len(truncatedID) > 12 {
232202
truncatedID = truncatedID[:12]
233203
}
234204

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)
252207

253208
// Generate URL for the MCP server
254209
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)
257212
}
258213

259-
// Print container information
214+
// Print server information
260215
fmt.Fprintf(w, "%s\t%s\t%s\t%s\t%s\t%d\t%s\n",
261216
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,
267222
url,
268223
)
269224
}

cmd/thv/app/registry.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ func registryListCmdFunc(_ *cobra.Command, _ []string) error {
6666

6767
// Output based on format
6868
switch registryFormat {
69-
case "json":
69+
case FormatJSON:
7070
return printJSONServers(servers)
7171
default:
7272
printTextServers(servers)

0 commit comments

Comments
 (0)