Erste Schritte mit MCP und A2A mit ADK

1. Übersicht

KI-Agenten werden immer beliebter. Sie revolutionieren die Aufgabenautomatisierung und Entscheidungsfindung, da sie autonom agieren, lernen und mit ihrer Umgebung interagieren können, um Ziele zu erreichen.

In diesem Codelab erstellen Sie ein End-to-End-Multi-Agenten-System. Sie erstellen einen MCP-Server für Währungen, einen Währungs-Agenten, der den MCP-Server nutzt und über das Agent2Agent-Protokoll (A2A) bereitgestellt wird, einen Reise-Agenten mit einem prozessinternen Wetter-Subagenten, der den Währungs-Agenten über A2A nutzt, und stellen schließlich alle Dienste in Cloud Run bereit.

Architektur

Kerntechnologien

Model Context Protocol (MCP)

Das Model Context Protocol (MCP) ist ein offenes Protokoll, das die Bereitstellung von Kontext und Tools durch Anwendungen an LLMs standardisiert. Man kann sich MCP wie einen USB-C-Anschluss für KI-Anwendungen vorstellen: Es bietet eine standardisierte Möglichkeit, KI-Modelle mit externen Datenquellen, APIs und Tools zu verbinden.

In diesem Codelab stellt der currency_mcp_server ein get_exchange_rate-Tool über Streamable HTTP (/mcp) bereit, das von der öffentlichen Frankfurter API unterstützt wird.

Agent Development Kit (ADK)

Das Agent Development Kit (ADK) ist ein flexibles Orchestrierungs-Framework zum Entwickeln und Bereitstellen von KI-Agenten. Das ADK ist modellunabhängig, bereitstellungsunabhängig und mit anderen Frameworks kompatibel. Mit dem ADK fühlt sich die Entwicklung von KI-Agenten wie Standard-Softwareentwicklung an. So lassen sich komplexe agentische Workflows einfach erstellen, testen und orchestrieren.

Das ADK verarbeitet Nutzerunterhaltungen, stellt die interaktive Web-UI bereit, stellt über McpToolset eine Verbindung zu MCP-Tools her und verwaltet die A2A-Kommunikation.

Agent2Agent-Protokoll (A2A)

Das Agent2Agent-Protokoll (A2A) ist ein offener Standard, der die Kommunikation und Zusammenarbeit zwischen KI-Agenten ermöglichen soll. So wie MCP die Verbindungen zwischen Agenten und Tools standardisiert, standardisiert A2A die Zusammenarbeit zwischen Agenten. In einer Welt, in der KI-Agenten auf verschiedenen Frameworks, Hosting-Umgebungen und Organisationen basieren, bietet A2A eine gemeinsame Sprache für die Erkennung und Aufgabendelegation.

Das ADK stellt currency_agent als A2A-Dienst (to_a2a) bereit und ermöglicht es travel_agent, ihn remote als AgentTool (RemoteA2aAgent) zu nutzen.

Lokale Sub-Agenten im Vergleich zu Remote-A2A-Agenten

Diese Architektur verdeutlicht ein wichtiges Muster im Multi-Agenten-Design:

  • Lokales Agententool (weather_agent): Wird prozessintern im Orchestrator als AgentTool ausgeführt, ohne Netzwerklatenz oder Protokollserialisierungs-Overhead.
  • Remote Agent Tool (currency_agent): Wird als unabhängiger Mikrodienst ausgeführt und über das Netzwerk über das A2A-Protokoll aufgerufen.

Lerninhalte

  • Lokalen MCP-Server mit FastMCP über Streamable HTTP erstellen und testen
  • Agenten mit ADK erstellen, der MCP-Tools verwendet (McpToolset)
  • ADK-Agent als A2A-Server bereitstellen (to_a2a)
  • A2A-Server mit dem A2A-Python-Client (a2a.client) testen
  • Orchestrator-Agenten erstellen, der lokale Subagenten-Tools mit Remote-A2A-Agenten kombiniert
  • Das gesamte Multi-Agenten-System lokal mit der ADK-Web-UI ausführen und testen
  • Alle drei Komponenten containerisieren und in Google Cloud Run bereitstellen

Voraussetzungen

  • Ein Browser wie Chrome
  • Google Cloud-Projekt mit aktivierter Abrechnungsfunktion.

2. Hinweis

Projekt erstellen

Wenn Sie noch kein Google Cloud-Projekt haben, erstellen Sie eines.

Wählen Sie in der Google Cloud Console auf der Seite zur Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.

Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für ein Projekt aktiviert ist.

