fix: detect server subfolder in init (#566)
<!-- Provide a brief summary of your changes --> ## Motivation and Context Discussion from this issue: https://github.com/modelcontextprotocol/registry/issues/538 We want to make it clearer that repo name & server name do not HAVE to be the same, especially in monorepos. @tadasant this seems like a minor thing that doesn't have to be documented specifically, lmk if you disagree :) ## How Has This Been Tested? Tested the init flow locally, running the built `init` command from a subfolder and the repo root. ## Breaking Changes No ## 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) - [x] 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. --> - [x] I have read the [MCP Documentation](https://modelcontextprotocol.io) - [x] My code follows the repository's style guidelines - [x] New and existing tests pass locally - [x] I have added appropriate error handling - [x] I have added or updated documentation as needed ## Additional context <!-- Add any other context, implementation notes, or design decisions -->
This commit is contained in:
parent
73d2174cec
commit
ce2171d207
1 changed files with 87 additions and 19 deletions
|
|
@ -21,8 +21,11 @@ func InitCommand() error {
|
|||
return errors.New("server.json already exists")
|
||||
}
|
||||
|
||||
// Detect if we're in a subdirectory of the git repository
|
||||
subfolder := detectSubfolder()
|
||||
|
||||
// Try to detect values from environment
|
||||
name := detectServerName()
|
||||
name := detectServerName(subfolder)
|
||||
description := detectDescription()
|
||||
version := "1.0.0"
|
||||
repoURL := detectRepoURL()
|
||||
|
|
@ -55,7 +58,7 @@ func InitCommand() error {
|
|||
|
||||
// Create the server structure
|
||||
server := createServerJSON(
|
||||
name, description, version, repoURL, repoSource,
|
||||
name, description, version, repoURL, repoSource, subfolder,
|
||||
packageType, packageIdentifier, version, envVars,
|
||||
)
|
||||
|
||||
|
|
@ -82,6 +85,50 @@ func InitCommand() error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func detectSubfolder() string {
|
||||
// Get current working directory
|
||||
cwd, err := os.Getwd()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Find git repository root
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
|
||||
defer cancel()
|
||||
cmd := exec.CommandContext(ctx, "git", "rev-parse", "--show-toplevel")
|
||||
cmd.Dir = cwd
|
||||
output, err := cmd.Output()
|
||||
if err != nil {
|
||||
// Not in a git repository
|
||||
return ""
|
||||
}
|
||||
|
||||
gitRoot := strings.TrimSpace(string(output))
|
||||
|
||||
// Clean the paths to ensure proper comparison
|
||||
gitRoot = filepath.Clean(gitRoot)
|
||||
cwd = filepath.Clean(cwd)
|
||||
|
||||
// If we're in the root, no subfolder
|
||||
if gitRoot == cwd {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Check if cwd is actually within gitRoot
|
||||
if !strings.HasPrefix(cwd, gitRoot) {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Calculate relative path from git root to current directory
|
||||
relPath, err := filepath.Rel(gitRoot, cwd)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Convert to forward slashes for consistency (important for cross-platform)
|
||||
return filepath.ToSlash(relPath)
|
||||
}
|
||||
|
||||
func getNameFromPackageJSON() string {
|
||||
data, err := os.ReadFile("package.json")
|
||||
if err != nil {
|
||||
|
|
@ -109,18 +156,13 @@ func getNameFromPackageJSON() string {
|
|||
return fmt.Sprintf("io.github.<your-username>/%s", name)
|
||||
}
|
||||
|
||||
func detectServerName() string {
|
||||
func detectServerName(subfolder string) string {
|
||||
// Try to get from git remote
|
||||
repoURL := detectRepoURL()
|
||||
if repoURL != "" {
|
||||
// Extract owner/repo from GitHub URL
|
||||
if strings.Contains(repoURL, "github.com") {
|
||||
parts := strings.Split(repoURL, "/")
|
||||
if len(parts) >= 5 {
|
||||
owner := parts[3]
|
||||
repo := strings.TrimSuffix(parts[4], ".git")
|
||||
return fmt.Sprintf("io.github.%s/%s", owner, repo)
|
||||
}
|
||||
if repoURL != "" && strings.Contains(repoURL, "github.com") {
|
||||
name := buildGitHubServerName(repoURL, subfolder)
|
||||
if name != "" {
|
||||
return name
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -138,6 +180,24 @@ func detectServerName() string {
|
|||
return "com.example/my-mcp-server"
|
||||
}
|
||||
|
||||
func buildGitHubServerName(repoURL, subfolder string) string {
|
||||
parts := strings.Split(repoURL, "/")
|
||||
if len(parts) < 5 {
|
||||
return ""
|
||||
}
|
||||
|
||||
owner := parts[3]
|
||||
repo := strings.TrimSuffix(parts[4], ".git")
|
||||
|
||||
// If we're in a subdirectory, use the current folder name
|
||||
if subfolder != "" {
|
||||
folderName := filepath.Base(subfolder)
|
||||
return fmt.Sprintf("io.github.%s/%s", owner, folderName)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("io.github.%s/%s", owner, repo)
|
||||
}
|
||||
|
||||
func detectDescription() string {
|
||||
// Try to get from package.json
|
||||
if data, err := os.ReadFile("package.json"); err == nil {
|
||||
|
|
@ -263,7 +323,7 @@ func detectPackageIdentifier(serverName string, packageType string) string {
|
|||
}
|
||||
|
||||
func createServerJSON(
|
||||
name, description, version, repoURL, repoSource,
|
||||
name, description, version, repoURL, repoSource, subfolder,
|
||||
packageType, packageIdentifier, packageVersion string,
|
||||
envVars []model.KeyValueInput,
|
||||
) apiv0.ServerJSON {
|
||||
|
|
@ -326,16 +386,24 @@ func createServerJSON(
|
|||
}
|
||||
}
|
||||
|
||||
// Create repository with optional subfolder
|
||||
repo := model.Repository{
|
||||
URL: repoURL,
|
||||
Source: repoSource,
|
||||
}
|
||||
|
||||
// Only set subfolder if we're actually in a subdirectory
|
||||
if subfolder != "" {
|
||||
repo.Subfolder = subfolder
|
||||
}
|
||||
|
||||
// Create server structure
|
||||
return apiv0.ServerJSON{
|
||||
Schema: model.CurrentSchemaURL,
|
||||
Name: name,
|
||||
Description: description,
|
||||
Repository: model.Repository{
|
||||
URL: repoURL,
|
||||
Source: repoSource,
|
||||
},
|
||||
Version: version,
|
||||
Packages: []model.Package{pkg},
|
||||
Repository: repo,
|
||||
Version: version,
|
||||
Packages: []model.Package{pkg},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue