Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
13 changes: 13 additions & 0 deletions devops-mcp-server/cloudrun/client/cloudrunclient.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ type CloudRunClient interface {
DeployFromSource(ctx context.Context, projectID, location, serviceName, source string, port int32, allowPublicAccess bool) error
DeleteService(ctx context.Context, projectID, location, serviceName string) error
SetServiceAccess(ctx context.Context, serviceName string, allowPublicAccess bool) error
GetServiceStatus(ctx context.Context, projectID, location, serviceName string) (*cloudrunpb.Condition_State, error)
}

// NewCloudRunClient creates a new CloudRunClient.
Expand Down Expand Up @@ -144,6 +145,18 @@ func (c *CloudRunClientImpl) GetService(ctx context.Context, projectID, location
return service, nil
}

func (c *CloudRunClientImpl) GetServiceStatus(ctx context.Context, projectID, location, serviceName string) (*cloudrunpb.Condition_State, error) {
service, err := c.GetService(ctx, projectID, location, serviceName)
if err != nil {
return nil, fmt.Errorf("failed to get service: %w", err)
}
terminalCondition := service.GetTerminalCondition()
if terminalCondition == nil {
return nil, fmt.Errorf("service %q does not have a terminal condition", service.Name)
}
return &terminalCondition.State, nil
}

func (c *CloudRunClientImpl) GetRevision(ctx context.Context, service *cloudrunpb.Service) (*cloudrunpb.Revision, error) {
// Get the latest revision
latestRevision, err := c.revisionsClient.GetRevision(ctx, &cloudrunpb.GetRevisionRequest{Name: service.LatestReadyRevision})
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type MockCloudRunClient struct {
DeployFromSourceFunc func(ctx context.Context, projectID, location, serviceName, source string, port int32, allowPublicAccess bool) error
DeleteServiceFunc func(ctx context.Context, projectID, location, serviceName string) error
SetServiceAccessFunc func(ctx context.Context, serviceName string, allowPublicAccess bool) error
GetServiceStatusFunc func(ctx context.Context, projectID, location, serviceName string) (*cloudrunpb.Condition_State, error)
}

// DeleteService mocks the DeleteService method.
Expand Down Expand Up @@ -70,3 +71,8 @@ func (m *MockCloudRunClient) DeployFromSource(ctx context.Context, projectID, lo
func (m *MockCloudRunClient) SetServiceAccess(ctx context.Context, serviceName string, allowPublicAccess bool) error {
return m.SetServiceAccessFunc(ctx, serviceName, allowPublicAccess)
}

// GetServiceStatus mocks the GetServiceStatus method.
func (m *MockCloudRunClient) GetServiceStatus(ctx context.Context, projectID, location, serviceName string) (*cloudrunpb.Condition_State, error) {
return m.GetServiceStatusFunc(ctx, projectID, location, serviceName)
}
20 changes: 20 additions & 0 deletions devops-mcp-server/cloudrun/cloudrun.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ func (h *Handler) Register(server *mcp.Server) {
addListServicesTool(server, h.CrClient)
addDeployToCloudRunFromImageTool(server, h.CrClient)
addDeployToCloudRunFromSourceTool(server, h.CrClient)
addGetServiceStatusTool(server, h.CrClient)
}

type ListServicesArgs struct {
Expand Down Expand Up @@ -134,3 +135,22 @@ func addDeployToCloudRunFromSourceTool(server *mcp.Server, crClient cloudrunclie
}
mcp.AddTool(server, &mcp.Tool{Name: "cloudrun.deploy_to_cloud_run_from_source", Description: "Creates a new Cloud Run service or updates an existing one from source. This tool may take a couple minutes to finish running."}, deployToCloudRunFromSourceToolFunc)
}

type GetServiceStatusArgs struct{
ProjectID string `json:"project_id" jsonschema:"The Google Cloud project ID."`
Location string `json:"location" jsonschema:"The Google Cloud location."`
ServiceName string `json:"service_name" jsonschema:"The Cloud Run service name"`
}

var getServiceStatusToolFunc func(ctx context.Context, req *mcp.CallToolRequest, args GetServiceStatusArgs) (*mcp.CallToolResult, any, error)

func addGetServiceStatusTool(server *mcp.Server, crClient cloudrunclient.CloudRunClient) {
getServiceStatusToolFunc = func(ctx context.Context, req *mcp.CallToolRequest, args GetServiceStatusArgs) (*mcp.CallToolResult, any, error) {
state, err := crClient.GetServiceStatus(ctx, args.ProjectID, args.Location, args.ServiceName)
if err != nil {
return &mcp.CallToolResult{}, nil, fmt.Errorf("failed to get service state: %w", err)
}
return &mcp.CallToolResult{}, state, nil
}
mcp.AddTool(server, &mcp.Tool{Name: "cloudrun.service_status", Description: "Gets the current status of a Cloud Run service."}, getServiceStatusToolFunc)
}
Comment on lines 147 to 156

Choose a reason for hiding this comment

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

critical

This new function to add the service status tool is incomplete and has several issues that will cause compilation and runtime errors:

  1. Function Name Mismatch: The function is named addGetServiceStatusTool, but it's called as addGetServiceStatus in the Register method. This will cause an "undefined" compile error.
  2. Missing Tool Registration: The function defines a tool handler (getServiceStatusToolFunc) but never registers it with the MCP server using mcp.AddTool. The tool will not be available.
  3. Incorrect Handler Signature: The function literal for the handler is missing its return types (*mcp.CallToolResult, any, error). This is a compile error.
  4. Undeclared Variable: The variable getServiceStatusToolFunc is used without being declared at the package level. You need to add a var declaration for it, similar to listServicesToolFunc.
  5. Formatting Issues: There are several formatting problems, including incorrect indentation and a missing space in req* mcp.CallToolRequest.

Here is a corrected version of the function. Please note you will also need to add var getServiceStatusToolFunc func(ctx context.Context, req *mcp.CallToolRequest, args GetServiceStatusArgs) (*mcp.CallToolResult, any, error) at the package level.

Suggested change
func addGetServiceStatusTool(server *mcp.Server, crClient cloudrunclient.CloudRunClient) {
getServiceStatusToolFunc = func(ctx context.Context, req* mcp.CallToolRequest, args GetServiceStatusArgs){
state, err := crClient.GetServiceStatus(ctx, args.ProjectID, args.Location, args.ServiceName)
if err != nil {
return &mcp.CallToolResult{}, nil, fmt.Errorf("failed to get service state: %w", err)
}
return &mcp.CallToolResult{}, state, nil
}
}
func addGetServiceStatus(server *mcp.Server, crClient cloudrunclient.CloudRunClient) {
getServiceStatusToolFunc = func(ctx context.Context, req *mcp.CallToolRequest, args GetServiceStatusArgs) (*mcp.CallToolResult, any, error) {
state, err := crClient.GetStatus(ctx, args.ProjectID, args.Location, args.ServiceName)
if err != nil {
return &mcp.CallToolResult{}, nil, fmt.Errorf("failed to get service state: %w", err)
}
return &mcp.CallToolResult{}, state, nil
}
mcp.AddTool(server, &mcp.Tool{Name: "cloudrun.service_status", Description: "Provide detailed status of a Cloud Run service."}, getServiceStatusToolFunc)
}

Loading