Skip to content

Commit ef4a605

Browse files
authored
Make Repository field properly optional in server.json (#717)
<!-- Provide a brief summary of your changes --> ## Motivation and Context <!-- Why is this change needed? What problem does it solve? --> The Repository field in ServerJSON was not properly omitting empty values when marshaling to JSON. Even when a server had no repository configured, the JSON would include `"repository": {"url": "", "source": ""}` due to: 1. Repository struct fields (URL, Source) lacking omitempty tags 2. Repository being a value type instead of pointer in ServerJSON This caused validation warnings for servers without repository URLs. Changes: - Add omitempty tags to Repository.URL and Repository.Source fields - Change ServerJSON.Repository from model.Repository to *model.Repository - Update validateRepository to handle nil pointers - Update all code creating Repository instances to use pointers Now, servers without repository information correctly omit the field entirely from JSON output, eliminating spurious validation warnings. ## How Has This Been Tested? <!-- Have you tested this in a real application? Which scenarios were tested? --> ## Breaking Changes <!-- Will users need to update their code or configurations? --> ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [ ] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [ ] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed ## Additional context <!-- Add any other context, implementation notes, or design decisions --> Signed-off-by: Radoslav Dimitrov <[email protected]>
1 parent 88c2e1b commit ef4a605

File tree

11 files changed

+95
-92
lines changed

11 files changed

+95
-92
lines changed

cmd/publisher/commands/init.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -387,14 +387,17 @@ func createServerJSON(
387387
}
388388

389389
// Create repository with optional subfolder
390-
repo := model.Repository{
391-
URL: repoURL,
392-
Source: repoSource,
393-
}
390+
var repo *model.Repository
391+
if repoURL != "" && repoSource != "" {
392+
repo = &model.Repository{
393+
URL: repoURL,
394+
Source: repoSource,
395+
}
394396

395-
// Only set subfolder if we're actually in a subdirectory
396-
if subfolder != "" {
397-
repo.Subfolder = subfolder
397+
// Only set subfolder if we're actually in a subdirectory
398+
if subfolder != "" {
399+
repo.Subfolder = subfolder
400+
}
398401
}
399402

400403
// Create server structure

cmd/publisher/commands/publish_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ func TestPublishCommand_DeprecatedSchema(t *testing.T) {
6969
Name: "com.example/test-server",
7070
Description: "A test server",
7171
Version: "1.0.0",
72-
Repository: model.Repository{
72+
Repository: &model.Repository{
7373
URL: "https://github.com/example/test",
7474
Source: "github",
7575
},

internal/api/handlers/v0/edit_test.go

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ func TestEditServerEndpoint(t *testing.T) {
4646
Name: "io.github.testuser/editable-server",
4747
Description: "Server that can be edited",
4848
Version: "1.0.0",
49-
Repository: model.Repository{
49+
Repository: &model.Repository{
5050
URL: "https://github.com/testuser/editable-server",
5151
Source: "github",
5252
ID: "testuser/editable-server",
@@ -57,7 +57,7 @@ func TestEditServerEndpoint(t *testing.T) {
5757
Name: "io.github.otheruser/other-server",
5858
Description: "Server owned by another user",
5959
Version: "1.0.0",
60-
Repository: model.Repository{
60+
Repository: &model.Repository{
6161
URL: "https://github.com/otheruser/other-server",
6262
Source: "github",
6363
ID: "otheruser/other-server",
@@ -77,7 +77,7 @@ func TestEditServerEndpoint(t *testing.T) {
7777
Name: "io.github.testuser/deleted-server",
7878
Description: "Server that was deleted",
7979
Version: "1.0.0",
80-
Repository: model.Repository{
80+
Repository: &model.Repository{
8181
URL: "https://github.com/testuser/deleted-server",
8282
Source: "github",
8383
ID: "testuser/deleted-server",
@@ -96,7 +96,7 @@ func TestEditServerEndpoint(t *testing.T) {
9696
Name: "io.github.testuser/build-metadata-server",
9797
Description: "Server with build metadata version",
9898
Version: "1.0.0+20130313144700",
99-
Repository: model.Repository{
99+
Repository: &model.Repository{
100100
URL: "https://github.com/testuser/build-metadata-server",
101101
Source: "github",
102102
ID: "testuser/build-metadata-server",
@@ -133,7 +133,7 @@ func TestEditServerEndpoint(t *testing.T) {
133133
Name: "io.github.testuser/editable-server",
134134
Description: "Updated server description",
135135
Version: "1.0.0",
136-
Repository: model.Repository{
136+
Repository: &model.Repository{
137137
URL: "https://github.com/testuser/editable-server",
138138
Source: "github",
139139
ID: "testuser/editable-server",
@@ -347,7 +347,7 @@ func TestEditServerEndpoint(t *testing.T) {
347347
Name: "io.github.testuser/build-metadata-server",
348348
Description: "Updated server with build metadata",
349349
Version: "1.0.0+20130313144700",
350-
Repository: model.Repository{
350+
Repository: &model.Repository{
351351
URL: "https://github.com/testuser/build-metadata-server",
352352
Source: "github",
353353
ID: "testuser/build-metadata-server",

internal/api/handlers/v0/publish_integration_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ func TestPublishIntegration(t *testing.T) {
6060
Schema: model.CurrentSchemaURL,
6161
Name: "io.github.testuser/test-mcp-server",
6262
Description: "A test MCP server for integration testing",
63-
Repository: model.Repository{
63+
Repository: &model.Repository{
6464
URL: "https://github.com/testuser/test-mcp-server",
6565
Source: "github",
6666
ID: "testuser/test-mcp-server",
@@ -105,7 +105,7 @@ func TestPublishIntegration(t *testing.T) {
105105
Schema: model.CurrentSchemaURL,
106106
Name: "com.example/test-mcp-server-no-auth",
107107
Description: "A test MCP server without authentication",
108-
Repository: model.Repository{
108+
Repository: &model.Repository{
109109
URL: "https://github.com/example/test-server",
110110
Source: "github",
111111
ID: "example/test-server",
@@ -191,7 +191,7 @@ func TestPublishIntegration(t *testing.T) {
191191
Name: "io.github.other/test-server",
192192
Description: "A test server",
193193
Version: "1.0.0",
194-
Repository: model.Repository{
194+
Repository: &model.Repository{
195195
URL: "https://github.com/example/test-server",
196196
Source: "github",
197197
ID: "example/test-server",

internal/api/handlers/v0/publish_test.go

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ func TestPublishEndpoint(t *testing.T) {
5959
Schema: model.CurrentSchemaURL,
6060
Name: "io.github.example/test-server",
6161
Description: "A test server",
62-
Repository: model.Repository{
62+
Repository: &model.Repository{
6363
URL: "https://github.com/example/test-server",
6464
Source: "github",
6565
ID: "example/test-server",
@@ -84,7 +84,7 @@ func TestPublishEndpoint(t *testing.T) {
8484
Schema: model.CurrentSchemaURL,
8585
Name: "example/test-server",
8686
Description: "A test server without auth",
87-
Repository: model.Repository{
87+
Repository: &model.Repository{
8888
URL: "https://github.com/example/test-server",
8989
Source: "github",
9090
ID: "example/test-server",
@@ -149,7 +149,7 @@ func TestPublishEndpoint(t *testing.T) {
149149
Name: "io.github.other/test-server",
150150
Description: "A test server",
151151
Version: "1.0.0",
152-
Repository: model.Repository{
152+
Repository: &model.Repository{
153153
URL: "https://github.com/example/test-server",
154154
Source: "github",
155155
ID: "example/test-server",
@@ -174,7 +174,7 @@ func TestPublishEndpoint(t *testing.T) {
174174
Name: "example/test-server",
175175
Description: "A test server",
176176
Version: "1.0.0",
177-
Repository: model.Repository{
177+
Repository: &model.Repository{
178178
URL: "https://github.com/example/test-server",
179179
Source: "github",
180180
ID: "example/test-server",
@@ -193,7 +193,7 @@ func TestPublishEndpoint(t *testing.T) {
193193
Name: "example/test-server",
194194
Description: "Existing test server",
195195
Version: "1.0.0",
196-
Repository: model.Repository{
196+
Repository: &model.Repository{
197197
URL: "https://github.com/example/test-server-existing",
198198
Source: "github",
199199
ID: "example/test-server-existing",
@@ -239,7 +239,7 @@ func TestPublishEndpoint(t *testing.T) {
239239
Name: "com.example/server/path",
240240
Description: "Server with multiple slashes in name",
241241
Version: "1.0.0",
242-
Repository: model.Repository{
242+
Repository: &model.Repository{
243243
URL: "https://github.com/example/test-server",
244244
Source: "github",
245245
ID: "example/test-server",
@@ -334,7 +334,7 @@ func TestPublishEndpoint(t *testing.T) {
334334
Name: "com.example/test/server/v2",
335335
Description: "Complex server with invalid name",
336336
Version: "2.0.0",
337-
Repository: model.Repository{
337+
Repository: &model.Repository{
338338
URL: "https://github.com/example/test-server",
339339
Source: "github",
340340
ID: "example/test-server",

internal/api/handlers/v0/telemetry_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func TestPrometheusHandler(t *testing.T) {
2727
Schema: model.CurrentSchemaURL,
2828
Name: "io.github.example/test-server",
2929
Description: "Test server detail",
30-
Repository: model.Repository{
30+
Repository: &model.Repository{
3131
URL: "https://github.com/example/test-server",
3232
Source: "github",
3333
ID: "example/test-server",

internal/importer/importer_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestImportService_LocalFile(t *testing.T) {
2626
Schema: model.CurrentSchemaURL,
2727
Name: "io.github.test/test-server-1",
2828
Description: "Test server 1",
29-
Repository: model.Repository{
29+
Repository: &model.Repository{
3030
URL: "https://github.com/test/repo1",
3131
Source: "github",
3232
ID: "123",
@@ -69,7 +69,7 @@ func TestImportService_HTTPFile(t *testing.T) {
6969
Schema: model.CurrentSchemaURL,
7070
Name: "io.github.test/http-test-server",
7171
Description: "HTTP test server",
72-
Repository: model.Repository{
72+
Repository: &model.Repository{
7373
URL: "https://github.com/test/http-repo",
7474
Source: "github",
7575
ID: "456",

internal/validators/validators.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ func ValidateServerJSON(serverJSON *apiv0.ServerJSON) error {
7474
}
7575

7676
// Validate repository
77-
if err := validateRepository(&serverJSON.Repository); err != nil {
77+
if err := validateRepository(serverJSON.Repository); err != nil {
7878
return err
7979
}
8080

@@ -122,8 +122,8 @@ func ValidateServerJSON(serverJSON *apiv0.ServerJSON) error {
122122
}
123123

124124
func validateRepository(obj *model.Repository) error {
125-
// Skip validation for empty repository (optional field)
126-
if obj.URL == "" && obj.Source == "" {
125+
// Skip validation if repository is nil or empty (optional field)
126+
if obj == nil || (obj.URL == "" && obj.Source == "") {
127127
return nil
128128
}
129129

0 commit comments

Comments
 (0)