הטמעת שרת MCP משלכם ב-kagent

מבוא

שרתי Model Context Protocol‏ (MCP) מסוג Bring your own‏ (BYO) מאפשרים לסוכני AI לשלוח שאילתות ולעבד נתונים ממאגרים חיצוניים בזמן אמת, באמצעות חיבורים סטנדרטיים בתשתית הקיימת.

במסמך הזה, שמתאר הטמעה של פתרון לדוגמה (SRI), מוסבר איך לפרוס את האפליקציה בקוד פתוח Nextcloud ואת שרת ה-MCP שלה לצד סוכן Nextcloud ב-Solo Enterprise for kagent. הארכיטקטורה הזו מחברת בין Nextcloud,‏ kagent והמודל Gemma 4 בתוך אשכול Google Kubernetes Engine (GKE) שנפרס ב-Distributed Cloud software only (GDC). בהגדרה הזו, kagent משתמש ב-Nextcloud כמאגר נתונים, ומאפשר למודל Gemma 4 לגשת לקבצים ב-Nextcloud ולעבד אותם באמצעות ממשקי MCP סטנדרטיים. להקשר הארכיטקטוני, ראו את ארכיטקטורת העזר הנלווית.

סקירה כללית על Nextcloud

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

ב-Nextcloud יש את התכונות הבאות:

  • סנכרון ושיתוף של קבצים: אחסון קבצים, סנכרון שלהם במחשב ובמכשירים ניידים באמצעות אפליקציות ייעודיות, ושיתוף שלהם עם אחרים באמצעות קישורים.
  • כלים לשיפור הפרודוקטיביות: ניהול לוחות זמנים ותקשורת באמצעות יומן, אנשי קשר, ניהול משימות ותוכנות אימייל מובנים.
  • שיתוף פעולה: שילוב של חבילות Office (כמו Collabora Online או ONLYOFFICE) ישירות ב-Nextcloud כדי לערוך ביחד מסמכים, גיליונות אלקטרוניים ומצגות בזמן אמת.
  • הרחבה: אפשר להתקין פלאגינים מחנות האפליקציות כדי להוסיף תכונות כמו מנהלי סיסמאות, לוחות קנבן או נגני מוזיקה.

ארכיטקטורת פתרונות

כדי להשתמש בפתרון הזה, צריך סביבת GDC שבה פרוסים Solo Enterprise ל-kagent ו-vLLM עם מודל Gemma 4, ותחנת עבודה שמותקנים בה kubectl ו-helm.

בתרשים הבא מוצגת ארכיטקטורת הפתרון שמחברת בין GDC,‏ kagent,‏ Nextcloud ו-vLLM עם Gemma 4:

ארכיטקטורת הפתרון: GDC,‏ kagent,‏ Nextcloud ו-vLLM עם Gemma 4.

גישת הפריסה

כדי לפרוס את Nextcloud ולשלב את שרת ה-MCP שלו עם kagent, מבצעים את השלבים הכלליים הבאים:

  1. יצירת מרחב שמות ייעודי ל-Nextcloud: מבודדים את הפריסה על ידי יצירת מרחב השמות nextcloud באמצעות kubectl.
  2. הוספה ועדכון של מאגר Helm: מגדירים את תחנת העבודה עם מאגר Helm הרשמי של Nextcloud ומעדכנים את המטא-נתונים של התרשים המקומי.
  3. הגדרת ערכי פריסה בהתאמה אישית: יוצרים קובץ values.yaml בהתאמה אישית כדי להגדיר את Nextcloud לסביבת היעד. ההגדרה הזו משביתה את מסד הנתונים המקומי של SQLite שמוגדר כברירת מחדל, מגדירה את האחסון המתמיד של MariaDB, מגדירה את פרטי הכניסה של האדמין ומגדירה ניתוב פנימי באמצעות שירות ClusterIP.
  4. מריצים את ההתקנה של Helm: פורסים את התרשים במרחב השמות של היעד באמצעות קובץ התצורה בהתאמה אישית. מוודאים שכל הרכיבים, כולל אפליקציית Nextcloud ו-Pods של אחסון MariaDB, מגיעים לסטטוס Running.
  5. פורסים את שרת ה-MCP של Nextcloud: יוצרים מניפסט פריסה (nextcloud-mcp.yaml) שמכיל סוד אטום לפרטי הכניסה, פריסה באמצעות קובץ האימג' nextcloud-mcp-server:latest ושירות ClusterIP שחושף את היציאה 8000. מחילים את המניפסט הזה כדי לאפשר תקשורת DNS פנימית של Kubernetes עם אפליקציית Nextcloud.
  6. רושמים את שרת הכלים ב-kagent: מחברים את השרת בממשק המשתמש של kagent באמצעות כתובת ה-URL של השירות הפנימי http://nextcloud-mcp-service.nextcloud.svc.cluster.local:8000/mcp והפרוטוקול STREAMABLE_HTTP.

פריסת Nextcloud ושרת ה-MCP

  1. יוצרים מרחב שמות ל-Nextcloud:

    kubectl create namespace nextcloud
    

    הפלט אמור להיראות כך:

    namespace/nextcloud created
    
  2. מוסיפים את מאגר Nextcloud Helm לתחנת העבודה ומעדכנים את המטא-נתונים של התרשים המקומי:

    helm repo add nextcloud https://nextcloud.github.io/helm/
    helm repo update
    

    הפלט אמור להיראות כך:

    "nextcloud" has been added to your repositories
    Hang tight while we grab the latest from your chart repositories...
    ...Successfully got an update from the "nextcloud" chart repository
    Update Complete. ⎈Happy Helming!⎈
    
  3. יוצרים קובץ values.yaml בהתאמה אישית בתחנת העבודה כדי לשנות את הפרמטרים של הגדרות ברירת המחדל של תרשים Nextcloud Helm:

    # 0. Nextcloud administrator configuration
    nextcloud:
      # Use the internal CoreDNS record
      host: "nextcloud.nextcloud.svc.cluster.local"  # Application access through CoreDNS rather than external DNS
      username: "admin"  # Application Login Credentials
      password: "SuperSecretPassword123"
    
    # You can use a standard ClusterIP service since
    # you are relying on internal routing, not an External LB.
    service:
      type: ClusterIP
    
    # 1. Configure RWO Storage for Nextcloud
    persistence:
      enabled: true
      storageClass: "local-shared"
      accessMode: ReadWriteOnce
      size: 50Gi # Adjust based on your file storage needs
    
    # 2. Explicitly disable the default local SQLite database
    internalDatabase:
      enabled: false
    
    # 3. Configure RWO Storage for the Database
    mariadb:
      enabled: true
      auth:
        database: "nextcloud"
        username: "nextcloud"
        password: "NextcloudDBPassword123"
        rootPassword: "RootDBPassword123"
      primary:
        persistence:
          enabled: true
          storageClass: "local-shared"
          accessModes:
            - ReadWriteOnce
          size: 10Gi
    
    # 4. Force Nextcloud to connect through the TCP Network
    externalDatabase:
      enabled: true
      type: mysql
      host: "nextcloud-mariadb" # The internal Kubernetes service name for the DB
      database: "nextcloud"
      user: "nextcloud"
      password: "NextcloudDBPassword123" # MUST match mariadb.auth.password above
    
    # Optional: Enable Ingress to route external traffic to Nextcloud
    ingress:
      enabled: false # Set to true if you are using an Ingress Controller (like NGINX)
      className: "nginx"
      annotations:
        nginx.ingress.kubernetes.io/proxy-body-size: 4G # Required to allow large file uploads
    
  4. פורסים את Nextcloud באמצעות Helm:

    helm install nextcloud nextcloud/nextcloud \
        --namespace nextcloud \
        --values values.yaml
    

    הפלט אמור להיראות כך:

    NAME: nextcloud
    LAST DEPLOYED: Thu Jul  9 17:14:03 2026
    NAMESPACE: nextcloud
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    1. Get the nextcloud URL by running:
    
      export POD_NAME=$(kubectl get pods --namespace nextcloud -l "app.kubernetes.io/name=nextcloud" -o jsonpath="{.items[0].metadata.name}")
      echo http://127.0.0.1:8080/
      kubectl port-forward --namespace nextcloud $POD_NAME 8080:80
    
    2. Get your nextcloud login credentials by running:
    
      echo User:     admin
      echo Password: $(kubectl get secret --namespace nextcloud nextcloud -o jsonpath="{.data.nextcloud-password}" | base64 --decode)
    

    מוודאים שה-Pods של Nextcloud נמצאים בסטטוס Running ושהשירותים קיימים במרחב השמות nextcloud:

    kubectl get pod -n nextcloud
    kubectl get svc -n nextcloud
    

    הפלט אמור להיראות כך:

    NAME                                    READY   STATUS    RESTARTS   AGE
    nextcloud-558cbccb4c-q6zqq              1/1     Running   0          25m
    nextcloud-mariadb-0                     1/1     Running   0          25m
    
    NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    nextcloud                    ClusterIP   10.255.224.187   <none>        8080/TCP   25m
    nextcloud-mariadb            ClusterIP   10.255.226.235   <none>        3306/TCP   25m
    nextcloud-mariadb-headless   ClusterIP   None             <none>        3306/TCP   25m
    
  5. כדי לפרוס את שרת ה-MCP של Nextcloud במרחב השמות nextcloud, יוצרים קובץ בשם nextcloud-mcp.yaml בתחנת העבודה:

    # Secret Creation
    apiVersion: v1
    kind: Secret
    metadata:
      name: nextcloud-mcp-secret
      namespace: nextcloud
    type: Opaque
    stringData:
      # Use your dedicated App Password here, NEVER your primary administrator password
      NEXTCLOUD_USERNAME: "admin"
      NEXTCLOUD_PASSWORD: "SuperSecretPassword123"
    ---
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: nextcloud-mcp-server
      namespace: nextcloud
      labels:
        app: nextcloud-mcp
    spec:
      replicas: 1
      selector:
        matchLabels:
          app: nextcloud-mcp
      template:
        metadata:
          labels:
            app: nextcloud-mcp
        spec:
          containers:
            - name: mcp-server
              # The official Docker image provided by the project
              image: ghcr.io/cbcoutinho/nextcloud-mcp-server:latest
              imagePullPolicy: Always
              ports:
                - containerPort: 8000
                  name: http-mcp
              env:
                - name: NEXTCLOUD_HOST
                  # Since the MCP server is in the same namespace, it can securely
                  # talk to Nextcloud through the internal Kubernetes DNS, completely bypassing the internet.
                  value: "http://nextcloud.nextcloud.svc.cluster.local:8080"
                - name: NEXTCLOUD_USERNAME
                  valueFrom:
                    secretKeyRef:
                      name: nextcloud-mcp-secret
                      key: NEXTCLOUD_USERNAME
                - name: NEXTCLOUD_PASSWORD
                  valueFrom:
                    secretKeyRef:
                      name: nextcloud-mcp-secret
                      key: NEXTCLOUD_PASSWORD
              resources:
                requests:
                  cpu: "100m"
                  memory: "128Mi"
                limits:
                  cpu: "500m"
                  memory: "512Mi"
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: nextcloud-mcp-service
      namespace: nextcloud
    spec:
      type: ClusterIP
      ports:
        - port: 8000
          targetPort: 8000
          protocol: TCP
          name: http-mcp
      selector:
        app: nextcloud-mcp
    

    מחילים את המניפסט nextcloud-mcp.yaml:

    kubectl apply -f nextcloud-mcp.yaml
    

    הפלט אמור להיראות כך:

    secret/nextcloud-mcp-secret created
    deployment.apps/nextcloud-mcp-server created
    service/nextcloud-mcp-service created
    

    מוודאים שה-Pods והשירותים פועלים במרחב השמות nextcloud:

    kubectl get svc -n nextcloud
    kubectl get pod -n nextcloud
    

    הפלט אמור להיראות כך:

    NAME                         TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)    AGE
    nextcloud                    ClusterIP   10.255.224.187   <none>        8080/TCP   26m
    nextcloud-mariadb            ClusterIP   10.255.226.235   <none>        3306/TCP   26m
    nextcloud-mariadb-headless   ClusterIP   None             <none>        3306/TCP   26m
    nextcloud-mcp-service        ClusterIP   10.255.226.105   <none>        8000/TCP   55s
    
    NAME                                    READY   STATUS    RESTARTS   AGE
    nextcloud-558cbccb4c-q6zqq              1/1     Running   0          29m
    nextcloud-mariadb-0                     1/1     Running   0          29m
    nextcloud-mcp-server-58484d5799-mfvct   1/1     Running   0          4m11s
    
  6. כדי לשלב את כלי ה-MCP של Nextcloud באמצעות כתובת URL, עוברים לממשק המשתמש של kagent ורושמים שרת כלים עם הערכים הבאים:

    • כתובת URL: http://nextcloud-mcp-service.nextcloud.svc.cluster.local:8000/mcp
    • פרוטוקול: STREAMABLE_HTTP
    • מרחב שמות: kagent
    • ‫Cluster: שם האשכול (לדוגמה, mgmt-cluster)

    מוודאים שהמשאב RemoteMCPServer אושר במרחב השמות kagent:

    kubectl get remotemcpserver -n kagent
    

    הפלט אמור להיראות כך:

    NAME                 PROTOCOL          URL                                                                 ACCEPTED
    kagent-grafana-mcp   STREAMABLE_HTTP   http://kagent-grafana-mcp.kagent:8000/mcp                           True
    kagent-tool-server   STREAMABLE_HTTP   http://kagent-tools.kagent:8084/mcp                                 True
    nextcloud            STREAMABLE_HTTP   http://nextcloud-mcp-service.nextcloud.svc.cluster.local:8000/mcp   True
    
  7. כדי לגשת ל-Nextcloud מתחנת העבודה, מעבירים את היציאה המקומית 8080 לשירות nextcloud (אם הגדרתם כתובת URL חיצונית, דלגו על השלב הזה):

    kubectl port-forward -n nextcloud svc/nextcloud 8080:8080 &
    

    הפלט אמור להיראות כך:

    Forwarding from 127.0.0.1:8080 -> 80
    Forwarding from [::1]:8080 -> 80
    

אימות הפריסה והגדרת הסוכן של Nextcloud

בדפדפן של תחנת העבודה, פותחים את http://localhost:8080 כדי להציג את מרכז הבקרה של Nextcloud:

דף מרכז הבקרה של אפליקציית Nextcloud.

בתצוגה Files מופיעים הקבצים והספריות שמאוחסנים ב-Nextcloud:

ממשק הספרייה והקבצים באפליקציית Nextcloud.

בדף Dashboard בממשק המשתמש של kagent מוצגים האשכולות המחוברים והסוכנים שנפרסו:

לוח הבקרה של אפליקציית kagent.

בדף שרתי כלים מופיעה רשימה של הכלים שזוהו באמצעות MCP באפליקציית Nextcloud:

דף שרתי הכלים של kagent, שבו מוצגים הכלים שנמצאו לאפליקציית Nextcloud.

בדף Tools מוצג אוסף הכלים של Nextcloud שזמינים לנציגים:

אוסף הכלים של kagent זמין ב-Nextcloud.

כדי ליצור את הסוכן nextcloud בממשק המשתמש של kagent, מזינים את שם הסוכן, האשכול, מרחב השמות והתיאור בקטע Basic Information:

יצירת סוכן kagent ל-Nextcloud.

בקטע Behavior & Model Settings, בוחרים את המודל Gemma 4 ומזינים את הוראות המערכת לסוכן:

הגדרת סוכן kagent להתאמה של מיומנות ומודל.

בקטע Tools and Agents, בוחרים את כלי ה-MCP של Nextcloud בשביל הנציג ולוחצים על Create Agent:

הגדרות הסוכן kagent לבחירת הכלי Nextcloud.

בדף Agents מופיע הנציג nextcloud עם הסטטוס Ready:

סוכנים שנוספו לאפליקציית kagent.

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

סוכן Nextcloud שמציג רשימה של ספריות וקבצים.

אפשר גם לבקש מסוכן Nextcloud לתרגם ולתעתק תוכן של קבצים מאנגלית לצרפתית:

סוכן Nextcloud מתרגם תוכן של קובץ מאנגלית לצרפתית.