Skip to content

Commit 288e03b

Browse files
committed
Mark schema as required field and fix linting errors
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
1 parent 1e32e1a commit 288e03b

5 files changed

Lines changed: 51 additions & 49 deletions

File tree

internal/api/handlers/v0/publish_integration_test.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -145,8 +145,8 @@ func TestPublishIntegration(t *testing.T) {
145145

146146
t.Run("publish fails with missing authorization header", func(t *testing.T) {
147147
publishReq := apiv0.ServerJSON{
148-
Schema: model.CurrentSchemaURL,
149-
Name: "test-server",
148+
Schema: model.CurrentSchemaURL,
149+
Name: "test-server",
150150
}
151151

152152
body, err := json.Marshal(publishReq)

internal/service/registry_service_test.go

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -134,15 +134,15 @@ func TestGetServerByName(t *testing.T) {
134134

135135
// Create multiple versions of the same server
136136
_, err := service.CreateServer(ctx, &apiv0.ServerJSON{
137-
Schema: model.CurrentSchemaURL,
137+
Schema: model.CurrentSchemaURL,
138138
Name: "com.example/test-server",
139139
Description: "Test server v1",
140140
Version: "1.0.0",
141141
})
142142
require.NoError(t, err)
143143

144144
_, err = service.CreateServer(ctx, &apiv0.ServerJSON{
145-
Schema: model.CurrentSchemaURL,
145+
Schema: model.CurrentSchemaURL,
146146
Name: "com.example/test-server",
147147
Description: "Test server v2",
148148
Version: "2.0.0",
@@ -205,15 +205,15 @@ func TestGetServerByNameAndVersion(t *testing.T) {
205205

206206
// Create multiple versions of the same server
207207
_, err := service.CreateServer(ctx, &apiv0.ServerJSON{
208-
Schema: model.CurrentSchemaURL,
208+
Schema: model.CurrentSchemaURL,
209209
Name: serverName,
210210
Description: "Versioned server v1",
211211
Version: "1.0.0",
212212
})
213213
require.NoError(t, err)
214214

215215
_, err = service.CreateServer(ctx, &apiv0.ServerJSON{
216-
Schema: model.CurrentSchemaURL,
216+
Schema: model.CurrentSchemaURL,
217217
Name: serverName,
218218
Description: "Versioned server v2",
219219
Version: "2.0.0",
@@ -298,23 +298,23 @@ func TestGetAllVersionsByServerName(t *testing.T) {
298298

299299
// Create multiple versions of the same server
300300
_, err := service.CreateServer(ctx, &apiv0.ServerJSON{
301-
Schema: model.CurrentSchemaURL,
301+
Schema: model.CurrentSchemaURL,
302302
Name: serverName,
303303
Description: "Multi-version server v1",
304304
Version: "1.0.0",
305305
})
306306
require.NoError(t, err)
307307

308308
_, err = service.CreateServer(ctx, &apiv0.ServerJSON{
309-
Schema: model.CurrentSchemaURL,
309+
Schema: model.CurrentSchemaURL,
310310
Name: serverName,
311311
Description: "Multi-version server v2",
312312
Version: "2.0.0",
313313
})
314314
require.NoError(t, err)
315315

316316
_, err = service.CreateServer(ctx, &apiv0.ServerJSON{
317-
Schema: model.CurrentSchemaURL,
317+
Schema: model.CurrentSchemaURL,
318318
Name: serverName,
319319
Description: "Multi-version server v2.1",
320320
Version: "2.1.0",
@@ -401,8 +401,8 @@ func TestCreateServerConcurrentVersionsNoRace(t *testing.T) {
401401
go func(idx int) {
402402
defer wg.Done()
403403
result, err := service.CreateServer(ctx, &apiv0.ServerJSON{
404-
Schema: model.CurrentSchemaURL,
405-
Name: serverName,
404+
Schema: model.CurrentSchemaURL,
405+
Name: serverName,
406406
Description: fmt.Sprintf("Version %d", idx),
407407
Version: fmt.Sprintf("1.0.%d", idx),
408408
})
@@ -451,7 +451,7 @@ func TestUpdateServer(t *testing.T) {
451451

452452
// Create initial server
453453
_, err := service.CreateServer(ctx, &apiv0.ServerJSON{
454-
Schema: model.CurrentSchemaURL,
454+
Schema: model.CurrentSchemaURL,
455455
Name: serverName,
456456
Description: "Original description",
457457
Version: version,
@@ -660,8 +660,8 @@ func TestListServers(t *testing.T) {
660660

661661
for _, server := range testServers {
662662
_, err := service.CreateServer(ctx, &apiv0.ServerJSON{
663-
Schema: model.CurrentSchemaURL,
664-
Name: server.name,
663+
Schema: model.CurrentSchemaURL,
664+
Name: server.name,
665665
Description: server.description,
666666
Version: server.version,
667667
})
@@ -758,8 +758,8 @@ func TestVersionComparison(t *testing.T) {
758758
time.Sleep(v.delay)
759759
}
760760
_, err := service.CreateServer(ctx, &apiv0.ServerJSON{
761-
Schema: model.CurrentSchemaURL,
762-
Name: serverName,
761+
Schema: model.CurrentSchemaURL,
762+
Name: serverName,
763763
Description: v.description,
764764
Version: v.version,
765765
})

internal/validators/validators.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ var (
5454

5555
func ValidateServerJSON(serverJSON *apiv0.ServerJSON) error {
5656
// Validate schema version is provided and supported
57+
// Note: Schema field is also marked as required in the ServerJSON struct definition
58+
// for API-level validation and documentation
5759
if serverJSON.Schema == "" {
5860
return fmt.Errorf("$schema field is required")
5961
}

internal/validators/validators_test.go

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -757,8 +757,8 @@ func TestValidate_RemoteNamespaceMatch(t *testing.T) {
757757
{
758758
name: "valid match - example.com domain",
759759
serverDetail: apiv0.ServerJSON{
760-
Schema: model.CurrentSchemaURL,
761-
Name: "com.example/test-server",
760+
Schema: model.CurrentSchemaURL,
761+
Name: "com.example/test-server",
762762
Remotes: []model.Transport{
763763
{
764764
Type: "streamable-http",
@@ -771,8 +771,8 @@ func TestValidate_RemoteNamespaceMatch(t *testing.T) {
771771
{
772772
name: "valid match - subdomain mcp.example.com",
773773
serverDetail: apiv0.ServerJSON{
774-
Schema: model.CurrentSchemaURL,
775-
Name: "com.example/test-server",
774+
Schema: model.CurrentSchemaURL,
775+
Name: "com.example/test-server",
776776
Remotes: []model.Transport{
777777
{
778778
Type: "streamable-http",
@@ -785,8 +785,8 @@ func TestValidate_RemoteNamespaceMatch(t *testing.T) {
785785
{
786786
name: "valid match - api subdomain",
787787
serverDetail: apiv0.ServerJSON{
788-
Schema: model.CurrentSchemaURL,
789-
Name: "com.example/api-server",
788+
Schema: model.CurrentSchemaURL,
789+
Name: "com.example/api-server",
790790
Remotes: []model.Transport{
791791
{
792792
Type: "streamable-http",
@@ -799,8 +799,8 @@ func TestValidate_RemoteNamespaceMatch(t *testing.T) {
799799
{
800800
name: "invalid - wrong domain",
801801
serverDetail: apiv0.ServerJSON{
802-
Schema: model.CurrentSchemaURL,
803-
Name: "com.example/test-server",
802+
Schema: model.CurrentSchemaURL,
803+
Name: "com.example/test-server",
804804
Remotes: []model.Transport{
805805
{
806806
Type: "streamable-http",
@@ -814,8 +814,8 @@ func TestValidate_RemoteNamespaceMatch(t *testing.T) {
814814
{
815815
name: "invalid - different domain entirely",
816816
serverDetail: apiv0.ServerJSON{
817-
Schema: model.CurrentSchemaURL,
818-
Name: "com.microsoft/server",
817+
Schema: model.CurrentSchemaURL,
818+
Name: "com.microsoft/server",
819819
Remotes: []model.Transport{
820820
{
821821
Type: "streamable-http",
@@ -829,8 +829,8 @@ func TestValidate_RemoteNamespaceMatch(t *testing.T) {
829829
{
830830
name: "invalid URL format",
831831
serverDetail: apiv0.ServerJSON{
832-
Schema: model.CurrentSchemaURL,
833-
Name: "com.example/test",
832+
Schema: model.CurrentSchemaURL,
833+
Name: "com.example/test",
834834
Remotes: []model.Transport{
835835
{
836836
Type: "streamable-http",
@@ -844,7 +844,7 @@ func TestValidate_RemoteNamespaceMatch(t *testing.T) {
844844
{
845845
name: "empty remotes array",
846846
serverDetail: apiv0.ServerJSON{
847-
Schema: model.CurrentSchemaURL,
847+
Schema: model.CurrentSchemaURL,
848848
Name: "com.example/test",
849849
Remotes: []model.Transport{},
850850
},
@@ -853,8 +853,8 @@ func TestValidate_RemoteNamespaceMatch(t *testing.T) {
853853
{
854854
name: "multiple valid remotes - different subdomains",
855855
serverDetail: apiv0.ServerJSON{
856-
Schema: model.CurrentSchemaURL,
857-
Name: "com.example/server",
856+
Schema: model.CurrentSchemaURL,
857+
Name: "com.example/server",
858858
Remotes: []model.Transport{
859859
{
860860
Type: "streamable-http",
@@ -871,8 +871,8 @@ func TestValidate_RemoteNamespaceMatch(t *testing.T) {
871871
{
872872
name: "one valid, one invalid remote",
873873
serverDetail: apiv0.ServerJSON{
874-
Schema: model.CurrentSchemaURL,
875-
Name: "com.example/server",
874+
Schema: model.CurrentSchemaURL,
875+
Name: "com.example/server",
876876
Remotes: []model.Transport{
877877
{
878878
Type: "streamable-http",
@@ -913,60 +913,60 @@ func TestValidate_ServerNameFormat(t *testing.T) {
913913
{
914914
name: "valid namespace/name format",
915915
serverDetail: apiv0.ServerJSON{
916-
Schema: model.CurrentSchemaURL,
917-
Name: "com.example.api/server",
916+
Schema: model.CurrentSchemaURL,
917+
Name: "com.example.api/server",
918918
},
919919
expectError: false,
920920
},
921921
{
922922
name: "valid complex namespace",
923923
serverDetail: apiv0.ServerJSON{
924-
Schema: model.CurrentSchemaURL,
925-
Name: "com.microsoft.azure.service/webapp-server",
924+
Schema: model.CurrentSchemaURL,
925+
Name: "com.microsoft.azure.service/webapp-server",
926926
},
927927
expectError: false,
928928
},
929929
{
930930
name: "empty server name",
931931
serverDetail: apiv0.ServerJSON{
932-
Schema: model.CurrentSchemaURL,
933-
Name: "",
932+
Schema: model.CurrentSchemaURL,
933+
Name: "",
934934
},
935935
expectError: true,
936936
errorMsg: "server name is required",
937937
},
938938
{
939939
name: "missing slash separator",
940940
serverDetail: apiv0.ServerJSON{
941-
Schema: model.CurrentSchemaURL,
942-
Name: "com.example.server",
941+
Schema: model.CurrentSchemaURL,
942+
Name: "com.example.server",
943943
},
944944
expectError: true,
945945
errorMsg: "server name must be in format 'dns-namespace/name'",
946946
},
947947
{
948948
name: "empty namespace part",
949949
serverDetail: apiv0.ServerJSON{
950-
Schema: model.CurrentSchemaURL,
951-
Name: "/server-name",
950+
Schema: model.CurrentSchemaURL,
951+
Name: "/server-name",
952952
},
953953
expectError: true,
954954
errorMsg: "non-empty namespace and name parts",
955955
},
956956
{
957957
name: "empty name part",
958958
serverDetail: apiv0.ServerJSON{
959-
Schema: model.CurrentSchemaURL,
960-
Name: "com.example/",
959+
Schema: model.CurrentSchemaURL,
960+
Name: "com.example/",
961961
},
962962
expectError: true,
963963
errorMsg: "non-empty namespace and name parts",
964964
},
965965
{
966966
name: "multiple slashes - should be rejected",
967967
serverDetail: apiv0.ServerJSON{
968-
Schema: model.CurrentSchemaURL,
969-
Name: "com.example/server/path",
968+
Schema: model.CurrentSchemaURL,
969+
Name: "com.example/server/path",
970970
},
971971
expectError: true,
972972
errorMsg: "server name cannot contain multiple slashes",
@@ -1052,7 +1052,7 @@ func TestValidate_MultipleSlashesInServerName(t *testing.T) {
10521052
t.Run(tt.name, func(t *testing.T) {
10531053
serverDetail := apiv0.ServerJSON{
10541054
Schema: model.CurrentSchemaURL,
1055-
Name: tt.serverName,
1055+
Name: tt.serverName,
10561056
}
10571057
err := validators.ValidateServerJSON(&serverDetail)
10581058

pkg/api/v0/types.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ type ServerMeta struct {
3838

3939
// ServerJSON represents complete server information as defined in the MCP spec, with extension support
4040
type ServerJSON struct {
41-
Schema string `json:"$schema,omitempty"`
41+
Schema string `json:"$schema" required:"true" minLength:"1"`
4242
Name string `json:"name" minLength:"1" maxLength:"200"`
4343
Description string `json:"description" minLength:"1" maxLength:"100"`
4444
Repository model.Repository `json:"repository,omitempty"`

0 commit comments

Comments
 (0)