Cloud Shell aktivieren

Google Cloud Shell ist eine interaktive, browserbasierte Entwicklungsumgebung, die direkt in der Google Cloud Console bereitgestellt wird. Dies ist die einfachste Möglichkeit, mit Google Cloud zu beginnen, ohne Tools lokal installieren zu müssen.

Aktivieren Sie die Cloud Shell, indem Sie auf diesen Link klicken. Sie können zwischen dem Cloud Shell-Terminal (zum Ausführen von Cloud-Befehlen) und dem Editor (zum Ansehen von Dateien) wechseln, indem Sie in der Cloud Shell auf den entsprechenden Button klicken.

Prüfen Sie nach dem Herstellen der Verbindung zu Cloud Shell, ob Sie authentifiziert sind:

gcloud auth list

Prüfen Sie, ob der Befehl gcloud Ihr Projekt kennt:

gcloud config list project

Legen Sie Ihre Projekt-ID fest:

export PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
gcloud config set project $PROJECT_ID

Cloud APIs aktivieren

Aktivieren Sie die erforderlichen APIs für Cloud Run, Cloud Build, Artifact Registry und Vertex AI:

gcloud services enable run.googleapis.com \
                       cloudbuild.googleapis.com \
                       artifactregistry.googleapis.com \
                       aiplatform.googleapis.com

Code abrufen

Klonen Sie das Repository und rufen Sie das Verzeichnis python auf:

git clone https://github.com/meteatamel/getting-started-mcp-a2a-adk.git
cd getting-started-mcp-a2a-adk/python

Installieren Sie Abhängigkeiten mit uv:

uv ist ein schneller Python-Paket- und Projektmanager. Es ist in Cloud Shell vorinstalliert. Wenn Sie es lokal ausführen, können Sie es so installieren:

# macOS and Linux
curl -LsSf https://astral.sh/uv/install.sh | sh

# Windows (PowerShell)
# powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex"

Das Python-Verzeichnis ist als einheitliches uv strukturiert.

Workspace. Installieren Sie alle Abhängigkeiten für alle Arbeitsbereichsmitglieder (currency_mcp_server, currency_agent und travel_agent) in einer einzigen virtuellen Umgebung, indem Sie Folgendes ausführen:

uv sync

Umgebungsvariablen konfigurieren

Konfigurieren Sie Umgebungsvariablen in einer .env-Datei im Verzeichnis python:

Option A: Gemini Enterprise (Google Cloud / Cloud Shell)

echo "GOOGLE_GENAI_USE_ENTERPRISE=TRUE" >> .env \
&& echo "GOOGLE_CLOUD_PROJECT=$PROJECT_ID" >> .env \
&& echo "GOOGLE_CLOUD_LOCATION=global" >> .env

Option B: Google AI Studio (lokaler API-Schlüssel)

Wenn Sie stattdessen einen API-Schlüssel von Google AI Studio verwenden möchten:

echo "GOOGLE_API_KEY=<your_api_key_here>"<>>/span>  .env \
&& echo "GOOGLE_GENAI_USE_ENTERPRISE=FALSE" >> .env

3. MCP-Server für Währungen erstellen

Bevor Sie Ihre KI-Agenten erstellen, sehen Sie sich den MCP-Server an, der das Tool zur Währungsumrechnung bereitstellt.

Mit einem MCP-Server können Sie einfache Programme schreiben, um Funktionen als Tools bereitzustellen. Ein Agent (oder mehrere Agenten) kann dann über das standardisierte Model Context Protocol auf diese Tools zugreifen.

Mit dem Python-Paket FastMCP können Sie einen MCP-Server erstellen, der ein einzelnes Tool namens get_exchange_rate bereitstellt. Das Tool get_exchange_rate ruft die Frankfurter API auf, um den aktuellen Wechselkurs zwischen zwei Währungen abzurufen.

Der Code für den MCP-Server befindet sich in currency_mcp_server/server.py:

import asyncio
import logging
import os

import httpx
from fastmcp import FastMCP

logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)

mcp = FastMCP("Currency MCP Server 💵")


