ביצוע אינסטרומנטציה לשרת MCP באירוח עצמי באמצעות OpenTelemetry

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

במאמר הזה מוסבר איך לבצע את השלבים הבאים:

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

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

  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. מפעילים את ממשקי ה-API של Artifact Registry,‏ Cloud Run,‏ Cloud Build,‏ Telemetry,‏ Cloud Logging,‏ Cloud Monitoring ו-Cloud Trace.

    תפקידים שנדרשים להפעלת ממשקי 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_ID: מזהה הפרויקט.
    • PRINCIPAL: מזהה של חשבון המשתמש שרוצים להקצות לו את התפקיד. בדרך כלל, מזהי החשבונות הראשיים מופיעים בפורמט הבא: PRINCIPAL-TYPE:ID. לדוגמה, user:my-user@example.com. רשימה מלאה של הפורמטים האפשריים של PRINCIPAL מופיעה במאמר מזהים של חשבונות משתמשים.
    • ROLE: תפקיד IAM.
  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.
    • otel_setup.py כדי להגדיר את OpenTelemetry.
    • test_server.py כדי לבדוק את השרת באירוח עצמי.
    • קובץ Dockerfile לפריסה ב-Cloud Run.
    touch server.py otel_setup.py test_server.py Dockerfile
    

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

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

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

בקטע הזה מגדירים שרת MCP למתמטיקה באמצעות FastMCP. ‫FastMCP מאפשר ליצור במהירות שרתי MCP ולקוחות באמצעות Python.

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

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

    uv add fastmcp==3.2.0 opentelemetry-api==1.40.0 opentelemetry-sdk==1.40.0 opentelemetry-exporter-otlp-proto-grpc==1.40.0 --no-sync
    
  2. מוסיפים את קוד ההגדרה הבא של OpenTelemetry לקובץ otel_setup.py:

    import logging
    import google.auth
    import google.auth.transport.requests
    import grpc
    from google.auth.transport.grpc import AuthMetadataPlugin
    from opentelemetry import trace
    from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import (
        OTLPSpanExporter,
    )
    from opentelemetry.sdk.resources import SERVICE_NAME, Resource
    from opentelemetry.sdk.trace import TracerProvider
    from opentelemetry.sdk.trace.export import BatchSpanProcessor
    
    logger = logging.getLogger(__name__)
    
    
    def setup_opentelemetry(service_name: str) -> None:
        """Sets up OpenTelemetry to send traces to Google Cloud Observability."""
        credentials, project_id = google.auth.default()
        if not project_id:
            raise Exception("Could not determine Google Cloud project ID.")
    
        resource = Resource.create(
            attributes={
                SERVICE_NAME: service_name,
                "gcp.project_id": project_id,
            }
        )
    
        # Set up OTLP auth
        request = google.auth.transport.requests.Request()
        auth_metadata_plugin = AuthMetadataPlugin(credentials=credentials, request=request)
        channel_creds = grpc.composite_channel_credentials(
            grpc.ssl_channel_credentials(),
            grpc.metadata_call_credentials(auth_metadata_plugin),
        )
    
        # Set up OpenTelemetry Python SDK
        tracer_provider = TracerProvider(resource=resource)
        tracer_provider.add_span_processor(
            BatchSpanProcessor(
                OTLPSpanExporter(
                    credentials=channel_creds,
                    endpoint="https://telemetry.googleapis.com:443/v1/traces",
                )
            )
        )
        trace.set_tracer_provider(tracer_provider)
        logger.info("OpenTelemetry successfully initialized.")
    
    
  3. מוסיפים את קוד המקור הבא של שרת ה-MCP של המתמטיקה לקובץ server.py:

    from otel_setup import setup_opentelemetry
    setup_opentelemetry("mcp-server")
    
    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),
            )
        )
    
  4. כדי להשתמש בכלי 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 self-hosted-mcp-servers \
    --repository-format=docker \
    --location=us-central1 \
    --description="Repository for self-hosted MCP servers" \
    --project=PROJECT_ID
    
  2. יוצרים את קובץ האימג' של הקונטיינר ומעבירים אותו בדחיפה ל-Artifact Registry באמצעות Cloud Build:

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

    gcloud run deploy mcp-server \
    --image us-central1-docker.pkg.dev/PROJECT_ID/self-hosted-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. מריצים את הפרוקסי של 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 ומוסיפים את הקוד הבא:

    from otel_setup import setup_opentelemetry
    setup_opentelemetry("test-server")
    
    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
    

הצגת נתוני הטלמטריה

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

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

כדי לקבל את ההרשאות שדרושות להצגת נתוני היומן, המדדים והמעקב, צריך לבקש מהאדמין להקצות לכם את תפקידי ה-IAM הבאים בפרויקט:

להסבר על מתן תפקידים, ראו איך מנהלים את הגישה ברמת הפרויקט, התיקייה והארגון.

יכול להיות שאפשר לקבל את ההרשאות הנדרשות גם באמצעות תפקידים בהתאמה אישית או תפקידים מוגדרים מראש.

צפייה בטלמטריה

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

נתוני יומן

במסוף Google Cloud , נכנסים לדף Logs Explorer:

כניסה אל Logs Explorer

אם משתמשים בסרגל החיפוש כדי למצוא את הדף הזה, בוחרים בתוצאה שכותרת המשנה שלה היא Logging.

מידע נוסף על השימוש בדף Logs Explorer מופיע במאמר הצגה וניתוח של יומנים.

נתוני מדדים

נכנסים לדף  Metrics explorer במסוף Google Cloud :

כניסה אל Metrics Explorer

אם משתמשים בסרגל החיפוש כדי למצוא את הדף הזה, בוחרים בתוצאה שבה הכותרת המשנית היא Monitoring.

מידע נוסף על השימוש בדף Metrics Explorer זמין במאמר יצירת תרשימים באמצעות Metrics Explorer.

נתוני מעקב

נכנסים לדף Trace explorer במסוף Google Cloud :

כניסה אל Trace explorer

אפשר גם להשתמש בסרגל החיפוש כדי למצוא את הדף הזה.

בצילום המסך הבא מוצג החלונית פרטים בדף Trace Explorer, שבו מוצגים טווחי מעקב שנוצרו מפעולות tools/call:

חלונית הפרטים שבה מוצג מעקב והטווחים שמשויכים אליו.

מידע נוסף על השימוש בדף Trace Explorer מופיע במאמר חיפוש עקבות וניתוח שלהם.

המאמרים הבאים