Skip to content

feat: support Go modules as a package type - #1321

Open
koriyoshi2041 wants to merge 2 commits into
modelcontextprotocol:mainfrom
koriyoshi2041:feat/go-package-type
Open

koriyoshi2041 wants to merge 2 commits into
modelcontextprotocol:mainfrom
koriyoshi2041:feat/go-package-type

Conversation

@koriyoshi2041

Copy link
Copy Markdown

Closes #1307.

Adds "registryType": "go" so MCP servers distributed as go install-able modules can be published to the registry. Design discussed in #1307.

Ownership reuses the publisher's GitHub namespace rather than inventing an mcpName-style marker (which wouldn't be idiomatic in a go.mod). A Go module path is its source location, so a server published under io.github.<owner> must use a module path rooted at github.com/<owner>/.... The owner is compared case-insensitively (GitHub owners are case-insensitive). Since the publisher already authenticates for the io.github.<owner> namespace, matching the module owner proves ownership. Non-GitHub module paths are intentionally left for a follow-up (a sentinel-file/go.mod-directive check can be added later without changing this).

Existence is verified against the Go module proxy (https://proxy.golang.org) — the canonical source of truth, with no auth/rate-limit concerns. The module path and version are case-encoded per the goproxy protocol (uppercase → !+lowercase), and ./.. path elements are rejected so a crafted identifier can't escape the proxy path.

Changes

  • pkg/model/constants.go: RegistryTypeGo + RegistryURLGoProxy.
  • internal/validators/package.go: dispatch go to ValidateGo.
  • internal/validators/registries/go.go: ValidateGo + ValidateGoModuleOwnership + module-proxy existence check + EscapeGoModulePath.
  • internal/validators/registries/go_test.go: ownership matrix (incl. case-insensitivity and mismatch), path-escaping/traversal, and ValidateGo guard errors — all deterministic, no network.
  • docs/.../package-types.mdx: Go section.

Example

{
  "registryType": "go",
  "identifier": "github.com/username/audit-mcp",
  "version": "v1.0.0"
}

go test ./internal/validators/... passes; gofmt/go vet clean. The existence path is exercised against the live proxy on a real publish; the unit tests cover the ownership and escaping logic without network. Happy to adjust the identifier semantics (module path vs. go install sub-path) if you'd prefer a different convention.

@P4ST4S

This comment was marked as spam.

@koriyoshi2041

Copy link
Copy Markdown
Author

Thanks for the careful read — really appreciate the detailed notes.

I pushed two of these:

  1. HTTP path coverage — added TestValidateGoModuleExists, an httptest.Server-backed test covering 200/404/410/500 and asserting the case-encoded proxy request path (!alice etc.). To make it testable from the external _test package without hitting the real proxy I exported validateGoModuleExists → ValidateGoModuleExists. So the case 503: return nil-style regression you mentioned would now fail the suite.

  2. Timeout — lifted to a package-level goProxyRequestTimeout const.

On (1), golang.org/x/mod/module.EscapePath: I went with the inline encoder deliberately to keep this from pulling x/mod into the API server for a single function, and the ./.. + control-char guards cover the path-injection surface that matters here. You're right that CheckPath's extra validation (Windows reserved names, /vN suffix structure) isn't replicated — but that's belt-and-suspenders on top of the proxy itself rejecting bad paths. If maintainers would rather lean on x/mod for the future-proofing, I'm happy to swap it; just didn't want to add the dep unilaterally.

Pushed in 30310e7.

@P4ST4S

This comment was marked as spam.

Wolfe-Jam pushed a commit to Wolfe-Jam/registry that referenced this pull request Jun 2, 2026
@koriyoshi2041
koriyoshi2041 force-pushed the feat/go-package-type branch from 30310e7 to 7a81964 Compare June 3, 2026 09:35
Adds "registryType": "go" so MCP servers distributed as go-install-able
modules can be published. Ownership reuses the publisher's GitHub namespace:
a server under io.github.<owner> must use a module path rooted at
github.com/<owner>/... (compared case-insensitively, since GitHub owners are
case-insensitive). Existence is verified against the Go module proxy
(proxy.golang.org). Non-GitHub module paths are left for a follow-up.

Closes modelcontextprotocol#1307
Add an httptest-backed test for ValidateGoModuleExists covering 200/404/410/500
responses and asserting the case-encoded proxy request path. Exporting the
function makes it testable from the external test package without hitting the
real proxy. Also lift the hardcoded 10s client timeout to a package const.
@koriyoshi2041
koriyoshi2041 force-pushed the feat/go-package-type branch from 7a81964 to 33e2e12 Compare June 4, 2026 05:40

This branch has not been deployed

No deployments
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.

Support for Go modules (go install) as a package type

2 participants