Agent Registry lets your orchestrator agents securely authenticate to
discovered remote agents, Model Context Protocol (MCP) toolsets, and
Google Cloud services. Using
[Agent Identity](https://docs.cloud.google.com/iam/docs/agent-identity-overview.md.txt) and
[Agent Identity auth manager](https://docs.cloud.google.com/iam/docs/auth-manager-overview.md.txt),
you can configure credentials, bindings, and custom HTTP headers when calling
capabilities discovered through Agent Registry.

## Before you begin

Before you authenticate to tools and resources, complete the following:

1. [Set up Agent Registry](https://docs.cloud.google.com/agent-registry/setup.md.txt).
2. For a single-project setup, get
   [the project ID](https://support.google.com/googleapi/answer/7014113)
   of the [governance project](https://docs.cloud.google.com/agent-registry/overview.md.txt#governance-project)
   where Agent Registry is enabled. If you configured a
   [management boundary](https://docs.cloud.google.com/agent-registry/boundaries-and-topology.md.txt) for multiple
   projects, use the ID of your management project for boundary-wide discovery
   and registration, or specify a member project ID for single-project
   operations.

3. Install or upgrade to the latest version of the Agent Development Kit (ADK)
   with the A2A, Agent Identity, and MCP dependencies:

   ### pip

   ```bash
   pip install --upgrade "google-adk[a2a,agent-identity,mcp]"
   ```

   ### uv

   ```bash
   uv add "google-adk[a2a,agent-identity,mcp]"
   ```

   You must upgrade to at least `google-adk>=1.29.0`.
4. To use
   [Application Default Credentials (ADC)](https://docs.cloud.google.com/docs/authentication/provide-credentials-adc.md.txt)
   for authentication, configure them:

   ```bash
   gcloud auth application-default login
   ```

   ADC credentials must have the necessary Identity and Access Management (IAM)
   permissions for the underlying Google Cloud services the agents or
   tools interact with.
5. Set up the following environment variables:

   ```bash
   export GOOGLE_CLOUD_PROJECT=PROJECT_ID
   export GOOGLE_CLOUD_LOCATION=LOCATION
   export API_KEY=EXTERNAL_API_KEY
   ```

   Replace the following:
   - `PROJECT_ID`: the project ID of your governance project.
   - `LOCATION`: the [Agent Registry location](https://docs.cloud.google.com/agent-registry/locations.md.txt) where your agents and MCP servers are registered, such as `us-central1` or `global`.
   - `EXTERNAL_API_KEY`: if using [custom headers](https://docs.cloud.google.com/agent-registry/authenticate-toolsets.md.txt#custom-headers), your external API key.

## Learn about authentication models

To manage credentials, Agent Registry relies on
[Agent Identity](https://docs.cloud.google.com/iam/docs/agent-identity-overview.md.txt) for built-in
Google Cloud authentication and the
[auth manager](https://docs.cloud.google.com/iam/docs/auth-manager-overview.md.txt)
for [auth providers](https://docs.cloud.google.com/agent-registry/component-lifecycle-and-discovery.md.txt#auth-providers)
and [bindings](https://docs.cloud.google.com/agent-registry/component-lifecycle-and-discovery.md.txt#bindings).

Your agents can use their own identity or use the auth manager
to access tools using API keys or OAuth 2.0. The agent's own identity is
provided through
[Application Default Credentials (ADC)](https://docs.cloud.google.com/docs/authentication/provide-credentials-adc.md.txt)
whether you are using Agent Identity or
[service accounts](https://docs.cloud.google.com/iam/docs/service-accounts-create.md.txt).

If you need to authenticate without using the auth manager,
provide [custom HTTP headers](https://docs.cloud.google.com/agent-registry/authenticate-toolsets.md.txt#custom-headers) directly in your
ADK requests.

To pass user credentials or limit the permissions of tokens sent to remote
[Agent2Agent (A2A)](https://docs.cloud.google.com/agent-registry/a2a-protocol.md.txt) agents, see [Limit agent
permissions with scoped credentials](https://docs.cloud.google.com/agent-registry/limit-agent-permissions).

To determine the best approach for your use case, see
[Authentication models](https://docs.cloud.google.com/iam/docs/agent-identity-overview.md.txt#auth-models).

## Use Agent Identity for Google Cloud tools

For Google Cloud services, such as
Agent Runtime on Gemini Enterprise Agent Platform or Cloud Storage,
[your agent uses its own identity](https://docs.cloud.google.com/iam/docs/auth-agent-own-identity.md.txt) to access
the tools. This access is managed through
[Application Default Credentials (ADC)](https://docs.cloud.google.com/docs/authentication/provide-credentials-adc.md.txt)
whether you are using
[Agent Identity](https://docs.cloud.google.com/iam/docs/agent-identity-overview.md.txt) or
[service accounts](https://docs.cloud.google.com/iam/docs/service-accounts-create.md.txt).

The identity associated with your agent must have the necessary
IAM permissions for the underlying Google Cloud services.
For example, if an MCP tool manages Compute Engine VM instances, the agent
identity must have roles such as
[Compute Instance Admin (v1) or higher](https://docs.cloud.google.com/compute/docs/use-compute-engine-mcp.md.txt#before-you-begin),
in addition to the
[Agent Registry API Viewer role](https://docs.cloud.google.com/agent-registry/roles-permissions.md.txt).

### Authenticate remote A2A agents

If your orchestrator agent is connecting to a remote Google Agent2Agent (A2A)
agent using its own identity, you must explicitly include `httpx.AsyncClient`
configured with your Google authentication headers to the
`get_remote_a2a_agent()` method.

To prevent exceeding the default HTTP client timeout limits, define a custom
timeout.

The following example shows how to configure the `httpx.AsyncClient` with ADC
and a custom timeout:

```python
import os
import httpx
import google.auth
from google.auth.transport.requests import Request
from google.adk.integrations.agent_registry import AgentRegistry

class GoogleAuth(httpx.Auth):
    def __init__(self):
        self.creds, _ = google.auth.default()
    def auth_flow(self, request):
        if not self.creds.valid:
            self.creds.refresh(Request())
        request.headers["Authorization"] = f"Bearer {self.creds.token}"
        yield request

# Initialize the registry client
project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
location = os.environ.get("GOOGLE_CLOUD_LOCATION", "global")

if not project_id:
    raise ValueError("GOOGLE_CLOUD_PROJECT environment variable not set.")

registry = AgentRegistry(
    project_id=project_id,
    location=location,
)

# Configure the HTTP client with GoogleAuth and a 60-second timeout
httpx_client = httpx.AsyncClient(auth=GoogleAuth(), timeout=httpx.Timeout(60.0))

# Connect to a remote A2A agent using its resource name in short or full format
# Short formats automatically imply the client's configured project and location
# Short format: "agents/AGENT_ID"
# Full format: f"projects/{project_id}/locations/{location}/agents/AGENT_ID"
agent_name = "agents/AGENT_ID"
my_remote_agent = registry.get_remote_a2a_agent(
    agent_name=agent_name,
    httpx_client=httpx_client,
)
```

Replace `AGENT_ID` with the ID of the registered A2A
subagent that you want your orchestrator agent to call.

### Authenticate MCP tools

If your orchestrator agent uses its own identity to access an MCP toolset, you
can initialize the registry client using your ADC and the `get_mcp_toolset()`
method:

```python
import os
from google.adk.integrations.agent_registry import AgentRegistry

# Initialize the registry client
project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
location = os.environ.get("GOOGLE_CLOUD_LOCATION", "global")

if not project_id:
    raise ValueError("GOOGLE_CLOUD_PROJECT environment variable not set.")

registry = AgentRegistry(
    project_id=project_id,
    location=location,
)

# Retrieve an MCP toolset using its resource name in short or full format
# Short formats automatically imply the client's configured project and location
# Short format: "mcpServers/SERVER_ID"
# Full format: f"projects/{project_id}/locations/{location}/mcpServers/SERVER_ID"
mcp_server_name = "mcpServers/SERVER_ID"
my_mcp_toolset = registry.get_mcp_toolset(mcp_server_name=mcp_server_name)
```

Replace `SERVER_ID` with the ID of your registered MCP
server.

## Use the auth manager for custom tools and delegated access

When your agent needs to connect to external APIs, custom tools, or external MCP
servers, you can use the
[auth manager](https://docs.cloud.google.com/iam/docs/auth-manager-overview.md.txt)
to manage credentials without hardcoding them in your application.

Depending on your use case, you can configure the auth manager
for the following scenarios:

- [**Access custom tools**](https://docs.cloud.google.com/agent-registry/authenticate-toolsets.md.txt#custom-tools): authenticate the agent with [API keys](https://docs.cloud.google.com/iam/docs/auth-with-api-key-v2.md.txt) or [2-legged OAuth (2LO)](https://docs.cloud.google.com/iam/docs/auth-with-2lo-v2.md.txt) when the agent needs to access a tool using its own identity and permissions.
- [**Access tools on behalf of a user**](https://docs.cloud.google.com/agent-registry/authenticate-toolsets.md.txt#user-delegated-access): authenticate the agent acting as an individual user with [3-legged OAuth (3LO)](https://docs.cloud.google.com/iam/docs/auth-with-3lo-v2.md.txt). This model is recommended when the agent must access tools on behalf of the person interacting with it, requiring user consent and delegated permission.

These models require you to create an auth provider. Then, you create a binding
in Agent Registry to link the auth provider to your registry resources.

After configuring the auth provider, the ADK manages the
authentication flow for your orchestrator agent. For an example, see
[Resolve bindings in your ADK code](https://docs.cloud.google.com/agent-registry/authenticate-toolsets.md.txt#bindings-in-code).

### Access custom tools

If you want your agent to connect to external or custom tools using its own
credentials, you can configure the auth manager to handle API
keys or 2-legged OAuth (2LO):

1. **Create the auth provider** : create an auth provider in the auth manager to store the API key or OAuth credentials. For information, see [Authenticate using 2-legged OAuth with auth manager](https://docs.cloud.google.com/iam/docs/auth-with-2lo-v2.md.txt) or [Authenticate using API key with auth manager](https://docs.cloud.google.com/iam/docs/auth-with-api-key-v2.md.txt).
2. **Bind the auth provider**: to let your orchestrator agent detect the
   correct auth provider for a target, you must create a binding in
   Agent Registry between your agent, the target resource, and the auth
   provider. With bindings, you don't have to manually define auth providers in
   your code:

   ### gcloud

   Create a binding to explicitly link your agent to the target resource and
   auth provider by running the
   [`gcloud agent-registry bindings create`](https://docs.cloud.google.com/sdk/gcloud/reference/agent-registry/bindings/create.md.txt)
   command. When specifying the `--auth-provider-binding` resource name, you
   must use the project ID of your governance project:

   ```bash
   gcloud agent-registry bindings create BINDING_NAME \
       --project=PROJECT_ID \
       --location=LOCATION \
       --display-name="DISPLAY_NAME" \
       --source-identifier="SOURCE_ID" \
       --target-identifier="TARGET_ID" \
       --auth-provider-binding="projects/PROJECT_ID/locations/LOCATION/authProviders/AUTH_PROVIDER_ID"
   ```

   ### Terraform

   Configure the `google_agent_registry_binding` resource to link your agent
   and target resource to the auth provider:

   ```terraform
   resource "google_agent_registry_binding" "custom_tool_binding" {
     project      = "PROJECT_ID"
     location     = "LOCATION"
     binding_id   = "BINDING_NAME"
     display_name = "DISPLAY_NAME"

     source {
       identifier = "SOURCE_ID"
     }

     target {
       identifier = "TARGET_ID"
     }

     auth_provider_binding {
       auth_provider = "projects/PROJECT_ID/locations/LOCATION/authProviders/AUTH_PROVIDER_ID"
     }
   }
   ```

   Replace the following:
   - `BINDING_NAME`: the unique ID for the binding.
   - `PROJECT_ID`: the project ID of your governance project.
   - `LOCATION`: the registry region or location, such as `us-central1` or `global`.
   - `DISPLAY_NAME`: a human-readable display name for the binding.
   - `SOURCE_ID`: the [agent identifier](https://docs.cloud.google.com/agent-registry/identity-and-identifiers.md.txt#agent-identifiers) of the source agent in URN format.
   - `TARGET_ID`: the [registry identifier](https://docs.cloud.google.com/agent-registry/identity-and-identifiers.md.txt#registry-identifiers) of the target MCP server or endpoint in URN format.
   - `AUTH_PROVIDER_ID`: the ID of your auth provider.

   For more information about managing these connections, see
   [Manage bindings](https://docs.cloud.google.com/agent-registry/manage-bindings.md.txt).

### Access tools on behalf of a user

If you want your agent to authenticate to remote MCP servers or tools on behalf
of an individual user, use 3-legged OAuth (3LO) through the
auth manager.

The auth manager provides a fully Google-managed service for
handling OAuth tokens, user consent, and redirects. When an end user interacts
with the agent and triggers a tool that requires delegated permissions, the
platform automatically prompts the user for consent, stores the credentials, and
resumes the workflow:

1. **Create the auth provider** : create an auth provider in the auth manager and configure your OAuth redirect URIs. For information, see [Authenticate using 3-legged OAuth with auth manager](https://docs.cloud.google.com/iam/docs/auth-with-3lo-v2.md.txt).
2. **Update the client application** : update your application client to handle the `adk_request_credential` function call and manage user consent. For detailed instructions, see [Update your client-side application](https://docs.cloud.google.com/iam/docs/auth-with-3lo-v2.md.txt#update-client).
3. **Bind the auth provider**: to let your orchestrator agent detect the
   correct auth provider for a target, you must create a binding in
   Agent Registry between your agent, the target resource, and the auth
   provider. With bindings, you don't have to manually define auth providers in
   your code:

   ### gcloud

   Create a binding to explicitly link your agent to the target resource and
   auth provider by running the
   [`gcloud agent-registry bindings create`](https://docs.cloud.google.com/sdk/gcloud/reference/agent-registry/bindings/create.md.txt)
   command. When specifying the `--auth-provider-binding` resource name, you
   must use the project ID of your governance project:

   ```bash
   gcloud agent-registry bindings create BINDING_NAME \
       --project=PROJECT_ID \
       --location=LOCATION \
       --display-name="DISPLAY_NAME" \
       --source-identifier="SOURCE_ID" \
       --target-identifier="TARGET_ID" \
       --auth-provider-binding="projects/PROJECT_ID/locations/LOCATION/authProviders/AUTH_PROVIDER_ID" \
       --auth-provider-binding-scopes=SCOPES \
       --auth-provider-binding-continue-uri="https://REDIRECT_URI"
   ```

   ### Terraform

   Configure the `google_agent_registry_binding` resource with your OAuth 2.0
   scopes and continue URI:

   ```terraform
   resource "google_agent_registry_binding" "user_delegated_binding" {
     project      = "PROJECT_ID"
     location     = "LOCATION"
     binding_id   = "BINDING_NAME"
     display_name = "DISPLAY_NAME"

     source {
       identifier = "SOURCE_ID"
     }

     target {
       identifier = "TARGET_ID"
     }

     auth_provider_binding {
       auth_provider = "projects/PROJECT_ID/locations/LOCATION/authProviders/AUTH_PROVIDER_ID"
       scopes        = [SCOPES]
       continue_uri  = "https://REDIRECT_URI"
     }
   }
   ```

   Replace the following:
   - `BINDING_NAME`: the unique ID for the binding.
   - `PROJECT_ID`: the project ID of your governance project.
   - `LOCATION`: the registry region or location, such as `us-central1` or `global`.
   - `DISPLAY_NAME`: a human-readable display name for the binding.
   - `SOURCE_ID`: the [agent identifier](https://docs.cloud.google.com/agent-registry/identity-and-identifiers.md.txt#agent-identifiers) of the source agent in URN format.
   - `TARGET_ID`: the [registry identifier](https://docs.cloud.google.com/agent-registry/identity-and-identifiers.md.txt#registry-identifiers) of the target MCP server or tool resource in URN format.
   - `AUTH_PROVIDER_ID`: the ID of your auth provider.
   - `SCOPES`: a comma-separated list of OAuth 2.0 scopes, such as `https://www.googleapis.com/auth/cloud-platform`. In Terraform, enclose each scope in double quotes.
   - `REDIRECT_URI`: the redirect URI configured for your auth provider after user consent.

   For more information about managing these connections, see
   [Manage bindings](https://docs.cloud.google.com/agent-registry/manage-bindings.md.txt).

### Resolve bindings in your ADK code

After you create the auth provider binding in Agent Registry, the
ADK handles the authentication flow.

When you use the `AgentRegistry` client to fetch an MCP toolset, the
ADK automatically resolves any bindings associated with that
server and applies the correct scheme. You don't need to manually configure
credentials in your code.

The following example demonstrates how to fetch an authenticated MCP toolset and
attach it to an agent:

```python
import os
from google.adk.agents.llm_agent import LlmAgent
from google.adk.auth.credential_manager import CredentialManager
from google.adk.integrations.agent_identity import GcpAuthProvider
from google.adk.integrations.agent_registry import AgentRegistry

project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
location = os.environ.get("GOOGLE_CLOUD_LOCATION", "global")

if not project_id:
    raise ValueError("GOOGLE_CLOUD_PROJECT environment variable not set.")

# Register the auth provider
CredentialManager.register_auth_provider(GcpAuthProvider())

# Initialize the registry client
registry = AgentRegistry(
    project_id=project_id,
    location=location,
)

# Fetch the registered MCP toolset.
# The ADK applies the bindings configured in Agent Registry.
mcp_server_name = "mcpServers/SERVER_ID"
my_mcp_toolset = registry.get_mcp_toolset(mcp_server_name=mcp_server_name)

# Compose the agent
maps_agent = LlmAgent(
    name="maps_agent",
    model="gemini-1.5-flash",
    instruction=(
        "You are a local guide and navigation expert. Your goal is to provide "
        "accurate location information and directions.\n\n"
        "Rules:\n"
        "1. **Planning**: Before answering, plan how to use the tools to get "
        "the best information (e.g., search for a place first, then get details "
        "or directions).\n"
        "2. **Tool Usage**: Use the Maps MCP tools to find locations, addresses, "
        "and navigation details. Do not guess locations or distances.\n"
        "3. **Output Format**: Provide clear summaries of locations, including "
        "full addresses and key details. Use formatting to make recommendations "
        "easy to read.\n"
        "4. **Tone**: Be helpful, enthusiastic, and descriptive, with "
        "appropriate emojis to enhance the experience."
    ),
    tools=[my_mcp_toolset],
)
```

Replace `SERVER_ID` with the ID of your registered MCP
server.

If you set up 3LO for
[accessing tools on behalf of a user](https://docs.cloud.google.com/agent-registry/authenticate-toolsets.md.txt#user-delegated-access), you must also
provide `continue_uri` to the `get_mcp_toolset` method. This URI indicates where
the end user is redirected after granting consent:

```python
import os
from google.adk.agents.llm_agent import LlmAgent
from google.adk.auth.credential_manager import CredentialManager
from google.adk.integrations.agent_identity import GcpAuthProvider
from google.adk.integrations.agent_registry import AgentRegistry

project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
location = os.environ.get("GOOGLE_CLOUD_LOCATION", "global")

if not project_id:
    raise ValueError("GOOGLE_CLOUD_PROJECT environment variable not set.")

# Register the auth provider
CredentialManager.register_auth_provider(GcpAuthProvider())

# Initialize the registry client
registry = AgentRegistry(
    project_id=project_id,
    location=location,
)

# Fetch the registered MCP toolset.
# The ADK applies the bindings configured in Agent Registry.
# For 3-legged OAuth (3LO), provide continue_uri.
mcp_server_name = "mcpServers/SERVER_ID"
my_mcp_toolset = registry.get_mcp_toolset(
    mcp_server_name=mcp_server_name,
    # Replace with your app's redirect URI:
    continue_uri="https://REDIRECT_URI"
)

# Compose the agent
maps_agent = LlmAgent(
    name="maps_agent",
    model="gemini-1.5-flash",
    instruction=(
        "You are a local guide and navigation expert. Your goal is to provide "
        "accurate location information and directions.\n\n"
        "Rules:\n"
        "1. **Planning**: Before answering, plan how to use the tools to get "
        "the best information (e.g., search for a place first, then get details "
        "or directions).\n"
        "2. **Tool Usage**: Use the Maps MCP tools to find locations, addresses, "
        "and navigation details. Do not guess locations or distances.\n"
        "3. **Output Format**: Provide clear summaries of locations, including "
        "full addresses and key details. Use formatting to make recommendations "
        "easy to read.\n"
        "4. **Tone**: Be helpful, enthusiastic, and descriptive, with "
        "appropriate emojis to enhance the experience."
    ),
    tools=[my_mcp_toolset],
)
```

Replace the following:

- `SERVER_ID`: the ID of your registered MCP server.
- `REDIRECT_URI`: the redirect URI of your application where the user is sent after granting consent.

## Use custom headers for external tools

If you need to authenticate or pass request headers without using the
[auth manager](https://docs.cloud.google.com/iam/docs/auth-manager-overview.md.txt),
provide custom HTTP headers directly in your ADK requests.

Configure custom headers by providing a `header_provider` callback when
initializing your `AgentRegistry` client.

The `header_provider` callback receives the current execution context and
returns a dictionary of HTTP headers. The `McpToolset` component automatically
attaches these headers to downstream requests sent to the MCP server.

Custom headers provided by the `header_provider` callback are only sent to the
target MCP servers. Custom headers aren't used to authenticate against the
Agent Registry API itself. The API always relies on ADC.

This example demonstrates how to provide an API key or custom bearer token for
an external toolset:

```python
import os
from typing import Any
from google.adk.integrations.agent_registry import AgentRegistry

project_id = os.environ.get("GOOGLE_CLOUD_PROJECT")
location = os.environ.get("GOOGLE_CLOUD_LOCATION", "global")
external_api_key = os.environ.get("API_KEY")

# Define the custom header provider.
def my_auth_headers(context: Any) -> dict[str, str]:
    """Returns custom headers injected into MCP toolset requests."""
    return {
        "Authorization": f"Bearer {external_api_key}",
        "X-Custom-Context": "orchestrator-request"
    }

# Initialize the registry client.
# The header_provider is sent to the target MCP server when calling tools.
# The header_provider is not used to authenticate against the Agent Registry API.
# The Agent Registry API always uses your Google ADC.
registry = AgentRegistry(
    project_id=project_id,
    location=location,
    header_provider=my_auth_headers
)

# Fetching the toolset automatically attaches the header_provider to the MCP server.
# Replace with the full resource name of your registered MCP server.
mcp_server_name = f"projects/PROJECT_ID/locations/LOCATION/mcpServers/EXTERNAL_SERVER_ID"
external_mcp_toolset = registry.get_mcp_toolset(mcp_server_name=mcp_server_name)
```

Replace the following:

- `PROJECT_ID`: the project ID of your governance project.
- `LOCATION`: the registry region or location, such as `us-central1`.
- `EXTERNAL_SERVER_ID`: the ID of your registered external MCP server.

## What's next

- Learn how to [limit agent permissions with scoped
  credentials](https://docs.cloud.google.com/agent-registry/limit-agent-permissions).
- Learn how to use [Agent Gateway](https://docs.cloud.google.com/gemini-enterprise-agent-platform/govern/gateways/agent-gateway-overview.md.txt) to enforce access controls and network perimeters on your authenticated tool requests.