(Updated auto-generated PR description from @tadasant / Claude on Feb 22, 2026) ## Motivation and Context Fixes #637 Server lifecycle management (deprecation and yanking) is a standard requirement for package registries. Use cases like rebranding, security vulnerabilities, and end-of-life servers demand the ability to mark servers as deprecated or deleted, with optional messaging to guide consumers toward alternatives. ## Changes ### New API endpoints - **`PATCH /v0/servers/{serverName}/versions/{version}/status`** — Update the lifecycle status of a single server version - **`PATCH /v0/servers/{serverName}/status`** — Update the lifecycle status of all versions of a server in a single transaction Both endpoints accept: ```json { "status": "active|deprecated|deleted", "statusMessage": "Optional message (max 500 chars) explaining the change" } ``` ### New CLI command - **`mcp-publisher status <serverName> [version]`** — Update server lifecycle status from the command line - `--status` (required): `active`, `deprecated`, or `deleted` - `--message`: Optional status message - `--all-versions`: Apply to all versions of the server (replaces the `<version>` argument) ### API response changes `RegistryExtensions` now includes two new fields: - `statusChangedAt` — Timestamp of the last status change - `statusMessage` — Optional free-form message (e.g., deprecation reason, migration guidance) ### List endpoint changes - New `include_deleted` query parameter on `GET /v0/servers` — defaults to `false`, hiding deleted servers from listings - When `updated_since` is provided, `include_deleted` is automatically set to `true` for incremental sync ### Database - Migration `013_add_status_fields.sql`: Adds `status_changed_at` (NOT NULL, initialized from `published_at`) and `status_message` columns to the `servers` table ### Design decisions (from review discussion) - **Dedicated status endpoints** rather than overloading the existing edit endpoint - **Bidirectional status transitions** — all transitions between `active`, `deprecated`, and `deleted` are allowed - **`statusMessage` as free-form text** — no structured `nextName` or `alternativeUrl` fields (per maintainer feedback, to avoid complexity around chaining, trust transfer, etc.) - **Publish permission** grants status change access (not limited to admin/edit) - **Status message auto-cleared** when transitioning back to `active` Good, now I have the full picture. Here's the addendum: ### Consumer-facing API changes The new status fields live inside `_meta["io.modelcontextprotocol.registry/official"]` on every `ServerResponse`. This is the existing `RegistryExtensions` object — two new fields are added alongside the existing ones: **Before:** ```json { "server": { "name": "com.example/my-server", "...": "..." }, "_meta": { "io.modelcontextprotocol.registry/official": { "status": "active", "publishedAt": "2025-06-01T00:00:00Z", "updatedAt": "2025-06-15T00:00:00Z", "isLatest": true } } } ``` **After:** ```json { "server": { "name": "com.example/my-server", "...": "..." }, "_meta": { "io.modelcontextprotocol.registry/official": { "status": "deprecated", "statusChangedAt": "2026-02-01T12:00:00Z", "statusMessage": "Deprecated in favor of com.example/my-server-v2", "publishedAt": "2025-06-01T00:00:00Z", "updatedAt": "2026-02-01T12:00:00Z", "isLatest": true } } } ``` | New field | Type | Present when | |-----------|------|-------------| | `statusChangedAt` | `string` (RFC3339) | Always — initialized to `publishedAt` for existing records | | `statusMessage` | `string` (max 500 chars) | Only when set — `null`/omitted for active servers (auto-cleared on transition to active) | These fields appear on **every endpoint that returns a `ServerResponse`**: `GET /v0/servers`, `GET /v0/servers/{name}`, `GET /v0/servers/{name}/versions/{version}`, and the new PATCH status endpoints. ### List endpoint filtering `GET /v0/servers` gains an `include_deleted` query parameter: | Scenario | Behavior | |----------|----------| | No `include_deleted` param | Deleted servers hidden (default `false`) | | `include_deleted=true` | Deleted servers included in results | | `updated_since` provided | `include_deleted` forced to `true` for incremental sync | ## How Has This Been Tested? - Unit tests for status handler (`status_test.go`) covering status transitions, permission checks, validation errors, and the all-versions endpoint - Unit tests for the CLI command (`status_test.go`) - Integration with existing server/edit handler tests - Database layer tests for the new status update and query methods - Tested locally with `make dev-compose` ## Types of changes - [x] New feature (non-breaking change which adds functionality) ## Checklist - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [x] I have added appropriate error handling - [x] I have added or updated documentation as needed ## Open items from review - [ ] `include_deleted` silent override: When `updated_since` is provided and `include_deleted=false` is explicitly passed, should return a 400 error rather than silently overriding ([thread](https://github.com/modelcontextprotocol/registry/pull/893#discussion_r2100879360)) — agreed upon but may not yet be implemented
5.1 KiB
Registry API Changelog
Changes to the REST API endpoints and responses.
Unreleased
Added
Server Status Management Endpoints
New endpoints for managing server lifecycle status:
PATCH /v0/servers/{serverName}/versions/{version}/status- Update status of a specific server versionPATCH /v0/servers/{serverName}/status- Update status of all versions of a server in a single transaction
Status values:
active- Server is active and visible in default listingsdeprecated- Server is deprecated but still visible with a warning messagedeleted- Server is hidden from default listings
Authentication: Requires publish or edit permission for the server namespace.
New Response Fields
New fields added to _meta["io.modelcontextprotocol.registry/official"] (RegistryExtensions):
statusChangedAt- Timestamp when the server status was last changedstatusMessage- Optional message explaining status change (e.g., deprecation reason, migration guidance)
Server Filtering Enhancements
New include_deleted query parameter added to multiple endpoints:
GET /v0/servers- Include deleted servers in list results (default:false, automaticallytruewhenupdated_sinceis provided)GET /v0/servers/{serverName}/versions/{version}- Include deleted servers in detail results (default:false)GET /v0/servers/{serverName}/versions- Include deleted servers in version history (default:false)
2025-10-17
Added
API Versioning - v0.1 Introduction
Introduced /v0.1/ as a stable API version while /v0/ continues as the development version.
New version paths:
- All
/v0/endpoints are now also available at/v0.1/ - Both versions currently share identical behavior
/v0/will continue to evolve with additive changes (new optional fields, new endpoints)/v0.1/will remain stable with only additive, backward-compatible changes- Both versions will be maintained until a future v1.0 release
Migration guidance:
- Production applications should consider using
/v0.1/for stability - Development and testing can continue using
/v0/for latest features - No immediate action required -
/v0/remains fully supported
⚠️ BREAKING CHANGES
Endpoint Simplification
Removed redundant endpoint to simplify API surface and reduce implementation burden for subregistries.
Removed endpoints:
GET /v0/servers/{serverName}- UseGET /v0/servers/{serverName}/versions/latestinstead
2025-09-29
⚠️ BREAKING CHANGES
API Endpoint Restructuring
API endpoints updated to use server names instead of server IDs for better usability.
Changed endpoints:
GET /v0/servers/{server_id}→GET /v0/servers/{serverName}GET /v0/servers/{server_id}/versions→GET /v0/servers/{serverName}/versions
New endpoints:
GET /v0/servers/{serverName}/versions/{version}- Get specific server versionPUT /v0/servers/{serverName}/versions/{version}- Edit server version (admin only)
Response format changes:
- Introduced
ServerResponseschema separating server data from registry metadata - Moved
statusfield from server data to_meta.io.modelcontextprotocol.registry/official - Removed
io.modelcontextprotocol.registry/officialmetadata fromServerDetailschema
Changed
- OpenAPI spec version:
2025-09-16→2025-09-29
2025-09-16
⚠️ BREAKING CHANGES
Server ID Endpoints (#396)
API endpoints updated for consistent server identification across versions.
Problem: Each server version had a unique ID, preventing version history tracking and server renaming.
Solution: Introduced consistent server identification across versions.
Changed endpoints:
GET /v0/servers/{id}→GET /v0/servers/{server_id}
New endpoints:
GET /v0/servers/{server_id}/versions- List all versions of a serverGET /v0/servers/{server_id}?version=1.0.0- Get specific version
Changed response metadata:
_meta.*.id→_meta.*.serverId- Added:
_meta.*.versionId
Migration Examples
Old Structure:
{
"_meta": {
"io.modelcontextprotocol.registry/official": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"published_at": "2024-01-01T00:00:00Z",
"is_latest": true
}
}
}
New Structure:
{
"_meta": {
"io.modelcontextprotocol.registry/official": {
"serverId": "550e8400-e29b-41d4-a716-446655440000",
"versionId": "773f9b2e-1a47-4c8d-b5e6-2f8d9c4a7b3e",
"published_at": "2024-01-01T00:00:00Z",
"is_latest": true
}
}
}
Migration Checklist for API Consumers
- Update API endpoint URLs from
/v0/servers/{id}to/v0/servers/{server_id} - Update code reading registry metadata from
idtoserverId/versionId - Add support for new
/v0/servers/{server_id}/versionsendpoint if needed - Update JSON parsing to expect camelCase field names
- Test with new API responses
Changed
- OpenAPI spec version:
2025-07-09→2025-09-16
2025-07-09
Initial release of the Registry API.