Skip to content

Commit 6734a4b

Browse files
authored
Bump mcp/registry to v1.3.7 (#331)
* Bump mcp/registry to v1.3.7 Signed-off-by: Radoslav Dimitrov <[email protected]> * Fix linting errors Signed-off-by: Radoslav Dimitrov <[email protected]> --------- Signed-off-by: Radoslav Dimitrov <[email protected]>
1 parent 5ac38e1 commit 6734a4b

File tree

6 files changed

+102
-104
lines changed

6 files changed

+102
-104
lines changed

go.mod

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ go 1.24.6
44

55
require (
66
github.com/google/go-cmp v0.7.0
7-
github.com/modelcontextprotocol/registry v1.3.5
7+
github.com/modelcontextprotocol/registry v1.3.7
88
github.com/spf13/cobra v1.10.1
99
github.com/stacklok/toolhive v0.3.7
1010
github.com/stretchr/testify v1.11.1
@@ -166,7 +166,7 @@ require (
166166
golang.org/x/crypto v0.42.0 // indirect
167167
golang.org/x/exp v0.0.0-20250620022241-b7579e27df2b // indirect
168168
golang.org/x/mod v0.29.0 // indirect
169-
golang.org/x/net v0.43.0 // indirect
169+
golang.org/x/net v0.44.0 // indirect
170170
golang.org/x/oauth2 v0.31.0 // indirect
171171
golang.org/x/sync v0.17.0 // indirect
172172
golang.org/x/sys v0.36.0 // indirect

go.sum

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -342,8 +342,8 @@ cloud.google.com/go/kms v1.8.0/go.mod h1:4xFEhYFqvW+4VMELtZyxomGSYtSQKzM178ylFW4
342342
cloud.google.com/go/kms v1.9.0/go.mod h1:qb1tPTgfF9RQP8e1wq4cLFErVuTJv7UsSC915J8dh3w=
343343
cloud.google.com/go/kms v1.10.0/go.mod h1:ng3KTUtQQU9bPX3+QGLsflZIHlkbn8amFAMY63m8d24=
344344
cloud.google.com/go/kms v1.10.1/go.mod h1:rIWk/TryCkR59GMC3YtHtXeLzd634lBbKenvyySAyYI=
345-
cloud.google.com/go/kms v1.22.0 h1:dBRIj7+GDeeEvatJeTB19oYZNV0aj6wEqSIT/7gLqtk=
346-
cloud.google.com/go/kms v1.22.0/go.mod h1:U7mf8Sva5jpOb4bxYZdtw/9zsbIjrklYwPcvMk34AL8=
345+
cloud.google.com/go/kms v1.23.0 h1:WaqAZsUptyHwOo9II8rFC1Kd2I+yvNsNP2IJ14H2sUw=
346+
cloud.google.com/go/kms v1.23.0/go.mod h1:rZ5kK0I7Kn9W4erhYVoIRPtpizjunlrfU4fUkumUp8g=
347347
cloud.google.com/go/language v1.4.0/go.mod h1:F9dRpNFQmJbkaop6g0JhSBXCNlO90e1KWx5iDdxbWic=
348348
cloud.google.com/go/language v1.6.0/go.mod h1:6dJ8t3B+lUYfStgls25GusK04NLh3eDLQnWM3mdEbhI=
349349
cloud.google.com/go/language v1.7.0/go.mod h1:DJ6dYN/W+SQOjF8e1hLQXMF21AkH2w9wiPzPCJa2MIE=
@@ -629,10 +629,10 @@ github.com/1password/onepassword-sdk-go v0.3.1 h1:dz0LrYuIh/HrZ7rxr8NMymikNLBIXh
629629
github.com/1password/onepassword-sdk-go v0.3.1/go.mod h1:kssODrGGqHtniqPR91ZPoCMEo79mKulKat7RaD1bunk=
630630
github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230919221257-8b5d3ce2d11d h1:zjqpY4C7H15HjRPEenkS4SAn3Jy2eRRjkjZbGR30TOg=
631631
github.com/AdamKorcz/go-fuzz-headers-1 v0.0.0-20230919221257-8b5d3ce2d11d/go.mod h1:XNqJ7hv2kY++g8XEHREpi+JqZo3+0l+CH2egBVN4yqM=
632-
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.2 h1:Hr5FTipp7SL07o2FvoVOX9HRiRH3CR3Mj8pxqCcdD5A=
633-
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.18.2/go.mod h1:QyVsSSN64v5TGltphKLQ2sQxe4OBQg0J1eKRcVBnfgE=
634-
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0 h1:MhRfI58HblXzCtWEZCO0feHs8LweePB3s90r7WaR1KU=
635-
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.11.0/go.mod h1:okZ+ZURbArNdlJ+ptXoyHNuOETzOl1Oww19rm8I2WLA=
632+
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1 h1:5YTBM8QDVIBN3sxBil89WfdAAqDZbyJTgh688DSxX5w=
633+
github.com/Azure/azure-sdk-for-go/sdk/azcore v1.19.1/go.mod h1:YD5h/ldMsG0XiIw7PdyNhLxaM317eFh5yNLccNfGdyw=
634+
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0 h1:wL5IEG5zb7BVv1Kv0Xm92orq+5hB5Nipn3B5tn4Rqfk=
635+
github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.12.0/go.mod h1:J7MUC/wtRpfGVbQ5sIItY5/FuVWmvzlY21WAOfQnq/I=
636636
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2 h1:9iefClla7iYpfYWdzPCRDozdmndjTm8DXdpCzPajMgA=
637637
github.com/Azure/azure-sdk-for-go/sdk/internal v1.11.2/go.mod h1:XtLgD3ZD34DAaVIIAyG3objl5DynM3CQ/vMcbBNJZGI=
638638
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/azkeys v1.4.0 h1:E4MgwLBGeVB5f2MdcIVD3ELVAWpr+WD6MUe1i+tM/PA=
@@ -641,8 +641,8 @@ github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0 h1:nCYfg
641641
github.com/Azure/azure-sdk-for-go/sdk/security/keyvault/internal v1.2.0/go.mod h1:ucUjca2JtSZboY8IoUqyQyuuXvwbMBVwFOm0vdQPNhA=
642642
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c h1:udKWzYgxTojEKWjV8V+WSxDXJ4NFATAsZjh8iIbsQIg=
643643
github.com/Azure/go-ansiterm v0.0.0-20250102033503-faa5f7b0171c/go.mod h1:xomTg63KZ2rFqZQzSB4Vz2SUXa1BpHTVz9L5PTmPC4E=
644-
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2 h1:oygO0locgZJe7PpYPXT5A29ZkwJaPqcva7BVeemZOZs=
645-
github.com/AzureAD/microsoft-authentication-library-for-go v1.4.2/go.mod h1:wP83P5OoQ5p6ip3ScPr0BAq0BvuPAvacpEuSzyouqAI=
644+
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0 h1:XkkQbfMyuH2jTSjQjSoihryI8GINRcs4xp8lNawg0FI=
645+
github.com/AzureAD/microsoft-authentication-library-for-go v1.5.0/go.mod h1:HKpQxkWaGLJ+D/5H8QRpyQXA1eKjxkFlOMwck5+33Jk=
646646
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
647647
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
648648
github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.3 h1:2afWGsMzkIcN8Qm4mgPJKZWyroE5QBszMiDMYEBrnfw=
@@ -1131,8 +1131,8 @@ github.com/moby/sys/sequential v0.6.0 h1:qrx7XFUd/5DxtqcoH1h438hF5TmOvzC/lspjy7z
11311131
github.com/moby/sys/sequential v0.6.0/go.mod h1:uyv8EUTrca5PnDsdMGXhZe6CCe8U/UiTWd+lL+7b/Ko=
11321132
github.com/moby/term v0.5.2 h1:6qk3FJAFDs6i/q3W/pQ97SX192qKfZgGjCQqfCJkgzQ=
11331133
github.com/moby/term v0.5.2/go.mod h1:d3djjFCrjnB+fl8NJux+EJzu0msscUP+f8it8hPkFLc=
1134-
github.com/modelcontextprotocol/registry v1.3.5 h1:M1ZTKPkxVICKlFBYio01/CkHbpjMcaGjLFF5M5QgZxc=
1135-
github.com/modelcontextprotocol/registry v1.3.5/go.mod h1:68KOBW2R5FX53BTrid2OFvPoCKEEYZk6z8LUa2ahLM0=
1134+
github.com/modelcontextprotocol/registry v1.3.7 h1:FR8vcBPBE0nRAz0P5lNGkiZmdtokZIyTry3Lx7J0nhE=
1135+
github.com/modelcontextprotocol/registry v1.3.7/go.mod h1:v2pC//yAoG3PPlkvXPrBI+CQd/5sar+MYCxWioL/NDk=
11361136
github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
11371137
github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
11381138
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA=
@@ -1493,8 +1493,8 @@ golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
14931493
golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
14941494
golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc=
14951495
golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns=
1496-
golang.org/x/net v0.43.0 h1:lat02VYK2j4aLzMzecihNvTlJNQUq316m2Mr9rnM6YE=
1497-
golang.org/x/net v0.43.0/go.mod h1:vhO1fvI4dGsIjh73sWfUVjj3N7CA9WkKJNQm2svM6Jg=
1496+
golang.org/x/net v0.44.0 h1:evd8IRDyfNBMBTTY5XRF1vaZlD+EmWx6x8PkhR04H/I=
1497+
golang.org/x/net v0.44.0/go.mod h1:ECOoLqd5U3Lhyeyo/QDCEVQ4sNgYsqvCZ722XogGieY=
14981498
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
14991499
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
15001500
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=

pkg/registry/converters/converters_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ func createTestServerJSON() *upstream.ServerJSON {
2020
Name: "io.github.stacklok/test-server",
2121
Description: "Test MCP server",
2222
Version: "1.0.0",
23-
Repository: model.Repository{
23+
Repository: &model.Repository{
2424
URL: "https://github.com/test/repo",
2525
Source: "github",
2626
},
@@ -459,7 +459,7 @@ func TestServerJSONToRemoteServerMetadata_Success(t *testing.T) {
459459
serverJSON := &upstream.ServerJSON{
460460
Name: "io.github.stacklok/test-remote",
461461
Description: "Test remote server",
462-
Repository: model.Repository{
462+
Repository: &model.Repository{
463463
URL: "https://github.com/test/remote",
464464
},
465465
Remotes: []model.Transport{
@@ -882,7 +882,7 @@ func TestRealWorld_GitHubServer(t *testing.T) {
882882
Name: "io.github.github/github-mcp-server",
883883
Description: "Connect AI assistants to GitHub - manage repos, issues, PRs, and workflows through natural language.",
884884
Version: "0.19.1",
885-
Repository: model.Repository{
885+
Repository: &model.Repository{
886886
URL: "https://github.com/github/github-mcp-server",
887887
Source: "github",
888888
},

pkg/registry/converters/toolhive_to_upstream.go

Lines changed: 4 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,23 +37,12 @@ func ImageMetadataToServerJSON(name string, imageMetadata *registry.ImageMetadat
3737
Version: "1.0.0", // TODO: Extract from image tag or metadata
3838
}
3939

40-
// Set repository
40+
// Set repository if available
4141
if imageMetadata.RepositoryURL != "" {
42-
serverJSON.Repository = model.Repository{
42+
serverJSON.Repository = &model.Repository{
4343
URL: imageMetadata.RepositoryURL,
4444
Source: "github", // Assume GitHub
4545
}
46-
} else {
47-
// Use toolhive-registry as fallback when no repository URL is available.
48-
// This is necessary for schema validation - the upstream Repository field is a struct
49-
// (not a pointer), so it can't be omitted with omitempty and would serialize as
50-
// empty strings {"url": "", "source": ""}, which fails URI format validation.
51-
// Using the toolhive-registry URL is reasonable since it's where these servers
52-
// are registered and documented.
53-
serverJSON.Repository = model.Repository{
54-
URL: "https://github.com/stacklok/toolhive-registry",
55-
Source: "github",
56-
}
5746
}
5847

5948
// Create package
@@ -86,23 +75,12 @@ func RemoteServerMetadataToServerJSON(name string, remoteMetadata *registry.Remo
8675
Version: "1.0.0", // TODO: Version management
8776
}
8877

89-
// Set repository
78+
// Set repository if available
9079
if remoteMetadata.RepositoryURL != "" {
91-
serverJSON.Repository = model.Repository{
80+
serverJSON.Repository = &model.Repository{
9281
URL: remoteMetadata.RepositoryURL,
9382
Source: "github", // Assume GitHub
9483
}
95-
} else {
96-
// Use toolhive-registry as fallback when no repository URL is available.
97-
// This is necessary for schema validation - the upstream Repository field is a struct
98-
// (not a pointer), so it can't be omitted with omitempty and would serialize as
99-
// empty strings {"url": "", "source": ""}, which fails URI format validation.
100-
// Using the toolhive-registry URL is reasonable since it's where these servers
101-
// are registered and documented.
102-
serverJSON.Repository = model.Repository{
103-
URL: "https://github.com/stacklok/toolhive-registry",
104-
Source: "github",
105-
}
10684
}
10785

10886
// Create remote

pkg/registry/converters/upstream_to_toolhive.go

Lines changed: 77 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,46 @@ func ServerJSONToImageMetadata(serverJSON *upstream.ServerJSON) (*registry.Image
2121
return nil, fmt.Errorf("serverJSON cannot be nil")
2222
}
2323

24+
pkg, err := extractSingleOCIPackage(serverJSON)
25+
if err != nil {
26+
return nil, err
27+
}
28+
29+
imageMetadata := &registry.ImageMetadata{
30+
BaseServerMetadata: registry.BaseServerMetadata{
31+
Name: serverJSON.Title,
32+
Description: serverJSON.Description,
33+
Transport: pkg.Transport.Type,
34+
},
35+
Image: pkg.Identifier, // OCI packages store full image ref in Identifier
36+
}
37+
38+
// Set repository URL
39+
if serverJSON.Repository != nil && serverJSON.Repository.URL != "" {
40+
imageMetadata.RepositoryURL = serverJSON.Repository.URL
41+
}
42+
43+
// Convert environment variables
44+
imageMetadata.EnvVars = convertEnvironmentVariables(pkg.EnvironmentVariables)
45+
46+
// Extract target port from transport URL if present
47+
imageMetadata.TargetPort = extractTargetPort(pkg.Transport.URL, serverJSON.Name)
48+
49+
// Convert PackageArguments to simple Args (priority: structured arguments first)
50+
if len(pkg.PackageArguments) > 0 {
51+
imageMetadata.Args = flattenPackageArguments(pkg.PackageArguments)
52+
}
53+
54+
// Extract publisher-provided extensions (including Args fallback)
55+
extractImageExtensions(serverJSON, imageMetadata)
56+
57+
return imageMetadata, nil
58+
}
59+
60+
// extractSingleOCIPackage validates and extracts the single OCI package from ServerJSON
61+
func extractSingleOCIPackage(serverJSON *upstream.ServerJSON) (model.Package, error) {
2462
if len(serverJSON.Packages) == 0 {
25-
return nil, fmt.Errorf("server '%s' has no packages (not a container-based server)", serverJSON.Name)
63+
return model.Package{}, fmt.Errorf("server '%s' has no packages (not a container-based server)", serverJSON.Name)
2664
}
2765

2866
// Filter for OCI packages only
@@ -36,70 +74,60 @@ func ServerJSONToImageMetadata(serverJSON *upstream.ServerJSON) (*registry.Image
3674
}
3775

3876
if len(ociPackages) == 0 {
39-
return nil, fmt.Errorf("server '%s' has no OCI packages (found: %v)", serverJSON.Name, packageTypes)
77+
return model.Package{}, fmt.Errorf("server '%s' has no OCI packages (found: %v)", serverJSON.Name, packageTypes)
4078
}
4179

4280
if len(ociPackages) > 1 {
43-
return nil, fmt.Errorf("server '%s' has %d OCI packages, expected exactly 1", serverJSON.Name, len(ociPackages))
81+
return model.Package{}, fmt.Errorf("server '%s' has %d OCI packages, expected exactly 1", serverJSON.Name, len(ociPackages))
4482
}
4583

46-
pkg := ociPackages[0]
84+
return ociPackages[0], nil
85+
}
4786

48-
imageMetadata := &registry.ImageMetadata{
49-
BaseServerMetadata: registry.BaseServerMetadata{
50-
Name: serverJSON.Title,
51-
Description: serverJSON.Description,
52-
Transport: pkg.Transport.Type,
53-
},
54-
Image: pkg.Identifier, // OCI packages store full image ref in Identifier
87+
// convertEnvironmentVariables converts model.KeyValueInput to registry.EnvVar
88+
func convertEnvironmentVariables(envVars []model.KeyValueInput) []*registry.EnvVar {
89+
if len(envVars) == 0 {
90+
return nil
5591
}
5692

57-
// Set repository URL
58-
if serverJSON.Repository.URL != "" {
59-
imageMetadata.RepositoryURL = serverJSON.Repository.URL
93+
result := make([]*registry.EnvVar, 0, len(envVars))
94+
for _, envVar := range envVars {
95+
result = append(result, &registry.EnvVar{
96+
Name: envVar.Name,
97+
Description: envVar.Description,
98+
Required: envVar.IsRequired,
99+
Secret: envVar.IsSecret,
100+
Default: envVar.Default,
101+
})
60102
}
103+
return result
104+
}
61105

62-
// Convert environment variables
63-
if len(pkg.EnvironmentVariables) > 0 {
64-
imageMetadata.EnvVars = make([]*registry.EnvVar, 0, len(pkg.EnvironmentVariables))
65-
for _, envVar := range pkg.EnvironmentVariables {
66-
imageMetadata.EnvVars = append(imageMetadata.EnvVars, &registry.EnvVar{
67-
Name: envVar.Name,
68-
Description: envVar.Description,
69-
Required: envVar.IsRequired,
70-
Secret: envVar.IsSecret,
71-
Default: envVar.Default,
72-
})
73-
}
106+
// extractTargetPort extracts the port number from a transport URL
107+
func extractTargetPort(transportURL, serverName string) int {
108+
if transportURL == "" {
109+
return 0
74110
}
75111

76-
// Extract target port from transport URL if present
77-
if pkg.Transport.URL != "" {
78-
// Parse URL like "http://localhost:8080"
79-
parsedURL, err := url.Parse(pkg.Transport.URL)
80-
if err != nil {
81-
// Log parse error to aid debugging but don't fail conversion
82-
fmt.Printf("⚠️ Failed to parse transport URL '%s' for server '%s': %v\n",
83-
pkg.Transport.URL, serverJSON.Name, err)
84-
} else if parsedURL.Port() != "" {
85-
if port, err := strconv.Atoi(parsedURL.Port()); err == nil {
86-
imageMetadata.TargetPort = port
87-
} else {
88-
fmt.Printf("⚠️ Failed to parse port from URL '%s' for server '%s': %v\n",
89-
pkg.Transport.URL, serverJSON.Name, err)
90-
}
91-
}
112+
parsedURL, err := url.Parse(transportURL)
113+
if err != nil {
114+
fmt.Printf("⚠️ Failed to parse transport URL '%s' for server '%s': %v\n",
115+
transportURL, serverName, err)
116+
return 0
92117
}
93118

94-
// Convert PackageArguments to simple Args (priority: structured arguments first)
95-
if len(pkg.PackageArguments) > 0 {
96-
imageMetadata.Args = flattenPackageArguments(pkg.PackageArguments)
119+
if parsedURL.Port() == "" {
120+
return 0
97121
}
98122

99-
// Extract publisher-provided extensions (including Args fallback)
100-
extractImageExtensions(serverJSON, imageMetadata)
123+
port, err := strconv.Atoi(parsedURL.Port())
124+
if err != nil {
125+
fmt.Printf("⚠️ Failed to parse port from URL '%s' for server '%s': %v\n",
126+
transportURL, serverName, err)
127+
return 0
128+
}
101129

102-
return imageMetadata, nil
130+
return port
103131
}
104132

105133
// ServerJSONToRemoteServerMetadata converts an upstream ServerJSON (with remotes) to toolhive RemoteServerMetadata
@@ -125,7 +153,7 @@ func ServerJSONToRemoteServerMetadata(serverJSON *upstream.ServerJSON) (*registr
125153
}
126154

127155
// Set repository URL
128-
if serverJSON.Repository.URL != "" {
156+
if serverJSON.Repository != nil && serverJSON.Repository.URL != "" {
129157
remoteMetadata.RepositoryURL = serverJSON.Repository.URL
130158
}
131159

pkg/registry/official.go

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,7 @@ func (or *OfficialRegistry) transformEntry(name string, entry *types.RegistryEnt
223223
}
224224

225225
// createRepository creates repository information from entry
226-
func (*OfficialRegistry) createRepository(entry *types.RegistryEntry) model.Repository {
226+
func (*OfficialRegistry) createRepository(entry *types.RegistryEntry) *model.Repository {
227227
var repositoryURL string
228228

229229
if entry.IsImage() && entry.ImageMetadata.RepositoryURL != "" {
@@ -232,20 +232,12 @@ func (*OfficialRegistry) createRepository(entry *types.RegistryEntry) model.Repo
232232
repositoryURL = entry.RemoteServerMetadata.RepositoryURL
233233
}
234234

235-
// If no repository URL is available, use toolhive-registry as fallback.
236-
// This is necessary for schema validation - the upstream Repository field is a struct
237-
// (not a pointer), so it can't be omitted with omitempty and would serialize as
238-
// empty strings {"url": "", "source": ""}, which fails URI format validation.
239-
// Using the toolhive-registry URL is reasonable since it's where these servers
240-
// are registered and documented.
235+
// If no repository URL is available, return nil (will be omitted with omitempty)
241236
if repositoryURL == "" {
242-
return model.Repository{
243-
URL: "https://github.com/stacklok/toolhive-registry",
244-
Source: "github",
245-
}
237+
return nil
246238
}
247239

248-
return model.Repository{
240+
return &model.Repository{
249241
URL: repositoryURL,
250242
Source: "github", // Assume GitHub for now
251243
}

0 commit comments

Comments
 (0)