diff --git a/README.md b/README.md index f4d5ac5..0bbcdad 100644 --- a/README.md +++ b/README.md @@ -1,30 +1,14 @@ # MCP Registry +The MCP registry provides MCP clients with a list of MCP servers, like an app store for MCP servers. + +📖 **[Full documentation](./docs)** + +## Development Status + > [!WARNING] > The registry is under [active development](#development-status). The registry API spec is unstable and the official MCP registry database may be wiped at any time. -📖 **[API Documentation](https://staging.registry.modelcontextprotocol.io/docs)** | 📚 **[Technical Docs](./docs)** - -## What is the registry? - -The registry will provide MCP clients with a list of MCP servers, like an app store for MCP servers. (In the future it might do more, like also hosting a list of clients). - -There are two parts to the registry project: -1. 🟦 **The MCP registry spec**: An [API specification](./docs/server-registry-api/) that allows anyone to implement a registry. -2. 🟥 **The Official MCP registry**: A hosted registry following the MCP registry spec at [`registry.modelcontextprotocol.io`](https://registry.modelcontextprotocol.io). This serves as the **authoritative repository** for publicly-available MCP servers. Server creators publish once, and all consumers (MCP clients, aggregators, marketplaces) reference the same canonical data. This is owned by the MCP open-source community, backed by major trusted contributors to the MCP ecosystem such as Anthropic, GitHub, PulseMCP and Microsoft. - -The registry is built around the [`server.json`](./docs/server-json/) format - a standardized way to describe MCP servers that works across discovery, initialization, and packaging scenarios. - -In time, we expect the ecosystem to look a bit like this: - -![](./docs/ecosystem-diagram.excalidraw.svg) - -Note that MCP registries are _metaregistries_. They host metadata about packages, but not the package code or binaries. Instead, they reference other package registries (like NPM, PyPi or Docker) for this. - -Additionally, we expect clients pull from _subregistries_. These subregistries add value to the registry ecosystem by providing curation, or extending it with additional metadata. The Official MCP registry expects a lot of API requests from ETL jobs from these subregistries. - -## Development Status - **2025-09-04 update**: We're targeting a 'preview' go-live on 8th September. This may still be unstable and not provide durability guarantees, but is a step towards being more solidified. A general availability (GA) release will follow later. Current key maintainers: @@ -106,7 +90,7 @@ make publisher ./cmd/publisher/bin/mcp-publisher --help ``` -See [the publisher README](./cmd/publisher/README.md) for more details. +See [the publisher guide](./docs/guides/publishing/publish-server.md) for more details. #### Other commands @@ -130,9 +114,7 @@ For Claude and other AI tools: Always prefer make targets over custom commands w │ └── publisher/ # Server publishing tool ├── data/ # Seed data ├── deploy/ # Deployment configuration (Pulumi) -├── docs/ # Technical documentation -│ ├── server-json/ # server.json specification & examples -│ └── server-registry-api/ # API specification +├── docs/ # Documentation ├── internal/ # Private application code │ ├── api/ # HTTP handlers and routing │ ├── auth/ # Authentication (GitHub OAuth, JWT, namespace blocking) @@ -165,4 +147,4 @@ The registry validates namespace ownership when publishing. E.g. to publish...: ## More documentation -See the [docs](./docs) folder for more details if your question has not been answered here! +See the [documentation](./docs) for more details if your question has not been answered here! diff --git a/cmd/publisher/README.md b/cmd/publisher/README.md index 51bb6a2..274cab8 100644 --- a/cmd/publisher/README.md +++ b/cmd/publisher/README.md @@ -2,7 +2,7 @@ CLI tool for publishing MCP servers to the registry. -> These docs are for contributors. See the [Publisher User Guide](../../docs/publisher/guide.md) for end-user documentation. +> These docs are for contributors. See the [Publisher User Guide](../../docs/guides/publishing/publish-server.md) for end-user documentation. ## Quick Development Setup diff --git a/docs/README.md b/docs/README.md index 60b98f0..f3ee9be 100644 --- a/docs/README.md +++ b/docs/README.md @@ -1,18 +1,16 @@ -# Official Registry Documentation +# MCP Registry Documentation -This extends [the main README](../README.md). +The MCP registry provides MCP clients with a list of MCP servers, like an app store for MCP servers. -## Project Documentation +## I want to... -- [`faq.md`](./faq.md) - Frequently asked questions about the MCP Registry -- [`design_principles.md`](./design_principles.md) - Core constraints and principles guiding the registry design -- [`roadmap.md`](./roadmap.md) - High-level roadmap for the MCP Registry development -- [`MCP Developers Summit 2025 - Registry Talk Slides.pdf`](./MCP%20Developers%20Summit%202025%20-%20Registry%20Talk%20Slides.pdf) - Slides from a talk given at the MCP Developers Summit on May 23, 2025, with an up-to-date vision of how we are thinking about the official registry. +- **📤 Publish my MCP server** → [Publishing Guide](guides/publishing/publish-server.md) +- **📥 Consume registry data** → [API Usage Guide](guides/consuming/use-rest-api.md) +- **🔌 Understand the registry's purpose** → [Ecosystem vision](explanations/ecosystem-vision.md) +- **📋 Look up specific information** → [server.json spec](reference/server-json/generic-server-json.md) | [API spec](reference/api/generic-registry-api.md) | [CLI reference](reference/cli/commands.md) -## API & Technical Specifications +## Documentation Index -- [`openapi.yaml`](./server-registry-api/openapi.yaml) - OpenAPI specification for the official registry API -- [`api_examples.md`](./api_examples.md) - Examples of what data will actually look like coming from the official registry API -- [`architecture.md`](./architecture.md) - Technical architecture, deployment strategies, and data flows -- [`server.json` README](./server-json/README.md) - description of the `server.json` purpose and schema -- [`new_package_registry.md`](./new_package_registry.md) - steps to add a new package registry for local server packages +- 🛠️ [How-To Guides: Task-focused instructions](./guides/) +- 💡 [Explanations: Understanding-oriented content](./explanations/) +- 📖 [Reference: Technical specifications and lookup material](./reference/) diff --git a/docs/explanations/README.md b/docs/explanations/README.md new file mode 100644 index 0000000..7d97439 --- /dev/null +++ b/docs/explanations/README.md @@ -0,0 +1,10 @@ +# Explanations + +Understanding-oriented documentation that clarifies and illuminates the MCP Registry. + +- [Design principles](design-principles.md) +- [Ecosystem vision](ecosystem-vision.md) +- [Roadmap](roadmap.md) +- [Tech architecture](tech-architecture.md) +- [Namespacing](namespacing.md) +- [Versioning](versioning.md) diff --git a/docs/design_principles.md b/docs/explanations/design-principles.md similarity index 100% rename from docs/design_principles.md rename to docs/explanations/design-principles.md diff --git a/docs/ecosystem-diagram.excalidraw.svg b/docs/explanations/ecosystem-diagram.excalidraw.svg similarity index 100% rename from docs/ecosystem-diagram.excalidraw.svg rename to docs/explanations/ecosystem-diagram.excalidraw.svg diff --git a/docs/explanations/ecosystem-vision.md b/docs/explanations/ecosystem-vision.md new file mode 100644 index 0000000..2e74383 --- /dev/null +++ b/docs/explanations/ecosystem-vision.md @@ -0,0 +1,56 @@ +# Ecosystem Vision + +How the MCP Registry fits into the broader ecosystem and our vision for the future. + +## The Registry Ecosystem + +The MCP registry provides MCP clients with a list of MCP servers, like an app store for MCP servers. (In the future it might do more, like also hosting a list of clients). + +There are two parts to the registry project: + +1. 🟦 **The MCP registry spec**: An [API specification](../reference/api/) that allows anyone to implement a registry. +2. 🟥 **The Official MCP registry**: A hosted registry following the MCP registry spec at [`registry.modelcontextprotocol.io`](https://registry.modelcontextprotocol.io). This serves as the **authoritative repository** for publicly-available MCP servers. Server creators publish once, and all consumers (MCP clients, aggregators, marketplaces) reference the same canonical data. This is owned by the MCP open-source community, backed by major trusted contributors to the MCP ecosystem such as Anthropic, GitHub, PulseMCP and Microsoft. + +The registry is built around the [`server.json`](../reference/server-json/) format - a standardized way to describe MCP servers that works across discovery, initialization, and packaging scenarios. + +In time, we expect the ecosystem to look a bit like this: + +![](./ecosystem-diagram.excalidraw.svg) + +Note that MCP registries are _metaregistries_. They host metadata about packages, but not the package code or binaries. Instead, they reference other package registries (like NPM, PyPi or Docker) for this. + +Additionally, we expect clients pull from _subregistries_. These subregistries add value to the registry ecosystem by providing curation, or extending it with additional metadata. The Official MCP registry expects a lot of API requests from ETL jobs from these subregistries. + +## Registry vs Package Registry + +Key distinction: MCP Registries are **metaregistries**. + +- **Package registries** (npm, PyPI, Docker Hub) host actual code/binaries +- **The MCP Registry** hosts metadata pointing to those packages + +``` +MCP Registry: "weather-server v1.2.0 is at npm:weather-mcp" +NPM Registry: [actual weather-mcp package code] +``` + +## Official vs Community Registries + +**Official MCP Registry** (`registry.modelcontextprotocol.io`): +- Canonical source for publicly-available servers +- Community-owned, backed by trusted contributors +- Focuses on discoverability and basic metadata + +**Subregistries** (Smithery, PulseMCP, etc.): +- Add value through curation, ratings, enhanced metadata +- ETL from official registry + additional annotations +- Serve specific communities or use cases + +## How Servers Are Represented + +Each server entry contains: +- **Identity**: Unique name (`io.github.user/server-name`) +- **Packages**: Where to download it (`npm`, `pypi`, `docker`, etc.) +- **Runtime**: How to execute it (args, env vars) +- **Metadata**: Description, capabilities, version + +This is stored in a standardized `server.json` format that works across discovery, installation, and execution. diff --git a/docs/explanations/namespacing.md b/docs/explanations/namespacing.md new file mode 100644 index 0000000..cda7882 --- /dev/null +++ b/docs/explanations/namespacing.md @@ -0,0 +1,45 @@ +# Namespacing and Security + +Namespacing prevents name squatting, makes impersonation and typo squatting much harder, and provides attribution through domain-based identity. + +For practical steps on how to authenticate for different namespaces, see the [publishing guide](../guides/publishing/publish-server.md#authenticate). + +## Namespace Format + +All server names follow reverse-DNS format. Examples: +- `io.github.alice/weather-server` - GitHub user `alice` +- `com.acme/internal-tool` - Company domain `acme.com` +- `org.nonprofit.research/data-analyzer` - Subdomain `research.nonprofit.org` + +## Security Model + +### Ownership Verification + +Publishing to a namespace requires proving you control the corresponding identity: + +**GitHub namespaces** (`io.github.*`): +- OAuth login to GitHub account/organization +- OIDC tokens in GitHub Actions workflows + +**Domain namespaces** (`com.company.*`): +- DNS verification: TXT record at `_mcp-registry.company.com` +- HTTP verification: File at `https://company.com/.well-known/mcp-registry-auth` + +## Namespace Scoping + +Different authentication methods grant different namespace access: + +**GitHub OAuth/OIDC**: +- `io.github.username/*` (for personal accounts) +- `io.github.orgname/*` (for organizations) + +**DNS verification**: +- `com.domain/*` and `com.domain.*/*` (domain + all subdomains) + +**HTTP verification**: +- `com.domain/*` only (exact domain, no subdomains) + +## Limitations + +**Domain ownership changes**: If someone loses/sells a domain, they lose publishing rights. Similarly if someone gains a domain, they gain publishing rights. +**Package validation**: Registry validates namespace ownership, but actual packages may still be malicious etc. diff --git a/docs/MCP Developers Summit 2025 - Registry Talk Slides.pdf b/docs/explanations/registry-goals-presentation.pdf similarity index 100% rename from docs/MCP Developers Summit 2025 - Registry Talk Slides.pdf rename to docs/explanations/registry-goals-presentation.pdf diff --git a/docs/roadmap.md b/docs/explanations/roadmap.md similarity index 100% rename from docs/roadmap.md rename to docs/explanations/roadmap.md diff --git a/docs/architecture.md b/docs/explanations/tech-architecture.md similarity index 84% rename from docs/architecture.md rename to docs/explanations/tech-architecture.md index 3bd89ce..d163dff 100644 --- a/docs/architecture.md +++ b/docs/explanations/tech-architecture.md @@ -1,4 +1,4 @@ -# MCP Registry Architecture +# MCP Registry Technical Architecture This document describes the technical architecture of the MCP Registry, including system components, deployment strategies, and data flows. @@ -6,52 +6,6 @@ This document describes the technical architecture of the MCP Registry, includin The MCP Registry is designed as a lightweight metadata service that bridges MCP server creators with consumers (MCP clients and aggregators). -```mermaid -graph TB - subgraph "Server Maintainers" - CLI[CLI Tool] - end - - subgraph "MCP Registry" - API[REST API
Go] - DB[(PostgreSQL)] - CDN[CDN Cache] - end - - subgraph "Intermediaries" - MKT[Marketplaces] - AGG[Aggregators] - end - - subgraph "End Consumers" - MC[MCP Client Host Apps
e.g. Claude Desktop] - end - - subgraph "External Services" - NPM[npm Registry] - PYPI[PyPI Registry] - DOCKER[Docker Hub] - NUGET[NuGet Gallery] - DNS[DNS Services] - GH[GitHub OAuth] - end - - CLI --> |Publish| API - API --> DB - API --> CDN - CDN --> |Daily ETL| MKT - CDN --> |Daily ETL| AGG - MKT --> MC - AGG --> MC - API -.-> |Auth| GH - API -.-> |Admin Auth| GCP[Google Cloud Identity] - API -.-> |Verify| DNS - API -.-> |Reference| NPM - API -.-> |Reference| PYPI - API -.-> |Reference| NUGET - API -.-> |Reference| DOCKER -``` - ## Core Components ### REST API (Go) diff --git a/docs/versioning.md b/docs/explanations/versioning.md similarity index 69% rename from docs/versioning.md rename to docs/explanations/versioning.md index 8a4b670..b900638 100644 --- a/docs/versioning.md +++ b/docs/explanations/versioning.md @@ -130,6 +130,104 @@ Existing servers with non-semantic versions will continue to work without change 2. Consider the ordering implications when transitioning from non-semantic to semantic versions 3. Use prerelease labels for registry-specific versioning needs +## Common Scenarios + +### Standard Releases +**Package and server versions aligned**: +```json +{ + "version_detail": { + "version": "1.2.3" + }, + "packages": [ + { + "registry_type": "npm", + "identifier": "@myorg/server", + "version": "1.2.3" + } + ] +} +``` + +### Registry-Only Updates +**Server metadata changes without package updates**: +```json +{ + "version_detail": { + "version": "1.2.3-1" + }, + "packages": [ + { + "registry_type": "npm", + "identifier": "@myorg/server", + "version": "1.2.3" + } + ] +} +``` + +Note: `1.2.3-1` is considered lower than `1.2.3` in semver ordering. Publish prerelease versions first. + +### Remote Server Versioning +**Remote servers without package dependencies**: +```json +{ + "version_detail": { + "version": "2.1.0" + }, + "remotes": [ + { + "transport_type": "sse", + "url": "https://api.myservice.com/mcp/v2.1" + } + ] +} +``` + +Version strategy options: +- **API versioning**: Match your service API version +- **Semantic versioning**: Standard semver for feature changes +- **Date-based**: `2024.03.15` for regular releases + +### Multi-Package Versioning +**Different package versions**: +```json +{ + "version_detail": { + "version": "1.3.0" + }, + "packages": [ + { + "registry_type": "npm", + "identifier": "@myorg/server", + "version": "1.3.0" + }, + { + "registry_type": "oci", + "identifier": "myorg/server", + "version": "1.2.5" + } + ] +} +``` + +Use server version to indicate the overall release. + +## Decision Guide + +**Which version strategy should I use?** + +``` +Do you have underlying packages? +├─ Yes: Align with package version +│ ├─ Same package version → Use package version +│ └─ Different package versions → Use highest + indicate relationship +└─ No (remote server): Choose versioning scheme + ├─ API versioning → Match service API version + ├─ Feature-based → Use semantic versioning + └─ Regular releases → Consider date-based versioning +``` + ## Future Considerations This versioning approach is designed to be compatible with potential future changes to the MCP specification's `Implementation.version` field. Any SHOULD requirements introduced here may be proposed as updates to the specification through the SEP (Specification Enhancement Proposal) process. \ No newline at end of file diff --git a/docs/guides/README.md b/docs/guides/README.md new file mode 100644 index 0000000..a3ad40c --- /dev/null +++ b/docs/guides/README.md @@ -0,0 +1,21 @@ +# How-To Guides + +Problem-oriented guides for specific tasks with the MCP Registry. + +## Publishing Servers + +- [Publish a server](publishing/publish-server.md) +- [GitHub Actions](publishing/github-actions.md) + +## Consuming Registry Data + +- [Use the REST API](consuming/use-rest-api.md) + +## Contributing + +- [Add package registry](contributing/add-package-registry.md) + +## Administration + +- [Admin operations](administration/admin-operations.md) +- [Moderation guidelines](administration/moderation-guidelines.md) \ No newline at end of file diff --git a/docs/admin-operations.md b/docs/guides/administration/admin-operations.md similarity index 95% rename from docs/admin-operations.md rename to docs/guides/administration/admin-operations.md index 5df5dba..0d9f8c3 100644 --- a/docs/admin-operations.md +++ b/docs/guides/administration/admin-operations.md @@ -1,6 +1,6 @@ # Admin Operations -This is a brief guide for admins and moderators managing content on the registry. All actions should be taken in line with the [moderation guidelines](./moderation-guidelines.md). +This is a brief guide for admins and moderators managing content on the registry. All actions should be taken in line with the [moderation guidelines](moderation-guidelines.md). ## Prerequisites diff --git a/docs/moderation-guidelines.md b/docs/guides/administration/moderation-guidelines.md similarity index 100% rename from docs/moderation-guidelines.md rename to docs/guides/administration/moderation-guidelines.md diff --git a/docs/guides/consuming/use-rest-api.md b/docs/guides/consuming/use-rest-api.md new file mode 100644 index 0000000..7f1e380 --- /dev/null +++ b/docs/guides/consuming/use-rest-api.md @@ -0,0 +1,77 @@ +# Consuming Registry Data via REST API + +Integration patterns and best practices for building applications that consume MCP registry data. + +## Key details + +**Base URL**: `https://registry.modelcontextprotocol.io` + +**Authentication**: Not required for read-only access + +- **`GET /v0/servers`** - List all servers with pagination +- **`GET /v0/servers/{id}`** - Get full server details including packages and configuration + +See the [interactive API documentation](https://registry.modelcontextprotocol.io/docs) for complete request/response schemas. + +**Disclaimer**: The official registry provides no uptime or data durability guarantees. You should design your applications to handle service downtime via caching. + +## Building a subregistry +**Create enhanced registries** - ETL official registry data and add your own metadata like ratings, security scans, or compatibility info. + +For now we recommend scraping the `GET /v0/servers` endpoint on some regular basis. In the future we might provide a filter for updated_at ([#291](https://github.com/modelcontextprotocol/registry/issues/291)) to get only recently changed servers. + +Servers are generally immutable, except for the `status` field which can be updated to `deleted` (among other states). For these packages, we recommend you also update the status field to `deleted` or remove the package from your registry quickly. This is because this status generally indicates it has violated our permissive [moderation guidelines](../administration/moderation-guidelines.md), suggesting it is illegal, malware or spam. + +### Filtering & Enhancement + +The official registry has a [permissive moderation policy](../administration/moderation-guidelines.md), so you may want to implement your own filtering on top of registry data. + +You can also add custom metadata to servers using the `_meta` field. For example, user ratings, download counts, or security scan results. If you do this, we recommend you put this under a key that is namespaced to your organization, for example: + +```json +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", + "name": "io.github.yourname/weather-server", + "description": "MCP server for weather data access", + "status": "active", + "version_detail": { + "version": "1.0.0" + }, + "packages": [ + { + "registry_type": "npm", + "identifier": "weather-mcp-server", + "version": "1.0.0" + } + ], + "_meta": { + "com.example.subregistry/custom": { + "user_rating": 4.5, + "download_count": 12345, + "security_scan": { + "last_scanned": "2024-06-01T12:00:00Z", + "vulnerabilities_found": 0 + } + } + } +} +``` + +### Providing an API + +We recommend that your subregistry provides an API meeting the registry API specification, so it's easy for clients to switch between registries. See the [registry API documentation](../../reference/api/) for details. + +## MCP Client Integration +**Convert registry data to client configuration** - Fetch servers and transform package information into your MCP client's config format. + +We highly recommend using a subregistry rather than fetching data from the official registry directly. You might want to make this configurable so that users of your client can choose their preferred registry, for example we expect that some enterprise users may have their own registry. + +Your client should gracefully handle registries that meet the minimum spec, i.e. avoid hard dependencies on `_meta` fields. + +### Filtering + +You likely should filter out servers that are not `active` in the `status` field. + +### Running servers + +You can use the `packages` or `remotes` field to determine how to run a server. More details of these fields are in the [server.json documentation](../../reference/server-json/generic-server-json.md). diff --git a/docs/new_package_registry.md b/docs/guides/contributing/add-package-registry.md similarity index 80% rename from docs/new_package_registry.md rename to docs/guides/contributing/add-package-registry.md index c9e2941..e162624 100644 --- a/docs/new_package_registry.md +++ b/docs/guides/contributing/add-package-registry.md @@ -2,9 +2,9 @@ The MCP Registry project is a **metaregistry**, meaning that it hosts metadata for MCP servers but does not host the code for the servers directly. -For local MCP servers, the MCP Registry has pointers in the `packages` node of the [`server.json`](server-json/README.md) schema that refer to packages in supported package managers. +For local MCP servers, the MCP Registry has pointers in the `packages` node of the [`server.json`](../../reference/server-json/generic-server-json.md) schema that refer to packages in supported package managers. -The list of supported package managers for hosting MCP servers is defined by the `properties.packages[N].properties.registry_type` string enum in the [`server.json` schema](server-json/server.schema.json). For example, this could be "npm" (for npmjs.com packages) or "pypi" (for PyPI packages). +The list of supported package managers for hosting MCP servers is defined by the `properties.packages[N].properties.registry_type` string enum in the [`server.json` schema](../../reference/server-json/server.schema.json). For example, this could be "npm" (for npmjs.com packages) or "pypi" (for PyPI packages). For remote MCP servers, the package registry is not relevant. The MCP client consumes the server via a URL instead of by downloading and running a package. In other words, this document only applies to local MCP servers. @@ -33,15 +33,15 @@ These steps may evolve as additional validations or details are discovered and m 1. [Create a feature request issue](https://github.com/modelcontextprotocol/registry/issues/new?template=feature_request.md) on the MCP Registry repository to begin the discussion about adding the package registry. - Example for NuGet: https://github.com/modelcontextprotocol/registry/issues/126 1. Open a PR with the following changes: - - Update the [`server.json` schema](server-json/server.schema.json) + - Update the [`server.json` schema](../../reference/server-json/server.schema.json) - Add your package registry name to the `registry_type` example array. - Add your package registry base url to the `registry_base_url` example array. - Add the single-shot CLI command name to the `runtime_hint` example value array. - - Update the [`openapi.yaml`](server-registry-api/openapi.yaml) + - Update the [`openapi.yaml`](../../reference/api/openapi.yaml) - Add your package registry name to the `registry_type` enum value array. - Add your package registry base url to the `registry_base_url` enum value array. - Add the single-shot CLI command name to the `runtime_hint` example value array. - - Add a sample, minimal `server.json` to the [`server.json` examples](server-json/examples.md). + - Add a sample, minimal `server.json` to the [`server.json` examples](../../reference/server-json/generic-server-json.md). - Implement a registry validator: - Create a new validator file: `internal/validators/registries/yourregistry.go`, following the pattern of existing validators. Examples: - **npm**: Checks for an `mcpName` field in `package.json` that matches the server name @@ -50,3 +50,7 @@ These steps may evolve as additional validations or details are discovered and m - **Docker/OCI**: Validates a Docker image label `io.modelcontextprotocol.server.name` in the image manifest - Add corresponding unit tests: `internal/validators/registries/yourregistry_test.go` - Register your validator in `internal/validators/validators.go` + - Update the publishing documentation: + - Add a new publishing guide: `docs/guides/publishing/publish-[yourregistry].md`, following the pattern of existing publishing guides (e.g., `publish-npm.md`, `publish-pypi.md`) + - Include instructions on how to prepare packages for your registry, including any specific validation requirements + - Update `docs/guides/publishing/README.md` to reference your new publishing guide diff --git a/docs/guides/publishing/github-actions.md b/docs/guides/publishing/github-actions.md new file mode 100644 index 0000000..7433ef1 --- /dev/null +++ b/docs/guides/publishing/github-actions.md @@ -0,0 +1,331 @@ +# Automate Publishing with GitHub Actions + +Set up automated MCP server publishing using GitHub Actions. + +## What You'll Learn + +By the end of this tutorial, you'll have: +- A GitHub Actions workflow that automatically publishes your server +- Understanding of GitHub OIDC authentication +- Knowledge of best practices for automated publishing +- Working examples for Node.js, Python, and Docker projects + +## Prerequisites + +- Already published your server manually (complete [Publishing Tutorial](publish-server.md) first) +- GitHub repository with your MCP server code +- Basic understanding of CI/CD concepts +- 20-30 minutes + +## GitHub Actions Setup + +### Step 1: Create Workflow File + +Create `.github/workflows/publish-mcp.yml` in your repository: + +```yaml +name: Publish to MCP Registry + +on: + push: + tags: ['v*'] # Triggers on version tags like v1.0.0 + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write # Required for OIDC authentication + contents: read + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js # Adjust for your language + uses: actions/setup-node@v4 + with: + node-version: '20' + registry-url: 'https://registry.npmjs.org' + + - name: Install dependencies + run: npm ci + + - name: Run tests + run: npm test + + - name: Build package + run: npm run build + + - name: Publish to npm + run: npm publish + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Install MCP Publisher + run: | + # Build publisher from source (requires Go) + git clone https://github.com/modelcontextprotocol/registry publisher-repo + cd publisher-repo + make publisher + cp cmd/publisher/bin/mcp-publisher ../mcp-publisher + cd .. + chmod +x mcp-publisher + + - name: Login to MCP Registry + run: ./mcp-publisher login github-oidc + + - name: Publish to MCP Registry + run: ./mcp-publisher publish +``` + +### Step 2: Configure Secrets + +For npm publishing, add your NPM token to repository secrets: + +1. Go to repository Settings → Secrets and variables → Actions +2. Add `NPM_TOKEN` with your npm access token + +**Note:** GitHub OIDC authentication requires no additional secrets for MCP Registry publishing. + +### Step 3: Tag and Release + +Create a version tag to trigger the workflow: + +```bash +git tag v1.0.0 +git push origin v1.0.0 +``` + +The workflow will: +1. Run tests +2. Build your package +3. Publish to npm +4. Automatically authenticate with the MCP Registry +5. Publish updated server.json + +## Authentication Methods by CI Platform + +### GitHub Actions - OIDC (Recommended) + +```yaml +- name: Login to MCP Registry + run: mcp-publisher login github-oidc +``` + +**Advantages:** +- No secrets to manage +- Automatically scoped to your repository +- Most secure option + +### GitHub Actions - Personal Access Token + +```yaml +- name: Login to MCP Registry + run: mcp-publisher login github --token ${{ secrets.GITHUB_TOKEN }} + env: + GITHUB_TOKEN: ${{ secrets.MCP_GITHUB_TOKEN }} +``` + +Add `MCP_GITHUB_TOKEN` secret with a GitHub PAT that has repo access. + +### DNS Authentication (Any CI) + +For custom domain namespaces (`com.yourcompany/*`): + +```yaml +- name: Login to MCP Registry + run: | + echo "${{ secrets.MCP_PRIVATE_KEY }}" > key.pem + mcp-publisher login dns --domain yourcompany.com --private-key-file key.pem +``` + +Add your Ed25519 private key as `MCP_PRIVATE_KEY` secret. + +## Language-Specific Examples + +### Python Project + +```yaml +name: Publish Python MCP Server + +on: + push: + tags: ['v*'] + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + + steps: + - uses: actions/checkout@v4 + + - name: Setup Python + uses: actions/setup-python@v4 + with: + python-version: '3.11' + + - name: Install Poetry + run: pipx install poetry + + - name: Build package + run: poetry build + + - name: Publish to PyPI + run: poetry publish + env: + POETRY_PYPI_TOKEN_PYPI: ${{ secrets.PYPI_TOKEN }} + + - name: Install MCP Publisher + run: | + git clone https://github.com/modelcontextprotocol/registry publisher-repo + cd publisher-repo && make publisher && cd .. + cp publisher-repo/cmd/publisher/bin/mcp-publisher mcp-publisher + + - name: Publish to MCP Registry + run: | + ./mcp-publisher login github-oidc + ./mcp-publisher publish +``` + +### Docker Project + +```yaml +name: Publish Docker MCP Server + +on: + push: + tags: ['v*'] + +jobs: + publish: + runs-on: ubuntu-latest + permissions: + id-token: write + contents: read + + steps: + - uses: actions/checkout@v4 + + - name: Setup Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Extract version + id: version + run: echo "version=${GITHUB_REF#refs/tags/v}" >> $GITHUB_OUTPUT + + - name: Build and push + uses: docker/build-push-action@v5 + with: + context: . + push: true + tags: yourname/your-server:${{ steps.version.outputs.version }} + labels: | + io.modelcontextprotocol.server.name=io.github.yourname/your-server + + - name: Install MCP Publisher + run: | + git clone https://github.com/modelcontextprotocol/registry publisher-repo + cd publisher-repo && make publisher && cd .. + cp publisher-repo/cmd/publisher/bin/mcp-publisher mcp-publisher + + - name: Publish to MCP Registry + run: | + ./mcp-publisher login github-oidc + ./mcp-publisher publish +``` + + +## Best Practices + +### 1. Version Alignment + +Keep your package version and server.json version in sync: + +```yaml +- name: Update server.json version + run: | + VERSION=${GITHUB_REF#refs/tags/v} + jq --arg version "$VERSION" '.version_detail.version = $version' server.json > tmp.json + mv tmp.json server.json +``` + +### 2. Conditional Publishing + +Only publish to registry after package publishing succeeds: + +```yaml +- name: Publish to npm + run: npm publish + id: npm-publish + +- name: Publish to MCP Registry + if: steps.npm-publish.outcome == 'success' + run: ./mcp-publisher publish +``` + +### 3. Test Before Publishing + +Include validation in your workflow: + +```yaml +- name: Validate server.json + run: | + # Validate against schema + curl -s https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json | \ + jq . > schema.json + npx ajv-cli validate -s schema.json -d server.json + + # Test with publisher + ./mcp-publisher init --validate-only +``` + +### 4. Notification Setup + +Get notified of publishing status: + +```yaml +- name: Notify on success + if: success() + run: | + curl -X POST "${{ secrets.WEBHOOK_URL }}" \ + -H "Content-Type: application/json" \ + -d '{"text": "✅ MCP server ${{ github.repository }} published successfully"}' + +- name: Notify on failure + if: failure() + run: | + curl -X POST "${{ secrets.WEBHOOK_URL }}" \ + -H "Content-Type: application/json" \ + -d '{"text": "❌ MCP server ${{ github.repository }} publishing failed"}' +``` + +## Troubleshooting + +**"Publisher binary not found"** - Ensure you download the correct binary for your CI platform (linux/mac/windows). + +**"Authentication failed"** - For GitHub OIDC, verify `id-token: write` permission is set. For other methods, check secret configuration. + +**"Package validation failed"** - Ensure your package was published successfully before MCP Registry publishing runs. + +**"Version already exists"** - Each server.json version must be unique. Consider using build numbers: `1.0.0-build.123`. + +## What You've Accomplished + +You now have automated MCP server publishing that: +- Triggers on version tags +- Runs tests before publishing +- Publishes to package registry first +- Automatically publishes to MCP Registry +- Handles authentication securely +- Provides failure notifications + +Your MCP server publishing is now fully automated - just tag a release and everything happens automatically! \ No newline at end of file diff --git a/docs/publisher/guide.md b/docs/guides/publishing/publish-server.md similarity index 51% rename from docs/publisher/guide.md rename to docs/guides/publishing/publish-server.md index fb29982..8b58651 100644 --- a/docs/publisher/guide.md +++ b/docs/guides/publishing/publish-server.md @@ -1,51 +1,80 @@ -# MCP Server Publisher Guide +# Publish Your MCP Server -This guide will explain how you can publish your MCP server to the official registry. +Complete guide to publishing an MCP server to the registry. -## Quick Start +## What You'll Learn + +By the end of this tutorial, you'll have: +- Created a server.json file for your MCP server +- Authenticated with the registry +- Successfully published your server +- Verified your server appears in the registry + +## Prerequisites + +- An MCP server you've already built ([follow this guide if you don't have one already](https://modelcontextprotocol.io/quickstart/server)) +- Your server published to a package registry (npm, PyPI, Docker Hub, etc.) + +## Step 1: Install the Publisher CLI + + + +Download and build the MCP publisher tool: ```bash -# 1. Create a template server.json file -mcp-publisher init +# Clone the registry repository (requires Go 1.24+) +git clone https://github.com/modelcontextprotocol/registry +cd registry +make publisher -# 2. Edit server.json with your server details -# 3. Add registry validation metadata to your package - -# 4. Authenticate with the registry (one-time setup) -mcp-publisher login - -# 5. Publish your server -mcp-publisher publish +# The binary will be at cmd/publisher/bin/mcp-publisher +export PATH=$PATH:$(pwd)/cmd/publisher/bin ``` -## Step 1: Initialize Template +## Step 2: Initialize Your server.json -Create a template `server.json` file with smart auto-detection: +Navigate to your server's directory and create a template: ```bash +cd /path/to/your/mcp-server mcp-publisher init ``` -We'll try to autodetect your configuration, but you'll probably need to fill in some placeholder in the next step. +This creates a `server.json` with auto-detected values. You'll see something like: -## Step 2: Configure Server Details +```json +{ + "$schema": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", + "name": "io.github.yourname/your-server", + "description": "A description of your MCP server", + "version_detail": { + "version": "1.0.0" + }, + "packages": [ + { + "registry_type": "npm", + "identifier": "your-package-name", + "version": "1.0.0" + } + ] +} +``` -Edit the generated `server.json` file with your specific details: +## Step 3: Configure Your Server Details -- **Server name** - Must follow reverse-DNS format (e.g., `io.github.username/server-name`) - - In step 4, you'll have to authenticate to this namespace. If you use your github username, you'll need to login with GitHub. If you use a custom domain, you'll need to set up a DNS or HTTP verification. -- **Description** - Clear explanation of what your server does -- **Package references** - Point to your published packages -- **Runtime configuration** - Arguments, environment variables, etc. - - We recommend trying to reduce the configuration your server needs to start up, and using environment variables where configuration is needed. +Edit the generated `server.json`: -**📖 Resources:** -- **[server.json Examples](../server-json/examples.md)** - Real-world server configurations -- **[server.json Specification](../server-json/)** - Complete field reference +### Choose Your Namespace -## Step 3: Add Package Validation Metadata +The `name` field determines authentication requirements: + +- **`io.github.yourname/*`** - Requires GitHub authentication +- **`com.yourcompany/*`** - Requires DNS or HTTP domain verification + +### Add Package Validation + +Your package must include validation metadata to prove ownership. -All packages must include ownership verification metadata to prevent misattribution. When you publish, the registry validates that you actually control the packages you're referencing by checking for specific metadata in each package.
📦 NPM Packages @@ -207,95 +236,74 @@ The official MCP registry currently only supports artifacts hosted on GitHub or
-## Step 4: Authenticate with Registry +## Step 4: Authenticate -Choose your authentication method based on your use case: +Choose your authentication method based on your namespace: -
-🐙 GitHub - -GitHub auth grants publishing rights for `io.github.{username}/*` and `io.github.{org}/*` namespaces - -### Interactive +### GitHub Authentication (for io.github.* namespaces) ```bash mcp-publisher login github ``` -- Opens browser for GitHub OAuth +This opens your browser for OAuth authentication. -### CI/CD in GitHub Actions +### DNS Authentication (for custom domains) ```bash -mcp-publisher login github-oidc -``` - -- Uses GitHub Actions OIDC tokens automatically -- Requires `id-token: write` permission in workflow - -#### GitHub Actions Example -```yaml -name: Publish to MCP Registry -on: - push: - tags: ['v*'] - -jobs: - publish: - runs-on: ubuntu-latest - permissions: - id-token: write # Required for OIDC - contents: read - steps: - - uses: actions/checkout@v4 - - name: Login to Registry - run: mcp-publisher login github-oidc - - name: Publish to Registry - run: mcp-publisher publish -``` - -
- -
-🌐 DNS - -DNS auth grants publishing rights for `com.yourdomain/*` and `com.yourdomain.*/*` namespaces. - -```bash -# 1. Generate keypair and get DNS record +# Generate keypair openssl genpkey -algorithm Ed25519 -out key.pem -echo "Add this TXT record to your domain:" -echo "_mcp-registry.yourdomain.com. IN TXT \"v=MCPv1; k=ed25519; p=$(openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64)\"" -# 2. Login with private key -mcp-publisher login dns --domain yourdomain.com --private-key $(openssl pkey -in key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n') +# Get public key for DNS record +echo "_mcp-registry.yourcompany.com. IN TXT \"v=MCPv1; k=ed25519; p=$(openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64)\"" + +# Add the TXT record to your DNS, then login +mcp-publisher login dns --domain yourcompany.com --private-key $(openssl pkey -in key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n') ``` -
- -
-🔗 HTTP - -HTTP auth grants publishing rights for the `com.yourdomain/*` namespace. - -```bash -# 1. Generate keypair and host public key -openssl genpkey -algorithm Ed25519 -out key.pem -echo "Host at: https://yourdomain.com/.well-known/mcp-registry-auth" -echo "Content: v=MCPv1; k=ed25519; p=$(openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64)" - -# 2. Login with private key -mcp-publisher login http --domain yourdomain.com --private-key $(openssl pkey -in key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n') -``` - -
- ## Step 5: Publish Your Server -Once you've completed steps 1-4, publish your server: +With authentication complete, publish your server: ```bash mcp-publisher publish ``` -If successful, your server will be available at `https://registry.modelcontextprotocol.io`! +You'll see output like: +``` +✓ Validating server.json +✓ Checking package ownership +✓ Publishing to registry +✓ Server published successfully! + +Your server is now available at: +https://registry.modelcontextprotocol.io/servers/io.github.yourname/weather-server +``` + +## Step 6: Verify Publication + +Check that your server appears in the registry: + +```bash +curl https://registry.modelcontextprotocol.io/servers/io.github.yourname/weather-server +``` + +You should see your server metadata returned as JSON. + +## Troubleshooting + +**"Package validation failed"** - Ensure your package includes the required validation metadata (mcpName field, README mention, or Docker label). + +**"Authentication failed"** - Verify you've correctly set up DNS records or are logged into the right GitHub account. + +**"Namespace not authorized"** - Your authentication method doesn't match your chosen namespace format. + +## Next Steps + +- **Update your server**: Publish new versions with updated server.json files +- **Set up CI/CD**: Automate publishing with [GitHub Actions](github-actions.md) +- **Learn more**: Understand [server.json format](../../reference/server-json/generic-server-json.md) in depth + +## What You've Accomplished + +You've successfully published your first MCP server to the registry! Your server is now discoverable by MCP clients and can be installed by users worldwide. \ No newline at end of file diff --git a/docs/reference/README.md b/docs/reference/README.md new file mode 100644 index 0000000..d69ae2c --- /dev/null +++ b/docs/reference/README.md @@ -0,0 +1,21 @@ +# Reference Documentation + +Technical specifications and quick lookups for the MCP Registry. + +## API Reference + +- [Generic Registry API](./api/generic-registry-api.md) +- [Official Registry API](./api/official-registry-api.md) + +## server.json Reference + +- [Generic server.json Format](./server-json/generic-server-json.md) +- [Official Registry Requirements](./server-json/official-registry-requirements.md) + +## CLI Reference + +- [Commands](./cli/commands.md) + +## Quick Reference + +- [FAQ](./faq.md) \ No newline at end of file diff --git a/docs/reference/api/generic-registry-api.md b/docs/reference/api/generic-registry-api.md new file mode 100644 index 0000000..a5fe987 --- /dev/null +++ b/docs/reference/api/generic-registry-api.md @@ -0,0 +1,54 @@ +# Generic Registry API Specification + +A standardized RESTful HTTP API for MCP registries to provide consistent endpoints for discovering and retrieving MCP servers. + +Also see: +- For guidance consuming the API, see the [consuming guide](../../guides/consuming/use-rest-api.md). + +## Browse the Complete API Specification + +**📋 View the full API specification interactively**: Open [openapi.yaml](./openapi.yaml) in an OpenAPI viewer like [Stoplight Elements](https://elements-demo.stoplight.io/?spec=https://raw.githubusercontent.com/modelcontextprotocol/registry/refs/heads/main/docs/reference/api/openapi.yaml). + +The official registry has some more endpoints and restrictions on top of this. See the [official registry API spec](./official-registry-api.md) for details. + +## Quick Reference + +### Core Endpoints +- **`GET /v0/servers`** - List all servers with pagination +- **`GET /v0/servers/{id}`** - Get detailed server information by ID +- **`POST /v0/publish`** - Publish new server (optional, registry-specific authentication) + +### Authentication +- **Read operations**: No authentication required +- **Write operations**: Registry-specific authentication (if supported) + +### Content Type +All requests and responses use `application/json` + +### Basic Example: List Servers + +```bash +curl https://registry.example.com/v0/servers?limit=10 +``` + +```json +{ + "servers": [ + { + "name": "io.modelcontextprotocol/filesystem", + "description": "Filesystem operations server", + "status": "active", + "version_detail": { + "version": "1.0.2", + "is_latest": true + } + } + ], + "metadata": { + "count": 10, + "next_cursor": "eyJ..." + } +} +``` + +For complete endpoint documentation, view the OpenAPI specification in a schema viewer. diff --git a/docs/reference/api/official-registry-api.md b/docs/reference/api/official-registry-api.md new file mode 100644 index 0000000..c482397 --- /dev/null +++ b/docs/reference/api/official-registry-api.md @@ -0,0 +1,48 @@ +# Official MCP Registry API + +This document describes the API for the official MCP Registry hosted at `registry.modelcontextprotocol.io`. + +This API is based on the [generic registry API](./generic-registry-api.md) with additional endpoints and authentication. For practical examples of consuming the API, see the [API usage guide](../../guides/consuming/use-rest-api.md). For publishing servers using the API, see the [publishing guide](../../guides/publishing/publish-server.md). + +## Base URLs + +- **Production**: `https://registry.modelcontextprotocol.io` +- **Staging**: `https://staging.registry.modelcontextprotocol.io` + +## Interactive Documentation + +- **[Live API Docs](https://registry.modelcontextprotocol.io/docs)** - Stoplight elements with try-it-now functionality +- **[OpenAPI Spec](https://registry.modelcontextprotocol.io/openapi.yaml)** - Complete machine-readable specification + +## Extensions + +The official registry implements the [Generic Registry API](./generic-registry-api.md) with the following specific configurations and extensions: + +### Authentication + +Publishing requires namespace-based authentication: + +- **GitHub OAuth** - For `io.github.*` namespaces +- **GitHub OIDC** - For publishing from GitHub Actions +- **DNS verification** - For domain-based namespaces (`com.example.*`) +- **HTTP verification** - For domain-based namespaces (`com.example.*`) + +See [Publisher Commands](../cli/commands.md) for authentication setup. + +### Package Validation + +The official registry enforces additional [package validation requirements](../server-json/official-registry-requirements.md) when publishing. + +### Additional endpoints + +#### Auth endpoints +- POST `/v0/auth/dns` - Exchange signed DNS challenge for auth token +- POST `/v0/auth/http` - Exchange signed HTTP challenge for auth token +- POST `/v0/auth/github-at` - Exchange GitHub access token for auth token +- POST `/v0/auth/github-oidc` - Exchange GitHub OIDC token for auth token +- POST `/v0/auth/oidc` - Exchange Google OIDC token for auth token (for admins) + +#### Admin endpoints +- GET `/metrics` - Prometheus metrics endpoint +- GET `/v0/health` - Basic health check endpoint +- PUT `/v0/servers/{id}` - Edit existing server diff --git a/docs/server-registry-api/openapi.yaml b/docs/reference/api/openapi.yaml similarity index 96% rename from docs/server-registry-api/openapi.yaml rename to docs/reference/api/openapi.yaml index d62d90b..40d3806 100644 --- a/docs/server-registry-api/openapi.yaml +++ b/docs/reference/api/openapi.yaml @@ -12,7 +12,7 @@ info: identifier: MIT paths: - /servers: + /v0/servers: get: summary: List MCP servers description: Returns a list of all registered MCP servers @@ -36,7 +36,7 @@ paths: application/json: schema: $ref: '#/components/schemas/ServerList' - /servers/{id}: + /v0/servers/{id}: get: summary: Get MCP server details description: Returns detailed information about a specific MCP server @@ -70,10 +70,15 @@ paths: error: type: string example: "Server not found" - /publish: + /v0/publish: post: - summary: Publish MCP server - description: Publish a new MCP server to the registry or update an existing one + summary: Publish MCP server (Optional) + description: | + Publish a new MCP server to the registry or update an existing one. + + **Note**: This endpoint is optional for registry implementations. Read-only registries may not provide this functionality. + + Authentication mechanism is registry-specific and may vary between implementations. security: - bearerAuth: [] requestBody: @@ -176,7 +181,10 @@ components: type: http scheme: bearer bearerFormat: JWT - description: Registry JWT token. Convention is that this can be obtained from a `/v0/auth/` endpoint. + description: | + Registry-specific authentication token. The authentication mechanism and token format may vary between registry implementations. + + Some registries may use JWT tokens, others may use API keys or OAuth. Consult your specific registry's authentication documentation. schemas: Repository: type: object diff --git a/docs/reference/cli/commands.md b/docs/reference/cli/commands.md new file mode 100644 index 0000000..2b2e201 --- /dev/null +++ b/docs/reference/cli/commands.md @@ -0,0 +1,187 @@ +# Publisher CLI Commands Reference + +Complete command reference for the `mcp-publisher` CLI tool. + +See the [publishing guide](../../guides/publishing/publish-server.md) for a walkthrough of using the CLI to publish a server. + +## Installation + + + +```bash +# Build from source (from repository root) +make publisher +# Binary created at ./cmd/publisher/bin/mcp-publisher + +# Install globally (optional) +cp ./cmd/publisher/bin/mcp-publisher /usr/local/bin/ +``` + +## Global Options + +All commands support: +- `--help`, `-h` - Show command help +- `--registry` - Registry URL (default: `https://registry.modelcontextprotocol.io`) + +## Commands + +### `mcp-publisher init` + +Generate a `server.json` template with automatic detection. + +**Usage:** +```bash +mcp-publisher init [options] +``` + +**Behavior:** +- Creates `server.json` in current directory +- Auto-detects package managers (`package.json`, `setup.py`, etc.) +- Pre-fills fields where possible +- Prompts for missing required fields + +**Example output:** +```json +{ + "name": "io.github.username/server-name", + "description": "TODO: Add server description", + "version_detail": { "version": "1.0.0" }, + "packages": [ + { + "registry_type": "npm", + "identifier": "detected-package-name", + "version": "1.0.0" + } + ] +} +``` + +### `mcp-publisher login ` + +Authenticate with the registry. + +**Authentication Methods:** + +#### GitHub Interactive +```bash +mcp-publisher login github [--registry=URL] +``` +- Opens browser for GitHub OAuth flow +- Grants access to `io.github.{username}/*` and `io.github.{org}/*` namespaces + +#### GitHub OIDC (CI/CD) +```bash +mcp-publisher login github-oidc [--registry=URL] +``` +- Uses GitHub Actions OIDC tokens automatically +- Requires `id-token: write` permission in workflow +- No browser interaction needed + +Also see [the guide to publishing from GitHub Actions](../../guides/publishing/github-actions.md). + +#### DNS Verification +```bash +mcp-publisher login dns --domain=example.com --private-key=HEX_KEY [--registry=URL] +``` +- Verifies domain ownership via DNS TXT record +- Grants access to `com.example.*` namespaces +- Requires Ed25519 private key (64-character hex) + +**Setup:** +```bash +# Generate keypair +openssl genpkey -algorithm Ed25519 -out key.pem + +# Get public key for DNS record +openssl pkey -in key.pem -pubout -outform DER | tail -c 32 | base64 + +# Add DNS TXT record: +# _mcp-registry.example.com. IN TXT "v=MCPv1; k=ed25519; p=PUBLIC_KEY" + +# Extract private key for login +openssl pkey -in key.pem -noout -text | grep -A3 "priv:" | tail -n +2 | tr -d ' :\n' +``` + +#### HTTP Verification +```bash +mcp-publisher login http --domain=example.com --private-key=HEX_KEY [--registry=URL] +``` +- Verifies domain ownership via HTTPS endpoint +- Grants access to `com.example.*` namespaces +- Requires Ed25519 private key (64-character hex) + +**Setup:** +```bash +# Generate keypair (same as DNS) +openssl genpkey -algorithm Ed25519 -out key.pem + +# Host public key at: +# https://example.com/.well-known/mcp-registry-auth +# Content: v=MCPv1; k=ed25519; p=PUBLIC_KEY +``` + +#### Anonymous (Testing) +```bash +mcp-publisher login none [--registry=URL] +``` +- No authentication - for local testing only +- Only works with local registry instances + +### `mcp-publisher publish` + +Publish server to the registry. + +For detailed guidance on the publishing process, see the [publishing guide](../../guides/publishing/publish-server.md). + +**Usage:** +```bash +mcp-publisher publish [options] +``` + +**Options:** +- `--file=PATH` - Path to server.json (default: `./server.json`) +- `--registry=URL` - Registry URL override +- `--dry-run` - Validate without publishing + +**Process:** +1. Validates `server.json` against schema +2. Verifies package ownership (see [Official Registry Requirements](../server-json/official-registry-requirements.md)) +3. Checks namespace authentication +4. Publishes to registry + +**Example:** +```bash +# Basic publish +mcp-publisher publish + +# Dry run validation +mcp-publisher publish --dry-run + +# Custom file location +mcp-publisher publish --file=./config/server.json +``` + +### `mcp-publisher logout` + +Clear stored authentication credentials. + +**Usage:** +```bash +mcp-publisher logout +``` + +**Behavior:** +- Removes `~/.mcp_publisher_token` +- Does not revoke tokens on server side + +## Configuration + +### Token Storage +Authentication tokens stored in `~/.mcp_publisher_token` as JSON: +```json +{ + "token": "jwt-token-here", + "registry_url": "https://registry.modelcontextprotocol.io", + "expires_at": "2024-12-31T23:59:59Z" +} +``` diff --git a/docs/faq.md b/docs/reference/faq.md similarity index 95% rename from docs/faq.md rename to docs/reference/faq.md index 548a2d9..d23e5bf 100644 --- a/docs/faq.md +++ b/docs/reference/faq.md @@ -16,7 +16,7 @@ The MCP Registry is the official centralized metadata repository for publicly-ac ### What is the difference between "Official MCP Registry", "MCP Registry", "MCP registry", "MCP Registry API", etc? There are four underlying concepts: -- "MCP Server Registry API" (or "MCP Registry API"): The OpenAPI specification defined in [openapi.yaml](./server-registry-api/openapi.yaml). This is a reusable API specification that anyone building any sort of "MCP server registry" should consider adopting / aligning with. +- "MCP Server Registry API" (or "MCP Registry API"): The OpenAPI specification defined in [openapi.yaml](./api/openapi.yaml). This is a reusable API specification that anyone building any sort of "MCP server registry" should consider adopting / aligning with. - "Official MCP Registry" (or "MCP Registry"): The application that lives at `https://registry.modelcontextprotocol.io`. This registry currently only catalogs MCP servers, but may be extended in the future to also catalog MCP client/host apps and frameworks. - "Official MCP Registry API": The REST API served at `https://registry.modelcontextprotocol.io`, which is a superset of the MCP Registry API. Its OpenAPI specification can be downloaded from [https://registry.modelcontextprotocol.io/openapi.yaml](https://registry.modelcontextprotocol.io/openapi.yaml) - "MCP server registry" (or "MCP registry"): A third party, likely commercial, implementation of the MCP Server Registry API or derivative specification. @@ -35,13 +35,13 @@ The registry is designed for programmatic consumption by: ### Will there be feature X? -See [roadmap.md](./roadmap.md). +See [roadmap.md](../explanations/roadmap.md). ## Publishing Servers ### How do I publish my MCP server? -See the [publisher README](../cmd/publisher/README.md) +See the [publisher README](../../cmd/publisher/README.md) ### What namespaces are available? @@ -83,7 +83,7 @@ The registry accepts any version string up to 255 characters, but we recommend: - **SHOULD align with package versions** to reduce confusion - **MAY use prerelease labels** (e.g., "1.0.0-1") for registry-specific versions -The registry attempts to parse versions as semantic versions for proper ordering. Non-semantic versions are allowed but will be ordered by publication timestamp. See the [versioning guide](./versioning.md) for detailed guidance. +The registry attempts to parse versions as semantic versions for proper ordering. Non-semantic versions are allowed but will be ordered by publication timestamp. See the [versioning guide](../explanations/versioning.md) for detailed guidance. ### Can I add custom metadata when publishing? diff --git a/docs/server-json/examples.md b/docs/reference/server-json/generic-server-json.md similarity index 91% rename from docs/server-json/examples.md rename to docs/reference/server-json/generic-server-json.md index 4ae7b52..423b1de 100644 --- a/docs/server-json/examples.md +++ b/docs/reference/server-json/generic-server-json.md @@ -1,6 +1,24 @@ -# Server JSON Examples +# server.json Format Specification -## Basic Server with NPM Package +A `server.json` file is a standardized way to describe MCP servers for registry publishing, client discovery, and package management. + +Also see: +- For step-by-step instructions on creating and using server.json files, see the [publishing guide](../../guides/publishing/publish-server.md). +- For understanding the validation requirements when publishing to the official registry, see [official registry requirements](./official-registry-requirements.md). + +## Browse the Complete Schema + +**📋 View the full specification interactively**: Open [server.schema.json](./server.schema.json) in a schema viewer like [json-schema.app](https://json-schema.app/view/%23?url=https%3A%2F%2Fstatic.modelcontextprotocol.io%2Fschemas%2F2025-07-09%2Fserver.schema.json). + +The schema contains all field definitions, validation rules, examples, and detailed descriptions. + +The official registry has some more restrictions on top of this. See the [official registry requirements](./official-registry-requirements.md) for details. + +## Examples + + + +### Basic Server with NPM Package ```json { @@ -46,7 +64,7 @@ } ``` -## Server in a Monorepo with Subfolder +### Server in a Monorepo with Subfolder For MCP servers located within a subdirectory of a larger repository (monorepo structure), use the `subfolder` field to specify the relative path: @@ -87,7 +105,7 @@ For MCP servers located within a subdirectory of a larger repository (monorepo s } ``` -## Constant (fixed) arguments needed to start the MCP server +### Constant (fixed) arguments needed to start the MCP server Suppose your MCP server application requires a `mcp start` CLI arguments to start in MCP server mode. Express these as positional arguments like this: @@ -134,7 +152,7 @@ Suppose your MCP server application requires a `mcp start` CLI arguments to star This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcpServer@0.4.0-beta -- mcp start` instead of the default `dnx Knapcode.SampleMcpServer@0.4.0-beta` (when no `package_arguments` are provided). -## Filesystem Server with Multiple Packages +### Filesystem Server with Multiple Packages ```json { @@ -238,7 +256,7 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp } ``` -## Remote Server Example +### Remote Server Example ```json { @@ -273,7 +291,7 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp } ``` -## Python Package Example +### Python Package Example ```json { @@ -327,7 +345,7 @@ This will essentially instruct the MCP client to execute `dnx Knapcode.SampleMcp } ``` -## NuGet (.NET) Package Example +### NuGet (.NET) Package Example The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6. @@ -379,7 +397,7 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6. } ``` -## Complex Docker Server with Multiple Arguments +### Complex Docker Server with Multiple Arguments ```json { @@ -491,7 +509,7 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6. } ``` -## Server with Remote and Package Options +### Server with Remote and Package Options ```json { @@ -578,7 +596,7 @@ The `dnx` tool ships with the .NET 10 SDK, starting with Preview 6. } ``` -## MCP Bundle (MCPB) Package Example +### MCP Bundle (MCPB) Package Example ```json { @@ -621,7 +639,7 @@ This example shows an MCPB (MCP Bundle) package that: - Includes a SHA-256 hash for integrity verification - Can be downloaded and executed directly by MCP clients that support MCPB -## Embedded MCP inside a CLI tool +### Embedded MCP inside a CLI tool Some CLI tools bundle an MCP server, without a standalone MCP package or a public repository. In these cases, reuse the existing `packages` shape by pointing at the host CLI package and supplying the `package_arguments` and `runtime_hint` if needed to start the MCP server. @@ -658,7 +676,7 @@ Some CLI tools bundle an MCP server, without a standalone MCP package or a publi } ``` -## Deprecated Server Example +### Deprecated Server Example ```json { diff --git a/docs/reference/server-json/official-registry-requirements.md b/docs/reference/server-json/official-registry-requirements.md new file mode 100644 index 0000000..fc52a27 --- /dev/null +++ b/docs/reference/server-json/official-registry-requirements.md @@ -0,0 +1,48 @@ +# Official Registry Server.json Requirements + +This document describes the additional requirements and validation rules that apply when publishing to the official MCP Registry at `registry.modelcontextprotocol.io`. + +For step-by-step publishing instructions, see the [publishing guide](../../guides/publishing/publish-server.md). + +## Overview + +While the [generic server.json format](./generic-server-json.md) defines the base specification, the official registry enforces additional validation to ensure: + +- **Namespace authentication** - Servers are published under appropriate namespaces +- **Package ownership verification** - Publishers actually control referenced packages +- **Remote server URL match** - Remote server base urls match namespaces +- **Restricted registry base urls** - Packages are from trusted public registries +- **`_meta` namespace restrictions** - Restricted to `publisher` key only + +## Namespace Authentication + +Publishers must prove ownership of their namespace. For example to publish to `com.example/server`, the publisher must prove they own the `example.com` domain. + +See the [publishing guide](../../guides/publishing/publish-server.md) for authentication details for GitHub and domain namespaces. + +## Package Ownership Verification + +All packages must include metadata proving the publisher owns them. This prevents impersonation and ensures authenticity (see more reasoning in [#96](https://github.com/modelcontextprotocol/registry/issues/96)). + +For detailed verification requirements for each registry type, see the [publishing guide](../../guides/publishing/publish-server.md). + +## Remote Server URL Match + +Remote servers must use URLs that match the publisher's domain from their namespace. For example, `com.example/server` can only use remote URLs on `example.com` or its subdomains. + +## Restricted Registry Base URLs + +Only trusted public registries are supported. Private registries and alternative mirrors are not allowed. + +**Supported registries:** +- **NPM**: `https://registry.npmjs.org` only +- **PyPI**: `https://pypi.org` only +- **NuGet**: `https://api.nuget.org` only +- **Docker/OCI**: `https://docker.io` only +- **MCPB**: `https://github.com` releases and `https://gitlab.com` releases only + +## `_meta` Namespace Restrictions + +The `_meta` field is restricted to the `publisher` key only during publishing. This `_meta.publisher` extension is currently limited to 4KB. + +Registry metadata is added automatically and cannot be overridden. diff --git a/docs/server-json/server.schema.json b/docs/reference/server-json/server.schema.json similarity index 90% rename from docs/server-json/server.schema.json rename to docs/reference/server-json/server.schema.json index 333d8e3..4caadd6 100644 --- a/docs/server-json/server.schema.json +++ b/docs/reference/server-json/server.schema.json @@ -6,6 +6,7 @@ "$defs": { "Repository": { "type": "object", + "description": "Repository metadata for the MCP server source code. Enables users and security experts to inspect the code, improving transparency.", "required": [ "url", "source" @@ -14,20 +15,22 @@ "url": { "type": "string", "format": "uri", + "description": "Repository URL for browsing source code. Should support both web browsing and git clone operations.", "example": "https://github.com/modelcontextprotocol/servers" }, "source": { "type": "string", - "description": "Repository hosting service", + "description": "Repository hosting service identifier. Used by registries to determine validation and API access methods.", "example": "github" }, "id": { "type": "string", + "description": "Repository identifier from the hosting service (e.g., GitHub repo ID). Owned and determined by the source forge. Should remain stable across repository renames and may be used to detect repository resurrection attacks - if a repository is deleted and recreated, the ID should change. For GitHub, use: gh api repos// --jq '.id'", "example": "b94b5f7e-c7c6-d760-2c78-a5e9b8a5b8c9" }, "subfolder": { "type": "string", - "description": "Optional relative path from repository root to the server location within a monorepo or nested package structure", + "description": "Optional relative path from repository root to the server location within a monorepo or nested package structure. Must be a clean relative path.", "example": "src/everything" } } @@ -57,15 +60,16 @@ "properties": { "name": { "type": "string", - "description": "Server name/identifier", - "example": "io.modelcontextprotocol/filesystem", - "minLength": 1, + "description": "Server name in reverse-DNS format. Must contain exactly one forward slash separating namespace from server name.", + "example": "io.github.user/weather", + "pattern": "^[a-zA-Z0-9.-]+/[a-zA-Z0-9._-]+$", + "minLength": 3, "maxLength": 200 }, "description": { "type": "string", - "description": "Human-readable description of the server's functionality", - "example": "Node.js server implementing Model Context Protocol (MCP) for filesystem operations.", + "description": "Clear human-readable explanation of server functionality. Should focus on capabilities, not implementation details.", + "example": "MCP server providing weather data and forecasts via OpenWeatherMap API", "minLength": 1, "maxLength": 100 }, @@ -76,7 +80,8 @@ "description": "Server lifecycle status. 'deprecated' indicates the server is no longer recommended for new usage. 'deleted' indicates the server should never be installed and existing installations should be uninstalled - this is rare, and usually indicates malware or a legal takedown." }, "repository": { - "$ref": "#/$defs/Repository" + "$ref": "#/$defs/Repository", + "description": "Optional repository metadata for the MCP server source code. Recommended for transparency and security inspection." }, "version_detail": { "$ref": "#/$defs/VersionDetail" diff --git a/docs/server-json/README.md b/docs/server-json/README.md deleted file mode 100644 index e579386..0000000 --- a/docs/server-json/README.md +++ /dev/null @@ -1,39 +0,0 @@ -# server.json file - -There are a variety of use cases where a _static representation of an MCP server_ is necessary: -- Discoverability on a centralized registry (i.e. our official Registry work) -- Discoverability on a decentralized `.well-known` endpoint -- As a response to an initialization call, so the client knows information about the MCP server to which it is connecting -- As an input into crafting a [DXT file](https://www.anthropic.com/engineering/desktop-extensions) -- Packaged in with the source code of an MCP server, so as to have a structured way to identify a server given just its source code - -All of these scenarios (and more) would benefit from an agreed-upon, standardized format that makes it easy to port around and maintain a consistent experience for consumers and developers working with the data. At the end of the day, it's all the same data (or a subset of it). MCP server maintainers should have to manage one copy of this file, and all these use cases can serve that file (or a programmatic derivative/subset of it). - -Please note: this is different from the file commonly referred to as `mcp.json`, which is _an MCP client's configuration file for **running** a specific set of MCP servers_. See [this issue](https://github.com/modelcontextprotocol/modelcontextprotocol/issues/292). - -References: -- [server.schema.json](./server.schema.json) - The official JSON schema specification for this representation -- [examples.md](./examples.md) - Example manifestations of the JSON schema -- [registry-schema.json](./registry-schema.json) - A more constrained version of `server.schema.json` that the official registry supports - -## Validation Tools - -Two validation tools are provided in the repository's `tools/` directory: -- **validate-schemas** - Validates that `server.schema.json` and `registry-schema.json` are valid JSON Schema documents -- **validate-examples** - Validates that all JSON examples in `examples.md` conform to both schemas - -### Usage - -From the repository root: - -#### Validate JSON Schemas - -```bash -./tools/validate-schemas.sh -``` - -#### Validate Examples - -```bash -./tools/validate-examples.sh -``` \ No newline at end of file diff --git a/docs/server-json/registry-schema.json b/docs/server-json/registry-schema.json deleted file mode 100644 index adfa67e..0000000 --- a/docs/server-json/registry-schema.json +++ /dev/null @@ -1,51 +0,0 @@ -{ - "$schema": "https://json-schema.org/draft/2020-12/schema", - "$id": "https://modelcontextprotocol.io/schemas/draft/2025-07-09/registry-server.json", - "title": "MCP Server Detail - Registry Schema", - "description": "Registry-specific constraints for MCP server representation. Extends the base schema with additional validation rules.", - "$ref": "https://static.modelcontextprotocol.io/schemas/2025-07-09/server.schema.json", - "properties": { - "repository": { - "properties": { - "source": { - "enum": [ - "github" - ] - } - } - }, - "packages": { - "items": { - "properties": { - "registry_type": { - "enum": [ - "npm", - "pypi", - "oci", - "nuget", - "mcpb" - ] - }, - "registry_base_url": { - "enum": [ - "https://registry.npmjs.org", - "https://pypi.org", - "https://docker.io", - "https://api.nuget.org", - "https://github.com", - "https://gitlab.com" - ] - }, - "runtime_hint": { - "enum": [ - "npx", - "uvx", - "docker", - "dnx" - ] - } - } - } - } - } -} \ No newline at end of file diff --git a/docs/server-json/repository_references.md b/docs/server-json/repository_references.md deleted file mode 100644 index abb48c1..0000000 --- a/docs/server-json/repository_references.md +++ /dev/null @@ -1,36 +0,0 @@ -# Repository References in server.json - -The [`server.json` schema](server.schema.json) MAY contain a `repository` property at the root of the JSON object. The `repository` object provides metadata about the MCP server's source code. This enables users and security experts to inspect the code of the MCP service, thereby improving the transparency of what the MCP server is doing at runtime. - -The inclusion of the `repository` object is RECOMMENDED for both local and remote MCP servers. - -Consumers of the `server.json` metadata MAY use the `source` property to determine which specific source forge is used for hosting the MCP server's code. The value of `source` SHOULD be a string enum (a well-known list of values defined by the MCP Registry deployment). - -The `url` property MAY be used to browse the source code. Some source forges, such as GitHub, support `git clone ` on the URL, which also works for web browsing. For the purposes of the Official MCP Registry, the URL MUST be accessible in a web browser. - -The optional `subfolder` property MAY be used to specify a relative path from the repository root to the location of the MCP server within a monorepo structure. The value MUST be a clean relative path. - -The `id` property is owned and determined by the source forge, such as GitHub. This value SHOULD be stable across repository renames and, if applicable on the source forge, MAY be used to detect repository resurrection attacks. If a repository is renamed, the `id` value SHOULD remain constant. If the repository is deleted and then recreated later, the `id` value SHOULD change. - -Determining the `id` is specific to the source forge. For GitHub, the following [GitHub CLI](https://cli.github.com/) command MAY be used (works for both public and private repositories): - -```bash -gh auth login -gh api repos// --jq '.id' -``` - -MCP server registries MAY define their own policies for allowed `source` values and whether the `url` MUST be publicly accessible. - -An MCP server registry SHOULD validate that the `id` matches the given `url`, perhaps by invoking source-specific REST APIs to match the `id`. MCP server publish tooling MAY compute the `id` value dynamically and enrich the `server.json` payload provided to the publish endpoint to simplify the workflow. - -## Official MCP Registry Policies - -The `repository` metadata MAY be included in the `server.json`, as in the general MCP Registry protocol. - -The Official MCP Registry has policies related to the `repository` object that are stricter than those the general MCP Registry protocol allows. - -See the [`registry-schema.json`](registry-schema.json) for the allowed `source` values. - -The repository referenced by the `repository` property SHOULD be publicly accessible, but this is not REQUIRED. - -The `id` MUST match the repository referenced by the `url`. diff --git a/docs/server-registry-api/README.md b/docs/server-registry-api/README.md deleted file mode 100644 index 1facb31..0000000 --- a/docs/server-registry-api/README.md +++ /dev/null @@ -1,13 +0,0 @@ -# Registry API - -There are a variety of use cases where an MCP Server Registry API is useful to the MCP ecosystem. At least the following: -- Implementation of a centralized, publicly available catalog of all publicly accessible MCP server implementations -- Implementation of a private catalog of MCP server implementations exclusively accessible by a specific group of people (e.g. a single enterprise) - -These scenarios would benefit from a standard "MCP server registry API" specification that they could potentially compose, as well as share resources (like SDK implementations). - -The centralized, publicly available catalog ("Official MCP Registry") needs additional constraints that need not apply to the broader "MCP server registry API" - -References: -- [openapi.yaml](./openapi.yaml) - A reusable API specification (MCP Server Registry API) that anyone building any sort of "MCP server registry" should consider adopting / aligning with. -- [https://registry.modelcontextprotocol.io/openapi.yaml](https://registry.modelcontextprotocol.io/openapi.yaml) - The specification backing the Official MCP Registry; a derivative of the MCP Server Registry API specification. diff --git a/tests/integration/README.md b/tests/integration/README.md index 3766b60..63d6c1c 100644 --- a/tests/integration/README.md +++ b/tests/integration/README.md @@ -6,7 +6,7 @@ This directory contains an end-to-end test for publishing to the registry. 1. **Publisher Tool**: Tests the `publisher` CLI that publishes metadata to the registry 2. **Registry API**: Validates the `/v0/publish` and `/v0/servers/{id}` endpoints work correctly -3. **Example Validation**: Ensures all example JSON in `docs/server-json/examples.md` is valid and can be published +3. **Example Validation**: Ensures all example JSON in `docs/reference/server-json/generic-server-json.md` is valid and can be published 4. **Data Consistency**: Verifies published data matches what's retrieved from the registry ## Test Flow diff --git a/tests/integration/main.go b/tests/integration/main.go index b7d785f..2d78e4a 100644 --- a/tests/integration/main.go +++ b/tests/integration/main.go @@ -30,7 +30,7 @@ func main() { } func run() error { - examplesPath := filepath.Join("docs", "server-json", "examples.md") + examplesPath := filepath.Join("docs", "reference", "server-json", "generic-server-json.md") examples, err := getExamples(examplesPath) if err != nil { log.Fatalf("failed to extract examples: %v", err) diff --git a/tools/validate-examples.sh b/tools/validate-examples.sh index 0e58fcb..377e970 100755 --- a/tools/validate-examples.sh +++ b/tools/validate-examples.sh @@ -1,6 +1,5 @@ #!/bin/bash -# Validate examples in docs/server-json/examples.md -# For more information, see docs/server-json/README.md +# Validate example server.json files set -e diff --git a/tools/validate-examples/main.go b/tools/validate-examples/main.go index 23f140c..73fa1e8 100644 --- a/tools/validate-examples/main.go +++ b/tools/validate-examples/main.go @@ -20,10 +20,9 @@ import ( ) const ( - // expectedExampleCount is the number of JSON examples we expect to find in examples.md - // IMPORTANT: Only change this count if you have intentionally added or removed examples - // from the examples.md file. This check prevents accidental formatting changes from - // causing examples to be skipped during validation. + // expectedExampleCount is the number of JSON examples we expect to find in generic-server-json.md + // IMPORTANT: Only change this count if you have intentionally added or removed examples. This + // check prevents accidental formatting changes from causing examples to be skipped during validation. expectedExampleCount = 12 ) @@ -36,11 +35,10 @@ func main() { } func runValidation() error { - basePath := filepath.Join("docs", "server-json") + basePath := filepath.Join("docs", "reference", "server-json") - examplesPath := filepath.Join(basePath, "examples.md") + examplesPath := filepath.Join(basePath, "generic-server-json.md") schemaPath := filepath.Join(basePath, "server.schema.json") - registrySchemaPath := filepath.Join(basePath, "registry-schema.json") examples, err := extractExamples(examplesPath) if err != nil { @@ -61,17 +59,12 @@ func runValidation() error { return fmt.Errorf("failed to compile server.schema.json: %w", err) } - registrySchema, err := compileSchema(registrySchemaPath) - if err != nil { - return fmt.Errorf("failed to compile registry-schema.json: %w", err) - } - validatedCount := 0 for i, example := range examples { log.Printf("Example %d:", i+1) - if validateExample(example, baseSchema, registrySchema) { + if validateExample(example, baseSchema) { validatedCount++ } @@ -87,7 +80,7 @@ func runValidation() error { return nil } -func validateExample(ex example, baseSchema, registrySchema *jsonschema.Schema) bool { +func validateExample(ex example, baseSchema *jsonschema.Schema) bool { var data any if err := json.Unmarshal([]byte(ex.content), &data); err != nil { log.Printf(" ❌ Invalid JSON: %v", err) @@ -111,11 +104,10 @@ func validateExample(ex example, baseSchema, registrySchema *jsonschema.Schema) } baseValid := validateAgainstSchema(serverData, baseSchema, "server.schema.json") - registryValid := validateAgainstSchema(serverData, registrySchema, "registry-schema.json") goValidatorValid := validateWithObjectValidator(serverData) // Only count as validated if all validations passed - return publishRequestValid && baseValid && registryValid && goValidatorValid + return publishRequestValid && baseValid && goValidatorValid } func validateAgainstSchema(data any, schema *jsonschema.Schema, schemaName string) bool { diff --git a/tools/validate-schemas/main.go b/tools/validate-schemas/main.go index bc7f8b9..ae1e556 100644 --- a/tools/validate-schemas/main.go +++ b/tools/validate-schemas/main.go @@ -25,14 +25,13 @@ func main() { } func runValidation() error { - basePath := filepath.Join("docs", "server-json") + basePath := filepath.Join("docs", "reference", "server-json") schemas := []struct { name string path string }{ {"server.schema.json", filepath.Join(basePath, "server.schema.json")}, - {"registry-schema.json", filepath.Join(basePath, "registry-schema.json")}, } expectedSchemaCount := len(schemas)