> **Update — 2026-06-01 (commit 1f3be53)**
>
> - **All @P4ST4S review feedback addressed** — positive-path hermetic
mock + live anchor against `rust-faf-mcp v0.3.1`; 5xx routed as
transient; doc comment qualified. See the [close-out
comment](https://github.com/modelcontextprotocol/registry/pull/1207#issuecomment-4589711057)
for the per-item breakdown.
> - **Runtime-model question RESOLVED** — `package-types.mdx` documents
cargo and MCPB as both first-class Rust MCP distribution paths (cargo
for source-distributed, MCPB for prebuilt-binary). The "Open question"
section below was the original draft framing; the doc now ships the
resolution.
> - **Cargo-specific gotcha discovered and documented** — crates.io
strips HTML comments during README rendering, unlike PyPI/NuGet.
`package-types.mdx` now spells this out so cargo authors don't ship
invisible mcp-name tokens (which is exactly what happened to
`rust-faf-mcp v0.3.0`; fixed in v0.3.1).
> - **Stale reference removed in this update** — the "Out of scope" line
mentioning `docs/guides/publishing/publish-cargo.md` pointed at a path
that doesn't exist. The canonical per-type doc is
`docs/modelcontextprotocol-io/package-types.mdx`; the Cargo section has
been added there directly.
> - **Two real-world Rust MCP servers queued for day-one register**:
`rust-faf-mcp v0.3.1` (live, end-to-end validated by the new live test)
and `perfetto-mcp-rs` ([@0xZOne](https://github.com/0xZOne) in #1055).
> - **Tests:** 19/19 cargo tests pass (16 existing + 2 hermetic + 1 live
anchor). `make validate` clean. `golangci-lint` 0 issues.
---
Adds support for `registryType: cargo` so Rust MCP servers published to
crates.io can be registered through the
documented validation flow rather than the MCPB binary-packaging
workaround. Closes#1055.
## Motivation and Context
#1055 noted that crates.io has ~1,800 MCP-related packages with no
direct path into the registry — only the MCPB
binary-packaging workaround. This PR adds first-class support for cargo
as a package registry type: schema +
API surface, validator, integration tests, and a documented example. The
publishing guide
(`docs/guides/publishing/publish-cargo.md`) follows on this branch once
the runtime-model direction in
**Additional context** is settled.
## How Has This Been Tested?
- **`make validate`** — clean. Schema-vs-openapi sync verified; 17/17
examples in `generic-server-json.md`
validate against the schema; `expectedServerJSONCount` bumped 16 → 17 to
match the new Cargo example.
- **`go test ./internal/validators/...`** — passes. 16 cargo validator
sub-cases across 4 test functions, run
against real crates.io (~2.5s wall):
- Input validation rejection paths
- Registry-baseURL rejection (4 variants: different host, trailing
slash, http-not-https, subdomain typo)
- Ownership validation against real crates (`serde`, `tokio`, `rand`) —
all correctly rejected for missing
`mcp-name` token
- Server-name format variations (canonical `io.github.OWNER/REPO`,
multi-hyphen, underscore, numeric suffix)
- **Positive-path test** — gated on `rust-faf-mcp` v0.2.3+ being
published with `mcp-name:
io.github.Wolfe-Jam/rust-faf-mcp` in its README. Reserved as a TODO in
`cargo_test.go`; uncomments to become the
live anchor once that publish lands.
- **Local `make test-unit`** — not run due to a Go toolchain version
quirk on my workstation (project
auto-downloads 1.26.0; my local `go` is 1.25.6, causing compile
mismatch). CI will exercise the full
PostgreSQL-backed suite.
## Breaking Changes
None. This is an additive change — `cargo` joins the supported
`registryType` enum alongside
`npm`/`pypi`/`nuget`/`oci`/`mcpb`. Existing publishes continue to work
unchanged.
## Types of changes
- [x] New feature (non-breaking change which adds functionality)
- [x] Documentation update (new Cargo example in
`generic-server-json.md`)
## 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
## Additional context
### Validator design — two-call retrieval on the documented API
`internal/validators/registries/cargo.go` mirrors the PyPI validator's
README-token approach (substring-match
`mcp-name: <serverName>`), with a two-call retrieval pattern to stay on
the documented public crates.io API:
1. `GET /api/v1/crates/{name}/{version}/readme` returns 200 OK with a
JSON pointer (`{"url":
"https://static.crates.io/readmes/.../...html"}`) — crates.io hands us
the URL rather than emitting a 302.
2. Follow the pointer to the rendered HTML; substring-match for the
token.
The two-call pattern stays on the documented public surface. The CDN URL
layout is observed-stable, but treating
it as the entry point would mean depending on an undocumented path. With
two calls, crates.io controls where
the README lives — if they move it, the metadata endpoint hands us the
new URL.
Missing crates and missing versions surface as **403** from the CDN
(S3's default for missing keys), not 404.
The validator treats any non-200 as "not found" and surfaces the actual
status code in the error message.
### Open question — runtime model
Cargo's runtime model is genuinely different from npm/PyPI/NuGet. `cargo
install` is one-time (binary lands on
PATH at `~/.cargo/bin`), not per-invocation like `npx`, `uvx`, or `dnx`
(the new one in .NET 10 SDK Preview 6+).
The new Cargo example in `generic-server-json.md` annotates this
honestly and omits `runtimeHint`.
If a different framing is preferred — e.g. recommending **MCPB**
(prebuilt binary distribution via GitHub
Releases) as the primary path for Rust MCP servers instead of cargo —
happy to adjust the documentation
accordingly. The schema + validator code in this PR is **additive** and
doesn't force a recommendation either
way; a Rust author who chooses cargo can use it, and one who prefers
MCPB still can.
### Out of scope (deferred)
- **`docs/guides/publishing/publish-cargo.md`** — follows on this branch
once the runtime-model direction above
is settled.
- **Publisher CLI `Cargo.toml` autodetect** in
`cmd/publisher/commands/init.go` — separate concern, separate PR.
- **Positive-path validator test** — gated on `rust-faf-mcp` v0.2.3+
publishing as noted in *How Has This Been
Tested?*.
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Radoslav Dimitrov <radoslav@stacklok.com>
Adds support for the Quay.io container registry to the OCI validator.
This allows MCP servers hosted on Quay.io to be registered and validated
by the official registry.
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
Quay.io is a major, trusted public OCI registry widely used by the
cloud-native and open-source communities. Currently, attempting to
publish a server using a Quay image results in an unsupported OCI
registry error. This change enables developers to use Quay.io as a
first-class hosting option for their MCP server images.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
- **Unit Tests:** Updated `internal/validators/registries/oci_test.go`
to transition Quay.io from a rejected test case to an allowed one.
- **Pattern Matching:** Verified that the allowlist correctly handles
both specific image identifiers and general pattern matching for the
`quay.io` host.
- **Local Validation:** Ran `make check` to ensure no regressions in the
existing OCI validation logic.
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
No. This is an additive change that expands the allowlist of supported
registries. Existing configurations are unaffected.
## 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)
- [x] 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
<!-- Add any other context, implementation notes, or design decisions
-->
The implementation follows the existing pattern for OCI registries:
1. Added a `RegistryURLQuay` constant to `pkg/model` for consistency.
2. Hardcoded `quay.io` into the `allowedOCIRegistries` map in the
validator to minimize architectural complexity.
3. Updated all relevant documentation files (`package-types.mdx`,
`generic-server-json.md`, and `official-registry-requirements.md`) to
ensure the source of truth is updated across the project.
4. Validation remains scoped to public images; no private registry
authentication was added for this host.
Signed-off-by: Mikel Olasagasti Uranga <mikel@olasagasti.info>
Co-authored-by: Radoslav Dimitrov <radoslav@stacklok.com>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
This PR ensures that the draft URL points to the actual draft schema
improvement suggested in
https://github.com/modelcontextprotocol/registry/issues/814
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## 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
-->
Added schema validation and support for exhaustive and more detailed
validation to existing validators. Added new `mcp-publisher validate`
command. No change to any existing tests or behavior other than the new
command.
## Motivation and Context
Many currently published servers fail schema validation. Of those that
pass, many have semantic/logical errors or other errors that make them
impossible to configure, or their configuration when applied doesn't
generate correct MCP server configuration (per their own documentation).
To address this, we need better tooling to validate servers and to
inform server publishers of errors, issues, and best practices in a way
that is clear and actionable, both during server development and at time
of publishing.
I have started a discussion about the broader topic:
https://github.com/modelcontextprotocol/registry/discussions/635
There is also a fairly detailed document describing the design,
architecture, implementation, future plans, etc. See [Enhanced
Validation Design](docs/explanations/proposed-enhanced-validation.md)
This PR is the first step in the process of improving validation. It
adds schema validation and updates all existing validators to use a new
model that allows them to track context and return rich and exhaustive
results. This has been done in a way that is backward compatible
(ValidateServerJSON is unchanged as are all existing validation unit
tests).
There is a new `mcp-publisher` command called `validate` that is
currenty the only place that schema validation and enhanced
(exhaustive/rich) validation results are exposed.
### Changes
Internal Validation improvements
- Schema validation has been implemented and is available as an option
in validation methods (defaults to off)
- Existing validators track the JSON path (context) of the attribute
they're evaluating, passing it to any child validators
- Existing validators are exhaustive (return all issues, not failing
fast on the first error)
- Existing validators return rich validation results, including:
- type (schema, semantic, linter)
- severity (error, warn, info)
- path (JSON path to server.json element)
- reference (to the schema element or rule that triggered the result)
- message (currently the same as previous error message)
A new `validate` command has been added to `mcp-publisher` so publishers
can evaluate their server.json before publishing
- Includes new schema validation and previous semantic validation
- Shows full details of all issues encountered during validation
### Usage
Given a server.json that looks like this:
```json
{
"$schema": "https://static.modelcontextprotocol.io/schemas/2025-09-29/server.schema.json",
"name": "io.github.BobDickinson/registry",
"description": "An MCP server that provides [describe what your server does]",
"repository": {
"url": "",
"source": ""
},
"version": "=1.0.0",
"packages": [
{
"registryType": "oci",
"registryBaseUrl": "https://docker.io",
"identifier": "registry",
"version": "1.0.0",
"transport": {
"type": "sse"
},
"packageArguments": [
{
"type": "named",
"name": "--mode",
"description": "Operation mode",
"format": "foo"
}
],
"environmentVariables": [
{
"description": "Your API key for the service",
"isRequired": true,
"format": "string",
"isSecret": true,
"name": "YOUR_API_KEY"
}
]
}
]
}
```
Run the command:
`mcp-publisher validate server.json`
Which will produce the output:
```bash
❌ Validation failed with 5 issue(s):
1. [error] packages.0.packageArguments.0.format (schema)
value must be one of "string", "number", "boolean", "filepath"
Reference: #/definitions/Input/properties/format/enum from: [#/definitions/ServerDetail]/properties/packages/items/[#/definitions/Package]/properties/packageArguments/items/[#/definitions/Argument]/else/[#/definitions/NamedArgument]/allOf/0/[#/definitions/InputWithVariables]/allOf/0/[#/definitions/Input]/properties/format/enum
2. [error] packages.0.transport (schema)
missing required fields: 'url'
Reference: #/definitions/SseTransport/required from: [#/definitions/ServerDetail]/properties/packages/items/[#/definitions/Package]/properties/transport/else/else/[#/definitions/SseTransport]/required
3. [error] repository.url (schema)
'' has invalid format 'uri'
Reference: #/definitions/Repository/properties/url/format from: [#/definitions/ServerDetail]/properties/repository/[#/definitions/Repository]/properties/url/format
4. [error] version (semantic)
version must be a specific version, not a range: "=1.0.0"
Reference: version-looks-like-range
5. [error] packages[0].transport.url (semantic)
url is required for sse transport type
Reference: streamable-transport-url-required
Error: validation failed
```
Note in the results above:
- All errors contain the JSON path of the triggering element from
server.json.
- The first three errors are schema errors detected during schema
validation. The `Reference` provided contains an absolute path to the
schema rule that was violated, followed by the full schema path that
enforced that rule (with $ref redirect values substited and enclosed in
square brackets).
- The error messages provided by the existing semantic validators are
exactly the same as the previous error messages those validators
produced.
In the final solution we would remove semantic validators that are
redundant to schema validation (as in number 5 above). We have the
option to use the structured data produced by schema validation to
replace the generic schema validation message with a more descriptive
message if that is an issue (in particular, if the only argument for an
ad-hoc validator is that is produces a better/cleaner message, we would
just move that message creation code to the schema error result
formatter and special case it as opposed to having a redundant
validator).
### What's Next
If this general direction is supported and this PR is accepted, a fast
follow would include:
- Add new validators (infliuenced by observed issues) for both semantic
errors and best practices
- Require passing schema validation (in addition to improved semantic
validation) in order to publish
- Remove existing validation code that is redundant to schema validation
(ensuring error messages remain intelligible)
- Update validation client code and tests to handle the new rich return
types natively
### Issues
Schema validation requires embedding the `server.schema.json` file into
the validators package via `go:embed`, which is restricted from
embedding files outside of the package. For this reason we copy the
schema file into a schema subdir (via a prep target in the makefile) and
we .gitignore it. I tried cleaning up the copy in the make clean target,
but then the linter would complain about the embed target being missing
if it wasn't there during development. I also considered just checking
in the schema file and assuming a separate workflow for updating the
embedded schema file, but it's not clear what that workflow would be or
how it would be maintained. I'm open to a different approach, but the
schema file does need to be embedded somehow for schema validation to
work.
## How Has This Been Tested?
All existing validation tests pass, new tests implemented and all pass.
## Breaking Changes
No breaking changes, no behavior change except new `validate` command
## 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
- [X] I have added or updated documentation as needed
---------
Co-authored-by: GitHub Action <action@github.com>
Co-authored with Claude Code, but I've closely reviewed/modified/vetted
all changes; ready for final review.
## Summary
This PR adds LocalTransport and RemoteTransport separation with URL
template variable support for remote servers, enabling e.g. multi-tenant
deployments with configurable endpoints.
**Key additions:**
- LocalTransport (for Packages) and RemoteTransport (for Remotes)
- URL template variables for remote transports (e.g., `{tenant_id}` in
URLs)
- Pattern validation ensuring URLs are URL-like while allowing templates
- Full test coverage via Go validator tests and documentation examples
## ⚠️ server.json Update
This PR updates the `server.json` schema. A new schema version will be
cut after this lands.
## Problem
The current schema describes URL templating with `{curly_braces}` for
transports but provides no mechanism for Remote contexts to define what
those variables should resolve to, making the feature unusable for
remote servers.
Referenced issue: #394
- Users need multi-tenant remote servers with different endpoints per
deployment
- Each tenant/region has its own URL (e.g., `us-cell1.example.com`,
`emea-cell1.example.com`)
- Current schema doesn't support parameterized remote URLs
## Solution
### Schema Architecture
**LocalTransport** (for Package context):
```typescript
LocalTransport = StdioTransport | StreamableHttpTransport | SseTransport
```
- Used in Package context (non-breaking rename of existing behavior)
- Variables in `{curly_braces}` reference parent Package
arguments/environment variables
- Supports all three transport types including stdio
**RemoteTransport** (for Remote context):
```typescript
RemoteTransport = (StreamableHttpTransport | SseTransport) + { variables: object }
```
- Extends StreamableHttp/Sse via `allOf` composition - no duplication!
- Adds `variables` object for URL templating
- Only supports streamable-http and sse (stdio not valid for remotes)
### Key Changes
**1. Schema Updates** (`openapi.yaml`, `server.schema.json`):
- Added `LocalTransport` union type for Package context
- Added `RemoteTransport` with `allOf` composition extending base
transports
- Updated Package to reference `LocalTransport`
- Updated remotes to reference `RemoteTransport`
- Added URL pattern validation: `^https?://[^\\s]+$` to both
StreamableHttp and SSE
- Removed `format: uri` from SSE (was blocking template variables)
**2. Go Types** (`pkg/model/types.go`):
- Base `Transport` struct unchanged for Package context
- `RemoteTransport` struct for remotes with `Variables` field
- Both work with existing validation infrastructure
**3. Validators** (`internal/validators/`):
- `validateRemoteTransport()` validates Remote-specific constraints
- `collectRemoteTransportVariables()` extracts available variables
- `IsValidTemplatedURL()` validates template variables reference defined
variables
- `IsValidRemoteURL()` handles template variable substitution before
localhost check
- 6 new test cases for remote transport variable validation
**4. Documentation Examples** (`generic-server-json.md`):
- Remote Server with URL Templating (StreamableHttp with `{tenant_id}`)
- SSE Remote with URL Templating (SSE with `{tenant_id}`)
- Local Server with URL Templating (Package with `{port}`)
- All examples validate via existing `validate-examples` tool
## Example: Remote Transport with Variables
```json
{
"remotes": [
{
"type": "streamable-http",
"url": "https://api.example.com/mcp/{tenant_id}/{region}",
"variables": {
"tenant_id": {
"description": "Tenant identifier",
"isRequired": true,
"choices": ["us-cell1", "emea-cell1", "apac-cell1"]
},
"region": {
"description": "Deployment region",
"isRequired": true
}
}
}
]
}
```
Clients configure the variables, and `{tenant_id}` and `{region}` get
replaced to connect to tenant-specific endpoints like
`https://api.example.com/mcp/us-cell1/east`.
## Architecture Details
**Context-based variable resolution:**
- **Package + LocalTransport**: `{port}` references `--port` argument or
`PORT` env var from parent Package
- **Remote + RemoteTransport**: `{tenant_id}` references
`variables.tenant_id` defined in the transport itself
- **Code reuse**: StreamableHttp/Sse definitions shared via `allOf`, not
duplicated
- **Validation**: Template variables validated against available
variables for each context
---
## Follow-on Work
Follow-on work will be done to adopt the feedback in
https://github.com/modelcontextprotocol/registry/pull/570#issuecomment-3367417636
regarding variable naming/prioritzation/scoping conventions, but should
not have any impact on the shape being introduced here (just
validations).
---------
Co-authored-by: yuna0x0 <yuna@yuna0x0.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Connor Peet <connor@peet.io>
This PR reorganizes and extends the existing documentation in
preparation for publishing on https://modelcontextprotocol.io/.
The current plan is for docs to remain in this repo, and be synced to
the `modelcontextprotocol/modelcontextprotocol` whenever necessary
(e.g., accompanying a release of the registry). I have included a script
in
https://github.com/modelcontextprotocol/modelcontextprotocol/pull/1725
(`bin/pull-registry-docs.sh`) that can be run manually to perform the
sync.
If we later decide to permanently move the docs to the
`modelcontextprotocol/modelcontextprotocol` repo, that also works.
This PR puts all https://modelcontextprotocol.io/ docs into
`docs/modelcontextprotocol-io/`. Docs outside that subdirectory, such as
`docs/administration/admin-operations.md`, are intended to be accessible
solely via this repo. One major exception is the
`docs/reference/server-json/` subdirectory, which will depend on the
resolution of
https://github.com/modelcontextprotocol/modelcontextprotocol/issues/1649.
However, I think we could address that in a follow-up PR.
---------
Co-authored-by: Adam Jones <adamj+git@anthropic.com>
Co-authored-by: Claude <noreply@anthropic.com>
## Summary
- Remove the `status` field from all server.json examples in
documentation
- Remove the deprecated server example that was primarily about
demonstrating the status field
- Update example count validation from 13 to 12
## Context
The `status` field was removed from the server.json schema in commit
b21c6f5 (#562). This PR cleans up the documentation to reflect that
change.
## Why didn't tests catch this?
The schema validation didn't catch the invalid `status` field because
the JSON schema doesn't have `additionalProperties: false` set. This
means the schema allows arbitrary additional properties by default.
## Test plan
- [x] All validation checks pass (`make check`)
- [x] Example count updated to match the new total (12 examples)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-authored-by: Claude <noreply@anthropic.com>
- Add missing required fields (description, transport) to all
server.json examples
- Add $schema field to examples that were missing it
- Add version field to MCPB example
- Create validation tool for guide examples with $schema
- Integrate guide validation into Makefile and CI
Fixes#507🤖 Generated with [Claude Code](https://claude.ai/code)
---------
Co-authored-by: claude[bot] <209825114+claude[bot]@users.noreply.github.com>
Co-authored-by: adam jones <domdomegg@users.noreply.github.com>
Co-authored-by: Claude <noreply@anthropic.com>
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>
<!-- Provide a brief summary of your changes -->
## Motivation and Context
Currently there are a couple shortcomings I found in the
server.schema.json:
- It uses `https://json-schema.org/draft/2020-12/schema` which is
unfortunately [not supported by VS
Code](https://github.com/microsoft/vscode/issues/165219)
- The Package schema does not require properties that are required by
the service
This means that need to round trip with the publish endpoint (perhaps
spinning CI builds) to get the server.json right. It would be great if
we could shift left and get indications in VS Code easier.
I propose we downgrade the schema to
`http://json-schema.org/draft-07/schema#`. The only difference for us is
the name of `$def` pointers.
I looked that [SchemaStore](https://github.com/SchemaStore/schemastore)
and it looks like `draft-07` is by far the most popular. I believe the
concession of using an older schema is worth it to get VS Code editor
hints.
Schema version | Count in SchemaStore
-- | --
`http://json-schema.org/draft-04/schema#` | 292
`http://json-schema.org/draft-07/schema#` | 1972
`https://json-schema.org/draft/2019-09/schema` | 4
`https://json-schema.org/draft/2020-12/schema` | 4
<!-- Why is this change needed? What problem does it solve? -->
## Open questions
- [ ] Should package `transport` actually be required? Or should `stdio`
be assumed?
- [ ] Should package `registry_base_url` be required? All of the
examples have it it's not required by the publish endpoint.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
I have tried the new schema inside VS Code and I get helpful warning.
For example, these are the warnings for the old schema.
<img width="1561" height="919" alt="image"
src="https://github.com/user-attachments/assets/474170b8-acf8-4dca-a3d9-66c68c0d1902"
/>
I have run these:
`go run .\tools\validate-examples\main.go`
`go run .\tools\validate-schemas\main.go `
## Breaking Changes
I don't think these are breaking changes. I am expressing what the
publish endpoint enforces at runtime.
## 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)
- [x] 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
- [x] I have added or updated documentation as needed
## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->
Adds optional website_url field to the server.json schema allowing
publishers to provide a url to the server's homepage, documentation, or
project website. This provides a central link for users to learn more
about the server. Particularly useful when the server has custom
installation instructions or setup requirements.
Issue: #183
PR: #130
Discussion: #274
## Motivation and Context
This change addresses the need identified in #130, #183 and #274 for a
standardized way to direct users to an official landing page similar to
`homepage` used in NPM
([example](https://www.npmjs.com/package/@modelcontextprotocol/sdk)). It
is also serves as a viable option for MCP Servers that don't follow
typical package manager patterns (e.g., embedded in a Desktop app).
## How Has This Been Tested?
- Schema validation: All 13 example server.json files validate
successfully against the updated schema
- Go validator tests: Added additional test cases covering URL format
validation and namespace matching
- Run all checks: Updated example files to work with anonymous
publishing and verified `make check` passes
## Breaking Changes
None. The website_url field is optional and backward compatible with
existing server.json files.
## Types of changes
- [ ] 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)
- [x] Documentation update
## 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
## Additional context
Security considerations:
- Website URL validation enforces that the domain matches the
publisher's reverse-DNS namespace
- HTTP/HTTPS protocols are required (no file:// or other schemes)
- Validation is consistent with existing remote URL validation patterns
## Motivation and Context
Docs currently don't have very clear organisation, and don't explain
core flows.
This fixes#89 (although we still might want to push these to
`https://modelcontextprotocol.io/docs/`), based on the plan there.
One minor change from that plan is that I merged tutorials and guides,
because they ended up basically being duplicates which I thought would
be annoying for us to keep in sync. Additionally in the Diátaxis
framework, tutorials and guides are separated by whether they are
focused on acquisition of skills (e.g. in a learning environment) or
application of skills (e.g. in a work environment). I expect the
registry to be something that will be used occasionally in a work
environment, rather than a fundamental 'learnable' skill so I think it's
reasonable not to have tutorials and fold these into guides.
## How Has This Been Tested?
- Read through all these updated docs
- Unit and integration tests (that previously used examples.md and use
the schema) working
- Ran `npx markdown-link-check .` to check all the links work
## Breaking Changes
Links to old docs will break, but I don't think there are any. All
internal links have been checked and updated.
## 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)
- [x] Documentation update
Add example for MCP servers embedded inside a CLI tool and update
example validator count.
## Motivation and Context
Document how to model CLI-embedded MCP servers using existing
packages/arguments, per discussion
[#274](https://github.com/modelcontextprotocol/registry/discussions/274).
No schema changes.
## How Has This Been Tested?
- Ran validators: schemas valid; 11/11 examples pass.
- Scripts: ./tools/validate-schemas.sh, ./tools/validate-examples.sh
## Breaking Changes
None.
## Types of changes
- [ ] 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)
- [x] Documentation update
## 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
- [ ] I have added appropriate error handling
- [x] I have added or updated documentation as needed
## Additional context
Startup reference: [Agentic integrations - Snyk MCP
Server](https://docs.snyk.io/integrations/developer-guardrails-for-agentic-workflows)
---------
Co-authored-by: Adam Jones <adamj@anthropic.com>
Co-authored-by: adam jones <adamj+git@anthropic.com>
Adds an optional `subfolder` field to the Repository object in
server.json schema to support MCP servers located within subdirectories
of monorepo structures.
## Motivation and Context
Addresses issue #360 .
The current MCP registry schema doesn't explicitly define how to
reference servers that are located within a subdirectory of a Git
repository (a "monorepo" structure). This is a common pattern (e.g.,
[microsoft/mcp](https://github.com/microsoft/mcp) &
[awslabs/mcp](https://github.com/awslabs/mcp).
## How Has This Been Tested?
- **Validator tests**: Added 6 new test cases covering valid subfolders
and security validation (path traversal, absolute paths, invalid
characters, etc.)
- **Schema validation**: All 11 examples in `examples.md` validate
successfully against both `server.schema.json` and
`registry-schema.json`
- **End-to-end validation**: Publisher tool (`mcp-publisher init`) works
correctly and generates valid templates without subfolder
- **Backward compatibility**: Existing server.json files without
subfolder continue to work unchanged
## Breaking Changes
**None.** This is a fully backward-compatible change:
- The `subfolder` field is optional (uses `omitempty` JSON tag)
- Existing server.json files work unchanged
- Publisher tools generate valid templates without subfolder by default
- All existing validation and schemas remain compatible
## Types of changes
- [ ] 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)
- [x] Documentation update
## 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
### Implementation Details
**Schema Changes:**
- Added `subfolder` property to Repository definition in
`server.schema.json` and `openapi.yaml`
- Field is optional with description and example (`"src/everything"`)
**Go Model:**
- Added `Subfolder string` field to Repository struct with
`json:"subfolder,omitempty"` tag
- Maintains backward compatibility through omitempty behavior
**Security-Focused Validation:**
- Validates subfolder is a clean relative path (no leading `/`)
- Prevents path traversal attacks (no `..` sequences)
- Blocks malformed paths (no trailing `/`, empty segments, invalid
characters)
- Uses regex validation for allowed characters: `^[a-zA-Z0-9\-_./]+$`
**Documentation:**
- Added monorepo example to `examples.md` demonstrating subfolder usage
- Updated `repository_references.md` with concise subfolder
documentation
- Maintained consistency across all documentation with same example path
**Testing:**
- 6 new integration tests in validator covering security and format
validation
- Updated example count validation tool for new example
- All existing tests continue to pass
### Design Decisions
1. **Optional by design**: Most servers don't need subfolder
(single-repo pattern is common)
2. **Clean separation**: Repository URL stays clean, subfolder is
separate metadata
3. **Security first**: Comprehensive validation prevents common
path-based attacks
4. **Publisher tool unchanged**: Default templates don't include
subfolder to avoid confusion for typical use cases
This enables publishers with monorepo structures to clearly specify
server locations while maintaining simplicity for the common
single-repository case.
Originally by @dmartinol. This branch is an attempt by @domdomegg to fix
the merge conflicts...
---
## Motivation and Context
Closes#145
Add comprehensive validation for named arguments in MCP server packages
to ensure argument names, values, and defaults follow proper format
conventions. This prevents common issues where argument names contain
embedded values or descriptions, and where values/defaults incorrectly
start with the argument name itself.
Key changes:
- Add ArgumentValidator with validation rules for named argument format
- Enhance PackageValidator to validate runtime and package arguments
- Update import process to log warnings for invalid servers instead of
failing
- Fix 396 servers in seed.json with malformed named arguments
- Extended `validate-examples` tool to apply the object validator (it
was completely missed before)
- Add comprehensive test coverage for all validation scenarios
Examples of fixes applied:
- "--directory <path>" → "--directory" with value "<path>"
- "--with-editable $REPO" → "--with-editable" with value "$REPO"
- "recipient@example.com" → "--recipient" (proper argument naming)
All servers now pass validation during both API publishing and data
import.
🤖 Generated with [Claude Code](https://claude.ai/code)
## How Has This Been Tested?
With ad-hoc unit tests.
Manual integration tests of built artifact and the seed data.
## Breaking Changes
New registrations need to follow the argument name conventions,
otherwise the import would fail for the inconsistent servers.
## Types of changes
- [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
- [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
---------
Signed-off-by: Daniele Martinoli <dmartino@redhat.com>
Co-authored-by: Daniele Martinoli <dmartino@redhat.com>
Co-authored-by: Claude <noreply@anthropic.com>
## Motivation and Context
- Add MCPB as a new registry_name option
- Add file_hashes field to package model for integrity verification
- Implement URL validation restricting MCPB packages to GitHub/GitLab
hosts
- Require SHA-256 hash for all MCPB packages
- Add example MCPB package in documentation
- Update schemas and OpenAPI specification
See issue #260
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
N/A, registry has not yet been launched
## 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)
- [ ] My code follows the repository's style guidelines
- [ ] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [x] I have added or updated documentation as needed
---------
Co-authored-by: Adam Jones <adamj+git@anthropic.com>
## Summary
- Add optional `$schema` property to ServerDetail specification
- Update JSON Schema, OpenAPI spec, Go models, examples, and publisher
template
- Enable schema versioning and IDE validation support
## Changes
- Added `$schema` as optional string property with URI format in specs
- Updated Go ServerDetail struct with new Schema field
- Added `$schema` to examples and publisher template
- Copy schema file to ../static for GitHub Pages hosting
Fixes#139
<!-- 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>
This PR simplifies the seed data import configuration based on
maintainer feedback by removing command line flags and using a clearer
environment variable name.
## Key Changes
### Configuration Simplification
- **Renamed**: `MCP_REGISTRY_SEED_FILE_PATH` → `MCP_REGISTRY_SEED_FROM`
- **Removed**: `--seed-file-path` command line flag to eliminate
configuration complexity
### Improved User Experience
Users now configure seed data import using a single, clear environment
variable:
```bash
# Before (multiple ways to configure)
MCP_REGISTRY_SEED_FILE_PATH=data/seed.json ./registry
./registry --seed-file-path=data/seed.json
# After (simplified single method)
MCP_REGISTRY_SEED_FROM=data/seed.json ./registry
```
### Registry Composability
The composability workflow is now simplified while maintaining all
functionality:
```bash
# Start first registry with seed data
MCP_REGISTRY_SEED_FROM=data/seed.json ./registry
# Start second registry importing from first via pagination
MCP_REGISTRY_SEED_FROM=http://localhost:8080 ./registry
```
## Technical Implementation
- Maintains full backward compatibility for import functionality
- All existing seed data sources continue to work (local files, HTTP
URLs, registry URLs)
- Automatic pagination through `/v0/servers` endpoint remains unchanged
- Configurable delays between requests preserved
## Benefits
- **Reduced complexity**: Single configuration method instead of
multiple
- **Clearer naming**: `SEED_FROM` better describes the source of seed
data
- **Easier maintenance**: Fewer configuration paths to test and document
- **Consistent patterns**: Aligns with other environment-variable-only
configuration
All existing functionality is preserved while providing a cleaner, more
maintainable configuration interface.
<!-- START COPILOT CODING AGENT TIPS -->
---
💬 Share your feedback on Copilot coding agent for the chance to win a
$200 gift card! Click
[here](https://survey.alchemer.com/s3/8343779/Copilot-Coding-agent) to
start the survey.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Avinash Sridhar <sridharavinash@users.noreply.github.com>
Co-authored-by: Toby Padilla <toby@toby.sh>
Co-authored-by: toby <83556+toby@users.noreply.github.com>
The following PR adds a new server `status` field to support the status
of servers, like deprecated or active
Details:
* Add status field to server.json schema with 'active' and 'deprecated'
values
* Update OpenAPI spec to include status field in Server responses
* Add ServerStatus enum and field to Go model structs
* Update examples to demonstrate status field usage (`active` and
`deprecated`)
Since this is my first PR there's a good chance I might have missed
something so I'll appreciate any feedback to make this and any PRs in
the future easier for you to review 😃Fixes: #181
## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
The main goal is to have a way for server authors to notify registry
consumers that a server may no longer be maintained and shouldn't be
considered for using.
## How Has This Been Tested?
<!-- Have you tested this in a real application? Which scenarios were
tested? -->
## Breaking Changes
<!-- Will users need to update their code or configurations? -->
## 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)
- [ ] 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>
Co-authored-by: Tadas Antanavicius <tadas@tadasant.com>
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>