package tools
import (
"context"
"fmt"
"strings"
"github.com/modelcontextprotocol/go-sdk/mcp"
"github.com/sirupsen/logrus"
k8scontext "mcp-k8swizard/internal/context"
"mcp-k8swizard/internal/prompts"
)
// PromptTools handles prompt-related operations
type PromptTools struct {
contextManager *k8scontext.Manager
}
// NewPromptTools creates a new PromptTools instance
func NewPromptTools(contextManager *k8scontext.Manager) *PromptTools {
return &PromptTools{
contextManager: contextManager,
}
}
// PromptArgs represents arguments for prompt tools
type PromptArgs struct {
Keyword string `json:"keyword"`
Namespace string `json:"namespace"`
Context string `json:"context"`
}
// HandleK8sDiagnose handles the /k8s-diagnose prompt
func (pt *PromptTools) HandleK8sDiagnose(ctx context.Context, req *mcp.CallToolRequest, args PromptArgs) (*mcp.CallToolResult, any, error) {
logrus.WithFields(logrus.Fields{
"tool": "k8s_diagnose",
"args": args,
}).Info("Handling K8s diagnose prompt")
// Set defaults
keyword := args.Keyword
namespace := args.Namespace
if namespace == "" {
namespace = "default"
}
if keyword == "" {
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: "❌ Error: Please provide a keyword to identify the pods you want to diagnose.\n\nUsage: /k8s-diagnose <keyword> [namespace]\n\nExample: /k8s-diagnose nginx production"},
},
}, nil, nil
}
// Get the diagnostic prompt
prompt := prompts.GetDiagnosticPrompt(prompts.PromptTypeDiagnose, keyword, namespace)
// Format the prompt with current context information
formattedPrompt := pt.enhancePromptWithContext(prompt, keyword, namespace)
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: formattedPrompt},
},
}, formattedPrompt, nil
}
// HandleK8sTroubleshoot handles the /k8s-troubleshoot prompt
func (pt *PromptTools) HandleK8sTroubleshoot(ctx context.Context, req *mcp.CallToolRequest, args PromptArgs) (*mcp.CallToolResult, any, error) {
logrus.WithFields(logrus.Fields{
"tool": "k8s_troubleshoot",
"args": args,
}).Info("Handling K8s troubleshoot prompt")
// Set defaults
keyword := args.Keyword
namespace := args.Namespace
if namespace == "" {
namespace = "default"
}
if keyword == "" {
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: "❌ Error: Please provide a keyword to identify the resources you want to troubleshoot.\n\nUsage: /k8s-troubleshoot <keyword> [namespace]\n\nExample: /k8s-troubleshoot api-server kube-system"},
},
}, nil, nil
}
// Get the troubleshoot prompt
prompt := prompts.GetDiagnosticPrompt(prompts.PromptTypeTroubleshoot, keyword, namespace)
// Format the prompt with current context information
formattedPrompt := pt.enhancePromptWithContext(prompt, keyword, namespace)
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: formattedPrompt},
},
}, formattedPrompt, nil
}
// HandleK8sOptimize handles the /k8s-optimize prompt
func (pt *PromptTools) HandleK8sOptimize(ctx context.Context, req *mcp.CallToolRequest, args PromptArgs) (*mcp.CallToolResult, any, error) {
logrus.WithFields(logrus.Fields{
"tool": "k8s_optimize",
"args": args,
}).Info("Handling K8s optimize prompt")
// Set defaults
keyword := args.Keyword
namespace := args.Namespace
if namespace == "" {
namespace = "default"
}
if keyword == "" {
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: "❌ Error: Please provide a keyword to identify the resources you want to optimize.\n\nUsage: /k8s-optimize <keyword> [namespace]\n\nExample: /k8s-optimize web-app production"},
},
}, nil, nil
}
// Get the optimize prompt
prompt := prompts.GetDiagnosticPrompt(prompts.PromptTypeOptimize, keyword, namespace)
// Format the prompt with current context information
formattedPrompt := pt.enhancePromptWithContext(prompt, keyword, namespace)
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: formattedPrompt},
},
}, formattedPrompt, nil
}
// HandleK8sSecurity handles the /k8s-security prompt
func (pt *PromptTools) HandleK8sSecurity(ctx context.Context, req *mcp.CallToolRequest, args PromptArgs) (*mcp.CallToolResult, any, error) {
logrus.WithFields(logrus.Fields{
"tool": "k8s_security",
"args": args,
}).Info("Handling K8s security prompt")
// Set defaults
keyword := args.Keyword
namespace := args.Namespace
if namespace == "" {
namespace = "default"
}
if keyword == "" {
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: "❌ Error: Please provide a keyword to identify the resources you want to analyze for security.\n\nUsage: /k8s-security <keyword> [namespace]\n\nExample: /k8s-security api-server kube-system"},
},
}, nil, nil
}
// Get the security prompt
prompt := prompts.GetDiagnosticPrompt(prompts.PromptTypeSecurity, keyword, namespace)
// Format the prompt with current context information
formattedPrompt := pt.enhancePromptWithContext(prompt, keyword, namespace)
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: formattedPrompt},
},
}, formattedPrompt, nil
}
// HandleK8sPerformance handles the /k8s-performance prompt
func (pt *PromptTools) HandleK8sPerformance(ctx context.Context, req *mcp.CallToolRequest, args PromptArgs) (*mcp.CallToolResult, any, error) {
logrus.WithFields(logrus.Fields{
"tool": "k8s_performance",
"args": args,
}).Info("Handling K8s performance prompt")
// Set defaults
keyword := args.Keyword
namespace := args.Namespace
if namespace == "" {
namespace = "default"
}
if keyword == "" {
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: "❌ Error: Please provide a keyword to identify the resources you want to monitor for performance.\n\nUsage: /k8s-performance <keyword> [namespace]\n\nExample: /k8s-performance web-app production"},
},
}, nil, nil
}
// Get the performance prompt
prompt := prompts.GetDiagnosticPrompt(prompts.PromptTypePerformance, keyword, namespace)
// Format the prompt with current context information
formattedPrompt := pt.enhancePromptWithContext(prompt, keyword, namespace)
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: formattedPrompt},
},
}, formattedPrompt, nil
}
// HandleK8sDeployment handles the /k8s-deployment prompt
func (pt *PromptTools) HandleK8sDeployment(ctx context.Context, req *mcp.CallToolRequest, args PromptArgs) (*mcp.CallToolResult, any, error) {
logrus.WithFields(logrus.Fields{
"tool": "k8s_deployment",
"args": args,
}).Info("Handling K8s deployment prompt")
// Set defaults
keyword := args.Keyword
namespace := args.Namespace
if namespace == "" {
namespace = "default"
}
if keyword == "" {
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: "❌ Error: Please provide a keyword to identify the deployment you want to analyze.\n\nUsage: /k8s-deployment <keyword> [namespace]\n\nExample: /k8s-deployment web-app production"},
},
}, nil, nil
}
// Get the deployment prompt
prompt := prompts.GetDiagnosticPrompt(prompts.PromptTypeDeployment, keyword, namespace)
// Format the prompt with current context information
formattedPrompt := pt.enhancePromptWithContext(prompt, keyword, namespace)
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: formattedPrompt},
},
}, formattedPrompt, nil
}
// HandlePromptSuggestions handles prompt suggestions based on context
func (pt *PromptTools) HandlePromptSuggestions(ctx context.Context, req *mcp.CallToolRequest, args PromptArgs) (*mcp.CallToolResult, any, error) {
logrus.WithFields(logrus.Fields{
"tool": "prompt_suggestions",
"args": args,
}).Info("Handling prompt suggestions")
// Get context from arguments
context := args.Context
// Get suggestions based on context
suggestions := prompts.GetPromptSuggestions(context)
var output strings.Builder
output.WriteString("# 🎯 MCP-K8sWizard Prompt Suggestions\n\n")
output.WriteString("Based on your context, here are the most relevant prompts:\n\n")
for _, suggestion := range suggestions {
output.WriteString(fmt.Sprintf("- %s\n", suggestion))
}
output.WriteString("\n## 📚 All Available Prompts\n\n")
output.WriteString("| Prompt | Description | Usage |\n")
output.WriteString("|--------|-------------|-------|\n")
output.WriteString("| `/k8s-diagnose` | Systematic pod troubleshooting | `/k8s-diagnose <keyword> [namespace]` |\n")
output.WriteString("| `/k8s-troubleshoot` | Advanced debugging | `/k8s-troubleshoot <keyword> [namespace]` |\n")
output.WriteString("| `/k8s-optimize` | Performance optimization | `/k8s-optimize <keyword> [namespace]` |\n")
output.WriteString("| `/k8s-security` | Security analysis | `/k8s-security <keyword> [namespace]` |\n")
output.WriteString("| `/k8s-performance` | Performance monitoring | `/k8s-performance <keyword> [namespace]` |\n")
output.WriteString("| `/k8s-deployment` | Deployment analysis | `/k8s-deployment <keyword> [namespace]` |\n")
output.WriteString("\n## 💡 Tips\n")
output.WriteString("- Use specific keywords (e.g., `nginx`, `api-server`, `web-app`)\n")
output.WriteString("- Specify namespace if not using `default`\n")
output.WriteString("- Combine prompts for comprehensive analysis\n")
output.WriteString("- Use natural language queries for general guidance\n")
formattedOutput := output.String()
return &mcp.CallToolResult{
Content: []mcp.Content{
&mcp.TextContent{Text: formattedOutput},
},
}, formattedOutput, nil
}
// enhancePromptWithContext enhances a prompt with current cluster context
func (pt *PromptTools) enhancePromptWithContext(prompt *prompts.DiagnosticPrompt, keyword, namespace string) string {
var output strings.Builder
// Add header with context information
output.WriteString(fmt.Sprintf("# %s\n\n", prompt.Title))
output.WriteString(fmt.Sprintf("**Target:** `%s` in namespace `%s`\n\n", keyword, namespace))
output.WriteString(fmt.Sprintf("**Description:** %s\n\n", prompt.Description))
// Add current context information
currentContext := pt.contextManager.GetCurrentContext()
if currentContext != "" {
output.WriteString(fmt.Sprintf("**Current K8s Context:** `%s`\n\n", currentContext))
}
// Add available tools
output.WriteString("## 🛠️ Available Tools\n")
for _, tool := range prompt.Tools {
output.WriteString(fmt.Sprintf("- `%s`\n", tool))
}
output.WriteString("\n")
// Add diagnostic steps
output.WriteString("## 📋 Diagnostic Steps\n\n")
for _, step := range prompt.Steps {
output.WriteString(fmt.Sprintf("### Step %d: %s\n", step.Number, step.Title))
output.WriteString(fmt.Sprintf("**Description:** %s\n\n", step.Description))
output.WriteString(fmt.Sprintf("**Command:**\n```bash\n%s\n```\n\n", step.Command))
output.WriteString(fmt.Sprintf("**Expected Output:** %s\n\n", step.Expected))
output.WriteString(fmt.Sprintf("**Next Action:** %s\n\n", step.NextAction))
output.WriteString("---\n\n")
}
// Add footer with additional guidance
output.WriteString("## 🚀 Quick Start\n\n")
output.WriteString("1. **Start with Step 1** to identify your target resources\n")
output.WriteString("2. **Follow the steps sequentially** for systematic diagnosis\n")
output.WriteString("3. **Use the suggested commands** with MCP-K8sWizard tools\n")
output.WriteString("4. **Adapt the commands** based on your specific resource names\n")
output.WriteString("5. **Document findings** for future reference\n\n")
output.WriteString("## 💡 Pro Tips\n\n")
output.WriteString("- Use `k8s_list_resources` first to get exact resource names\n")
output.WriteString("- Check logs with `k8s_get_logs` for detailed error information\n")
output.WriteString("- Use `kubectl_describe` for comprehensive resource details\n")
output.WriteString("- Combine multiple tools for thorough analysis\n")
output.WriteString("- Save successful commands for future troubleshooting\n\n")
output.WriteString("---\n")
output.WriteString("*Generated by MCP-K8sWizard - The Kubernetes Wizard for Modern DevOps* 🧙♂️")
return output.String()
}