Skip to main content
Glama

metoro-mcp-server

Official
by metoro-io
package tools import ( "bytes" "context" "encoding/json" "fmt" mcpgolang "github.com/metoro-io/mcp-golang" "github.com/metoro-io/metoro-mcp-server/model" "github.com/metoro-io/metoro-mcp-server/utils" "gopkg.in/yaml.v3" ) type GetVersionForServiceHandlerArgs struct { TimeConfig utils.TimeConfig `json:"time_config" jsonschema:"required,description=The time to get container versions. e.g. if you want to see the versions 5 minutes ago you would set time_period=5 and time_window=Minutes. You can also set an absolute time range by setting start_time and end_time"` ServiceName string `json:"serviceName" jsonschema:"required,description=The name of the service to get container versions for."` Environments []string `json:"environments" jsonschema:"description=The environments to get service versions for. If empty all environments will be used."` } type GetVersionForServiceResponse struct { ContainerVersions map[string]map[string]string `json:"container_versions"` } type K8sResourceSummaryResponse struct { K8sResourceSummary []struct { Environment string `json:"environment"` Kind string `json:"kind"` ResourceYaml string `json:"resourceYaml"` } `json:"k8sResourceSummary"` } func GetVersionForServiceHandler(ctx context.Context, arguments GetVersionForServiceHandlerArgs) (*mcpgolang.ToolResponse, error) { startTime, endTime, err := utils.CalculateTimeRange(arguments.TimeConfig) if err != nil { return nil, fmt.Errorf("error calculating time range: %v", err) } request := model.GetPodsRequest{ StartTime: startTime, EndTime: endTime, ServiceName: arguments.ServiceName, Environments: arguments.Environments, } jsonBody, err := json.Marshal(request) if err != nil { return nil, fmt.Errorf("error marshaling request: %v", err) } resp, err := utils.MakeMetoroAPIRequest("POST", "k8s/summary", bytes.NewBuffer(jsonBody), utils.GetAPIRequirementsFromRequest(ctx)) if err != nil { return nil, fmt.Errorf("error making Metoro call: %v", err) } // Parse the JSON response var summaryResponse K8sResourceSummaryResponse err = json.Unmarshal(resp, &summaryResponse) if err != nil { return nil, fmt.Errorf("error parsing JSON response: %v", err) } // Extract container versions from each environment containerVersions := make(map[string]map[string]string) for _, resource := range summaryResponse.K8sResourceSummary { // Parse the YAML for each resource var yamlData map[string]interface{} err = yaml.Unmarshal([]byte(resource.ResourceYaml), &yamlData) if err != nil { continue // Skip if we can't parse this resource } // Extract containers for this environment envContainers := make(map[string]string) // Check for spec.template.spec.containers (Deployment/StatefulSet) if spec, ok := yamlData["spec"].(map[string]interface{}); ok { if template, ok := spec["template"].(map[string]interface{}); ok { if templateSpec, ok := template["spec"].(map[string]interface{}); ok { extractContainers(templateSpec, envContainers) } } // Also check spec.containers directly (DaemonSet) extractContainers(spec, envContainers) } if len(envContainers) > 0 { containerVersions[resource.Environment] = envContainers } } response := GetVersionForServiceResponse{ ContainerVersions: containerVersions, } jsonResponse, err := json.Marshal(response) if err != nil { return nil, fmt.Errorf("error marshaling response: %v", err) } return mcpgolang.NewToolResponse(mcpgolang.NewTextContent(string(jsonResponse))), nil } func extractContainers(spec map[string]interface{}, containerVersions map[string]string) { if containers, ok := spec["containers"].([]interface{}); ok { for _, container := range containers { if containerMap, ok := container.(map[string]interface{}); ok { containerName, nameOk := containerMap["name"].(string) image, imageOk := containerMap["image"].(string) if nameOk && imageOk { containerVersions[containerName] = image } } } } // Also check for init containers if initContainers, ok := spec["initContainers"].([]interface{}); ok { for _, container := range initContainers { if containerMap, ok := container.(map[string]interface{}); ok { containerName, nameOk := containerMap["name"].(string) image, imageOk := containerMap["image"].(string) if nameOk && imageOk { containerVersions["init-"+containerName] = image } } } } }

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/metoro-io/metoro-mcp-server'

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