Init world. Basic registry API server
Work in progress . This commit adds the core registry service implementation with methods to: - Retrieve all registry entries - List entries with cursor-based pagination - Fetch specific server details by ID
This commit is contained in:
parent
2e8c761edf
commit
4fb5bc477e
3 changed files with 1702 additions and 2 deletions
109
internal/service/fake_service.go
Normal file
109
internal/service/fake_service.go
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/modelcontextprotocol/registry/internal/database"
|
||||
"github.com/modelcontextprotocol/registry/internal/model"
|
||||
)
|
||||
|
||||
// fakeRegistryService implements RegistryService interface with an in-memory database
|
||||
type fakeRegistryService struct {
|
||||
db *database.MemoryDB
|
||||
}
|
||||
|
||||
// NewFakeRegistryService creates a new fake registry service with pre-populated data
|
||||
func NewFakeRegistryService() RegistryService {
|
||||
// Sample registry entries with updated model structure
|
||||
registries := []*model.Entry{
|
||||
{
|
||||
ID: uuid.New().String(),
|
||||
Name: "bluegreen/mcp-server",
|
||||
Description: "A dummy MCP registry for testing",
|
||||
Repository: model.Repository{
|
||||
URL: "https://github.com/example/mcp-1",
|
||||
SubFolder: "server",
|
||||
Branch: "main",
|
||||
Commit: "abc123def456",
|
||||
},
|
||||
Version: "1.0.0",
|
||||
},
|
||||
{
|
||||
ID: uuid.New().String(),
|
||||
Name: "orangepurple/mcp-server",
|
||||
Description: "Another dummy MCP registry for testing",
|
||||
Repository: model.Repository{
|
||||
URL: "https://github.com/example/mcp-2",
|
||||
SubFolder: "mcp",
|
||||
Branch: "develop",
|
||||
Commit: "def456ghi789",
|
||||
},
|
||||
Version: "2.1.0",
|
||||
},
|
||||
{
|
||||
ID: uuid.New().String(),
|
||||
Name: "greenyellow/mcp-server",
|
||||
Description: "Yet another dummy MCP registry for testing",
|
||||
Repository: model.Repository{
|
||||
URL: "https://github.com/example/mcp-3",
|
||||
SubFolder: "",
|
||||
Branch: "feature/mcp-server",
|
||||
Commit: "789jkl012mno",
|
||||
},
|
||||
Version: "0.9.5",
|
||||
},
|
||||
}
|
||||
|
||||
// Create a new in-memory database
|
||||
registryMap := make(map[string]*model.Entry)
|
||||
for _, entry := range registries {
|
||||
registryMap[entry.ID] = entry
|
||||
}
|
||||
memDB := database.NewMemoryDB(registryMap)
|
||||
return &fakeRegistryService{
|
||||
db: memDB,
|
||||
}
|
||||
}
|
||||
|
||||
// List retrieves MCPRegistry entries with optional filtering and pagination
|
||||
func (s *fakeRegistryService) List(cursor string, limit int) ([]model.Entry, string, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Use the database's List method with no filters to get all entries
|
||||
entries, nextCursor, err := s.db.List(ctx, nil, cursor, limit)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
// Convert from []*model.Entry to []model.Entry
|
||||
result := make([]model.Entry, len(entries))
|
||||
for i, entry := range entries {
|
||||
result[i] = *entry
|
||||
}
|
||||
|
||||
return result, nextCursor, nil
|
||||
}
|
||||
|
||||
// GetByID retrieves a specific server detail by its ID
|
||||
func (s *fakeRegistryService) GetByID(id string) (*model.ServerDetail, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Use the database's GetByID method to retrieve the server detail
|
||||
serverDetail, err := s.db.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return serverDetail, nil
|
||||
}
|
||||
|
||||
// Close closes the in-memory database connection
|
||||
func (s *fakeRegistryService) Close() error {
|
||||
return s.db.Close()
|
||||
}
|
||||
83
internal/service/registry_service.go
Normal file
83
internal/service/registry_service.go
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
"time"
|
||||
|
||||
"github.com/modelcontextprotocol/registry/internal/database"
|
||||
"github.com/modelcontextprotocol/registry/internal/model"
|
||||
)
|
||||
|
||||
// registryServiceImpl implements the RegistryService interface using our Database
|
||||
type registryServiceImpl struct {
|
||||
db database.Database
|
||||
}
|
||||
|
||||
// NewRegistryServiceWithDB creates a new registry service with the provided database
|
||||
func NewRegistryServiceWithDB(db database.Database) RegistryService {
|
||||
return ®istryServiceImpl{
|
||||
db: db,
|
||||
}
|
||||
}
|
||||
|
||||
// GetAll returns all registry entries
|
||||
func (s *registryServiceImpl) GetAll() ([]model.Entry, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Use the database's List method with no filters to get all entries
|
||||
entries, _, err := s.db.List(ctx, nil, "", 30)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Convert from []*model.Entry to []model.Entry
|
||||
result := make([]model.Entry, len(entries))
|
||||
for i, entry := range entries {
|
||||
result[i] = *entry
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
// List returns registry entries with cursor-based pagination
|
||||
func (s *registryServiceImpl) List(cursor string, limit int) ([]model.Entry, string, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// If limit is not set or negative, use a default limit
|
||||
if limit <= 0 {
|
||||
limit = 30
|
||||
}
|
||||
|
||||
// Use the database's List method with pagination
|
||||
entries, nextCursor, err := s.db.List(ctx, nil, cursor, limit)
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
// Convert from []*model.MCPRegistry to []model.MCPRegistry
|
||||
result := make([]model.Entry, len(entries))
|
||||
for i, entry := range entries {
|
||||
result[i] = *entry
|
||||
}
|
||||
|
||||
return result, nextCursor, nil
|
||||
}
|
||||
|
||||
// GetByID retrieves a specific server detail by its ID
|
||||
func (s *registryServiceImpl) GetByID(id string) (*model.ServerDetail, error) {
|
||||
// Create a timeout context for the database operation
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
|
||||
// Use the database's GetByID method to retrieve the server detail
|
||||
serverDetail, err := s.db.GetByID(ctx, id)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return serverDetail, nil
|
||||
}
|
||||
9
internal/service/service.go
Normal file
9
internal/service/service.go
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
package service
|
||||
|
||||
import "github.com/modelcontextprotocol/registry/internal/model"
|
||||
|
||||
// RegistryService defines the interface for registry operations
|
||||
type RegistryService interface {
|
||||
List(cursor string, limit int) ([]model.Entry, string, error)
|
||||
GetByID(id string) (*model.ServerDetail, error)
|
||||
}
|
||||
Loading…
Reference in a new issue