docs(samples): add ManagedAgent remote MCP (Maps Grounding Lite) sample

Add a runnable sample wiring `ManagedAgent` to the Maps Grounding Lite MCP
server via `RemoteMcpServer`, with a `header_provider` callback that reads
`GOOGLE_MAPS_API_KEY` and sends it as the `X-Goog-Api-Key` header. Demonstrates
server-side remote MCP execution with runtime header minting.

Co-authored-by: Haran Rajkumar <haranrk@google.com>
PiperOrigin-RevId: 947137422
This commit is contained in:
Haran Rajkumar
2026-07-13 11:07:03 -07:00
committed by Copybara-Service
parent c4d82b5aae
commit cc444b6cbf
5 changed files with 155 additions and 2 deletions
@@ -0,0 +1,63 @@
# Managed Agent - Remote MCP (Maps Grounding Lite)
## Overview
This sample runs a `ManagedAgent` wired to a remote MCP server: Google Maps
Platform Grounding Lite (`https://mapstools.mtls.googleapis.com/mcp`). The MCP server
is executed server-side. `ManagedAgent` forwards the server URL and auth headers
to the Managed Agents API, and the backend opens the MCP session and calls the
Maps tools (`search_places`, `lookup_weather`, `compute_routes`).
Unlike `LlmAgent`'s `McpToolset`, which opens the MCP session and runs tools
client-side, ADK never connects to the MCP server here. Authentication uses a
`header_provider` callback that returns the `X-Goog-Api-Key` header at runtime
from the `GOOGLE_MAPS_API_KEY` environment variable, using the same callback
contract as `LlmAgent`'s `McpToolset.header_provider`.
## Setup
1. Enable the Maps Grounding Lite service on your Google Cloud project and obtain
an API key (see https://developers.google.com/maps/ai/grounding-lite). For
testing you may use the Maps Demo Key.
1. Set the key in your environment (or a `.env` in this directory):
```bash
export GOOGLE_MAPS_API_KEY="YOUR_MAPS_API_KEY"
```
1. Ensure Managed Agents / interactions auth (ADC) is configured, as with the
other `managed_agent` samples.
Note: Maps Grounding Lite may only be used with an LLM that complies with the
Google Maps Platform Terms of Service (no training or caching of Maps content).
The managed-agent backend model is the LLM in this path.
## Sample Inputs
- `Find a few coffee shops near Golden Gate Park.`
The backend calls the `search_places` MCP tool and grounds the answer in Maps
results.
- `What's the weather in San Francisco tomorrow?`
A follow-up turn that reuses the previous interaction, calling the
`lookup_weather` MCP tool.
## Graph
```mermaid
graph TD
ManagedAgent[managed_maps_agent] -->|calls| Maps(maps_grounding_lite)
```
## How To
- Create the agent: instantiate `ManagedAgent` with an `agent_id` and a
`RemoteMcpServer` in `tools`.
- Declare the MCP server: `RemoteMcpServer(name=..., url=..., header_provider=...)`. Only remote (HTTP/streamable) MCP servers are supported,
and execution is server-side.
- Mint auth at runtime: the `header_provider` callback runs during resolution
each turn and returns the headers sent to the MCP server, here
`{'X-Goog-Api-Key': <GOOGLE_MAPS_API_KEY>}`.
@@ -0,0 +1,15 @@
# Copyright 2026 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.
from . import agent
@@ -0,0 +1,76 @@
# Copyright 2026 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.
"""A ManagedAgent wired to a remote MCP server (Maps Grounding Lite).
``ManagedAgent`` executes MCP **server-side**: it forwards the MCP server
URL and headers to the Managed Agents API, and the backend opens the MCP
session and runs the tools. Unlike ``LlmAgent``'s ``McpToolset``
(client-side execution), ADK never connects to the MCP server here.
Authentication uses a ``header_provider`` callback that mints the request
header at runtime (invoked by the Runner during resolution). Here it reads
``GOOGLE_MAPS_API_KEY`` from the environment and sends it as
``X-Goog-Api-Key``, the header the Maps Grounding Lite MCP server expects.
Run with ``adk web`` or
``adk run contributing/samples/managed_agent/remote_mcp``. See the README
for the required environment / auth setup (enable the Maps Grounding Lite
service and set GOOGLE_MAPS_API_KEY).
"""
import os
from google.adk.agents import ManagedAgent
from google.adk.agents.readonly_context import ReadonlyContext
from google.adk.tools import RemoteMcpServer
# The Managed Agent id served by the Managed Agents API. Override with the
# MANAGED_AGENT_ID environment variable if your project has access to a
# different agent.
_DEFAULT_AGENT_ID = 'antigravity-preview-05-2026'
# The Maps Grounding Lite MCP server (Streamable HTTP transport). Uses the mTLS
# endpoint host (mapstools.mtls.googleapis.com); the backend opens the session.
_MAPS_MCP_URL = 'https://mapstools.mtls.googleapis.com/mcp'
def _maps_headers(ctx: ReadonlyContext) -> dict[str, str]:
"""Mint the Maps auth header at request time (runner-invoked).
Reads GOOGLE_MAPS_API_KEY from the environment. Raising here surfaces loudly
during tool resolution rather than becoming a silent error event.
"""
api_key = os.environ.get('GOOGLE_MAPS_API_KEY')
if not api_key:
raise ValueError(
'GOOGLE_MAPS_API_KEY is not set. Enable the Maps Grounding Lite service'
' and export GOOGLE_MAPS_API_KEY (see the README).'
)
return {'X-Goog-Api-Key': api_key}
root_agent = ManagedAgent(
name='managed_maps_agent',
agent_id=os.environ.get('MANAGED_AGENT_ID', _DEFAULT_AGENT_ID),
# Server-side remote MCP: ADK forwards the URL + headers; the backend runs
# the MCP tools. The header_provider mints the auth header per turn.
tools=[
RemoteMcpServer(
name='maps_grounding_lite',
url=_MAPS_MCP_URL,
header_provider=_maps_headers,
)
],
)
-1
View File
@@ -63,7 +63,6 @@ _EXCLUDED_FROM_MTLS = {
'src/google/adk/tools/openapi_tool/auth/credential_exchangers/service_account_exchanger.py',
'src/google/adk/tools/pubsub/pubsub_credentials.py',
'src/google/adk/tools/spanner/spanner_credentials.py',
'tests/integration/test_managed_agent.py',
'tests/unittests/auth/test_credential_manager.py',
'tests/unittests/cli/utils/test_gcp_utils.py',
'tests/unittests/flows/llm_flows/test_functions_request_euc.py',
+1 -1
View File
@@ -145,7 +145,7 @@ async def test_remote_mcp_maps_grounding_lite():
tools=[
RemoteMcpServer(
name='maps_grounding_lite',
url='https://mapstools.googleapis.com/mcp',
url='https://mapstools.mtls.googleapis.com/mcp',
header_provider=lambda ctx: {
'X-Goog-Api-Key': os.environ['GOOGLE_MAPS_API_KEY']
},