Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 65 additions & 1 deletion docs/deploy/agent-engine.md
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,71 @@ Expected output for `stream_query` (remote):
{'parts': [{'text': 'The weather in New York is sunny with a temperature of 25 degrees Celsius (41 degrees Fahrenheit).'}], 'role': 'model'}
```

## Deploying Agents with MCP Tools

When deploying an agent to Agent Engine that depends on an `MCPToolset`, you must ensure the MCP server is accessible over the network and that credentials are handled securely.

### Architecture

* **External MCP Server**: The MCP server cannot be a local subprocess (`StdioConnectionParams` is not supported). It must be deployed as a separate, network-accessible service (e.g., on Cloud Run, GKE, or another compute platform).
* **Network Connectivity**: Ensure that the Agent Engine environment has the necessary VPC network configuration and firewall rules to reach your MCP server's endpoint.
* **Connection Parameters**: In your agent code, use `StreamableHTTPConnectionParams` to specify the URL of your deployed MCP server.

### Secure Credential Management

Handling authentication tokens and other secrets is critical for security.

* **Use Secret Manager**: The recommended best practice is to store credentials like API tokens in [Google Cloud Secret Manager](https://cloud.google.com/secret-manager).
* **Runtime Access**: Your agent code, running within Agent Engine, should be granted an IAM role (e.g., `Secret Manager Secret Accessor`) that allows it to fetch the secret value at runtime. This avoids exposing secrets in environment variables or source code.
* **Pass Secrets to Tools**: Once fetched from Secret Manager, the token can be used to construct the `AuthCredential` for your `MCPToolset`.

### Example: Agent with MCP Toolset for Agent Engine

Your agent definition would be packaged for Agent Engine, fetching credentials securely.

```python
# In your agent.py to be deployed to Agent Engine
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StreamableHTTPConnectionParams
from google.adk.auth import AuthCredential, AuthCredentialTypes, HttpAuth, HttpCredentials
from google.adk.auth.auth_schemes import HTTPBearer
# You would also need the Secret Manager client library
# from google.cloud import secretmanager

def get_secret(secret_id: str) -> str:
# Placeholder for logic to fetch a secret from Google Secret Manager
# client = secretmanager.SecretManagerServiceClient()
# name = f"projects/{os.environ['GCP_PROJECT']}/secrets/{secret_id}/versions/latest"
# response = client.access_secret_version(name=name)
# return response.payload.data.decode("UTF-8")
# For deployment, you would use the real client. For local testing, you might use an env var.
return os.environ.get(secret_id)

# Get configuration from environment variables or secrets
MCP_SERVER_URL = os.environ.get("MCP_SERVER_URL")
MCP_AUTH_TOKEN = get_secret("MCP_API_TOKEN_SECRET_ID")

if not MCP_SERVER_URL or not MCP_AUTH_TOKEN:
raise ValueError("MCP server configuration or token is missing.")

root_agent = LlmAgent(
model='gemini-1.5-flash',
tools=[
MCPToolset(
connection_params=StreamableHTTPConnectionParams(url=MCP_SERVER_URL),
auth_scheme=HTTPBearer(),
auth_credential=AuthCredential(
auth_type=AuthCredentialTypes.HTTP,
http=HttpAuth(scheme="bearer", credentials=HttpCredentials(token=MCP_AUTH_TOKEN))
)
)
],
# ... other agent parameters
)
```

When deploying with `agent_engines.create`, you would need to ensure the `requirements` list includes `google-cloud-secret-manager` and that the necessary environment variables (`MCP_SERVER_URL`, `MCP_API_TOKEN_SECRET_ID`, `GCP_PROJECT`) are available to the runtime.

## Clean up

Expand All @@ -230,4 +294,4 @@ charges on your Google Cloud account.
remote_app.delete(force=True)
```

`force=True` will also delete any child resources that were generated from the deployed agent, such as sessions.
`force=True` will also delete any child resources that were generated from the deployed agent, such as sessions.
51 changes: 50 additions & 1 deletion docs/deploy/cloud-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,56 @@ export GOOGLE_GENAI_USE_VERTEXAI=True

