feat: add admin edit endpoint for server moderation (#315)

## Summary

Implements `PUT /v0/servers/{id}` admin edit endpoint to address part of
issue #182, providing an API-based solution for server moderation
without requiring direct database access.

- **New endpoint**: `PUT /v0/servers/{id}` for editing existing servers
- **Security**: Uses existing JWT auth with `PermissionActionEdit`
permissions
- **Anti-undelete protection**: Added `ServerStatusDeleted` status that
cannot be reverted
- **Full implementation**: Database, service, API, and comprehensive
test coverage

## Key Use Cases

- Mark malicious servers as `deleted` for takedown
- Update server metadata for moderation actions

Related to: https://github.com/modelcontextprotocol/registry/issues/182
(but that is not _done_ yet because we need admins to be able to login
(probably with #283), and need to add docs on how to do the takedown,
and probably guidelines on what we will/won't takedown)
This commit is contained in:
adam jones 2025-08-27 21:28:04 +01:00 • committed by GitHub
commit 6431f23107
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -246,6 +246,29 @@ func (db *MemoryDB) UpdateLatestFlag(ctx context.Context, id string, isLatest bo
return ErrNotFound
}
// UpdateServer updates an existing server record with new server details
func (db *MemoryDB) UpdateServer(ctx context.Context, id string, serverDetail model.ServerDetail, publisherExtensions map[string]interface{}) (*model.ServerRecord, error) {
if ctx.Err() != nil {
return nil, ctx.Err()
}
db.mu.Lock()
defer db.mu.Unlock()
entry, exists := db.entries[id]
if !exists {
return nil, ErrNotFound
}
// Update the server details
entry.ServerJSON = serverDetail
entry.PublisherExtensions = publisherExtensions
entry.RegistryMetadata.UpdatedAt = time.Now()
// Return the updated record
return entry, nil
}
// Close closes the database connection
// For an in-memory database, this is a no-op
func (db *MemoryDB) Close() error {