# -*- coding: utf-8 -*- # # Copyright 2025 Google LLC. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """services mcp enable command.""" from googlecloudsdk.api_lib.services import services_util from googlecloudsdk.api_lib.services import serviceusage from googlecloudsdk.calliope import base from googlecloudsdk.command_lib.services import common_flags from googlecloudsdk.core import log from googlecloudsdk.core import properties from googlecloudsdk.core.console import console_io _OP_BASE_CMD = 'gcloud beta services operations ' _OP_WAIT_CMD = _OP_BASE_CMD + 'wait {0}' _SERVICE = 'services/%s' _PROJECT_RESOURCE = 'projects/{}' _FOLDER_RESOURCE = 'folders/{}' _ORGANIZATION_RESOURCE = 'organizations/{}' _CONSUMER_POLICY_DEFAULT = '/consumerPolicies/{}' @base.UniverseCompatible @base.ReleaseTracks(base.ReleaseTrack.ALPHA, base.ReleaseTrack.BETA) class Enable(base.SilentCommand): """Enable a service for MCP on a project, folder or organization. Enable a service for MCP on a project, folder or organization ## EXAMPLES To enable a service for MCP called `my-service` on the current project, run: $ {command} my-service To enable a service for MCP called `my-service` on the project `my-project`, run: $ {command} my-service --project=my-project To enable a service for MCP called `my-service` on the folder `my-folder, run: $ {command} my-service --folder=my-folder To enable a service for MCP called `my-service` on the organization `my-organization`, run: $ {command} my-service --organization=my-organization To run the same command asynchronously (non-blocking), run: $ {command} my-service --async """ @staticmethod def Args(parser): """Args is called by calliope to gather arguments for this command. Args: parser: An argparse parser that you can use to add arguments that go on the command line after this command. Positional arguments are allowed. """ common_flags.service_flag(suffix='to enable MCP').AddToParser(parser) common_flags.add_resource_args(parser) common_flags.skip_mcp_endpoint_check_flag(parser) base.ASYNC_FLAG.AddToParser(parser) def Run(self, args): """Run 'services mcp enable'. Args: args: argparse.Namespace, The arguments that this command was invoked with. Returns: Updated MCP Policy. """ project = properties.VALUES.core.project.Get(required=True) resource_name = _PROJECT_RESOURCE.format(project) if args.IsSpecified('project'): resource_name = _PROJECT_RESOURCE.format(args.project) project = args.project if args.IsSpecified('folder'): resource_name = _FOLDER_RESOURCE.format(args.folder) folder = args.folder else: folder = None if args.IsSpecified('organization'): resource_name = _ORGANIZATION_RESOURCE.format(args.organization) organization = args.organization else: organization = None # check if sevice has Mcp Config service_metadata = serviceusage.GetServiceV2Beta( f'{resource_name}/services/{args.service}' ) if not args.skip_mcp_endpoint_check and ( not service_metadata.service.mcpServer or not service_metadata.service.mcpServer.urls ): log.error( f'The service {args.service} does not have MCP endpoint.' ) return if not service_metadata.state.enableRules: enable_msg = serviceusage.GetMcpEnabledError(resource_name) do_enable = console_io.PromptContinue( enable_msg, default=False, throw_if_unattended=True, ) if do_enable: enable_service_op, _ = serviceusage.AddEnableRule( [args.service], project, folder=folder, organization=organization, ) # The operation should not be None when enable rules are empty, # but in case it is, we check it here to avoid error. if enable_service_op: enable_service_op = services_util.WaitOperation( enable_service_op.name, serviceusage.GetOperationV2Beta ) if enable_service_op.error: log.error( f'Failed to enable the service {args.service} for the resource' f' {resource_name}: {enable_service_op.error}' ) return else: return op = serviceusage.AddMcpEnableRule( args.service, project, folder=folder, organization=organization, ) if op is None: return None if args.async_: cmd = _OP_WAIT_CMD.format(op.name) log.status.Print( 'Asynchronous operation is in progress... ' 'Use the following command to wait for its ' f'completion:\n {cmd}' ) return op = services_util.WaitOperation(op.name, serviceusage.GetOperationV2Beta) if op.error: services_util.PrintOperation(op) else: log.status.Print( f'The MCP endpoint for service {args.service} has been enabled for' f' the resource {resource_name}.' )