Replace / with - for operation IDs (#660)

<!-- Provide a brief summary of your changes -->

## Motivation and Context
<!-- Why is this change needed? What problem does it solve? -->
Follow up from #658 addressing the feedback from @tadasant 

## 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)
- [ ] New feature (non-breaking change which adds functionality)
- [ ] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Documentation update

## Checklist
<!-- Go over all the following points, and put an `x` in all the boxes
that apply. -->
- [ ] I have read the [MCP
Documentation](https://modelcontextprotocol.io)
- [ ] My code follows the repository's style guidelines
- [ ] New and existing tests pass locally
- [ ] I have added appropriate error handling
- [ ] I have added or updated documentation as needed

## Additional context
<!-- Add any other context, implementation notes, or design decisions
-->

Signed-off-by: Radoslav Dimitrov <radoslav@stacklok.com>
This commit is contained in:
Radoslav Dimitrov 2025-10-14 15:26:43 +03:00 • committed by GitHub
commit 087d8085b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 22 additions and 14 deletions

View file

@ -9,10 +9,11 @@ Integration patterns and best practices for building applications that consume M
**Authentication**: Not required for read-only access
**API Versions**:
- `/v0/` - Development version with latest features (may receive additive changes)
- `/v0/` - Development version with latest features (may receive breaking changes)
- `/v0.1/` - Stable version (only backward-compatible changes)
**Recommendation**: Use `/v0.1/` for production applications requiring API stability. Both versions currently have identical functionality.
We may add breaking changes _only_ to `/v0/` in the future, and we reserve the possibility of deprecating `/v0/` entirely.
**Core endpoints:**
- **`GET /v0.1/servers`** - List all servers with pagination

View file

@ -5,6 +5,7 @@ import (
"fmt"
"net"
"net/http"
"strings"
"github.com/danielgtaylor/huma/v2"
v0 "github.com/modelcontextprotocol/registry/internal/api/handlers/v0"
@ -55,7 +56,7 @@ func RegisterDNSEndpoint(api huma.API, pathPrefix string, cfg *config.Config) {
// DNS authentication endpoint
huma.Register(api, huma.Operation{
OperationID: "exchange-dns-token" + pathPrefix,
OperationID: "exchange-dns-token" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodPost,
Path: pathPrefix + "/auth/dns",
Summary: "Exchange DNS signature for Registry JWT",

View file

@ -7,6 +7,7 @@ import (
"io"
"net/http"
"regexp"
"strings"
"github.com/danielgtaylor/huma/v2"
v0 "github.com/modelcontextprotocol/registry/internal/api/handlers/v0"
@ -48,7 +49,7 @@ func RegisterGitHubATEndpoint(api huma.API, pathPrefix string, cfg *config.Confi
// GitHub token exchange endpoint
huma.Register(api, huma.Operation{
OperationID: "exchange-github-token" + pathPrefix,
OperationID: "exchange-github-token" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodPost,
Path: pathPrefix + "/auth/github-at",
Summary: "Exchange GitHub OAuth access token for Registry JWT",

View file

@ -9,6 +9,7 @@ import (
"io"
"math/big"
"net/http"
"strings"
"github.com/danielgtaylor/huma/v2"
"github.com/golang-jwt/jwt/v5"
@ -231,7 +232,7 @@ func RegisterGitHubOIDCEndpoint(api huma.API, pathPrefix string, cfg *config.Con
// GitHub OIDC token exchange endpoint
huma.Register(api, huma.Operation{
OperationID: "exchange-github-oidc-token" + pathPrefix,
OperationID: "exchange-github-oidc-token" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodPost,
Path: pathPrefix + "/auth/github-oidc",
Summary: "Exchange GitHub OIDC token for Registry JWT",

View file

@ -113,7 +113,7 @@ func RegisterHTTPEndpoint(api huma.API, pathPrefix string, cfg *config.Config) {
// HTTP authentication endpoint
huma.Register(api, huma.Operation{
OperationID: "exchange-http-token" + pathPrefix,
OperationID: "exchange-http-token" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodPost,
Path: pathPrefix + "/auth/http",
Summary: "Exchange HTTP signature for Registry JWT",

View file

@ -4,6 +4,7 @@ import (
"context"
"fmt"
"net/http"
"strings"
"github.com/danielgtaylor/huma/v2"
v0 "github.com/modelcontextprotocol/registry/internal/api/handlers/v0"
@ -37,7 +38,7 @@ func RegisterNoneEndpoint(api huma.API, pathPrefix string, cfg *config.Config) {
// Anonymous token endpoint for development/testing only
huma.Register(api, huma.Operation{
OperationID: "get-anonymous-token",
OperationID: "get-anonymous-token" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodPost,
Path: pathPrefix + "/auth/none",
Summary: "Get anonymous Registry JWT (Development/Testing Only)",

View file

@ -154,7 +154,7 @@ func RegisterOIDCEndpoints(api huma.API, pathPrefix string, cfg *config.Config)
// Direct token exchange endpoint
huma.Register(api, huma.Operation{
OperationID: "exchange-oidc-token" + pathPrefix,
OperationID: "exchange-oidc-token" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodPost,
Path: pathPrefix + "/auth/oidc",
Summary: "Exchange OIDC ID token for Registry JWT",

View file

@ -31,7 +31,7 @@ func RegisterEditEndpoints(api huma.API, pathPrefix string, registry service.Reg
// Edit server endpoint
huma.Register(api, huma.Operation{
OperationID: "edit-server" + pathPrefix,
OperationID: "edit-server" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodPut,
Path: pathPrefix + "/servers/{serverName}/versions/{version}",
Summary: "Edit MCP server",

View file

@ -3,6 +3,7 @@ package v0
import (
"context"
"net/http"
"strings"
"github.com/danielgtaylor/huma/v2"
"go.opentelemetry.io/otel/attribute"
@ -21,7 +22,7 @@ type HealthBody struct {
// RegisterHealthEndpoint registers the health check endpoint with a custom path prefix
func RegisterHealthEndpoint(api huma.API, pathPrefix string, cfg *config.Config, metrics *telemetry.Metrics) {
huma.Register(api, huma.Operation{
OperationID: "get-health" + pathPrefix,
OperationID: "get-health" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodGet,
Path: pathPrefix + "/health",
Summary: "Health check",

View file

@ -3,6 +3,7 @@ package v0
import (
"context"
"net/http"
"strings"
"github.com/danielgtaylor/huma/v2"
)
@ -15,7 +16,7 @@ type PingBody struct {
// RegisterPingEndpoint registers the ping endpoint with a custom path prefix
func RegisterPingEndpoint(api huma.API, pathPrefix string) {
huma.Register(api, huma.Operation{
OperationID: "ping" + pathPrefix,
OperationID: "ping" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodGet,
Path: pathPrefix + "/ping",
Summary: "Ping",

View file

@ -24,7 +24,7 @@ func RegisterPublishEndpoint(api huma.API, pathPrefix string, registry service.R
jwtManager := auth.NewJWTManager(cfg)
huma.Register(api, huma.Operation{
OperationID: "publish-server" + pathPrefix,
OperationID: "publish-server" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodPost,
Path: pathPrefix + "/publish",
Summary: "Publish MCP server",

View file

@ -5,6 +5,7 @@ import (
"errors"
"net/http"
"net/url"
"strings"
"time"
"github.com/danielgtaylor/huma/v2"
@ -44,7 +45,7 @@ type ServerVersionsInput struct {
func RegisterServersEndpoints(api huma.API, pathPrefix string, registry service.RegistryService) {
// List servers endpoint
huma.Register(api, huma.Operation{
OperationID: "list-servers" + pathPrefix,
OperationID: "list-servers" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodGet,
Path: pathPrefix + "/servers",
Summary: "List MCP servers",
@ -106,7 +107,7 @@ func RegisterServersEndpoints(api huma.API, pathPrefix string, registry service.
// Get specific server version endpoint (supports "latest" as special version)
huma.Register(api, huma.Operation{
OperationID: "get-server-version" + pathPrefix,
OperationID: "get-server-version" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodGet,
Path: pathPrefix + "/servers/{serverName}/versions/{version}",
Summary: "Get specific MCP server version",
@ -147,7 +148,7 @@ func RegisterServersEndpoints(api huma.API, pathPrefix string, registry service.
// Get server versions endpoint
huma.Register(api, huma.Operation{
OperationID: "get-server-versions" + pathPrefix,
OperationID: "get-server-versions" + strings.ReplaceAll(pathPrefix, "/", "-"),
Method: http.MethodGet,
Path: pathPrefix + "/servers/{serverName}/versions",
Summary: "Get all versions of an MCP server",