diff --git a/Makefile b/Makefile index eb9b107..cec590d 100644 --- a/Makefile +++ b/Makefile @@ -32,7 +32,7 @@ test-unit: ## Run unit tests with coverage (requires PostgreSQL) @echo "Waiting for PostgreSQL to be ready..." @sleep 3 @echo "Running unit tests..." - go test -v -race -coverprofile=coverage.out -covermode=atomic ./internal/... + go test -v -race -coverprofile=coverage.out -covermode=atomic ./internal/... ./cmd/... go tool cover -html=coverage.out -o coverage.html @echo "Coverage report generated: coverage.html" @echo "Stopping PostgreSQL..." diff --git a/cmd/publisher/commands/publish_test.go b/cmd/publisher/commands/publish_test.go index 67a7022..a7e5618 100644 --- a/cmd/publisher/commands/publish_test.go +++ b/cmd/publisher/commands/publish_test.go @@ -44,8 +44,8 @@ func TestPublishCommand_DeprecatedSchema(t *testing.T) { errorSubstr: "deprecated schema detected", }, { - name: "current 2025-09-29 schema should pass validation", - schema: "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + name: "current 2025-10-17 schema should pass validation", + schema: "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", expectError: false, }, { diff --git a/data/seed.json b/data/seed.json index 6ffb9c5..92fa625 100644 --- a/data/seed.json +++ b/data/seed.json @@ -1,6 +1,6 @@ [ { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.domdomegg/airtable-mcp-server", "description": "Read and write access to Airtable database schemas, tables, and records.", "repository": { @@ -62,7 +62,7 @@ ] }, { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.domdomegg/airtable-mcp-server", "description": "Read and write access to Airtable database schemas, tables, and records.", "repository": { @@ -115,7 +115,7 @@ ] }, { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.domdomegg/time-mcp-nuget", "description": "Get the current UTC time in RFC 3339 format.", "repository": { @@ -136,7 +136,7 @@ ] }, { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.domdomegg/time-mcp-pypi", "description": "Get the current UTC time in RFC 3339 format.", "repository": { diff --git a/docs/guides/consuming/use-rest-api.md b/docs/guides/consuming/use-rest-api.md index 024e58d..1198808 100644 --- a/docs/guides/consuming/use-rest-api.md +++ b/docs/guides/consuming/use-rest-api.md @@ -67,7 +67,7 @@ You can also add custom metadata to servers using the `_meta` field. For example ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.yourname/weather-server", "description": "MCP server for weather data access", "status": "active", diff --git a/docs/guides/publishing/publish-server.md b/docs/guides/publishing/publish-server.md index b5d6e7e..cc45fa1 100644 --- a/docs/guides/publishing/publish-server.md +++ b/docs/guides/publishing/publish-server.md @@ -93,7 +93,7 @@ This creates a `server.json` with auto-detected values. You'll see something lik ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.yourname/weather-data-mcp", "title": "Weather Data", "description": "Access real-time weather data and forecasts", @@ -153,7 +153,7 @@ Add an `mcpName` field to your `package.json`: ### Example server.json ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.username/slack-integration-mcp", "title": "Slack Integration", "description": "Send messages and manage Slack workspaces", @@ -192,7 +192,7 @@ Add it to your README.md file (which becomes the package description on PyPI). T ### Example server.json ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.username/database-query-mcp", "title": "Database Query", "description": "Execute SQL queries and manage database connections", @@ -231,7 +231,7 @@ Add a README file to your NuGet package that includes the server name. This can ### Example server.json ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.username/azure-devops-mcp", "title": "Azure DevOps", "description": "Manage Azure DevOps work items and pipelines", @@ -274,7 +274,7 @@ LABEL io.modelcontextprotocol.server.name="io.github.username/server-name" ### Example server.json (Docker Hub) ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.username/kubernetes-manager-mcp", "title": "Kubernetes Manager", "description": "Deploy and manage Kubernetes resources", @@ -282,9 +282,7 @@ LABEL io.modelcontextprotocol.server.name="io.github.username/server-name" "packages": [ { "registryType": "oci", - "registryBaseUrl": "https://docker.io", - "identifier": "yourusername/kubernetes-manager-mcp", - "version": "1.0.0", + "identifier": "docker.io/yourusername/kubernetes-manager-mcp:1.0.0", "transport": { "type": "stdio" } @@ -296,7 +294,7 @@ LABEL io.modelcontextprotocol.server.name="io.github.username/server-name" ### Example server.json (GitHub Container Registry) ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.username/git-operations-mcp", "title": "Git Operations", "description": "Advanced Git repository management and operations", @@ -304,9 +302,7 @@ LABEL io.modelcontextprotocol.server.name="io.github.username/server-name" "packages": [ { "registryType": "oci", - "registryBaseUrl": "https://ghcr.io", - "identifier": "username/git-operations-mcp", - "version": "1.0.0", + "identifier": "ghcr.io/username/git-operations-mcp:1.0.0", "transport": { "type": "stdio" } @@ -315,9 +311,9 @@ LABEL io.modelcontextprotocol.server.name="io.github.username/server-name" } ``` -The identifier is `namespace/repository`, and version is the tag and optionally digest. +The identifier format is `registry/namespace/repository:tag` (e.g., `docker.io/user/app:1.0.0` or `ghcr.io/user/app:1.0.0`). The version can also be specified as a digest. -The official MCP registry currently supports Docker Hub (`https://docker.io`) and GitHub Container Registry (`https://ghcr.io`). +The official MCP registry currently supports Docker Hub (`docker.io`) and GitHub Container Registry (`ghcr.io`). @@ -339,7 +335,7 @@ openssl dgst -sha256 server.mcpb ### Example server.json ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.username/image-processor-mcp", "title": "Image Processor", "description": "Process and transform images with various filters", @@ -348,7 +344,6 @@ openssl dgst -sha256 server.mcpb { "registryType": "mcpb", "identifier": "https://github.com/username/image-processor-mcp/releases/download/v1.0.0/image-processor.mcpb", - "version": "1.0.0", "fileSha256": "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce", "transport": { "type": "stdio" @@ -385,7 +380,7 @@ Add the `remotes` field to your `server.json` (can coexist with `packages`): ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "com.yourcompany/acme-analytics", "title": "ACME Analytics", "description": "Real-time business intelligence and reporting platform", diff --git a/docs/reference/api/openapi.yaml b/docs/reference/api/openapi.yaml index 2680619..a661a87 100644 --- a/docs/reference/api/openapi.yaml +++ b/docs/reference/api/openapi.yaml @@ -1,9 +1,9 @@ openapi: 3.1.0 jsonSchemaDialect: "https://json-schema.org/draft/2020-12/schema" -$id: https://modelcontextprotocol.io/schemas/draft/2025-10-11/server-registry-openapi +$id: https://modelcontextprotocol.io/schemas/draft/2025-10-17/server-registry-openapi info: title: MCP Server Registry API - version: "2025-10-11" + version: "2025-10-17" summary: API for discovering and accessing MCP server metadata description: | Specification for a theoretical REST API that serves up metadata about MCP servers. @@ -616,7 +616,7 @@ components: type: string format: uri description: JSON Schema URI for this server.json format - example: "https://static.modelcontextprotocol.io/schemas/2025-10-11/server.schema.json" + example: "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json" packages: type: array items: diff --git a/docs/reference/server-json/CHANGELOG.md b/docs/reference/server-json/CHANGELOG.md index 9e74988..fb60a48 100644 --- a/docs/reference/server-json/CHANGELOG.md +++ b/docs/reference/server-json/CHANGELOG.md @@ -2,6 +2,60 @@ Changes to the server.json schema and format. +## 2025-10-17 + +### Changed + +The `version` field is now **optional** for MCPB packages, providing flexibility for publishers. + +**Key Changes:** + +- **MCPB packages can now include an optional `version` field** - Previously rejected by validation, MCPB packages can now optionally specify a version field for clarity and metadata purposes. +- **Both formats are valid**: + - MCPB packages **with** version field: Provides explicit version metadata + - MCPB packages **without** version field: Version information is embedded in the download URL (as before) + +**Migration:** + +Publishers using MCPB packages can optionally add a `version` field to their package configuration. This is particularly useful when: +- The version information is not clearly visible in the download URL +- You want to provide explicit version metadata for tooling and clients +- You need consistent version tracking across different package types + +Existing MCPB packages without the version field continue to work without any changes. + +**Example - MCPB Package with optional version:** +```json +{ + "packages": [{ + "registryType": "mcpb", + "identifier": "https://github.com/example/releases/download/v1.0.0/package.mcpb", + "version": "1.0.0", + "fileSha256": "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce", + "transport": { + "type": "stdio" + } + }] +} +``` + +**Example - MCPB Package without version (still valid):** +```json +{ + "packages": [{ + "registryType": "mcpb", + "identifier": "https://github.com/example/releases/download/v1.0.0/package.mcpb", + "fileSha256": "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce", + "transport": { + "type": "stdio" + } + }] +} +``` + +### Schema Version +- Schema version: `2025-10-11` → `2025-10-17` + ## 2025-10-11 ### Changed diff --git a/docs/reference/server-json/generic-server-json.md b/docs/reference/server-json/generic-server-json.md index b59929f..b2afa61 100644 --- a/docs/reference/server-json/generic-server-json.md +++ b/docs/reference/server-json/generic-server-json.md @@ -22,7 +22,7 @@ The official registry has some more restrictions on top of this. See the [offici ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.modelcontextprotocol.anonymous/brave-search", "description": "MCP server for Brave Search API integration", "title": "Brave Search", @@ -69,7 +69,7 @@ For MCP servers located within a subdirectory of a larger repository (monorepo s ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.modelcontextprotocol/everything", "description": "MCP server that exercises all the features of the MCP protocol", "title": "Everything", @@ -108,7 +108,7 @@ Suppose your MCP server application requires a `mcp start` CLI arguments to star ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.joelverhagen/knapcode-samplemcpserver", "description": "Sample NuGet MCP server for a random number and random weather", "version": "0.4.0-beta", @@ -152,7 +152,7 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.modelcontextprotocol/filesystem", "description": "Node.js server implementing Model Context Protocol (MCP) for filesystem operations.", "title": "Filesystem", @@ -252,7 +252,7 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.modelcontextprotocol.anonymous/mcp-fs", "description": "Cloud-hosted MCP filesystem server", "repository": { @@ -286,7 +286,7 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.example/weather-mcp", "description": "Python MCP server for weather data access", "title": "Weather", @@ -342,7 +342,7 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6. ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.joelverhagen/knapcode-samplemcpserver", "description": "Sample NuGet MCP server for a random number and random weather", "repository": { @@ -391,7 +391,7 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6. ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.github.example/database-manager", "description": "MCP server for database operations with support for multiple database types", "repository": { @@ -500,7 +500,7 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6. ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.modelcontextprotocol.anonymous/hybrid-mcp", "description": "MCP server available as both local package and remote service", "title": "Hybrid", @@ -586,7 +586,7 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6. ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.modelcontextprotocol/text-editor", "description": "MCP Bundle server for advanced text editing capabilities", "title": "Text Editor", @@ -629,7 +629,7 @@ Some CLI tools bundle an MCP server, without a standalone MCP package or a publi ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.snyk/cli-mcp", "description": "MCP server provided by the Snyk CLI", "title": "Snyk", @@ -664,7 +664,7 @@ For MCP servers that follow a custom installation path or are embedded in applic ```json { - "$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json", + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "name": "io.modelcontextprotocol.anonymous/embedded-mcp", "description": "MCP server embedded in a Desktop app", "websiteUrl": "https://anonymous.modelcontextprotocol.io/embedded-mcp-guide", diff --git a/docs/reference/server-json/server.schema.json b/docs/reference/server-json/server.schema.json index 8022347..59967b5 100644 --- a/docs/reference/server-json/server.schema.json +++ b/docs/reference/server-json/server.schema.json @@ -1,6 +1,6 @@ { "$comment": "This file is auto-generated from docs/reference/api/openapi.yaml. Do not edit manually. Run 'make generate-schema' to update.", - "$id": "https://static.modelcontextprotocol.io/schemas/2025-10-11/server.schema.json", + "$id": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "$ref": "#/definitions/ServerDetail", "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { @@ -373,7 +373,7 @@ "properties": { "$schema": { "description": "JSON Schema URI for this server.json format", - "example": "https://static.modelcontextprotocol.io/schemas/2025-10-11/server.schema.json", + "example": "https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json", "format": "uri", "type": "string" }, diff --git a/internal/validators/registries/mcpb.go b/internal/validators/registries/mcpb.go index 72293e6..d42059b 100644 --- a/internal/validators/registries/mcpb.go +++ b/internal/validators/registries/mcpb.go @@ -27,14 +27,13 @@ func ValidateMCPB(ctx context.Context, pkg model.Package, _ string) error { return ErrMissingIdentifierForMCPB } - // Validate that old format fields are not present - // MCPB packages use URL in identifier, version is embedded in the URL - if pkg.Version != "" { - return fmt.Errorf("MCPB packages must not have 'version' field - version should be embedded in the download URL") - } + // Validate that registryBaseUrl is not present + // MCPB packages use full download URLs in identifier if pkg.RegistryBaseURL != "" { return fmt.Errorf("MCPB packages must not have 'registryBaseUrl' field - use the full download URL in 'identifier' instead") } + // Note: version field is optional for MCPB packages + // It can be included for clarity or omitted if the version is embedded in the download URL err := validateMCPBUrl(pkg.Identifier) if err != nil { diff --git a/internal/validators/registries/mcpb_test.go b/internal/validators/registries/mcpb_test.go index b3a0c33..eb9fb97 100644 --- a/internal/validators/registries/mcpb_test.go +++ b/internal/validators/registries/mcpb_test.go @@ -120,67 +120,68 @@ func TestValidateMCPB(t *testing.T) { } } -func TestValidateMCPB_RejectsExtraFields(t *testing.T) { +func TestValidateMCPB_OptionalFields(t *testing.T) { ctx := context.Background() tests := []struct { name string pkg model.Package + expectError bool errorMessage string }{ { - name: "MCPB package with version field should be rejected", + name: "MCPB package with optional version field should pass", pkg: model.Package{ RegistryType: model.RegistryTypeMCPB, - Identifier: "https://github.com/example/repo/releases/download/v1.0.0/server.mcpb", - Version: "1.0.0", - FileSHA256: "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce", + Identifier: "https://github.com/domdomegg/airtable-mcp-server/releases/download/v1.7.2/airtable-mcp-server.mcpb", + Version: "1.7.2", + FileSHA256: "8220de07a08ebe908f04da139ea03dbfe29758141347e945da60535fb7bcca20", }, - errorMessage: "MCPB packages must not have 'version' field", + expectError: false, + }, + { + name: "MCPB package without version field should pass", + pkg: model.Package{ + RegistryType: model.RegistryTypeMCPB, + Identifier: "https://github.com/domdomegg/airtable-mcp-server/releases/download/v1.7.2/airtable-mcp-server.mcpb", + FileSHA256: "8220de07a08ebe908f04da139ea03dbfe29758141347e945da60535fb7bcca20", + }, + expectError: false, }, { name: "MCPB package with registryBaseUrl should be rejected", pkg: model.Package{ RegistryType: model.RegistryTypeMCPB, - Identifier: "https://github.com/example/repo/releases/download/v1.0.0/server.mcpb", + Identifier: "https://github.com/domdomegg/airtable-mcp-server/releases/download/v1.7.2/airtable-mcp-server.mcpb", RegistryBaseURL: "https://github.com", - FileSHA256: "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce", + FileSHA256: "8220de07a08ebe908f04da139ea03dbfe29758141347e945da60535fb7bcca20", }, + expectError: true, errorMessage: "MCPB packages must not have 'registryBaseUrl' field", }, { - name: "MCPB package with both extra fields should fail on version first", + name: "MCPB package with both version and registryBaseUrl should fail on registryBaseUrl", pkg: model.Package{ RegistryType: model.RegistryTypeMCPB, - Identifier: "https://github.com/example/repo/releases/download/v1.0.0/server.mcpb", - Version: "1.0.0", + Identifier: "https://github.com/domdomegg/airtable-mcp-server/releases/download/v1.7.2/airtable-mcp-server.mcpb", + Version: "1.7.2", RegistryBaseURL: "https://github.com", - FileSHA256: "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce", + FileSHA256: "8220de07a08ebe908f04da139ea03dbfe29758141347e945da60535fb7bcca20", }, - errorMessage: "MCPB packages must not have 'version' field", - }, - { - name: "MCPB package with canonical format should pass extra field validation", - pkg: model.Package{ - RegistryType: model.RegistryTypeMCPB, - Identifier: "https://github.com/domdomegg/airtable-mcp-server/releases/download/v1.7.2/airtable-mcp-server.mcpb", - FileSHA256: "fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce", - }, - errorMessage: "", // Should pass extra field check (will succeed as this is a real package) + expectError: true, + errorMessage: "MCPB packages must not have 'registryBaseUrl' field", }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := registries.ValidateMCPB(ctx, tt.pkg, "com.example/test") + err := registries.ValidateMCPB(ctx, tt.pkg, "io.github.domdomegg/airtable-mcp-server") - if tt.errorMessage != "" { + if tt.expectError { assert.Error(t, err) assert.Contains(t, err.Error(), tt.errorMessage) - } else if err != nil { - // Should not fail with extra field error (may pass completely for real package) - assert.NotContains(t, err.Error(), "must not have 'version'") - assert.NotContains(t, err.Error(), "must not have 'registryBaseUrl'") + } else { + assert.NoError(t, err) } }) } diff --git a/internal/validators/validators_test.go b/internal/validators/validators_test.go index 3a1aa43..1dc0e22 100644 --- a/internal/validators/validators_test.go +++ b/internal/validators/validators_test.go @@ -47,7 +47,7 @@ func TestValidate(t *testing.T) { expectedError: "schema version https://static.modelcontextprotocol.io/schemas/2025-01-27/server.schema.json is not supported", }, { - name: "Schema version accepts current schema (2025-09-29)", + name: "Schema version accepts current schema (2025-10-17)", serverDetail: apiv0.ServerJSON{ Schema: model.CurrentSchemaURL, Name: "com.example/test-server", diff --git a/pkg/api/v0/types.go b/pkg/api/v0/types.go index a183113..1bfbe63 100644 --- a/pkg/api/v0/types.go +++ b/pkg/api/v0/types.go @@ -32,7 +32,7 @@ type ServerMeta struct { } type ServerJSON struct { - Schema string `json:"$schema" required:"true" minLength:"1" format:"uri" doc:"JSON Schema URI for this server.json format" example:"https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json"` + Schema string `json:"$schema" required:"true" minLength:"1" format:"uri" doc:"JSON Schema URI for this server.json format" example:"https://static.modelcontextprotocol.io/schemas/2025-10-17/server.schema.json"` Name string `json:"name" minLength:"3" maxLength:"200" pattern:"^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$" doc:"Server name in reverse-DNS format. Must contain exactly one forward slash separating namespace from server name." example:"io.github.user/weather"` Description string `json:"description" minLength:"1" maxLength:"100" doc:"Clear human-readable explanation of server functionality." example:"MCP server providing weather data and forecasts via OpenWeatherMap API"` Title string `json:"title,omitempty" minLength:"1" maxLength:"100" doc:"Optional human-readable title or display name for the MCP server." example:"Weather API"` diff --git a/pkg/model/constants.go b/pkg/model/constants.go index dce2750..d0aafc9 100644 --- a/pkg/model/constants.go +++ b/pkg/model/constants.go @@ -38,7 +38,7 @@ const ( // Schema versions const ( // CurrentSchemaVersion is the current supported schema version date - CurrentSchemaVersion = "2025-09-29" + CurrentSchemaVersion = "2025-10-17" // CurrentSchemaURL is the full URL to the current schema CurrentSchemaURL = "https://static.modelcontextprotocol.io/schemas/" + CurrentSchemaVersion + "/server.schema.json" ) diff --git a/pkg/model/types.go b/pkg/model/types.go index 620f3de..fe85f5a 100644 --- a/pkg/model/types.go +++ b/pkg/model/types.go @@ -20,7 +20,7 @@ type Transport struct { // - PyPI: RegistryType, Identifier (package name), Version, RegistryBaseURL (optional) // - NuGet: RegistryType, Identifier (package ID), Version, RegistryBaseURL (optional) // - OCI: RegistryType, Identifier (full image reference like "ghcr.io/owner/repo:tag") -// - MCPB: RegistryType, Identifier (download URL), FileSHA256 (required) +// - MCPB: RegistryType, Identifier (download URL), Version (optional), FileSHA256 (required) type Package struct { // RegistryType indicates how to download packages (e.g., "npm", "pypi", "oci", "nuget", "mcpb") RegistryType string `json:"registryType" minLength:"1" doc:"Registry type indicating how to download packages (e.g., 'npm', 'pypi', 'oci', 'nuget', 'mcpb')" example:"npm"` @@ -31,7 +31,7 @@ type Package struct { // - For OCI: full image reference (e.g., "ghcr.io/owner/repo:v1.0.0") // - For MCPB: direct download URL Identifier string `json:"identifier" minLength:"1" doc:"Package identifier - either a package name (for registries) or URL (for direct downloads)" example:"@modelcontextprotocol/server-brave-search"` - // Version is the package version (used by npm, pypi, nuget; not used by oci, mcpb where version is in the identifier) + // Version is the package version (required for npm, pypi, nuget; optional for mcpb; not used by oci where version is in the identifier) Version string `json:"version,omitempty" minLength:"1" doc:"Package version. Must be a specific version. Version ranges are rejected (e.g., '^1.2.3', '~1.2.3', '>=1.2.3', '1.x', '1.*')." example:"1.0.2"` // FileSHA256 is the SHA-256 hash for integrity verification (required for mcpb, optional for others) FileSHA256 string `json:"fileSha256,omitempty" pattern:"^[a-f0-9]{64}$" doc:"SHA-256 hash of the package file for integrity verification. Required for MCPB packages and optional for other package types. Authors are responsible for generating correct SHA-256 hashes when creating server.json. If present, MCP clients must validate the downloaded file matches the hash before running packages to ensure file integrity." example:"fe333e598595000ae021bd27117db32ec69af6987f507ba7a63c90638ff633ce"` diff --git a/tests/integration/run.sh b/tests/integration/run.sh index af7e6c2..f206b88 100755 --- a/tests/integration/run.sh +++ b/tests/integration/run.sh @@ -24,7 +24,8 @@ cleanup() { go build -o ./bin/publisher ./cmd/publisher -docker build -t registry . +# Build the registry image with both tags, forcing a rebuild to ensure latest code +docker build --no-cache -t registry -t modelcontextprotocol/registry:dev . trap cleanup EXIT