Skip to main content
Glama
utils.go8.77 kB
package tools import ( "bytes" "context" "encoding/json" "fmt" "log" "os/exec" "time" "github.com/mark3labs/mcp-go/mcp" ) // ExecutionResult contains the result of a command execution type ExecutionResult struct { Stdout string Stderr string ExitCode int Duration time.Duration Successful bool Command string // Command that was executed } // NLMetadata represents natural language metadata for tools type NLMetadata struct { Aliases []string `json:"aliases"` Examples []string `json:"examples"` } // ToolNLMetadata maps tool names to their natural language metadata var ToolNLMetadata = map[string]NLMetadata{ "go_build": { Aliases: []string{ "compile", "build", "create executable", "generate binary", "make binary", "construct program", "prepare executable", "generate program", "assemble code", "create program", "make executable", "generate exe", "turn into binary", "convert to executable", "transform into program", }, Examples: []string{ "compile this Go code", "build this program", "create an executable from this code", "make a binary from this Go file", "convert this source code into an executable", "generate a binary in the bin directory", "build this with the debug tag", "compile my Go application with race detection", "create a statically linked executable", "build with optimizations enabled", }, }, "go_test": { Aliases: []string{ "test", "unit test", "run tests", "check tests", "verify tests", "execute tests", "validate tests", "run test suite", "run unit tests", "check test cases", "run test coverage", "test the code", "verify test cases", "test functions", "run test functions", "perform tests", }, Examples: []string{ "test this Go code", "run unit tests", "check if tests pass", "verify test coverage", "run tests with verbose output", "test this package and show coverage", "run only the TestLogin function", "test with race detection enabled", "run short tests only", "check if tests pass with verbose output", "I want to run the unit tests for this code", }, }, "go_run": { Aliases: []string{ "run", "execute", "start", "launch", "run code", "execute code", "run program", "start program", "launch application", "start application", "execute program", "run application", "execute application", "invoke program", "run this", "execute this", }, Examples: []string{ "run this Go code", "execute this program", "start this application with arguments", "run this code with the input parameter set to 'test'", "execute the main package", "run this with environment variable DEBUG=true", "start the web server on port 8080", "run the application with configuration file config.json", "execute the script with verbose logging", "start this program and capture its output", }, }, "go_mod": { Aliases: []string{ "dependencies", "modules", "manage dependencies", "dependency management", "update modules", "package dependencies", "go.mod", "module dependencies", "dependency tracking", "import management", "external packages", "third-party packages", "package management", "lib management", "library dependencies", }, Examples: []string{ "initialize a new module", "update dependencies", "add a new dependency", "tidy up module dependencies", "create a new go.mod file", "add github.com/gorilla/mux to the dependencies", "update all dependencies to their latest versions", "clean up unused dependencies with go mod tidy", "vendor all dependencies for this project", "initialize a module for a new project", "check for available updates to dependencies", }, }, "go_fmt": { Aliases: []string{ "format", "beautify", "pretty-print", "indent", "format code", "beautify code", "pretty-print code", "clean up code", "standardize format", "fix formatting", "align code", "normalize code", "standardize indentation", "reorganize code", "improve readability", "gofmt", }, Examples: []string{ "format this Go code", "beautify this program", "fix the formatting of this code", "make this code look nice", "apply gofmt to this file", "standardize indentation in this code", "fix whitespace in this Go file", "reformat according to Go standards", "clean up this messy code", "apply standard Go formatting to this code", "pretty-print this function", }, }, "go_analyze": { Aliases: []string{ "lint", "check", "validate", "inspect", "analyze", "examine", "vet", "go vet", "static analysis", "code check", "quality check", "verify code", "scrutinize", "review code", "find issues", "detect problems", "spot errors", "check for bugs", }, Examples: []string{ "analyze this Go code for issues", "check for bugs", "validate this function", "inspect code quality", "run go vet on this code", "find potential concurrency issues", "check for memory leaks in this code", "detect possible nil pointer dereferences", "analyze for inefficient patterns", "look for security vulnerabilities", "identify unused variables and imports", "check for proper error handling", }, }, "go_workspace": { Aliases: []string{ "workspace", "multi-module", "workspace management", "manage workspace", "workspace operations", "workspace commands", "work with workspace", "initialize workspace", "create workspace", "setup workspace", "workspace initialization", "add modules to workspace", "workspace sync", "synchronize workspace", "vendor workspace", "workspace vendor", }, Examples: []string{ "initialize a new workspace", "create a workspace with these modules", "add modules to the workspace", "synchronize workspace dependencies", "vendor all workspace dependencies", "get workspace information", "setup a multi-module workspace", "manage workspace modules", "edit workspace configuration", "show workspace status", }, }, } // execute runs a command and returns the execution result with better logging func execute(cmd *exec.Cmd) (*ExecutionResult, error) { var stdout, stderr bytes.Buffer cmd.Stdout = &stdout cmd.Stderr = &stderr // Capture the command for debugging cmdStr := cmd.String() log.Printf("Executing command: %s", cmdStr) // Execute with timeout context ctx, cancel := context.WithTimeout(context.Background(), 30*time.Second) defer cancel() // Use CommandContext instead of cmd.Run() execCmd := exec.CommandContext(ctx, cmd.Path, cmd.Args[1:]...) execCmd.Env = cmd.Env execCmd.Dir = cmd.Dir execCmd.Stdout = &stdout execCmd.Stderr = &stderr start := time.Now() err := execCmd.Run() duration := time.Since(start) // Check if the context deadline exceeded if ctx.Err() == context.DeadlineExceeded { log.Printf("Command timed out after %v: %s", duration, cmdStr) return &ExecutionResult{ Stdout: stdout.String(), Stderr: "Command execution timed out", ExitCode: -1, Duration: duration, Successful: false, Command: cmdStr, }, fmt.Errorf("command timed out after %v", duration) } result := &ExecutionResult{ Stdout: stdout.String(), Stderr: stderr.String(), Duration: duration, Successful: err == nil, Command: cmdStr, } if exitErr, ok := err.(*exec.ExitError); ok { result.ExitCode = exitErr.ExitCode() } // Log execution results if result.Successful { log.Printf("Command succeeded in %v: %s", duration, cmdStr) } else { log.Printf("Command failed in %v with exit code %d: %s", duration, result.ExitCode, cmdStr) } return result, nil } // FormatCommandResult creates a standardized JSON response for tool executions func FormatCommandResult(result *ExecutionResult, responseType string) *mcp.CallToolResult { response := map[string]interface{}{ "success": result.Successful, "exitCode": result.ExitCode, "duration": result.Duration.String(), "command": result.Command, "type": responseType, "timestamp": time.Now().Format(time.RFC3339), } if result.Stdout != "" { response["stdout"] = result.Stdout } if result.Stderr != "" { response["stderr"] = result.Stderr // Add structured error details if there's an error if !result.Successful { response["errorDetails"] = ParseGoErrors(result.Stderr) } } // Add natural language metadata based on the tool type AddNLMetadata(response, responseType) jsonBytes, err := json.MarshalIndent(response, "", " ") if err != nil { return mcp.NewToolResultError(fmt.Sprintf("Error marshaling response: %v", err)) } if result.Successful { return mcp.NewToolResultText(string(jsonBytes)) } else { return mcp.NewToolResultError(string(jsonBytes)) } }

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/MrFixit96/go-dev-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server