Skip to content

Conversation

@BobDickinson
Copy link
Contributor

Motivation and Context

Per discussion with @rdimitrov - all validation now happens in a new /validate endpoint. For details, see below.

Breaking Changes

None. Validation on /publish only validates schema version and semantic checks (manual checks) as before. We can add schema validation by changing a flag in the called to ValidateJSONSchema when we're ready.

Types of changes

  • New feature (non-breaking change which adds functionality)

Checklist

  • I have read the MCP Documentation
  • 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

API Changes

1. New /validate Endpoint

A new public endpoint was added for validating server.json files without publishing them.

Details:

  • Paths: /v0/validate and /v0.1/validate
  • Method: POST
  • Authentication: None required (public endpoint)
  • Request: JSON body containing ServerJSON
  • Response: 200 OK with ValidationResult containing:
    • valid (boolean)
    • issues (array of validation issues with type, path, message, severity, reference)

Implementation:

  • New handler file: internal/api/handlers/v0/validate.go
  • Performs comprehensive validation using ValidationAll option:
    • Schema version validation
    • Full schema validation
    • Semantic validation
  • Always returns 200 OK - validity is indicated in result.Valid field
  • Registered in router for both /v0 and /v0.1 prefixes

2. /publish Endpoint Validation Flow Changes

The publish endpoint now validates earlier in the request flow and provides clearer error responses.

Before: Validation was mixed into ValidatePublishRequest() (which also handled publisher extensions and registry ownership).

After:

  1. Validates ServerJSON structure first using ValidateServerJSON() (schema version + semantic validation)
  2. Returns 422 Unprocessable Entity with message: "Failed to publish server, invalid schema: call /validate for details"
  3. Only proceeds to publisher extensions/registry validation if schema validation passes
  4. No longer calls ValidatePublishRequest() internally for schema validation

Key Changes:

  • Validation happens before CreateServer() call
  • Returns 422 on schema/semantic validation failures
  • Error message directs users to /validate endpoint for details
  • ValidatePublishRequest() no longer performs schema validation (added note in comments)

3. /edit Endpoint Validation Flow Changes

Similar validation changes were applied to the edit endpoint.

Changes:

  • Added ValidateServerJSON() call before server update
  • Returns 422 with same error message format on validation failure
  • Matches the /publish endpoint behavior

4. Validator Functions Refactoring

Updated validator functions to reflect that schema validation is now done separately.

Changes to ValidatePublishRequest():

  • Removed internal ValidateServerJSON() call
  • Added note: "ValidateServerJSON should be called separately before this function"
  • Now only validates publisher extensions and registry ownership

Changes to ValidateUpdateRequest():

  • Same change (removed schema validation, added note)
  • Now only validates registry ownership

CLI Changes

1. validate Command: Now Uses API Endpoint

Before: Performed local validation using validators.ValidateServerJSON().

After: Calls the /v0/validate endpoint on the registry.

Details:

  • Reads server.json and sends it to the registry API
  • Displays validation results returned by the server
  • Uses the same error formatting as before
  • Registry URL comes from token file (or default)
  • No authentication required (public endpoint)

Implementation:

  • Added validateViaAPI() function that POSTs to /v0/validate
  • Parses ValidationResult response from server
  • Uses shared printValidationIssues() for formatting

2. publish Command: Validation Only on 422 Errors

Before: Performed upfront local schema validation before publishing.

After: Attempts publish first, then validates only if server returns 422.

Details:

  • Attempts publish immediately (no upfront validation)
  • If publish returns 422 (Unprocessable Entity):
    • Calls /v0/validate endpoint to get detailed validation errors
    • Formats and displays them using same logic as validate command
    • Returns error with migration links
  • For non-422 errors (401, 403, etc.), returns original error (no validation call)

Implementation Changes:

  • Removed upfront runValidationAndPrintIssues() call
  • Modified publishToRegistry() to return HTTP status code alongside response/error
  • Added 422 detection logic that calls validateViaAPI()

3. Shared Validation Error Formatting

Before: runValidationAndPrintIssues() function handled both validation and printing together.

After: Refactored to separate printing logic.

Details:

  • Created printValidationIssues() function - just prints validation issues (no validation logic)
  • Removed runValidationAndPrintIssues() function (no longer used)
  • Both validate and publish commands use printValidationIssues() for consistent output

Behavior:

  • Prints schema validation errors with migration guidance
  • Prints all other validation issues with formatting
  • Returns formatted error message string for schema issues

Summary

Both CLI commands now use the /validate API endpoint for validation instead of local validation. The publish command validates only after receiving a 422 error response, and both commands share the same error formatting via printValidationIssues().

Benefits

  • Centralized validation logic - All validation happens on the server
  • Always up-to-date - CLI always uses current server validation rules
  • Consistent experience - Same validation behavior whether using CLI or API directly
  • Better separation of concerns - Schema validation separated from publisher-specific validation

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant