diff --git a/.repo-metadata-full.json b/.repo-metadata-full.json
index 771229c6598..95acf82d3d4 100644
--- a/.repo-metadata-full.json
+++ b/.repo-metadata-full.json
@@ -105,6 +105,14 @@
"issue_tracker": "https://github.com/googleapis/google-cloud-php/issues",
"api_shortname": "apikeys"
},
+ "ApiRegistry": {
+ "language": "php",
+ "distribution_name": "google/cloud-apiregistry",
+ "release_level": "preview",
+ "client_documentation": "https://cloud.google.com/php/docs/reference/cloud-apiregistry/latest",
+ "library_type": "GAPIC_AUTO",
+ "api_shortname": "cloudapiregistry"
+ },
"ApigeeConnect": {
"language": "php",
"distribution_name": "google/cloud-apigee-connect",
diff --git a/ApiRegistry/.OwlBot.yaml b/ApiRegistry/.OwlBot.yaml
new file mode 100644
index 00000000000..934ed23e376
--- /dev/null
+++ b/ApiRegistry/.OwlBot.yaml
@@ -0,0 +1,4 @@
+deep-copy-regex:
+ - source: /google/cloud/apiregistry/(v1beta)/.*-php/(.*)
+ dest: /owl-bot-staging/ApiRegistry/$1/$2
+api-name: ApiRegistry
diff --git a/ApiRegistry/.gitattributes b/ApiRegistry/.gitattributes
new file mode 100644
index 00000000000..4bf0fe6f415
--- /dev/null
+++ b/ApiRegistry/.gitattributes
@@ -0,0 +1,7 @@
+/*.xml.dist export-ignore
+/.OwlBot.yaml export-ignore
+/.github export-ignore
+/owlbot.py export-ignore
+/src/**/gapic_metadata.json export-ignore
+/samples export-ignore
+/tests export-ignore
diff --git a/ApiRegistry/.github/pull_request_template.md b/ApiRegistry/.github/pull_request_template.md
new file mode 100644
index 00000000000..3c8d56ff6b9
--- /dev/null
+++ b/ApiRegistry/.github/pull_request_template.md
@@ -0,0 +1,24 @@
+**PLEASE READ THIS ENTIRE MESSAGE**
+
+Hello, and thank you for your contribution! Please note that this repository is
+a read-only split of `googleapis/google-cloud-php`. As such, we are
+unable to accept pull requests to this repository.
+
+We welcome your pull request and would be happy to consider it for inclusion in
+our library if you follow these steps:
+
+* Clone the parent client library repository:
+
+```sh
+$ git clone git@github.com:googleapis/google-cloud-php.git
+```
+
+* Move your changes into the correct location in that library. Library code
+belongs in `ApiRegistry/src`, and tests in `ApiRegistry/tests`.
+
+* Push the changes in a new branch to a fork, and open a new pull request
+[here](https://github.com/googleapis/google-cloud-php).
+
+Thanks again, and we look forward to seeing your proposed change!
+
+The Google Cloud PHP team
diff --git a/ApiRegistry/CONTRIBUTING.md b/ApiRegistry/CONTRIBUTING.md
new file mode 100644
index 00000000000..76ea811cacd
--- /dev/null
+++ b/ApiRegistry/CONTRIBUTING.md
@@ -0,0 +1,10 @@
+# How to Contribute
+
+We'd love to accept your patches and contributions to this project. We accept
+and review pull requests against the main
+[Google Cloud PHP](https://github.com/googleapis/google-cloud-php)
+repository, which contains all of our client libraries. You will also need to
+sign a Contributor License Agreement. For more details about how to contribute,
+see the
+[CONTRIBUTING.md](https://github.com/googleapis/google-cloud-php/blob/main/CONTRIBUTING.md)
+file in the main Google Cloud PHP repository.
diff --git a/ApiRegistry/LICENSE b/ApiRegistry/LICENSE
new file mode 100644
index 00000000000..8f71f43fee3
--- /dev/null
+++ b/ApiRegistry/LICENSE
@@ -0,0 +1,202 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "{}"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright {yyyy} {name of copyright owner}
+
+ 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.
+
diff --git a/ApiRegistry/README.md b/ApiRegistry/README.md
new file mode 100644
index 00000000000..f0e3b373c13
--- /dev/null
+++ b/ApiRegistry/README.md
@@ -0,0 +1,72 @@
+# Google Cloud Api Registry for PHP
+
+> Idiomatic PHP client for [Google Cloud Api Registry](https://docs.cloud.google.com/api-registry/docs).
+
+[](https://packagist.org/packages/google/cloud-apiregistry) [](https://packagist.org/packages/google/cloud-apiregistry)
+
+* [API documentation](https://cloud.google.com/php/docs/reference/cloud-apiregistry/latest)
+
+**NOTE:** This repository is part of [Google Cloud PHP](https://github.com/googleapis/google-cloud-php). Any
+support requests, bug reports, or development contributions should be directed to
+that project.
+
+### Installation
+
+To begin, install the preferred dependency manager for PHP, [Composer](https://getcomposer.org/).
+
+Now, install this component:
+
+```sh
+$ composer require google/cloud-apiregistry
+```
+
+> Browse the complete list of [Google Cloud APIs](https://cloud.google.com/php/docs/reference)
+> for PHP
+
+This component supports both REST over HTTP/1.1 and gRPC. In order to take advantage of the benefits
+offered by gRPC (such as streaming methods) please see our
+[gRPC installation guide](https://cloud.google.com/php/grpc).
+
+### Authentication
+
+Please see our [Authentication guide](https://github.com/googleapis/google-cloud-php/blob/main/AUTHENTICATION.md) for more information
+on authenticating your client. Once authenticated, you'll be ready to start making requests.
+
+### Sample
+
+```php
+use Google\ApiCore\ApiException;
+use Google\Cloud\ApiRegistry\V1beta\Client\CloudApiRegistryClient;
+use Google\Cloud\Location\GetLocationRequest;
+use Google\Cloud\Location\Location;
+
+// Create a client.
+$cloudApiRegistryClient = new CloudApiRegistryClient();
+
+// Prepare the request message.
+$request = new GetLocationRequest();
+
+// Call the API and handle any network failures.
+try {
+ /** @var Location $response */
+ $response = $cloudApiRegistryClient->getLocation($request);
+ printf('Response data: %s' . PHP_EOL, $response->serializeToJsonString());
+} catch (ApiException $ex) {
+ printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage());
+}
+```
+
+See the [samples directory](https://github.com/googleapis/google-cloud-php-apiregistry/tree/main/samples) for a canonical list of samples.
+
+### Debugging
+
+Please see our [Debugging guide](https://github.com/googleapis/google-cloud-php/blob/main/DEBUG.md)
+for more information about the debugging tools.
+
+### Version
+
+This component is considered alpha. As such, it is still a work-in-progress and is more likely to get backwards-incompatible updates.
+
+### Next Steps
+
+1. Understand the [official documentation](https://docs.cloud.google.com/api-registry/docs/overview).
diff --git a/ApiRegistry/VERSION b/ApiRegistry/VERSION
new file mode 100644
index 00000000000..77d6f4ca237
--- /dev/null
+++ b/ApiRegistry/VERSION
@@ -0,0 +1 @@
+0.0.0
diff --git a/ApiRegistry/composer.json b/ApiRegistry/composer.json
new file mode 100644
index 00000000000..da77eafe290
--- /dev/null
+++ b/ApiRegistry/composer.json
@@ -0,0 +1,30 @@
+{
+ "name": "google/cloud-apiregistry",
+ "description": "Google Cloud Api Registry Client for PHP",
+ "license": "Apache-2.0",
+ "minimum-stability": "stable",
+ "autoload": {
+ "psr-4": {
+ "Google\\Cloud\\ApiRegistry\\": "src",
+ "GPBMetadata\\Google\\Cloud\\Apiregistry\\": "metadata"
+ }
+ },
+ "extra": {
+ "component": {
+ "id": "cloud-apiregistry",
+ "path": "ApiRegistry",
+ "target": "googleapis/google-cloud-php-apiregistry"
+ }
+ },
+ "require": {
+ "php": "^8.1",
+ "google/gax": "^1.40.0"
+ },
+ "require-dev": {
+ "phpunit/phpunit": "^9.0"
+ },
+ "suggest": {
+ "ext-grpc": "Enables use of gRPC, a universal high-performance RPC framework created by Google.",
+ "ext-protobuf": "Provides a significant increase in throughput over the pure PHP protobuf implementation. See https://cloud.google.com/php/grpc for installation instructions."
+ }
+}
diff --git a/ApiRegistry/metadata/V1Beta/Common.php b/ApiRegistry/metadata/V1Beta/Common.php
new file mode 100644
index 00000000000..0051f313d90
Binary files /dev/null and b/ApiRegistry/metadata/V1Beta/Common.php differ
diff --git a/ApiRegistry/metadata/V1Beta/Resources.php b/ApiRegistry/metadata/V1Beta/Resources.php
new file mode 100644
index 00000000000..495ad071177
--- /dev/null
+++ b/ApiRegistry/metadata/V1Beta/Resources.php
@@ -0,0 +1,50 @@
+internalAddGeneratedFile(
+ '
+
+
+/google/cloud/apiregistry/v1beta/resources.protogoogle.cloud.apiregistry.v1betagoogle/api/resource.proto,google/cloud/apiregistry/v1beta/common.protogoogle/protobuf/struct.proto"
+ McpServer
+name ( BA
+display_name ( BA
+description ( BA
+urls ( -
+capabilities (2.google.protobuf.Struct:
+state (2&.google.cloud.apiregistry.v1beta.StateBA:A
+)cloudapiregistry.googleapis.com/McpServer]projects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}?projects/{project}/locations/{location}/mcpServers/{mcp_server}*
+mcpServers2 mcpServer"
+McpTool
+name ( BA
+display_name ( BA
+description (
+mcp_server_urls ( -
+input_schema (2.google.protobuf.Struct.
+
output_schema (2.google.protobuf.Struct,
+annotations (2.google.protobuf.Struct:A
+\'cloudapiregistry.googleapis.com/McpToolqprojects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}Sprojects/{project}/locations/{location}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}*mcpTools2mcpToolB
+#com.google.cloud.apiregistry.v1betaBResourcesProtoPZEcloud.google.com/go/apiregistry/apiv1beta/apiregistrypb;apiregistrypbGoogle.Cloud.ApiRegistry.V1BetaGoogle\\Cloud\\ApiRegistry\\V1beta"Google::Cloud::ApiRegistry::V1betabproto3'
+ , true);
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/ApiRegistry/metadata/V1Beta/Service.php b/ApiRegistry/metadata/V1Beta/Service.php
new file mode 100644
index 00000000000..03949707347
--- /dev/null
+++ b/ApiRegistry/metadata/V1Beta/Service.php
@@ -0,0 +1,68 @@
+internalAddGeneratedFile(
+ '
+
+-google/cloud/apiregistry/v1beta/service.protogoogle.cloud.apiregistry.v1betagoogle/api/client.protogoogle/api/field_behavior.protogoogle/api/resource.proto/google/cloud/apiregistry/v1beta/resources.proto"V
+GetMcpServerRequest?
+name ( B1AA+
+)cloudapiregistry.googleapis.com/McpServer"
+ListMcpServersRequest9
+parent ( B)AA#
+!locations.googleapis.com/Location
+ page_size (BA
+
+page_token ( BA
+filter ( BA
+order_by ( BA"
+ListMcpServersResponse?
+mcp_servers (2*.google.cloud.apiregistry.v1beta.McpServer
+next_page_token (
+unreachable ( "R
+GetMcpToolRequest=
+name ( B/AA)
+\'cloudapiregistry.googleapis.com/McpTool"
+ListMcpToolsRequest?
+parent ( B/AA)\'cloudapiregistry.googleapis.com/McpTool
+ page_size (BA
+
+page_token ( BA
+filter ( BA
+order_by ( BA"
+ListMcpToolsResponse;
+ mcp_tools (2(.google.cloud.apiregistry.v1beta.McpTool
+next_page_token (
+unreachable ( 2
+CloudApiRegistry
+GetMcpServer4.google.cloud.apiregistry.v1beta.GetMcpServerRequest*.google.cloud.apiregistry.v1beta.McpServer"AAname42/v1beta/{name=projects/*/locations/*/mcpServers/*}
+ListMcpServers6.google.cloud.apiregistry.v1beta.ListMcpServersRequest7.google.cloud.apiregistry.v1beta.ListMcpServersResponse"CAparent42/v1beta/{parent=projects/*/locations/*}/mcpServers
+
+GetMcpTool2.google.cloud.apiregistry.v1beta.GetMcpToolRequest(.google.cloud.apiregistry.v1beta.McpTool"LAname?=/v1beta/{name=projects/*/locations/*/mcpServers/*/mcpTools/*}
+ListMcpTools4.google.cloud.apiregistry.v1beta.ListMcpToolsRequest5.google.cloud.apiregistry.v1beta.ListMcpToolsResponse"NAparent?=/v1beta/{parent=projects/*/locations/*/mcpServers/*}/mcpToolsSAcloudapiregistry.googleapis.comA.https://www.googleapis.com/auth/cloud-platformB
+#com.google.cloud.apiregistry.v1betaBServiceProtoPZEcloud.google.com/go/apiregistry/apiv1beta/apiregistrypb;apiregistrypbGoogle.Cloud.ApiRegistry.V1BetaGoogle\\Cloud\\ApiRegistry\\V1beta"Google::Cloud::ApiRegistry::V1betaAu
+,cloudapiregistry.googleapis.com/ApiNamespaceEprojects/{project}/locations/{location}/apiNamespaces/{api_namespace}bproto3'
+ , true);
+
+ static::$is_initialized = true;
+ }
+}
+
diff --git a/ApiRegistry/owlbot.py b/ApiRegistry/owlbot.py
new file mode 100644
index 00000000000..95cda3f373f
--- /dev/null
+++ b/ApiRegistry/owlbot.py
@@ -0,0 +1,56 @@
+# Copyright 2024 Google LLC
+#
+# 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.
+
+"""This script is used to synthesize generated parts of this library."""
+
+import logging
+from pathlib import Path
+import subprocess
+
+import synthtool as s
+from synthtool.languages import php
+from synthtool import _tracked_paths
+
+logging.basicConfig(level=logging.DEBUG)
+
+src = Path(f"../{php.STAGING_DIR}/ApiRegistry").resolve()
+dest = Path().resolve()
+
+# Added so that we can pass copy_excludes in the owlbot_main() call
+_tracked_paths.add(src)
+
+php.owlbot_main(src=src, dest=dest)
+
+# remove class_alias code
+s.replace(
+ "src/V*/**/*.php",
+ r"^// Adding a class alias for backwards compatibility with the previous class name.$"
+ + "\n"
+ + r"^class_alias\(.*\);$"
+ + "\n",
+ '')
+
+# format generated clients
+subprocess.run([
+ 'npm',
+ 'exec',
+ '--yes',
+ '--package=@prettier/plugin-php@^0.19',
+ '--',
+ 'prettier',
+ '**/Client/*',
+ '--write',
+ '--parser=php',
+ '--single-quote',
+ '--print-width=120'])
diff --git a/ApiRegistry/phpunit.xml.dist b/ApiRegistry/phpunit.xml.dist
new file mode 100644
index 00000000000..ca0bc7c995f
--- /dev/null
+++ b/ApiRegistry/phpunit.xml.dist
@@ -0,0 +1,16 @@
+
+
+
+
+ src
+
+
+ src/V[!a-zA-Z]*
+
+
+
+
+ tests/Unit
+
+
+
diff --git a/ApiRegistry/samples/V1beta/CloudApiRegistryClient/get_location.php b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/get_location.php
new file mode 100644
index 00000000000..9dfbc0439d4
--- /dev/null
+++ b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/get_location.php
@@ -0,0 +1,57 @@
+getLocation($request);
+ printf('Response data: %s' . PHP_EOL, $response->serializeToJsonString());
+ } catch (ApiException $ex) {
+ printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage());
+ }
+}
+// [END cloudapiregistry_v1beta_generated_CloudApiRegistry_GetLocation_sync]
diff --git a/ApiRegistry/samples/V1beta/CloudApiRegistryClient/get_mcp_server.php b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/get_mcp_server.php
new file mode 100644
index 00000000000..a0c59b09ff6
--- /dev/null
+++ b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/get_mcp_server.php
@@ -0,0 +1,76 @@
+setName($formattedName);
+
+ // Call the API and handle any network failures.
+ try {
+ /** @var McpServer $response */
+ $response = $cloudApiRegistryClient->getMcpServer($request);
+ printf('Response data: %s' . PHP_EOL, $response->serializeToJsonString());
+ } catch (ApiException $ex) {
+ printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage());
+ }
+}
+
+/**
+ * Helper to execute the sample.
+ *
+ * This sample has been automatically generated and should be regarded as a code
+ * template only. It will require modifications to work:
+ * - It may require correct/in-range values for request initialization.
+ * - It may require specifying regional endpoints when creating the service client,
+ * please see the apiEndpoint client configuration option for more details.
+ */
+function callSample(): void
+{
+ $formattedName = CloudApiRegistryClient::mcpServerName(
+ '[PROJECT]',
+ '[LOCATION]',
+ '[API_NAMESPACE]',
+ '[MCP_SERVER]'
+ );
+
+ get_mcp_server_sample($formattedName);
+}
+// [END cloudapiregistry_v1beta_generated_CloudApiRegistry_GetMcpServer_sync]
diff --git a/ApiRegistry/samples/V1beta/CloudApiRegistryClient/get_mcp_tool.php b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/get_mcp_tool.php
new file mode 100644
index 00000000000..8d4a23382f9
--- /dev/null
+++ b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/get_mcp_tool.php
@@ -0,0 +1,77 @@
+setName($formattedName);
+
+ // Call the API and handle any network failures.
+ try {
+ /** @var McpTool $response */
+ $response = $cloudApiRegistryClient->getMcpTool($request);
+ printf('Response data: %s' . PHP_EOL, $response->serializeToJsonString());
+ } catch (ApiException $ex) {
+ printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage());
+ }
+}
+
+/**
+ * Helper to execute the sample.
+ *
+ * This sample has been automatically generated and should be regarded as a code
+ * template only. It will require modifications to work:
+ * - It may require correct/in-range values for request initialization.
+ * - It may require specifying regional endpoints when creating the service client,
+ * please see the apiEndpoint client configuration option for more details.
+ */
+function callSample(): void
+{
+ $formattedName = CloudApiRegistryClient::mcpToolName(
+ '[PROJECT]',
+ '[LOCATION]',
+ '[API_NAMESPACE]',
+ '[MCP_SERVER]',
+ '[MCP_TOOL]'
+ );
+
+ get_mcp_tool_sample($formattedName);
+}
+// [END cloudapiregistry_v1beta_generated_CloudApiRegistry_GetMcpTool_sync]
diff --git a/ApiRegistry/samples/V1beta/CloudApiRegistryClient/list_locations.php b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/list_locations.php
new file mode 100644
index 00000000000..4aa5eb7b828
--- /dev/null
+++ b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/list_locations.php
@@ -0,0 +1,62 @@
+listLocations($request);
+
+ /** @var Location $element */
+ foreach ($response as $element) {
+ printf('Element data: %s' . PHP_EOL, $element->serializeToJsonString());
+ }
+ } catch (ApiException $ex) {
+ printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage());
+ }
+}
+// [END cloudapiregistry_v1beta_generated_CloudApiRegistry_ListLocations_sync]
diff --git a/ApiRegistry/samples/V1beta/CloudApiRegistryClient/list_mcp_servers.php b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/list_mcp_servers.php
new file mode 100644
index 00000000000..eb3c992ae96
--- /dev/null
+++ b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/list_mcp_servers.php
@@ -0,0 +1,76 @@
+setParent($formattedParent);
+
+ // Call the API and handle any network failures.
+ try {
+ /** @var PagedListResponse $response */
+ $response = $cloudApiRegistryClient->listMcpServers($request);
+
+ /** @var McpServer $element */
+ foreach ($response as $element) {
+ printf('Element data: %s' . PHP_EOL, $element->serializeToJsonString());
+ }
+ } catch (ApiException $ex) {
+ printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage());
+ }
+}
+
+/**
+ * Helper to execute the sample.
+ *
+ * This sample has been automatically generated and should be regarded as a code
+ * template only. It will require modifications to work:
+ * - It may require correct/in-range values for request initialization.
+ * - It may require specifying regional endpoints when creating the service client,
+ * please see the apiEndpoint client configuration option for more details.
+ */
+function callSample(): void
+{
+ $formattedParent = CloudApiRegistryClient::locationName('[PROJECT]', '[LOCATION]');
+
+ list_mcp_servers_sample($formattedParent);
+}
+// [END cloudapiregistry_v1beta_generated_CloudApiRegistry_ListMcpServers_sync]
diff --git a/ApiRegistry/samples/V1beta/CloudApiRegistryClient/list_mcp_tools.php b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/list_mcp_tools.php
new file mode 100644
index 00000000000..5249b63c30d
--- /dev/null
+++ b/ApiRegistry/samples/V1beta/CloudApiRegistryClient/list_mcp_tools.php
@@ -0,0 +1,81 @@
+setParent($formattedParent);
+
+ // Call the API and handle any network failures.
+ try {
+ /** @var PagedListResponse $response */
+ $response = $cloudApiRegistryClient->listMcpTools($request);
+
+ /** @var McpTool $element */
+ foreach ($response as $element) {
+ printf('Element data: %s' . PHP_EOL, $element->serializeToJsonString());
+ }
+ } catch (ApiException $ex) {
+ printf('Call failed with message: %s' . PHP_EOL, $ex->getMessage());
+ }
+}
+
+/**
+ * Helper to execute the sample.
+ *
+ * This sample has been automatically generated and should be regarded as a code
+ * template only. It will require modifications to work:
+ * - It may require correct/in-range values for request initialization.
+ * - It may require specifying regional endpoints when creating the service client,
+ * please see the apiEndpoint client configuration option for more details.
+ */
+function callSample(): void
+{
+ $formattedParent = CloudApiRegistryClient::mcpServerName(
+ '[PROJECT]',
+ '[LOCATION]',
+ '[API_NAMESPACE]',
+ '[MCP_SERVER]'
+ );
+
+ list_mcp_tools_sample($formattedParent);
+}
+// [END cloudapiregistry_v1beta_generated_CloudApiRegistry_ListMcpTools_sync]
diff --git a/ApiRegistry/src/V1beta/Client/CloudApiRegistryClient.php b/ApiRegistry/src/V1beta/Client/CloudApiRegistryClient.php
new file mode 100644
index 00000000000..0d6da8bd44b
--- /dev/null
+++ b/ApiRegistry/src/V1beta/Client/CloudApiRegistryClient.php
@@ -0,0 +1,585 @@
+ getMcpServerAsync(GetMcpServerRequest $request, array $optionalArgs = [])
+ * @method PromiseInterface getMcpToolAsync(GetMcpToolRequest $request, array $optionalArgs = [])
+ * @method PromiseInterface listMcpServersAsync(ListMcpServersRequest $request, array $optionalArgs = [])
+ * @method PromiseInterface listMcpToolsAsync(ListMcpToolsRequest $request, array $optionalArgs = [])
+ * @method PromiseInterface getLocationAsync(GetLocationRequest $request, array $optionalArgs = [])
+ * @method PromiseInterface listLocationsAsync(ListLocationsRequest $request, array $optionalArgs = [])
+ */
+final class CloudApiRegistryClient
+{
+ use GapicClientTrait;
+ use ResourceHelperTrait;
+
+ /** The name of the service. */
+ private const SERVICE_NAME = 'google.cloud.apiregistry.v1beta.CloudApiRegistry';
+
+ /**
+ * The default address of the service.
+ *
+ * @deprecated SERVICE_ADDRESS_TEMPLATE should be used instead.
+ */
+ private const SERVICE_ADDRESS = 'cloudapiregistry.googleapis.com';
+
+ /** The address template of the service. */
+ private const SERVICE_ADDRESS_TEMPLATE = 'cloudapiregistry.UNIVERSE_DOMAIN';
+
+ /** The default port of the service. */
+ private const DEFAULT_SERVICE_PORT = 443;
+
+ /** The name of the code generator, to be included in the agent header. */
+ private const CODEGEN_NAME = 'gapic';
+
+ /** The default scopes required by the service. */
+ public static $serviceScopes = ['https://www.googleapis.com/auth/cloud-platform'];
+
+ private static function getClientDefaults()
+ {
+ return [
+ 'serviceName' => self::SERVICE_NAME,
+ 'apiEndpoint' => self::SERVICE_ADDRESS . ':' . self::DEFAULT_SERVICE_PORT,
+ 'clientConfig' => __DIR__ . '/../resources/cloud_api_registry_client_config.json',
+ 'descriptorsConfigPath' => __DIR__ . '/../resources/cloud_api_registry_descriptor_config.php',
+ 'gcpApiConfigPath' => __DIR__ . '/../resources/cloud_api_registry_grpc_config.json',
+ 'credentialsConfig' => [
+ 'defaultScopes' => self::$serviceScopes,
+ ],
+ 'transportConfig' => [
+ 'rest' => [
+ 'restClientConfigPath' => __DIR__ . '/../resources/cloud_api_registry_rest_client_config.php',
+ ],
+ ],
+ ];
+ }
+
+ /**
+ * Formats a string containing the fully-qualified path to represent a location
+ * resource.
+ *
+ * @param string $project
+ * @param string $location
+ *
+ * @return string The formatted location resource.
+ *
+ * @experimental
+ */
+ public static function locationName(string $project, string $location): string
+ {
+ return self::getPathTemplate('location')->render([
+ 'project' => $project,
+ 'location' => $location,
+ ]);
+ }
+
+ /**
+ * Formats a string containing the fully-qualified path to represent a mcp_server
+ * resource.
+ *
+ * @param string $project
+ * @param string $location
+ * @param string $apiNamespace
+ * @param string $mcpServer
+ *
+ * @return string The formatted mcp_server resource.
+ *
+ * @experimental
+ */
+ public static function mcpServerName(
+ string $project,
+ string $location,
+ string $apiNamespace,
+ string $mcpServer
+ ): string {
+ return self::getPathTemplate('mcpServer')->render([
+ 'project' => $project,
+ 'location' => $location,
+ 'api_namespace' => $apiNamespace,
+ 'mcp_server' => $mcpServer,
+ ]);
+ }
+
+ /**
+ * Formats a string containing the fully-qualified path to represent a mcp_tool
+ * resource.
+ *
+ * @param string $project
+ * @param string $location
+ * @param string $apiNamespace
+ * @param string $mcpServer
+ * @param string $mcpTool
+ *
+ * @return string The formatted mcp_tool resource.
+ *
+ * @experimental
+ */
+ public static function mcpToolName(
+ string $project,
+ string $location,
+ string $apiNamespace,
+ string $mcpServer,
+ string $mcpTool
+ ): string {
+ return self::getPathTemplate('mcpTool')->render([
+ 'project' => $project,
+ 'location' => $location,
+ 'api_namespace' => $apiNamespace,
+ 'mcp_server' => $mcpServer,
+ 'mcp_tool' => $mcpTool,
+ ]);
+ }
+
+ /**
+ * Formats a string containing the fully-qualified path to represent a
+ * project_location_api_namespace_mcp_server resource.
+ *
+ * @param string $project
+ * @param string $location
+ * @param string $apiNamespace
+ * @param string $mcpServer
+ *
+ * @return string The formatted project_location_api_namespace_mcp_server resource.
+ *
+ * @experimental
+ */
+ public static function projectLocationApiNamespaceMcpServerName(
+ string $project,
+ string $location,
+ string $apiNamespace,
+ string $mcpServer
+ ): string {
+ return self::getPathTemplate('projectLocationApiNamespaceMcpServer')->render([
+ 'project' => $project,
+ 'location' => $location,
+ 'api_namespace' => $apiNamespace,
+ 'mcp_server' => $mcpServer,
+ ]);
+ }
+
+ /**
+ * Formats a string containing the fully-qualified path to represent a
+ * project_location_api_namespace_mcp_server_mcp_tool resource.
+ *
+ * @param string $project
+ * @param string $location
+ * @param string $apiNamespace
+ * @param string $mcpServer
+ * @param string $mcpTool
+ *
+ * @return string The formatted project_location_api_namespace_mcp_server_mcp_tool resource.
+ *
+ * @experimental
+ */
+ public static function projectLocationApiNamespaceMcpServerMcpToolName(
+ string $project,
+ string $location,
+ string $apiNamespace,
+ string $mcpServer,
+ string $mcpTool
+ ): string {
+ return self::getPathTemplate('projectLocationApiNamespaceMcpServerMcpTool')->render([
+ 'project' => $project,
+ 'location' => $location,
+ 'api_namespace' => $apiNamespace,
+ 'mcp_server' => $mcpServer,
+ 'mcp_tool' => $mcpTool,
+ ]);
+ }
+
+ /**
+ * Formats a string containing the fully-qualified path to represent a
+ * project_location_mcp_server resource.
+ *
+ * @param string $project
+ * @param string $location
+ * @param string $mcpServer
+ *
+ * @return string The formatted project_location_mcp_server resource.
+ *
+ * @experimental
+ */
+ public static function projectLocationMcpServerName(string $project, string $location, string $mcpServer): string
+ {
+ return self::getPathTemplate('projectLocationMcpServer')->render([
+ 'project' => $project,
+ 'location' => $location,
+ 'mcp_server' => $mcpServer,
+ ]);
+ }
+
+ /**
+ * Formats a string containing the fully-qualified path to represent a
+ * project_location_mcp_server_mcp_tool resource.
+ *
+ * @param string $project
+ * @param string $location
+ * @param string $mcpServer
+ * @param string $mcpTool
+ *
+ * @return string The formatted project_location_mcp_server_mcp_tool resource.
+ *
+ * @experimental
+ */
+ public static function projectLocationMcpServerMcpToolName(
+ string $project,
+ string $location,
+ string $mcpServer,
+ string $mcpTool
+ ): string {
+ return self::getPathTemplate('projectLocationMcpServerMcpTool')->render([
+ 'project' => $project,
+ 'location' => $location,
+ 'mcp_server' => $mcpServer,
+ 'mcp_tool' => $mcpTool,
+ ]);
+ }
+
+ /**
+ * Parses a formatted name string and returns an associative array of the components in the name.
+ * The following name formats are supported:
+ * Template: Pattern
+ * - location: projects/{project}/locations/{location}
+ * - mcpServer: projects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}
+ * - mcpTool: projects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}
+ * - projectLocationApiNamespaceMcpServer: projects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}
+ * - projectLocationApiNamespaceMcpServerMcpTool: projects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}
+ * - projectLocationMcpServer: projects/{project}/locations/{location}/mcpServers/{mcp_server}
+ * - projectLocationMcpServerMcpTool: projects/{project}/locations/{location}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}
+ *
+ * The optional $template argument can be supplied to specify a particular pattern,
+ * and must match one of the templates listed above. If no $template argument is
+ * provided, or if the $template argument does not match one of the templates
+ * listed, then parseName will check each of the supported templates, and return
+ * the first match.
+ *
+ * @param string $formattedName The formatted name string
+ * @param ?string $template Optional name of template to match
+ *
+ * @return array An associative array from name component IDs to component values.
+ *
+ * @throws ValidationException If $formattedName could not be matched.
+ *
+ * @experimental
+ */
+ public static function parseName(string $formattedName, ?string $template = null): array
+ {
+ return self::parseFormattedName($formattedName, $template);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param array|ClientOptions $options {
+ * Optional. Options for configuring the service API wrapper.
+ *
+ * @type string $apiEndpoint
+ * The address of the API remote host. May optionally include the port, formatted
+ * as ":". Default 'cloudapiregistry.googleapis.com:443'.
+ * @type FetchAuthTokenInterface|CredentialsWrapper $credentials
+ * This option should only be used with a pre-constructed
+ * {@see FetchAuthTokenInterface} or {@see CredentialsWrapper} object. Note that
+ * when one of these objects are provided, any settings in $credentialsConfig will
+ * be ignored.
+ * **Important**: If you are providing a path to a credentials file, or a decoded
+ * credentials file as a PHP array, this usage is now DEPRECATED. Providing an
+ * unvalidated credential configuration to Google APIs can compromise the security
+ * of your systems and data. It is recommended to create the credentials explicitly
+ * ```
+ * use Google\Auth\Credentials\ServiceAccountCredentials;
+ * use Google\Cloud\ApiRegistry\V1beta\CloudApiRegistryClient;
+ * $creds = new ServiceAccountCredentials($scopes, $json);
+ * $options = new CloudApiRegistryClient(['credentials' => $creds]);
+ * ```
+ * {@see
+ * https://cloud.google.com/docs/authentication/external/externally-sourced-credentials}
+ * @type array $credentialsConfig
+ * Options used to configure credentials, including auth token caching, for the
+ * client. For a full list of supporting configuration options, see
+ * {@see \Google\ApiCore\CredentialsWrapper::build()} .
+ * @type bool $disableRetries
+ * Determines whether or not retries defined by the client configuration should be
+ * disabled. Defaults to `false`.
+ * @type string|array $clientConfig
+ * Client method configuration, including retry settings. This option can be either
+ * a path to a JSON file, or a PHP array containing the decoded JSON data. By
+ * default this settings points to the default client config file, which is
+ * provided in the resources folder.
+ * @type string|TransportInterface $transport
+ * The transport used for executing network requests. May be either the string
+ * `rest` or `grpc`. Defaults to `grpc` if gRPC support is detected on the system.
+ * *Advanced usage*: Additionally, it is possible to pass in an already
+ * instantiated {@see \Google\ApiCore\Transport\TransportInterface} object. Note
+ * that when this object is provided, any settings in $transportConfig, and any
+ * $apiEndpoint setting, will be ignored.
+ * @type array $transportConfig
+ * Configuration options that will be used to construct the transport. Options for
+ * each supported transport type should be passed in a key for that transport. For
+ * example:
+ * $transportConfig = [
+ * 'grpc' => [...],
+ * 'rest' => [...],
+ * ];
+ * See the {@see \Google\ApiCore\Transport\GrpcTransport::build()} and
+ * {@see \Google\ApiCore\Transport\RestTransport::build()} methods for the
+ * supported options.
+ * @type callable $clientCertSource
+ * A callable which returns the client cert as a string. This can be used to
+ * provide a certificate and private key to the transport layer for mTLS.
+ * @type false|LoggerInterface $logger
+ * A PSR-3 compliant logger. If set to false, logging is disabled, ignoring the
+ * 'GOOGLE_SDK_PHP_LOGGING' environment flag
+ * @type string $universeDomain
+ * The service domain for the client. Defaults to 'googleapis.com'.
+ * }
+ *
+ * @throws ValidationException
+ *
+ * @experimental
+ */
+ public function __construct(array|ClientOptions $options = [])
+ {
+ $clientOptions = $this->buildClientOptions($options);
+ $this->setClientOptions($clientOptions);
+ }
+
+ /** Handles execution of the async variants for each documented method. */
+ public function __call($method, $args)
+ {
+ if (substr($method, -5) !== 'Async') {
+ trigger_error('Call to undefined method ' . __CLASS__ . "::$method()", E_USER_ERROR);
+ }
+
+ array_unshift($args, substr($method, 0, -5));
+ return call_user_func_array([$this, 'startAsyncCall'], $args);
+ }
+
+ /**
+ * Gets a single McpServer.
+ *
+ * The async variant is {@see CloudApiRegistryClient::getMcpServerAsync()} .
+ *
+ * @example samples/V1beta/CloudApiRegistryClient/get_mcp_server.php
+ *
+ * @param GetMcpServerRequest $request A request to house fields associated with the call.
+ * @param array $callOptions {
+ * Optional.
+ *
+ * @type RetrySettings|array $retrySettings
+ * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
+ * associative array of retry settings parameters. See the documentation on
+ * {@see RetrySettings} for example usage.
+ * }
+ *
+ * @return McpServer
+ *
+ * @throws ApiException Thrown if the API call fails.
+ *
+ * @experimental
+ */
+ public function getMcpServer(GetMcpServerRequest $request, array $callOptions = []): McpServer
+ {
+ return $this->startApiCall('GetMcpServer', $request, $callOptions)->wait();
+ }
+
+ /**
+ * Gets a single McpTool.
+ *
+ * The async variant is {@see CloudApiRegistryClient::getMcpToolAsync()} .
+ *
+ * @example samples/V1beta/CloudApiRegistryClient/get_mcp_tool.php
+ *
+ * @param GetMcpToolRequest $request A request to house fields associated with the call.
+ * @param array $callOptions {
+ * Optional.
+ *
+ * @type RetrySettings|array $retrySettings
+ * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
+ * associative array of retry settings parameters. See the documentation on
+ * {@see RetrySettings} for example usage.
+ * }
+ *
+ * @return McpTool
+ *
+ * @throws ApiException Thrown if the API call fails.
+ *
+ * @experimental
+ */
+ public function getMcpTool(GetMcpToolRequest $request, array $callOptions = []): McpTool
+ {
+ return $this->startApiCall('GetMcpTool', $request, $callOptions)->wait();
+ }
+
+ /**
+ * Lists McpServers in a given Project.
+ *
+ * The async variant is {@see CloudApiRegistryClient::listMcpServersAsync()} .
+ *
+ * @example samples/V1beta/CloudApiRegistryClient/list_mcp_servers.php
+ *
+ * @param ListMcpServersRequest $request A request to house fields associated with the call.
+ * @param array $callOptions {
+ * Optional.
+ *
+ * @type RetrySettings|array $retrySettings
+ * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
+ * associative array of retry settings parameters. See the documentation on
+ * {@see RetrySettings} for example usage.
+ * }
+ *
+ * @return PagedListResponse
+ *
+ * @throws ApiException Thrown if the API call fails.
+ *
+ * @experimental
+ */
+ public function listMcpServers(ListMcpServersRequest $request, array $callOptions = []): PagedListResponse
+ {
+ return $this->startApiCall('ListMcpServers', $request, $callOptions);
+ }
+
+ /**
+ * Lists McpTools in a given McpServer.
+ *
+ * The async variant is {@see CloudApiRegistryClient::listMcpToolsAsync()} .
+ *
+ * @example samples/V1beta/CloudApiRegistryClient/list_mcp_tools.php
+ *
+ * @param ListMcpToolsRequest $request A request to house fields associated with the call.
+ * @param array $callOptions {
+ * Optional.
+ *
+ * @type RetrySettings|array $retrySettings
+ * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
+ * associative array of retry settings parameters. See the documentation on
+ * {@see RetrySettings} for example usage.
+ * }
+ *
+ * @return PagedListResponse
+ *
+ * @throws ApiException Thrown if the API call fails.
+ *
+ * @experimental
+ */
+ public function listMcpTools(ListMcpToolsRequest $request, array $callOptions = []): PagedListResponse
+ {
+ return $this->startApiCall('ListMcpTools', $request, $callOptions);
+ }
+
+ /**
+ * Gets information about a location.
+ *
+ * The async variant is {@see CloudApiRegistryClient::getLocationAsync()} .
+ *
+ * @example samples/V1beta/CloudApiRegistryClient/get_location.php
+ *
+ * @param GetLocationRequest $request A request to house fields associated with the call.
+ * @param array $callOptions {
+ * Optional.
+ *
+ * @type RetrySettings|array $retrySettings
+ * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
+ * associative array of retry settings parameters. See the documentation on
+ * {@see RetrySettings} for example usage.
+ * }
+ *
+ * @return Location
+ *
+ * @throws ApiException Thrown if the API call fails.
+ *
+ * @experimental
+ */
+ public function getLocation(GetLocationRequest $request, array $callOptions = []): Location
+ {
+ return $this->startApiCall('GetLocation', $request, $callOptions)->wait();
+ }
+
+ /**
+ * Lists information about the supported locations for this service.
+ *
+ * The async variant is {@see CloudApiRegistryClient::listLocationsAsync()} .
+ *
+ * @example samples/V1beta/CloudApiRegistryClient/list_locations.php
+ *
+ * @param ListLocationsRequest $request A request to house fields associated with the call.
+ * @param array $callOptions {
+ * Optional.
+ *
+ * @type RetrySettings|array $retrySettings
+ * Retry settings to use for this call. Can be a {@see RetrySettings} object, or an
+ * associative array of retry settings parameters. See the documentation on
+ * {@see RetrySettings} for example usage.
+ * }
+ *
+ * @return PagedListResponse
+ *
+ * @throws ApiException Thrown if the API call fails.
+ *
+ * @experimental
+ */
+ public function listLocations(ListLocationsRequest $request, array $callOptions = []): PagedListResponse
+ {
+ return $this->startApiCall('ListLocations', $request, $callOptions);
+ }
+}
diff --git a/ApiRegistry/src/V1beta/GetMcpServerRequest.php b/ApiRegistry/src/V1beta/GetMcpServerRequest.php
new file mode 100644
index 00000000000..3554a237fd4
--- /dev/null
+++ b/ApiRegistry/src/V1beta/GetMcpServerRequest.php
@@ -0,0 +1,81 @@
+google.cloud.apiregistry.v1beta.GetMcpServerRequest
+ */
+class GetMcpServerRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Required. Name of the resource
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ */
+ protected $name = '';
+
+ /**
+ * @param string $name Required. Name of the resource
+ * Please see {@see CloudApiRegistryClient::mcpServerName()} for help formatting this field.
+ *
+ * @return \Google\Cloud\ApiRegistry\V1beta\GetMcpServerRequest
+ *
+ * @experimental
+ */
+ public static function build(string $name): self
+ {
+ return (new self())
+ ->setName($name);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $name
+ * Required. Name of the resource
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Cloud\Apiregistry\V1Beta\Service::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Required. Name of the resource
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Required. Name of the resource
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ * @param string $var
+ * @return $this
+ */
+ public function setName($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->name = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/ApiRegistry/src/V1beta/GetMcpToolRequest.php b/ApiRegistry/src/V1beta/GetMcpToolRequest.php
new file mode 100644
index 00000000000..3b1e287bba7
--- /dev/null
+++ b/ApiRegistry/src/V1beta/GetMcpToolRequest.php
@@ -0,0 +1,81 @@
+google.cloud.apiregistry.v1beta.GetMcpToolRequest
+ */
+class GetMcpToolRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Required. Name of the resource
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ */
+ protected $name = '';
+
+ /**
+ * @param string $name Required. Name of the resource
+ * Please see {@see CloudApiRegistryClient::mcpToolName()} for help formatting this field.
+ *
+ * @return \Google\Cloud\ApiRegistry\V1beta\GetMcpToolRequest
+ *
+ * @experimental
+ */
+ public static function build(string $name): self
+ {
+ return (new self())
+ ->setName($name);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $name
+ * Required. Name of the resource
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Cloud\Apiregistry\V1Beta\Service::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Required. Name of the resource
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Required. Name of the resource
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ * @param string $var
+ * @return $this
+ */
+ public function setName($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->name = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/ApiRegistry/src/V1beta/ListMcpServersRequest.php b/ApiRegistry/src/V1beta/ListMcpServersRequest.php
new file mode 100644
index 00000000000..3fe7739eb1a
--- /dev/null
+++ b/ApiRegistry/src/V1beta/ListMcpServersRequest.php
@@ -0,0 +1,221 @@
+google.cloud.apiregistry.v1beta.ListMcpServersRequest
+ */
+class ListMcpServersRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Required. Parent value for ListMcpServersRequest
+ *
+ * Generated from protobuf field string parent = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ */
+ protected $parent = '';
+ /**
+ * Optional. Requested page size. Server may return fewer items than
+ * requested. If unspecified, server will pick an appropriate default.
+ *
+ * Generated from protobuf field int32 page_size = 2 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $page_size = 0;
+ /**
+ * Optional. A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string page_token = 3 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $page_token = '';
+ /**
+ * Optional. Filtering results
+ *
+ * Generated from protobuf field string filter = 4 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $filter = '';
+ /**
+ * Optional. Hint for how to order the results
+ *
+ * Generated from protobuf field string order_by = 5 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $order_by = '';
+
+ /**
+ * @param string $parent Required. Parent value for ListMcpServersRequest
+ * Please see {@see CloudApiRegistryClient::locationName()} for help formatting this field.
+ *
+ * @return \Google\Cloud\ApiRegistry\V1beta\ListMcpServersRequest
+ *
+ * @experimental
+ */
+ public static function build(string $parent): self
+ {
+ return (new self())
+ ->setParent($parent);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $parent
+ * Required. Parent value for ListMcpServersRequest
+ * @type int $page_size
+ * Optional. Requested page size. Server may return fewer items than
+ * requested. If unspecified, server will pick an appropriate default.
+ * @type string $page_token
+ * Optional. A token identifying a page of results the server should return.
+ * @type string $filter
+ * Optional. Filtering results
+ * @type string $order_by
+ * Optional. Hint for how to order the results
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Cloud\Apiregistry\V1Beta\Service::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Required. Parent value for ListMcpServersRequest
+ *
+ * Generated from protobuf field string parent = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ * @return string
+ */
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Required. Parent value for ListMcpServersRequest
+ *
+ * Generated from protobuf field string parent = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ * @param string $var
+ * @return $this
+ */
+ public function setParent($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->parent = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. Requested page size. Server may return fewer items than
+ * requested. If unspecified, server will pick an appropriate default.
+ *
+ * Generated from protobuf field int32 page_size = 2 [(.google.api.field_behavior) = OPTIONAL];
+ * @return int
+ */
+ public function getPageSize()
+ {
+ return $this->page_size;
+ }
+
+ /**
+ * Optional. Requested page size. Server may return fewer items than
+ * requested. If unspecified, server will pick an appropriate default.
+ *
+ * Generated from protobuf field int32 page_size = 2 [(.google.api.field_behavior) = OPTIONAL];
+ * @param int $var
+ * @return $this
+ */
+ public function setPageSize($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->page_size = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string page_token = 3 [(.google.api.field_behavior) = OPTIONAL];
+ * @return string
+ */
+ public function getPageToken()
+ {
+ return $this->page_token;
+ }
+
+ /**
+ * Optional. A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string page_token = 3 [(.google.api.field_behavior) = OPTIONAL];
+ * @param string $var
+ * @return $this
+ */
+ public function setPageToken($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->page_token = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. Filtering results
+ *
+ * Generated from protobuf field string filter = 4 [(.google.api.field_behavior) = OPTIONAL];
+ * @return string
+ */
+ public function getFilter()
+ {
+ return $this->filter;
+ }
+
+ /**
+ * Optional. Filtering results
+ *
+ * Generated from protobuf field string filter = 4 [(.google.api.field_behavior) = OPTIONAL];
+ * @param string $var
+ * @return $this
+ */
+ public function setFilter($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->filter = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. Hint for how to order the results
+ *
+ * Generated from protobuf field string order_by = 5 [(.google.api.field_behavior) = OPTIONAL];
+ * @return string
+ */
+ public function getOrderBy()
+ {
+ return $this->order_by;
+ }
+
+ /**
+ * Optional. Hint for how to order the results
+ *
+ * Generated from protobuf field string order_by = 5 [(.google.api.field_behavior) = OPTIONAL];
+ * @param string $var
+ * @return $this
+ */
+ public function setOrderBy($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->order_by = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/ApiRegistry/src/V1beta/ListMcpServersResponse.php b/ApiRegistry/src/V1beta/ListMcpServersResponse.php
new file mode 100644
index 00000000000..199d83efcf3
--- /dev/null
+++ b/ApiRegistry/src/V1beta/ListMcpServersResponse.php
@@ -0,0 +1,135 @@
+google.cloud.apiregistry.v1beta.ListMcpServersResponse
+ */
+class ListMcpServersResponse extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The list of McpServer
+ *
+ * Generated from protobuf field repeated .google.cloud.apiregistry.v1beta.McpServer mcp_servers = 1;
+ */
+ private $mcp_servers;
+ /**
+ * A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string next_page_token = 2;
+ */
+ protected $next_page_token = '';
+ /**
+ * Locations that could not be reached.
+ *
+ * Generated from protobuf field repeated string unreachable = 3;
+ */
+ private $unreachable;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type array<\Google\Cloud\ApiRegistry\V1beta\McpServer>|\Google\Protobuf\Internal\RepeatedField $mcp_servers
+ * The list of McpServer
+ * @type string $next_page_token
+ * A token identifying a page of results the server should return.
+ * @type array|\Google\Protobuf\Internal\RepeatedField $unreachable
+ * Locations that could not be reached.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Cloud\Apiregistry\V1Beta\Service::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The list of McpServer
+ *
+ * Generated from protobuf field repeated .google.cloud.apiregistry.v1beta.McpServer mcp_servers = 1;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getMcpServers()
+ {
+ return $this->mcp_servers;
+ }
+
+ /**
+ * The list of McpServer
+ *
+ * Generated from protobuf field repeated .google.cloud.apiregistry.v1beta.McpServer mcp_servers = 1;
+ * @param array<\Google\Cloud\ApiRegistry\V1beta\McpServer>|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setMcpServers($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\ApiRegistry\V1beta\McpServer::class);
+ $this->mcp_servers = $arr;
+
+ return $this;
+ }
+
+ /**
+ * A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string next_page_token = 2;
+ * @return string
+ */
+ public function getNextPageToken()
+ {
+ return $this->next_page_token;
+ }
+
+ /**
+ * A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string next_page_token = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setNextPageToken($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->next_page_token = $var;
+
+ return $this;
+ }
+
+ /**
+ * Locations that could not be reached.
+ *
+ * Generated from protobuf field repeated string unreachable = 3;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getUnreachable()
+ {
+ return $this->unreachable;
+ }
+
+ /**
+ * Locations that could not be reached.
+ *
+ * Generated from protobuf field repeated string unreachable = 3;
+ * @param array|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setUnreachable($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
+ $this->unreachable = $arr;
+
+ return $this;
+ }
+
+}
+
diff --git a/ApiRegistry/src/V1beta/ListMcpToolsRequest.php b/ApiRegistry/src/V1beta/ListMcpToolsRequest.php
new file mode 100644
index 00000000000..da991332bfc
--- /dev/null
+++ b/ApiRegistry/src/V1beta/ListMcpToolsRequest.php
@@ -0,0 +1,221 @@
+google.cloud.apiregistry.v1beta.ListMcpToolsRequest
+ */
+class ListMcpToolsRequest extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Required. Parent value for ListMcpToolsRequest
+ *
+ * Generated from protobuf field string parent = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ */
+ protected $parent = '';
+ /**
+ * Optional. Requested page size. Server may return fewer items than
+ * requested. If unspecified, server will pick an appropriate default.
+ *
+ * Generated from protobuf field int32 page_size = 2 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $page_size = 0;
+ /**
+ * Optional. A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string page_token = 3 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $page_token = '';
+ /**
+ * Optional. Filtering results
+ *
+ * Generated from protobuf field string filter = 4 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $filter = '';
+ /**
+ * Optional. Hint for how to order the results
+ *
+ * Generated from protobuf field string order_by = 5 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $order_by = '';
+
+ /**
+ * @param string $parent Required. Parent value for ListMcpToolsRequest
+ * Please see {@see CloudApiRegistryClient::mcpServerName()} for help formatting this field.
+ *
+ * @return \Google\Cloud\ApiRegistry\V1beta\ListMcpToolsRequest
+ *
+ * @experimental
+ */
+ public static function build(string $parent): self
+ {
+ return (new self())
+ ->setParent($parent);
+ }
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $parent
+ * Required. Parent value for ListMcpToolsRequest
+ * @type int $page_size
+ * Optional. Requested page size. Server may return fewer items than
+ * requested. If unspecified, server will pick an appropriate default.
+ * @type string $page_token
+ * Optional. A token identifying a page of results the server should return.
+ * @type string $filter
+ * Optional. Filtering results
+ * @type string $order_by
+ * Optional. Hint for how to order the results
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Cloud\Apiregistry\V1Beta\Service::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Required. Parent value for ListMcpToolsRequest
+ *
+ * Generated from protobuf field string parent = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ * @return string
+ */
+ public function getParent()
+ {
+ return $this->parent;
+ }
+
+ /**
+ * Required. Parent value for ListMcpToolsRequest
+ *
+ * Generated from protobuf field string parent = 1 [(.google.api.field_behavior) = REQUIRED, (.google.api.resource_reference) = {
+ * @param string $var
+ * @return $this
+ */
+ public function setParent($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->parent = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. Requested page size. Server may return fewer items than
+ * requested. If unspecified, server will pick an appropriate default.
+ *
+ * Generated from protobuf field int32 page_size = 2 [(.google.api.field_behavior) = OPTIONAL];
+ * @return int
+ */
+ public function getPageSize()
+ {
+ return $this->page_size;
+ }
+
+ /**
+ * Optional. Requested page size. Server may return fewer items than
+ * requested. If unspecified, server will pick an appropriate default.
+ *
+ * Generated from protobuf field int32 page_size = 2 [(.google.api.field_behavior) = OPTIONAL];
+ * @param int $var
+ * @return $this
+ */
+ public function setPageSize($var)
+ {
+ GPBUtil::checkInt32($var);
+ $this->page_size = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string page_token = 3 [(.google.api.field_behavior) = OPTIONAL];
+ * @return string
+ */
+ public function getPageToken()
+ {
+ return $this->page_token;
+ }
+
+ /**
+ * Optional. A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string page_token = 3 [(.google.api.field_behavior) = OPTIONAL];
+ * @param string $var
+ * @return $this
+ */
+ public function setPageToken($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->page_token = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. Filtering results
+ *
+ * Generated from protobuf field string filter = 4 [(.google.api.field_behavior) = OPTIONAL];
+ * @return string
+ */
+ public function getFilter()
+ {
+ return $this->filter;
+ }
+
+ /**
+ * Optional. Filtering results
+ *
+ * Generated from protobuf field string filter = 4 [(.google.api.field_behavior) = OPTIONAL];
+ * @param string $var
+ * @return $this
+ */
+ public function setFilter($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->filter = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. Hint for how to order the results
+ *
+ * Generated from protobuf field string order_by = 5 [(.google.api.field_behavior) = OPTIONAL];
+ * @return string
+ */
+ public function getOrderBy()
+ {
+ return $this->order_by;
+ }
+
+ /**
+ * Optional. Hint for how to order the results
+ *
+ * Generated from protobuf field string order_by = 5 [(.google.api.field_behavior) = OPTIONAL];
+ * @param string $var
+ * @return $this
+ */
+ public function setOrderBy($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->order_by = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/ApiRegistry/src/V1beta/ListMcpToolsResponse.php b/ApiRegistry/src/V1beta/ListMcpToolsResponse.php
new file mode 100644
index 00000000000..3bb5a4a93d1
--- /dev/null
+++ b/ApiRegistry/src/V1beta/ListMcpToolsResponse.php
@@ -0,0 +1,135 @@
+google.cloud.apiregistry.v1beta.ListMcpToolsResponse
+ */
+class ListMcpToolsResponse extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * The list of McpTool
+ *
+ * Generated from protobuf field repeated .google.cloud.apiregistry.v1beta.McpTool mcp_tools = 1;
+ */
+ private $mcp_tools;
+ /**
+ * A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string next_page_token = 2;
+ */
+ protected $next_page_token = '';
+ /**
+ * Locations that could not be reached.
+ *
+ * Generated from protobuf field repeated string unreachable = 3;
+ */
+ private $unreachable;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type array<\Google\Cloud\ApiRegistry\V1beta\McpTool>|\Google\Protobuf\Internal\RepeatedField $mcp_tools
+ * The list of McpTool
+ * @type string $next_page_token
+ * A token identifying a page of results the server should return.
+ * @type array|\Google\Protobuf\Internal\RepeatedField $unreachable
+ * Locations that could not be reached.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Cloud\Apiregistry\V1Beta\Service::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * The list of McpTool
+ *
+ * Generated from protobuf field repeated .google.cloud.apiregistry.v1beta.McpTool mcp_tools = 1;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getMcpTools()
+ {
+ return $this->mcp_tools;
+ }
+
+ /**
+ * The list of McpTool
+ *
+ * Generated from protobuf field repeated .google.cloud.apiregistry.v1beta.McpTool mcp_tools = 1;
+ * @param array<\Google\Cloud\ApiRegistry\V1beta\McpTool>|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setMcpTools($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::MESSAGE, \Google\Cloud\ApiRegistry\V1beta\McpTool::class);
+ $this->mcp_tools = $arr;
+
+ return $this;
+ }
+
+ /**
+ * A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string next_page_token = 2;
+ * @return string
+ */
+ public function getNextPageToken()
+ {
+ return $this->next_page_token;
+ }
+
+ /**
+ * A token identifying a page of results the server should return.
+ *
+ * Generated from protobuf field string next_page_token = 2;
+ * @param string $var
+ * @return $this
+ */
+ public function setNextPageToken($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->next_page_token = $var;
+
+ return $this;
+ }
+
+ /**
+ * Locations that could not be reached.
+ *
+ * Generated from protobuf field repeated string unreachable = 3;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getUnreachable()
+ {
+ return $this->unreachable;
+ }
+
+ /**
+ * Locations that could not be reached.
+ *
+ * Generated from protobuf field repeated string unreachable = 3;
+ * @param array|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setUnreachable($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
+ $this->unreachable = $arr;
+
+ return $this;
+ }
+
+}
+
diff --git a/ApiRegistry/src/V1beta/McpServer.php b/ApiRegistry/src/V1beta/McpServer.php
new file mode 100644
index 00000000000..1aa3098331f
--- /dev/null
+++ b/ApiRegistry/src/V1beta/McpServer.php
@@ -0,0 +1,284 @@
+google.cloud.apiregistry.v1beta.McpServer
+ */
+class McpServer extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Identifier. The resource name of the MCP Server.
+ * Format:
+ * `projects/{project}/locations/{location}/mcpServers/{mcp_server}`.
+ * Example:
+ * projects/12345/locations/us-central1/mcpServers/google:bigquery.googleapis.com:mcp
+ * for 1p
+ * projects/12345/locations/us-central1/mcpServers/apphub:starbucks for
+ * 2p
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = IDENTIFIER];
+ */
+ protected $name = '';
+ /**
+ * Optional. A human readable name for the MCP server.
+ *
+ * Generated from protobuf field string display_name = 2 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $display_name = '';
+ /**
+ * Optional. A human-readable description of the MCP Server's functionality.
+ *
+ * Generated from protobuf field string description = 3 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $description = '';
+ /**
+ * The base URL of the MCP server. Example: [geolocation.googleapis.com/mcp].
+ *
+ * Generated from protobuf field repeated string urls = 4;
+ */
+ private $urls;
+ /**
+ * The capabilities that a server may support. Known capabilities defined in
+ * https://modelcontextprotocol.io/specification/2025-06-18/schema#servercapabilities
+ * and additional capabilities defined by the servers.
+ *
+ * Generated from protobuf field .google.protobuf.Struct capabilities = 6;
+ */
+ protected $capabilities = null;
+ /**
+ * Output only. The state of the MCP Server.
+ *
+ * Generated from protobuf field .google.cloud.apiregistry.v1beta.State state = 7 [(.google.api.field_behavior) = OUTPUT_ONLY];
+ */
+ protected $state = 0;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $name
+ * Identifier. The resource name of the MCP Server.
+ * Format:
+ * `projects/{project}/locations/{location}/mcpServers/{mcp_server}`.
+ * Example:
+ * projects/12345/locations/us-central1/mcpServers/google:bigquery.googleapis.com:mcp
+ * for 1p
+ * projects/12345/locations/us-central1/mcpServers/apphub:starbucks for
+ * 2p
+ * @type string $display_name
+ * Optional. A human readable name for the MCP server.
+ * @type string $description
+ * Optional. A human-readable description of the MCP Server's functionality.
+ * @type array|\Google\Protobuf\Internal\RepeatedField $urls
+ * The base URL of the MCP server. Example: [geolocation.googleapis.com/mcp].
+ * @type \Google\Protobuf\Struct $capabilities
+ * The capabilities that a server may support. Known capabilities defined in
+ * https://modelcontextprotocol.io/specification/2025-06-18/schema#servercapabilities
+ * and additional capabilities defined by the servers.
+ * @type int $state
+ * Output only. The state of the MCP Server.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Cloud\Apiregistry\V1Beta\Resources::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Identifier. The resource name of the MCP Server.
+ * Format:
+ * `projects/{project}/locations/{location}/mcpServers/{mcp_server}`.
+ * Example:
+ * projects/12345/locations/us-central1/mcpServers/google:bigquery.googleapis.com:mcp
+ * for 1p
+ * projects/12345/locations/us-central1/mcpServers/apphub:starbucks for
+ * 2p
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = IDENTIFIER];
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Identifier. The resource name of the MCP Server.
+ * Format:
+ * `projects/{project}/locations/{location}/mcpServers/{mcp_server}`.
+ * Example:
+ * projects/12345/locations/us-central1/mcpServers/google:bigquery.googleapis.com:mcp
+ * for 1p
+ * projects/12345/locations/us-central1/mcpServers/apphub:starbucks for
+ * 2p
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = IDENTIFIER];
+ * @param string $var
+ * @return $this
+ */
+ public function setName($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->name = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. A human readable name for the MCP server.
+ *
+ * Generated from protobuf field string display_name = 2 [(.google.api.field_behavior) = OPTIONAL];
+ * @return string
+ */
+ public function getDisplayName()
+ {
+ return $this->display_name;
+ }
+
+ /**
+ * Optional. A human readable name for the MCP server.
+ *
+ * Generated from protobuf field string display_name = 2 [(.google.api.field_behavior) = OPTIONAL];
+ * @param string $var
+ * @return $this
+ */
+ public function setDisplayName($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->display_name = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. A human-readable description of the MCP Server's functionality.
+ *
+ * Generated from protobuf field string description = 3 [(.google.api.field_behavior) = OPTIONAL];
+ * @return string
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * Optional. A human-readable description of the MCP Server's functionality.
+ *
+ * Generated from protobuf field string description = 3 [(.google.api.field_behavior) = OPTIONAL];
+ * @param string $var
+ * @return $this
+ */
+ public function setDescription($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->description = $var;
+
+ return $this;
+ }
+
+ /**
+ * The base URL of the MCP server. Example: [geolocation.googleapis.com/mcp].
+ *
+ * Generated from protobuf field repeated string urls = 4;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getUrls()
+ {
+ return $this->urls;
+ }
+
+ /**
+ * The base URL of the MCP server. Example: [geolocation.googleapis.com/mcp].
+ *
+ * Generated from protobuf field repeated string urls = 4;
+ * @param array|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setUrls($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
+ $this->urls = $arr;
+
+ return $this;
+ }
+
+ /**
+ * The capabilities that a server may support. Known capabilities defined in
+ * https://modelcontextprotocol.io/specification/2025-06-18/schema#servercapabilities
+ * and additional capabilities defined by the servers.
+ *
+ * Generated from protobuf field .google.protobuf.Struct capabilities = 6;
+ * @return \Google\Protobuf\Struct|null
+ */
+ public function getCapabilities()
+ {
+ return $this->capabilities;
+ }
+
+ public function hasCapabilities()
+ {
+ return isset($this->capabilities);
+ }
+
+ public function clearCapabilities()
+ {
+ unset($this->capabilities);
+ }
+
+ /**
+ * The capabilities that a server may support. Known capabilities defined in
+ * https://modelcontextprotocol.io/specification/2025-06-18/schema#servercapabilities
+ * and additional capabilities defined by the servers.
+ *
+ * Generated from protobuf field .google.protobuf.Struct capabilities = 6;
+ * @param \Google\Protobuf\Struct $var
+ * @return $this
+ */
+ public function setCapabilities($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
+ $this->capabilities = $var;
+
+ return $this;
+ }
+
+ /**
+ * Output only. The state of the MCP Server.
+ *
+ * Generated from protobuf field .google.cloud.apiregistry.v1beta.State state = 7 [(.google.api.field_behavior) = OUTPUT_ONLY];
+ * @return int
+ */
+ public function getState()
+ {
+ return $this->state;
+ }
+
+ /**
+ * Output only. The state of the MCP Server.
+ *
+ * Generated from protobuf field .google.cloud.apiregistry.v1beta.State state = 7 [(.google.api.field_behavior) = OUTPUT_ONLY];
+ * @param int $var
+ * @return $this
+ */
+ public function setState($var)
+ {
+ GPBUtil::checkEnum($var, \Google\Cloud\ApiRegistry\V1beta\State::class);
+ $this->state = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/ApiRegistry/src/V1beta/McpTool.php b/ApiRegistry/src/V1beta/McpTool.php
new file mode 100644
index 00000000000..481e3f26bca
--- /dev/null
+++ b/ApiRegistry/src/V1beta/McpTool.php
@@ -0,0 +1,401 @@
+google.cloud.apiregistry.v1beta.McpTool
+ */
+class McpTool extends \Google\Protobuf\Internal\Message
+{
+ /**
+ * Identifier. The resource name of the McpTool.
+ * Format:
+ * `projects/{project}/locations/{location}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}`.
+ * Example:
+ * projects/12345/locations/us-central1/mcpServers/google:bigquery.googleapis.com:mcp/mcpTools/insert_job
+ * for 1p
+ * projects/12345/locations/us-central1/mcpServers/apphub:starbucks/mcpTools/order_pizza
+ * for 2p
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = IDENTIFIER];
+ */
+ protected $name = '';
+ /**
+ * Optional. A human-readable name for the tool, suitable for display.
+ *
+ * Generated from protobuf field string display_name = 2 [(.google.api.field_behavior) = OPTIONAL];
+ */
+ protected $display_name = '';
+ /**
+ * A human-readable description of the tool's functionality.
+ *
+ * Generated from protobuf field string description = 3;
+ */
+ protected $description = '';
+ /**
+ * Automatically populated reference to MCP Server. Helpful when multiple
+ * tools are requested across different MCP Servers.
+ *
+ * Generated from protobuf field repeated string mcp_server_urls = 4;
+ */
+ private $mcp_server_urls;
+ /**
+ * A JSON Schema object defining the expected parameters for invoking the
+ * tool.
+ *
+ * Generated from protobuf field .google.protobuf.Struct input_schema = 5;
+ */
+ protected $input_schema = null;
+ /**
+ * Optional. A JSON Schema object defining the expected structure of the
+ * tool's output.
+ *
+ * Generated from protobuf field .google.protobuf.Struct output_schema = 6;
+ */
+ protected $output_schema = null;
+ /**
+ * Optional key-value object that allows developers to provide additional
+ * information regarding tool properties, behavior, and usage best practices.
+ * Annotations or tags to facilitate semantic search across tools ("semantic
+ * tags") are not in the MVP scope. When implemented, the first set of
+ * supported annotations will likely be the standard, predefined annotations
+ * from the open-source MCP spec. These include:
+ * - title: A human-readable title for the tool, useful for UI display.
+ * - readOnlyHint: If true, indicates the tool does not modify its
+ * environment.
+ * - destructiveHint: If true, the tool may perform destructive updates
+ * (only meaningful when readOnlyHint is false).
+ * - idempotentHint: If true, calling the tool repeatedly with the same
+ * arguments has no additional effect (only meaningful when readOnlyHint is
+ * false).
+ * - openWorldHint: If true, the tool may interact with an "open world" of
+ * external entities.
+ *
+ * Generated from protobuf field .google.protobuf.Struct annotations = 7;
+ */
+ protected $annotations = null;
+
+ /**
+ * Constructor.
+ *
+ * @param array $data {
+ * Optional. Data for populating the Message object.
+ *
+ * @type string $name
+ * Identifier. The resource name of the McpTool.
+ * Format:
+ * `projects/{project}/locations/{location}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}`.
+ * Example:
+ * projects/12345/locations/us-central1/mcpServers/google:bigquery.googleapis.com:mcp/mcpTools/insert_job
+ * for 1p
+ * projects/12345/locations/us-central1/mcpServers/apphub:starbucks/mcpTools/order_pizza
+ * for 2p
+ * @type string $display_name
+ * Optional. A human-readable name for the tool, suitable for display.
+ * @type string $description
+ * A human-readable description of the tool's functionality.
+ * @type array|\Google\Protobuf\Internal\RepeatedField $mcp_server_urls
+ * Automatically populated reference to MCP Server. Helpful when multiple
+ * tools are requested across different MCP Servers.
+ * @type \Google\Protobuf\Struct $input_schema
+ * A JSON Schema object defining the expected parameters for invoking the
+ * tool.
+ * @type \Google\Protobuf\Struct $output_schema
+ * Optional. A JSON Schema object defining the expected structure of the
+ * tool's output.
+ * @type \Google\Protobuf\Struct $annotations
+ * Optional key-value object that allows developers to provide additional
+ * information regarding tool properties, behavior, and usage best practices.
+ * Annotations or tags to facilitate semantic search across tools ("semantic
+ * tags") are not in the MVP scope. When implemented, the first set of
+ * supported annotations will likely be the standard, predefined annotations
+ * from the open-source MCP spec. These include:
+ * - title: A human-readable title for the tool, useful for UI display.
+ * - readOnlyHint: If true, indicates the tool does not modify its
+ * environment.
+ * - destructiveHint: If true, the tool may perform destructive updates
+ * (only meaningful when readOnlyHint is false).
+ * - idempotentHint: If true, calling the tool repeatedly with the same
+ * arguments has no additional effect (only meaningful when readOnlyHint is
+ * false).
+ * - openWorldHint: If true, the tool may interact with an "open world" of
+ * external entities.
+ * }
+ */
+ public function __construct($data = NULL) {
+ \GPBMetadata\Google\Cloud\Apiregistry\V1Beta\Resources::initOnce();
+ parent::__construct($data);
+ }
+
+ /**
+ * Identifier. The resource name of the McpTool.
+ * Format:
+ * `projects/{project}/locations/{location}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}`.
+ * Example:
+ * projects/12345/locations/us-central1/mcpServers/google:bigquery.googleapis.com:mcp/mcpTools/insert_job
+ * for 1p
+ * projects/12345/locations/us-central1/mcpServers/apphub:starbucks/mcpTools/order_pizza
+ * for 2p
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = IDENTIFIER];
+ * @return string
+ */
+ public function getName()
+ {
+ return $this->name;
+ }
+
+ /**
+ * Identifier. The resource name of the McpTool.
+ * Format:
+ * `projects/{project}/locations/{location}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}`.
+ * Example:
+ * projects/12345/locations/us-central1/mcpServers/google:bigquery.googleapis.com:mcp/mcpTools/insert_job
+ * for 1p
+ * projects/12345/locations/us-central1/mcpServers/apphub:starbucks/mcpTools/order_pizza
+ * for 2p
+ *
+ * Generated from protobuf field string name = 1 [(.google.api.field_behavior) = IDENTIFIER];
+ * @param string $var
+ * @return $this
+ */
+ public function setName($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->name = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. A human-readable name for the tool, suitable for display.
+ *
+ * Generated from protobuf field string display_name = 2 [(.google.api.field_behavior) = OPTIONAL];
+ * @return string
+ */
+ public function getDisplayName()
+ {
+ return $this->display_name;
+ }
+
+ /**
+ * Optional. A human-readable name for the tool, suitable for display.
+ *
+ * Generated from protobuf field string display_name = 2 [(.google.api.field_behavior) = OPTIONAL];
+ * @param string $var
+ * @return $this
+ */
+ public function setDisplayName($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->display_name = $var;
+
+ return $this;
+ }
+
+ /**
+ * A human-readable description of the tool's functionality.
+ *
+ * Generated from protobuf field string description = 3;
+ * @return string
+ */
+ public function getDescription()
+ {
+ return $this->description;
+ }
+
+ /**
+ * A human-readable description of the tool's functionality.
+ *
+ * Generated from protobuf field string description = 3;
+ * @param string $var
+ * @return $this
+ */
+ public function setDescription($var)
+ {
+ GPBUtil::checkString($var, True);
+ $this->description = $var;
+
+ return $this;
+ }
+
+ /**
+ * Automatically populated reference to MCP Server. Helpful when multiple
+ * tools are requested across different MCP Servers.
+ *
+ * Generated from protobuf field repeated string mcp_server_urls = 4;
+ * @return \Google\Protobuf\Internal\RepeatedField
+ */
+ public function getMcpServerUrls()
+ {
+ return $this->mcp_server_urls;
+ }
+
+ /**
+ * Automatically populated reference to MCP Server. Helpful when multiple
+ * tools are requested across different MCP Servers.
+ *
+ * Generated from protobuf field repeated string mcp_server_urls = 4;
+ * @param array|\Google\Protobuf\Internal\RepeatedField $var
+ * @return $this
+ */
+ public function setMcpServerUrls($var)
+ {
+ $arr = GPBUtil::checkRepeatedField($var, \Google\Protobuf\Internal\GPBType::STRING);
+ $this->mcp_server_urls = $arr;
+
+ return $this;
+ }
+
+ /**
+ * A JSON Schema object defining the expected parameters for invoking the
+ * tool.
+ *
+ * Generated from protobuf field .google.protobuf.Struct input_schema = 5;
+ * @return \Google\Protobuf\Struct|null
+ */
+ public function getInputSchema()
+ {
+ return $this->input_schema;
+ }
+
+ public function hasInputSchema()
+ {
+ return isset($this->input_schema);
+ }
+
+ public function clearInputSchema()
+ {
+ unset($this->input_schema);
+ }
+
+ /**
+ * A JSON Schema object defining the expected parameters for invoking the
+ * tool.
+ *
+ * Generated from protobuf field .google.protobuf.Struct input_schema = 5;
+ * @param \Google\Protobuf\Struct $var
+ * @return $this
+ */
+ public function setInputSchema($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
+ $this->input_schema = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional. A JSON Schema object defining the expected structure of the
+ * tool's output.
+ *
+ * Generated from protobuf field .google.protobuf.Struct output_schema = 6;
+ * @return \Google\Protobuf\Struct|null
+ */
+ public function getOutputSchema()
+ {
+ return $this->output_schema;
+ }
+
+ public function hasOutputSchema()
+ {
+ return isset($this->output_schema);
+ }
+
+ public function clearOutputSchema()
+ {
+ unset($this->output_schema);
+ }
+
+ /**
+ * Optional. A JSON Schema object defining the expected structure of the
+ * tool's output.
+ *
+ * Generated from protobuf field .google.protobuf.Struct output_schema = 6;
+ * @param \Google\Protobuf\Struct $var
+ * @return $this
+ */
+ public function setOutputSchema($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
+ $this->output_schema = $var;
+
+ return $this;
+ }
+
+ /**
+ * Optional key-value object that allows developers to provide additional
+ * information regarding tool properties, behavior, and usage best practices.
+ * Annotations or tags to facilitate semantic search across tools ("semantic
+ * tags") are not in the MVP scope. When implemented, the first set of
+ * supported annotations will likely be the standard, predefined annotations
+ * from the open-source MCP spec. These include:
+ * - title: A human-readable title for the tool, useful for UI display.
+ * - readOnlyHint: If true, indicates the tool does not modify its
+ * environment.
+ * - destructiveHint: If true, the tool may perform destructive updates
+ * (only meaningful when readOnlyHint is false).
+ * - idempotentHint: If true, calling the tool repeatedly with the same
+ * arguments has no additional effect (only meaningful when readOnlyHint is
+ * false).
+ * - openWorldHint: If true, the tool may interact with an "open world" of
+ * external entities.
+ *
+ * Generated from protobuf field .google.protobuf.Struct annotations = 7;
+ * @return \Google\Protobuf\Struct|null
+ */
+ public function getAnnotations()
+ {
+ return $this->annotations;
+ }
+
+ public function hasAnnotations()
+ {
+ return isset($this->annotations);
+ }
+
+ public function clearAnnotations()
+ {
+ unset($this->annotations);
+ }
+
+ /**
+ * Optional key-value object that allows developers to provide additional
+ * information regarding tool properties, behavior, and usage best practices.
+ * Annotations or tags to facilitate semantic search across tools ("semantic
+ * tags") are not in the MVP scope. When implemented, the first set of
+ * supported annotations will likely be the standard, predefined annotations
+ * from the open-source MCP spec. These include:
+ * - title: A human-readable title for the tool, useful for UI display.
+ * - readOnlyHint: If true, indicates the tool does not modify its
+ * environment.
+ * - destructiveHint: If true, the tool may perform destructive updates
+ * (only meaningful when readOnlyHint is false).
+ * - idempotentHint: If true, calling the tool repeatedly with the same
+ * arguments has no additional effect (only meaningful when readOnlyHint is
+ * false).
+ * - openWorldHint: If true, the tool may interact with an "open world" of
+ * external entities.
+ *
+ * Generated from protobuf field .google.protobuf.Struct annotations = 7;
+ * @param \Google\Protobuf\Struct $var
+ * @return $this
+ */
+ public function setAnnotations($var)
+ {
+ GPBUtil::checkMessage($var, \Google\Protobuf\Struct::class);
+ $this->annotations = $var;
+
+ return $this;
+ }
+
+}
+
diff --git a/ApiRegistry/src/V1beta/State.php b/ApiRegistry/src/V1beta/State.php
new file mode 100644
index 00000000000..30d6863bcc2
--- /dev/null
+++ b/ApiRegistry/src/V1beta/State.php
@@ -0,0 +1,61 @@
+google.cloud.apiregistry.v1beta.State
+ */
+class State
+{
+ /**
+ * The McpServer state is unspecified.
+ *
+ * Generated from protobuf enum STATE_UNSPECIFIED = 0;
+ */
+ const STATE_UNSPECIFIED = 0;
+ /**
+ * The McpServer is enabled.
+ *
+ * Generated from protobuf enum ENABLED = 1;
+ */
+ const ENABLED = 1;
+ /**
+ * The McpServer is disabled.
+ *
+ * Generated from protobuf enum DISABLED = 2;
+ */
+ const DISABLED = 2;
+
+ private static $valueToName = [
+ self::STATE_UNSPECIFIED => 'STATE_UNSPECIFIED',
+ self::ENABLED => 'ENABLED',
+ self::DISABLED => 'DISABLED',
+ ];
+
+ public static function name($value)
+ {
+ if (!isset(self::$valueToName[$value])) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no name defined for value %s', __CLASS__, $value));
+ }
+ return self::$valueToName[$value];
+ }
+
+
+ public static function value($name)
+ {
+ $const = __CLASS__ . '::' . strtoupper($name);
+ if (!defined($const)) {
+ throw new UnexpectedValueException(sprintf(
+ 'Enum %s has no value defined for name %s', __CLASS__, $name));
+ }
+ return constant($const);
+ }
+}
+
diff --git a/ApiRegistry/src/V1beta/gapic_metadata.json b/ApiRegistry/src/V1beta/gapic_metadata.json
new file mode 100644
index 00000000000..766c6e246ee
--- /dev/null
+++ b/ApiRegistry/src/V1beta/gapic_metadata.json
@@ -0,0 +1,48 @@
+{
+ "schema": "1.0",
+ "comment": "This file maps proto services\/RPCs to the corresponding library clients\/methods",
+ "language": "php",
+ "protoPackage": "google.cloud.apiregistry.v1beta",
+ "libraryPackage": "Google\\Cloud\\ApiRegistry\\V1beta",
+ "services": {
+ "CloudApiRegistry": {
+ "clients": {
+ "grpc": {
+ "libraryClient": "CloudApiRegistryGapicClient",
+ "rpcs": {
+ "GetMcpServer": {
+ "methods": [
+ "getMcpServer"
+ ]
+ },
+ "GetMcpTool": {
+ "methods": [
+ "getMcpTool"
+ ]
+ },
+ "ListMcpServers": {
+ "methods": [
+ "listMcpServers"
+ ]
+ },
+ "ListMcpTools": {
+ "methods": [
+ "listMcpTools"
+ ]
+ },
+ "GetLocation": {
+ "methods": [
+ "getLocation"
+ ]
+ },
+ "ListLocations": {
+ "methods": [
+ "listLocations"
+ ]
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/ApiRegistry/src/V1beta/resources/cloud_api_registry_client_config.json b/ApiRegistry/src/V1beta/resources/cloud_api_registry_client_config.json
new file mode 100644
index 00000000000..71ea56bf9c3
--- /dev/null
+++ b/ApiRegistry/src/V1beta/resources/cloud_api_registry_client_config.json
@@ -0,0 +1,64 @@
+{
+ "interfaces": {
+ "google.cloud.apiregistry.v1beta.CloudApiRegistry": {
+ "retry_codes": {
+ "no_retry_codes": [],
+ "retry_policy_1_codes": [
+ "UNAVAILABLE"
+ ]
+ },
+ "retry_params": {
+ "no_retry_params": {
+ "initial_retry_delay_millis": 0,
+ "retry_delay_multiplier": 0.0,
+ "max_retry_delay_millis": 0,
+ "initial_rpc_timeout_millis": 0,
+ "rpc_timeout_multiplier": 1.0,
+ "max_rpc_timeout_millis": 0,
+ "total_timeout_millis": 0
+ },
+ "retry_policy_1_params": {
+ "initial_retry_delay_millis": 1000,
+ "retry_delay_multiplier": 1.3,
+ "max_retry_delay_millis": 10000,
+ "initial_rpc_timeout_millis": 60000,
+ "rpc_timeout_multiplier": 1.0,
+ "max_rpc_timeout_millis": 60000,
+ "total_timeout_millis": 60000
+ }
+ },
+ "methods": {
+ "GetMcpServer": {
+ "timeout_millis": 60000,
+ "retry_codes_name": "retry_policy_1_codes",
+ "retry_params_name": "retry_policy_1_params"
+ },
+ "GetMcpTool": {
+ "timeout_millis": 60000,
+ "retry_codes_name": "retry_policy_1_codes",
+ "retry_params_name": "retry_policy_1_params"
+ },
+ "ListMcpServers": {
+ "timeout_millis": 60000,
+ "retry_codes_name": "retry_policy_1_codes",
+ "retry_params_name": "retry_policy_1_params"
+ },
+ "ListMcpTools": {
+ "timeout_millis": 60000,
+ "retry_codes_name": "retry_policy_1_codes",
+ "retry_params_name": "retry_policy_1_params"
+ },
+ "GetLocation": {
+ "timeout_millis": 60000,
+ "retry_codes_name": "no_retry_codes",
+ "retry_params_name": "no_retry_params"
+ },
+ "ListLocations": {
+ "timeout_millis": 60000,
+ "retry_codes_name": "no_retry_codes",
+ "retry_params_name": "no_retry_params"
+ }
+ }
+ }
+ }
+}
diff --git a/ApiRegistry/src/V1beta/resources/cloud_api_registry_descriptor_config.php b/ApiRegistry/src/V1beta/resources/cloud_api_registry_descriptor_config.php
new file mode 100644
index 00000000000..9f8d14a8020
--- /dev/null
+++ b/ApiRegistry/src/V1beta/resources/cloud_api_registry_descriptor_config.php
@@ -0,0 +1,135 @@
+ [
+ 'google.cloud.apiregistry.v1beta.CloudApiRegistry' => [
+ 'GetMcpServer' => [
+ 'callType' => \Google\ApiCore\Call::UNARY_CALL,
+ 'responseType' => 'Google\Cloud\ApiRegistry\V1beta\McpServer',
+ 'headerParams' => [
+ [
+ 'keyName' => 'name',
+ 'fieldAccessors' => [
+ 'getName',
+ ],
+ ],
+ ],
+ ],
+ 'GetMcpTool' => [
+ 'callType' => \Google\ApiCore\Call::UNARY_CALL,
+ 'responseType' => 'Google\Cloud\ApiRegistry\V1beta\McpTool',
+ 'headerParams' => [
+ [
+ 'keyName' => 'name',
+ 'fieldAccessors' => [
+ 'getName',
+ ],
+ ],
+ ],
+ ],
+ 'ListMcpServers' => [
+ 'pageStreaming' => [
+ 'requestPageTokenGetMethod' => 'getPageToken',
+ 'requestPageTokenSetMethod' => 'setPageToken',
+ 'requestPageSizeGetMethod' => 'getPageSize',
+ 'requestPageSizeSetMethod' => 'setPageSize',
+ 'responsePageTokenGetMethod' => 'getNextPageToken',
+ 'resourcesGetMethod' => 'getMcpServers',
+ ],
+ 'callType' => \Google\ApiCore\Call::PAGINATED_CALL,
+ 'responseType' => 'Google\Cloud\ApiRegistry\V1beta\ListMcpServersResponse',
+ 'headerParams' => [
+ [
+ 'keyName' => 'parent',
+ 'fieldAccessors' => [
+ 'getParent',
+ ],
+ ],
+ ],
+ ],
+ 'ListMcpTools' => [
+ 'pageStreaming' => [
+ 'requestPageTokenGetMethod' => 'getPageToken',
+ 'requestPageTokenSetMethod' => 'setPageToken',
+ 'requestPageSizeGetMethod' => 'getPageSize',
+ 'requestPageSizeSetMethod' => 'setPageSize',
+ 'responsePageTokenGetMethod' => 'getNextPageToken',
+ 'resourcesGetMethod' => 'getMcpTools',
+ ],
+ 'callType' => \Google\ApiCore\Call::PAGINATED_CALL,
+ 'responseType' => 'Google\Cloud\ApiRegistry\V1beta\ListMcpToolsResponse',
+ 'headerParams' => [
+ [
+ 'keyName' => 'parent',
+ 'fieldAccessors' => [
+ 'getParent',
+ ],
+ ],
+ ],
+ ],
+ 'GetLocation' => [
+ 'callType' => \Google\ApiCore\Call::UNARY_CALL,
+ 'responseType' => 'Google\Cloud\Location\Location',
+ 'headerParams' => [
+ [
+ 'keyName' => 'name',
+ 'fieldAccessors' => [
+ 'getName',
+ ],
+ ],
+ ],
+ 'interfaceOverride' => 'google.cloud.location.Locations',
+ ],
+ 'ListLocations' => [
+ 'pageStreaming' => [
+ 'requestPageTokenGetMethod' => 'getPageToken',
+ 'requestPageTokenSetMethod' => 'setPageToken',
+ 'requestPageSizeGetMethod' => 'getPageSize',
+ 'requestPageSizeSetMethod' => 'setPageSize',
+ 'responsePageTokenGetMethod' => 'getNextPageToken',
+ 'resourcesGetMethod' => 'getLocations',
+ ],
+ 'callType' => \Google\ApiCore\Call::PAGINATED_CALL,
+ 'responseType' => 'Google\Cloud\Location\ListLocationsResponse',
+ 'headerParams' => [
+ [
+ 'keyName' => 'name',
+ 'fieldAccessors' => [
+ 'getName',
+ ],
+ ],
+ ],
+ 'interfaceOverride' => 'google.cloud.location.Locations',
+ ],
+ 'templateMap' => [
+ 'location' => 'projects/{project}/locations/{location}',
+ 'mcpServer' => 'projects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}',
+ 'mcpTool' => 'projects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}',
+ 'projectLocationApiNamespaceMcpServer' => 'projects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}',
+ 'projectLocationApiNamespaceMcpServerMcpTool' => 'projects/{project}/locations/{location}/apiNamespaces/{api_namespace}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}',
+ 'projectLocationMcpServer' => 'projects/{project}/locations/{location}/mcpServers/{mcp_server}',
+ 'projectLocationMcpServerMcpTool' => 'projects/{project}/locations/{location}/mcpServers/{mcp_server}/mcpTools/{mcp_tool}',
+ ],
+ ],
+ ],
+];
diff --git a/ApiRegistry/src/V1beta/resources/cloud_api_registry_rest_client_config.php b/ApiRegistry/src/V1beta/resources/cloud_api_registry_rest_client_config.php
new file mode 100644
index 00000000000..f7bc494d54f
--- /dev/null
+++ b/ApiRegistry/src/V1beta/resources/cloud_api_registry_rest_client_config.php
@@ -0,0 +1,97 @@
+ [
+ 'google.cloud.apiregistry.v1beta.CloudApiRegistry' => [
+ 'GetMcpServer' => [
+ 'method' => 'get',
+ 'uriTemplate' => '/v1beta/{name=projects/*/locations/*/mcpServers/*}',
+ 'placeholders' => [
+ 'name' => [
+ 'getters' => [
+ 'getName',
+ ],
+ ],
+ ],
+ ],
+ 'GetMcpTool' => [
+ 'method' => 'get',
+ 'uriTemplate' => '/v1beta/{name=projects/*/locations/*/mcpServers/*/mcpTools/*}',
+ 'placeholders' => [
+ 'name' => [
+ 'getters' => [
+ 'getName',
+ ],
+ ],
+ ],
+ ],
+ 'ListMcpServers' => [
+ 'method' => 'get',
+ 'uriTemplate' => '/v1beta/{parent=projects/*/locations/*}/mcpServers',
+ 'placeholders' => [
+ 'parent' => [
+ 'getters' => [
+ 'getParent',
+ ],
+ ],
+ ],
+ ],
+ 'ListMcpTools' => [
+ 'method' => 'get',
+ 'uriTemplate' => '/v1beta/{parent=projects/*/locations/*/mcpServers/*}/mcpTools',
+ 'placeholders' => [
+ 'parent' => [
+ 'getters' => [
+ 'getParent',
+ ],
+ ],
+ ],
+ ],
+ ],
+ 'google.cloud.location.Locations' => [
+ 'GetLocation' => [
+ 'method' => 'get',
+ 'uriTemplate' => '/v1beta/{name=projects/*/locations/*}',
+ 'placeholders' => [
+ 'name' => [
+ 'getters' => [
+ 'getName',
+ ],
+ ],
+ ],
+ ],
+ 'ListLocations' => [
+ 'method' => 'get',
+ 'uriTemplate' => '/v1beta/{name=projects/*}/locations',
+ 'placeholders' => [
+ 'name' => [
+ 'getters' => [
+ 'getName',
+ ],
+ ],
+ ],
+ ],
+ ],
+ ],
+ 'numericEnums' => true,
+];
diff --git a/ApiRegistry/tests/Unit/V1beta/Client/CloudApiRegistryClientTest.php b/ApiRegistry/tests/Unit/V1beta/Client/CloudApiRegistryClientTest.php
new file mode 100644
index 00000000000..d03fa760966
--- /dev/null
+++ b/ApiRegistry/tests/Unit/V1beta/Client/CloudApiRegistryClientTest.php
@@ -0,0 +1,526 @@
+getMockBuilder(CredentialsWrapper::class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ }
+
+ /** @return CloudApiRegistryClient */
+ private function createClient(array $options = [])
+ {
+ $options += [
+ 'credentials' => $this->createCredentials(),
+ ];
+ return new CloudApiRegistryClient($options);
+ }
+
+ /** @test */
+ public function getMcpServerTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ // Mock response
+ $name2 = 'name2-1052831874';
+ $displayName = 'displayName1615086568';
+ $description = 'description-1724546052';
+ $expectedResponse = new McpServer();
+ $expectedResponse->setName($name2);
+ $expectedResponse->setDisplayName($displayName);
+ $expectedResponse->setDescription($description);
+ $transport->addResponse($expectedResponse);
+ // Mock request
+ $formattedName = $gapicClient->mcpServerName('[PROJECT]', '[LOCATION]', '[API_NAMESPACE]', '[MCP_SERVER]');
+ $request = (new GetMcpServerRequest())->setName($formattedName);
+ $response = $gapicClient->getMcpServer($request);
+ $this->assertEquals($expectedResponse, $response);
+ $actualRequests = $transport->popReceivedCalls();
+ $this->assertSame(1, count($actualRequests));
+ $actualFuncCall = $actualRequests[0]->getFuncCall();
+ $actualRequestObject = $actualRequests[0]->getRequestObject();
+ $this->assertSame('/google.cloud.apiregistry.v1beta.CloudApiRegistry/GetMcpServer', $actualFuncCall);
+ $actualValue = $actualRequestObject->getName();
+ $this->assertProtobufEquals($formattedName, $actualValue);
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function getMcpServerExceptionTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ $status = new stdClass();
+ $status->code = Code::DATA_LOSS;
+ $status->details = 'internal error';
+ $expectedExceptionMessage = json_encode(
+ [
+ 'message' => 'internal error',
+ 'code' => Code::DATA_LOSS,
+ 'status' => 'DATA_LOSS',
+ 'details' => [],
+ ],
+ JSON_PRETTY_PRINT
+ );
+ $transport->addResponse(null, $status);
+ // Mock request
+ $formattedName = $gapicClient->mcpServerName('[PROJECT]', '[LOCATION]', '[API_NAMESPACE]', '[MCP_SERVER]');
+ $request = (new GetMcpServerRequest())->setName($formattedName);
+ try {
+ $gapicClient->getMcpServer($request);
+ // If the $gapicClient method call did not throw, fail the test
+ $this->fail('Expected an ApiException, but no exception was thrown.');
+ } catch (ApiException $ex) {
+ $this->assertEquals($status->code, $ex->getCode());
+ $this->assertEquals($expectedExceptionMessage, $ex->getMessage());
+ }
+ // Call popReceivedCalls to ensure the stub is exhausted
+ $transport->popReceivedCalls();
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function getMcpToolTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ // Mock response
+ $name2 = 'name2-1052831874';
+ $displayName = 'displayName1615086568';
+ $description = 'description-1724546052';
+ $expectedResponse = new McpTool();
+ $expectedResponse->setName($name2);
+ $expectedResponse->setDisplayName($displayName);
+ $expectedResponse->setDescription($description);
+ $transport->addResponse($expectedResponse);
+ // Mock request
+ $formattedName = $gapicClient->mcpToolName(
+ '[PROJECT]',
+ '[LOCATION]',
+ '[API_NAMESPACE]',
+ '[MCP_SERVER]',
+ '[MCP_TOOL]'
+ );
+ $request = (new GetMcpToolRequest())->setName($formattedName);
+ $response = $gapicClient->getMcpTool($request);
+ $this->assertEquals($expectedResponse, $response);
+ $actualRequests = $transport->popReceivedCalls();
+ $this->assertSame(1, count($actualRequests));
+ $actualFuncCall = $actualRequests[0]->getFuncCall();
+ $actualRequestObject = $actualRequests[0]->getRequestObject();
+ $this->assertSame('/google.cloud.apiregistry.v1beta.CloudApiRegistry/GetMcpTool', $actualFuncCall);
+ $actualValue = $actualRequestObject->getName();
+ $this->assertProtobufEquals($formattedName, $actualValue);
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function getMcpToolExceptionTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ $status = new stdClass();
+ $status->code = Code::DATA_LOSS;
+ $status->details = 'internal error';
+ $expectedExceptionMessage = json_encode(
+ [
+ 'message' => 'internal error',
+ 'code' => Code::DATA_LOSS,
+ 'status' => 'DATA_LOSS',
+ 'details' => [],
+ ],
+ JSON_PRETTY_PRINT
+ );
+ $transport->addResponse(null, $status);
+ // Mock request
+ $formattedName = $gapicClient->mcpToolName(
+ '[PROJECT]',
+ '[LOCATION]',
+ '[API_NAMESPACE]',
+ '[MCP_SERVER]',
+ '[MCP_TOOL]'
+ );
+ $request = (new GetMcpToolRequest())->setName($formattedName);
+ try {
+ $gapicClient->getMcpTool($request);
+ // If the $gapicClient method call did not throw, fail the test
+ $this->fail('Expected an ApiException, but no exception was thrown.');
+ } catch (ApiException $ex) {
+ $this->assertEquals($status->code, $ex->getCode());
+ $this->assertEquals($expectedExceptionMessage, $ex->getMessage());
+ }
+ // Call popReceivedCalls to ensure the stub is exhausted
+ $transport->popReceivedCalls();
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function listMcpServersTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ // Mock response
+ $nextPageToken = '';
+ $mcpServersElement = new McpServer();
+ $mcpServers = [$mcpServersElement];
+ $expectedResponse = new ListMcpServersResponse();
+ $expectedResponse->setNextPageToken($nextPageToken);
+ $expectedResponse->setMcpServers($mcpServers);
+ $transport->addResponse($expectedResponse);
+ // Mock request
+ $formattedParent = $gapicClient->locationName('[PROJECT]', '[LOCATION]');
+ $request = (new ListMcpServersRequest())->setParent($formattedParent);
+ $response = $gapicClient->listMcpServers($request);
+ $this->assertEquals($expectedResponse, $response->getPage()->getResponseObject());
+ $resources = iterator_to_array($response->iterateAllElements());
+ $this->assertSame(1, count($resources));
+ $this->assertEquals($expectedResponse->getMcpServers()[0], $resources[0]);
+ $actualRequests = $transport->popReceivedCalls();
+ $this->assertSame(1, count($actualRequests));
+ $actualFuncCall = $actualRequests[0]->getFuncCall();
+ $actualRequestObject = $actualRequests[0]->getRequestObject();
+ $this->assertSame('/google.cloud.apiregistry.v1beta.CloudApiRegistry/ListMcpServers', $actualFuncCall);
+ $actualValue = $actualRequestObject->getParent();
+ $this->assertProtobufEquals($formattedParent, $actualValue);
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function listMcpServersExceptionTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ $status = new stdClass();
+ $status->code = Code::DATA_LOSS;
+ $status->details = 'internal error';
+ $expectedExceptionMessage = json_encode(
+ [
+ 'message' => 'internal error',
+ 'code' => Code::DATA_LOSS,
+ 'status' => 'DATA_LOSS',
+ 'details' => [],
+ ],
+ JSON_PRETTY_PRINT
+ );
+ $transport->addResponse(null, $status);
+ // Mock request
+ $formattedParent = $gapicClient->locationName('[PROJECT]', '[LOCATION]');
+ $request = (new ListMcpServersRequest())->setParent($formattedParent);
+ try {
+ $gapicClient->listMcpServers($request);
+ // If the $gapicClient method call did not throw, fail the test
+ $this->fail('Expected an ApiException, but no exception was thrown.');
+ } catch (ApiException $ex) {
+ $this->assertEquals($status->code, $ex->getCode());
+ $this->assertEquals($expectedExceptionMessage, $ex->getMessage());
+ }
+ // Call popReceivedCalls to ensure the stub is exhausted
+ $transport->popReceivedCalls();
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function listMcpToolsTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ // Mock response
+ $nextPageToken = '';
+ $mcpToolsElement = new McpTool();
+ $mcpTools = [$mcpToolsElement];
+ $expectedResponse = new ListMcpToolsResponse();
+ $expectedResponse->setNextPageToken($nextPageToken);
+ $expectedResponse->setMcpTools($mcpTools);
+ $transport->addResponse($expectedResponse);
+ // Mock request
+ $formattedParent = $gapicClient->mcpServerName('[PROJECT]', '[LOCATION]', '[API_NAMESPACE]', '[MCP_SERVER]');
+ $request = (new ListMcpToolsRequest())->setParent($formattedParent);
+ $response = $gapicClient->listMcpTools($request);
+ $this->assertEquals($expectedResponse, $response->getPage()->getResponseObject());
+ $resources = iterator_to_array($response->iterateAllElements());
+ $this->assertSame(1, count($resources));
+ $this->assertEquals($expectedResponse->getMcpTools()[0], $resources[0]);
+ $actualRequests = $transport->popReceivedCalls();
+ $this->assertSame(1, count($actualRequests));
+ $actualFuncCall = $actualRequests[0]->getFuncCall();
+ $actualRequestObject = $actualRequests[0]->getRequestObject();
+ $this->assertSame('/google.cloud.apiregistry.v1beta.CloudApiRegistry/ListMcpTools', $actualFuncCall);
+ $actualValue = $actualRequestObject->getParent();
+ $this->assertProtobufEquals($formattedParent, $actualValue);
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function listMcpToolsExceptionTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ $status = new stdClass();
+ $status->code = Code::DATA_LOSS;
+ $status->details = 'internal error';
+ $expectedExceptionMessage = json_encode(
+ [
+ 'message' => 'internal error',
+ 'code' => Code::DATA_LOSS,
+ 'status' => 'DATA_LOSS',
+ 'details' => [],
+ ],
+ JSON_PRETTY_PRINT
+ );
+ $transport->addResponse(null, $status);
+ // Mock request
+ $formattedParent = $gapicClient->mcpServerName('[PROJECT]', '[LOCATION]', '[API_NAMESPACE]', '[MCP_SERVER]');
+ $request = (new ListMcpToolsRequest())->setParent($formattedParent);
+ try {
+ $gapicClient->listMcpTools($request);
+ // If the $gapicClient method call did not throw, fail the test
+ $this->fail('Expected an ApiException, but no exception was thrown.');
+ } catch (ApiException $ex) {
+ $this->assertEquals($status->code, $ex->getCode());
+ $this->assertEquals($expectedExceptionMessage, $ex->getMessage());
+ }
+ // Call popReceivedCalls to ensure the stub is exhausted
+ $transport->popReceivedCalls();
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function getLocationTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ // Mock response
+ $name2 = 'name2-1052831874';
+ $locationId = 'locationId552319461';
+ $displayName = 'displayName1615086568';
+ $expectedResponse = new Location();
+ $expectedResponse->setName($name2);
+ $expectedResponse->setLocationId($locationId);
+ $expectedResponse->setDisplayName($displayName);
+ $transport->addResponse($expectedResponse);
+ $request = new GetLocationRequest();
+ $response = $gapicClient->getLocation($request);
+ $this->assertEquals($expectedResponse, $response);
+ $actualRequests = $transport->popReceivedCalls();
+ $this->assertSame(1, count($actualRequests));
+ $actualFuncCall = $actualRequests[0]->getFuncCall();
+ $actualRequestObject = $actualRequests[0]->getRequestObject();
+ $this->assertSame('/google.cloud.location.Locations/GetLocation', $actualFuncCall);
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function getLocationExceptionTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ $status = new stdClass();
+ $status->code = Code::DATA_LOSS;
+ $status->details = 'internal error';
+ $expectedExceptionMessage = json_encode(
+ [
+ 'message' => 'internal error',
+ 'code' => Code::DATA_LOSS,
+ 'status' => 'DATA_LOSS',
+ 'details' => [],
+ ],
+ JSON_PRETTY_PRINT
+ );
+ $transport->addResponse(null, $status);
+ $request = new GetLocationRequest();
+ try {
+ $gapicClient->getLocation($request);
+ // If the $gapicClient method call did not throw, fail the test
+ $this->fail('Expected an ApiException, but no exception was thrown.');
+ } catch (ApiException $ex) {
+ $this->assertEquals($status->code, $ex->getCode());
+ $this->assertEquals($expectedExceptionMessage, $ex->getMessage());
+ }
+ // Call popReceivedCalls to ensure the stub is exhausted
+ $transport->popReceivedCalls();
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function listLocationsTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ // Mock response
+ $nextPageToken = '';
+ $locationsElement = new Location();
+ $locations = [$locationsElement];
+ $expectedResponse = new ListLocationsResponse();
+ $expectedResponse->setNextPageToken($nextPageToken);
+ $expectedResponse->setLocations($locations);
+ $transport->addResponse($expectedResponse);
+ $request = new ListLocationsRequest();
+ $response = $gapicClient->listLocations($request);
+ $this->assertEquals($expectedResponse, $response->getPage()->getResponseObject());
+ $resources = iterator_to_array($response->iterateAllElements());
+ $this->assertSame(1, count($resources));
+ $this->assertEquals($expectedResponse->getLocations()[0], $resources[0]);
+ $actualRequests = $transport->popReceivedCalls();
+ $this->assertSame(1, count($actualRequests));
+ $actualFuncCall = $actualRequests[0]->getFuncCall();
+ $actualRequestObject = $actualRequests[0]->getRequestObject();
+ $this->assertSame('/google.cloud.location.Locations/ListLocations', $actualFuncCall);
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function listLocationsExceptionTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ $status = new stdClass();
+ $status->code = Code::DATA_LOSS;
+ $status->details = 'internal error';
+ $expectedExceptionMessage = json_encode(
+ [
+ 'message' => 'internal error',
+ 'code' => Code::DATA_LOSS,
+ 'status' => 'DATA_LOSS',
+ 'details' => [],
+ ],
+ JSON_PRETTY_PRINT
+ );
+ $transport->addResponse(null, $status);
+ $request = new ListLocationsRequest();
+ try {
+ $gapicClient->listLocations($request);
+ // If the $gapicClient method call did not throw, fail the test
+ $this->fail('Expected an ApiException, but no exception was thrown.');
+ } catch (ApiException $ex) {
+ $this->assertEquals($status->code, $ex->getCode());
+ $this->assertEquals($expectedExceptionMessage, $ex->getMessage());
+ }
+ // Call popReceivedCalls to ensure the stub is exhausted
+ $transport->popReceivedCalls();
+ $this->assertTrue($transport->isExhausted());
+ }
+
+ /** @test */
+ public function getMcpServerAsyncTest()
+ {
+ $transport = $this->createTransport();
+ $gapicClient = $this->createClient([
+ 'transport' => $transport,
+ ]);
+ $this->assertTrue($transport->isExhausted());
+ // Mock response
+ $name2 = 'name2-1052831874';
+ $displayName = 'displayName1615086568';
+ $description = 'description-1724546052';
+ $expectedResponse = new McpServer();
+ $expectedResponse->setName($name2);
+ $expectedResponse->setDisplayName($displayName);
+ $expectedResponse->setDescription($description);
+ $transport->addResponse($expectedResponse);
+ // Mock request
+ $formattedName = $gapicClient->mcpServerName('[PROJECT]', '[LOCATION]', '[API_NAMESPACE]', '[MCP_SERVER]');
+ $request = (new GetMcpServerRequest())->setName($formattedName);
+ $response = $gapicClient->getMcpServerAsync($request)->wait();
+ $this->assertEquals($expectedResponse, $response);
+ $actualRequests = $transport->popReceivedCalls();
+ $this->assertSame(1, count($actualRequests));
+ $actualFuncCall = $actualRequests[0]->getFuncCall();
+ $actualRequestObject = $actualRequests[0]->getRequestObject();
+ $this->assertSame('/google.cloud.apiregistry.v1beta.CloudApiRegistry/GetMcpServer', $actualFuncCall);
+ $actualValue = $actualRequestObject->getName();
+ $this->assertProtobufEquals($formattedName, $actualValue);
+ $this->assertTrue($transport->isExhausted());
+ }
+}
diff --git a/composer.json b/composer.json
index 6d16867010a..608ca67f2ca 100644
--- a/composer.json
+++ b/composer.json
@@ -98,6 +98,7 @@
"google/cloud-apigee-connect": "2.1.2",
"google/cloud-apigee-registry": "1.1.2",
"google/cloud-apihub": "0.4.2",
+ "google/cloud-apiregistry": "0.0.0",
"google/cloud-appengine-admin": "2.1.2",
"google/cloud-apphub": "0.4.2",
"google/cloud-artifact-registry": "1.6.0",
@@ -332,6 +333,7 @@
"GPBMetadata\\Google\\Cloud\\Apigeeconnect\\": "ApigeeConnect/metadata",
"GPBMetadata\\Google\\Cloud\\Apigeeregistry\\": "ApigeeRegistry/metadata",
"GPBMetadata\\Google\\Cloud\\Apihub\\": "ApiHub/metadata",
+ "GPBMetadata\\Google\\Cloud\\Apiregistry\\": "ApiRegistry/metadata",
"GPBMetadata\\Google\\Cloud\\Apphub\\": "AppHub/metadata",
"GPBMetadata\\Google\\Cloud\\Asset\\": "Asset/metadata",
"GPBMetadata\\Google\\Cloud\\Assuredworkloads\\": "AssuredWorkloads/metadata",
@@ -563,6 +565,7 @@
"Google\\Cloud\\ApiGateway\\": "ApiGateway/src",
"Google\\Cloud\\ApiHub\\": "ApiHub/src",
"Google\\Cloud\\ApiKeys\\": "ApiKeys/src",
+ "Google\\Cloud\\ApiRegistry\\": "ApiRegistry/src",
"Google\\Cloud\\ApigeeConnect\\": "ApigeeConnect/src",
"Google\\Cloud\\ApigeeRegistry\\": "ApigeeRegistry/src",
"Google\\Cloud\\AppEngine\\": "AppEngineAdmin/src",
diff --git a/dev/src/Command/ComponentNewCommand.php b/dev/src/Command/ComponentNewCommand.php
index db0ab1f0429..5cfc1bda4d7 100644
--- a/dev/src/Command/ComponentNewCommand.php
+++ b/dev/src/Command/ComponentNewCommand.php
@@ -298,7 +298,7 @@ private function loadProtoContent(string $proto): string
private function getHomePageFromDocsUrl(?string $url): ?string
{
- $productHomePage = !empty($url) ? explode('/docs', $url)[0] : null;
+ $productHomePage = !empty($url) ? explode('/docs/', $url)[0] : null;
$response = $this->httpClient->get($productHomePage, ['http_errors' => false]);
return $response->getStatusCode() >= 400 ? null : $productHomePage;
}