@mcp.tool()
def get_exchange_rate(
    currency_from: str = "USD",
    currency_to: str = "EUR",
    currency_date: str = "latest",
):
    """Use this to get current exchange rate.

    Args:
        currency_from: The currency to convert from (e.g., "USD").
        currency_to: The currency to convert to (e.g., "EUR").
        currency_date: The date for the exchange rate or "latest". Defaults to "latest".

    Returns:
        A dictionary containing the exchange rate data, or an error message if the request fails.
    """
    logger.info(
        f"--- 🛠️ Tool: get_exchange_rate called for converting {currency_from} to {currency_to} ---"
    )
    try:
        response = httpx.get(
            f"https://api.frankfurter.dev/v1/{currency_date}",
            params={"from": currency_from, "to": currency_to},
        )
        response.raise_for_status()

        data = response.json()
        if "rates" not in data:
            logger.error(f"❌ rates not found in response: {data}")
            return {"error": "Invalid API response format."}
        logger.info(f"✅ API response: {data}")
        return data
    except httpx.HTTPError as e:
        logger.error(f"❌ API request failed: {e}")
        return {"error": f"API request failed: {e}"}
    except ValueError:
        logger.error("❌ Invalid JSON response from API")
        return {"error": "Invalid JSON response from API."}


if __name__ == "__main__":
    port = int(os.getenv("PORT", 8080))
    logger.info(f"🚀 MCP server started on port {port}")
    # Could also use 'sse' transport, host="0.0.0.0" required for Cloud Run.
    asyncio.run(
        mcp.run_async(
            transport="http",
            host="0.0.0.0",
            port=port,
        )
    )

MCP-Server lokal starten

Starten Sie den MCP-Server in Ihrem Terminal:

uv run python currency_mcp_server/server.py

Der Server wird an Port 8080 gestartet. Der Streamable-HTTP-Endpunkt ist unter /mcp (http://localhost:8080/mcp) verfügbar.

MCP-Server testen

Öffnen Sie ein zweites Terminalfenster (lassen Sie den MCP-Server im ersten Fenster laufen), rufen Sie den Ordner python (cd getting-started-mcp-a2a-adk/python) auf und führen Sie das Testskript aus:

uv run python currency_mcp_server/test_server.py

Das Testskript stellt über Client von FastMCP eine Verbindung zum MCP-Endpunkt her, listet die Tools auf und ruft get_exchange_rate auf:

Connecting to MCP server at: http://localhost:8080/mcp
--- 🛠️  Tool found: get_exchange_rate ---
--- 🪛  Calling get_exchange_rate tool for USD to EUR ---
--- ✅  Success: {"amount":1.0,"base":"USD","date":"2026-09-29","rates":{"EUR":0.84919}} ---

Sehr gut! Sie haben einen funktionierenden MCP-Server, der ein Live-Währungstool bereitstellt. Lassen Sie dieses Terminal für die nächsten Schritte geöffnet.

4. Währungs-Agent mit ADK erstellen

Jetzt erstellen Sie den Währungs-Agenten mit dem Agent Development Kit (ADK).

Das ADK bietet integrierte Unterstützung für MCP-Tools über die Klasse McpToolset. Der Währungs-Agent stellt über StreamableHTTPConnectionParams eine Verbindung zu unserem MCP-Server her.

Sehen Sie sich die Definition des Währungs-Agenten in currency_agent/agent.py an:

import logging
import os
from urllib.parse import urlparse

from dotenv import load_dotenv
from google.adk.agents import LlmAgent
from google.adk.a2a.utils.agent_to_a2a import to_a2a
from google.adk.tools.mcp_tool import McpToolset, StreamableHTTPConnectionParams

logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)

load_dotenv()

SYSTEM_INSTRUCTION = (
    "You are a specialized assistant for currency conversions. "
    "Your sole purpose is to use the 'get_exchange_rate' tool to answer questions about currency exchange rates. "
    "If the user asks about anything other than currency conversion or exchange rates, "
    "politely state that you cannot help with that topic and can only assist with currency-related queries. "
    "Do not attempt to answer unrelated questions or use tools for other purposes."
)

mcp_server_url = os.getenv("MCP_SERVER_URL", "http://localhost:8080/mcp")
if not mcp_server_url.endswith("/mcp"):
    mcp_server_url = f"{mcp_server_url.rstrip('/')}/mcp"

logger.info(f"--- 🔧 Loading MCP tools from MCP Server at {mcp_server_url}... ---")
logger.info("--- 🤖 Creating ADK Currency Agent... ---")

root_agent = LlmAgent(
    model="gemini-3.8-flash",
    name="currency_agent",
    description="An agent that can help with currency conversions",
    instruction=SYSTEM_INSTRUCTION,
    tools=[
        McpToolset(
            connection_params=StreamableHTTPConnectionParams(
                url=mcp_server_url
            )
        )
    ],
)

McpToolset erkennt und lädt das get_exchange_rate-Tool automatisch über HTTP direkt vom laufenden MCP-Server.

Währungsagenten mit der ADK-Web-UI testen

Sie können den Agenten isoliert über die Weboberfläche für die Entwicklung des ADK testen. Führen Sie im zweiten Terminal Folgendes aus:

uv run adk web --allow_origins "*" currency_agent

Öffnen Sie Ihren Browser unter http://localhost:8000 oder klicken Sie in Cloud Shell auf Webvorschau.

ADK-Web-Währungs-Agent

Stellen Sie dem KI-Agenten folgende Frage:

„Wie viel sind 250 USD in EUR?“

Sie sehen, dass der Agent das MCP-Tool get_exchange_rate aufruft und den umgerechneten Betrag zurückgibt. Beenden Sie den adk web-Prozess mit Ctrl+C, bevor Sie fortfahren.

5. Agent2Agent-Protokoll (A2A)

Das Agent2Agent-Protokoll (A2A) ist ein offener Standard, der die Kommunikation und Zusammenarbeit zwischen KI-Agenten ermöglichen soll.

In modernen Multi-Agenten-Systemen werden KI-Agenten häufig mit verschiedenen Frameworks (ADK, LangChain, CrewAI, AutoGen) erstellt und auf unterschiedlichen Infrastrukturen bereitgestellt. A2A bricht diese Silos auf, indem ein standardisierter Kommunikationsvertrag definiert wird.

A2A-Protokoll

Wichtige Konzepte von A2A

  • Agentenerkennung (Agentenkarte): Jeder A2A-konforme Agent gibt seine Funktionen, unterstützten E/A-Modi, Authentifizierungsanforderungen und Fähigkeiten über eine Standard-JSON-Datei bekannt, die unter /.well-known/agent-card.json gehostet wird.
  • Agentische Skills (AgentSkill): Bestimmte Funktionen oder Tools, die der KI-Agent ausführen kann. Andere KI-Agenten lesen diese Fähigkeiten, um zu entscheiden, wann sie Aufgaben delegieren sollen.
  • JSON-RPC-Kommunikation: Agenten tauschen strukturierte Nachrichten, Aufgaben und Artefakte über Standardtransportprotokolle wie HTTP JSON-RPC 2.0 aus.

Karte des A2A-KI-Agenten

Im nächsten Schritt machen Sie den ADK-Währungsumrechnungs-Agenten als A2A-Server verfügbar, damit andere KI-Agenten ihn finden und ihm Aufgaben zur Währungsumrechnung übertragen können.

6. Currency Agent als A2A-Server bereitstellen

Mit dem ADK können Sie jeden LlmAgent mit der Dienstfunktion to_a2a() ganz einfach in einen A2A-kompatiblen Server umwandeln.

Sehen Sie sich den unteren Teil von currency_agent/agent.py an:

# Make the agent A2A-compatible
PORT = int(os.getenv("PORT", 8081))
AGENT_URL = os.getenv("AGENT_URL")

if AGENT_URL:
    parsed = urlparse(AGENT_URL)
    protocol = parsed.scheme or "https"
    host = parsed.hostname
    port = parsed.port or 443
else:
    protocol = "http"
    host = "localhost"
    port = PORT

a2a_app = to_a2a(root_agent, host=host, port=port, protocol=protocol)

if __name__ == "__main__":
    import uvicorn

    logger.info(f"🚀 Starting currency_agent on port {PORT}")
    uvicorn.run(a2a_app, host="0.0.0.0", port=PORT)

Der to_a2a()-Helper führt automatisch Folgendes aus:

  1. Prüft die Tools und Anweisungen des LlmAgent.
  2. Generiert eine A2A-AgentCard, die die Fähigkeiten des Agenten beschreibt (z.B. currency_agent-get_exchange_rate).
  3. Verpackt den Agenten in eine FastAPI-Anwendung (a2a_app), die JSON-RPC-Endpunkte unterstützt.
  4. Konfiguriert die beworbene url in der Agentenkarte dynamisch basierend auf AGENT_URL (oder localhost).

Currency Agent-A2A-Server starten

Starten Sie den Währungs-KI-Agenten im zweiten Terminal:

uv run python currency_agent/agent.py

Der Server wird an Port 8081 gestartet:

[INFO]: --- 🔧 Loading MCP tools from MCP Server at http://localhost:8080/mcp... ---
[INFO]: --- 🤖 Creating ADK Currency Agent... ---
[INFO]: 🚀 Starting currency_agent on port 8081
INFO:     Started server process
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://0.0.0.0:8081 (Press CTRL+C to quit)

Agentenkarte prüfen

Rufen Sie in Ihrem Browser den Endpunkt der Agentenkarte auf: http://localhost:8081/.well-known/agent-card.json

Die automatisch generierten JSON-Metadaten werden angezeigt:

{
  "name": "currency_agent",
  "description": "An agent that can help with currency conversions",
  "supportedInterfaces": [
    {
      "url": "http://localhost:8081",
      "protocolBinding": "JSONRPC",
      "protocolVersion": "1.0"
    }
  ],
  "version": "0.0.1",
  "capabilities": {
    "streaming": true
  },
  "defaultInputModes": [
    "text/plain"
  ],
  "defaultOutputModes": [
    "text/plain"
  ],
  "skills": [
    {
      "id": "currency_agent",
      "name": "model",
      "description": "An agent that can help with currency conversions",
      "tags": [
        "llm"
      ]
    },
    {
      "id": "currency_agent-get_exchange_rate",
      "name": "get_exchange_rate",
      "description": "Use this to get current exchange rate.",
      "tags": [
        "llm",
        "tools"
      ]
    }
  ]
}

Mit dem A2A-Client testen

Öffnen Sie ein drittes Terminal, rufen Sie den Ordner python (cd getting-started-mcp-a2a-adk/python) auf und testen Sie den A2A-Endpunkt mit dem dedizierten A2A-Testclientskript:

uv run python currency_agent/test_a2aclient.py

Der Client löst die Agentenkarte mit A2ACardResolver auf und sendet eine JSON-RPC-Nachricht:

🔄 Fetching the agent card at http://localhost:8081
✅ Successfully fetched the agent card
====================================================
                     AgentCard                      
====================================================
Name        : currency_agent
Description : An agent that can help with currency conversions
Interfaces  : [0] http://localhost:8081  (JSONRPC 1.0)
Skills      : currency_agent, currency_agent-get_exchange_rate
====================================================
🔄 Initializing a non-streaming client
Sending request: "how much is 100 USD in GBP?"
Response:
100 USD is currently equal to approximately 73.37 GBP...

Der Währungs-Agent ist jetzt als voll funktionsfähiger A2A-Server im Einsatz.

7. Reisebüro-KI-Agenten erstellen

Jetzt erstellen Sie das orchestrierende Reisebüro. Dieser Agent zeigt, wie ein ADK-Agent zwei verschiedene Tool-Paradigmen mühelos kombinieren kann:

  1. Lokales Agent-Tool (weather_agent): Ein prozessinterner ADK-Subagent, der in derselben Python-Laufzeit ausgeführt wird, wodurch Netzwerk- oder Serialisierungslatenzen vermieden werden.
  2. Remote-Agent-Tool (currency_agent): Ein externer Agent, der über das Netzwerk über das A2A-Protokoll mit RemoteA2aAgent verbunden ist.
                    +-----------------------------+
                    |        travel_agent         |
                    | (Orchestrator with Web UI)  |
                    +--------------+--------------+
                                   |
             +---------------------+---------------------+
             | (In-process call)                         | (A2A Network Hop)
             v                                           v
+-------------------------+                 +-------------------------+
|   weather_agent         |                 |   currency_agent        |
|  (Local AgentTool)      |                 |  (Remote A2A Agent)     |
|  Calls wttr.in API      |                 |  Calls Currency MCP Svc |
+-------------------------+                 +-------------------------+

1. Sub-Agent für lokales Wetter

Sehen Sie sich travel_agent/subagents/weather_agent.py an:

import logging
import httpx
from google.adk.agents import LlmAgent

logger = logging.getLogger(__name__)

SYSTEM_INSTRUCTION = (
    "You are a specialized assistant for providing weather forecasts and conditions for travel destinations. "
    "Your sole purpose is to use the 'get_weather' tool to fetch weather information. "
    "Provide clear, concise summaries of current weather conditions, temperatures, and forecasts to help travelers pack and plan."
)


def get_weather(location: str = "London") -> dict:
    """Gets the current weather and forecast for a given location or city."""
    logger.info(f"--- 🌤️ Tool: get_weather called for {location} ---")
    try:
        response = httpx.get(
            f"https://wttr.in/{location}?format=j1",
            headers={"User-Agent": "curl/7.68.0"},
            timeout=8.0,
        )
        response.raise_for_status()
        data = response.json()
        current = data["current_condition"][0]
        return {
            "location": location,
            "condition": current.get("weatherDesc", [{}])[0].get("value", "Unknown"),
            "temperature_celsius": f"{current.get('temp_C', 'N/A')}°C",
            "temperature_fahrenheit": f"{current.get('temp_F', 'N/A')}°F",
            "humidity": f"{current.get('humidity', 'N/A')}%",
            "wind_speed_kmph": f"{current.get('windspeedKmph', 'N/A')} km/h",
        }
    except Exception as e:
        logger.warning(f"⚠️ Weather lookup failed: {e}. Returning simulated estimate.")
        return {
            "location": location,
            "condition": "Partly Cloudy",
            "temperature_celsius": "20°C",
            "temperature_fahrenheit": "68°F",
            "humidity": "55%",
            "wind_speed_kmph": "10 km/h",
            "note": f"Live data unavailable ({e}); showing estimated conditions.",
        }


weather_agent = LlmAgent(
    model="gemini-3.8-flash",
    name="weather_agent",
    description="A local specialist agent that provides current weather reports and forecasts for travel destinations.",
    instruction=SYSTEM_INSTRUCTION,
    tools=[get_weather],
)

Der Wetter-Agent ist ein LlmAgent mit einem Funktionstool, das Echtzeit-Wetterdaten von wttr.in mit einem robusten Fallback abruft.

2. Der Reisebüro-Orchestrator

Sehen Sie sich jetzt travel_agent/agent.py an:

import logging
import os
from dotenv import load_dotenv
from google.adk.agents import LlmAgent
from google.adk.tools.agent_tool import AgentTool
from google.adk.agents.remote_a2a_agent import RemoteA2aAgent, AGENT_CARD_WELL_KNOWN_PATH

try:
    from travel_agent.subagents.weather_agent import weather_agent
except ImportError:
    from subagents.weather_agent import weather_agent

logger = logging.getLogger(__name__)
logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)

load_dotenv()

SYSTEM_INSTRUCTION = (
    "You are a helpful travel assistant. You help users plan trips, recommend places, "
    "and answer travel-related questions.\n\n"
    "- Whenever a user asks about currency exchange rates or money conversions, "
    "delegate the request to the 'currency_agent' tool.\n"
    "- Whenever a user asks about the weather, climate, or forecasts for a destination, "
    "delegate the request to the 'weather_agent' tool."
)

CURRENCY_AGENT_URL = os.getenv("CURRENCY_AGENT_URL", "http://localhost:8081").rstrip("/")

logger.info(
    "--- 🔗 Connecting to Remote A2A Currency Agent at %s... ---",
    CURRENCY_AGENT_URL,
)

currency_remote_agent = RemoteA2aAgent(
    name="currency_agent",
    agent_card=f"{CURRENCY_AGENT_URL}{AGENT_CARD_WELL_KNOWN_PATH}",
    description="An agent that can help with currency conversions and exchange rates.",
)

logger.info("--- 🤖 Creating ADK Travel Agent... ---")

root_agent = LlmAgent(
    model="gemini-3.8-flash",
    name="travel_agent",
    description="A travel assistant that can help plan trips, check weather forecasts via the local weather agent, and convert currencies via the remote currency agent.",
    instruction=SYSTEM_INSTRUCTION,
    tools=[
        AgentTool(agent=currency_remote_agent),
        AgentTool(agent=weather_agent),
    ],
)

if __name__ == "__main__":
    import uvicorn
    from google.adk.cli.fast_api import get_fast_api_app

    PORT = int(os.getenv("PORT", 8082))
    logger.info(f"🚀 Starting travel_agent Web UI on port {PORT}")
    app = get_fast_api_app(web=True, allow_origins=["*"], agents_dir=os.path.dirname(__file__) or ".")
    uvicorn.run(app, host="0.0.0.0", port=PORT)

Wichtige Highlights:

  • RemoteA2aAgent ruft die Karte des Währungs-Agenten von http://localhost:8081/.well-known/agent-card.json ab.
  • Sowohl currency_remote_agent als auch weather_agent werden mit dem AgentTool des ADK umschlossen.
  • Wenn Sie travel_agent/agent.py ausführen, wird die ADK-Web-UI direkt auf Port 8082 mit get_fast_api_app(web=True) gestartet.

8. Multi-Agenten-System lokal ausführen und testen

Jetzt sind alle drei Komponenten bereit. Führen Sie das gesamte System lokal aus und testen Sie es.

Alle drei Dienste ausführen

Achten Sie darauf, dass die Dienste in drei separaten Terminalfenstern (im Verzeichnis getting-started-mcp-a2a-adk/python) in der folgenden Reihenfolge ausgeführt werden:

Terminal 1 (MCP-Server für Währungen):

uv run python currency_mcp_server/server.py

(Running on port 8080)

Terminal 2 (Currency A2A Agent):

uv run python currency_agent/agent.py

(Running on port 8081)

Terminal 3 (Reisebüro mit Web-UI):

uv run python travel_agent/agent.py

(Running on port 8082)

Über die ADK-Web-UI testen

Öffnen Sie Ihren Browser unter http://localhost:8082 (oder verwenden Sie die Webvorschau auf Port 8082 in Cloud Shell).

Stellen Sie dem Reisebüro-Agenten eine zusammengesetzte Frage, für die beide Tools erforderlich sind:

„Ich plane eine Reise nach London. Wie ist das Wetter und wie viel sind 200 Euro in Pfund?

Sehen Sie sich den Ablauf der Ausführung an:

  1. Das Reisebüro erhält die Anfrage in der Web-UI.
  2. Sie delegiert die Wetterfrage im Prozess an die lokale weather_agent, die die aktuellen Bedingungen von wttr.in abruft.
  3. Die Währungsumrechnung wird über das A2A-Protokoll an currency_agent auf Port 8081 delegiert.
  4. Der currency_agent ruft den currency_mcp_server über MCP an Port 8080 auf, um den Wechselkurs abzurufen.
  5. Alle Ergebnisse werden zusammengefasst und in einer einheitlichen, hilfreichen Antwort an Sie zurückgegeben.

ADK Web Remote Currency Agent

Über die Befehlszeile testen

Sie können Abfragen auch direkt über die Befehlszeile testen, ohne einen Browser zu öffnen:

uv run adk run travel_agent "What is the weather in London and how much is 100 USD in EUR?"

Nachdem alles auf Ihrem lokalen Computer reibungslos funktioniert, stellen wir das gesamte System in Google Cloud Run bereit.

9. Multi-Agenten-System in Cloud Run bereitstellen

Jede Komponente hat ein eigenes Dockerfile und ein eigenständiges pyproject.toml, sodass sie unabhängig voneinander erstellt und in Cloud Run bereitgestellt werden können.

Mit gcloud stellen Sie die einzelnen Dienste bereit und verknüpfen ihre URLs automatisch.

Umgebungsvariablen festlegen

Legen Sie Ihre Cloud-Projekt-ID und die Zielregion fest:

export PROJECT_ID=<YOUR_GOOGLE_CLOUD_PROJECT_ID>
export REGION=us-central1

Schritt 1: MCP-Server für Währungen bereitstellen

Stellen Sie den MCP-Server direkt aus der Quelle bereit:

# 1. Deploy MCP server
gcloud run deploy currency-mcp-server \
  --source currency_mcp_server \
  --region $REGION \
  --allow-unauthenticated

# 2. Capture the deployed MCP server URL
MCP_SERVER_URL=$(gcloud run services describe currency-mcp-server --region $REGION --format='value(status.url)')/mcp
echo "MCP Server URL: $MCP_SERVER_URL"

Schritt 2: Currency Agent bereitstellen

Da die öffentliche URL von currency-agent bei der ersten Bereitstellung zugewiesen wird, müssen Sie den Dienst zuerst bereitstellen, seine URL erfassen und die Umgebungsvariable AGENT_URL aktualisieren, damit die A2A-Agentenkarte die richtige öffentliche HTTPS-Adresse enthält:

# 1. Deploy Currency Agent connected to the deployed MCP Server
gcloud run deploy currency-agent \
  --source currency_agent \
  --region $REGION \
  --allow-unauthenticated \
  --update-env-vars MCP_SERVER_URL="$MCP_SERVER_URL",GOOGLE_GENAI_USE_ENTERPRISE="true",GOOGLE_CLOUD_PROJECT="$PROJECT_ID",GOOGLE_CLOUD_LOCATION="global"

# 2. Capture its assigned Cloud Run URL
CURRENCY_AGENT_URL=$(gcloud run services describe currency-agent --region $REGION --format='value(status.url)')
echo "Currency Agent URL: $CURRENCY_AGENT_URL"

# 3. Update AGENT_URL so the agent advertises its public HTTPS endpoint in its Agent Card
gcloud run services update currency-agent \
  --region $REGION \
  --update-env-vars AGENT_URL="$CURRENCY_AGENT_URL"

Schritt 3: Reisebüro bereitstellen

Stellen Sie jetzt den Reise-Agenten bereit und konfigurieren Sie ihn mit der CURRENCY_AGENT_URL:

