Skip to content

Commit 3483e43

Browse files
authored
Migrate old auto_discovery to new client registration setup (#853)
Migrates old auto_discovery to new client registration setup Signed-off-by: lujunsan <[email protected]>
1 parent 948e8d0 commit 3483e43

File tree

3 files changed

+107
-0
lines changed

3 files changed

+107
-0
lines changed

cmd/thv/main.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"os"
66

77
"github.com/stacklok/toolhive/cmd/thv/app"
8+
"github.com/stacklok/toolhive/pkg/client"
89
"github.com/stacklok/toolhive/pkg/container"
910
"github.com/stacklok/toolhive/pkg/logger"
1011
)
@@ -13,6 +14,10 @@ func main() {
1314
// Initialize the logger
1415
logger.Initialize()
1516

17+
// Check and perform auto-discovery migration if needed
18+
// Handles the auto-discovery flag depreciation, only executes once on old config files
19+
client.CheckAndPerformAutoDiscoveryMigration()
20+
1621
// Skip update check for completion command or if we are running in kubernetes
1722
if err := app.NewRootCmd(!app.IsCompletionCommand(os.Args) && !container.IsKubernetesRuntime()).Execute(); err != nil {
1823
os.Exit(1)

pkg/client/migration.go

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package client
2+
3+
import (
4+
"fmt"
5+
"sync"
6+
7+
"github.com/stacklok/toolhive/pkg/config"
8+
"github.com/stacklok/toolhive/pkg/logger"
9+
)
10+
11+
// migrationOnce ensures the migration only runs once
12+
var migrationOnce sync.Once
13+
14+
// CheckAndPerformAutoDiscoveryMigration checks if auto-discovery migration is needed and performs it
15+
// This is called once at application startup
16+
func CheckAndPerformAutoDiscoveryMigration() {
17+
migrationOnce.Do(func() {
18+
appConfig := config.GetConfig()
19+
20+
// Check if auto-discovery flag is set to true, use of deprecated object is expected here
21+
if appConfig.Clients.AutoDiscovery {
22+
performAutoDiscoveryMigration()
23+
}
24+
})
25+
}
26+
27+
// performAutoDiscoveryMigration discovers and registers all installed clients
28+
func performAutoDiscoveryMigration() {
29+
fmt.Println("Migrating from deprecated auto-discovery to manual client registration...")
30+
fmt.Println()
31+
32+
// Get current client statuses to determine what to register
33+
clientStatuses, err := GetClientStatus()
34+
if err != nil {
35+
logger.Errorf("Error discovering clients during migration: %v", err)
36+
return
37+
}
38+
39+
// Get current config to see what's already registered
40+
appConfig := config.GetConfig()
41+
42+
var clientsToRegister []string
43+
var alreadyRegistered = appConfig.Clients.RegisteredClients
44+
45+
// Find installed clients that aren't registered yet
46+
for _, status := range clientStatuses {
47+
if status.Installed && !status.Registered {
48+
clientsToRegister = append(clientsToRegister, string(status.ClientType))
49+
fmt.Println("Registering client", string(status.ClientType))
50+
}
51+
}
52+
53+
// Register new clients and remove the auto-discovery flag
54+
err = config.UpdateConfig(func(c *config.Config) {
55+
for _, clientName := range clientsToRegister {
56+
// Double-check if not already registered (safety check)
57+
found := false
58+
for _, registered := range c.Clients.RegisteredClients {
59+
if registered == clientName {
60+
found = true
61+
break
62+
}
63+
}
64+
65+
if !found {
66+
c.Clients.RegisteredClients = append(c.Clients.RegisteredClients, clientName)
67+
}
68+
}
69+
70+
// Remove the auto-discovery flag during the same config update
71+
c.Clients.AutoDiscovery = false
72+
})
73+
74+
if err != nil {
75+
logger.Errorf("Error updating config during migration: %v", err)
76+
return
77+
}
78+
79+
// Print success messages for newly registered clients
80+
for _, clientName := range clientsToRegister {
81+
fmt.Printf(" ✓ Automatically registered client: %s\n", clientName)
82+
}
83+
84+
fmt.Println()
85+
fmt.Println("NOTICE: Auto-discovery of MCP clients has been deprecated and is no longer supported.")
86+
fmt.Println("Your existing clients have been automatically migrated to the new manual registration system.")
87+
fmt.Println()
88+
fmt.Println("Going forward, use 'thv client setup' to discover and register new MCP clients.")
89+
fmt.Println("This provides better control and security for your client configurations.")
90+
fmt.Println()
91+
92+
// Show all registered clients (both newly registered and previously registered)
93+
allRegisteredClients := append(alreadyRegistered, clientsToRegister...)
94+
if len(allRegisteredClients) > 0 {
95+
fmt.Println("Registered clients:")
96+
for _, clientName := range allRegisteredClients {
97+
fmt.Printf(" - %s\n", clientName)
98+
}
99+
fmt.Println()
100+
}
101+
}

pkg/config/config.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ func (s *Secrets) GetProviderType() (secrets.ProviderType, error) {
7171
// Clients contains settings for client configuration.
7272
type Clients struct {
7373
RegisteredClients []string `yaml:"registered_clients"`
74+
AutoDiscovery bool `yaml:"auto_discovery"` // Deprecated: kept for migration purposes only
7475
}
7576

7677
// defaultPathGenerator generates the default config path using xdg

0 commit comments

Comments
 (0)