Skip to content
Merged
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 89 additions & 19 deletions cmd/publisher/commands/init.go
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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,
)

Expand All @@ -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 {
Expand Down Expand Up @@ -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
}
}

Expand All @@ -138,6 +180,26 @@ 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 != "" {
if cwd, err := os.Getwd(); err == nil {
folderName := filepath.Base(cwd)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It seems we use subfolder as a boolean even though it's a string. Wouldn't it be better to reuse the subfolder variable we already have?

For example if it's != "" construct the path using it (and avoid reading the base path again), otherwise proceed as if we are in the root repo.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you're completely right, I pushed a fix

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 {
Expand Down Expand Up @@ -263,7 +325,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 {
Expand Down Expand Up @@ -299,16 +361,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