פיתוח ופריסה של שרת MCP מרחוק ב-Cloud Run

במדריך הזה נסביר איך ליצור ולפרוס שרת מרוחק של Model Context Protocol ‏ (MCP) ב-Cloud Run באמצעות העברה של HTTP שניתנת להזרמה. בשיטת התעבורה HTTP עם סטרימינג, שרת ה-MCP פועל כתהליך עצמאי שיכול לטפל בכמה חיבורי לקוח.

מטרות

במדריך הזה תלמדו:

  1. הכנת פרויקט Python באמצעות מנהל החבילות uv.
  2. יצירת שרת MCP לפעולות מתמטיות.
  3. פריסה ב-Cloud Run.
  4. אימות לקוח MCP.
  5. בדיקת שרת ה-MCP המרוחק.

עלויות

במסמך הזה משתמשים ברכיבים הבאים של Google Cloud, והשימוש בהם כרוך בתשלום:

כדי להעריך את ההוצאות בהתאם לתחזית השימוש שלכם, אתם יכולים להיעזר במחשבון העלויות.

משתמשים חדשים של Google Cloud ? יכול להיות שאתם זכאים לתקופת ניסיון בחינם.

לפני שמתחילים

  1. נכנסים לחשבון Google Cloud . אם אתם משתמשים חדשים ב- Google Cloud, צרו חשבון כדי שתוכלו להעריך את הביצועים של המוצרים שלנו בתרחישים מהעולם האמיתי. לקוחות חדשים מקבלים בחינם גם קרדיט בשווי 300$ להרצה, לבדיקה ולפריסה של עומסי העבודה.
  2. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  3. Verify that billing is enabled for your Google Cloud project.

  4. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  5. Verify that billing is enabled for your Google Cloud project.

  6. מפעילים את Artifact Registry,‏ Cloud Run Admin API ו-Cloud Build API.

    תפקידים שנדרשים להפעלת ממשקי API

    כדי להפעיל ממשקי API, צריך את תפקיד ה-IAM 'אדמין של Service Usage' (roles/serviceusage.serviceUsageAdmin), שכולל את ההרשאה serviceusage.services.enable. איך מקצים תפקידים

    הפעלת ממשקי ה-API

  7. הגדרת סביבת הפיתוח של Cloud Run בפרויקט Google Cloud .
  8. מוודאים שיש לכם את ההרשאות המתאימות לפריסת שירותים, ושהתפקידים Cloud Run Admin ‏ (roles/run.admin) ו-Service Account User ‏ (roles/iam.serviceAccountUser) הוקצו לחשבון שלכם.
  9. מקצים לחשבון את התפקיד Cloud Run Invoker (הפעלת Cloud Run) (roles/run.invoker). התפקיד הזה מאפשר לשרת ה-MCP המרוחק לגשת לשירות Cloud Run.
  10. איך נותנים את התפקידים

    המסוף

    1. נכנסים לדף IAM במסוף Google Cloud .

      כניסה לדף IAM
    2. בוחרים את הפרויקט.
    3. לוחצים על Grant access.
    4. בשדה New principals, מזינים את מזהה המשתמש. בדרך כלל מדובר בכתובת האימייל שמשמשת לפריסת שירות Cloud Run.

    5. בוחרים תפקיד מהרשימה Select a role.
    6. כדי להקצות עוד תפקידים, לוחצים על Add another role ומוסיפים את כולם.
    7. לוחצים על Save.

    gcloud

    כדי להקצות לחשבון שלכם את תפקידי ה-IAM הנדרשים בפרויקט:

       gcloud projects add-iam-policy-binding PROJECT_ID \
           --member=PRINCIPAL \
           --role=ROLE
       

    מחליפים את:

    • PROJECT_NUMBER: מספר הפרויקט ב- Google Cloud .
    • PROJECT_ID: מזהה הפרויקט ב- Google Cloud .
    • PRINCIPAL: כתובת האימייל של החשבון שאתם מקצים לו את התפקיד.
    • ROLE: התפקיד שאתם מוסיפים לחשבון של המשתמש שפורס את האפליקציה.
  11. אם אתם כפופים למדיניות ארגונית של הגבלת דומיין שמגבילה הפעלות לא מאומתות של הפרויקט, תצטרכו לגשת לשירות הפרוס שלכם כמו שמתואר בקטע בדיקת שירותים פרטיים.

  12. מתקינים את Uv, מנהל פרויקטים וחבילות של Python.

הכנת פרויקט Python

בשלבים הבאים מוסבר איך להגדיר את פרויקט Python באמצעות מנהל החבילות uv.

  1. יוצרים תיקייה בשם mcp-on-cloudrun כדי לאחסן את קוד המקור לפריסה:

      mkdir mcp-on-cloudrun
      cd mcp-on-cloudrun
    
  2. יוצרים פרויקט Python באמצעות הכלי uv כדי ליצור קובץ pyproject.toml:

      uv init --name "mcp-on-cloudrun" --description "Example of deploying an MCP server on Cloud Run" --bare --python 3.10
    

    הפקודה uv init יוצרת את הקובץ pyproject.toml הבא:

    [project]
    name = "mcp-server"
    version = "0.1.0"
    description = "Example of deploying an MCP server on Cloud Run"
    readme = "README.md"
    requires-python = ">=3.10"
    dependencies = []
    
  3. יוצרים את הקבצים החדשים הנוספים הבאים:

    • server.py לקוד המקור של שרת ה-MCP
    • test_server.py כדי לבדוק את השרת המרוחק
    • קובץ Dockerfile לפריסה ב-Cloud Run
    touch server.py test_server.py Dockerfile
    

    ספריית הפרויקט צריכה להכיל את המבנה הבא:

    ├── mcp-on-cloudrun
    │   ├── pyproject.toml
    │   ├── server.py
    │   ├── test_server.py
    │   └── Dockerfile
    

יצירת שרת MCP לפעולות מתמטיות

כדי לספק הקשר חשוב לשיפור השימוש במודלים גדולים של שפה (LLM) באמצעות MCP, צריך להגדיר שרת MCP למתמטיקה באמצעות FastMCP. ‫FastMCP מאפשר ליצור במהירות שרתי MCP ולקוחות באמצעות Python.

כדי ליצור שרת MCP לפעולות מתמטיות כמו חיבור וחיסור, פועלים לפי השלבים הבאים.

  1. מריצים את הפקודה הבאה כדי להוסיף את FastMCP כתלות בקובץ pyproject.toml:

    uv add fastmcp==2.13.1 --no-sync
    
  2. מוסיפים את קוד המקור הבא של שרת ה-MCP של המתמטיקה לקובץ server.py:

    import asyncio
    import logging
    import os
    
    from fastmcp import FastMCP 
    
    logger = logging.getLogger(__name__)
    logging.basicConfig(format="[%(levelname)s]: %(message)s", level=logging.INFO)
    
    mcp = FastMCP("MCP Server on Cloud Run")
    
    @mcp.tool()
    def add(a: int, b: int) -> int:
        """Use this to add two numbers together.
    
        Args:
            a: The first number.
            b: The second number.
    
        Returns:
            The sum of the two numbers.
        """
        logger.info(f">>> 🛠️ Tool: 'add' called with numbers '{a}' and '{b}'")
        return a + b
    
    @mcp.tool()
    def subtract(a: int, b: int) -> int:
        """Use this to subtract two numbers.
    
        Args:
            a: The first number.
            b: The second number.
    
        Returns:
            The difference of the two numbers.
        """
        logger.info(f">>> 🛠️ Tool: 'subtract' called with numbers '{a}' and '{b}'")
        return a - b
    
    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="streamable-http",
                host="0.0.0.0",
                port=os.getenv("PORT", 8080),
            )
        )
    
  3. כדי להשתמש בכלי uv להרצת הקובץ server.py, צריך לכלול את הקוד הבא ב-Dockerfile:‏

    # Use the official Python image
    FROM python:3.14-slim
    
    # Install uv
    COPY --from=ghcr.io/astral-sh/uv:latest /uv /uvx /bin/
    
    # Install the project into /app
    COPY . /app
    WORKDIR /app
    
    # Allow statements and log messages to immediately appear in the logs
    ENV PYTHONUNBUFFERED=1
    
    # Install dependencies
    RUN uv sync
    
    EXPOSE $PORT
    
    # Run the FastMCP server
    CMD ["uv", "run", "server.py"]
    

פריסה ב-Cloud Run

אפשר לפרוס את שרת ה-MCP כקובץ אימג' של קונטיינר או כקוד מקור:

קובץ אימג' של קונטיינר

כדי לפרוס שרת MCP שמוגדר כקובץ אימג' של קונטיינר, צריך לפעול לפי ההוראות האלה.

  1. יוצרים מאגר ב-Artifact Registry לאחסון קובץ האימג' של הקונטיינר:

    gcloud artifacts repositories create remote-mcp-servers \
    --repository-format=docker \
    --location=us-central1 \
    --description="Repository for remote MCP servers" \
    --project=PROJECT_ID
    
  2. יוצרים את קובץ האימג' של הקונטיינר ומעבירים אותו בדחיפה ל-Artifact Registry באמצעות Cloud Build:

    gcloud builds submit --region=us-central1 --tag us-central1-docker.pkg.dev/PROJECT_ID/remote-mcp-servers/mcp-server:latest
    
  3. פורסים את קובץ האימג' של קונטיינר שרת ה-MCP ל-Cloud Run:

    gcloud run deploy mcp-server \
    --image us-central1-docker.pkg.dev/PROJECT_ID/remote-mcp-servers/mcp-server:latest \
    --region=us-central1 \
    --no-allow-unauthenticated
    

מקור

אפשר לפרוס שרתי MCP מרוחקים ל-Cloud Run מהמקורות שלהם.

כדי לבצע פריסה מקוד המקור, מריצים את הפקודה הבאה:

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

אימות לקוח MCP

אם פרסתם את השירות עם הדגל --no-allow-unauthenticated, כל לקוח MCP שמתחבר לשרת ה-MCP המרוחק שלכם צריך לעבור אימות.

  1. מקצים לחשבון השירות את התפקיד Cloud Run Invoker (הפעלת Cloud Run) ‏(roles/run.invoker). הקישור הזה של מדיניות ניהול הזהויות והגישה (IAM) מוודא שמנגנון אבטחה חזק משמש לאימות של לקוח ה-MCP המקומי.

  2. מריצים את ה-proxy של Cloud Run כדי ליצור מנהרה מאומתת לשרת ה-MCP המרוחק במחשב המקומי:

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

    אם הפרוקסי של Cloud Run עדיין לא מותקן, הפקודה הזו תציג בקשה להוריד את הפרוקסי. פועלים לפי ההנחיות כדי להוריד ולהתקין את השרת הפרוקסי.

‫Cloud Run מאמת את כל התעבורה אל http://127.0.0.1:8080 ומעביר בקשות לשרת ה-MCP המרוחק.

בדיקת שרת ה-MCP המרוחק

כדי לבדוק את החיבור לשרת ה-MCP המרוחק ולהתחבר אליו, משתמשים בלקוח FastMCP וניגשים לכתובת ה-URL‏ http://127.0.0.1:8080/mcp.

כדי לבדוק את מנגנון ההוספה וההפחתה ולהפעיל אותו, מבצעים את השלבים הבאים:

  1. לפני שמריצים את שרת הבדיקה, מריצים את ה-proxy של Cloud Run.

  2. יוצרים קובץ בדיקה בשם test_server.py ומוסיפים את הקוד הבא:

    import asyncio
    
    from fastmcp import Client
    
    
    async def test_server():
        # Test the MCP server using streamable-http transport.
        # Use "/sse" endpoint if using sse transport.
        async with Client("http://localhost:8080/mcp") as client:
            # List available tools
            tools = await client.list_tools()
            for tool in tools:
                print(f">>> 🛠️  Tool found: {tool.name}")
            # Call add tool
            print(">>> 🪛  Calling add tool for 1 + 2")
            result = await client.call_tool("add", {"a": 1, "b": 2})
            print(f"<<< ✅ Result: {result.content[0].text}")
            # Call subtract tool
            print(">>> 🪛  Calling subtract tool for 10 - 3")
            result = await client.call_tool("subtract", {"a": 10, "b": 3})
            print(f"<<< ✅ Result: {result.content[0].text}")
    
    
    if __name__ == "__main__":
        asyncio.run(test_server())
  3. במסוף חדש, מריצים את שרת הבדיקה:

    uv run test_server.py
    

    הפלט הבא אמור להתקבל:

     🛠️ Tool found: add
     🛠️ Tool found: subtract
     🪛 Calling add tool for 1 + 2
     ✅ Result: 3
     🪛 Calling subtract tool for 10 - 3
     ✅ Result: 7
    

הסרת המשאבים

כדי להימנע מחיובים נוספים בחשבון Google Cloud , מוחקים את כל המשאבים שהצבתם באמצעות המדריך הזה.

מחיקת הפרויקט

אם יצרתם פרויקט חדש בשביל המדריך הזה, מוחקים את הפרויקט. אם השתמשתם בפרויקט קיים ואתם רוצים לשמור אותו בלי השינויים שהוספתם במדריך הזה, תצטרכו למחוק את המשאבים שיצרתם לצורך המדריך.

הדרך הקלה ביותר לבטל את החיוב היא למחוק את הפרויקט שיצרתם בשביל המדריך.

כדי למחוק את הפרויקט:

  1. במסוף Google Cloud , נכנסים לדף Manage resources.

    כניסה לדף Manage resources

  2. ברשימת הפרויקטים, בוחרים את הפרויקט שרוצים למחוק ולוחצים על Delete.
  3. כדי למחוק את הפרויקט, כותבים את מזהה הפרויקט בתיבת הדו-שיח ולוחצים על Shut down.

מחיקת משאבי הדרכה

  1. מוחקים את שירות Cloud Run שפרסתם במדריך הזה. שירותי Cloud Run לא צוברים עלויות עד שהם מקבלים בקשות.

    כדי למחוק את שירות Cloud Run, מריצים את הפקודה הבאה:

    gcloud run services delete SERVICE-NAME

    מחליפים את SERVICE-NAME בשם השירות.

    אפשר גם למחוק שירותים של Cloud Run מGoogle Cloud המסוף.

  2. מסירים את הגדרת ברירת המחדל של האזור gcloud שהוספתם במהלך ההגדרה של המדריך:

     gcloud config unset run/region
    
  3. מסירים את הגדרות הפרויקט:

     gcloud config unset project