| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
bb84ea69e8 |
Publisher-managed "deleted" support (#893)
(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 |
||
|
|
b21c6f564d |
Changes on the server.json format and the API (#562) | ||
|
|
747ad310bb |
Fix atomic latest version update to prevent missing isLatest flags (#530)
## Summary Fixes a race condition where a server could have no version marked as `isLatest` if the database operations failed independently. ## Changes - **CreateServer signature**: Now accepts `oldLatestVersionID` parameter to atomically unmark previous latest version - **PostgreSQL implementation**: Uses a transaction to ensure UPDATE (unmark old latest) and INSERT (create new version) happen atomically - **Service layer**: Maintains `WithPublishLock` for concurrent operation serialization - **Two-level protection**: Advisory lock prevents races, transaction ensures atomicity ## Test plan - [x] Existing race condition tests pass - [x] Integration tests pass - [x] Unit tests pass 🤖 Generated with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
ddcc586842 |
Remove the in-memory database (#537)
<!-- Provide a brief summary of your changes --> ## Motivation and Context <!-- Why is this change needed? What problem does it solve? --> The follow PR removes the in-memory database option from the registry. We had a chat about this with @domdomegg and although it is supposed to be convenient, it isn't that useful in reality. We want to test and develop the registry in a setup that is closer to the environment it is supposed to be run. One of the main reasons are: * We don't use it anywhere else besides unit testing and potentially local development. Instead we should use postgresql for reliable results (in-memory was actually giving false positive results) * We have to keep maintaining it and make sure it mimics the behaviour we have for postgresql which is not yielding a lot of value ## How Has This Been Tested? <!-- Have you tested this in a real application? Which scenarios were tested? --> Yes, I've updated the test unit make target to run in the postgresql environment and now we can see the race condition issue happening. ## Breaking Changes <!-- Will users need to update their code or configurations? --> No ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [ ] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [ ] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed ## Additional context <!-- Add any other context, implementation notes, or design decisions --> --------- Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com> |
||
|
|
60c801c0c2 |
Fix race conditions in concurrent server publishing (#528)
## Summary Fixes race conditions in concurrent server publishing that could result in data integrity violations: - Multiple versions marked as `isLatest=true` for the same server - Duplicate (serverId, version) combinations - Same server name assigned different serverIDs ## Solution Uses two complementary approaches for correctness: ### 1. PostgreSQL Advisory Locks - Serializes concurrent publishes per server name using `pg_advisory_xact_lock` - Uses FNV-1a hash to convert server name to lock ID - Transaction-scoped locks auto-release on commit/rollback - **Required after #465**: The serverId introduction means concurrent publishes must atomically coordinate whether to reuse an existing serverId (for additional versions) or generate a new one (for first version). Without locks, race conditions would assign different serverIDs to versions of the same server. ### 2. Unique Constraints (Migration 007) Two new indexes provide data integrity guarantees: - **idx_unique_server_version**: Ensures (serverId, version) is unique across all versions - **idx_unique_latest_version**: Partial index ensuring only one version per serverId has `isLatest=true` These constraints serve as defense-in-depth safety nets. Even if lock logic had a bug, the database would reject integrity violations. Also drops redundant `idx_servers_version_id` since `version_id` is already the primary key. ## Why WithPublishLock validation is needed after #465 The `ctx.Err()` check at the start of `WithPublishLock` is critical because: 1. After #465 introduced serverId, the publish flow must atomically check existing versions and assign/reuse serverId 2. If the context is cancelled during lock acquisition, we could deadlock 3. Checking ctx validity before acquiring locks prevents these deadlocks ## Testing Added `TestPublishConcurrentVersionsNoRace` with 100 concurrent goroutines publishing different versions of the same server. All succeed with: - Exactly one version marked as latest - All versions sharing the same serverId - No duplicate (serverId, version) combinations NB: this only covers the in memory db, not the postgres db. It'd be nice to write tests for this one as well, but our current setup is a bit annoying for this. Separately looking into ways to easily run all our tests with real postgres and ideally scrap memory.go completely. |
||
|
|
56e8b4879b |
Introduce serverId, rename id to versionId (#465)
Wielded Claude Code to do this; across many iterations and have reviewed all the code + largely rewritten the PR commentary here. This PR implements the server ID consistency changes from [#396](https://github.com/modelcontextprotocol/registry/issues/396). Our goal is to: - Rename `id` to `versionId` to make it clear that it is the ID for a specific version, not a server - Introduce `serverId` as a net new concept. This will be 1:1 with `name`. While not strictly necessary (we could just use name as a PK), the convention of having a UUID as an ID on our objects is just a helpful subjective architecture decision. Plus also leaves open the door to reconsidering the "should we allow renames" question. ## Key Changes ### 🗄️ Database Schema Changes - **Renamed**: `id` column → `version_id` (unique identifier for each server version) ### 📋 Metadata Structure Updates - **JSON Schema**: Updated `_meta.io.modelcontextprotocol.registry/official` to include: - `serverId`: Consistent ID across all versions of a server - `versionId`: Unique ID for this specific version (renamed from `id`) ### 🔧 API Endpoint Updates - **New endpoint structure**: Changed from version-ID-based to server-ID-based URLs: - `GET /v0/servers/{server_id}` - Get latest version of server - `GET /v0/servers/{server_id}?version=X.X.X` - Get specific version - `GET /v0/servers/{server_id}/versions` - List all versions of a server - `PUT /v0/servers/{server_id}?version=X.X.X` - Edit specific version - **Consistent URL patterns**: All server endpoints now use `server_id` as the primary identifier ### Database Migration Strategy The migration (`005_add_server_id_rename_version_id.sql`): 1. Adds new `version_id` column 2. Generates deterministic UUIDs for servers with the same name 3. Updates JSON metadata to add `serverId` and rename `id` to `versionId` 4. Copies existing `id` values to `version_id` column 5. Drops old `id` column and makes `version_id` the new primary key ## Testing Besides of course automated tests passing, I: 1. Set up my local db with the pre-005-migration state, imported all the production data 2. Ran the migration 3. Spot checked some diffs of the data that resulted -- ```json // before { "name": "io.github.ruvnet/ruv-swarm", "_meta": { "io.modelcontextprotocol.registry/official": { "id": "0a9cda7f-2b73-4839-844b-6582f335de42", "is_latest": false, "updated_at": "2025-09-10T17:21:34.92137012Z", "published_at": "2025-09-10T17:15:32.69690433Z" } }, "version": "1.0.18", "repository": { "url": "", "source": "" }, "description": "Neural network swarm orchestration with WebAssembly acceleration and MCP integration" } // after { "name": "io.github.ruvnet/ruv-swarm", "_meta": { "io.modelcontextprotocol.registry/official": { "serverId": "e8538952-96af-4a33-9e31-7fbed012521e", "is_latest": false, "versionId": "0a9cda7f-2b73-4839-844b-6582f335de42", "updated_at": "2025-09-10T17:21:34.92137012Z", "published_at": "2025-09-10T17:15:32.69690433Z" } }, "version": "1.0.18", "repository": { "url": "", "source": "" }, "description": "Neural network swarm orchestration with WebAssembly acceleration and MCP integration" } ``` Servers that have multiple versions stayed consistent in their `serverId`: ```json // First version { "name": "app.getdialer/dialer", "_meta": { "io.modelcontextprotocol.registry/official": { "serverId": "80f08bdb-f3e4-4f19-b072-1676ae49b663", "is_latest": false, "versionId": "04f25b17-331d-48d7-b08b-37baece208a7", "updated_at": "2025-09-09T00:16:49.162620072Z", "published_at": "2025-09-08T23:47:09.452137971Z" } }, "status": "active", "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", "remotes": [ { "url": "https://getdialer.app/mcp", "type": "streamable-http" }, { "url": "https://getdialer.app/sse", "type": "sse" } ], "version": "1.0.0", "repository": { "url": "", "source": "" }, "description": "An MCP server that provides your you make outbound phone calls using your own phone number" } // Second version { "name": "app.getdialer/dialer", "_meta": { "io.modelcontextprotocol.registry/official": { "serverId": "80f08bdb-f3e4-4f19-b072-1676ae49b663", "is_latest": true, "versionId": "faa26cb9-3aad-415e-aece-f715fff5fe5e", "updated_at": "2025-09-09T00:16:49.107842808Z", "published_at": "2025-09-09T00:16:49.107842808Z" } }, "status": "active", "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", "remotes": [ { "url": "https://getdialer.app/mcp", "type": "streamable-http" }, { "url": "https://getdialer.app/sse", "type": "sse" } ], "version": "1.0.1", "repository": { "url": "", "source": "" }, "description": "An MCP server that provides lets you make outbound phone calls using your own phone number" } ``` And I also tried publishing a test server anew; looked good: ```bash ⏺ Bash(curl -s "http://localhost:8080/v0/servers/102dc4e4-6ca8-40e6-aa11-cd45763d3352" | jq '.') ⎿ { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", "name": "io.modelcontextprotocol.anonymous/test-claude-migration-server", "description": "A test server to verify the new migration and API endpoints work correctly", "status": "active", "repository": { "url": "https://github.com/example/test-claude-migration-server", "source": "github", "id": "example/test-claude-migration-server" }, "version": "1.0.0", "_meta": { "io.modelcontextprotocol.registry/official": { "serverId": "102dc4e4-6ca8-40e6-aa11-cd45763d3352", "versionId": "48c9cd55-7bc4-4ac2-896e-59e81eb653e4", "published_at": "2025-09-12T18:33:23.264203-07:00", "updated_at": "2025-09-12T18:33:23.264203-07:00", "is_latest": true } } } ⏺ Bash(curl -s "http://localhost:8080/v0/servers/102dc4e4-6ca8-40e6-aa11-cd45763d3352/versions" | jq '.') ⎿ { "servers": [ { "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", "name": "io.modelcontextprotocol.anonymous/test-claude-migration-server", "description": "A test server to verify the new migration and API endpoints work correctly", "status": "active", "repository": { "url": "https://github.com/example/test-claude-migration-server", "source": "github", "id": "example/test-claude-migration-server" }, "version": "1.0.0", "_meta": { "io.modelcontextprotocol.registry/official": { "serverId": "102dc4e4-6ca8-40e6-aa11-cd45763d3352", "versionId": "48c9cd55-7bc4-4ac2-896e-59e81eb653e4", "published_at": "2025-09-12T18:33:23.264203-07:00", "updated_at": "2025-09-12T18:33:23.264203-07:00", "is_latest": true } } } ], "metadata": { "count": 1 } } ``` Co-Authored-By: Claude <noreply@anthropic.com> --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Preeti Dewani <preetidewani1990@gmail.com> Co-authored-by: adam jones <adamj+git@anthropic.com> Co-authored-by: Adam Jones <adamj@anthropic.com> |
||
|
|
a85456a9b9 |
Add filtering functionality to server list endpoint (#374)
## Summary - Adds `updated_since`, `search`, and `version` query parameters to `GET /v0/servers` - Enables incremental synchronization via RFC3339 timestamp filtering - Provides simple substring search on server names - Supports latest version filtering with `version=latest` This implementation provides the core filtering capabilities needed for efficient registry synchronization and improved server discovery. Fixes #291 Fixes #135 |
||
|
|
9d9a02c57f |
Database implementation cleanup (#335)
## Motivation and Context The database logic was getting a bit unwieldy and fragile - especially because business logic that should really have lived at the registry service level was being pushed into the persistence level. This PR tightens the interface, simplifies the code there, as well as rips out a bunch of mocks etc. we don't need. ## How Has This Been Tested? Locally everything works ## Breaking Changes The list endpoint was surprisingly always filtering for isLatest only, which seems like a bug? I have removed this filter. |
||
|
|
218b0b422d |
Implement flattened _meta format for server extensions (#331)
## Summary This PR implements the flattened `_meta` format for server extensions as discussed in #284, replacing the confusing wrapper format with a clean single-file approach. **Before (wrapper format):** ```json { "server": { "name": "my-server", "description": "..." }, "x-publisher": { "build_info": "..." }, "x-io.modelcontextprotocol.registry": { "id": "...", "published_at": "..." } } ``` **After (flattened format):** ```json { "name": "my-server", "description": "...", "_meta": { "publisher": { "build_info": "..." }, "io.modelcontextprotocol.registry": { "id": "...", "published_at": "..." } } } ``` ## Key Changes - **Flattened Format**: Single `ServerJSON` file with structured `_meta` field - **Better DX**: Publishers maintain one file instead of separate server.json + extensions.json - **MCP Compliance**: Uses standard `_meta` mechanism instead of `x-*` prefixes - **Simplified Database**: PostgreSQL now uses simple `id, value` table structure - **Type Safety**: Structured `ServerMeta` with known extension fields ## Database Migration Added migration `003_simplify_to_key_value.sql` that drops the complex relational structure and creates a simple key-value table. This significantly simplifies database management. ## Testing - All core tests passing (validators, service layer) - Schema validation working for all 10 examples - Seed data successfully migrated (396 entries) - Publishing functionality verified Fixes #284 |
||
|
|
c0a94cca8c |
Rename api/v1 -> api/v0 to match API paths (#320)
This PR renames the API paths from v1 to v0 to align with the actual API versioning scheme. |
||
|
|
099a2d702e |
Deduplicate server JSON structs between publisher and registry (#318)
<!-- Provide a brief summary of your changes --> ## Motivation and Context <!-- Why is this change needed? What problem does it solve? --> The following PR eliminates duplicate struct definitions by migrating the publisher tool to use canonical types from pkg/model, creating a single source of truth across the codebase. The publisher tool previously had its own copies of structs that were duplicated, ie. ServerJSON, Package, Repository, VersionDetail, EnvironmentVariable, RuntimeArgument and a few others which was not optimal **Changes in the PR:** - Refactored the structs to single canonical types located at pkg/model - Refactor the implementation to use/build canonical structures directly - Remove all duplicate definitions (5 structs eliminated) - Publisher now uses model.ServerJSON, model.Package, model.Repository, etc. - Renamed some of the structs to better reflect their use case, i.e. ServerJSON instead of ServerDetail - Fixes an issue where the Remote property was missing from the previous publisher copy of the Server **Benefits:** - Single source of truth - Schema changes in one place - Type safety - Compiler catches mismatches - Enhanced validation - Field constraints and bson tags - Zero breaking changes - Same CLI interface and JSON output - Future-proof - New canonical fields automatically available Supersedes: #217 and #240 ## How Has This Been Tested? <!-- Have you tested this in a real application? Which scenarios were tested? --> Locally ## Breaking Changes <!-- Will users need to update their code or configurations? --> No ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [x] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [ ] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [ ] My code follows the repository's style guidelines - [ ] New and existing tests pass locally - [ ] I have added appropriate error handling - [ ] I have added or updated documentation as needed ## Additional context <!-- Add any other context, implementation notes, or design decisions --> --------- Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com> |
||
|
|
6431f23107 |
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)
|
||
|
|
923b2e07b9 |
feat: implement DNS namespace validation and remote URL uniqueness checks (#306)
## Summary - Add reverse-DNS namespace format validation for server names (namespace/name) - Validate remote URLs match the DNS namespace derived from hostname - Prevent duplicate remote URLs across different servers - Support localhost/development URLs without namespace restrictions - Add comprehensive test coverage for validation logic - Update database layer to support remote_url filtering Fixes #180 by ensuring proper namespace governance and preventing URL conflicts. --------- Co-authored-by: Claude <noreply@anthropic.com> |
||
|
|
7b211a46d6 |
feat: implement server versioning approach with semantic versioning support (#296)
This implements the versioning approach agreed upon in issue #158: ## Key Changes ### Documentation - Added comprehensive versioning guide (docs/versioning.md) - Updated FAQ with versioning guidance and best practices - Enhanced schema description with SHOULD recommendations ### Schema Updates - Added 255-character limit for version strings in schema.json - Enhanced version field description with semantic versioning guidance ### Implementation - New isSemanticVersion() function for proper semver detection - Enhanced compareSemanticVersions() with prerelease support - Implemented compareVersions() strategy: * Both semver: use semantic comparison * Neither semver: use timestamp comparison * Mixed: semver versions always take precedence - Updated publish logic to determine "latest" using new strategy - Added version length validation (255 char max) ### Versioning Strategy 1. Version MUST be string up to 255 characters 2. SHOULD use semantic versioning for predictable ordering 3. SHOULD align with package versions to reduce confusion 4. MAY use prerelease labels for registry-specific versions 5. Registry attempts semver parsing, falls back to timestamp ordering 6. Clients SHOULD follow same comparison logic Resolves #158 --------- Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com> Co-authored-by: adam jones <domdomegg@users.noreply.github.com> |
||
|
|
8d7e471fd3 |
Allow for vendor extensions on servers (#298)
<!-- Provide a brief summary of your changes -->
This PR serves as a placeholder and brings together all of the changes
related to supporting vendor extensions passed through the API. The idea
is to have a single place to track and review the work as it comes
together (even if it’s still a bit of a work in progress).
**The changes in this PR cover:**
* Updates on the data model
* Updates on both databases (in-memory and postgresql), added a new
table to PSQL for tracking the extensions leaving the server table only
for the clean server.json properties
* Updates the seed.json file (thus the big line change)
* Adds a seed-migrate tool to help migrating an existing seed file to
the new format
* Updates the seed import mechanism to support this
* Updates the existing tests - unit, integration and validation tests
* Adds the publish handler to the OpenAPI spec (it was missing)
* Fixes linting errors
* Updates on the API side on (publish, list, get) to support the new
format of `ServerResponse` -
```
{
"server": {},
"x-io.modelcontextprotocol.registry": {}, /*not available for publish since this gets populated by the registry*/
"x-publisher": {}
}
```
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
Motivated by the discussions in:
https://github.com/modelcontextprotocol/registry/discussions/284
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
Locally and by running all of the tests
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
Yes, it changes both the API and the format of the seed file
## Types of changes
<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->
- [ ] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update
---
Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
Co-authored-by: adam jones <domdomegg+git@gmail.com>
|
||
|
|
ebaf4c9c99 |
Refactor database implementation to use PostgreSQL instead of MongoDB (#289)
Fixes #228 ## Motivation and Context See #19 ## How Has This Been Tested? - Run locally - Run in docker compose - Run infra in minikube - Unit and integration tests all passing :) ## Breaking Changes Yes: users will not be able to access any data they used to have in custom mongodb. We are accepting this breaking change, given the registry is in experimental development status. ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [ ] Bug fix (non-breaking change which fixes an issue) - [ ] New feature (non-breaking change which adds functionality) - [x] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [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 ## Additional context I have not implemented connection pooling support for simplicity, and because cloudnative-pg already provides built-in connection pooling with pgBouncer so if we want it later we can switch to this endpoint easily. |
||
|
|
774a0df592 |
Add validation tools for server.json schemas and examples (#176)
This is a first PR for #159 - adding some validation scripts. I want to get to a place where we are confident that making schema changes is in sync with the rest of our code. Step one is making sure the schemas are in sync with our examples. Step two will be making sure the schemas are in sync with our actual Registry implementation code. This is just for the JSON right now; if we're feeling good about this approach I'll do an analogous change for the OpenAPI schemas as well. I'll also follow with adding usage of these scripts to our CI pipeline so we have automated checks on them with every change. ## Summary - Added CLI validation tools for JSON schemas and examples in `docs/server-json/` - Fixed some minor validation errors found in `examples.md` - Ensures schema consistency and example validity in CI/CD pipelines ## Changes ### New Validation Tools 1. **`tools/validate-schemas`** - Validates that `schema.json` and `registry-schema.json` are valid JSON Schema documents 2. **`tools/validate-examples`** - Validates all JSON examples in `examples.md` against both schemas ### Key Features - ✅ Validates JSON schema syntax and structure - ✅ Validates all examples against both base and registry schemas - ✅ Tracks validation counts to prevent silent failures - ✅ Proper exit codes for CI integration - ✅ Clear error messages for debugging ### Fixes to examples.md - Added missing `repository.id` field in NuGet example - Changed `repository.source` from "gitlab" to "github" in Docker example ### Usage ```bash # From repository root ./tools/validate-schemas.sh ./tools/validate-examples.sh ``` ## Testing I ran these scripts locally with minor (breaking) changes, which they each correctly reported. As submitted, they are both passing. 🤖 Co-authored with [Claude Code](https://claude.ai/code) --------- Co-authored-by: Claude <noreply@anthropic.com> Co-authored-by: Charles Lowell <10964656+chlowell@users.noreply.github.com> |
||
|
|
686fbe1e78 |
feat(database): support SeedFile import for memory database (#128)
<!-- Provide a brief summary of your changes --> Add SeedFile import support for memory database to ensure consistent seed data loading across both MongoDB and memory modes. ## Motivation and Context <!-- Why is this change needed? What problem does it solve? --> Previously, SeedFile import was only available when using MongoDB. After memory database support was added, it lacked this feature, leading to inconsistent behavior and missing seed data during development or testing. This PR solves the problem by enabling the application to load SeedFile data even when running with a memory database, ensuring consistency and improving the developer/testing experience. ## How Has This Been Tested? <!-- Have you tested this in a real application? Which scenarios were tested? --> ```bash $ export MCP_REGISTRY_DATABASE_TYPE="memory" $ ./scripts/test_endpoints.sh ================================================== MCP Registry Endpoint Test Script ================================================== This script expects the MCP Registry server to be running locally. Please ensure the server is started using one of the following methods: • Docker Compose: docker compose up • Direct execution: go run cmd/registry/main.go • Built binary: ./build/registry ================================================== Testing health endpoint: http://localhost:8080/v0/health Status Code: 200 Response: { "status": "ok", "github_client_id": "" } Health check successful ------------------------------------- Testing servers endpoint: http://localhost:8080/v0/servers Status Code: 200 Response Summary: Total registries: 30 servers Names: io.github.appcypher/awesome-mcp-servers io.github.kenjihikmatullah/productboard-mcp io.github.kyrietangsheng/mcp-server-nationalparks io.github.gongrzhe/redis-mcp-server io.github.zubeidhendricks/youtube-mcp-server io.github.zzaebok/mcp-wikidata io.github.ihor-sokoliuk/mcp-searxng io.github.sv/mcp-paradex-py io.github.felores/airtable-mcp io.github.eqtylab/mcp-guardian io.github.co-browser/attestable-mcp-server io.github.ubie-oss/mcp-vertexai-search io.github.kukapay/crypto-indicators-mcp io.github.pinecone-io/assistant-mcp io.github.metricool/mcp-metricool io.github.r-huijts/strava-mcp io.github.googleapis/genai-toolbox io.github.wilsonchenghy/shadertoy-mcp io.github.klavis-ai/klavis io.github.fireproof-storage/mcp-database-server io.github.xxxbrian/mcp-rquest io.github.geropl/linear-mcp-go io.github.amornpan/py-mcp-mssql io.github.chaindead/telegram-mcp io.github.bazinga012/mcp_code_executor io.github.lharries/whatsapp-mcp io.github.mektigboy/server-hyperliquid io.github.omar-v2/mcp-ical io.github.open-strategy-partners/osp_marketing_tools io.github.smn2gnt/mcp-salesforce Pagination Metadata: { "next_cursor": "0e45cb5a-5b45-47f3-8b5e-12bdf88d176a", "count": 30 } servers Details: { "servers": [ { "id": "0007544a-3948-4934-866b-b4a96fe53b55", "name": "io.github.appcypher/awesome-mcp-servers", "description": "Awesome MCP Servers - A curated list of Model Context Protocol servers", "repository": { "url": "https://github.com/appcypher/awesome-mcp-servers", "source": "github", "id": "895801050" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:16:40Z", "is_latest": true } }, { "id": "00613acb-73e2-4f93-8b96-296df17316c8", "name": "io.github.kenjihikmatullah/productboard-mcp", "description": "Integrate the Productboard API into agentic workflows via MCP", "repository": { "url": "https://github.com/kenjihikmatullah/productboard-mcp", "source": "github", "id": "939104710" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:12:44Z", "is_latest": true } }, { "id": "010904ec-6e39-4bdc-878a-75a6e79d0500", "name": "io.github.kyrietangsheng/mcp-server-nationalparks", "description": "", "repository": { "url": "https://github.com/KyrieTangSheng/mcp-server-nationalparks", "source": "github", "id": "951713109" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:11:05Z", "is_latest": true } }, { "id": "01129bff-3d65-4e3d-8e82-6f2f269f818c", "name": "io.github.gongrzhe/redis-mcp-server", "description": "A Redis MCP server (pushed to https://github.com/modelcontextprotocol/servers/tree/main/src/redis) implementation for interacting with Redis databases. This server enables LLMs to interact with Redis key-value stores through a set of standardized tools.", "repository": { "url": "https://github.com/GongRzhe/REDIS-MCP-Server", "source": "github", "id": "907849235" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:13:21Z", "is_latest": true } }, { "id": "0278fd92-a009-4a47-a6df-5f77db37e6ab", "name": "io.github.zubeidhendricks/youtube-mcp-server", "description": "MCP Server for YouTube API, enabling video management, Shorts creation, and advanced analytics", "repository": { "url": "https://github.com/ZubeidHendricks/youtube-mcp-server", "source": "github", "id": "909607678" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:16:14Z", "is_latest": true } }, { "id": "02b79b89-cce8-4401-aa1f-255b01587266", "name": "io.github.zzaebok/mcp-wikidata", "description": "A server implementation for Wikidata API using the Model Context Protocol (MCP).", "repository": { "url": "https://github.com/zzaebok/mcp-wikidata", "source": "github", "id": "959274715" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:15:49Z", "is_latest": true } }, { "id": "02cdb980-1dcd-4345-a8d1-d3f3f522d04b", "name": "io.github.ihor-sokoliuk/mcp-searxng", "description": "MCP Server for SearXNG", "repository": { "url": "https://github.com/ihor-sokoliuk/mcp-searxng", "source": "github", "id": "907172461" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:13:48Z", "is_latest": true } }, { "id": "038a3024-c319-4a07-bd7f-9cf699cfebf1", "name": "io.github.sv/mcp-paradex-py", "description": "Connect AI agents to the Paradex trading platform. Retrieve market data, manage accounts, and execute trades seamlessly. Enhance your trading experience with automated tools and real-time insights.", "repository": { "url": "https://github.com/sv/mcp-paradex-py", "source": "github", "id": "944258239" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:12:24Z", "is_latest": true } }, { "id": "04216a87-0760-4f25-b809-42ffbfbb8962", "name": "io.github.felores/airtable-mcp", "description": "Search, create and update Airtable bases, tables, fields, and records using Claude Desktop and MCP (Model Context Protocol) clients", "repository": { "url": "https://github.com/felores/airtable-mcp", "source": "github", "id": "904238387" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:02:48Z", "is_latest": true } }, { "id": "04b4489b-db48-4aaa-98f6-036bcf5fd483", "name": "io.github.eqtylab/mcp-guardian", "description": "Manage / Proxy / Secure your MCP Servers", "repository": { "url": "https://github.com/eqtylab/mcp-guardian", "source": "github", "id": "926222936" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:16:58Z", "is_latest": true } }, { "id": "05ca6ccc-d6e1-47ab-ab8d-25949db9ada7", "name": "io.github.co-browser/attestable-mcp-server", "description": "Verify that any MCP server is running the intended and untampered code via hardware attestation.", "repository": { "url": "https://github.com/co-browser/attestable-mcp-server", "source": "github", "id": "955641588" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:03:19Z", "is_latest": true } }, { "id": "07ccf835-680a-42b4-bf0b-db28367519ee", "name": "io.github.ubie-oss/mcp-vertexai-search", "description": "A MCP server for Vertex AI Search", "repository": { "url": "https://github.com/ubie-oss/mcp-vertexai-search", "source": "github", "id": "934580342" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:07:44Z", "is_latest": true } }, { "id": "0852caec-a861-4f9c-9e94-a7c8b67a1641", "name": "io.github.kukapay/crypto-indicators-mcp", "description": "An MCP server providing a range of cryptocurrency technical analysis indicators and strategies.", "repository": { "url": "https://github.com/kukapay/crypto-indicators-mcp", "source": "github", "id": "953321792" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:05:01Z", "is_latest": true } }, { "id": "08668c6a-c2f6-47b0-a4e0-75a8ee9bcf10", "name": "io.github.pinecone-io/assistant-mcp", "description": "Pinecone Assistant MCP server", "repository": { "url": "https://github.com/pinecone-io/assistant-mcp", "source": "github", "id": "940446625" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:01:06Z", "is_latest": true } }, { "id": "091ef217-8e6d-4e06-8cb9-bc5ffe5467b1", "name": "io.github.metricool/mcp-metricool", "description": "This is a Multi-Agent Collaboration Protocol (MCP) server for interacting with the Metricool API. It allows AI agents to access and analyze social media metrics and campaign data from your Metricool account.", "repository": { "url": "https://github.com/metricool/mcp-metricool", "source": "github", "id": "967888435" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:10:11Z", "is_latest": true } }, { "id": "09a2ecf8-1774-490e-8542-2b25a6445a58", "name": "io.github.r-huijts/strava-mcp", "description": "A Model Context Protocol (MCP) server that connects to Strava API, providing tools to access Strava data through LLMs", "repository": { "url": "https://github.com/r-huijts/strava-mcp", "source": "github", "id": "961429605" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:14:17Z", "is_latest": true } }, { "id": "09f19715-3a0c-4900-932b-1ff0035aff11", "name": "io.github.googleapis/genai-toolbox", "description": "MCP Toolbox for Databases is an open source MCP server for databases.", "repository": { "url": "https://github.com/googleapis/genai-toolbox", "source": "github", "id": "812044182" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:00:18Z", "is_latest": true } }, { "id": "0b245c5f-ba2b-4e8d-b9db-26681b0fa2e3", "name": "io.github.wilsonchenghy/shadertoy-mcp", "description": "", "repository": { "url": "https://github.com/wilsonchenghy/ShaderToy-MCP", "source": "github", "id": "958998300" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:14:23Z", "is_latest": true } }, { "id": "0bc33e11-876e-4b0f-9c72-75c126d89978", "name": "io.github.klavis-ai/klavis", "description": "Klavis AI (YC X25): Open Source MCP integration for AI applications", "repository": { "url": "https://github.com/Klavis-AI/klavis", "source": "github", "id": "965974441" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T18:59:59Z", "is_latest": true } }, { "id": "0bee6074-d16a-4482-a315-5b8f0f1abcf1", "name": "io.github.fireproof-storage/mcp-database-server", "description": "Store and load JSON documents from LLM tool use", "repository": { "url": "https://github.com/fireproof-storage/mcp-database-server", "source": "github", "id": "904432283" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T18:58:57Z", "is_latest": true } }, { "id": "0c43f128-7589-4ce6-9382-5399ba24bebd", "name": "io.github.xxxbrian/mcp-rquest", "description": "A MCP server providing realistic browser-like HTTP request capabilities with accurate TLS/JA3/JA4 fingerprints for bypassing anti-bot measures. It also supports converting PDF and HTML documents to Markdown for easier processing by LLMs.", "repository": { "url": "https://github.com/xxxbrian/mcp-rquest", "source": "github", "id": "950863558" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:13:30Z", "is_latest": true } }, { "id": "0c8e4aae-53ed-4acf-87d9-19d44ac4afd1", "name": "io.github.geropl/linear-mcp-go", "description": "linear MCP server based on mcp-go", "repository": { "url": "https://github.com/geropl/linear-mcp-go", "source": "github", "id": "940084523" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:09:19Z", "is_latest": true } }, { "id": "0c9a70a7-7523-42b7-a951-b4c4b8077710", "name": "io.github.amornpan/py-mcp-mssql", "description": "py-mcp-mssql", "repository": { "url": "https://github.com/amornpan/py-mcp-mssql", "source": "github", "id": "922607489" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:10:17Z", "is_latest": true } }, { "id": "0cd13ce0-2f67-414a-afb1-4e11dd3e4cba", "name": "io.github.chaindead/telegram-mcp", "description": "Telegram MCP for managing dialogs, messages, drafts, read statuses, and more.", "repository": { "url": "https://github.com/chaindead/telegram-mcp", "source": "github", "id": "958652024" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:14:34Z", "is_latest": true } }, { "id": "0cdfed38-6495-42a3-a837-3788f35aadd3", "name": "io.github.bazinga012/mcp_code_executor", "description": "The MCP Code Executor is an MCP server that allows LLMs to execute Python code within a specified Conda environment.", "repository": { "url": "https://github.com/bazinga012/mcp_code_executor", "source": "github", "id": "928420039" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:04:37Z", "is_latest": true } }, { "id": "0d2cbcc1-4b34-4b2b-af66-595d8fb5e78a", "name": "io.github.lharries/whatsapp-mcp", "description": "WhatsApp MCP server", "repository": { "url": "https://github.com/lharries/whatsapp-mcp", "source": "github", "id": "957053334" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:15:45Z", "is_latest": true } }, { "id": "0d57edf7-3fbb-42b4-aa9e-b255e7d6f8fa", "name": "io.github.mektigboy/server-hyperliquid", "description": "MCP Hyperliquid (https://app.hyperliquid.xyz) server", "repository": { "url": "https://github.com/mektigboy/server-hyperliquid", "source": "github", "id": "943734921" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:08:12Z", "is_latest": true } }, { "id": "0d7bc864-fdf3-4afd-8b44-48468b12d550", "name": "io.github.omar-v2/mcp-ical", "description": "A Model Context Protocol Server that allows you to interact with your MacOS Calendar through natural language.", "repository": { "url": "https://github.com/Omar-V2/mcp-ical", "source": "github", "id": "930007673" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:03:05Z", "is_latest": true } }, { "id": "0d8b287c-6023-4809-a5ba-963c5612efa2", "name": "io.github.open-strategy-partners/osp_marketing_tools", "description": "A Model Context Protocol (MCP) server that empowers LLMs to use some of Open Srategy Partners' core writing and product marketing techniques.", "repository": { "url": "https://github.com/open-strategy-partners/osp_marketing_tools", "source": "github", "id": "917730483" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:12:14Z", "is_latest": true } }, { "id": "0e45cb5a-5b45-47f3-8b5e-12bdf88d176a", "name": "io.github.smn2gnt/mcp-salesforce", "description": "MCP Salesforce connector", "repository": { "url": "https://github.com/smn2gnt/MCP-Salesforce", "source": "github", "id": "904538810" }, "version_detail": { "version": "0.0.1-seed", "release_date": "2025-05-16T19:13:41Z", "is_latest": true } } ], "metadata": { "next_cursor": "0e45cb5a-5b45-47f3-8b5e-12bdf88d176a", "count": 30 } } servers request successful ------------------------------------- Testing ping endpoint: http://localhost:8080/v0/ping Status Code: 200 Response: { "status": "ok", "version": "dev" } Ping successful ------------------------------------- All tests passed successfully! ``` ## Breaking Changes <!-- Will users need to update their code or configurations? --> No ## Types of changes <!-- What types of changes does your code introduce? Put an `x` in all the boxes that apply: --> - [ ] Bug fix (non-breaking change which fixes an issue) - [x] New feature (non-breaking change which adds functionality) - [ ] Breaking change (fix or feature that would cause existing functionality to change) - [ ] Documentation update ## Checklist <!-- Go over all the following points, and put an `x` in all the boxes that apply. --> - [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 - [ ] I have added or updated documentation as needed ## Additional context <!-- Add any other context, implementation notes, or design decisions --> Close #127 |
||
|
|
d0a0adf620 | feat(tests): add integration tests for publish functionality and enhance error handling | ||
|
|
5c238eceef |
feat: refactor to account for updated openAPI schema
* Update the model to handle new changes to schema based on https://github.com/modelcontextprotocol/registry/pull/33 * Made the import script a little simpler. * Add a new updated seed file * update template mcp.json file for publisher |
||
|
|
582d93a103 | feat: implement publish endpoint and related database functionality | ||
|
|
4fb5bc477e |
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 |
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb84ea69e8 |
||
|
|
b21c6f564d |
||
|
|
747ad310bb |
||
|
|
ddcc586842 |
||
|
|
60c801c0c2 |
||
|
|
56e8b4879b |
||
|
|
a85456a9b9 |
||
|
|
9d9a02c57f |
||
|
|
218b0b422d |
||
|
|
c0a94cca8c |
||
|
|
099a2d702e |
||
|
|
6431f23107 |
||
|
|
923b2e07b9 |
||
|
|
7b211a46d6 |
||
|
|
8d7e471fd3 |
||
|
|
ebaf4c9c99 |
||
|
|
774a0df592 |
||
|
|
686fbe1e78 |
||
|
|
d0a0adf620 | ||
|
|
5c238eceef | ||
|
|
582d93a103 | ||
|
|
4fb5bc477e |