# 1. Deploy Travel Agent (with ADK Web UI) connected to Currency Agent
gcloud run deploy travel-agent \
  --source travel_agent \
  --region $REGION \
  --allow-unauthenticated \
  --update-env-vars CURRENCY_AGENT_URL="$CURRENCY_AGENT_URL",GOOGLE_GENAI_USE_ENTERPRISE="true",GOOGLE_CLOUD_PROJECT="$PROJECT_ID",GOOGLE_CLOUD_LOCATION="global"

# 2. Capture its assigned Cloud Run URL
TRAVEL_AGENT_URL=$(gcloud run services describe travel-agent --region $REGION --format='value(status.url)')
echo "Travel Agent URL: $TRAVEL_AGENT_URL"

10. Multi-Agenten-System in Cloud Run testen

Nachdem alle drei Mikrodienste bereitgestellt wurden, überprüfen wir die einzelnen Ebenen in Cloud Run.

1. Remote-MCP-Server testen

Testen Sie den bereitgestellten Cloud Run-MCP-Server über die Befehlszeile:

MCP_SERVER_URL="$MCP_SERVER_URL" uv run python currency_mcp_server/test_server.py

Das Tool sollte aufgeführt und erfolgreich in Cloud Run aufgerufen werden.

2. Währungs-Agent über A2A testen

Testen Sie den bereitgestellten Currency Agent mit dem A2A-Testclient:

AGENT_URL="$CURRENCY_AGENT_URL" uv run python currency_agent/test_a2aclient.py

Der Client ruft die Remote-Agentenkarte von Cloud Run ab und tauscht Nachrichten über HTTPS JSON-RPC aus.

3. Web-UI des Reisebüros in Cloud Run testen

Öffnen Sie $TRAVEL_AGENT_URL in Ihrem Browser.

Die vollständige ADK-Web-UI wird direkt über Cloud Run bereitgestellt. Frag zum Beispiel:

„Ich plane eine Reise nach Tokio. Wie ist das Wetter und wie viel sind 500 USD in JPY?

[Browser] 
   │
   ▼ (HTTPS)
[Cloud Run: travel-agent]
   ├──> Local in-process tool: weather_agent (wttr.in)
   └──> A2A JSON-RPC (HTTPS)
           │
           ▼
        [Cloud Run: currency-agent]
           └──> MCP Streamable HTTP (HTTPS)
                   │
                   ▼
                [Cloud Run: currency-mcp-server] (Frankfurter API)

Alle drei Dienste werden unabhängig voneinander auf einer serverlosen Infrastruktur skaliert und kommunizieren nahtlos über offene Protokolle.

11. Glückwunsch und Aufräumen

Ihr Lernerfolg

Glückwunsch! Sie haben ein produktionsreifes Multi-Agenten-System erstellt und bereitgestellt:

  • Model Context Protocol (MCP): Es wurde ein FastMCP-Server erstellt, der Live-API-Tools über Streamable HTTP bereitstellt.
  • Agent Development Kit (ADK): Sie haben modulare Agenten mit LlmAgent erstellt, MCP-Tools mit McpToolset verbunden und die ADK-Web-UI gehostet.
  • Agent2Agent-Protokoll (A2A): Sie haben einen KI-Agenten als A2A-Dienst (to_a2a) bereitgestellt, Agentenkarten (agent-card.json) veröffentlicht und Remote-KI-Agenten mit RemoteA2aAgent verwendet.
  • Multi-Agenten-Architektur: Kombiniert lokale prozessinterne Sub-Agenten (weather_agent) mit verteilten Remote-Agenten (currency_agent).
  • Serverlose Bereitstellung mit Cloud Run: Alle drei Dienste wurden containerisiert und mit automatisierter Konfigurationsverknüpfung bereitgestellt.

Den vollständigen Code (einschließlich der Python- und Java-Implementierungen) und zukünftige Updates finden Sie im getting-started-mcp-a2a-adk-Repository.

Bereinigen

So vermeiden Sie, dass Ihrem Google Cloud-Konto die in diesem Codelab erstellten Cloud Run-Dienste in Rechnung gestellt werden:

Löschen Sie die bereitgestellten Cloud Run-Dienste:

gcloud run services delete currency-mcp-server --region $REGION --quiet
gcloud run services delete currency-agent --region $REGION --quiet
gcloud run services delete travel-agent --region $REGION --quiet

Wenn Sie für dieses Codelab ein eigenes Projekt erstellt haben, können Sie alternativ das gesamte Projekt beenden:

gcloud projects delete $PROJECT_ID