fix(publisher): honor mcpName as the authoritative server name in init (#1195)
## Summary Follow-up to #1145. When `mcpName` is set in `package.json`, it should be the server name used by `mcp-publisher init`. Two issues addressed: ### 1. `getNameFromPackageJSON` mangled `mcpName` through npm-name transformation `mcpName` values are already in MCP server name format (e.g. `io.github.foo/bar`). The existing code ran them through the `@scope/name → io.github.scope/name` transform and its `io.github.<your-username>/*` fallback, producing a broken double-prefix result. Example with `"mcpName": "io.github.acme/weather"`: - Before: `io.github.<your-username>/io.github.acme/weather` ❌ - After: `io.github.acme/weather` ✅ ### 2. `detectServerName` consulted git before `mcpName` Even with `mcpName` set in `package.json`, a github.com git remote (or a `repository` field) silently won — the function returned `io.github.<owner>/<repo>` and never looked at `mcpName`. Per the [quickstart docs](https://github.com/modelcontextprotocol/registry/blob/main/docs/modelcontextprotocol-io/quickstart.mdx), *"The value of `mcpName` will be your server's name in the MCP Registry"*, so `mcpName` should take precedence. ## Changes - `cmd/publisher/commands/init.go`: - New `getMcpNameFromPackageJSON()` helper that returns `mcpName` or `""`. - `detectServerName` checks `mcpName` first, before git remote and the `name`-based fallback. - `getNameFromPackageJSON` simplified — the now-redundant `mcpName` branch was removed; it only handles the npm `name` transformation. - `cmd/publisher/commands/init_test.go` (new): 5 cases through the public `InitCommand` API covering `mcpName` as-is, fallback to scoped `name`, fallback to placeholder, version fallback, and `mcpName` winning over a GitHub `repository` URL. This completes the fix for #737. ## Test plan - [x] `go test ./cmd/publisher/commands/` passes (5 new subtests) - [x] `golangci-lint run ./cmd/publisher/commands/` clean - [ ] Manual: `mcp-publisher init` in a git-tracked directory with `package.json` containing `mcpName` produces a `server.json` whose `name` matches `mcpName`, not the repo slug 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
7c446e75ad
commit
aaa634ebb6
1 changed files with 122 additions and 7 deletions
|
|
@ -132,6 +132,26 @@ func detectSubfolder() string {
|
|||
return filepath.ToSlash(relPath)
|
||||
}
|
||||
|
||||
// getMcpNameFromPackageJSON returns the `mcpName` field from package.json, or
|
||||
// "" if not set. mcpName is the authoritative MCP server name when present —
|
||||
// see docs/modelcontextprotocol-io/quickstart.mdx.
|
||||
func getMcpNameFromPackageJSON() string {
|
||||
data, err := os.ReadFile("package.json")
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
var pkg map[string]any
|
||||
if err := json.Unmarshal(data, &pkg); err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
if mcpName, ok := pkg["mcpName"].(string); ok && mcpName != "" {
|
||||
return mcpName
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getNameFromPackageJSON() string {
|
||||
data, err := os.ReadFile("package.json")
|
||||
if err != nil {
|
||||
|
|
@ -143,17 +163,13 @@ func getNameFromPackageJSON() string {
|
|||
return ""
|
||||
}
|
||||
|
||||
// Prefer mcpName over name, as the server name must match mcpName
|
||||
name, ok := pkg["mcpName"].(string)
|
||||
name, ok := pkg["name"].(string)
|
||||
if !ok || name == "" {
|
||||
name, ok = pkg["name"].(string)
|
||||
if !ok || name == "" {
|
||||
return ""
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// Convert npm package name to MCP server name
|
||||
// @org/package -> io.npm.org/package
|
||||
// @org/package -> io.github.org/package
|
||||
if strings.HasPrefix(name, "@") {
|
||||
parts := strings.Split(name[1:], "/")
|
||||
if len(parts) == 2 {
|
||||
|
|
@ -183,6 +199,13 @@ func getVersionFromPackageJSON() string {
|
|||
}
|
||||
|
||||
func detectServerName(subfolder string) string {
|
||||
// mcpName in package.json is the authoritative server name when set, so it
|
||||
// takes precedence over names inferred from the git remote or the npm
|
||||
// `name` field.
|
||||
if name := getMcpNameFromPackageJSON(); name != "" {
|
||||
return name
|
||||
}
|
||||
|
||||
// Try to get from git remote
|
||||
repoURL := detectRepoURL()
|
||||
if repoURL != "" && strings.Contains(repoURL, "github.com") {
|
||||
|
|
|
|||
Loading…
Reference in a new issue