Commit 2241040
Changed files (2)
pkg
pkg/git/server.go
@@ -26,8 +26,9 @@ func New(repoPath string) *Server {
repoPath: repoPath,
}
- // Register all git tools
+ // Register all git tools and prompts
gitServer.registerTools()
+ gitServer.registerPrompts()
return gitServer
}
@@ -48,6 +49,33 @@ func (gs *Server) registerTools() {
gs.RegisterTool("git_init", gs.HandleGitInit)
}
+// registerPrompts registers all Git prompts with the server
+func (gs *Server) registerPrompts() {
+ commitPrompt := mcp.Prompt{
+ Name: "commit-message",
+ Description: "Prompt for crafting a well-structured git commit message",
+ Arguments: []mcp.PromptArgument{
+ {
+ Name: "changes",
+ Description: "Description of the changes being committed",
+ Required: true,
+ },
+ {
+ Name: "type",
+ Description: "Type of change (feat, fix, docs, style, refactor, test, chore)",
+ Required: false,
+ },
+ {
+ Name: "breaking",
+ Description: "Whether this is a breaking change (true/false)",
+ Required: false,
+ },
+ },
+ }
+
+ gs.RegisterPrompt(commitPrompt, gs.HandleCommitMessagePrompt)
+}
+
// ListTools returns all available Git tools
func (gs *Server) ListTools() []mcp.Tool {
return []mcp.Tool{
@@ -512,6 +540,102 @@ func (gs *Server) runGitCommand(repoPath string, args ...string) (string, error)
return strings.TrimSpace(string(output)), nil
}
+// Prompt handlers
+
+func (gs *Server) HandleCommitMessagePrompt(req mcp.GetPromptRequest) (mcp.GetPromptResult, error) {
+ changes, hasChanges := req.Arguments["changes"].(string)
+ commitType, hasType := req.Arguments["type"].(string)
+ breaking, hasBreaking := req.Arguments["breaking"]
+
+ if !hasChanges || changes == "" {
+ return mcp.GetPromptResult{}, fmt.Errorf("changes argument is required")
+ }
+
+ // Default type if not provided
+ if !hasType || commitType == "" {
+ commitType = "feat" // Default to feature
+ }
+
+ // Parse breaking change flag
+ isBreaking := false
+ if hasBreaking {
+ if breakingBool, ok := breaking.(bool); ok {
+ isBreaking = breakingBool
+ } else if breakingStr, ok := breaking.(string); ok {
+ isBreaking = breakingStr == "true"
+ }
+ }
+
+ // Create the prompt messages
+ var messages []mcp.PromptMessage
+
+ // User message describing the changes
+ userContent := fmt.Sprintf(`I need help writing a git commit message for the following changes:
+
+%s
+
+Please help me craft a well-structured commit message following conventional commit format.`, changes)
+
+ if hasType {
+ userContent += fmt.Sprintf("\n\nCommit type: %s", commitType)
+ }
+ if isBreaking {
+ userContent += "\n\nThis is a BREAKING CHANGE."
+ }
+
+ messages = append(messages, mcp.PromptMessage{
+ Role: "user",
+ Content: mcp.NewTextContent(userContent),
+ })
+
+ // Assistant message with suggested commit format
+ breakingPrefix := ""
+ if isBreaking {
+ breakingPrefix = "!"
+ }
+
+ assistantContent := fmt.Sprintf(`I'll help you create a conventional commit message. Here's the suggested format:
+
+**Commit message:**
+%s%s: %s
+
+**Format explanation:**
+- Type: %s (indicates the nature of the change)
+- Description: Clear, concise summary in present tense
+%s
+
+**Additional guidelines:**
+- Keep the subject line under 50 characters
+- Use imperative mood ("add" not "added")
+- Don't end subject line with a period
+- Include body if needed to explain what and why`,
+ commitType, breakingPrefix, changes,
+ commitType,
+ func() string {
+ if isBreaking {
+ return "- Breaking change: This change breaks backward compatibility"
+ }
+ return ""
+ }())
+
+ messages = append(messages, mcp.PromptMessage{
+ Role: "assistant",
+ Content: mcp.NewTextContent(assistantContent),
+ })
+
+ description := fmt.Sprintf("Commit message guidance for %s changes", commitType)
+ if isBreaking {
+ description += " (BREAKING)"
+ }
+
+ return mcp.GetPromptResult{
+ Description: description,
+ Messages: messages,
+ }, nil
+}
+
+// Helper methods
+
func (gs *Server) convertToStringSlice(input interface{}) ([]string, error) {
switch v := input.(type) {
case []interface{}:
pkg/git/server_test.go
@@ -22,7 +22,7 @@ func TestGitServer_GitStatus(t *testing.T) {
t.Fatal(err)
}
- server := New()
+ server := New(".")
// Test git status
req := mcp.CallToolRequest{
@@ -64,7 +64,7 @@ func TestGitServer_GitInit(t *testing.T) {
}
defer os.RemoveAll(tempDir)
- server := New()
+ server := New(".")
// Test git init
req := mcp.CallToolRequest{
@@ -119,7 +119,7 @@ func TestGitServer_GitAdd(t *testing.T) {
t.Fatal(err)
}
- server := New()
+ server := New(".")
// Test git add
req := mcp.CallToolRequest{
@@ -151,7 +151,7 @@ func TestGitServer_GitAdd(t *testing.T) {
}
func TestGitServer_ListTools(t *testing.T) {
- server := New()
+ server := New(".")
tools := server.ListTools()
expectedTools := []string{
@@ -179,7 +179,7 @@ func TestGitServer_ListTools(t *testing.T) {
// Helper functions
func initGitRepo(dir string) error {
// Use actual git init command for testing
- server := New()
+ server := New(".")
req := mcp.CallToolRequest{
Name: "git_init",
Arguments: map[string]interface{}{