feat(validators): expose config-free validators as an importable pkg/validators library#1451
Open
itguruhaseeb wants to merge 1 commit into
Open
Conversation
…rary Add a thin pkg/validators facade over the internal validators so external tools can validate a server.json locally without running a full registry. This is phase 1 of modelcontextprotocol#1394: it re-exports only the config-free surface (ValidateServerJSON, the ValidatePackage registries dispatcher, the Validation* result/option types and presets, and the sentinel errors), leaving the config-dependent ValidatePublishRequest/ValidateUpdateRequest and the auth-handler checks in internal/ for follow-up phases. Internal call sites are unaffected. Includes a test covering the public API.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Addresses #1394 (phase 1).
What this does
Adds a thin
pkg/validatorsfacade over the existinginternal/validatorspackage so the config-free validation logic can be imported and used as a library, without running a full registry. This covers the two common cases from the issue:ValidateServerJSON(serverJSON, opts)for schema/semantic validation of aserver.json, plus theValidation*option presets and theValidationResult/ValidationIssuetypes.ValidatePackage(ctx, pkg, serverName), the per-registry ownership dispatcher (npm / PyPI / NuGet / OCI / MCPB / Cargo) that already lives ininternal/validators/package.go.This lets tools such as a private sub-registry, or a preflight check that runs in CI before a release tag is cut, validate locally instead of calling a deployed
/validateendpoint.The re-exported sentinel errors (e.g.
ErrVersionLooksLikeRange) are aliases of the internal values, so consumers can useerrors.Israther than matching on error strings.Scope (phase 1 only)
Per the issue and the discussion, this intentionally exposes only the config-free surface. It uses a thin re-export facade to keep the diff small and leave all internal call sites compiling unchanged:
pkg/validators/validators.go: the facade (doc-commented package + re-exports).pkg/validators/validators_test.go: a test that importspkg/validatorsand validates a known-good and a known-badserver.jsonthrough the public API.No existing files are modified.
Deferred to follow-up phases (noted for reviewers, not done here):
ValidatePublishRequest/ValidateUpdateRequesttake a*config.Configand gate onEnableRegistryValidation, so they need a config-decoupling design before they can live inpkg/.github_oidc.go) and would be a broader refactor, as the issue notes.On typed outcomes
@sronix raised a good point in the thread about library consumers wanting typed outcomes (package missing vs ownership mismatch vs transient upstream error) rather than matching on error strings. This PR takes a first step by re-exporting the sentinel errors for
errors.Is, but the per-registry validators still largely return formatted strings. Happy to iterate on a richer typed-error surface in this PR or a follow-up if maintainers prefer that direction. I didn't want to expand the blast radius here.Verification
Run with Go 1.26 on darwin/arm64:
go build ./...: passesgo vet ./...: cleangofmt -l pkg/validators/: no diffsgo test ./pkg/validators/... ./internal/validators/...: passesThe DB-backed test packages (
internal/database,internal/service, etc.) were not run in my environment because they require a local PostgreSQL/Docker; this change doesn't touch them.Happy to adjust naming, scope, or the exported surface to match maintainer preferences.