For a full list of deployment options, see the [`gcloud run deploy` reference documentation](https://cloud.google.com/sdk/gcloud/reference/run/deploy).

## Deploying Agents with MCP Tools

When deploying an agent that uses an `MCPToolset`, it's important to follow best practices for production environments like Cloud Run.

### Architecture

* **Separate Services**: The recommended architecture is to deploy your MCP server as a separate Cloud Run service from your ADK agent service. This decouples the components and allows them to be scaled and managed independently.
* **Avoid `StdioConnectionParams`**: Do not use `StdioConnectionParams` in a Cloud Run environment. It relies on starting a local subprocess, which is not a reliable or scalable pattern for a managed container platform.
* **Use `StreamableHTTPConnectionParams`**: Configure your `MCPToolset` within the ADK agent to connect to the deployed MCP server's URL using `StreamableHTTPConnectionParams`.

### Authentication

* **Service-to-Service Authentication**: Secure the connection between your ADK agent service and your MCP server service. Configure the MCP server to only allow invocations from your ADK agent's service account. Cloud Run can automatically attach a secure identity token to outbound requests, which your MCP server can then validate. This is more secure than using static API keys.
* **Secure Credential Management**: If you must use API keys or other static tokens, do not hardcode them. Pass them to your Cloud Run service as environment variables backed by [Secret Manager](https://cloud.google.com/secret-manager).

### Example Configuration Snippet

Your agent code, when deployed, would look something like this:

```python
# In your agent.py deployed to Cloud Run
import os
from google.adk.agents import LlmAgent
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StreamableHTTPConnectionParams
from google.adk.auth import AuthCredential, AuthCredentialTypes, HttpAuth, HttpCredentials
from google.adk.auth.auth_schemes import HTTPBearer

# The URL of your deployed MCP server service
MCP_SERVER_URL = os.environ.get("MCP_SERVER_URL") # Injected as env var
# The token to authenticate with the MCP server
MCP_AUTH_TOKEN = os.environ.get("MCP_AUTH_TOKEN") # Injected from Secret Manager

if not MCP_SERVER_URL or not MCP_AUTH_TOKEN:
raise ValueError("MCP server configuration is missing.")

root_agent = LlmAgent(
model='gemini-1.5-flash',
tools=[
MCPToolset(
connection_params=StreamableHTTPConnectionParams(url=MCP_SERVER_URL),
auth_scheme=HTTPBearer(),
auth_credential=AuthCredential(
auth_type=AuthCredentialTypes.HTTP,
http=HttpAuth(scheme="bearer", credentials=HttpCredentials(token=MCP_AUTH_TOKEN))
)
)
],
# ... other agent parameters
)
```

## Testing your agent

Expand Down Expand Up @@ -451,4 +500,4 @@ Once your agent is deployed to Cloud Run, you can interact with it via the deplo
```

* Set `"streaming": true` if you want to receive Server-Sent Events (SSE).
* The response will contain the agent's execution events, including the final answer.
* The response will contain the agent's execution events, including the final answer.
2 changes: 2 additions & 0 deletions docs/tools/authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ You set up authentication when defining your tool:

* **RestApiTool / OpenAPIToolset**: Pass `auth_scheme` and `auth_credential` during initialization

* **`MCPToolset`**: For tools provided by a remote, secured [Model Context Protocol server](./mcp-tools.md).

* **GoogleApiToolSet Tools**: ADK has built-in 1st party tools like Google Calendar, BigQuery etc,. Use the toolset's specific method.

* **APIHubToolset / ApplicationIntegrationToolset**: Pass `auth_scheme` and `auth_credential`during initialization, if the API managed in API Hub / provided by Application Integration requires authentication.
Expand Down
118 changes: 118 additions & 0 deletions docs/tools/mcp-authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
# Authenticating with Remote MCP Servers

![python_only](https://img.shields.io/badge/Currently_supported_in-Python-blue){ title="This feature is currently available for Python."}

This guide explains how to connect your ADK agent to a remote Model Context Protocol (MCP) server that requires authentication. This is a common requirement for production environments where MCP servers expose sensitive tools or data and must be secured.

You will learn how to use ADK's built-in authentication framework with `MCPToolset` to securely pass credentials, such as Bearer tokens, to a remote MCP server.

## Core Concepts

ADK integrates its standard authentication system with `MCPToolset`, allowing you to secure connections to remote MCP servers in the same way you would for a REST API or OpenAPI tool.

The key components are:

1. **`MCPToolset`**: The ADK toolset for integrating with MCP servers.
2. **`StreamableHTTPConnectionParams`**: The recommended connection parameter class for connecting to remote MCP servers over HTTP. It allows you to specify the server's URL.
3. **`auth_scheme`**: An object defining *how* the server expects credentials. For many modern services, this will be `HTTPBearer()` for sending an `Authorization: Bearer <token>` header.
4. **`auth_credential`**: An object holding the *actual* credential information, such as the Bearer token itself.

When you provide an `auth_scheme` and `auth_credential` to `MCPToolset`, ADK automatically constructs the correct `Authorization` header and includes it in all requests to the MCP server.

## Example: Connecting to a Secured Server with a Bearer Token

This example demonstrates how to build an agent that connects to a remote MCP server protected by Bearer token authentication. We will provide a complete, runnable example that includes a mock server, so you can test the entire flow locally.

### Step 1: Create a Mock Authenticated MCP Server

First, let's create a simple MCP server using FastAPI that requires an `Authorization` header. This simulates a real-world secured service.

Save this code as `mock_mcp_server.py`:

```python title="mock_mcp_server.py"
--8<-- "examples/python/snippets/tools/mcp_auth/mock_mcp_server.py:init"
```

This server does the following:
* It listens for POST requests on the `/mcp` endpoint.
* It checks for an `Authorization` header.
* If the header is missing or the token is incorrect, it returns a `401 Unauthorized` error.
* If the token is valid (`secret-token-123`), it responds with a mock list of tools, simulating a real MCP server.

### Step 2: Create the ADK Agent with Authentication

Next, create the ADK agent. This agent will be configured to send the required Bearer token to the mock server.

Save this code as `agent_with_auth.py`:

```python title="agent_with_auth.py"
--8<-- "examples/python/snippets/tools/mcp_auth/agent_with_auth.py:init"
```

Key parts of this agent configuration:

* **`StreamableHTTPConnectionParams`**: We use this to point to our mock server's URL (`http://127.0.0.1:8001/mcp`).
* **`auth_scheme = HTTPBearer()`**: This tells ADK that the authentication method is a Bearer token sent via an HTTP header.
* **`auth_credential`**: This holds the actual token. We use `AuthCredential` with `auth_type=AuthCredentialTypes.HTTP` and provide the token value.

!!! tip "Best Practice: Use Environment Variables for Tokens"
In the example, the token is hardcoded for simplicity. In a real application, you should **never** hardcode secrets. Load them from environment variables or a secure secret manager.
```python
import os
my_token = os.environ.get("MY_MCP_API_TOKEN")
```

### Step 3: Run and Test the Example

1. **Install dependencies:**
```shell
pip install fastapi uvicorn
```

2. **Start the mock server:**
Open a terminal and run:
```shell
uvicorn mock_mcp_server:app --host 127.0.0.1 --port 8001
```
The server is now running and waiting for connections.

3. **Run the ADK agent:**
Open a *second* terminal, ensure your ADK environment is active, and run:
```shell
python agent_with_auth.py
```

**Expected Output:**

In the terminal running `agent_with_auth.py`, you should see the agent successfully get the tool list and then call the `get_user_profile` tool:

```console
User Query: 'What is the profile for user 42?'
Running agent...
Event received: ... 'function_call': {'name': 'get_user_profile', 'args': {'user_id': '42'}} ...
Event received: ... 'function_response': {'name': 'get_user_profile', 'response': {'id': '42', 'name': 'Jane Doe', 'email': '[email protected]'}} ...
Event received: ... 'text': 'The user profile for user ID 42 belongs to Jane Doe, with the email address [email protected].' ...
```

In the terminal running the `mock_mcp_server.py`, you will see logs confirming it received the requests with the correct authorization:

```console
INFO: Uvicorn running on http://127.0.0.1:8001 (Press CTRL+C to quit)
INFO: Application startup complete.
INFO: 127.0.0.1:xxxx - "POST /mcp HTTP/1.1" 200 OK
INFO: 127.0.0.1:xxxx - "POST /mcp HTTP/1.1" 200 OK
```

This confirms that the ADK agent successfully authenticated with the remote MCP server.

## Deployment Considerations

When deploying agents that use authenticated MCP tools to production environments like Cloud Run or Agent Engine, special considerations are necessary.

* **Avoid `StdioConnectionParams`**: Do not use `stdio`-based connections in a serverless or containerized environment. The MCP server should always be a separate, network-accessible service.
* **Secure Credential Management**: Use a service like Google Secret Manager to store and retrieve API tokens and other credentials at runtime. Do not store them in source code or as plain text environment variables.
* **Service-to-Service Authentication**: In cloud environments, leverage built-in service-to-service authentication mechanisms. For example, a Cloud Run service can be configured to only accept requests from other specific services, using automatically managed identity tokens.

For detailed guidance, see the new sections on deploying agents with MCP tools in the deployment guides:
* [**Deploy to Cloud Run**](../deploy/cloud-run.md#deploying-agents-with-mcp-tools)
* [**Deploy to Agent Engine**](../deploy/agent-engine.md#deploying-agents-with-mcp-tools)
Loading