MCP、ADK、A2A のスタートガイド

1. 概要

AI エージェントは急速に普及しており、自律的に動作し、学習し、環境とやり取りして目標を達成する能力により、タスクの自動化と意思決定に革命をもたらしています。

では、エージェントを構築するにはどうすればよいでしょうか?この Codelab では、さまざまな国の通貨を換算できる通貨エージェントを構築する方法を紹介します。次に、旅行代理店のエージェントを構築し、通貨エージェントに接続します。この Codelab の目的は、最新のテクノロジーについて説明し、インターネット上でよく見かける頭字語(MCP、ADK、A2A)の意味と、それらがどのように連携しているかを理解していただくことです。

アーキテクチャ

Model Context Protocol(MCP)

Model Context Protocol(MCP) は、アプリケーションが LLM にコンテキストを提供する方法を標準化するオープン プロトコルです。MCP は、AI モデルをリソース、プロンプト、ツールに接続する標準化された方法を提供します。

Agent Development Kit(ADK)

Agent Development Kit(ADK)は、AI エージェントの開発とデプロイのための柔軟なオーケストレーション フレームワークです。ADK はモデルやデプロイに依存せず、他のフレームワークとの互換性を保つよう構築されています。ADK は、エージェント開発をソフトウェア開発のような感覚で行えるよう設計されており、デベロッパーは基本的なタスクから複雑なワークフローまで、幅広いエージェント アーキテクチャを簡単に作成、デプロイ、オーケストレートできます。

Agent2Agent(A2A)プロトコル

Agent2Agent (A2A) プロトコルは、AI エージェント間のシームレスな通信とコラボレーションを可能にするように設計されたオープン スタンダードです。MCP が LLM にデータとツールへのアクセス権を付与する標準化された方法を提供するのと同じように、A2A はエージェントが他のエージェントと通信するための標準化された方法を提供します。さまざまなフレームワークを使用してさまざまなベンダーによってエージェントが構築される世界では、A2A は共通言語を提供し、サイロを解消して相互運用性を促進します。

学習内容

  • ローカル MCP サーバーを作成する方法
  • MCP サーバーを Cloud Run にデプロイする
  • MCP ツールを使用する Agent Development Kit でエージェントを構築する方法
  • ADK エージェントを A2A サーバーとして公開する方法
  • A2A クライアントを使用して A2A サーバーをテストする
  • A2A プロトコルを介して別のエージェントと通信するエージェントを構築する方法

必要なもの

  • ブラウザ(ChromeFirefox など)
  • 課金を有効にした Google Cloud プロジェクト

2. 始める前に

プロジェクトを作成する

Google Cloud プロジェクトがない場合は、作成します。

Google Cloud コンソールのプロジェクト選択ページで、Google Cloud プロジェクトを選択または作成します。

また、Cloud プロジェクトで課金が有効になっていることを確認します。プロジェクトで課金が有効になっているかどうかを確認する方法をご覧ください。

Cloud Shell をアクティブにする

Google Cloud Shell は、Google Cloud コンソール内で直接提供される、ブラウザベースのインタラクティブな開発環境です。ツールをローカルにインストールしなくても、Google Cloud を簡単に使い始めることができます。

こちらのリンクをクリックして、Cloud Shell をアクティブにします。Cloud Shell ターミナル(クラウド コマンドの実行用)とエディタ(プロジェクトの構築用)を切り替えるには、Cloud Shell の対応するボタンをクリックします。

Cloud Shell に接続したら、次のコマンドを使用して、すでに認証済みであることと、プロジェクトがプロジェクト ID に設定されていることを確認します。

gcloud auth list

Cloud Shell で次のコマンドを実行して、gcloud コマンドがプロジェクトを認識していることを確認します。

gcloud config list project

次のコマンドを使用して、プロジェクトを設定します。

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

Cloud APIs を有効にする

次のコマンドを使用して、必要な API を有効にします。これには数分かかることがあります。

gcloud services enable cloudresourcemanager.googleapis.com \
                       servicenetworking.googleapis.com \
                       run.googleapis.com \
                       cloudbuild.googleapis.com \
                       artifactregistry.googleapis.com \
                       aiplatform.googleapis.com \
                       compute.googleapis.com

gcloud コマンドとその使用方法については、ドキュメントをご覧ください。

コードを取得する

リポジトリのクローンを作成します。

git clone https://github.com/jackwotherspoon/currency-agent.git
cd currency-agent

uv は依存関係の管理に使用され、Cloud Shell にすでにインストールされていますが、Codelab をローカルで実行する場合は、次のようにインストールできます。

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

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

次のコマンドを実行して、.env ファイルで環境変数を構成します。

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

3. ローカル MCP サーバーを作成する

通貨エージェントのオーケストレーションを行う前に、エージェントに必要なツールを公開するための MCP サーバーを作成します。

MCP サーバーを使用すると、軽量プログラムを作成して、特定の機能(通貨換算レートの取得など)をツールとして公開できます。エージェントまたは複数のエージェントは、標準化された Model Context Protocol(MCP)を使用してこれらのツールにアクセスできます。

FastMCP Python パッケージを利用して、get_exchange_rate という単一のツールを公開する MCP サーバーを作成できます。get_exchange_rate ツールは、インターネット経由で Frankfurter API を呼び出して、2 つの通貨間の現在の換算レートを取得します。

MCP サーバーのコードは、mcp-server/server.py ファイルにあります。

import logging
import os

import httpx
from fastmcp import FastMCP

# Set up logging
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.app/{currency_date}',
            params={'from': currency_from, 'to': currency_to},
        )
        response.raise_for_status()

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

if __name__ == "__main__":
    logger.info(f"🚀 MCP server started on port {os.getenv('PORT', 8080)}")
    # 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=os.getenv("PORT", 8080),
        )
    )

MCP サーバーをローカルで起動するには、ターミナルを開いて次のコマンドを実行します(サーバーは http://localhost:8080 で起動します)。

uv run mcp-server/server.py

MCP サーバーが正しく機能し、Model Context Protocol を使用して get_exchange_rate ツールにアクセスできることをテストします。

新しいターミナル ウィンドウで(ローカル MCP サーバーを停止しないように)、次のコマンドを実行します。

uv run mcp-server/test_server.py

1 米ドル(USD)からユーロ(EUR)への現在の換算レートが出力されます。

--- 🛠️ Tool found: get_exchange_rate ---
--- 🪛 Calling get_exchange_rate tool for USD to EUR ---
---  Success: {
  "amount": 1.0,
  "base": "USD",
  "date": "2025-05-26",
  "rates": {
    "EUR": 0.87866
  }
} ---

ところ、エージェントがアクセスできるツールを備えた MCP サーバーが正常に動作しています。

次のステーションに進む前に、起動したターミナルで Ctrl+C(Mac の場合は Command+C)を実行して、ローカルで実行中の MCP サーバーを停止します。

4. MCP サーバーを Cloud Run にデプロイする

これで、MCP サーバーをリモート MCP サーバーとして Cloud Run にデプロイする準備ができました 🚀☁️

MCP サーバーをリモートで実行するメリット

MCP サーバーを Cloud Run でリモートで実行すると、次のようなメリットがあります。

  • 📈 スケーラビリティ: Cloud Run は、すべての受信リクエストを処理するために迅速にスケールアウトするように構築されています。Cloud Run は、需要に応じて MCP サーバーを自動的にスケールします。
  • 👥 集中型サーバー: 集中型 MCP サーバーへのアクセスを IAM 権限を通じてチームメンバーと共有できます。これにより、各自のローカルマシンからサーバーに接続でき、ローカルで独自のサーバーを実行する必要がなくなります。また、MCP サーバーに変更が加えられた場合はそれをチームメンバー全員が利用できます。
  • 🔐 セキュリティ: Cloud Run では、リクエストの認証を簡単に必須化できます。これにより、MCP サーバーへの安全な接続のみが許可され、不正アクセスが防止されます。

mcp-server ディレクトリに移動します。

cd mcp-server

MCP サーバーを Cloud Run にデプロイします。

gcloud run deploy mcp-server --no-allow-unauthenticated --region=us-central1 --source .

サービスが正常にデプロイされると、次のようなメッセージが表示されます。

Service [mcp-server] revision [mcp-server-12345-abc] has been deployed and is serving 100 percent of traffic.

MCP クライアントの認証

--no-allow-unauthenticated を指定して認証を必須にしたため、リモート MCP サーバーに接続する MCP クライアントは認証を受ける必要があります。

Cloud Run で MCP サーバーをホストする方法に関する公式ドキュメントで、MCP クライアントの実行場所別にこのトピックに関する詳細情報を提供しています。

ローカルマシンで Cloud Run プロキシ を実行して、リモート MCP サーバーへの認証済みトンネルを作成する必要があります。

デフォルトでは、Cloud Run サービスの URL では、すべてのリクエストに Cloud Run 起動元roles/run.invoker)IAM ロールによる認可が必要です。この IAM ポリシー バインディングにより、ローカル MCP クライアントの認証に強力なセキュリティ メカニズムが使用されます。

リモート MCP サーバーにアクセスしようとしているチームメンバーに、IAM プリンシパル(Google Cloud アカウント)にバインドされた roles/run.invoker IAM ロールがあることを確認します。

gcloud run services proxy mcp-server --region=us-central1

次の出力が表示されます。

Proxying to Cloud Run service [mcp-server] in project [<YOUR_PROJECT_ID>] region [us-central1]
http://127.0.0.1:8080 proxies to https://mcp-server-abcdefgh-uc.a.run.app

これで、http://127.0.0.1:8080 へのすべてのトラフィックが認証され、リモート MCP サーバーに転送されます。

リモート MCP サーバーをテストする

新しいターミナルで、ルートフォルダに戻り、mcp-server/test_server.py ファイルを再度実行して、リモート MCP サーバーが動作していることを確認します。

cd ..
uv run mcp-server/test_server.py

サーバーをローカルで実行した場合と同様の出力が表示されます。

--- 🛠️ Tool found: get_exchange_rate ---
--- 🪛 Calling get_exchange_rate tool for USD to EUR ---
---  Success: {
  "amount": 1.0,
  "base": "USD",
  "date": "2025-05-26",
  "rates": {
    "EUR": 0.87866
  }
} ---

デプロイされた Cloud Run MCP サーバーのログをクエリして、リモート サーバーが実際に呼び出されたことを確認できます。

gcloud run services logs read mcp-server --region us-central1 --limit 5

ログに次の出力が表示されます。

2025-06-04 14:28:29,871 [INFO]: --- 🛠️ Tool: get_exchange_rate called for converting USD to EUR ---
2025-06-04 14:28:30,610 [INFO]: HTTP Request: GET https://api.frankfurter.app/latest?from=USD&to=EUR "HTTP/1.1 200 OK"
2025-06-04 14:28:30,611 [INFO]:  API response: {'amount': 1.0, 'base': 'USD', 'date': '2025-06-03', 'rates': {'EUR': 0.87827}}

リモート MCP サーバーができたので、エージェントの作成に進みましょう。🤖

5. ADK でエージェントを作成する

MCP サーバーがデプロイされたので、Agent Development Kit(ADK)を使用して通貨エージェントを作成します。

ADK を使用すると、エージェントを非常に軽量に作成でき、MCP ツールを組み込みでサポートする MCP サーバーに接続できます。通貨エージェントは、ADK の MCPToolset クラスを使用して get_exchange_rate ツールにアクセスします。

通貨エージェントのコードは currency_agent/agent.py にあります。

import logging
import os

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."
)

logger.info("--- 🔧 Loading MCP tools from MCP Server... ---")
logger.info("--- 🤖 Creating ADK Currency Agent... ---")

root_agent = LlmAgent(
    model="gemini-3.7-flash",
    name="currency_agent",
    description="An agent that can help with currency conversions",
    instruction=SYSTEM_INSTRUCTION,
    tools=[
        MCPToolset(
            connection_params=StreamableHTTPConnectionParams(
                url=os.getenv("MCP_SERVER_URL", "http://localhost:8080/mcp")
            )
        )
    ],
)

通貨エージェントをすばやくテストするには、adk web を実行してアクセスする ADK の開発 UI を利用できます。

uv run adk web --allow_origins "regex:https://.*\.cloudshell\.dev"

ブラウザで http://localhost:8000 にアクセスして、エージェントを表示してテストします。

ウェブ UI の左上にあるエージェントとして currency_agent が選択されていることを確認します。

ADK ウェブ UI

チャットエリアでエージェントに「250 カナダドルは米ドルでいくらですか?」と尋ねます。エージェントが応答する前に、get_exchange_rate MCP ツールを呼び出すことがわかります。

ADK Web の通貨エージェント

エージェントが動作します。通貨換算に関するクエリを処理できます 💸。

6. Agent2Agent(A2A)プロトコル

Agent2Agent (A2A) プロトコルは、AI エージェント間のシームレスな通信とコラボレーションを可能にするように設計されたオープン スタンダードです。これにより、さまざまなフレームワークを使用してさまざまなベンダーによって構築されたエージェントが、共通言語で相互に通信し、サイロを解消して相互運用性を促進できます。

A2A プロトコル

A2A を使用すると、エージェントは次のことができます。

  • 検出: 標準化されたエージェント カードを使用して、他のエージェントを見つけ、そのスキル(AgentSkill)と機能(AgentCapabilities)を学習します。
  • 通信: メッセージとデータを安全に交換します。
  • コラボレーション: タスクを委任し、アクションを調整して複雑な目標を達成します。

A2A プロトコルは、エージェントが機能と接続情報を通知するために使用できるデジタル名刺として機能する「エージェント カード」などのメカニズムを通じて、この通信を容易にします。

A2A エージェント カード

通貨エージェントを A2A を使用して公開し、他のエージェントやクライアントから呼び出せるようにします。

A2A Python SDK

A2A Python SDK は、前述のリソース(AgentSkillAgentCapabilitiesAgentCard)ごとに Pydantic モデルを提供します。これにより、A2A プロトコルとの開発と統合を迅速化するためのインターフェースが提供されます。

AgentSkill は、通貨エージェントに get_exchange_rate のツールがあることを他のエージェントに通知する方法です。

# A2A Agent Skill definition
skill = AgentSkill(
    id='get_exchange_rate',
    name='Currency Exchange Rates Tool',
    description='Helps with exchange values between various currencies',
    tags=['currency conversion', 'currency exchange'],
    examples=['What is exchange rate between USD and GBP?'],
)

次に、AgentCard の一部として、エージェントのスキルと機能が、エージェントが処理できる入力モードや出力モードなどの詳細とともに一覧表示されます。

# A2A Agent Card definition
agent_card = AgentCard(
    name='Currency Agent',
    description='Helps with exchange rates for currencies',
    url=f'http://{host}:{port}/',
    version='1.0.0',
    defaultInputModes=["text"],
    defaultOutputModes=["text"],
    capabilities=AgentCapabilities(streaming=True),
    skills=[skill],
)

通貨エージェントと A2A の機能を組み合わせる時が来ました。

7. 通貨エージェントを A2A サーバーとして公開する

ADK を使用すると、A2A プロトコルを使用してエージェントを構築して接続するプロセスが簡素化されます。既存の ADK エージェントをA2A サーバー としてアクセス可能にする(公開する)には、ADK の to_a2a(root_agent) 関数を使用します(詳細については、ADK のドキュメントをご覧ください)。

to_a2a 関数は、既存のエージェントを A2A で動作するように変換し、uvicorn を介してサーバーとして公開できるようにします。つまり、エージェントを本番環境で使用する場合は、公開するものをより細かく制御できます。to_a2a() 関数は、バックグラウンドでA2A Python SDK を使用して、エージェント コードに基づいてエージェント カードを自動生成します。

currency_agent/agent.py ファイルの中身を見ると、to_a2a の使用方法と、通貨エージェントがわずか 2 行のコードで A2A サーバーとして公開されていることがわかります。

from google.adk.a2a.utils.agent_to_a2a import to_a2a
# ... see file for full code

# Make the agent A2A-compatible
a2a_app = to_a2a(root_agent, port=10000)

A2A サーバーを実行するには、新しいターミナル で次のコマンドを実行します。

uv run uvicorn currency_agent.agent:a2a_app --host localhost --port 10000

サーバーが正常に起動すると、次のように出力され、ポート 10000 で実行されていることが示されます。

[INFO]: --- 🔧 Loading MCP tools from MCP Server... ---
[INFO]: --- 🤖 Creating ADK Currency Agent... ---
INFO:     Started server process [45824]
INFO:     Waiting for application startup.
INFO:     Application startup complete.
INFO:     Uvicorn running on http://localhost:10000 (Press CTRL+C to quit)

これで、通貨エージェントが A2A サーバーとして正常に実行され、A2A プロトコルを使用して他のエージェントやクライアントから呼び出すことができます。

リモート エージェントが実行されていることを確認する

エージェントが起動して実行されていることを再確認するには、to_a2a() 関数によって自動生成された通貨エージェントのエージェント カード URL にアクセスします。

ブラウザで http://localhost:10000/.well-known/agent-card.json にアクセスします。

次のエージェント カードが表示されます。

{
  "capabilities": {

  },
  "defaultInputModes": [
    "text/plain"
  ],
  "defaultOutputModes": [
    "text/plain"
  ],
  "description": "An agent that can help with currency conversions",
  "name": "currency_agent",
  "preferredTransport": "JSONRPC",
  "protocolVersion": "0.3.0",
  "skills": [
    {
      "description": "An agent that can help with currency conversions I am a specialized assistant for currency conversions. my 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 I 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.",
      "id": "currency_agent",
      "name": "model",
      "tags": [
        "llm"
      ]
    },
    {
      "description": "Use this to get current exchange rate.\n\nArgs:\n    currency_from: The currency to convert from (e.g., \"USD\").\n    currency_to: The currency to convert to (e.g., \"EUR\").\n    currency_date: The date for the exchange rate or \"latest\". Defaults to \"latest\".\n\nReturns:\n    A dictionary containing the exchange rate data, or an error message if the request fails.",
      "id": "currency_agent-get_exchange_rate",
      "name": "get_exchange_rate",
      "tags": [
        "llm",
        "tools"
      ]
    }
  ],
  "supportsAuthenticatedExtendedCard": false,
  "url": "http://localhost:10000",
  "version": "0.0.1"
}

A2A サーバーをテストする

A2A を使用してリクエストを送信することで、サーバーをテストできるようになりました。

A2A Python SDK には、この処理を簡素化する a2a.client.Client クラスが用意されています。

currency_agent/test_a2aclient.py ファイルには、エージェント カードを取得して A2A サーバーにメッセージを送信する方法を示すコードが含まれています。

# ... see file for full code

async def get_agent_card():
    """Get the agent card."""
    print(f"🔄 Fetching the agent card at {AGENT_URL}")

    async with httpx.AsyncClient() as httpx_client:
        resolver = A2ACardResolver(
            httpx_client=httpx_client,
            base_url=AGENT_URL,
        )
        public_agent_card = await resolver.get_agent_card()
        print("✅ Successfully fetched the agent card")
    return public_agent_card


async def send_message(text_query: str) -> None:
    """
    Send a text query to the agent and print the response.
    """
    public_agent_card = await get_agent_card()

    print("🔄 Initializing a non-streaming client")
    config = ClientConfig(streaming=False)
    client = await create_client(agent=public_agent_card, client_config=config)

    message = new_text_message(text_query, role=Role.ROLE_USER)
    print("Sending request:")
    request = SendMessageRequest(message=message)
    print(request)

    print("Response:")
    async for chunk in client.send_message(request):
        print(chunk)
    await client.close()

次のコマンドを使用してテストを実行します。

uv run currency_agent/test_a2aclient.py

テストが正常に実行されると、次のようになります。

🔄 Fetching the agent card at http://localhost:10000
 Successfully fetched the agent card
====================================================
                     AgentCard                      
====================================================
--- General ---
Name        : currency_agent
Description : An agent that can help with currency conversions
Version     : 0.0.1

--- Interfaces ---
  [0] http://localhost:10000  (JSONRPC 1.0)

--- Capabilities ---
Streaming           : False
Push notifications  : False
Extended agent card : False

--- I/O Modes ---
Input  : text/plain
Output : 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
====================================================
🔄 Fetching the agent card at http://localhost:10000
 Successfully fetched the agent card
🔄 Initializing a non-streaming client
Sending request:
message {
  message_id: "5d190c88-336e-4a22-925d-e2af49cf4bad"
  role: ROLE_USER
  parts {
    text: "how much is 100 USD in GBP?"
  }
}

Response:
task {
  id: "e6f311bb-654a-477f-82a9-81c7a48f7b81"
  context_id: "672e351b-0ff3-4aed-a059-868b383c41a0"
  status {
    state: TASK_STATE_COMPLETED
    timestamp {
      seconds: 1787836031
      nanos: 994786000
    }
  }
  artifacts {
    artifact_id: "e0a05ac8-25c7-471c-a33c-1073fe48cbb8"
    parts {
      text: "100 USD is currently equal to approximately **73.37 GBP** (at an exchange rate of 1 USD = 0.73368 GBP)."
    }
  }
  ...

動作しました。A2A クライアントを使用して A2A プロトコルで通貨エージェントと通信できることをテストしました。🎉

その他の A2A サンプルについては、GitHub の a2a-samples リポジトリをご覧ください。

8. A2A を介してリモート通貨エージェントを使用する

前のステップでは、A2A クライアントを使用して A2A を介して通貨エージェントと通信しました。

このステップでは、別の旅行代理店のエージェントから通貨エージェントをリモート エージェントとして使用する方法について説明します。

旅行代理店のエージェントのコードは travel_agent/agent.py にあります。

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

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. "
    "Whenever a user asks about currency exchange rates or money conversions, "
    "delegate the request to the 'currency_agent' sub-agent."
)

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

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.7-flash",
    name="travel_agent",
    description="A travel assistant that can help plan trips and convert currencies via the remote currency agent.",
    instruction=SYSTEM_INSTRUCTION,
    tools=[AgentTool(agent=currency_remote_agent)],
)

RemoteA2aAgent を使用して通貨エージェントにアクセスする方法に注目してください。

adk web を実行して、旅行代理店のエージェントをテストします。

uv run adk web --allow_origins "regex:https://.*\.cloudshell\.dev"

ブラウザで http://localhost:8000 にアクセスして、エージェントを表示してテストします。

ウェブ UI の左上にあるエージェントとして travel_agent が選択されていることを確認します。

チャットエリアでエージェントに「250 カナダドルは米ドルでいくらですか?」と尋ねます。

旅行代理店のエージェントが応答する前に、currency_agent をリモートで呼び出すことがわかります。

ADK Web リモート通貨エージェント

エージェントが動作します。A2A を使用してリモート エージェントを呼び出すことで、通貨換算に関するクエリを処理できます 💸。

9. 完了

おめでとうございます!リモート MCP サーバーを構築してデプロイし、MCP を使用してツールに接続する Agent Development Kit(ADK)を使用して通貨エージェントを作成し、Agent2Agent(A2A)プロトコルを使用してエージェントを公開しました。次に、A2A を使用して通貨エージェントとリモートで通信する旅行代理店のエージェントを作成しました。

コードのドキュメントへのリンクはこちらです。

エージェントのデプロイをお考えですか?Gemini Enterprise Agent Platform の Agent Runtime は、AI エージェントを本番環境にデプロイするためのマネージド エクスペリエンスを提供します。

学習した内容

  • ローカル MCP サーバーを作成する方法
  • MCP サーバーを Cloud Run にデプロイする
  • MCP ツールを使用する Agent Development Kit でエージェントを構築する方法
  • ADK エージェントを A2A サーバーとして公開する方法
  • A2A クライアントを使用して A2A サーバーをテストする
  • A2A プロトコルを介して別のエージェントと通信するエージェントを構築する方法

クリーンアップ

このラボで使用したリソースについて、Google Cloud アカウントに課金されないようにするには、次の手順を行います。

  1. Google Cloud コンソールで、[リソースの管理] ページに移動します。
  2. プロジェクト リストで、削除するプロジェクトを選択し、[削除] をクリックします。
  3. ダイアログでプロジェクト ID を入力し、[シャットダウン] をクリックしてプロジェクトを削除します。