🕵️ SicherheitslückenCVE-2026-8070 | ASUS Armoury Crate up to 6.4.12 permission assignment(17.09.2026 um 13:05 Uhr)
🕵️ SicherheitslückenCVE-2026-8919 | ASUS GameSDK up to 1.0.5 Web cross-domain policy(17.09.2026 um 13:05 Uhr)
🕵️ Reverse EngineeringHow Candidates Could Use AI for Good(17.09.2026 um 13:06 Uhr)
🕵️ SicherheitslückenCVE-2026-8070 | ASUS Armoury Crate up to 6.4.12 permission assignment(17.09.2026 um 13:05 Uhr)
🕵️ SicherheitslückenCVE-2026-8919 | ASUS GameSDK up to 1.0.5 Web cross-domain policy(17.09.2026 um 13:05 Uhr)
🕵️ Reverse EngineeringHow Candidates Could Use AI for Good(17.09.2026 um 13:06 Uhr)
🔧 Programmierung 🕛 vor 4 Monaten 17 Min Lesezeit
0

Building Capabilities for a Multi-Agent System with Google ADK, MCP, and Cloud Run

↗ Quelle (dev.to)
🗣️ Stimme:
📑 Inhaltsübersicht
📺
dev.to

My team's mission is to accelerate the developer journey from writing code to running secure AI workloads on Google Cloud. To help developers succeed, we focus on identifying their most pressing questions and building demos that provide straightforward, easy-to-implement solutions.



Recently, I was struck with inspiration when the new —to identify technical questions from Reddit, research them using official documentation, and draft detailed technical blogs. Dev Signal also provides custom visuals using layer so the agent remembers my specific preferences and blogging style.



By connecting my coding assistant, in just two days.



Whether you want to learn how to architect a complex multi-agent system with long term memory, leverage local and remote MCP servers for tool standardization, or write detailed Terraform scripts for secure Cloud Run deployment, I'll show you how!



If you'd rather dive straight into the code and explore it at your own pace, you can clone the repository – You'll build the "brain" of the system by implementing a root orchestrator and a team of specialized agents. You'll also integrate the – Before moving to the cloud, you'll synchronize the agent's components and verify its performance on your workstation. You'll use a dedicated test runner to simulate the full lifecycle of discovery, research, and multimodal creation, with a special focus on validating long-term memory persistence by connecting your local agent directly to the cloud-based Vertex AI memory bank.


  • (gcloud CLI) installed and authenticated.


  • (required for the Reddit MCP tool).



  • You will also need:




    • A : Vertex AI, Cloud Run, Secret Manager, Artifact Registry.


    • Reddit API Credentials (Client ID, Secret) - You can get these from the .






    Project Setup



    The Dev Signal system was built by first running the by . This foundation provided the project's modular directory structure, which is used to separate concerns between Agent Logic, Server Code, Utilities, and Tools.



    The starter pack acts as a powerful starting point because it automates the creation of professional infrastructure, CI/CD pipelines, and observability tools in seconds. This allows you to focus entirely on the agent's unique intelligence while ensuring the underlying platform remains secure and scalable. By building on top of this generated boilerplate with AI assistance from , the development process is highly accelerated.



    The agent starter pack high level architecture:



    to standardize this. The Model Context Protocol (MCP) is a universal standard for connecting AI agents to external data and tools. Instead of writing custom API wrappers, we use standard MCP servers. This allows us to connect to APIs (Reddit), Knowledge Bases (Google Cloud Docs), and even local scripts (Image Generation using Nano Banana Pro) using a common interface. Create a new directory for the agent tools.




    CODE
    mkdir tools
    cd tools









    Tools Configuration



    We'll define our toolsets in dev_signal_agent/tools/mcp_config.py.



    This file defines the connection parameters for our three main tools.





    • Reddit: Connected via a local stdio subprocess.


    • Developer Knowledge: Connected via a remote HTTP endpoint.


    • Nano Banana: Connected via a local stdio subprocess (our custom Python script).






    Reddit Search (Discovery Tool)



    The provides grounding for your agent by allowing it to search the entire corpus of official Google Cloud documentation. Unlike the local Reddit server, this is a managed service hosted by Google and accessed as a remote endpoint over the internet. It exposes specialized tools like google_developer_documentation_search for semantic queries and google_developer_documentation_fetch to retrieve full markdown content, ensuring that every technical claim the agent makes is supported by definitive, up-to-date facts.




    Note: You can also connect your coding assistant tools such as to the developer knowledge MCP server to empower them with handy up to date Google Cloud documentation. I used it when writing this blog!




    To connect, the agent uses the McpToolset class with StreamableHTTPConnectionParams, pointing to a web URL instead of launching a local process. It securely authenticates using a DK_API_KEY (: We use the fastmcp library to drastically simplify server creation, allowing us to register Python functions as tools with just a few lines of code.


  • Gemini Integration: The server uses the Google GenAI SDK to call the gemini-3-pro-image-preview model, which converts the agent's descriptive prompts into raw image bytes.


  • GCS Upload & Hosting: Because agent interfaces typically require a URL to display images, the server automatically uploads the generated bytes to Google Cloud Storage (GCS) and returns a public link.



  • To connect this local tool, we use StdioConnectionParams because the server runs as a local subprocess communicating via standard input and output. This transport method directly matches the transport="stdio" configuration we will define in our server entrypoint, ensuring a seamless connection for your custom local scripts.



    The following code defines the MCP connection in dev_signal_agent/tools/mcp_config.py. We use uv run to ensure the server starts in an isolated environment with all its dependencies correctly installed.



    Paste this code in dev_signal_agent/tools/mcp_config.py:




    CODE
    def get_nano_banana_mcp_toolset():
    """
    Connects to our local
    'Nano Banana' image generator.
    This demonstrates how to wrap a local Python script as an MCP tool.
    """
    path = os.path.join("dev_signal_agent", "tools", "nano_banana_mcp", "main.py")
    bucket = os.getenv("AI_ASSETS_BUCKET")

    return McpToolset(
    connection_params=StdioConnectionParams(
    server_params=StdioServerParameters(
    command="uv",
    args=["run", path],
    env={**os.environ, "AI_ASSETS_BUCKET": bucket}
    ),
    timeout=600.0 # Image generation can take time
    )
    )









    Implementing the Nano Banana Pro Server Logic



    Now, we will implement the actual logic for this server. This implementation is based on the by Remigiusz Samborski. While Remi's original code provides instructions for deploying the MCP server to Cloud Run, we will run it here as a local subprocess for faster development and testing.



    To get started, create the directory for our new server:




    CODE
    mkdir -p dev_signal_agent/tools/nano_banana_mcp
    cd dev_signal_agent/tools/nano_banana_mcp









    The Server Entrypoint (main.py)



    This file acts as the "brain" that initializes and starts the MCP server.





    • FastMCP Initialization: We use the FastMCP library to create a server named "MediaGenerators" and register our generate_image function as a tool.


    • Safe Logging: The _initialize_console_logging function is critical. It forces all logs to sys.stderr. This is because the MCP "stdio" transport uses sys.stdout for communication between the agent and the tool; standard logs sent to stdout would corrupt that protocol.


    • Execution: The mcp.run(transport="stdio") line starts the server as a local subprocess, allowing it to listen for requests from your agent via standard input.



    Paste this code in dev_signal_agent/tools/nano_banana_mcp/main.py:




    CODE
    import logging
    import os
    import sys
    from fastmcp import FastMCP
    from dotenv import load_dotenv
    from nano_banana_pro import generate_image

    def _initialize_console_logging(min_level: int = logging.INFO):
    # Ensure logs go to STDERR so they don't break the MCP stdio protocol
    handler = logging.StreamHandler(sys.stderr)
    logging.basicConfig(level=min_level, handlers=[handler], force=True)

    tools = [generate_image]
    mcp = FastMCP(name="MediaGenerators", tools=tools)

    if __name__ == "__main__":
    load_dotenv()
    _initialize_console_logging()
    mcp.run(transport="stdio")









    The Generation Logic (nano_banana_pro.py)



    This is where the actual image generation happens using Gemini.





    • GenAI Client: We initialize the genai.Client() to interact with Google's generative models.


    • Model Selection: It specifically targets the gemini-3-pro-image-preview model. We set the response_modalities to "IMAGE" to tell the model we want pixels, not just text.


    • Robustness: The code includes a MAX_RETRIES loop (set to 5) to handle any transient generation errors, ensuring the agent has multiple attempts to get a valid image.


    • Byte Processing: Once the model generates the image, it arrives as raw inline data. We extract these bytes and call our helper to move them to the cloud.


    • URI Conversion: Finally, it replaces the internal gs:// path with a browser-accessible https:// URL so the user can actually see the image.



    Paste this code in dev_signal_agent/tools/nano_banana_mcp/nano_banana_pro.py:




    CODE
    import logging
    from typing import Literal, Optional
    from google import genai
    from google.genai import types
    from media_models import MediaAsset
    from storage_utils import upload_data_to_gcs

    AUTHORIZED_URI = "https://storage.mtls.cloud.google.com/"
    MAX_RETRIES = 5

    async def generate_image(
    prompt: str,
    aspect_ratio: Literal["16:9", "9:16"] = "16:9",
    ) -> MediaAsset:
    """Generates an image using Gemini 3 Image model."""
    genai_client = genai.Client()
    content = types.Content(parts=[types.Part.from_text(text=prompt)], role="user")
    logging.info(f"Starting image generation for prompt: {prompt[:50]}...")

    asset = MediaAsset(uri="")
    for _ in range(MAX_RETRIES):
    response = genai_client.models.generate_content(
    model="gemini-3-pro-image-preview",
    contents=[content],
    config=types.GenerateContentConfig(
    response_modalities=["IMAGE"],
    image_config=types.ImageConfig(aspect_ratio=aspect_ratio)
    )
    )
    if response and response.parts:
    for part in response.parts:
    if part.inline_data and part.inline_data.data:
    # Upload the raw bytes to GCS
    gcs_uri = await upload_data_to_gcs(
    "mcp-tools",
    part.inline_data.data,
    part.inline_data.mime_type
    )
    asset = MediaAsset(uri=gcs_uri)
    break
    if asset.uri: break

    if not asset.uri:
    asset.error = "No image was generated."
    else:
    # Convert gs:// URI to an HTTP accessible URL if needed
    asset.uri = asset.uri.replace('gs://', AUTHORIZED_URI)
    logging.info(f"Image URL: {asset.uri}")
    return asset









    GCS Upload Helper (storage_utils.py)



    Since agents need a web link to display images, this utility handles the hosting on Google Cloud Storage (GCS).





    • Dynamic Bucket Selection: It looks for a bucket name in your environment variables, falling back from AI_ASSETS_BUCKET to LOGS_BUCKET_NAME to ensure it always has a place to save data.


    • Unique Filenames: We use an MD5 hash of the raw image data to create a unique filename. This prevents filename collisions and acts as a simple way to avoid duplicate uploads of the same image.


    • Cloud Upload: The blob.upload_from_string method pushes the raw image bytes directly to your GCS bucket.



    Paste this code in dev_signal_agent/tools/nano_banana_mcp/storage_utils.py:




    CODE
    import hashlib
    import mimetypes
    import os
    from google.cloud.storage import Client, Blob
    from dotenv import load_dotenv

    load_dotenv()

    storage_client = Client()
    ai_bucket_name = os.environ.get("AI_ASSETS_BUCKET") or os.environ.get("LOGS_BUCKET_NAME")
    ai_bucket = storage_client.bucket(ai_bucket_name)

    async def upload_data_to_gcs(agent_id: str, data: bytes, mime_type: str) -> str:
    file_name = hashlib.md5(data).hexdigest()
    ext = mimetypes.guess_extension(mime_type) or ""
    blob_name = f"assets/{agent_id}/{file_name}{ext}"
    blob = Blob(bucket=ai_bucket, name=blob_name)
    blob.upload_from_string(data, content_type=mime_type, client=storage_client)
    return f"gs://{ai_bucket_name}/{blob_name}"









    Data Model (media_models.py)



    This file ensures that our data follows a strict structure (Schema).





    • Structured Output: By using a Pydantic BaseModel, we guarantee that the tool always returns a consistent JSON object containing a uri (the link) and an optional error message. This makes it much easier for the AI agent to understand and process the tool's result.



    Paste this code in dev_signal_agent/tools/nano_banana_mcp/media_models.py:




    CODE
    from typing import Optional
    from pydantic import BaseModel

    class MediaAsset(BaseModel):
    uri: str
    error: Optional[str] = None









    Tool Dependencies (requirements.txt)



    While we use uv to run our code, a requirements.txt file remains essential because it defines the specific dependencies uv needs to install for the Nano Banana server to function. This provides the necessary "ingredients" to set up the isolated environment before the server starts.



    This file lists the three core libraries required for this tool:





    • google-cloud-storage: Used for hosting the generated images on the cloud.


    • google-genai: Provides the logic for the Gemini 3 Pro image generation.


    • fastmcp: The framework that turns our Python script into a standardized MCP tool.



    Paste this code in dev_signal_agent/tools/nano_banana_mcp/requirements.txt:




    CODE
    google-cloud-storage==3.6.*
    google-genai==1.52.*
    fastmcp==2.13.*









    Summary



    In this first part of our series, we focused on establishing the agent's core capabilities by standardizing its external integrations through the Model Context Protocol (MCP). We initialized the project using uv for high-speed dependency management and successfully configured three critical toolsets: Reddit for trend discovery, Google Cloud Docs for technical grounding, and a custom "Nano Banana" MCP server for multimodal image generation. By utilizing the Google ADK's McpToolset, we've abstracted away complex API logic into simple, plug-and-play modules, ensuring that our tools share a common interface that decouples integration from intelligence.



    For a deeper look into our technical foundation, you can explore the to explore the framework's core capabilities.



    With our toolset fully configured and ready for action, we can now move to , where we will show you how to test the agent locally to verify these components on your workstation. If you’d like to dive ahead, you can explore the complete code for the entire series in our for the helpful review and feedback on this article.



    For more content like this, follow Shir on .

    Vollständiger Original-Artikel
    Den kompletten Beitrag mit allen Details direkt auf dev.to lesen.
    ↗ Original-Artikel auf dev.to lesen
    Wie bewertest du diesen Beitrag?
    1 Klick Feedback
    Teilen mit Netzwerk & Team:

    Community-Analysen & Experten-Meinungen 0

    Verfasse deine eigene Analyse, teile Workarounds oder diskutiere diesen Vorfall im Blog.
    Noch keine Community-Analyse verfasst. Markiere einen Textabschnitt oder klicke oben auf Eigene Analyse verfassen“!
    Community Pulse: Relevanz-Einschätzung
    1 Klick Experten-Votum
    🔴 Akute Relevanz 0%
    🟡 In Evaluierung 0%
    🟢 Keine Auswirkung 0%
    Spannende Innovation 0%
    Verwandte Story-Cluster & Quellen (Vektor-KI)
    Port 8095 Engine
    1 Quelle
    Update-Panne bei Microsoft: Windows-11-Update sperrt Nutzer aus Domänen aus
    1 Quelle
    Chips und mehr: Huawei hat einen Plan für die Konkurrenz mit Nvidia
    1 Quelle
    Neunjähriger gibt 118.000 Dollar aus, um YouTube-Kanal zu bewerben
    Ähnliche Beiträge
    🔍 Verwandte News

    Auch interessante Nachrichten Building Capabilities for a Multi-Agent System with Google ADK, MCP, and Cloud Run

    Thematisch verwandte Begriffe: Building, Capabilities, MultiAgent, System · 6 Treffer

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...

    Laden...

    Beiträge werden geladen ...

    Laden...

    Videos werden geladen ...