Skip to content

Commit 0eada9b

Browse files
authored
refactor: consolidate server list response types (#387)
## Summary - Consolidate ServerListResponse and Metadata types into pkg/api/v0 - Remove duplication between handler and API types - Change metadata from optional pointer to required value - Remove unused Total field from Metadata
1 parent d43d0bf commit 0eada9b

File tree

3 files changed

+19
-47
lines changed

3 files changed

+19
-47
lines changed

internal/api/handlers/v0/servers.go

Lines changed: 9 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,6 @@ import (
1212
apiv0 "github.com/modelcontextprotocol/registry/pkg/api/v0"
1313
)
1414

15-
// Metadata contains pagination metadata
16-
type Metadata struct {
17-
NextCursor string `json:"next_cursor,omitempty"`
18-
Count int `json:"count,omitempty"`
19-
Total int `json:"total,omitempty"`
20-
}
21-
2215
// ListServersInput represents the input for listing servers
2316
type ListServersInput struct {
2417
Cursor string `query:"cursor" doc:"Pagination cursor (UUID)" format:"uuid" required:"false" example:"550e8400-e29b-41d4-a716-446655440000"`
@@ -28,12 +21,6 @@ type ListServersInput struct {
2821
Version string `query:"version" doc:"Filter by version ('latest' for latest version, or an exact version like '1.2.3')" required:"false" example:"latest"`
2922
}
3023

31-
// ListServersBody represents the paginated server list response body
32-
type ListServersBody struct {
33-
Servers []apiv0.ServerJSON `json:"servers" doc:"List of MCP servers with extensions"`
34-
Metadata *Metadata `json:"metadata,omitempty" doc:"Pagination metadata"`
35-
}
36-
3724
// ServerDetailInput represents the input for getting server details
3825
type ServerDetailInput struct {
3926
ID string `path:"id" doc:"Server ID (UUID)" format:"uuid"`
@@ -49,7 +36,7 @@ func RegisterServersEndpoints(api huma.API, registry service.RegistryService) {
4936
Summary: "List MCP servers",
5037
Description: "Get a paginated list of MCP servers from the registry",
5138
Tags: []string{"servers"},
52-
}, func(_ context.Context, input *ListServersInput) (*Response[ListServersBody], error) {
39+
}, func(_ context.Context, input *ListServersInput) (*Response[apiv0.ServerListResponse], error) {
5340
// Validate cursor if provided
5441
if input.Cursor != "" {
5542
_, err := uuid.Parse(input.Cursor)
@@ -94,21 +81,14 @@ func RegisterServersEndpoints(api huma.API, registry service.RegistryService) {
9481
return nil, huma.Error500InternalServerError("Failed to get registry list", err)
9582
}
9683

97-
// Build response body
98-
body := ListServersBody{
99-
Servers: servers,
100-
}
101-
102-
// Add metadata if there's a next cursor
103-
if nextCursor != "" {
104-
body.Metadata = &Metadata{
105-
NextCursor: nextCursor,
106-
Count: len(servers),
107-
}
108-
}
109-
110-
return &Response[ListServersBody]{
111-
Body: body,
84+
return &Response[apiv0.ServerListResponse]{
85+
Body: apiv0.ServerListResponse{
86+
Servers: servers,
87+
Metadata: apiv0.Metadata{
88+
NextCursor: nextCursor,
89+
Count: len(servers),
90+
},
91+
},
11292
}, nil
11393
})
11494

internal/api/handlers/v0/servers_test.go

Lines changed: 8 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func TestServersListEndpoint(t *testing.T) {
2626
setupRegistryService func(service.RegistryService)
2727
expectedStatus int
2828
expectedServers []apiv0.ServerJSON
29-
expectedMeta *v0.Metadata
29+
expectedMeta *apiv0.Metadata
3030
expectedError string
3131
}{
3232
{
@@ -268,10 +268,7 @@ func TestServersListEndpoint(t *testing.T) {
268268
assert.Equal(t, "application/json", w.Header().Get("Content-Type"))
269269

270270
// Parse response body
271-
var resp struct {
272-
Servers []apiv0.ServerJSON `json:"servers"`
273-
Metadata *v0.Metadata `json:"metadata,omitempty"`
274-
}
271+
var resp apiv0.ServerListResponse
275272
err := json.NewDecoder(w.Body).Decode(&resp)
276273
assert.NoError(t, err)
277274

@@ -297,7 +294,7 @@ func TestServersListEndpoint(t *testing.T) {
297294
default:
298295
assert.NotEmpty(t, resp.Servers, "Expected at least one server")
299296
}
300-
297+
301298
// General structure validation
302299
for _, server := range resp.Servers {
303300
assert.NotEmpty(t, server.Name)
@@ -311,11 +308,9 @@ func TestServersListEndpoint(t *testing.T) {
311308
// Check metadata if expected
312309
if tc.expectedMeta != nil {
313310
assert.NotNil(t, resp.Metadata, "Expected metadata to be present")
314-
if resp.Metadata != nil {
315-
assert.Equal(t, tc.expectedMeta.Count, resp.Metadata.Count)
316-
if tc.expectedMeta.NextCursor != "" {
317-
assert.NotEmpty(t, resp.Metadata.NextCursor)
318-
}
311+
assert.Equal(t, tc.expectedMeta.Count, resp.Metadata.Count)
312+
if tc.expectedMeta.NextCursor != "" {
313+
assert.NotEmpty(t, resp.Metadata.NextCursor)
319314
}
320315
}
321316
} else if tc.expectedError != "" {
@@ -336,7 +331,7 @@ func TestServersDetailEndpoint(t *testing.T) {
336331
testServer, err := registryService.Publish(apiv0.ServerJSON{
337332
Name: "com.example/test-server",
338333
Description: "A test server",
339-
Version: "1.0.0",
334+
Version: "1.0.0",
340335
})
341336
assert.NoError(t, err)
342337

@@ -466,9 +461,7 @@ func TestServersEndpointsIntegration(t *testing.T) {
466461
assert.Equal(t, "application/json", resp.Header.Get("Content-Type"))
467462

468463
// Parse response body
469-
var listResp struct {
470-
Servers []apiv0.ServerJSON `json:"servers"`
471-
}
464+
var listResp apiv0.ServerListResponse
472465
err = json.NewDecoder(resp.Body).Decode(&listResp)
473466
assert.NoError(t, err)
474467

pkg/api/v0/types.go

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ type RegistryExtensions struct {
1717
// ServerListResponse represents the paginated server list response
1818
type ServerListResponse struct {
1919
Servers []ServerJSON `json:"servers"`
20-
Metadata *Metadata `json:"metadata,omitempty"`
20+
Metadata Metadata `json:"metadata"`
2121
}
2222

2323
// ServerMeta represents the structured metadata with known extension fields
@@ -42,6 +42,5 @@ type ServerJSON struct {
4242
// Metadata represents pagination metadata
4343
type Metadata struct {
4444
NextCursor string `json:"next_cursor,omitempty"`
45-
Count int `json:"count,omitempty"`
46-
Total int `json:"total,omitempty"`
45+
Count int `json:"count"`
4746
}

0 commit comments

Comments
 (0)